From 06a5bff084dd0ed1c4558ba3f38597e7d51faa48 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 4 May 2020 18:32:25 +0200 Subject: [PATCH 1/3] [ongoing] change user role --- .../controllers/admin/members.js.erb | 41 +++++++++++++ app/assets/javascripts/services/member.js | 4 ++ app/assets/stylesheets/modules/members.scss | 4 ++ .../admin/members/change_role_modal.html.erb | 12 ++++ .../templates/admin/members/members.html.erb | 7 ++- app/controllers/api/members_controller.rb | 11 +++- app/models/user.rb | 2 + app/policies/user_policy.rb | 2 +- config/routes.rb | 1 + public/rank-icon.svg | 61 +++++++++++++++++++ 10 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 app/assets/stylesheets/modules/members.scss create mode 100644 app/assets/templates/admin/members/change_role_modal.html.erb create mode 100644 public/rank-icon.svg diff --git a/app/assets/javascripts/controllers/admin/members.js.erb b/app/assets/javascripts/controllers/admin/members.js.erb index a02456b06..3f1a0ced1 100644 --- a/app/assets/javascripts/controllers/admin/members.js.erb +++ b/app/assets/javascripts/controllers/admin/members.js.erb @@ -265,6 +265,47 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce', }); }; + /** + * Open a modal dialog asking for confirmation to change the role of the given user + * @param userId {number} id of the user to "promote" + * @returns {*} + */ + $scope.changeUserRole = function(userId) { + const modalInstance = $uibModal.open({ + animation: true, + templateUrl: '<%= asset_path "admin/members/change_role_modal.html" %>', + size: 'lg', + resolve: { + userPromise: ['Member', function (Member) { return Member.get({ id: userId }).$promise; }] + }, + controller: ['$scope', '$uibModalInstance', 'Member', 'userPromise', function ($scope, $uibModalInstance, Member, userPromise) { + $scope.user = userPromise; + + $scope.role = userPromise.role; + + $scope.roles = ['admin', 'manager', 'member']; + + $scope.ok = function () { + Member.updateRole( + { id: $scope.user.id }, + { role: $scope.role }, + function (_res) { + growl.success(_t('app.admin.members_edit.role_changed')); + return $uibModalInstance.close(_res); + }, + function (error) { growl.error(_t('app.admin.members_edit.error_while_changing_role')); } + ); + }; + + $scope.cancel = function () { $uibModalInstance.dismiss('cancel'); }; + }] + }); + // once the form was validated successfully ... + return modalInstance.result.then(function (user) { + // remove the user for the old list add to the new + }); + } + /** * Ask for confirmation then delete the specified user diff --git a/app/assets/javascripts/services/member.js b/app/assets/javascripts/services/member.js index 52eab1157..c920fb263 100644 --- a/app/assets/javascripts/services/member.js +++ b/app/assets/javascripts/services/member.js @@ -44,6 +44,10 @@ Application.Services.factory('Member', ['$resource', '$q', function ($resource, return response.data; } } + }, + updateRole: { + method: 'PATCH', + url: '/api/members/:id/update_role' } } ); diff --git a/app/assets/stylesheets/modules/members.scss b/app/assets/stylesheets/modules/members.scss new file mode 100644 index 000000000..34a9209f9 --- /dev/null +++ b/app/assets/stylesheets/modules/members.scss @@ -0,0 +1,4 @@ +.promote-member img { + width: 16px; + height: 21px; +} \ No newline at end of file diff --git a/app/assets/templates/admin/members/change_role_modal.html.erb b/app/assets/templates/admin/members/change_role_modal.html.erb new file mode 100644 index 000000000..e18b3a6d6 --- /dev/null +++ b/app/assets/templates/admin/members/change_role_modal.html.erb @@ -0,0 +1,12 @@ + + + diff --git a/app/assets/templates/admin/members/members.html.erb b/app/assets/templates/admin/members/members.html.erb index 0b16110d6..16b080acc 100644 --- a/app/assets/templates/admin/members/members.html.erb +++ b/app/assets/templates/admin/members/members.html.erb @@ -41,9 +41,9 @@ {{ 'app.admin.members.first_name' | translate }} {{ 'app.admin.members.email' | translate }} {{ 'app.admin.members.phone' | translate }} - {{ 'app.admin.members.user_type' | translate }} + {{ 'app.admin.members.user_type' | translate }} {{ 'app.admin.members.subscription' | translate }} - + @@ -59,6 +59,9 @@ + diff --git a/app/controllers/api/members_controller.rb b/app/controllers/api/members_controller.rb index 8ae0b82e1..604b91df9 100644 --- a/app/controllers/api/members_controller.rb +++ b/app/controllers/api/members_controller.rb @@ -3,7 +3,7 @@ # API Controller for resources of type User with role 'member' class API::MembersController < API::ApiController before_action :authenticate_user!, except: [:last_subscribed] - before_action :set_member, only: %i[update destroy merge complete_tour] + before_action :set_member, only: %i[update destroy merge complete_tour update_role] respond_to :json def index @@ -202,6 +202,15 @@ class API::MembersController < API::ApiController end end + def update_role + authorize @member + + user.remove_role @member.role.to_sym + user.add_role params[:role] + + render json: @member + end + private def set_member diff --git a/app/models/user.rb b/app/models/user.rb index bc72bcb97..a5c5b9135 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -160,6 +160,8 @@ class User < ApplicationRecord 'admin' elsif manager? 'manager' + elsif member? + 'member' else 'other' end diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index 11c9debf2..2208c4f2d 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -39,7 +39,7 @@ class UserPolicy < ApplicationPolicy end end - %w[create mapping].each do |action| + %w[create mapping update_role].each do |action| define_method "#{action}?" do user.admin? end diff --git a/config/routes.rb b/config/routes.rb index cc86c6a5a..114868831 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -55,6 +55,7 @@ Rails.application.routes.draw do get 'search/:query', action: 'search', on: :collection get 'mapping', action: 'mapping', on: :collection patch ':id/complete_tour', action: 'complete_tour', on: :collection + patch ':id/update_role', action: 'update_role', on: :collection end resources :reservations, only: %i[show create index update] resources :notifications, only: %i[index show update] do diff --git a/public/rank-icon.svg b/public/rank-icon.svg new file mode 100644 index 000000000..d45ec416f --- /dev/null +++ b/public/rank-icon.svg @@ -0,0 +1,61 @@ + +image/svg+xml From d8a289e82505c948e15ffd65289ff9d4695deeca Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 4 May 2020 18:34:26 +0200 Subject: [PATCH 2/3] fixes change role API --- app/controllers/api/members_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/members_controller.rb b/app/controllers/api/members_controller.rb index 604b91df9..443ecdbcd 100644 --- a/app/controllers/api/members_controller.rb +++ b/app/controllers/api/members_controller.rb @@ -205,8 +205,8 @@ class API::MembersController < API::ApiController def update_role authorize @member - user.remove_role @member.role.to_sym - user.add_role params[:role] + @member.remove_role @member.role.to_sym + @member.add_role params[:role] render json: @member end From 2d8df2c1cd6c535e4ea5c1b73bd4b4d79e4911ec Mon Sep 17 00:00:00 2001 From: Sylvain Date: Tue, 5 May 2020 11:28:04 +0200 Subject: [PATCH 3/3] Ability to promote a user to a higher role (member > manager > admin) --- CHANGELOG.md | 1 + .../controllers/admin/members.js.erb | 89 ++++++++++--------- .../admin/members/change_role_modal.html.erb | 2 +- .../templates/admin/members/edit.html.erb | 4 +- .../templates/admin/members/members.html.erb | 3 - app/controllers/api/members_controller.rb | 22 ++++- app/models/notification_type.rb | 2 + .../api/i_calendar/_i_calendar.json.jbuilder | 2 +- .../_notify_admins_role_update.json.jbuilder | 7 ++ .../_notify_user_role_update.json.jbuilder | 5 ++ .../notify_admins_role_update.html.erb | 8 ++ .../notify_user_role_update.html.erb | 7 ++ config/locales/app.admin.en.yml | 7 ++ config/locales/app.admin.fr.yml | 7 ++ config/locales/en.yml | 8 ++ config/locales/mails.en.yml | 10 +++ 16 files changed, 135 insertions(+), 49 deletions(-) create mode 100644 app/views/api/notifications/_notify_admins_role_update.json.jbuilder create mode 100644 app/views/api/notifications/_notify_user_role_update.json.jbuilder create mode 100644 app/views/notifications_mailer/notify_admins_role_update.html.erb create mode 100644 app/views/notifications_mailer/notify_user_role_update.html.erb diff --git a/CHANGELOG.md b/CHANGELOG.md index 878dcd245..3468b75e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - The invoices list displays the operator in case of offline payment - Interface to manage partners - Ability to define, per availability, a custom duration for the reservation slots +- Ability to promote a user to a higher role (member > manager > admin) - Corrected the documentation about BOOK_SLOT_AT_SAME_TIME - Auto-adjusts text colors based on the selected theme colors - Fix a bug: unable to change group if the previous was deactivated diff --git a/app/assets/javascripts/controllers/admin/members.js.erb b/app/assets/javascripts/controllers/admin/members.js.erb index 3f1a0ced1..906bf8396 100644 --- a/app/assets/javascripts/controllers/admin/members.js.erb +++ b/app/assets/javascripts/controllers/admin/members.js.erb @@ -265,47 +265,6 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce', }); }; - /** - * Open a modal dialog asking for confirmation to change the role of the given user - * @param userId {number} id of the user to "promote" - * @returns {*} - */ - $scope.changeUserRole = function(userId) { - const modalInstance = $uibModal.open({ - animation: true, - templateUrl: '<%= asset_path "admin/members/change_role_modal.html" %>', - size: 'lg', - resolve: { - userPromise: ['Member', function (Member) { return Member.get({ id: userId }).$promise; }] - }, - controller: ['$scope', '$uibModalInstance', 'Member', 'userPromise', function ($scope, $uibModalInstance, Member, userPromise) { - $scope.user = userPromise; - - $scope.role = userPromise.role; - - $scope.roles = ['admin', 'manager', 'member']; - - $scope.ok = function () { - Member.updateRole( - { id: $scope.user.id }, - { role: $scope.role }, - function (_res) { - growl.success(_t('app.admin.members_edit.role_changed')); - return $uibModalInstance.close(_res); - }, - function (error) { growl.error(_t('app.admin.members_edit.error_while_changing_role')); } - ); - }; - - $scope.cancel = function () { $uibModalInstance.dismiss('cancel'); }; - }] - }); - // once the form was validated successfully ... - return modalInstance.result.then(function (user) { - // remove the user for the old list add to the new - }); - } - /** * Ask for confirmation then delete the specified user @@ -732,6 +691,54 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state', // current active authentication provider $scope.activeProvider = activeProviderPromise; + /** + * Open a modal dialog asking for confirmation to change the role of the given user + * @param userId {number} id of the user to "promote" + * @returns {*} + */ + $scope.changeUserRole = function() { + const modalInstance = $uibModal.open({ + animation: true, + templateUrl: '<%= asset_path "admin/members/change_role_modal.html" %>', + size: 'lg', + resolve: { + user() { return $scope.user; } + }, + controller: ['$scope', '$uibModalInstance', 'Member', 'user', '_t', function ($scope, $uibModalInstance, Member, user, _t) { + $scope.user = user; + + $scope.role = user.role; + + $scope.roles = [ + { key: 'admin', label: _t('app.admin.members_edit.admin') }, + { key: 'manager', label: _t('app.admin.members_edit.manager'), notAnOption: (user.role === 'admin') }, + { key: 'member', label: _t('app.admin.members_edit.member'), notAnOption: (user.role === 'admin' || user.role === 'manager') }, + ]; + + $scope.ok = function () { + Member.updateRole( + { id: $scope.user.id }, + { role: $scope.role }, + function (_res) { + growl.success(_t('app.admin.members_edit.role_changed', { OLD: _t(`app.admin.members_edit.${user.role}`), NEW: _t(`app.admin.members_edit.${$scope.role}`) })); + return $uibModalInstance.close(_res); + }, + function (error) { + growl.error(_t('app.admin.members_edit.error_while_changing_role')); + console.error(error); + } + ); + }; + + $scope.cancel = function () { $uibModalInstance.dismiss('cancel'); }; + }] + }); + // once the form was validated successfully ... + return modalInstance.result.then(function (user) { + // remove the user for the old list add to the new + }); + } + /** * Open a modal dialog, allowing the admin to extend the current user's subscription (freely or not) * @param subscription {Object} User's subscription object diff --git a/app/assets/templates/admin/members/change_role_modal.html.erb b/app/assets/templates/admin/members/change_role_modal.html.erb index e18b3a6d6..ce09403ca 100644 --- a/app/assets/templates/admin/members/change_role_modal.html.erb +++ b/app/assets/templates/admin/members/change_role_modal.html.erb @@ -4,7 +4,7 @@