1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-12-01 12:24:28 +01:00

configure the features tour display mode from the UI

This commit is contained in:
Sylvain 2020-05-27 18:49:53 +02:00
parent 3188e03319
commit 434c211ccf
27 changed files with 128 additions and 77 deletions

View File

@ -18,8 +18,8 @@
* Controller used in the calendar management page
*/
Application.Controllers.controller('AdminCalendarController', ['$scope', '$state', '$uibModal', 'moment', 'AuthService', 'Availability', 'Slot', 'Setting', 'Export', 'growl', 'dialogs', 'bookingWindowStart', 'bookingWindowEnd', 'machinesPromise', 'plansPromise', 'groupsPromise', 'slotDurationPromise', 'eventsInCalendarPromise', '_t', 'uiCalendarConfig', 'CalendarConfig', 'Member', 'uiTourService',
function ($scope, $state, $uibModal, moment, AuthService, Availability, Slot, Setting, Export, growl, dialogs, bookingWindowStart, bookingWindowEnd, machinesPromise, plansPromise, groupsPromise, slotDurationPromise, eventsInCalendarPromise, _t, uiCalendarConfig, CalendarConfig, Member, uiTourService) {
Application.Controllers.controller('AdminCalendarController', ['$scope', '$state', '$uibModal', 'moment', 'AuthService', 'Availability', 'Slot', 'Setting', 'Export', 'growl', 'dialogs', 'bookingWindowStart', 'bookingWindowEnd', 'machinesPromise', 'plansPromise', 'groupsPromise', 'settingsPromise', '_t', 'uiCalendarConfig', 'CalendarConfig', 'Member', 'uiTourService',
function ($scope, $state, $uibModal, moment, AuthService, Availability, Slot, Setting, Export, growl, dialogs, bookingWindowStart, bookingWindowEnd, machinesPromise, plansPromise, groupsPromise, settingsPromise, _t, uiCalendarConfig, CalendarConfig, Member, uiTourService) {
/* PRIVATE STATIC CONSTANTS */
// The calendar is divided in slots of 30 minutes
@ -29,7 +29,7 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
const BOOKING_SNAP = '00:30:00';
// We do not allow the creation of slots that are not a multiple of 60 minutes
const SLOT_MULTIPLE = parseInt(slotDurationPromise.setting.value, 10);
const SLOT_MULTIPLE = parseInt(settingsPromise.slot_duration, 10);
/* PUBLIC SCOPE */
@ -43,7 +43,7 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
$scope.availabilityDom = null;
// Should we show the scheduled events in the calendar?
$scope.eventsInCalendar = (eventsInCalendarPromise.setting.value === 'true');
$scope.eventsInCalendar = (settingsPromise.events_in_calendar === 'true');
// bind the availabilities slots with full-Calendar events
$scope.eventSources = [];
@ -352,7 +352,7 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state
}
});
// if the user has never seen the tour, show him now
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('calendar') < 0) {
if (settingsPromise.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('calendar') < 0) {
uitour.start();
}
}

View File

@ -153,8 +153,8 @@ class EventsController {
/**
* Controller used in the events listing page (admin view)
*/
Application.Controllers.controller('AdminEventsController', ['$scope', '$state', 'dialogs', '$uibModal', 'growl', 'AuthService', 'Event', 'Category', 'EventTheme', 'AgeRange', 'PriceCategory', 'eventsPromise', 'categoriesPromise', 'themesPromise', 'ageRangesPromise', 'priceCategoriesPromise', '_t', 'Member', 'uiTourService',
function ($scope, $state, dialogs, $uibModal, growl, AuthService, Event, Category, EventTheme, AgeRange, PriceCategory, eventsPromise, categoriesPromise, themesPromise, ageRangesPromise, priceCategoriesPromise, _t, Member, uiTourService) {
Application.Controllers.controller('AdminEventsController', ['$scope', '$state', 'dialogs', '$uibModal', 'growl', 'AuthService', 'Event', 'Category', 'EventTheme', 'AgeRange', 'PriceCategory', 'eventsPromise', 'categoriesPromise', 'themesPromise', 'ageRangesPromise', 'priceCategoriesPromise', '_t', 'Member', 'uiTourService', 'settingsPromise',
function ($scope, $state, dialogs, $uibModal, growl, AuthService, Event, Category, EventTheme, AgeRange, PriceCategory, eventsPromise, categoriesPromise, themesPromise, ageRangesPromise, priceCategoriesPromise, _t, Member, uiTourService, settingsPromise) {
/* PUBLIC SCOPE */
// By default, the pagination mode is activated to limit the page size
@ -465,7 +465,7 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state',
}
});
// if the user has never seen the tour, show him now
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('events') < 0) {
if (settingsPromise.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('events') < 0) {
uitour.start();
}
}

View File

@ -711,7 +711,7 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
}
});
// if the user has never seen the tour, show him now
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('invoices') < 0) {
if (settings.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('invoices') < 0) {
uitour.start();
}
}

View File

@ -126,8 +126,8 @@ class MembersController {
/**
* Controller used in the members/groups management page
*/
Application.Controllers.controller('AdminMembersController', ['$scope', '$sce', '$uibModal', 'membersPromise', 'adminsPromise', 'partnersPromise', 'managersPromise', 'growl', 'Admin', 'AuthService', 'dialogs', '_t', 'Member', 'Export', 'User', 'uiTourService',
function ($scope, $sce, $uibModal, membersPromise, adminsPromise, partnersPromise, managersPromise, growl, Admin, AuthService, dialogs, _t, Member, Export, User, uiTourService) {
Application.Controllers.controller('AdminMembersController', ['$scope', '$sce', '$uibModal', 'membersPromise', 'adminsPromise', 'partnersPromise', 'managersPromise', 'growl', 'Admin', 'AuthService', 'dialogs', '_t', 'Member', 'Export', 'User', 'uiTourService', 'settingsPromise',
function ($scope, $sce, $uibModal, membersPromise, adminsPromise, partnersPromise, managersPromise, growl, Admin, AuthService, dialogs, _t, Member, Export, User, uiTourService, settingsPromise) {
/* PRIVATE STATIC CONSTANTS */
// number of users loaded each time we click on 'load more...'
@ -567,7 +567,7 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
}
});
// if the user has never seen the tour, show him now
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('members') < 0) {
if (settingsPromise.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('members') < 0) {
uitour.start();
}
}

View File

@ -10,8 +10,8 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clientsPromise', 'growl', 'OpenAPIClient', 'dialogs', '_t', 'Member', 'uiTourService',
function ($scope, clientsPromise, growl, OpenAPIClient, dialogs, _t, Member, uiTourService) {
Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clientsPromise', 'settingsPromise', 'growl', 'OpenAPIClient', 'dialogs', '_t', 'Member', 'uiTourService',
function ($scope, clientsPromise, settingsPromise, growl, OpenAPIClient, dialogs, _t, Member, uiTourService) {
/* PUBLIC SCOPE */
// clients list
@ -149,7 +149,7 @@ Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clien
}
});
// if the user has never seen the tour, and if the display behavior is not configured to manual triggering only, show the tour now
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('open-api') < 0) {
if (settingsPromise.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('open-api') < 0) {
uitour.start();
}
};

View File

@ -18,8 +18,8 @@
/**
* Controller used in the prices edition page
*/
Application.Controllers.controller('EditPricingController', ['$scope', '$state', '$uibModal', '$filter', 'TrainingsPricing', 'Credit', 'Pricing', 'Plan', 'Coupon', 'plans', 'groups', 'growl', 'machinesPricesPromise', 'Price', 'dialogs', 'trainingsPricingsPromise', 'trainingsPromise', 'machineCreditsPromise', 'machinesPromise', 'trainingCreditsPromise', 'couponsPromise', 'spacesPromise', 'spacesPricesPromise', 'spacesCreditsPromise', 'slotDurationPromise', '_t', 'Member', 'uiTourService',
function ($scope, $state, $uibModal, $filter, TrainingsPricing, Credit, Pricing, Plan, Coupon, plans, groups, growl, machinesPricesPromise, Price, dialogs, trainingsPricingsPromise, trainingsPromise, machineCreditsPromise, machinesPromise, trainingCreditsPromise, couponsPromise, spacesPromise, spacesPricesPromise, spacesCreditsPromise, slotDurationPromise, _t, Member, uiTourService) {
Application.Controllers.controller('EditPricingController', ['$scope', '$state', '$uibModal', '$filter', 'TrainingsPricing', 'Credit', 'Pricing', 'Plan', 'Coupon', 'plans', 'groups', 'growl', 'machinesPricesPromise', 'Price', 'dialogs', 'trainingsPricingsPromise', 'trainingsPromise', 'machineCreditsPromise', 'machinesPromise', 'trainingCreditsPromise', 'couponsPromise', 'spacesPromise', 'spacesPricesPromise', 'spacesCreditsPromise', 'settingsPromise', '_t', 'Member', 'uiTourService',
function ($scope, $state, $uibModal, $filter, TrainingsPricing, Credit, Pricing, Plan, Coupon, plans, groups, growl, machinesPricesPromise, Price, dialogs, trainingsPricingsPromise, trainingsPromise, machineCreditsPromise, machinesPromise, trainingCreditsPromise, couponsPromise, spacesPromise, spacesPricesPromise, spacesCreditsPromise, settingsPromise, _t, Member, uiTourService) {
/* PUBLIC SCOPE */
// List of machines prices (not considering any plan)
@ -77,7 +77,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
$scope.planFiltering = 'enabled';
// Default duration for the slots
$scope.slotDuration = parseInt(slotDurationPromise.setting.value, 10);
$scope.slotDuration = parseInt(settingsPromise.slot_duration, 10);
// Available options for filtering plans by status
$scope.filterDisabled = [
@ -730,7 +730,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
}
});
// if the user has never seen the tour, show him now
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('pricing') < 0) {
if (settingsPromise.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('pricing') < 0) {
uitour.start();
}
}

View File

@ -12,8 +12,8 @@
*/
'use strict';
Application.Controllers.controller('ProjectElementsController', ['$scope', '$state', 'Component', 'Licence', 'Theme', 'componentsPromise', 'licencesPromise', 'themesPromise', '_t', 'Member', 'uiTourService',
function ($scope, $state, Component, Licence, Theme, componentsPromise, licencesPromise, themesPromise, _t, Member, uiTourService) {
Application.Controllers.controller('ProjectElementsController', ['$scope', '$state', 'Component', 'Licence', 'Theme', 'componentsPromise', 'licencesPromise', 'themesPromise', '_t', 'Member', 'uiTourService', 'settingsPromise',
function ($scope, $state, Component, Licence, Theme, componentsPromise, licencesPromise, themesPromise, _t, Member, uiTourService, settingsPromise) {
// Materials list (plastic, wood ...)
$scope.components = componentsPromise;
@ -198,7 +198,7 @@ Application.Controllers.controller('ProjectElementsController', ['$scope', '$sta
}
});
// if the user has never seen the tour, show him now
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('project-elements') < 0) {
if (settingsPromise.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('project-elements') < 0) {
uitour.start();
}
};

View File

@ -418,7 +418,7 @@ Application.Controllers.controller('SettingsController', ['$scope', '$rootScope'
}
});
// if the user has never seen the tour, show him now
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('settings') < 0) {
if ($scope.allSettings.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('settings') < 0) {
uitour.start();
}
}
@ -473,6 +473,19 @@ Application.Controllers.controller('SettingsController', ['$scope', '$rootScope'
$scope.$watch('advancedSettings.open', function (newValue) {
if (newValue) $scope.codeMirrorEditor.refresh();
})
// use the tours list, based on the selected value
$scope.$watch('allSettings.feature_tour_display', function (newValue, oldValue, scope) {
if (newValue === oldValue) return;
if (newValue === 'session') {
$scope.currentUser.profile.tours = Fablab.sessionTours;
} else if (newValue === 'once') {
Member.get({ id: $scope.currentUser.id }, function (user) {
$scope.currentUser.profile.tours = user.profile.tours;
});
}
});
};
// init the controller (call at the end !)

View File

@ -15,8 +15,8 @@
*/
'use strict';
Application.Controllers.controller('StatisticsController', ['$scope', '$state', '$rootScope', '$uibModal', 'es', 'Member', '_t', 'membersPromise', 'statisticsPromise', 'uiTourService',
function ($scope, $state, $rootScope, $uibModal, es, Member, _t, membersPromise, statisticsPromise, uiTourService) {
Application.Controllers.controller('StatisticsController', ['$scope', '$state', '$rootScope', '$uibModal', 'es', 'Member', '_t', 'membersPromise', 'statisticsPromise', 'uiTourService', 'settingsPromise',
function ($scope, $state, $rootScope, $uibModal, es, Member, _t, membersPromise, statisticsPromise, uiTourService, settingsPromise) {
/* PRIVATE STATIC CONSTANTS */
// search window size
@ -388,7 +388,7 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
}
});
// if the user has never seen the tour, show him now
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('statistics') < 0) {
if (settingsPromise.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('statistics') < 0) {
uitour.start();
}
}

View File

@ -150,8 +150,8 @@ Application.Controllers.controller('EditTrainingController', [ '$scope', '$state
/**
* Controller used in the trainings management page, allowing admins users to see and manage the list of trainings and reservations.
*/
Application.Controllers.controller('TrainingsAdminController', ['$scope', '$state', '$uibModal', 'Training', 'trainingsPromise', 'machinesPromise', '_t', 'growl', 'dialogs', 'Member', 'uiTourService',
function ($scope, $state, $uibModal, Training, trainingsPromise, machinesPromise, _t, growl, dialogs, Member, uiTourService) {
Application.Controllers.controller('TrainingsAdminController', ['$scope', '$state', '$uibModal', 'Training', 'trainingsPromise', 'machinesPromise', '_t', 'growl', 'dialogs', 'Member', 'uiTourService', 'settingsPromise',
function ($scope, $state, $uibModal, Training, trainingsPromise, machinesPromise, _t, growl, dialogs, Member, uiTourService, settingsPromise) {
// list of trainings
$scope.trainings = trainingsPromise;
@ -398,7 +398,7 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat
}
});
// if the user has never seen the tour, show him now
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('trainings') < 0) {
if (settingsPromise.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('trainings') < 0) {
uitour.start();
}
}

View File

@ -303,7 +303,7 @@ Application.Controllers.controller('HomeController', ['$scope', '$stateParams',
}
});
// if the user has never seen the tour, show him now
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('welcome') < 0) {
if (settingsPromise.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('welcome') < 0) {
uitour.start();
}
};

View File

@ -180,8 +180,8 @@ const _reserveMachine = function (machine, e) {
/**
* Controller used in the public listing page, allowing everyone to see the list of machines
*/
Application.Controllers.controller('MachinesController', ['$scope', '$state', '_t', 'AuthService', 'Machine', '$uibModal', 'machinesPromise', 'Member', 'uiTourService',
function ($scope, $state, _t, AuthService, Machine, $uibModal, machinesPromise, Member, uiTourService) {
Application.Controllers.controller('MachinesController', ['$scope', '$state', '_t', 'AuthService', 'Machine', '$uibModal', 'machinesPromise', 'settingsPromise', 'Member', 'uiTourService',
function ($scope, $state, _t, AuthService, Machine, $uibModal, machinesPromise, settingsPromise, Member, uiTourService) {
/* PUBLIC SCOPE */
// Retrieve the list of machines
@ -281,7 +281,7 @@ Application.Controllers.controller('MachinesController', ['$scope', '$state', '_
}
});
// if the user has never seen the tour, show him now
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('machines') < 0) {
if (settingsPromise.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('machines') < 0) {
uitour.start();
}
}

View File

@ -98,8 +98,8 @@ class SpacesController {
/**
* Controller used in the public listing page, allowing everyone to see the list of spaces
*/
Application.Controllers.controller('SpacesController', ['$scope', '$state', 'spacesPromise', 'AuthService', '_t', 'Member', 'uiTourService',
function ($scope, $state, spacesPromise, AuthService, _t, Member, uiTourService) {
Application.Controllers.controller('SpacesController', ['$scope', '$state', 'spacesPromise', 'AuthService', '_t', 'Member', 'uiTourService', 'settingsPromise',
function ($scope, $state, spacesPromise, AuthService, _t, Member, uiTourService, settingsPromise) {
/* PUBLIC SCOPE */
// Retrieve the list of spaces
@ -193,7 +193,7 @@ Application.Controllers.controller('SpacesController', ['$scope', '$state', 'spa
}
});
// if the user has never seen the tour, show him now
if (Fablab.featureTourDisplay !== 'manual' && $scope.currentUser.profile.tours.indexOf('spaces') < 0) {
if (settingsPromise.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('spaces') < 0) {
uitour.start();
}
}

View File

@ -104,7 +104,7 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['home_content', 'home_blogpost', 'spaces_module']" }).$promise; }]
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['home_content', 'home_blogpost', 'spaces_module', 'feature_tour_display']" }).$promise; }]
}
})
.state('app.public.privacy', {
@ -306,7 +306,8 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }]
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['feature_tour_display']" }).$promise; }]
}
})
.state('app.admin.machines_new', {
@ -380,7 +381,8 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
spacesPromise: ['Space', function (Space) { return Space.query().$promise; }]
spacesPromise: ['Space', function (Space) { return Space.query().$promise; }],
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['feature_tour_display']" }).$promise; }]
}
})
.state('app.admin.space_new', {
@ -595,8 +597,7 @@ angular.module('application.router', ['ui.router'])
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
plansPromise: ['Plan', function (Plan) { return Plan.query().$promise; }],
groupsPromise: ['Group', function (Group) { return Group.query().$promise; }],
slotDurationPromise: ['Setting', function (Setting) { return Setting.get({ name: 'slot_duration' }).$promise; }],
eventsInCalendarPromise: ['Setting', function (Setting) { return Setting.get({ name: 'events_in_calendar' }).$promise; }]
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['slot_duration', 'events_in_calendar', 'feature_tour_display']" }).$promise; }]
}
})
.state('app.admin.calendar.icalendar', {
@ -624,7 +625,8 @@ angular.module('application.router', ['ui.router'])
resolve: {
componentsPromise: ['Component', function (Component) { return Component.query().$promise; }],
licencesPromise: ['Licence', function (Licence) { return Licence.query().$promise; }],
themesPromise: ['Theme', function (Theme) { return Theme.query().$promise; }]
themesPromise: ['Theme', function (Theme) { return Theme.query().$promise; }],
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['feature_tour_display']" }).$promise; }]
}
})
.state('app.admin.manage_abuses', {
@ -651,7 +653,8 @@ angular.module('application.router', ['ui.router'])
},
resolve: {
trainingsPromise: ['Training', function (Training) { return Training.query().$promise; }],
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }]
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }],
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['feature_tour_display']" }).$promise; }]
}
})
.state('app.admin.trainings_new', {
@ -693,7 +696,8 @@ angular.module('application.router', ['ui.router'])
categoriesPromise: ['Category', function (Category) { return Category.query().$promise; }],
themesPromise: ['EventTheme', function (EventTheme) { return EventTheme.query().$promise; }],
ageRangesPromise: ['AgeRange', function (AgeRange) { return AgeRange.query().$promise; }],
priceCategoriesPromise: ['PriceCategory', function (PriceCategory) { return PriceCategory.query().$promise; }]
priceCategoriesPromise: ['PriceCategory', function (PriceCategory) { return PriceCategory.query().$promise; }],
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['feature_tour_display']" }).$promise; }]
}
})
.state('app.admin.events_new', {
@ -763,7 +767,7 @@ angular.module('application.router', ['ui.router'])
spacesPromise: ['Space', function (Space) { return Space.query().$promise; }],
spacesPricesPromise: ['Price', function (Price) { return Price.query({ priceable_type: 'Space', plan_id: 'null' }).$promise; }],
spacesCreditsPromise: ['Credit', function (Credit) { return Credit.query({ creditable_type: 'Space' }).$promise; }],
slotDurationPromise: ['Setting', function (Setting) { return Setting.get({ name: 'slot_duration' }).$promise; }]
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['feature_tour_display', 'slot_duration']" }).$promise; }]
}
})
@ -842,7 +846,8 @@ angular.module('application.router', ['ui.router'])
'accounting_other_client_code', 'accounting_other_client_label', 'accounting_wallet_code', 'accounting_wallet_label', \
'accounting_VAT_code', 'accounting_VAT_label', 'accounting_subscription_code', 'accounting_subscription_label', \
'accounting_Machine_code', 'accounting_Machine_label', 'accounting_Training_code', 'accounting_Training_label', \
'accounting_Event_code', 'accounting_Event_label', 'accounting_Space_code', 'accounting_Space_label']` }).$promise;
'accounting_Event_code', 'accounting_Event_label', 'accounting_Space_code', 'accounting_Space_label', \
'feature_tour_display']` }).$promise;
}],
invoices: [ 'Invoice', function (Invoice) {
return Invoice.list({
@ -881,7 +886,8 @@ angular.module('application.router', ['ui.router'])
managersPromise: ['User', function (User) { return User.query({ role: 'manager' }).$promise; }],
groupsPromise: ['Group', function (Group) { return Group.query().$promise; }],
tagsPromise: ['Tag', function (Tag) { return Tag.query().$promise; }],
authProvidersPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.query().$promise; }]
authProvidersPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.query().$promise; }],
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['feature_tour_display']" }).$promise; }]
}
})
.state('app.admin.members_new', {
@ -999,7 +1005,8 @@ angular.module('application.router', ['ui.router'])
},
resolve: {
membersPromise: ['Member', function (Member) { return Member.mapping().$promise; }],
statisticsPromise: ['Statistics', function (Statistics) { return Statistics.query().$promise; }]
statisticsPromise: ['Statistics', function (Statistics) { return Statistics.query().$promise; }],
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['feature_tour_display']" }).$promise; }]
}
})
.state('app.admin.stats_graphs', {
@ -1029,7 +1036,7 @@ angular.module('application.router', ['ui.router'])
'home_blogpost', 'machine_explications_alert', 'training_explications_alert', 'slot_duration', \
'training_information_message', 'subscription_explications_alert', 'event_explications_alert', \
'space_explications_alert', 'booking_window_start', 'booking_window_end', 'events_in_calendar', \
'booking_move_enable', 'booking_move_delay', 'booking_cancel_enable', \
'booking_move_enable', 'booking_move_delay', 'booking_cancel_enable', 'feature_tour_display', \
'booking_cancel_delay', 'main_color', 'secondary_color', 'spaces_module', 'twitter_analytics', \
'fablab_name', 'name_genre', 'reminder_enable', 'plans_module', \
'reminder_delay', 'visibility_yearly', 'visibility_others', \
@ -1054,7 +1061,8 @@ angular.module('application.router', ['ui.router'])
}
},
resolve: {
clientsPromise: ['OpenAPIClient', function (OpenAPIClient) { return OpenAPIClient.query().$promise; }]
clientsPromise: ['OpenAPIClient', function (OpenAPIClient) { return OpenAPIClient.query().$promise; }],
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['feature_tour_display']" }).$promise; }]
}
});
}

