1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-18 07:52:23 +01:00

(ui) option to disable the machines module

This commit is contained in:
Sylvain 2022-05-11 11:54:00 +02:00
parent 249285ea51
commit ac1d518ddc
20 changed files with 292 additions and 271 deletions

View File

@ -2,6 +2,7 @@
## next deploy ## next deploy
- Option to disable the 'machines' module
- Ability to define social networks for the FabLab "about page" - Ability to define social networks for the FabLab "about page"
- Support for OpenID Connect in Sign-Sign-On authentication providers - Support for OpenID Connect in Sign-Sign-On authentication providers
- ICS file attached to the reservation notification email - ICS file attached to the reservation notification email
@ -20,10 +21,12 @@
- Webpack overlay will now report eslint issues - Webpack overlay will now report eslint issues
- Linted all code according to eslint rules - Linted all code according to eslint rules
- when generating an avoir, the option "by_wallet" is not present anymore if wallet module is off - when generating an avoir, the option "by_wallet" is not present anymore if wallet module is off
- Fix a bug: when enabled, the statistics module is still not shown in the menu
- Fix a bug: Refused to connect to 'wss://localhost:3035/ws' when using a https tunnel in development mode - Fix a bug: Refused to connect to 'wss://localhost:3035/ws' when using a https tunnel in development mode
- Fix a bug: edge case of birthday in the future in seeds.rb, we should use Date.current instead of DateTime.current since birthday is a date (see https://github.com/sleede/fab-manager/issues/344) - Fix a bug: edge case of birthday in the future in seeds.rb, we should use Date.current instead of DateTime.current since birthday is a date (see https://github.com/sleede/fab-manager/issues/344)
- Fix a security issue: updated ruby to 2.6.10 to fix [CVE-2022-28739](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-28739) - Fix a security issue: updated ruby to 2.6.10 to fix [CVE-2022-28739](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-28739)
- Fix a security issue: updated rails to 5.2.7.1 to fix [CVE-2022-22577](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-22577) and [CVE-2022-27777](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27777) - Fix a security issue: updated rails to 5.2.7.1 to fix [CVE-2022-22577](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-22577) and [CVE-2022-27777](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27777)
- [TODO DEPLOY] `rails db:seed`
## v5.3.13 2022 May 02 ## v5.3.13 2022 May 02

View File

@ -621,7 +621,7 @@ Application.Controllers.controller('CreateEventModalController', ['$scope', '$ui
$scope.availability = { $scope.availability = {
start_at: start, start_at: start,
end_at: end, end_at: end,
available_type: 'machines', // default available_type: $scope.$root.modules.machines ? 'machines' : undefined, // default to machines if enabled
tag_ids: [], tag_ids: [],
is_recurrent: false, is_recurrent: false,
period: 'week', period: 'week',
@ -927,6 +927,9 @@ Application.Controllers.controller('CreateEventModalController', ['$scope', '$ui
* Initialize some settings, depending on the availability type, before continuing to step 2 (select a machine/training/space) * Initialize some settings, depending on the availability type, before continuing to step 2 (select a machine/training/space)
*/ */
const validateType = function () { const validateType = function () {
if ($scope.availability.available_type === null || $scope.availability.available_type === undefined) {
return growl.error(_t('app.admin.calendar.select_type'));
}
$scope.setNbTotalPlaces(); $scope.setNbTotalPlaces();
if ($scope.availability.available_type === 'training') { if ($scope.availability.available_type === 'training') {
$scope.availability.slot_duration = undefined; $scope.availability.slot_duration = undefined;

View File

@ -125,7 +125,8 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
$scope.hiddenTab = function (tab) { $scope.hiddenTab = function (tab) {
if (tab.graph) { if (tab.graph) {
return !((tab.es_type_key === 'subscription' && !$rootScope.modules.plans) || return !((tab.es_type_key === 'subscription' && !$rootScope.modules.plans) ||
(tab.es_type_key === 'training' && !$rootScope.modules.trainings)); (tab.es_type_key === 'training' && !$rootScope.modules.trainings) ||
(tab.es_type_key === 'machine' && !$rootScope.modules.machines));
} }
return false; return false;
}; };

View File

@ -685,6 +685,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
placement: 'bottom' placement: 'bottom'
}); });
} }
if ($scope.$root.modules.machines) {
uitour.createStep({ uitour.createStep({
selector: '.plans-pricing .machines-tab', selector: '.plans-pricing .machines-tab',
stepId: 'machines', stepId: 'machines',
@ -693,6 +694,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
content: _t('app.admin.tour.pricing.machines.content'), content: _t('app.admin.tour.pricing.machines.content'),
placement: 'bottom' placement: 'bottom'
}); });
}
if ($scope.$root.modules.spaces) { if ($scope.$root.modules.spaces) {
uitour.createStep({ uitour.createStep({
selector: '.plans-pricing .spaces-tab', selector: '.plans-pricing .spaces-tab',

View File

@ -186,7 +186,8 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
if (tab.table) { if (tab.table) {
return ((tab.es_type_key === 'subscription' && !$rootScope.modules.plans) || return ((tab.es_type_key === 'subscription' && !$rootScope.modules.plans) ||
(tab.es_type_key === 'training' && !$rootScope.modules.trainings) || (tab.es_type_key === 'training' && !$rootScope.modules.trainings) ||
(tab.es_type_key === 'space' && !$rootScope.modules.spaces) (tab.es_type_key === 'space' && !$rootScope.modules.spaces) ||
(tab.es_type_key === 'machine' && !$rootScope.modules.machines)
); );
} else { } else {
return true; return true;

View File

@ -23,12 +23,30 @@ Application.Controllers.controller('MainNavController', ['$scope', 'settingsProm
class: 'home-link' class: 'home-link'
}, },
{ class: 'menu-spacer' }, { class: 'menu-spacer' },
{ $scope.$root.modules.publicAgenda && {
state: 'app.public.calendar',
linkText: 'app.public.common.public_calendar',
linkIcon: 'calendar',
class: 'public-calendar-link'
},
$scope.$root.modules.machines && {
state: 'app.public.machines_list', state: 'app.public.machines_list',
linkText: 'app.public.common.reserve_a_machine', linkText: 'app.public.common.reserve_a_machine',
linkIcon: 'cogs', linkIcon: 'cogs',
class: 'reserve-machine-link' class: 'reserve-machine-link'
}, },
$scope.$root.modules.trainings && {
state: 'app.public.trainings_list',
linkText: 'app.public.common.trainings_registrations',
linkIcon: 'graduation-cap',
class: 'reserve-training-link'
},
$scope.$root.modules.spaces && {
state: 'app.public.spaces_list',
linkText: 'app.public.common.reserve_a_space',
linkIcon: 'rocket',
class: 'reserve-space-link'
},
{ {
state: 'app.public.events_list', state: 'app.public.events_list',
linkText: 'app.public.common.events_registrations', linkText: 'app.public.common.events_registrations',
@ -42,60 +60,40 @@ Application.Controllers.controller('MainNavController', ['$scope', 'settingsProm
linkIcon: 'th', linkIcon: 'th',
class: 'projects-gallery-link' class: 'projects-gallery-link'
}, },
{ class: 'menu-spacer' } $scope.$root.modules.plans && { class: 'menu-spacer' },
$scope.$root.modules.plans && {
];
if ($scope.$root.modules.plans) {
$scope.navLinks.push({
state: 'app.public.plans', state: 'app.public.plans',
linkText: 'app.public.common.subscriptions', linkText: 'app.public.common.subscriptions',
linkIcon: 'credit-card', linkIcon: 'credit-card',
class: 'plans-link' class: 'plans-link'
});
}
if ($scope.$root.modules.trainings) {
$scope.navLinks.splice(4, 0, {
state: 'app.public.trainings_list',
linkText: 'app.public.common.trainings_registrations',
linkIcon: 'graduation-cap',
class: 'reserve-training-link'
});
}
if ($scope.$root.modules.spaces) {
$scope.navLinks.splice(4, 0, {
state: 'app.public.spaces_list',
linkText: 'app.public.common.reserve_a_space',
linkIcon: 'rocket',
class: 'reserve-space-link'
});
}
if ($scope.$root.modules.publicAgenda) {
$scope.navLinks.splice(2, 0, {
state: 'app.public.calendar',
linkText: 'app.public.common.public_calendar',
linkIcon: 'calendar',
class: 'public-calendar-link'
});
} }
].filter(Boolean);
Fablab.adminNavLinks = Fablab.adminNavLinks || []; Fablab.adminNavLinks = Fablab.adminNavLinks || [];
const adminNavLinks = [ $scope.adminNavLinks = [
{ {
state: 'app.admin.calendar', state: 'app.admin.calendar',
linkText: 'app.public.common.manage_the_calendar', linkText: 'app.public.common.manage_the_calendar',
linkIcon: 'calendar', linkIcon: 'calendar',
authorizedRoles: ['admin', 'manager'] authorizedRoles: ['admin', 'manager']
}, },
{ $scope.$root.modules.machines && {
state: 'app.public.machines_list', state: 'app.public.machines_list',
linkText: 'app.public.common.manage_the_machines', linkText: 'app.public.common.manage_the_machines',
linkIcon: 'cogs', linkIcon: 'cogs',
authorizedRoles: ['admin', 'manager'] authorizedRoles: ['admin', 'manager']
}, },
$scope.$root.modules.trainings && {
state: 'app.admin.trainings',
linkText: 'app.public.common.trainings_monitoring',
linkIcon: 'graduation-cap',
authorizedRoles: ['admin', 'manager']
},
$scope.$root.modules.spaces && {
state: 'app.public.spaces_list',
linkText: 'app.public.common.manage_the_spaces',
linkIcon: 'rocket'
},
{ {
state: 'app.admin.events', state: 'app.admin.events',
linkText: 'app.public.common.manage_the_events', linkText: 'app.public.common.manage_the_events',
@ -121,6 +119,12 @@ Application.Controllers.controller('MainNavController', ['$scope', 'settingsProm
linkIcon: 'file-pdf-o', linkIcon: 'file-pdf-o',
authorizedRoles: ['admin', 'manager'] authorizedRoles: ['admin', 'manager']
}, },
$scope.$root.modules.statistics && {
state: 'app.admin.statistics',
linkText: 'app.public.common.statistics',
linkIcon: 'bar-chart-o',
authorizedRoles: ['admin']
},
{ {
class: 'menu-spacer', class: 'menu-spacer',
authorizedRoles: ['admin'] authorizedRoles: ['admin']
@ -143,35 +147,7 @@ Application.Controllers.controller('MainNavController', ['$scope', 'settingsProm
linkIcon: 'cloud', linkIcon: 'cloud',
authorizedRoles: ['admin'] authorizedRoles: ['admin']
} }
].concat(Fablab.adminNavLinks); ].filter(Boolean).concat(Fablab.adminNavLinks);
$scope.adminNavLinks = adminNavLinks;
if ($scope.$root.modules.trainings) {
$scope.adminNavLinks.splice(3, 0, {
state: 'app.admin.trainings',
linkText: 'app.public.common.trainings_monitoring',
linkIcon: 'graduation-cap',
authorizedRoles: ['admin', 'manager']
});
}
if ($scope.$root.modules.spaces) {
$scope.adminNavLinks.splice(3, 0, {
state: 'app.public.spaces_list',
linkText: 'app.public.common.manage_the_spaces',
linkIcon: 'rocket'
});
}
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',
authorizedRoles: ['admin']
});
}
/** /**
* Returns the current state of the public registration setting (allowed/blocked). * Returns the current state of the public registration setting (allowed/blocked).

View File

@ -132,7 +132,8 @@ export enum SettingName {
SocialsEchosciences = 'echosciences', SocialsEchosciences = 'echosciences',
SocialsPinterest = 'pinterest', SocialsPinterest = 'pinterest',
SocialsLastfm = 'lastfm', SocialsLastfm = 'lastfm',
SocialsFlickr = 'flickr' SocialsFlickr = 'flickr',
MachinesModule = 'machines_module',
} }
export type SettingValue = string|boolean|number; export type SettingValue = string|boolean|number;

View File

@ -27,7 +27,7 @@ angular.module('application.router', ['ui.router'])
logoFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'logo-file' }).$promise; }], logoFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'logo-file' }).$promise; }],
logoBlackFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'logo-black-file' }).$promise; }], logoBlackFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'logo-black-file' }).$promise; }],
sharedTranslations: ['Translations', function (Translations) { return Translations.query(['app.shared', 'app.public.common']).$promise; }], sharedTranslations: ['Translations', function (Translations) { return Translations.query(['app.shared', 'app.public.common']).$promise; }],
modulesPromise: ['Setting', function (Setting) { return Setting.query({ names: "['spaces_module', 'plans_module', 'invoicing_module', 'wallet_module', 'statistics_module', 'trainings_module', 'public_agenda_module']" }).$promise; }], modulesPromise: ['Setting', function (Setting) { return Setting.query({ names: "['machines_module', 'spaces_module', 'plans_module', 'invoicing_module', 'wallet_module', 'statistics_module', 'trainings_module', 'public_agenda_module']" }).$promise; }],
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['public_registrations']" }).$promise; }] settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['public_registrations']" }).$promise; }]
}, },
onEnter: ['$rootScope', 'logoFile', 'logoBlackFile', 'modulesPromise', 'CSRF', function ($rootScope, logoFile, logoBlackFile, modulesPromise, CSRF) { onEnter: ['$rootScope', 'logoFile', 'logoBlackFile', 'modulesPromise', 'CSRF', function ($rootScope, logoFile, logoBlackFile, modulesPromise, CSRF) {
@ -37,6 +37,7 @@ angular.module('application.router', ['ui.router'])
$rootScope.logo = logoFile.custom_asset; $rootScope.logo = logoFile.custom_asset;
$rootScope.logoBlack = logoBlackFile.custom_asset; $rootScope.logoBlack = logoBlackFile.custom_asset;
$rootScope.modules = { $rootScope.modules = {
machines: (modulesPromise.machines_module === 'true'),
spaces: (modulesPromise.spaces_module === 'true'), spaces: (modulesPromise.spaces_module === 'true'),
plans: (modulesPromise.plans_module === 'true'), plans: (modulesPromise.plans_module === 'true'),
trainings: (modulesPromise.trainings_module === 'true'), trainings: (modulesPromise.trainings_module === 'true'),
@ -1071,7 +1072,7 @@ angular.module('application.router', ['ui.router'])
"'renew_pack_threshold', 'pack_only_for_subscription', 'overlapping_categories', 'public_registrations'," + "'renew_pack_threshold', 'pack_only_for_subscription', 'overlapping_categories', 'public_registrations'," +
"'extended_prices_in_same_day', 'recaptcha_site_key', 'recaptcha_secret_key', 'user_validation_required', 'user_validation_required_machine', " + "'extended_prices_in_same_day', 'recaptcha_site_key', 'recaptcha_secret_key', 'user_validation_required', 'user_validation_required_machine', " +
"'user_validation_required_training', 'user_validation_required_subscription', 'user_validation_required_space'," + "'user_validation_required_training', 'user_validation_required_subscription', 'user_validation_required_space'," +
"'user_validation_required_event', 'user_validation_required_pack', 'user_validation_required_list']" "'user_validation_required_event', 'user_validation_required_pack', 'user_validation_required_list', 'machines_module']"
}).$promise; }).$promise;
}], }],
privacyDraftsPromise: ['Setting', function (Setting) { return Setting.get({ name: 'privacy_draft', history: true }).$promise; }], privacyDraftsPromise: ['Setting', function (Setting) { return Setting.get({ name: 'privacy_draft', history: true }).$promise; }],

View File

@ -37,7 +37,7 @@
<div class="calendar-legend-group"> <div class="calendar-legend-group">
<span class="calendar-legend-item text-sm border-formation" translate>{{ 'app.admin.calendar.trainings' }}</span><br> <span class="calendar-legend-item text-sm border-formation" translate>{{ 'app.admin.calendar.trainings' }}</span><br>
<span class="calendar-legend-item text-sm border-machine" translate>{{ 'app.admin.calendar.machines' }}</span><br> <span class="calendar-legend-item text-sm border-machine" translate>{{ 'app.admin.calendar.machines' }}</span><br>
<span class="calendar-legend-item text-sm border-space" ng-show="$root.modules.spaces" translate>{{ 'app.admin.calendar.spaces' }}</span> <span class="calendar-legend-item text-sm border-space" translate>{{ 'app.admin.calendar.spaces' }}</span>
<span class="calendar-legend-item text-sm border-event" ng-show="eventsInCalendar" translate>{{ 'app.admin.calendar.events' }}</span> <span class="calendar-legend-item text-sm border-event" ng-show="eventsInCalendar" translate>{{ 'app.admin.calendar.events' }}</span>
</div> </div>
</div> </div>

View File

@ -12,7 +12,7 @@
<span translate>{{ 'app.admin.calendar.training' }}</span> <span translate>{{ 'app.admin.calendar.training' }}</span>
</label> </label>
</div> </div>
<div class="radio"> <div class="radio" ng-show="$root.modules.machines">
<label> <label>
<input type="radio" id="machine" name="available_type" value="machines" ng-model="availability.available_type"> <input type="radio" id="machine" name="available_type" value="machines" ng-model="availability.available_type">
<span translate>{{ 'app.admin.calendar.machine' }}</span> <span translate>{{ 'app.admin.calendar.machine' }}</span>
@ -24,6 +24,9 @@
<span translate>{{ 'app.admin.calendar.space' }}</span> <span translate>{{ 'app.admin.calendar.space' }}</span>
</label> </label>
</div> </div>
<div class="alert alert-warning" ng-hide="$root.modules.spaces || $root.modules.machines || $root.modules.trainings">
<span translate>{{ 'app.admin.calendar.no_modules_available' }}</span>
</div>
</div> </div>
</div> </div>
<div class="modal-body" ng-show="step === 2"> <div class="modal-body" ng-show="step === 2">

View File

@ -52,6 +52,8 @@
<option value=""></option> <option value=""></option>
</select> </select>
</div> </div>
<div ng-show="$root.modules.machines">
<h3 translate>{{ 'app.admin.plans.edit.machines' }}</h3> <h3 translate>{{ 'app.admin.plans.edit.machines' }}</h3>
<table class="table"> <table class="table">
<thead> <thead>
@ -72,9 +74,11 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
<h3 ng-show="$root.modules.spaces" translate>{{ 'app.admin.plans.edit.spaces' }}</h3> <div ng-show="$root.modules.spaces">
<table class="table" ng-show="$root.modules.spaces"> <h3 translate>{{ 'app.admin.plans.edit.spaces' }}</h3>
<table class="table">
<thead> <thead>
<th translate>{{ 'app.admin.plans.edit.space' }}</th> <th translate>{{ 'app.admin.plans.edit.space' }}</th>
<th translate>{{ 'app.admin.plans.edit.hourly_rate' }}</th> <th translate>{{ 'app.admin.plans.edit.hourly_rate' }}</th>
@ -93,6 +97,7 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
<ul> <ul>
<li ng-repeat="(key, errors) in planForm.$error track by $index"> <strong>{{ key }}</strong> errors <li ng-repeat="(key, errors) in planForm.$error track by $index"> <strong>{{ key }}</strong> errors
<ul> <ul>

View File

@ -1,3 +1,4 @@
<div ng-show="$root.modules.trainings">
<h2 class="m-t-lg" translate>{{ 'app.admin.pricing.trainings' }}</h2> <h2 class="m-t-lg" translate>{{ 'app.admin.pricing.trainings' }}</h2>
<table class="table"> <table class="table">
<thead> <thead>
@ -42,7 +43,9 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
<div ng-show="$root.modules.machines">
<h2 class="m-t-lg" translate>{{ 'app.admin.pricing.machines' }}</h2> <h2 class="m-t-lg" translate>{{ 'app.admin.pricing.machines' }}</h2>
<div class="btn-group m-t-md m-b-md"> <div class="btn-group m-t-md m-b-md">
<button type="button" class="btn btn-warning" ng-click="addMachineCredit($event)" translate>{{ 'app.admin.pricing.add_a_machine_credit' }}</button> <button type="button" class="btn btn-warning" ng-click="addMachineCredit($event)" translate>{{ 'app.admin.pricing.add_a_machine_credit' }}</button>
@ -95,12 +98,14 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
<h2 ng-show="$root.modules.spaces" class="m-t-lg" translate>{{ 'app.admin.pricing.spaces' }}</h2> <div ng-show="$root.modules.spaces">
<div ng-show="$root.modules.spaces" class="btn-group m-t-md m-b-md"> <h2 class="m-t-lg" translate>{{ 'app.admin.pricing.spaces' }}</h2>
<div class="btn-group m-t-md m-b-md">
<button type="button" class="btn btn-warning" ng-click="addSpaceCredit($event)" translate>{{ 'app.admin.pricing.add_a_space_credit' }}</button> <button type="button" class="btn btn-warning" ng-click="addSpaceCredit($event)" translate>{{ 'app.admin.pricing.add_a_space_credit' }}</button>
</div> </div>
<table ng-show="$root.modules.spaces" class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
<th style="width:20%" translate>{{ 'app.admin.pricing.space' }}</th> <th style="width:20%" translate>{{ 'app.admin.pricing.space' }}</th>
@ -147,3 +152,4 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>

View File

@ -40,7 +40,7 @@
<ng-include src="'/admin/pricing/trainings.html'"></ng-include> <ng-include src="'/admin/pricing/trainings.html'"></ng-include>
</uib-tab> </uib-tab>
<uib-tab heading="{{ 'app.admin.pricing.machine_hours' | translate }}" index="2" class="machines-tab"> <uib-tab heading="{{ 'app.admin.pricing.machine_hours' | translate }}" ng-show="$root.modules.machines" index="2" class="machines-tab">
<ng-include src="'/admin/pricing/machine_hours.html'"></ng-include> <ng-include src="'/admin/pricing/machine_hours.html'"></ng-include>
</uib-tab> </uib-tab>

View File

@ -46,7 +46,7 @@
<div class="row"> <div class="row">
<div class="col-md-3"> <div class="col-md-3" ng-show="$root.modules.machines">
<h4 translate>{{ 'app.admin.settings.message_of_the_machine_booking_page' }}</h4> <h4 translate>{{ 'app.admin.settings.message_of_the_machine_booking_page' }}</h4>
<div ng-model="machineExplicationsAlert.value" <div ng-model="machineExplicationsAlert.value"
medium-editor medium-editor
@ -59,7 +59,7 @@
</div> </div>
<button name="button" class="btn btn-warning" ng-click="save(machineExplicationsAlert)" translate>{{ 'app.shared.buttons.save' }}</button> <button name="button" class="btn btn-warning" ng-click="save(machineExplicationsAlert)" translate>{{ 'app.shared.buttons.save' }}</button>
</div> </div>
<div class="col-md-3"> <div class="col-md-3" ng-show="$root.modules.trainings">
<h4 translate>{{ 'app.admin.settings.warning_message_of_the_training_booking_page'}}</h4> <h4 translate>{{ 'app.admin.settings.warning_message_of_the_training_booking_page'}}</h4>
<div ng-model="trainingExplicationsAlert.value" <div ng-model="trainingExplicationsAlert.value"
medium-editor medium-editor
@ -72,7 +72,7 @@
</div> </div>
<button name="button" class="btn btn-warning" ng-click="save(trainingExplicationsAlert)" translate>{{ 'app.shared.buttons.save' }}</button> <button name="button" class="btn btn-warning" ng-click="save(trainingExplicationsAlert)" translate>{{ 'app.shared.buttons.save' }}</button>
</div> </div>
<div class="col-md-3"> <div class="col-md-3" ng-show="$root.modules.trainings">
<h4 translate>{{ 'app.admin.settings.information_message_of_the_training_reservation_page'}}</h4> <h4 translate>{{ 'app.admin.settings.information_message_of_the_training_reservation_page'}}</h4>
<div ng-model="trainingInformationMessage.value" <div ng-model="trainingInformationMessage.value"
medium-editor medium-editor
@ -85,7 +85,7 @@
</div> </div>
<button name="button" class="btn btn-warning" ng-click="save(trainingInformationMessage)" translate>{{ 'app.shared.buttons.save' }}</button> <button name="button" class="btn btn-warning" ng-click="save(trainingInformationMessage)" translate>{{ 'app.shared.buttons.save' }}</button>
</div> </div>
<div class="col-md-3"> <div class="col-md-3" ng-show="$root.modules.plans">
<h4 translate>{{ 'app.admin.settings.message_of_the_subscriptions_page' }}</h4> <h4 translate>{{ 'app.admin.settings.message_of_the_subscriptions_page' }}</h4>
<div ng-model="subscriptionExplicationsAlert.value" <div ng-model="subscriptionExplicationsAlert.value"
medium-editor medium-editor
@ -109,7 +109,7 @@
</div> </div>
<button name="button" class="btn btn-warning" ng-click="save(eventExplicationsAlert)" translate>{{ 'app.shared.buttons.save' }}</button> <button name="button" class="btn btn-warning" ng-click="save(eventExplicationsAlert)" translate>{{ 'app.shared.buttons.save' }}</button>
</div> </div>
<div class="col-md-3" ng-show="$root.modules.spaces"> <div class="col-md-3" ng-show="$root.modules.spaces" ng-show="$root.modules.spaces">
<h4 translate>{{ 'app.admin.settings.message_of_the_spaces_page' }}</h4> <h4 translate>{{ 'app.admin.settings.message_of_the_spaces_page' }}</h4>
<div ng-model="spaceExplicationsAlert.value" <div ng-model="spaceExplicationsAlert.value"
medium-editor medium-editor
@ -340,7 +340,7 @@
</div> </div>
</div> </div>
<div class="panel panel-default m-t-lg"> <div class="panel panel-default m-t-lg" ng-show="$root.modules.machines">
<div class="panel-heading"> <div class="panel-heading">
<span class="font-sbold" translate>{{ 'app.admin.settings.general.elements_ordering' }}</span> <span class="font-sbold" translate>{{ 'app.admin.settings.general.elements_ordering' }}</span>
</div> </div>
@ -489,6 +489,14 @@
</div> </div>
<div class="panel-body"> <div class="panel-body">
<p class="alert alert-info"><i class="fa fa-info-circle m-r"></i><span translate>{{ 'app.admin.settings.remember_to_refresh_the_page_for_the_changes_to_take_effect' }}</span> </p> <p class="alert alert-info"><i class="fa fa-info-circle m-r"></i><span translate>{{ 'app.admin.settings.remember_to_refresh_the_page_for_the_changes_to_take_effect' }}</span> </p>
<div class="row">
<h3 class="m-l" translate>{{ 'app.admin.settings.machines' }}</h3>
<p class="alert alert-warning m-h-md" ng-bind-html="'app.admin.settings.machines_info_html' | translate"></p>
<boolean-setting name="machines_module"
settings="allSettings"
label="app.admin.settings.enable_machines"
classes="m-l"></boolean-setting>
</div>
<div class="row"> <div class="row">
<h3 class="m-l" translate>{{ 'app.admin.settings.spaces' }}</h3> <h3 class="m-l" translate>{{ 'app.admin.settings.spaces' }}</h3>
<p class="alert alert-warning m-h-md" ng-bind-html="'app.admin.settings.spaces_info_html' | translate"></p> <p class="alert alert-warning m-h-md" ng-bind-html="'app.admin.settings.spaces_info_html' | translate"></p>

View File

@ -175,7 +175,7 @@
<span class="font-sbold" translate>{{ 'app.admin.settings.display' }}</span> <span class="font-sbold" translate>{{ 'app.admin.settings.display' }}</span>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<div class="row"> <div class="row" ng-show="$root.modules.machines">
<h3 class="m-l" translate>{{ 'app.admin.settings.display_machine_reservation_user_name' }}</h3> <h3 class="m-l" translate>{{ 'app.admin.settings.display_machine_reservation_user_name' }}</h3>
<p class="alert alert-warning m-h-md" ng-bind-html="'app.admin.settings.display_name_info_html' | translate"></p> <p class="alert alert-warning m-h-md" ng-bind-html="'app.admin.settings.display_name_info_html' | translate"></p>
<boolean-setting name="display_name_enable" <boolean-setting name="display_name_enable"

View File

@ -143,7 +143,8 @@ class Setting < ApplicationRecord
echosciences echosciences
pinterest pinterest
lastfm lastfm
flickr] } flickr
machines_module] }
# WARNING: when adding a new key, you may also want to add it in: # WARNING: when adding a new key, you may also want to add it in:
# - config/locales/en.yml#settings # - config/locales/en.yml#settings
# - app/frontend/src/javascript/models/setting.ts#SettingName # - app/frontend/src/javascript/models/setting.ts#SettingName

View File

@ -32,6 +32,7 @@
<script type="text/javascript"> <script type="text/javascript">
var Fablab = Fablab || {}; var Fablab = Fablab || {};
Fablab.machinesModule = ('<%= Setting.get('machines_module') %>' === 'true');
Fablab.plansModule = ('<%= Setting.get('plans_module') %>' === 'true'); Fablab.plansModule = ('<%= Setting.get('plans_module') %>' === 'true');
Fablab.spacesModule = ('<%= Setting.get('spaces_module') %>' === 'true'); Fablab.spacesModule = ('<%= Setting.get('spaces_module') %>' === 'true');
Fablab.trainingsModule = ('<%= Setting.get('trainings_module') %>' === 'true'); Fablab.trainingsModule = ('<%= Setting.get('trainings_module') %>' === 'true');

View File

@ -111,6 +111,8 @@ en:
slots_of: "of" slots_of: "of"
minutes: "minutes" minutes: "minutes"
deleted_user: "Deleted user" deleted_user: "Deleted user"
select_type: "Please select a type to continue"
no_modules_available: "No reservable module available. Please enable at least one module (machines, spaces or trainings) in the Customization section."
# import external iCal calendar # import external iCal calendar
icalendar: icalendar:
icalendar_import: "iCalendar import" icalendar_import: "iCalendar import"
@ -1360,6 +1362,10 @@ en:
duration_minutes: "Duration (in minutes)" duration_minutes: "Duration (in minutes)"
default_slot_duration_info: "Machine and space availabilities are divided in multiple slots of this duration. This value can be overridden per availability." default_slot_duration_info: "Machine and space availabilities are divided in multiple slots of this duration. This value can be overridden per availability."
modules: "Modules" modules: "Modules"
machines: "Machines"
machines_info_html: "<p>Machines are the resources which are available for booking. A machine can be, <em>for example</em>, a 3D printer or a laser cutter.</p>"
enable_machines: "Enable the machines"
machines_module: "machines module"
spaces: "Spaces" spaces: "Spaces"
spaces_info_html: "<p>A space can be, for example, a woodshop or a meeting room. Their particularity is that they can be booked by several people at the same time.</p><p><strong>Warning:</strong> It is not recommended to disable spaces if at least one space reservation was made on the system.</p>" spaces_info_html: "<p>A space can be, for example, a woodshop or a meeting room. Their particularity is that they can be booked by several people at the same time.</p><p><strong>Warning:</strong> It is not recommended to disable spaces if at least one space reservation was made on the system.</p>"
enable_spaces: "Enable the spaces" enable_spaces: "Enable the spaces"

View File

@ -581,3 +581,4 @@ en:
pinterest: "pinterest" pinterest: "pinterest"
lastfm: "lastfm" lastfm: "lastfm"
flickr: "flickr" flickr: "flickr"
machines_module: "Machines module"

View File

@ -891,6 +891,8 @@ Setting.set('wallet_module', true) unless Setting.find_by(name: 'wallet_module')
Setting.set('statistics_module', true) unless Setting.find_by(name: 'statistics_module').try(:value) Setting.set('statistics_module', true) unless Setting.find_by(name: 'statistics_module').try(:value)
Setting.set('machines_module', true) unless Setting.find_by(name: 'machines_module').try(:value)
Setting.set('upcoming_events_shown', 'until_start') unless Setting.find_by(name: 'upcoming_events_shown').try(:value) Setting.set('upcoming_events_shown', 'until_start') unless Setting.find_by(name: 'upcoming_events_shown').try(:value)
Setting.set('trainings_module', true) unless Setting.find_by(name: 'trainings_module').try(:value) Setting.set('trainings_module', true) unless Setting.find_by(name: 'trainings_module').try(:value)