diff --git a/app/assets/javascripts/controllers/admin/members.js.erb b/app/assets/javascripts/controllers/admin/members.js.erb index 97c23cb55..d3a7318a3 100644 --- a/app/assets/javascripts/controllers/admin/members.js.erb +++ b/app/assets/javascripts/controllers/admin/members.js.erb @@ -217,6 +217,18 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce', } }; + /** + * Change the managers ordering criterion to the one provided + * @param orderManager {string} ordering criterion + */ + $scope.setOrderManager = function (orderManager) { + if ($scope.orderManager === orderManager) { + return $scope.orderManager = `-${orderManager}`; + } else { + return $scope.orderManager = orderManager; + } + }; + /** * Open a modal dialog allowing the admin to create a new partner user @@ -343,6 +355,36 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce', ); } + /** + * Ask for confirmation then delete the specified manager + * @param managers {Array} full list of managers + * @param manager {Object} manager to delete + */ + $scope.destroyManager = function (managers, manager) { + dialogs.confirm( + { + resolve: { + object () { + return { + title: _t('app.admin.members.confirmation_required'), + msg: $sce.trustAsHtml(_t('app.admin.members.delete_this_manager') + '

' + _t('app.admin.members.this_may_take_a_while_please_wait')) + }; + } + } + }, + function () { // cancel confirmed + User.delete( + { id: manager.id }, + function () { + managers.splice(findItemIdxById(managers, manager.id), 1); + return growl.success(_t('app.admin.members.manager_successfully_deleted')); + }, + function (error) { growl.error(_t('app.admin.members.unable_to_delete_the_manager')); } + ); + } + ); + } + /** * Callback for the 'load more' button. * Will load the next results of the current search, if any @@ -1029,3 +1071,65 @@ Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'A } ]); + +/** + * Controller used in the manager's creation page (admin view) + */ +Application.Controllers.controller('NewManagerController', ['$state', '$scope', 'User', 'growl', '_t', function ($state, $scope, User, growl, _t) { + // default admin profile + $scope.manager = { + statistic_profile_attributes: { + gender: true + }, + profile_attributes: {}, + invoicing_profile_attributes: {} + }; + + // Default parameters for AngularUI-Bootstrap datepicker + $scope.datePicker = { + format: Fablab.uibDateFormat, + opened: false, + options: { + startingDay: Fablab.weekStartingDay + } + }; + + /** + * Shows the birth day datepicker + * @param $event {Object} jQuery event object + */ + $scope.openDatePicker = function ($event) { $scope.datePicker.opened = true; }; + + /** + * Send the new manager, currently stored in $scope.manager, to the server for database saving + */ + $scope.saveManager = function () { + User.save( + {}, + { manager: $scope.manager }, + function () { + growl.success(_t('app.admin.manager_new.manager_successfully_created', { GENDER: getGender($scope.manager) })); + return $state.go('app.admin.members'); + } + , function (error) { + growl.error(_t('app.admin.admins_new.failed_to_create_admin') + JSON.stringify(error.data ? error.data : error)); + console.error(error); + } + ); + }; + + /* PRIVATE SCOPE */ + + /** + * Return an enumerable meaningful string for the gender of the provider user + * @param user {Object} Database user record + * @return {string} 'male' or 'female' + */ + const getGender = function (user) { + if (user.statistic_profile_attributes) { + if (user.statistic_profile_attributes.gender) { return 'male'; } else { return 'female'; } + } else { return 'other'; } + }; +} + +]); diff --git a/app/assets/javascripts/router.js.erb b/app/assets/javascripts/router.js.erb index 1e995dad0..1bed35283 100644 --- a/app/assets/javascripts/router.js.erb +++ b/app/assets/javascripts/router.js.erb @@ -931,8 +931,17 @@ angular.module('application.router', ['ui.router']) } } }) + .state('app.admin.managers_new', { + url: '/admin/managers/new', + views: { + 'main@': { + templateUrl: '<%= asset_path "admin/managers/new.html" %>', + controller: 'NewManagerController' + } + } + }) - // authentification providers + // authentication providers .state('app.admin.authentication_new', { url: '/admin/authentications/new', views: { diff --git a/app/assets/templates/admin/managers/new.html.erb b/app/assets/templates/admin/managers/new.html.erb new file mode 100644 index 000000000..ddcb029e9 --- /dev/null +++ b/app/assets/templates/admin/managers/new.html.erb @@ -0,0 +1,34 @@ +
+
+
+
+ +
+
+
+
+

{{ 'app.admin.manager_new.add_a_manager' }}

+
+
+ +
+
+ +
+
+ +
+
+
+ '"> +
+ + + +
+
+ +
+
diff --git a/app/assets/templates/admin/members/managers.html.erb b/app/assets/templates/admin/members/managers.html.erb index 31ce9c3b0..64e1028f0 100644 --- a/app/assets/templates/admin/members/managers.html.erb +++ b/app/assets/templates/admin/members/managers.html.erb @@ -2,34 +2,34 @@
- +
- + - + - + - + - + - - - - - + + + + + diff --git a/app/assets/templates/admin/members/partners.html.erb b/app/assets/templates/admin/members/partners.html.erb index 0261b68e2..aedfae2dc 100644 --- a/app/assets/templates/admin/members/partners.html.erb +++ b/app/assets/templates/admin/members/partners.html.erb @@ -33,7 +33,7 @@ diff --git a/app/assets/templates/admin/members/users.html.erb b/app/assets/templates/admin/members/users.html.erb index ef99ef151..689d9d955 100644 --- a/app/assets/templates/admin/members/users.html.erb +++ b/app/assets/templates/admin/members/users.html.erb @@ -8,9 +8,9 @@ '"> - + '"> diff --git a/app/assets/templates/shared/_manager_form.html b/app/assets/templates/shared/_manager_form.html new file mode 100644 index 000000000..a929ffe35 --- /dev/null +++ b/app/assets/templates/shared/_manager_form.html @@ -0,0 +1,153 @@ +
+
+
+ + + +
+ +
+
+ + +
+ {{ 'app.admin.manager_new.pseudonym_is_required' }} +
+ +
+
+ + +
+ {{ 'app.admin.manager_new.surname_is_required' }} +
+ +
+
+ + +
+ {{ 'app.admin.manager_new.first_name_is_required' }} +
+ +
+
+ + +
+ {{ 'app.admin.manager_new.email_is_required' }} +
+ +
+
+ + + +
+
+ +
+
+ + + +
+
+ +
+
+ + +
+
+ +
+ +
+ + + {{ 'app.shared.user_admin.group_is_required' }} +
+
+ +
+ +
+ + + + + + + + + + +
+
+ +
+
diff --git a/app/controllers/api/users_controller.rb b/app/controllers/api/users_controller.rb index 4327f0246..9a8a4ead7 100644 --- a/app/controllers/api/users_controller.rb +++ b/app/controllers/api/users_controller.rb @@ -15,12 +15,18 @@ class API::UsersController < API::ApiController def create authorize User - res = UserService.create_partner(partner_params) + res = if params[:user] + UserService.create_partner(partner_params) + elsif params[:manager] + UserService.create_manager(manager_params) + else + nil + end if res[:saved] @user = res[:user] render status: :created - else² + else render json: res[:user].errors.full_messages, status: :unprocessable_entity end end @@ -40,4 +46,13 @@ class API::UsersController < API::ApiController def partner_params params.require(:user).permit(:email, :first_name, :last_name) end + + def manager_params + params.require(:manager).permit( + :username, :email, :group_id, :tag_ids, + profile_attributes: %i[first_name last_name phone], + invoicing_profile_attributes: [address_attributes: [:address]], + statistic_profile_attributes: %i[gender birthday] + ) + end end diff --git a/app/services/user_service.rb b/app/services/user_service.rb index 4b2154dbc..ee44514f2 100644 --- a/app/services/user_service.rb +++ b/app/services/user_service.rb @@ -50,4 +50,19 @@ class UserService end { saved: saved, user: admin } end + + def self.create_manager(params) + generated_password = Devise.friendly_token.first(8) + manager = User.new(params.merge(password: generated_password)) + manager.send :set_slug + + saved = manager.save + if saved + manager.send_confirmation_instructions + manager.add_role(:admin) + manager.remove_role(:member) + UsersMailer.delay.notify_user_account_created(manager, generated_password) + end + { saved: saved, user: manager } + end end diff --git a/config/locales/app.admin.en.yml b/config/locales/app.admin.en.yml index b9170467f..8741e5d96 100644 --- a/config/locales/app.admin.en.yml +++ b/config/locales/app.admin.en.yml @@ -604,6 +604,12 @@ en: administrators: "Administrators" search_for_an_administrator: "Search for an administrator" add_a_new_administrator: "Add a new administrator" + managers: "Managers" + search_for_a_manager: "Search for a manager" + add_a_new_manager: "Add a new manager" + delete_this_manager: "Do you really want to delete this manager? This cannot be undone." + manager_successfully_deleted: "Manager successfully deleted." + unable_to_delete_the_manager: "Unable to delete the manager." partners: "Partners" partners_info: "A partner is a special user that can be associated with the «Partner» plans. These users will only receive notifications about subscriptions to these plans." search_for_a_partner: "Search for a partner" @@ -612,7 +618,6 @@ en: partner_successfully_deleted: "Partner successfully deleted." unable_to_delete_the_partner: "Unable to delete the partner." associated_plan: "Associated plan" - managers: "Managers" groups: "Groups" tags: "Tags" authentication: "Authentication" @@ -775,6 +780,24 @@ en: birth_date: "Date of birth" address: "Address" phone_number: "Phone number" + #add a new manager to the platform + manager_new: + add_a_manager: "Add a manager" + manager_successfully_created: "Manager successfully created. {GENDER, select, female{She} other{He}} receive {GENDER, select, female{her} other{his}} connection directives by e-mail." + failed_to_create_manager: "Unable to create the manager:" + man: "Man" + woman: "Woman" + pseudonym: "Pseudonym" + pseudonym_is_required: "Pseudonym is required." + first_name: "First name" + first_name_is_required: "First name is required." + surname: "Last name" + surname_is_required: "Last name is required." + email_address: "Email address" + email_is_required: "Email address is required." + birth_date: "Date of birth" + address: "Address" + phone_number: "Phone number" #add a new authentication provider (SSO) authentication_new: local_database: "Local Database"
{{ 'app.admin.members.surname' | translate }} {{ 'app.admin.members.surname' | translate }} {{ 'app.admin.members.first_name' | translate }} {{ 'app.admin.members.first_name' | translate }} {{ 'app.admin.members.email' | translate }} {{ 'app.admin.members.email' | translate }} {{ 'app.admin.members.phone' | translate }} {{ 'app.admin.members.phone' | translate }}
{{ admin.profile_attributes.last_name }}{{ admin.profile_attributes.first_name }}{{ admin.email }}{{ admin.profile_attributes.phone }}
{{ manager.profile_attributes.last_name }}{{ manager.profile_attributes.first_name }}{{ manager.email }}{{ manager.profile_attributes.phone }} - {{ partner.email }} {{ partner.resource ? partner.resource.base_name : '' }} -