[permissions V2] Upsert object and setting permissions (#11119)
Closes https://github.com/twentyhq/core-team-issues/issues/639
This commit is contained in:
@ -5,7 +5,7 @@ import { SettingsProtectedRouteWrapper } from '@/settings/components/SettingsPro
|
||||
import { SettingsSkeletonLoader } from '@/settings/components/SettingsSkeletonLoader';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
import { SettingsPermissions } from '~/generated/graphql';
|
||||
import { SettingPermissionType } from '~/generated/graphql';
|
||||
|
||||
const SettingsApiKeys = lazy(() =>
|
||||
import('~/pages/settings/developers/api-keys/SettingsApiKeys').then(
|
||||
@ -334,7 +334,7 @@ export const SettingsRoutes = ({
|
||||
<Route
|
||||
element={
|
||||
<SettingsProtectedRouteWrapper
|
||||
settingsPermission={SettingsPermissions.WORKSPACE}
|
||||
settingsPermission={SettingPermissionType.WORKSPACE}
|
||||
/>
|
||||
}
|
||||
>
|
||||
@ -345,7 +345,7 @@ export const SettingsRoutes = ({
|
||||
<Route
|
||||
element={
|
||||
<SettingsProtectedRouteWrapper
|
||||
settingsPermission={SettingsPermissions.WORKSPACE_MEMBERS}
|
||||
settingsPermission={SettingPermissionType.WORKSPACE_MEMBERS}
|
||||
/>
|
||||
}
|
||||
>
|
||||
@ -357,7 +357,7 @@ export const SettingsRoutes = ({
|
||||
<Route
|
||||
element={
|
||||
<SettingsProtectedRouteWrapper
|
||||
settingsPermission={SettingsPermissions.DATA_MODEL}
|
||||
settingsPermission={SettingPermissionType.DATA_MODEL}
|
||||
/>
|
||||
}
|
||||
>
|
||||
@ -387,7 +387,7 @@ export const SettingsRoutes = ({
|
||||
<Route
|
||||
element={
|
||||
<SettingsProtectedRouteWrapper
|
||||
settingsPermission={SettingsPermissions.ROLES}
|
||||
settingsPermission={SettingPermissionType.ROLES}
|
||||
requiredFeatureFlag={FeatureFlagKey.IsPermissionsEnabled}
|
||||
/>
|
||||
}
|
||||
@ -398,7 +398,7 @@ export const SettingsRoutes = ({
|
||||
<Route
|
||||
element={
|
||||
<SettingsProtectedRouteWrapper
|
||||
settingsPermission={SettingsPermissions.API_KEYS_AND_WEBHOOKS}
|
||||
settingsPermission={SettingPermissionType.API_KEYS_AND_WEBHOOKS}
|
||||
/>
|
||||
}
|
||||
>
|
||||
@ -465,7 +465,7 @@ export const SettingsRoutes = ({
|
||||
<Route
|
||||
element={
|
||||
<SettingsProtectedRouteWrapper
|
||||
settingsPermission={SettingsPermissions.SECURITY}
|
||||
settingsPermission={SettingPermissionType.SECURITY}
|
||||
/>
|
||||
}
|
||||
>
|
||||
@ -496,7 +496,7 @@ export const SettingsRoutes = ({
|
||||
<Route
|
||||
element={
|
||||
<SettingsProtectedRouteWrapper
|
||||
settingsPermission={SettingsPermissions.WORKSPACE}
|
||||
settingsPermission={SettingPermissionType.WORKSPACE}
|
||||
/>
|
||||
}
|
||||
>
|
||||
|
||||
@ -12,10 +12,10 @@ import { ViewType } from '@/views/types/ViewType';
|
||||
import { useCallback, useContext } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { IconEyeOff, IconSettings } from 'twenty-ui';
|
||||
import { SettingsPermissions } from '~/generated/graphql';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconEyeOff, IconSettings } from 'twenty-ui';
|
||||
import { SettingPermissionType } from '~/generated/graphql';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
|
||||
type UseRecordGroupActionsParams = {
|
||||
viewType: ViewType;
|
||||
@ -71,7 +71,7 @@ export const useRecordGroupActions = ({
|
||||
]);
|
||||
|
||||
const hasAccessToDataModelSettings = useHasSettingsPermission(
|
||||
SettingsPermissions.DATA_MODEL,
|
||||
SettingPermissionType.DATA_MODEL,
|
||||
);
|
||||
|
||||
const recordGroupActions: RecordGroupAction[] = [];
|
||||
|
||||
@ -3,12 +3,12 @@ import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { ReactNode } from 'react';
|
||||
import { Navigate, Outlet } from 'react-router-dom';
|
||||
import { FeatureFlagKey, SettingsPermissions } from '~/generated/graphql';
|
||||
import { FeatureFlagKey, SettingPermissionType } from '~/generated/graphql';
|
||||
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
||||
|
||||
type SettingsProtectedRouteWrapperProps = {
|
||||
children?: ReactNode;
|
||||
settingsPermission?: SettingsPermissions;
|
||||
settingsPermission?: SettingPermissionType;
|
||||
requiredFeatureFlag?: FeatureFlagKey;
|
||||
};
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ import {
|
||||
Billing,
|
||||
FeatureFlagKey,
|
||||
OnboardingStatus,
|
||||
SettingsPermissions,
|
||||
SettingPermissionType,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
@ -61,12 +61,12 @@ jest.mock('@/workspace/hooks/useFeatureFlagsMap', () => ({
|
||||
describe('useSettingsNavigationItems', () => {
|
||||
it('should hide workspace settings when no permissions', () => {
|
||||
(useSettingsPermissionMap as jest.Mock).mockImplementation(() => ({
|
||||
[SettingsPermissions.WORKSPACE]: false,
|
||||
[SettingsPermissions.WORKSPACE_MEMBERS]: false,
|
||||
[SettingsPermissions.DATA_MODEL]: false,
|
||||
[SettingsPermissions.API_KEYS_AND_WEBHOOKS]: false,
|
||||
[SettingsPermissions.ROLES]: false,
|
||||
[SettingsPermissions.SECURITY]: false,
|
||||
[SettingPermissionType.WORKSPACE]: false,
|
||||
[SettingPermissionType.WORKSPACE_MEMBERS]: false,
|
||||
[SettingPermissionType.DATA_MODEL]: false,
|
||||
[SettingPermissionType.API_KEYS_AND_WEBHOOKS]: false,
|
||||
[SettingPermissionType.ROLES]: false,
|
||||
[SettingPermissionType.SECURITY]: false,
|
||||
}));
|
||||
|
||||
const { result } = renderHook(() => useSettingsNavigationItems(), {
|
||||
@ -82,12 +82,12 @@ describe('useSettingsNavigationItems', () => {
|
||||
|
||||
it('should show workspace settings when has permissions', () => {
|
||||
(useSettingsPermissionMap as jest.Mock).mockImplementation(() => ({
|
||||
[SettingsPermissions.WORKSPACE]: true,
|
||||
[SettingsPermissions.WORKSPACE_MEMBERS]: true,
|
||||
[SettingsPermissions.DATA_MODEL]: true,
|
||||
[SettingsPermissions.API_KEYS_AND_WEBHOOKS]: true,
|
||||
[SettingsPermissions.ROLES]: true,
|
||||
[SettingsPermissions.SECURITY]: true,
|
||||
[SettingPermissionType.WORKSPACE]: true,
|
||||
[SettingPermissionType.WORKSPACE_MEMBERS]: true,
|
||||
[SettingPermissionType.DATA_MODEL]: true,
|
||||
[SettingPermissionType.API_KEYS_AND_WEBHOOKS]: true,
|
||||
[SettingPermissionType.ROLES]: true,
|
||||
[SettingPermissionType.SECURITY]: true,
|
||||
}));
|
||||
|
||||
const { result } = renderHook(() => useSettingsNavigationItems(), {
|
||||
|
||||
@ -22,7 +22,6 @@ import {
|
||||
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
import { SettingsPermissions } from '~/generated/graphql';
|
||||
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { billingState } from '@/client-config/states/billingState';
|
||||
@ -32,6 +31,7 @@ import { NavigationDrawerItemIndentationLevel } from '@/ui/navigation/navigation
|
||||
import { useFeatureFlagsMap } from '@/workspace/hooks/useFeatureFlagsMap';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { SettingPermissionType } from '~/generated/graphql';
|
||||
|
||||
export type SettingsNavigationSection = {
|
||||
label: string;
|
||||
@ -108,13 +108,13 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
|
||||
label: t`General`,
|
||||
path: SettingsPath.Workspace,
|
||||
Icon: IconSettings,
|
||||
isHidden: !permissionMap[SettingsPermissions.WORKSPACE],
|
||||
isHidden: !permissionMap[SettingPermissionType.WORKSPACE],
|
||||
},
|
||||
{
|
||||
label: t`Members`,
|
||||
path: SettingsPath.WorkspaceMembersPage,
|
||||
Icon: IconUsers,
|
||||
isHidden: !permissionMap[SettingsPermissions.WORKSPACE_MEMBERS],
|
||||
isHidden: !permissionMap[SettingPermissionType.WORKSPACE_MEMBERS],
|
||||
},
|
||||
{
|
||||
label: t`Roles`,
|
||||
@ -122,33 +122,34 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
|
||||
Icon: IconLock,
|
||||
isHidden:
|
||||
!featureFlags[FeatureFlagKey.IsPermissionsEnabled] ||
|
||||
!permissionMap[SettingsPermissions.ROLES],
|
||||
!permissionMap[SettingPermissionType.ROLES],
|
||||
},
|
||||
{
|
||||
label: t`Billing`,
|
||||
path: SettingsPath.Billing,
|
||||
Icon: IconCurrencyDollar,
|
||||
isHidden:
|
||||
!isBillingEnabled || !permissionMap[SettingsPermissions.WORKSPACE],
|
||||
!isBillingEnabled ||
|
||||
!permissionMap[SettingPermissionType.WORKSPACE],
|
||||
},
|
||||
{
|
||||
label: t`Data model`,
|
||||
path: SettingsPath.Objects,
|
||||
Icon: IconHierarchy2,
|
||||
isHidden: !permissionMap[SettingsPermissions.DATA_MODEL],
|
||||
isHidden: !permissionMap[SettingPermissionType.DATA_MODEL],
|
||||
},
|
||||
{
|
||||
label: t`Integrations`,
|
||||
path: SettingsPath.Integrations,
|
||||
Icon: IconApps,
|
||||
isHidden: !permissionMap[SettingsPermissions.API_KEYS_AND_WEBHOOKS],
|
||||
isHidden: !permissionMap[SettingPermissionType.API_KEYS_AND_WEBHOOKS],
|
||||
},
|
||||
{
|
||||
label: t`Security`,
|
||||
path: SettingsPath.Security,
|
||||
Icon: IconKey,
|
||||
isAdvanced: true,
|
||||
isHidden: !permissionMap[SettingsPermissions.SECURITY],
|
||||
isHidden: !permissionMap[SettingPermissionType.SECURITY],
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -161,14 +162,14 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
|
||||
path: SettingsPath.APIs,
|
||||
Icon: IconApi,
|
||||
isAdvanced: true,
|
||||
isHidden: !permissionMap[SettingsPermissions.API_KEYS_AND_WEBHOOKS],
|
||||
isHidden: !permissionMap[SettingPermissionType.API_KEYS_AND_WEBHOOKS],
|
||||
},
|
||||
{
|
||||
label: t`Webhooks`,
|
||||
path: SettingsPath.Webhooks,
|
||||
Icon: IconWebhook,
|
||||
isAdvanced: true,
|
||||
isHidden: !permissionMap[SettingsPermissions.API_KEYS_AND_WEBHOOKS],
|
||||
isHidden: !permissionMap[SettingPermissionType.API_KEYS_AND_WEBHOOKS],
|
||||
},
|
||||
{
|
||||
label: t`Functions`,
|
||||
@ -194,7 +195,7 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
|
||||
Icon: IconFlask,
|
||||
isHidden:
|
||||
!labPublicFeatureFlags.length ||
|
||||
!permissionMap[SettingsPermissions.WORKSPACE],
|
||||
!permissionMap[SettingPermissionType.WORKSPACE],
|
||||
},
|
||||
{
|
||||
label: t`Releases`,
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { currentUserWorkspaceState } from '@/auth/states/currentUserWorkspaceState';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { SettingsPermissions } from '~/generated/graphql';
|
||||
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
|
||||
import { SettingPermissionType } from '~/generated/graphql';
|
||||
|
||||
export const useHasSettingsPermission = (
|
||||
settingsPermission?: SettingsPermissions,
|
||||
settingsPermission?: SettingPermissionType,
|
||||
) => {
|
||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||
const currentUserWorkspace = useRecoilValue(currentUserWorkspaceState);
|
||||
@ -15,19 +15,18 @@ export const useHasSettingsPermission = (
|
||||
}
|
||||
|
||||
if (
|
||||
settingsPermission === SettingsPermissions.WORKSPACE &&
|
||||
settingsPermission === SettingPermissionType.WORKSPACE &&
|
||||
currentWorkspace?.activationStatus ===
|
||||
WorkspaceActivationStatus.PENDING_CREATION
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const currentUserWorkspaceSettingsPermissions =
|
||||
currentUserWorkspace?.settingsPermissions;
|
||||
const currentUserWorkspaceSetting = currentUserWorkspace?.settingsPermissions;
|
||||
|
||||
if (!currentUserWorkspaceSettingsPermissions) {
|
||||
if (!currentUserWorkspaceSetting) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return currentUserWorkspaceSettingsPermissions.includes(settingsPermission);
|
||||
return currentUserWorkspaceSetting.includes(settingsPermission);
|
||||
};
|
||||
|
||||
@ -2,11 +2,11 @@ import { currentUserWorkspaceState } from '@/auth/states/currentUserWorkspaceSta
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
import { SettingsPermissions } from '~/generated/graphql';
|
||||
import { SettingPermissionType } from '~/generated/graphql';
|
||||
import { buildRecordFromKeysWithSameValue } from '~/utils/array/buildRecordFromKeysWithSameValue';
|
||||
|
||||
export const useSettingsPermissionMap = (): Record<
|
||||
SettingsPermissions,
|
||||
SettingPermissionType,
|
||||
boolean
|
||||
> => {
|
||||
const currentUserWorkspace = useRecoilValue(currentUserWorkspaceState);
|
||||
@ -19,7 +19,7 @@ export const useSettingsPermissionMap = (): Record<
|
||||
currentUserWorkspace?.settingsPermissions;
|
||||
|
||||
const initialPermissions = buildRecordFromKeysWithSameValue(
|
||||
Object.values(SettingsPermissions),
|
||||
Object.values(SettingPermissionType),
|
||||
!isPermissionEnabled,
|
||||
);
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ import {
|
||||
Section,
|
||||
} from 'twenty-ui';
|
||||
import { Role } from '~/generated-metadata/graphql';
|
||||
import { SettingsPermissions } from '~/generated/graphql';
|
||||
import { SettingPermissionType } from '~/generated/graphql';
|
||||
import { RolePermissionsObjectsTableRow } from './RolePermissionsObjectsTableRow';
|
||||
|
||||
const StyledRolePermissionsContainer = styled.div`
|
||||
@ -81,49 +81,49 @@ export const RolePermissions = ({ role }: RolePermissionsProps) => {
|
||||
|
||||
const settingsPermissionsConfig: RolePermissionsSettingPermission[] = [
|
||||
{
|
||||
key: SettingsPermissions.API_KEYS_AND_WEBHOOKS,
|
||||
key: SettingPermissionType.API_KEYS_AND_WEBHOOKS,
|
||||
name: 'API Keys & Webhooks',
|
||||
description: 'Manage API keys and webhooks',
|
||||
value: role.canUpdateAllSettings,
|
||||
Icon: IconCode,
|
||||
},
|
||||
{
|
||||
key: SettingsPermissions.WORKSPACE,
|
||||
key: SettingPermissionType.WORKSPACE,
|
||||
name: 'Workspace',
|
||||
description: 'Set global workspace preferences',
|
||||
value: role.canUpdateAllSettings,
|
||||
Icon: IconSettings,
|
||||
},
|
||||
{
|
||||
key: SettingsPermissions.WORKSPACE_MEMBERS,
|
||||
key: SettingPermissionType.WORKSPACE_MEMBERS,
|
||||
name: 'Users',
|
||||
description: 'Add or remove users',
|
||||
value: role.canUpdateAllSettings,
|
||||
Icon: IconUsers,
|
||||
},
|
||||
{
|
||||
key: SettingsPermissions.ROLES,
|
||||
key: SettingPermissionType.ROLES,
|
||||
name: 'Roles',
|
||||
description: 'Define user roles and access levels',
|
||||
value: role.canUpdateAllSettings,
|
||||
Icon: IconLockOpen,
|
||||
},
|
||||
{
|
||||
key: SettingsPermissions.DATA_MODEL,
|
||||
key: SettingPermissionType.DATA_MODEL,
|
||||
name: 'Data Model',
|
||||
description: 'Edit CRM data structure and fields',
|
||||
value: role.canUpdateAllSettings,
|
||||
Icon: IconHierarchy,
|
||||
},
|
||||
{
|
||||
key: SettingsPermissions.ADMIN_PANEL,
|
||||
key: SettingPermissionType.ADMIN_PANEL,
|
||||
name: 'Admin Panel',
|
||||
description: 'Admin settings and system tools',
|
||||
value: role.canUpdateAllSettings,
|
||||
Icon: IconServer,
|
||||
},
|
||||
{
|
||||
key: SettingsPermissions.SECURITY,
|
||||
key: SettingPermissionType.SECURITY,
|
||||
name: 'Security',
|
||||
description: 'Manage security policies',
|
||||
value: role.canUpdateAllSettings,
|
||||
|
||||
Reference in New Issue
Block a user