mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-20 14:54:15 +01:00
Ability to promote a user to a higher role (member > manager > admin)
This commit is contained in:
parent
d8a289e825
commit
2d8df2c1cd
@ -4,6 +4,7 @@
|
|||||||
- The invoices list displays the operator in case of offline payment
|
- The invoices list displays the operator in case of offline payment
|
||||||
- Interface to manage partners
|
- Interface to manage partners
|
||||||
- Ability to define, per availability, a custom duration for the reservation slots
|
- 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
|
- Corrected the documentation about BOOK_SLOT_AT_SAME_TIME
|
||||||
- Auto-adjusts text colors based on the selected theme colors
|
- Auto-adjusts text colors based on the selected theme colors
|
||||||
- Fix a bug: unable to change group if the previous was deactivated
|
- Fix a bug: unable to change group if the previous was deactivated
|
||||||
|
@ -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
|
* Ask for confirmation then delete the specified user
|
||||||
@ -732,6 +691,54 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
|
|||||||
// current active authentication provider
|
// current active authentication provider
|
||||||
$scope.activeProvider = activeProviderPromise;
|
$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)
|
* Open a modal dialog, allowing the admin to extend the current user's subscription (freely or not)
|
||||||
* @param subscription {Object} User's subscription object
|
* @param subscription {Object} User's subscription object
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p class="alert alert-warning" translate>{{ 'app.admin.members_edit.warning_role_change' }}</p>
|
<p class="alert alert-warning" translate>{{ 'app.admin.members_edit.warning_role_change' }}</p>
|
||||||
<select ng-model="role" class="form-control" ng-options="r in roles"></select>
|
<select ng-model="role" class="form-control" ng-options="role.key as role.label disable when role.notAnOption for role in roles"></select>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class="btn btn-info" ng-click="ok()" translate>{{ 'app.shared.buttons.confirm' }}</button>
|
<button class="btn btn-info" ng-click="ok()" translate>{{ 'app.shared.buttons.confirm' }}</button>
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
|
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<section class="heading-actions wrapper">
|
<section class="heading-actions wrapper">
|
||||||
<div class="btn btn-lg btn-block btn-default m-t-xs" ng-click="cancel()" translate>
|
<div class="btn btn-lg btn-block btn-default promote-member m-t-xs" ng-click="changeUserRole()" ng-show="isAuthorized('admin')">
|
||||||
{{ 'app.shared.buttons.cancel' }}
|
<img src="/rank-icon.svg" alt="role icon" /><span class="m-l" translate>{{ 'app.admin.members_edit.change_role' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -59,9 +59,6 @@
|
|||||||
<button class="btn btn-default edit-member" ui-sref="app.admin.members_edit({id: m.id})">
|
<button class="btn btn-default edit-member" ui-sref="app.admin.members_edit({id: m.id})">
|
||||||
<i class="fa fa-edit"></i>
|
<i class="fa fa-edit"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-default promote-member">
|
|
||||||
<img src="/rank-icon.svg" alt="promote member" ng-click="changeUserRole(m.id)" ng-show="isAuthorized('admin')"/>
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-danger delete-member" ng-click="deleteMember(m.id)" ng-show="isAuthorized('admin')">
|
<button class="btn btn-danger delete-member" ng-click="deleteMember(m.id)" ng-show="isAuthorized('admin')">
|
||||||
<i class="fa fa-trash"></i>
|
<i class="fa fa-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -205,9 +205,29 @@ class API::MembersController < API::ApiController
|
|||||||
def update_role
|
def update_role
|
||||||
authorize @member
|
authorize @member
|
||||||
|
|
||||||
@member.remove_role @member.role.to_sym
|
# we do not allow dismissing a user to a lower role
|
||||||
|
if params[:role] == 'member'
|
||||||
|
render 403 and return if @member.role == 'admin' || @member.role == 'manager'
|
||||||
|
elsif params[:role] == 'manager'
|
||||||
|
render 403 and return if @member.role == 'admin'
|
||||||
|
end
|
||||||
|
|
||||||
|
# do nothing if the role does not change
|
||||||
|
render json: @member and return if params[:role] == @member.role
|
||||||
|
|
||||||
|
ex_role = @member.role.to_sym
|
||||||
|
@member.remove_role ex_role
|
||||||
@member.add_role params[:role]
|
@member.add_role params[:role]
|
||||||
|
|
||||||
|
NotificationCenter.call type: 'notify_user_role_update',
|
||||||
|
receiver: @member,
|
||||||
|
attached_object: @member
|
||||||
|
|
||||||
|
NotificationCenter.call type: 'notify_admins_role_update',
|
||||||
|
receiver: User.admins_and_managers,
|
||||||
|
attached_object: @member,
|
||||||
|
meta_data: { ex_role: ex_role }
|
||||||
|
|
||||||
render json: @member
|
render json: @member
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ class NotificationType
|
|||||||
notify_privacy_policy_changed
|
notify_privacy_policy_changed
|
||||||
notify_admin_import_complete
|
notify_admin_import_complete
|
||||||
notify_admin_refund_created
|
notify_admin_refund_created
|
||||||
|
notify_admins_role_update
|
||||||
|
notify_user_role_update
|
||||||
]
|
]
|
||||||
# deprecated:
|
# deprecated:
|
||||||
# - notify_member_subscribed_plan_is_changed
|
# - notify_member_subscribed_plan_is_changed
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
json.extract! i_cal, :id, :name, :url, :color, :primary_text_color, :text_hidden
|
json.extract! i_cal, :id, :name, :url, :color, :text_color, :text_hidden
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
json.title notification.notification_type
|
||||||
|
json.description t('.user_NAME_changed_ROLE_html',
|
||||||
|
NAME: notification.attached_object&.profile&.full_name || t('api.notifications.deleted_user'),
|
||||||
|
ROLE: t("roles.#{notification.attached_object&.role}"))
|
||||||
|
json.url notification_url(notification, format: :json)
|
@ -0,0 +1,5 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
json.title notification.notification_type
|
||||||
|
json.description t('.your_role_is_ROLE', ROLE: t("roles.#{notification.attached_object&.role}"))
|
||||||
|
json.url notification_url(notification, format: :json)
|
@ -0,0 +1,8 @@
|
|||||||
|
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||||
|
|
||||||
|
<p><%= t('.body.user_role_changed_html', NAME: @attached_object&.profile&.full_name || t('api.notifications.deleted_user')) %></p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<small><%= t('.body.previous_role') %> <strong><%= t("roles.#{@notification.get_meta_data(:ex_role)}") %></strong></small>
|
||||||
|
<br/><%= t('.body.new_role') %> <strong><%= t("roles.#{@attached_object.role}") %></strong>
|
||||||
|
</p>
|
@ -0,0 +1,7 @@
|
|||||||
|
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||||
|
|
||||||
|
<%
|
||||||
|
name = Setting.find_by(name: 'fablab_name').value
|
||||||
|
gender = Setting.find_by(name: 'name_genre').value
|
||||||
|
%>
|
||||||
|
<p><%= t('.body.role_changed', NAME: name, GENDER: gender, ROLE: t("roles.#{@attached_object.role}")) %></p>
|
@ -723,6 +723,13 @@ en:
|
|||||||
error_details: "Error's details:"
|
error_details: "Error's details:"
|
||||||
#edit a member
|
#edit a member
|
||||||
members_edit:
|
members_edit:
|
||||||
|
change_role: "Change role"
|
||||||
|
warning_role_change: "<p><strong>Warning:</strong> changing the role of a user is not a harmless operation. Is not currently possible to dismiss a user to a lower privileged role.</p><ul><li><strong>Members</strong> can only book reservations for themselves, paying by card or wallet.</li><li><strong>Managers</strong> can book reservations for themselves, paying by card or wallet, and for other members and managers, by collecting payments at the checkout.</li><li><strong>Administrators</strong> can only book reservations for members and managers, by collecting payments at the checkout. Moreover, they can change every settings of the application.</li></ul>"
|
||||||
|
admin: "Administrator"
|
||||||
|
manager: "Manager"
|
||||||
|
member: "Member"
|
||||||
|
role_changed: "Role successfully changed from {OLD} to {NEW}."
|
||||||
|
error_while_changing_role: "An error occurred while changing the role. Please try again later."
|
||||||
subscription: "Subscription"
|
subscription: "Subscription"
|
||||||
duration: "Duration:"
|
duration: "Duration:"
|
||||||
expires_at: "Expires at:"
|
expires_at: "Expires at:"
|
||||||
|
@ -723,6 +723,13 @@ fr:
|
|||||||
error_details: "Détails de l'erreur :"
|
error_details: "Détails de l'erreur :"
|
||||||
#edit a member
|
#edit a member
|
||||||
members_edit:
|
members_edit:
|
||||||
|
change_role: "Changer de rôle"
|
||||||
|
warning_role_change: "<p><strong>Attention :</strong> changer le rôle d'un utilisateur n'est pas une opération anodine. Il n'est actuellement pas possible de destituer un utilisateur vers un rôle de moindre privilège.</p><ul><li><strong>Les membres</strong> ne peuvent que prendre des réservations pour eux-même, en payant par carte bancaire ou par porte-monnaie.</li><li><strong>Les gestionnaires</strong> peuvent prendre des réservations pour eux-même, en payant par carte bancaire ou par porte-monnaie, ainsi que pour les autres membres et gestionnaires, en encaissant les paiements à la caisse.</li><li><strong>Les administrateurs</strong> ne peuvent que prendre des réservations pour les membres et gestionnaires, en encaissant les paiements à la caisse. De plus, ils peuvent modifier l'ensemble des paramètres de l'application.</li></ul>"
|
||||||
|
admin: "Administrateur"
|
||||||
|
manager: "Gestionnaire"
|
||||||
|
member: "Membre"
|
||||||
|
role_changed: "Le rôle de {OLD} à été changé en {NEW}."
|
||||||
|
error_while_changing_role: "Une erreur est survenue lors du changement de rôle. Merci de réessayer plus tard."
|
||||||
subscription: "Abonnement"
|
subscription: "Abonnement"
|
||||||
duration: "Durée :"
|
duration: "Durée :"
|
||||||
expires_at: "Expire le :"
|
expires_at: "Expire le :"
|
||||||
|
@ -214,6 +214,10 @@ en:
|
|||||||
event: "Event"
|
event: "Event"
|
||||||
reservations: "Reservations"
|
reservations: "Reservations"
|
||||||
available_seats: "Available seats"
|
available_seats: "Available seats"
|
||||||
|
roles:
|
||||||
|
member: "Member"
|
||||||
|
manager: "Manager"
|
||||||
|
admin: "Administrator"
|
||||||
api:
|
api:
|
||||||
#internal app notifications
|
#internal app notifications
|
||||||
notifications:
|
notifications:
|
||||||
@ -329,6 +333,10 @@ en:
|
|||||||
click_to_show: "Click here to consult"
|
click_to_show: "Click here to consult"
|
||||||
notify_admin_refund_created:
|
notify_admin_refund_created:
|
||||||
refund_created: "A refund of %{AMOUNT} has been created for user %{USER}"
|
refund_created: "A refund of %{AMOUNT} has been created for user %{USER}"
|
||||||
|
notify_user_role_update:
|
||||||
|
your_role_is_ROLE: "Your role has been changed to %{ROLE}."
|
||||||
|
notify_admins_role_update:
|
||||||
|
user_NAME_changed_ROLE_html: "User <strong><em>%{NAME}</strong></em> is now %{ROLE}."
|
||||||
#statistics tools for admins
|
#statistics tools for admins
|
||||||
statistics:
|
statistics:
|
||||||
subscriptions: "Subscriptions"
|
subscriptions: "Subscriptions"
|
||||||
|
@ -273,5 +273,15 @@ en:
|
|||||||
body:
|
body:
|
||||||
refund_created: "A refund of %{AMOUNT} has been generated on invoice %{INVOICE} of user %{USER}"
|
refund_created: "A refund of %{AMOUNT} has been generated on invoice %{INVOICE} of user %{USER}"
|
||||||
download: "Click here to download this refund invoice"
|
download: "Click here to download this refund invoice"
|
||||||
|
notify_admins_role_update:
|
||||||
|
subject: "The role of a user has changed"
|
||||||
|
body:
|
||||||
|
user_role_changed_html: "The role of the user <em><strong>%{NAME}</strong></em> has changed."
|
||||||
|
previous_role: "Previous role:"
|
||||||
|
new_role: "New role:"
|
||||||
|
notify_user_role_update:
|
||||||
|
subject: "Your role has changed"
|
||||||
|
body:
|
||||||
|
role_changed_html: "Your role at {GENDER, select, male{the} female{the} neutral{} other{the}} {NAME} has changed. You are now <strong>{ROLE}</strong>.<br/>With great power comes great responsibility, use your new privileges fairly and respectfully."
|
||||||
shared:
|
shared:
|
||||||
hello: "Hello %{user_name}"
|
hello: "Hello %{user_name}"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user