From e849378726cbd8d6ccdfb57d03937b02e81dbe7e Mon Sep 17 00:00:00 2001 From: Weiko Date: Thu, 6 Feb 2025 11:27:56 +0100 Subject: [PATCH] Add role edit page container (#10037) ## Context This PR adds a new SettingsRoleEdit page, the existing roles page now redirects to the role edition page when clicking on it. For now, we can't edit anything. Next step is to allow role assignment in the corresponding tab. Screenshot 2025-02-05 at 17 16 14 --- .../modules/app/components/SettingsRoutes.tsx | 7 + .../src/modules/types/SettingsPath.ts | 1 + .../pages/settings/roles/SettingsRoleEdit.tsx | 123 ++++++++++++++++++ .../pages/settings/roles/SettingsRoles.tsx | 11 +- .../roles/components/RoleAssignment.tsx | 19 +++ .../roles/components/RolePermissions.tsx | 19 +++ 6 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 packages/twenty-front/src/pages/settings/roles/SettingsRoleEdit.tsx create mode 100644 packages/twenty-front/src/pages/settings/roles/components/RoleAssignment.tsx create mode 100644 packages/twenty-front/src/pages/settings/roles/components/RolePermissions.tsx diff --git a/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx b/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx index 0b06ed6bd..31f7dc2b9 100644 --- a/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx +++ b/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx @@ -265,6 +265,12 @@ const SettingsRoles = lazy(() => })), ); +const SettingsRoleEdit = lazy(() => + import('~/pages/settings/roles/SettingsRoleEdit').then((module) => ({ + default: module.SettingsRoleEdit, + })), +); + type SettingsRoutesProps = { isBillingEnabled?: boolean; isFunctionSettingsEnabled?: boolean; @@ -311,6 +317,7 @@ export const SettingsRoutes = ({ /> } /> } /> + } /> } /> theme.spacing(2)}; +`; + +const StyledIconUser = styled(IconUser)` + color: ${({ theme }) => theme.font.color.primary}; +`; + +export const SETTINGS_ROLE_DETAIL_TABS = { + COMPONENT_INSTANCE_ID: 'settings-role-detail-tabs', + TABS_IDS: { + ASSIGNMENT: 'assignment', + PERMISSIONS: 'permissions', + }, +} as const; + +export const SettingsRoleEdit = () => { + const { roleId = '' } = useParams(); + const { data: rolesData, loading: rolesLoading } = useGetRolesQuery(); + const navigateSettings = useNavigateSettings(); + + const role = rolesData?.getRoles.find((r) => r.id === roleId); + + const { activeTabId } = useTabList( + SETTINGS_ROLE_DETAIL_TABS.COMPONENT_INSTANCE_ID, + ); + + useEffect(() => { + if (!rolesLoading && !role) { + navigateSettings(SettingsPath.Roles); + } + }, [role, navigateSettings, rolesLoading]); + + if (!role) return null; + + const tabs = [ + { + id: SETTINGS_ROLE_DETAIL_TABS.TABS_IDS.ASSIGNMENT, + title: t`Assignment`, + Icon: IconUserPlus, + hide: false, + }, + { + id: SETTINGS_ROLE_DETAIL_TABS.TABS_IDS.PERMISSIONS, + title: t`Permissions`, + Icon: IconLockOpen, + hide: false, + }, + ]; + + const renderActiveTabContent = () => { + switch (activeTabId) { + case SETTINGS_ROLE_DETAIL_TABS.TABS_IDS.ASSIGNMENT: + return ; + case SETTINGS_ROLE_DETAIL_TABS.TABS_IDS.PERMISSIONS: + return ; + default: + return null; + } + }; + + return ( + <> + + + + + } + links={[ + { + children: 'Workspace', + href: getSettingsPath(SettingsPath.Workspace), + }, + { + children: 'Roles', + href: getSettingsPath(SettingsPath.Roles), + }, + { + children: role.label, + }, + ]} + > + + + + {renderActiveTabContent()} + + + + + ); +}; diff --git a/packages/twenty-front/src/pages/settings/roles/SettingsRoles.tsx b/packages/twenty-front/src/pages/settings/roles/SettingsRoles.tsx index 775c26e16..7e17ffb7b 100644 --- a/packages/twenty-front/src/pages/settings/roles/SettingsRoles.tsx +++ b/packages/twenty-front/src/pages/settings/roles/SettingsRoles.tsx @@ -23,6 +23,7 @@ import { TableRow } from '@/ui/layout/table/components/TableRow'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useTheme } from '@emotion/react'; import { FeatureFlagKey, useGetRolesQuery } from '~/generated/graphql'; +import { useNavigateSettings } from '~/hooks/useNavigateSettings'; import { getSettingsPath } from '~/utils/navigation/getSettingsPath'; const StyledTable = styled(Table)` @@ -89,6 +90,7 @@ export const SettingsRoles = () => { FeatureFlagKey.IsPermissionsEnabled, ); const theme = useTheme(); + const navigateSettings = useNavigateSettings(); const { data: rolesData, loading: isRolesLoading } = useGetRolesQuery(); @@ -96,6 +98,10 @@ export const SettingsRoles = () => { return null; } + const handleRoleClick = (roleId: string) => { + navigateSettings(SettingsPath.RoleDetail, { roleId }); + }; + return ( { {!isRolesLoading && rolesData?.getRoles.map((role) => ( - + handleRoleClick(role.id)} + > diff --git a/packages/twenty-front/src/pages/settings/roles/components/RoleAssignment.tsx b/packages/twenty-front/src/pages/settings/roles/components/RoleAssignment.tsx new file mode 100644 index 000000000..5e625565c --- /dev/null +++ b/packages/twenty-front/src/pages/settings/roles/components/RoleAssignment.tsx @@ -0,0 +1,19 @@ +import { t } from '@lingui/core/macro'; +import { H2Title, Section } from 'twenty-ui'; +import { Role } from '~/generated-metadata/graphql'; + +type RoleAssignmentProps = { + role: Pick; +}; + +// eslint-disable-next-line unused-imports/no-unused-vars +export const RoleAssignment = ({ role }: RoleAssignmentProps) => { + return ( +
+ +
+ ); +}; diff --git a/packages/twenty-front/src/pages/settings/roles/components/RolePermissions.tsx b/packages/twenty-front/src/pages/settings/roles/components/RolePermissions.tsx new file mode 100644 index 000000000..e9d7f1c36 --- /dev/null +++ b/packages/twenty-front/src/pages/settings/roles/components/RolePermissions.tsx @@ -0,0 +1,19 @@ +import { t } from '@lingui/core/macro'; +import { H2Title, Section } from 'twenty-ui'; +import { Role } from '~/generated-metadata/graphql'; + +type RolePermissionsProps = { + role: Pick; +}; + +// eslint-disable-next-line unused-imports/no-unused-vars +export const RolePermissions = ({ role }: RolePermissionsProps) => { + return ( +
+ +
+ ); +};