Implement custom roles and improve permissions logic
The commit refactors the handling of account roles and enhances permissions checks. The account role has been shifted to use a string type, providing the ability to define custom roles. It also introduces the RolesDataProvider component, which stipulates role-related data for different forms and tables. The modification goes further to consider user role hierarchy in permissions checks, offering a more granular access control.
This commit is contained in:
@@ -35,6 +35,7 @@ type AccountInvitationsTableProps = {
|
||||
permissions: {
|
||||
canUpdateInvitation: boolean;
|
||||
canRemoveInvitation: boolean;
|
||||
currentUserRoleHierarchy: number;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -72,6 +73,7 @@ export function AccountInvitationsTable({
|
||||
function useGetColumns(permissions: {
|
||||
canUpdateInvitation: boolean;
|
||||
canRemoveInvitation: boolean;
|
||||
currentUserRoleHierarchy: number;
|
||||
}): ColumnDef<Invitations[0]>[] {
|
||||
const { t } = useTranslation('teams');
|
||||
|
||||
@@ -197,6 +199,7 @@ function ActionsDropdown({
|
||||
setIsOpen={setIsUpdatingRole}
|
||||
invitationId={invitation.id}
|
||||
userRole={invitation.role}
|
||||
userRoleHierarchy={permissions.currentUserRoleHierarchy}
|
||||
/>
|
||||
</If>
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Database } from '@kit/supabase/database';
|
||||
import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert';
|
||||
import { Button } from '@kit/ui/button';
|
||||
import {
|
||||
@@ -29,15 +28,17 @@ import { Trans } from '@kit/ui/trans';
|
||||
import { UpdateRoleSchema } from '../../schema/update-role-schema';
|
||||
import { updateInvitationAction } from '../../server/actions/team-invitations-server-actions';
|
||||
import { MembershipRoleSelector } from '../members/membership-role-selector';
|
||||
import { RolesDataProvider } from '../members/roles-data-provider';
|
||||
|
||||
type Role = Database['public']['Enums']['account_role'];
|
||||
type Role = string;
|
||||
|
||||
export const UpdateInvitationDialog: React.FC<{
|
||||
isOpen: boolean;
|
||||
setIsOpen: (isOpen: boolean) => void;
|
||||
invitationId: number;
|
||||
userRole: Role;
|
||||
}> = ({ isOpen, setIsOpen, invitationId, userRole }) => {
|
||||
userRoleHierarchy: number;
|
||||
}> = ({ isOpen, setIsOpen, invitationId, userRole, userRoleHierarchy }) => {
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||
<DialogContent>
|
||||
@@ -51,11 +52,16 @@ export const UpdateInvitationDialog: React.FC<{
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<UpdateInvitationForm
|
||||
setIsOpen={setIsOpen}
|
||||
invitationId={invitationId}
|
||||
userRole={userRole}
|
||||
/>
|
||||
<RolesDataProvider maxRoleHierarchy={userRoleHierarchy}>
|
||||
{(roles) => (
|
||||
<UpdateInvitationForm
|
||||
invitationId={invitationId}
|
||||
userRole={userRole}
|
||||
userRoleHierarchy={roles.length}
|
||||
setIsOpen={setIsOpen}
|
||||
/>
|
||||
)}
|
||||
</RolesDataProvider>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
@@ -64,10 +70,12 @@ export const UpdateInvitationDialog: React.FC<{
|
||||
function UpdateInvitationForm({
|
||||
invitationId,
|
||||
userRole,
|
||||
userRoleHierarchy,
|
||||
setIsOpen,
|
||||
}: React.PropsWithChildren<{
|
||||
invitationId: number;
|
||||
userRole: Role;
|
||||
userRoleHierarchy: number;
|
||||
setIsOpen: (isOpen: boolean) => void;
|
||||
}>) {
|
||||
const { t } = useTranslation('teams');
|
||||
@@ -128,11 +136,18 @@ function UpdateInvitationForm({
|
||||
</FormLabel>
|
||||
|
||||
<FormControl>
|
||||
<MembershipRoleSelector
|
||||
currentUserRole={userRole}
|
||||
value={field.value}
|
||||
onChange={(newRole) => form.setValue('role', newRole)}
|
||||
/>
|
||||
<RolesDataProvider maxRoleHierarchy={userRoleHierarchy}>
|
||||
{(roles) => (
|
||||
<MembershipRoleSelector
|
||||
roles={roles}
|
||||
currentUserRole={userRole}
|
||||
value={field.value}
|
||||
onChange={(newRole) =>
|
||||
form.setValue(field.name, newRole)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</RolesDataProvider>
|
||||
</FormControl>
|
||||
|
||||
<FormDescription>
|
||||
|
||||
Reference in New Issue
Block a user