View File

@ -1,6 +1,6 @@
'use strict';
Application.Services.factory('Member', ['$resource', '$q', function ($resource, $q) {
Application.Services.factory('Member', ['$resource', 'Setting', function ($resource, Setting) {
return $resource('/api/members/:id',
{ id: '@id' }, {
update: {
@ -37,11 +37,13 @@ Application.Services.factory('Member', ['$resource', '$q', function ($resource,
params: { id: '@id' },
interceptor: {
response: function (response) {
if (Fablab.featureTourDisplay === 'session') {
return Setting.query({ names: "['feature_tour_display']" }).$promise.then((settings) => {
if (settings.feature_tour_display === 'session') {
Fablab.sessionTours.push(response.data.tours[0]);
return { tours: Fablab.sessionTours };
}
return response.data;
});
}
}
},

View File

@ -338,6 +338,29 @@
</div>
</div>
<div class="panel panel-default m-t-lg">
<div class="panel-heading">
<span class="font-sbold" translate>{{ 'app.admin.settings.help' }}</span>
</div>
<div class="panel-body">
<div class="row">
<h3 class="m-l" translate>{{ 'app.admin.settings.feature_tour' }}</h3>
<p class="alert alert-warning m-h-md" ng-bind-html="'app.admin.settings.feature_tour_info_html' | translate"></p>
<div class="col-md-4">
<select-setting name="feature_tour_display"
settings="allSettings"
classes="m-l"
required="true"
label="app.admin.settings.feature_tour_display_mode"
option-1="['once', 'app.admin.settings.display_mode.once']"
option-2="['session', 'app.admin.settings.display_mode.session']"
option-3="['manual', 'app.admin.settings.display_mode.manual']">
</select-setting>
</div>
</div>
</div>
</div>
<div class="panel panel-default m-t-md">
<div class="panel-heading">
<span class="font-sbold" translate>{{ 'app.admin.settings.account_creation' }}</span>

View File

@ -192,7 +192,7 @@ class API::MembersController < API::ApiController
def complete_tour
authorize @member
if Rails.application.secrets.feature_tour_display == 'session'
if Setting.get('feature_tour_display') == 'session'
render json: { tours: [params[:tour]] }
else
tours = "#{@member.profile.tours} #{params[:tour]}"

View File

@ -87,7 +87,8 @@ class Setting < ApplicationRecord
facebook_app_id
twitter_analytics
recaptcha_site_key
recaptcha_secret_key] }
recaptcha_secret_key
feature_tour_display] }
def value
last_value = history_values.order(HistoryValue.arel_table['created_at'].desc).first
last_value&.value

View File

@ -27,7 +27,6 @@
Fablab.spacesModule = ('<%= Setting.get('spaces_module') %>' === 'true');
Fablab.withoutOnlinePayment = ('<%= Rails.application.secrets.fablab_without_online_payments %>' === 'true');
Fablab.fablabWithoutWallet = ('<%= Rails.application.secrets.fablab_without_wallet %>' === 'true');
Fablab.featureTourDisplay = "<%= Rails.application.secrets.feature_tour_display %>";
Fablab.disqusShortname = "<%= Rails.application.secrets.disqus_shortname %>";
Fablab.defaultHost = "<%= Rails.application.secrets.default_host %>";
Fablab.gaId = "<%= Setting.get('tracking_id') %>";

View File

@ -1063,6 +1063,15 @@ en:
secret_key: "Secret key"
recaptcha_site_key: "reCAPTCHA Site Key"
recaptcha_secret_key: "reCAPTCHA Secret Key"
help: "Help"
feature_tour: "Feature tour"
feature_tour_info_html: "<p>When an administrator or a manager in logged-in, a feature tour will be triggered the first time he/she visits each section of the application. You can change this behavior to one of the following values:</p><ul><li>« Once » to keep the default behavior.</li><li>« By session » to display the tours each time you reopen the application.</li><li>« Manual trigger » to prevent displaying the tours automatically. It'll still be possible to trigger them by pressing the F1 key or by clicking on « Help » in the user's menu.</li></ul>"
feature_tour_display_mode: "Feature tour display mode"
feature_tour_display: "feature tour display"
display_mode:
once: "Once"
session: "By session"
manual: "Manual trigger"
sort_by:
default: "Default"
name: "Name"

View File

@ -1063,6 +1063,15 @@ fr:
secret_key: "Clef secrète"
recaptcha_site_key: "clef de site reCAPTCHA"
recaptcha_secret_key: "clef secrète reCAPTCHA"
help: "Aide"
feature_tour: "Visite guidée des fonctionnalités"
feature_tour_info_html: "<p>Lorsque un administrateur ou un gestionnaire est connecté, une visite guidée des fonctionnalités se déclenchera lors de la première visite de chaque section de l'application. Vous pouvez modifier ce comportement pour une des valeur suivantes :</p><ul><li>« Une fois » pour garder le comportment par défaut.</li><li>« Par session » pour afficher les visites guidées chaque fois que l'application est ouverte de nouveau.</li><li>« Lancement manuel » pour éviter l'affichage automatique des visites guidées. Il sera toujours possible de les déclencher en appuyant sur F1 ou en cliquant sur « Aide » dans le menu utilisateur.</li></ul>"
feature_tour_display_mode: "Mode d'affichage des visites guidées"
feature_tour_display: "l'affichage des visites guidées"
display_mode:
once: "Une fois"
session: "Par session"
manual: "Lancement manuel"
sort_by:
default: "Défaut"
name: "Nom"

View File

@ -19,7 +19,6 @@ development:
fablab_without_online_payments: <%= ENV["FABLAB_WITHOUT_ONLINE_PAYMENT"] %>
fablab_without_wallet: <%= ENV["FABLAB_WITHOUT_WALLET"] %>
user_confirmation_needed_to_sign_in: <%= ENV["USER_CONFIRMATION_NEEDED_TO_SIGN_IN"] %>
feature_tour_display: <%= ENV["FEATURE_TOUR_DISPLAY"] %>
default_host: <%= ENV["DEFAULT_HOST"] %>
default_protocol: <%= ENV["DEFAULT_PROTOCOL"] %>
time_zone: <%= ENV["TIME_ZONE"] %>
@ -57,7 +56,6 @@ test:
fablab_without_online_payments: false
fablab_without_wallet: false
user_confirmation_needed_to_sign_in: <%= ENV["USER_CONFIRMATION_NEEDED_TO_SIGN_IN"] %>
feature_tour_display: <%= ENV["FEATURE_TOUR_DISPLAY"] %>
default_host: <%= ENV["DEFAULT_HOST"] %>
default_protocol: <%= ENV["DEFAULT_PROTOCOL"] %>
time_zone: Paris
@ -95,7 +93,6 @@ staging:
fablab_without_online_payments: <%= ENV["FABLAB_WITHOUT_ONLINE_PAYMENT"] %>
fablab_without_wallet: <%= ENV["FABLAB_WITHOUT_WALLET"] %>
user_confirmation_needed_to_sign_in: <%= ENV["USER_CONFIRMATION_NEEDED_TO_SIGN_IN"] %>
feature_tour_display: <%= ENV["FEATURE_TOUR_DISPLAY"] %>
default_host: <%= ENV["DEFAULT_HOST"] %>
default_protocol: <%= ENV["DEFAULT_PROTOCOL"] %>
delivery_method: <%= ENV['DELIVERY_METHOD'] %>
@ -144,7 +141,6 @@ production:
fablab_without_online_payments: <%= ENV["FABLAB_WITHOUT_ONLINE_PAYMENT"] %>
fablab_without_wallet: <%= ENV["FABLAB_WITHOUT_WALLET"] %>
user_confirmation_needed_to_sign_in: <%= ENV["USER_CONFIRMATION_NEEDED_TO_SIGN_IN"] %>
feature_tour_display: <%= ENV["FEATURE_TOUR_DISPLAY"] %>
default_host: <%= ENV["DEFAULT_HOST"] %>
default_protocol: <%= ENV["DEFAULT_PROTOCOL"] %>
delivery_method: <%= ENV['DELIVERY_METHOD'] %>

View File

@ -855,6 +855,8 @@ Setting.set('plans_module', true) unless Setting.find_by(name: 'plans_module').t
Setting.set('invoicing_module', true) unless Setting.find_by(name: 'invoicing_module').try(:value)
Setting.set('feature_tour_display', 'once') unless Setting.find_by(name: 'feature_tour_display').try(:value)
if StatisticCustomAggregation.count.zero?
# available reservations hours for machines
machine_hours = StatisticType.find_by(key: 'hour', statistic_index_id: 2)

View File

@ -190,16 +190,6 @@ If not specified, every admins will receive system administration notifications.
FORCE_VERSION_CHECK
In test and development environments, the version won't be check automatically, unless this variable is set to "true".
<a name="FEATURE_TOUR_DISPLAY"></a>
FEATURE_TOUR_DISPLAY
When logged-in as an administrator, a feature tour will be triggered the first time you visit each section of the application.
You can change this behavior by setting this variable to one of the following values:
- "once" to keep the default behavior.
- "session" to display the tours each time you reopen the application.
- "manual" to prevent displaying the tours automatically; you'll still be able to trigger them by pressing the F1 key.
<a name="ALLOW_INSECURE_HTTP"></a>
ALLOW_INSECURE_HTTP

View File

@ -22,8 +22,6 @@ FABLAB_WITHOUT_WALLET=false
USER_CONFIRMATION_NEEDED_TO_SIGN_IN=false
FEATURE_TOUR_DISPLAY=once
DEFAULT_MAIL_FROM=Fab-manager Demo <noreply@fab-manager.com>
# Configure carefully!

View File

@ -117,7 +117,8 @@ namespace :fablab do
%w[_ FACEBOOK_APP_ID facebook_app_id],
%w[_ TWITTER_NAME twitter_analytics],
%w[_ RECAPTCHA_SITE_KEY recaptcha_site_key],
%w[_ RECAPTCHA_SECRET_KEY recaptcha_secret_key]
%w[_ RECAPTCHA_SECRET_KEY recaptcha_secret_key],
%w[_ FEATURE_TOUR_DISPLAY feature_tour_display once]
]
mapping.each do |m|

View File

@ -237,7 +237,7 @@ configure_env_file()
variables=(STRIPE_API_KEY STRIPE_PUBLISHABLE_KEY STRIPE_CURRENCY INVOICE_PREFIX FABLAB_WITHOUT_ONLINE_PAYMENT FABLAB_WITHOUT_WALLET \
USER_CONFIRMATION_NEEDED_TO_SIGN_IN DEFAULT_MAIL_FROM DELIVERY_METHOD DEFAULT_HOST DEFAULT_PROTOCOL SMTP_ADDRESS SMTP_PORT SMTP_USER_NAME SMTP_PASSWORD SMTP_AUTHENTICATION \
SMTP_ENABLE_STARTTLS_AUTO SMTP_OPENSSL_VERIFY_MODE SMTP_TLS DISQUS_SHORTNAME \
LOG_LEVEL ALLOWED_EXTENSIONS ALLOWED_MIME_TYPES MAX_IMAGE_SIZE MAX_CAO_SIZE MAX_IMPORT_SIZE DISK_SPACE_MB_ALERT FEATURE_TOUR_DISPLAY \
LOG_LEVEL ALLOWED_EXTENSIONS ALLOWED_MIME_TYPES MAX_IMAGE_SIZE MAX_CAO_SIZE MAX_IMPORT_SIZE DISK_SPACE_MB_ALERT \
SUPERADMIN_EMAIL APP_LOCALE RAILS_LOCALE MOMENT_LOCALE SUMMERNOTE_LOCALE ANGULAR_LOCALE FULLCALENDAR_LOCALE ELASTICSEARCH_LANGUAGE_ANALYZER TIME_ZONE \
WEEK_STARTING_DAY D3_DATE_FORMAT UIB_DATE_FORMAT EXCEL_DATE_FORMAT OPENLAB_APP_ID OPENLAB_APP_SECRET OPENLAB_DEFAULT)
for variable in "${variables[@]}"; do