mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-17 06:52:27 +01:00
Merge branch 'dev' for release 4.5.7
This commit is contained in:
commit
2561b616a8
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,5 +1,16 @@
|
||||
# Changelog Fab-manager
|
||||
|
||||
## v4.5.7 2020 September 23
|
||||
|
||||
- Fix a bug: unable to run tests suite with run-tests.sh
|
||||
- Fix a bug: unable to search for projects (#230)
|
||||
- Fix a bug: wallet tab is not shown in members dashboard
|
||||
- Fix a bug: slots duration is not shown when looking at a new availability
|
||||
- Fix a bug: user's manual URL is not up-to-date
|
||||
- Fix a bug: unable to create a subscription plan for only one group
|
||||
- Fix a bug: removed unexpected character in coupon form
|
||||
- Updated coveralls gem to a supported version
|
||||
|
||||
## v4.5.6 2020 September 1st
|
||||
|
||||
- Fix a bug: unable to pay by card for events reservation
|
||||
|
2
Gemfile
2
Gemfile
@ -40,7 +40,7 @@ group :development do
|
||||
# Access an IRB console on exception pages or by using <%= console %> in views
|
||||
gem 'active_record_query_trace'
|
||||
gem 'awesome_print'
|
||||
gem 'coveralls', require: false
|
||||
gem 'coveralls_reborn', '~> 0.18.0', require: false
|
||||
gem 'foreman'
|
||||
gem 'web-console', '>= 3.3.0'
|
||||
# Preview mail in the browser
|
||||
|
22
Gemfile.lock
22
Gemfile.lock
@ -117,12 +117,11 @@ GEM
|
||||
sprockets (< 4.0)
|
||||
concurrent-ruby (1.1.6)
|
||||
connection_pool (2.2.3)
|
||||
coveralls (0.8.23)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov (~> 0.16.1)
|
||||
term-ansicolor (~> 1.3)
|
||||
thor (>= 0.19.4, < 2.0)
|
||||
tins (~> 1.6)
|
||||
coveralls_reborn (0.18.0)
|
||||
simplecov (>= 0.18.1, < 0.20.0)
|
||||
term-ansicolor (~> 1.6)
|
||||
thor (>= 0.20.3, < 2.0)
|
||||
tins (~> 1.16)
|
||||
crack (0.4.3)
|
||||
safe_yaml (~> 1.0.0)
|
||||
crass (1.0.6)
|
||||
@ -395,11 +394,10 @@ GEM
|
||||
concurrent-ruby (~> 1.0, >= 1.0.5)
|
||||
sidekiq (>= 4.0, < 7.0)
|
||||
thor (~> 0)
|
||||
simplecov (0.16.1)
|
||||
simplecov (0.19.0)
|
||||
docile (~> 1.1)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov-html (~> 0.10.0)
|
||||
simplecov-html (0.10.2)
|
||||
simplecov-html (~> 0.11)
|
||||
simplecov-html (0.12.2)
|
||||
spring (2.0.2)
|
||||
activesupport (>= 4.2)
|
||||
spring-watcher-listen (2.0.1)
|
||||
@ -421,7 +419,7 @@ GEM
|
||||
thor (0.20.3)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.10)
|
||||
tins (1.24.1)
|
||||
tins (1.25.0)
|
||||
sync
|
||||
ttfunk (1.5.1)
|
||||
twitter_cldr (5.4.0)
|
||||
@ -472,7 +470,7 @@ DEPENDENCIES
|
||||
chroma
|
||||
compass-core!
|
||||
compass-rails (= 3.1.0)
|
||||
coveralls
|
||||
coveralls_reborn (~> 0.18.0)
|
||||
database_cleaner
|
||||
devise (>= 4.6.0)
|
||||
dotenv-rails
|
||||
|
@ -451,7 +451,8 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
|
||||
tag_ids: availability.tag_ids,
|
||||
tags: availability.tags,
|
||||
machine_ids: availability.machine_ids,
|
||||
plan_ids: availability.plan_ids
|
||||
plan_ids: availability.plan_ids,
|
||||
slot_duration: availability.slot_duration
|
||||
},
|
||||
true
|
||||
);
|
||||
|
@ -21,12 +21,20 @@
|
||||
/* COMMON CODE */
|
||||
|
||||
class PlanController {
|
||||
constructor ($scope, groups, prices, partners, CSRF) {
|
||||
constructor ($scope, groups, prices, partners, CSRF, _t) {
|
||||
// protection against request forgery
|
||||
CSRF.setMetaTags();
|
||||
|
||||
// groups list
|
||||
$scope.groups = groups.filter(function (g) { return (g.slug !== 'admins') && !g.disabled; });
|
||||
$scope.groups = groups
|
||||
.filter(function (g) { return (g.slug !== 'admins') && !g.disabled; })
|
||||
.map(e => Object.assign({}, e, { category: 'app.shared.plan.groups', id: `${e.id}` }))
|
||||
$scope.groups.push({ id: 'all', name: 'app.shared.plan.transversal_all_groups', category: 'app.shared.plan.all' });
|
||||
|
||||
// dynamically translate a label if needed
|
||||
$scope.translateLabel = function (group, prop) {
|
||||
return group[prop] && group[prop].match(/^app\./) ? _t(group[prop]) : group[prop];
|
||||
}
|
||||
|
||||
// users with role 'partner', notifiables for a partner plan
|
||||
$scope.partners = partners.users;
|
||||
@ -156,7 +164,7 @@ Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal',
|
||||
}
|
||||
};
|
||||
|
||||
return new PlanController($scope, groups, prices, partners, CSRF);
|
||||
return new PlanController($scope, groups, prices, partners, CSRF, _t);
|
||||
}
|
||||
]);
|
||||
|
||||
@ -177,13 +185,13 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
|
||||
$scope.machines = machines;
|
||||
|
||||
// List of groups
|
||||
$scope.groups = groups;
|
||||
$scope.allGroups = groups;
|
||||
|
||||
// current form is used for edition mode
|
||||
$scope.mode = 'edition';
|
||||
|
||||
// edited plan data
|
||||
$scope.plan = planPromise;
|
||||
$scope.plan = Object.assign({}, planPromise, { group_id: `${planPromise.group_id}` });
|
||||
if ($scope.plan.type === null) { $scope.plan.type = 'Plan'; }
|
||||
if ($scope.plan.disabled) { $scope.plan.disabled = 'true'; }
|
||||
|
||||
@ -193,6 +201,11 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
|
||||
// HTTP method for the rest API
|
||||
$scope.method = 'PATCH';
|
||||
|
||||
$scope.selectedGroup = function () {
|
||||
const group = $scope.groups.filter(g => g.id === $scope.plan.group_id);
|
||||
return $scope.translateLabel(group[0], 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
* If a parent plan was set ($scope.plan.parent), the prices will be copied from this parent plan into
|
||||
* the current plan prices list. Otherwise, the current plan prices will be erased.
|
||||
@ -281,6 +294,6 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
|
||||
};
|
||||
|
||||
// Using the PlansController
|
||||
return new PlanController($scope, groups, prices, partners, CSRF);
|
||||
return new PlanController($scope, groups, prices, partners, CSRF, _t);
|
||||
}
|
||||
]);
|
||||
|
@ -676,7 +676,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
||||
content: _t('app.admin.tour.pricing.machines.content'),
|
||||
placement: 'bottom'
|
||||
});
|
||||
if ($scope.modules.spaces) {
|
||||
if ($scope.$root.modules.spaces) {
|
||||
uitour.createStep({
|
||||
selector: '.plans-pricing .spaces-tab',
|
||||
stepId: 'spaces',
|
||||
|
@ -140,7 +140,7 @@ Application.Controllers.controller('HomeController', ['$scope', '$stateParams',
|
||||
content: _t('app.public.tour.welcome.machines.content'),
|
||||
placement: 'right'
|
||||
});
|
||||
if ($scope.modules.spaces) {
|
||||
if ($scope.$root.modules.spaces) {
|
||||
uitour.createStep({
|
||||
selector: '.nav-primary li.reserve-space-link',
|
||||
stepId: 'spaces',
|
||||
|
@ -58,7 +58,7 @@ Application.Controllers.controller('MainNavController', ['$scope', function ($sc
|
||||
|
||||
];
|
||||
|
||||
if ($scope.modules.plans) {
|
||||
if ($scope.$root.modules.plans) {
|
||||
$scope.navLinks.push({
|
||||
state: 'app.public.plans',
|
||||
linkText: 'app.public.common.subscriptions',
|
||||
@ -67,7 +67,7 @@ Application.Controllers.controller('MainNavController', ['$scope', function ($sc
|
||||
});
|
||||
}
|
||||
|
||||
if ($scope.modules.spaces) {
|
||||
if ($scope.$root.modules.spaces) {
|
||||
$scope.navLinks.splice(4, 0, {
|
||||
state: 'app.public.spaces_list',
|
||||
linkText: 'app.public.common.reserve_a_space',
|
||||
@ -147,7 +147,7 @@ Application.Controllers.controller('MainNavController', ['$scope', function ($sc
|
||||
|
||||
$scope.adminNavLinks = adminNavLinks;
|
||||
|
||||
if ($scope.modules.spaces) {
|
||||
if ($scope.$root.modules.spaces) {
|
||||
$scope.adminNavLinks.splice(3, 0, {
|
||||
state: 'app.public.spaces_list',
|
||||
linkText: 'app.public.common.manage_the_spaces',
|
||||
@ -155,8 +155,8 @@ Application.Controllers.controller('MainNavController', ['$scope', function ($sc
|
||||
});
|
||||
}
|
||||
|
||||
if ($scope.modules.statistics) {
|
||||
$scope.adminNavLinks.splice($scope.modules.spaces ? 9 : 8, 0, {
|
||||
if ($scope.$root.modules.statistics) {
|
||||
$scope.adminNavLinks.splice($scope.$root.modules.spaces ? 9 : 8, 0, {
|
||||
state: 'app.admin.statistics',
|
||||
linkText: 'app.public.common.statistics',
|
||||
linkIcon: 'bar-chart-o',
|
||||
|
@ -334,7 +334,7 @@ Application.Controllers.controller('ProjectsController', ['$scope', '$state', 'P
|
||||
$scope.search.component_id = undefined;
|
||||
$scope.search.theme_id = undefined;
|
||||
$scope.setUrlQueryParams($scope.search);
|
||||
return $scope.triggerSearch();
|
||||
$scope.triggerSearch();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -346,22 +346,22 @@ Application.Controllers.controller('ProjectsController', ['$scope', '$state', 'P
|
||||
if ($scope.openlab.searchOverWholeNetwork === true) {
|
||||
updateUrlParam('whole_network', 't');
|
||||
$scope.projectsPagination = new paginationService.Instance(OpenlabProject, currentPage, PROJECTS_PER_PAGE, null, { }, loadMoreOpenlabCallback);
|
||||
return OpenlabProject.query({ q: $scope.search.q, page: currentPage, per_page: PROJECTS_PER_PAGE }, function (projectsPromise) {
|
||||
OpenlabProject.query({ q: $scope.search.q, page: currentPage, per_page: PROJECTS_PER_PAGE }, function (projectsPromise) {
|
||||
if (projectsPromise.errors) {
|
||||
growl.error(_t('app.public.projects_list.openlab_search_not_available_at_the_moment'));
|
||||
$scope.openlab.searchOverWholeNetwork = false;
|
||||
return $scope.triggerSearch();
|
||||
$scope.triggerSearch();
|
||||
} else {
|
||||
$scope.projectsPagination.totalCount = projectsPromise.meta.total;
|
||||
return $scope.projects = normalizeProjectsAttrs(projectsPromise.projects);
|
||||
$scope.projects = normalizeProjectsAttrs(projectsPromise.projects);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
updateUrlParam('whole_network', 'f');
|
||||
$scope.projectsPagination = new paginationService.Instance(Project, currentPage, PROJECTS_PER_PAGE, null, { }, loadMoreCallback, 'search');
|
||||
return Project.search({ search: $scope.search, page: currentPage, per_page: PROJECTS_PER_PAGE }, function (projectsPromise) {
|
||||
Project.search({ search: $scope.search, page: currentPage, per_page: PROJECTS_PER_PAGE }, function (projectsPromise) {
|
||||
$scope.projectsPagination.totalCount = projectsPromise.meta.total;
|
||||
return $scope.projects = projectsPromise.projects;
|
||||
$scope.projects = projectsPromise.projects;
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -388,7 +388,8 @@ Application.Controllers.controller('ProjectsController', ['$scope', '$state', 'P
|
||||
updateUrlParam('from', search.from);
|
||||
updateUrlParam('theme_id', search.theme_id);
|
||||
updateUrlParam('component_id', search.component_id);
|
||||
return updateUrlParam('machine_id', search.machine_id);
|
||||
updateUrlParam('machine_id', search.machine_id);
|
||||
return true;
|
||||
};
|
||||
|
||||
/* PRIVATE SCOPE */
|
||||
|
@ -29,7 +29,7 @@ Application.Services.factory('Help', ['$rootScope', '$uibModal', '$state', 'Auth
|
||||
|
||||
// if no tour, just open the guide
|
||||
if (tourName === undefined) {
|
||||
return window.open('https://github.com/sleede/fab-manager/raw/master/doc/fr/guide_utilisation_fab_manager_v4.3.pdf', '_blank');
|
||||
return window.open('https://github.com/sleede/fab-manager/raw/master/doc/fr/guide_utilisation_fab_manager_v4.5.pdf', '_blank');
|
||||
}
|
||||
|
||||
$uibModal.open({
|
||||
|
@ -53,7 +53,7 @@
|
||||
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': couponForm['coupon[amount_off]'].$dirty && couponForm['coupon[amount_off]'].$invalid}" ng-show="coupon.type == 'amount_off'">
|
||||
²<div class="input-group">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">{{currencySymbol}}</span>
|
||||
<input type="number" id="coupon[amount_off]"
|
||||
name="coupon[amount_off]"
|
||||
|
@ -32,12 +32,19 @@
|
||||
class="form-control"
|
||||
ng-model="plan.group_id"
|
||||
required="required"
|
||||
ng-disabled="method == 'PATCH'">
|
||||
<option value="all" translate>{{ 'app.shared.plan.transversal_all_groups' }}</option>
|
||||
<optgroup label="Groupes">
|
||||
<option ng-repeat="group in groups" ng-value="group.id" ng-selected="plan.group_id == group.id">{{group.name}}</option>
|
||||
</optgroup>
|
||||
ng-if="method !== 'PATCH'"
|
||||
ng-options="item.id as translateLabel(item, 'name') group by translateLabel(item, 'category') for item in groups track by item.id">
|
||||
</select>
|
||||
<input type="text"
|
||||
id="plan[group_id]"
|
||||
ng-value="selectedGroup()"
|
||||
ng-if="method == 'PATCH'"
|
||||
class="form-control"
|
||||
disabled />
|
||||
<input type="hidden"
|
||||
name="plan[group_id]"
|
||||
ng-value="plan.group_id"
|
||||
ng-if="method == 'PATCH'"/>
|
||||
<span class="help-block" ng-show="planForm['plan[group_id]'].$dirty && planForm['plan[group_id]'].$error.required" translate>{{ 'app.shared.plan.group_is_required' }}</span>
|
||||
</div>
|
||||
|
||||
|
@ -48,7 +48,7 @@
|
||||
<div class="form-group col-md-6 col-lg-offset-6">
|
||||
<input type="hidden" ng-model="plan.parent" name="plan[parent_id]" ng-value="plan.parent"/>
|
||||
<label for="parentPlan" translate>{{ 'app.admin.plans.edit.copy_prices_from' }}</label>
|
||||
<select id="parentPlan" ng-options="plan.id as humanReadablePlanName(plan, groups) for plan in plans" ng-model="plan.parent" ng-change="copyPricesFromPlan()" class="form-control">
|
||||
<select id="parentPlan" ng-options="plan.id as humanReadablePlanName(plan, allGroups) for plan in plans" ng-model="plan.parent" ng-change="copyPricesFromPlan()" class="form-control">
|
||||
<option value=""></option>
|
||||
</select>
|
||||
</div>
|
||||
|
@ -13,7 +13,7 @@
|
||||
<div class="row text-center m-t-lg m-b-md">
|
||||
<a class="btn btn-default"
|
||||
ng-click="onGuide()"
|
||||
href="https://github.com/sleede/fab-manager/raw/master/doc/fr/guide_utilisation_fab_manager_v4.3.pdf"
|
||||
href="https://github.com/sleede/fab-manager/raw/master/doc/fr/guide_utilisation_fab_manager_v4.5.pdf"
|
||||
target="_blank"
|
||||
translate>{{ 'app.shared.help.guide' }}</a>
|
||||
</div>
|
||||
|
@ -38,7 +38,7 @@ class SettingPolicy < ApplicationPolicy
|
||||
fablab_name name_genre event_explications_alert space_explications_alert link_name home_content phone_required
|
||||
tracking_id book_overlapping_slots slot_duration events_in_calendar spaces_module plans_module invoicing_module
|
||||
recaptcha_site_key feature_tour_display disqus_shortname allowed_cad_extensions openlab_app_id openlab_default
|
||||
online_payment_module stripe_public_key confirmation_required]
|
||||
online_payment_module stripe_public_key confirmation_required wallet_module]
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -20,3 +20,9 @@ Sidekiq.configure_client do |config|
|
||||
end
|
||||
|
||||
Sidekiq::Extensions.enable_delay!
|
||||
|
||||
# Quieting logging in the test environment
|
||||
if Rails.env.test?
|
||||
require 'sidekiq/testing'
|
||||
Sidekiq.logger.level = Logger::ERROR
|
||||
end
|
||||
|
@ -162,6 +162,8 @@ en:
|
||||
standard: "Standard"
|
||||
type_is_required: "Type is required."
|
||||
group: "Group"
|
||||
groups: "Groups"
|
||||
all: "All"
|
||||
transversal_all_groups: "Transversal (all groups)"
|
||||
group_is_required: "Group is required."
|
||||
number_of_periods: "Number of periods"
|
||||
|
@ -162,6 +162,8 @@ es:
|
||||
standard: "Standard"
|
||||
type_is_required: "Se requiere un tipo."
|
||||
group: "Grupo"
|
||||
groups: "Grupos"
|
||||
all: "Todos"
|
||||
transversal_all_groups: "Transversal (todos los grupos)"
|
||||
group_is_required: "Se requiere un grupo."
|
||||
number_of_periods: "Numero de periodos"
|
||||
|
@ -162,6 +162,8 @@ fr:
|
||||
standard: "Standard"
|
||||
type_is_required: "Le type est requis."
|
||||
group: "Groupe"
|
||||
groups: "Groupes"
|
||||
all: "Tous"
|
||||
transversal_all_groups: "Transversal (tout les groupes)"
|
||||
group_is_required: "Le groupe est requis."
|
||||
number_of_periods: "Nombre de périodes"
|
||||
|
@ -162,6 +162,8 @@ pt:
|
||||
standard: "Standard"
|
||||
type_is_required: "Tipo é obrigatório."
|
||||
group: "Grupo"
|
||||
groups: "Grupos"
|
||||
all: "Todos"
|
||||
transversal_all_groups: "Transversal (todos os grupos)"
|
||||
group_is_required: "Grupo é obrigatório."
|
||||
number_of_periods: "Número de períodos"
|
||||
|
@ -162,6 +162,8 @@ zu:
|
||||
standard: "crwdns9649:0crwdne9649:0"
|
||||
type_is_required: "crwdns9651:0crwdne9651:0"
|
||||
group: "crwdns9653:0crwdne9653:0"
|
||||
groups: "crwdns20894:0crwdne20894:0"
|
||||
all: "crwdns20896:0crwdne20896:0"
|
||||
transversal_all_groups: "crwdns9655:0crwdne9655:0"
|
||||
group_is_required: "crwdns9657:0crwdne9657:0"
|
||||
number_of_periods: "crwdns9659:0crwdne9659:0"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "fab-manager",
|
||||
"version": "4.5.6",
|
||||
"version": "4.5.7",
|
||||
"description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.",
|
||||
"keywords": [
|
||||
"fablab",
|
||||
|
Loading…
x
Reference in New Issue
Block a user