0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-24 22:41:28 -05:00

refactor(schemas): rename tenant member role to collaborator (#5616)

This commit is contained in:
Charles Zhao 2024-04-02 16:48:30 +08:00 committed by GitHub
parent d1c41a2fa7
commit e38e3c1bd0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 113 additions and 25 deletions

View file

@ -24,13 +24,13 @@ function EditMemberModal({ user, isOpen, onClose }: Props) {
const { currentTenantId } = useContext(TenantsContext);
const [isLoading, setIsLoading] = useState(false);
const [role, setRole] = useState(TenantRole.Member);
const [role, setRole] = useState(TenantRole.Collaborator);
const cloudApi = useAuthedCloudApi();
const roleOptions: Array<Option<TenantRole>> = useMemo(
() => [
{ value: TenantRole.Admin, title: t('admin') },
{ value: TenantRole.Member, title: t('member') },
{ value: TenantRole.Collaborator, title: t('collaborator') },
],
[t]
);
@ -38,10 +38,11 @@ function EditMemberModal({ user, isOpen, onClose }: Props) {
const onSubmit = async () => {
setIsLoading(true);
try {
await cloudApi.put(`/api/tenants/:tenantId/members/:userId/roles`, {
params: { tenantId: currentTenantId, userId: user.id },
body: { roleName: role },
});
// TODO: @charles Uncomment later once the Cloud APIs are updated
// await cloudApi.put(`/api/tenants/:tenantId/members/:userId/roles`, {
// params: { tenantId: currentTenantId, userId: user.id },
// body: { roleName: role },
// });
onClose();
} finally {
setIsLoading(false);

View file

@ -42,7 +42,7 @@ function InviteMemberModal({ isOpen, onClose }: Props) {
const formMethods = useForm<InviteMemberForm>({
defaultValues: {
emails: [],
role: TenantRole.Member,
role: TenantRole.Collaborator,
},
});
@ -56,7 +56,7 @@ function InviteMemberModal({ isOpen, onClose }: Props) {
const roleOptions: Array<Option<TenantRole>> = useMemo(
() => [
{ value: TenantRole.Admin, title: t('admin') },
{ value: TenantRole.Member, title: t('member') },
{ value: TenantRole.Collaborator, title: t('collaborator') },
],
[t]
);
@ -77,14 +77,15 @@ function InviteMemberModal({ isOpen, onClose }: Props) {
return;
}
await Promise.all(
emails.map(async (email) =>
cloudApi.post('/api/tenants/:tenantId/invitations', {
params: { tenantId: currentTenantId },
body: { invitee: email.value, roleName: role },
})
)
);
// TODO: @charles Uncomment later once the Cloud APIs are updated
// await Promise.all(
// emails.map(async (email) =>
// cloudApi.post('/api/tenants/:tenantId/invitations', {
// params: { tenantId: currentTenantId },
// body: { invitee: email.value, roleName: role },
// })
// )
// );
toast.success(t('messages.invitation_sent'));
onClose(true);
} finally {

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -1,11 +1,13 @@
const tenant_members = {
members: 'Members',
collaborators: 'Collaborators',
invitations: 'Invitations',
invite_members: 'Invite members',
user: 'User',
roles: 'Roles',
admin: 'Admin',
member: 'Member',
collaborator: 'Collaborator',
invitation_status: 'Invitation status',
invitation_sent: 'Invitation sent',
expiration_date: 'Expiration date',

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -2,6 +2,8 @@ const tenant_members = {
/** UNTRANSLATED */
members: 'Members',
/** UNTRANSLATED */
collaborators: 'Collaborators',
/** UNTRANSLATED */
invitations: 'Invitations',
/** UNTRANSLATED */
invite_members: 'Invite members',
@ -14,6 +16,8 @@ const tenant_members = {
/** UNTRANSLATED */
member: 'Member',
/** UNTRANSLATED */
collaborator: 'Collaborator',
/** UNTRANSLATED */
invitation_status: 'Invitation status',
/** UNTRANSLATED */
invitation_sent: 'Invitation sent',

View file

@ -0,0 +1,28 @@
import { sql } from '@silverhand/slonik';
import type { AlterationScript } from '../lib/types/alteration.js';
const alteration: AlterationScript = {
up: async (pool) => {
await pool.query(sql`
update organization_roles
set id = 'collaborator', name = 'collaborator', description = 'Collaborator of the tenant, who has permissions to operate the tenant data, but not the tenant settings.'
where tenant_id = 'admin' and id = 'member';
update organization_role_scope_relations
set organization_role_id = 'collaborator'
where tenant_id = 'admin' and organization_role_id = 'member';
`);
},
down: async (pool) => {
await pool.query(sql`
update organization_roles
set id = 'member', name = 'member', description = 'Member of the tenant, who has permissions to operate the tenant data, but not the tenant settings.'
where tenant_id = 'admin' and id = 'collaborator';
update organization_role_scope_relations
set organization_role_id = 'member'
where tenant_id = 'admin' and organization_role_id = 'collaborator';
`);
},
};
export default alteration;

View file

@ -124,14 +124,14 @@ const tenantScopeDescriptions: Readonly<Record<TenantScope, string>> = Object.fr
export enum TenantRole {
/** Admin of the tenant, who has all permissions. */
Admin = 'admin',
/** Member of the tenant, who has permissions to operate the tenant data, but not the tenant settings. */
Member = 'member',
/** Collaborator of the tenant, who has permissions to operate the tenant data, but not the tenant settings. */
Collaborator = 'collaborator',
}
const tenantRoleDescriptions: Readonly<Record<TenantRole, string>> = Object.freeze({
[TenantRole.Admin]: 'Admin of the tenant, who has all permissions.',
[TenantRole.Member]:
'Member of the tenant, who has permissions to operate the tenant data, but not the tenant settings.',
[TenantRole.Collaborator]:
'Collaborator of the tenant, who has permissions to operate the tenant data, but not the tenant settings.',
});
/**
@ -139,14 +139,14 @@ const tenantRoleDescriptions: Readonly<Record<TenantRole, string>> = Object.free
*
* @example
* ```ts
* const role = TenantRole.Member; // 'member'
* const role = TenantRole.Collaborator; // 'collaborator'
* const roleData = getTenantRole(role);
*
* expect(roleData).toEqual({
* tenantId: 'admin',
* id: 'member',
* name: 'member',
* description: 'Member of the tenant, who has permissions to operate the tenant data, but not the tenant settings.',
* id: 'collaborator',
* name: 'collaborator',
* description: 'Collaborator of the tenant, who has permissions to operate the tenant data, but not the tenant settings.',
* });
* ```
*
@ -167,7 +167,7 @@ export const getTenantRole = (role: TenantRole): Readonly<OrganizationRole> =>
export const tenantRoleScopes: Readonly<Record<TenantRole, Readonly<TenantScope[]>>> =
Object.freeze({
[TenantRole.Admin]: allTenantScopes,
[TenantRole.Member]: [
[TenantRole.Collaborator]: [
TenantScope.ReadData,
TenantScope.WriteData,
TenantScope.DeleteData,