Jotai 13 (#18178)
## Recoil to Jotai Migration — PR 13: Workflow, Page Layout, AI, Activities, Settings, SSE & Remaining Modules ### Summary This is the 13th PR in the [14-PR migration series](packages/twenty-front/src/modules/ui/utilities/state/jotai/MIGRATION_PLAN.md) to replace Recoil with Jotai as the state management library in `twenty-front`. This PR migrates the remaining consumer code across all modules — updating ~1,076 files with ~10k insertions/deletions. ### What changed **New Jotai infrastructure (13 new files):** - `createComponentSelectorV2` and `createComponentFamilySelectorV2` — instance-scoped derived atoms, replacing Recoil's component selectors - 6 new hooks: `useRecoilComponentSelectorValueV2`, `useRecoilComponentFamilySelectorValueV2`, `useRecoilComponentSelectorCallbackStateV2`, `useRecoilComponentFamilySelectorCallbackStateV2`, `useRecoilComponentStateCallbackStateV2`, `useRecoilComponentFamilyStateCallbackStateV2` - New types: `ComponentSelectorV2`, `ComponentFamilySelectorV2`, `SelectorCallbacksV2` - Extended `buildGetHelper` to support the new selector patterns **State definition migrations:** - `createState()` → `createStateV2()` (Jotai `atom()`) - `createFamilyState()` → `createFamilyStateV2()` (Jotai `atom()` with family cache) - Recoil `selector`/`selectorFamily` → Jotai derived `atom()` via V2 utilities **Hook migrations (~2,400 removed, ~1,545 added V2 equivalents):** - `useRecoilValue` → `useRecoilValueV2` - `useRecoilState` → `useRecoilStateV2` - `useSetRecoilState` → `useSetRecoilStateV2` - `useRecoilCallback` → `useCallback` + `jotaiStore.get/set` - `useRecoilComponentValue` → `useRecoilComponentValueV2` - `useSetRecoilComponentState` → `useSetRecoilComponentStateV2` - `useRecoilComponentFamilyValue` → `useRecoilComponentFamilyValueV2` / `useFamilySelectorValueV2` - ~397 direct `import from 'recoil'` removed **Deleted files (9 files):** - `dateLocaleState.ts` — consolidated - `currentAIChatThreadTitleStateV2.ts` — renamed to replace the original - `isCommandMenuOpenedState.ts` — removed - `filesFieldUploadState.ts` — replaced by V2 - `recordStoreFamilySelector.ts`, `recordStoreFieldValueSelector.ts`, `recordStoreRecordsSelector.ts` — replaced by V2 equivalents - `settingsAllRolesSelector.ts` — replaced by `useSettingsAllRoles` hook - `settingsRoleIdsStateV2.ts` — consolidated **Modules migrated:** - Workflow (diagram, steps, variables, filters) - Page Layout (widgets, fields, graph, tabs) - AI (chat, agents, browsing context) - Activities (rich text editor, targets, timeline) - Action Menu (single/multiple record actions) - Command Menu (navigation, history, pages, workflow) - Context Store - Record Board, Record Table, Record Calendar, Record Index - Record Field, Record Filter, Record Sort, Record Group - Record Drag, Record Picker, Record Store - Views (view bar, view picker, filters, sorts) - Settings (roles, permissions, SSO, security, data model, developers, domains) - SSE (event streams, subscriptions) - Spreadsheet Import - Auth, Favorites, Front Components, Information Banner
This commit is contained in:
+4
-4
@@ -1,6 +1,6 @@
|
||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||
import { recordStoreFamilySelectorV2 } from '@/object-record/record-store/states/selectors/recordStoreFamilySelectorV2';
|
||||
import { useEffect } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { useSetAtom } from 'jotai';
|
||||
|
||||
type SettingsDataModelSetFieldValueEffectProps = {
|
||||
recordId: string;
|
||||
@@ -13,8 +13,8 @@ export const SettingsDataModelSetFieldValueEffect = ({
|
||||
gqlFieldName,
|
||||
value,
|
||||
}: SettingsDataModelSetFieldValueEffectProps) => {
|
||||
const setFieldValue = useSetRecoilState(
|
||||
recordStoreFamilySelector({
|
||||
const setFieldValue = useSetAtom(
|
||||
recordStoreFamilySelectorV2.selectorFamily({
|
||||
recordId,
|
||||
fieldName: gqlFieldName,
|
||||
}),
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { usePreviewRecord } from '@/settings/data-model/fields/preview/hooks/usePreviewRecord';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { useEffect } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
type SettingsDataModelSetLabelIdentifierRecordEffectProps = {
|
||||
objectNameSingular: string;
|
||||
@@ -16,7 +16,7 @@ export const SettingsDataModelSetLabelIdentifierRecordEffect = ({
|
||||
objectNameSingular: objectNameSingular,
|
||||
});
|
||||
|
||||
const setRecord = useSetRecoilState(recordStoreFamilyState(recordId));
|
||||
const setRecord = useSetFamilyRecoilStateV2(recordStoreFamilyState, recordId);
|
||||
|
||||
useEffect(() => {
|
||||
setRecord(recordPreviewForLabelIdentifier);
|
||||
|
||||
+4
-5
@@ -13,8 +13,8 @@ import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { useMemo } from 'react';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { FieldMetadataType, SettingsPath } from 'twenty-shared/types';
|
||||
import { getSettingsPath, isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
@@ -139,10 +139,9 @@ export const SettingsObjectFieldItemTableRow = ({
|
||||
|
||||
const { deleteOneFieldMetadataItem } = useDeleteOneFieldMetadataItem();
|
||||
|
||||
const [, setActiveSettingsObjectFields] = useRecoilState(
|
||||
settingsObjectFieldsFamilyState({
|
||||
objectMetadataItemId: objectMetadataItem.id,
|
||||
}),
|
||||
const setActiveSettingsObjectFields = useSetFamilyRecoilStateV2(
|
||||
settingsObjectFieldsFamilyState,
|
||||
{ objectMetadataItemId: objectMetadataItem.id },
|
||||
);
|
||||
|
||||
const handleToggleField = () => {
|
||||
|
||||
+1
-2
@@ -11,7 +11,6 @@ import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMe
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
@@ -28,7 +27,7 @@ export const SettingsUpdateDataModelObjectAboutForm = ({
|
||||
objectMetadataItem,
|
||||
});
|
||||
const navigate = useNavigateSettings();
|
||||
const setUpdatedObjectNamePlural = useSetRecoilState(
|
||||
const setUpdatedObjectNamePlural = useSetRecoilStateV2(
|
||||
updatedObjectNamePluralState,
|
||||
);
|
||||
const setNavigationMemorizedUrl = useSetRecoilStateV2(
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
|
||||
import { createFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createFamilyStateV2';
|
||||
|
||||
export type SortedFieldByTableFamilyStateKey = {
|
||||
objectMetadataItemId: string;
|
||||
};
|
||||
|
||||
export const settingsObjectFieldsFamilyState = createFamilyState<
|
||||
export const settingsObjectFieldsFamilyState = createFamilyStateV2<
|
||||
FieldMetadataItem[] | null,
|
||||
SortedFieldByTableFamilyStateKey
|
||||
>({
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
import { type IndexMetadataItem } from '@/object-metadata/types/IndexMetadataItem';
|
||||
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
|
||||
import { createFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createFamilyStateV2';
|
||||
|
||||
export type SortedIndexByTableFamilyStateKey = {
|
||||
objectMetadataItemId: string;
|
||||
};
|
||||
|
||||
export const settingsObjectIndexesFamilyState = createFamilyState<
|
||||
export const settingsObjectIndexesFamilyState = createFamilyStateV2<
|
||||
IndexMetadataItem[] | null,
|
||||
SortedIndexByTableFamilyStateKey
|
||||
>({
|
||||
|
||||
+5
-2
@@ -1,6 +1,9 @@
|
||||
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
|
||||
import { createFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createFamilyStateV2';
|
||||
|
||||
export const apiKeyTokenFamilyState = createFamilyState<string | null, string>({
|
||||
export const apiKeyTokenFamilyState = createFamilyStateV2<
|
||||
string | null,
|
||||
string
|
||||
>({
|
||||
key: 'apiKeyTokenState',
|
||||
defaultValue: null,
|
||||
});
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ import {
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { CheckPublicDomainValidRecordsEffect } from '@/settings/domains/components/CheckPublicDomainValidRecordsEffect';
|
||||
import { selectedPublicDomainState } from '@/settings/domains/states/selectedPublicDomainState';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
|
||||
import { useState } from 'react';
|
||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||
import { getDomainValidationSchema } from '@/settings/domains/utils/get-domain-validation-schema';
|
||||
@@ -48,7 +48,7 @@ const StyledRecordsWrapper = styled.div`
|
||||
`;
|
||||
|
||||
export const SettingPublicDomain = () => {
|
||||
const [selectedPublicDomain, setSelectedPublicDomain] = useRecoilState(
|
||||
const [selectedPublicDomain, setSelectedPublicDomain] = useRecoilStateV2(
|
||||
selectedPublicDomainState,
|
||||
);
|
||||
const { t } = useLingui();
|
||||
|
||||
+1
-2
@@ -4,7 +4,6 @@ import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { H2Title, IconReload, IconTrash } from 'twenty-ui/display';
|
||||
import { Button, ButtonGroup } from 'twenty-ui/input';
|
||||
@@ -38,7 +37,7 @@ const StyledRecordsWrapper = styled.div`
|
||||
`;
|
||||
|
||||
export const SettingsCustomDomain = () => {
|
||||
const { customDomainRecords, isLoading } = useRecoilValue(
|
||||
const { customDomainRecords, isLoading } = useRecoilValueV2(
|
||||
customDomainRecordsState,
|
||||
);
|
||||
|
||||
|
||||
+4
-2
@@ -2,8 +2,8 @@ import { SettingsCard } from '@/settings/components/SettingsCard';
|
||||
import { SettingsListCard } from '@/settings/components/SettingsListCard';
|
||||
import { SettingPublicDomainRowDropdownMenu } from '@/settings/domains/components/SettingPublicDomainRowDropdownMenu';
|
||||
import { selectedPublicDomainState } from '@/settings/domains/states/selectedPublicDomainState';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import { IconAt, IconMailCog, Status } from 'twenty-ui/display';
|
||||
import {
|
||||
@@ -17,7 +17,9 @@ export const SettingsPublicDomainsListCard = () => {
|
||||
|
||||
const { t } = useLingui();
|
||||
|
||||
const setSelectedPublicDomain = useSetRecoilState(selectedPublicDomainState);
|
||||
const setSelectedPublicDomain = useSetRecoilStateV2(
|
||||
selectedPublicDomainState,
|
||||
);
|
||||
|
||||
const { data, loading } = useFindManyPublicDomainsQuery();
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import { useCheckCustomDomainValidRecordsMutation } from '~/generated-metadata/graphql';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { customDomainRecordsState } from '@/settings/domains/states/customDomainRecordsState';
|
||||
@@ -12,7 +12,7 @@ export const useCheckCustomDomainValidRecords = () => {
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const currentWorkspace = useRecoilValueV2(currentWorkspaceState);
|
||||
|
||||
const [{ isLoading }, setCustomDomainRecords] = useRecoilState(
|
||||
const [{ isLoading }, setCustomDomainRecords] = useRecoilStateV2(
|
||||
customDomainRecordsState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
import { type DomainValidRecords } from '~/generated-metadata/graphql';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export const customDomainRecordsState = createState<{
|
||||
export const customDomainRecordsState = createStateV2<{
|
||||
customDomainRecords: DomainValidRecords | null;
|
||||
isLoading: boolean;
|
||||
}>({
|
||||
|
||||
+4
-2
@@ -1,7 +1,9 @@
|
||||
import { type PublicDomain } from '~/generated-metadata/graphql';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
|
||||
export const selectedPublicDomainState = createState<PublicDomain | undefined>({
|
||||
export const selectedPublicDomainState = createStateV2<
|
||||
PublicDomain | undefined
|
||||
>({
|
||||
key: 'selectedPublicDomainState',
|
||||
defaultValue: undefined,
|
||||
});
|
||||
|
||||
+11
-9
@@ -1,11 +1,9 @@
|
||||
import { LogicFunctionExecutionResult } from '@/logic-functions/components/LogicFunctionExecutionResult';
|
||||
import {
|
||||
type LogicFunctionTestData,
|
||||
logicFunctionTestDataFamilyState,
|
||||
} from '@/workflow/workflow-steps/workflow-actions/code-action/states/logicFunctionTestDataFamilyState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { logicFunctionTestDataFamilyState } from '@/workflow/workflow-steps/workflow-actions/code-action/states/logicFunctionTestDataFamilyState';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { H2Title, IconPlayerPlay } from 'twenty-ui/display';
|
||||
import { Button, CodeEditor, CoreEditorHeader } from 'twenty-ui/input';
|
||||
import { Section } from 'twenty-ui/layout';
|
||||
@@ -33,10 +31,14 @@ export const SettingsLogicFunctionTestTab = ({
|
||||
isTesting?: boolean;
|
||||
}) => {
|
||||
const { t } = useLingui();
|
||||
const [logicFunctionTestData, setLogicFunctionTestData] =
|
||||
useRecoilState<LogicFunctionTestData>(
|
||||
logicFunctionTestDataFamilyState(logicFunctionId),
|
||||
);
|
||||
const logicFunctionTestData = useFamilyRecoilValueV2(
|
||||
logicFunctionTestDataFamilyState,
|
||||
logicFunctionId,
|
||||
);
|
||||
const setLogicFunctionTestData = useSetFamilyRecoilStateV2(
|
||||
logicFunctionTestDataFamilyState,
|
||||
logicFunctionId,
|
||||
);
|
||||
|
||||
const onChange = (newInput: string) => {
|
||||
setLogicFunctionTestData((prev) => ({
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
import { type FindManyLogicFunctionsQuery } from '~/generated-metadata/graphql';
|
||||
|
||||
export type LogicFunction =
|
||||
FindManyLogicFunctionsQuery['findManyLogicFunctions'][number];
|
||||
|
||||
export const logicFunctionsState = createState<LogicFunction[]>({
|
||||
export const logicFunctionsState = createStateV2<LogicFunction[]>({
|
||||
key: 'logicFunctionsState',
|
||||
defaultValue: [],
|
||||
});
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { settingsAllRolesSelector } from '@/settings/roles/states/settingsAllRolesSelector';
|
||||
import { useSettingsAllRoles } from '@/settings/roles/hooks/useSettingsAllRoles';
|
||||
import { settingsRolesIsLoadingStateV2 } from '@/settings/roles/states/settingsRolesIsLoadingStateV2';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
export const useWorkspaceMemberRoles = (workspaceMemberId: string) => {
|
||||
const settingsAllRoles = useRecoilValue(settingsAllRolesSelector);
|
||||
const settingsAllRoles = useSettingsAllRoles();
|
||||
const settingsRolesIsLoading = useRecoilValueV2(
|
||||
settingsRolesIsLoadingStateV2,
|
||||
);
|
||||
|
||||
+2
-2
@@ -1,5 +1,6 @@
|
||||
import { playgroundApiKeyState } from '@/settings/playground/states/playgroundApiKeyState';
|
||||
import { PlaygroundSchemas } from '@/settings/playground/types/PlaygroundSchemas';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { explorerPlugin } from '@graphiql/plugin-explorer';
|
||||
import '@graphiql/plugin-explorer/dist/style.css';
|
||||
@@ -7,7 +8,6 @@ import { createGraphiQLFetcher } from '@graphiql/toolkit';
|
||||
import { GraphiQL } from 'graphiql';
|
||||
import 'graphiql/graphiql.css';
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||
|
||||
@@ -35,7 +35,7 @@ export const GraphQLPlayground = ({
|
||||
onError,
|
||||
schema,
|
||||
}: GraphQLPlaygroundProps) => {
|
||||
const playgroundApiKey = useRecoilValue(playgroundApiKeyState);
|
||||
const playgroundApiKey = useRecoilValueV2(playgroundApiKeyState);
|
||||
const baseUrl = REACT_APP_SERVER_BASE_URL + '/' + schemaToPath[schema];
|
||||
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
+2
-2
@@ -4,11 +4,11 @@ import { PlaygroundSchemas } from '@/settings/playground/types/PlaygroundSchemas
|
||||
import { PlaygroundTypes } from '@/settings/playground/types/PlaygroundTypes';
|
||||
import { Select } from '@/ui/input/components/Select';
|
||||
import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput';
|
||||
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import { CustomError } from 'twenty-shared/utils';
|
||||
import { IconApi, IconBrandGraphql } from 'twenty-ui/display';
|
||||
@@ -37,7 +37,7 @@ const StyledForm = styled.form`
|
||||
export const PlaygroundSetupForm = () => {
|
||||
const { t } = useLingui();
|
||||
const navigateSettings = useNavigateSettings();
|
||||
const [playgroundApiKey, setPlaygroundApiKey] = useRecoilState(
|
||||
const [playgroundApiKey, setPlaygroundApiKey] = useRecoilStateV2(
|
||||
playgroundApiKeyState,
|
||||
);
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { playgroundApiKeyState } from '@/settings/playground/states/playgroundApiKeyState';
|
||||
import { type PlaygroundSchemas } from '@/settings/playground/types/PlaygroundSchemas';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { lazy, Suspense } from 'react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import { getSettingsPath } from 'twenty-shared/utils';
|
||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||
@@ -51,7 +51,7 @@ type RestPlaygroundProps = {
|
||||
|
||||
export const RestPlayground = ({ onError, schema }: RestPlaygroundProps) => {
|
||||
const theme = useTheme();
|
||||
const playgroundApiKey = useRecoilValue(playgroundApiKeyState);
|
||||
const playgroundApiKey = useRecoilValueV2(playgroundApiKeyState);
|
||||
|
||||
if (!playgroundApiKey) {
|
||||
onError();
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import { GraphQLPlayground } from '@/settings/playground/components/GraphQLPlayground';
|
||||
import { playgroundApiKeyState } from '@/settings/playground/states/playgroundApiKeyState';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
||||
import { useEffect } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { action } from 'storybook/actions';
|
||||
import {
|
||||
ComponentDecorator,
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
|
||||
const PlaygroundApiKeySetterEffect = () => {
|
||||
const setPlaygroundApiKey = useSetRecoilState(playgroundApiKeyState);
|
||||
const setPlaygroundApiKey = useSetRecoilStateV2(playgroundApiKeyState);
|
||||
|
||||
useEffect(() => {
|
||||
setPlaygroundApiKey('test-api-key-123');
|
||||
|
||||
+2
-2
@@ -1,15 +1,15 @@
|
||||
import { RestPlayground } from '@/settings/playground/components/RestPlayground';
|
||||
import { playgroundApiKeyState } from '@/settings/playground/states/playgroundApiKeyState';
|
||||
import { PlaygroundSchemas } from '@/settings/playground/types/PlaygroundSchemas';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
||||
import { HttpResponse, http } from 'msw';
|
||||
import { useEffect } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { action } from 'storybook/actions';
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
|
||||
const PlaygroundApiKeySetterEffect = () => {
|
||||
const setPlaygroundApiKey = useSetRecoilState(playgroundApiKeyState);
|
||||
const setPlaygroundApiKey = useSetRecoilStateV2(playgroundApiKeyState);
|
||||
|
||||
useEffect(() => {
|
||||
setPlaygroundApiKey('test-api-key-123');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
export const openAPIReferenceState = createState<any>({
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
export const openAPIReferenceState = createStateV2<any>({
|
||||
key: 'OpenAPIReference',
|
||||
defaultValue: null,
|
||||
});
|
||||
|
||||
+4
-5
@@ -1,8 +1,7 @@
|
||||
import { atom } from 'recoil';
|
||||
import { localStorageEffect } from '~/utils/recoil/localStorageEffect';
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
|
||||
export const playgroundApiKeyState = atom<string | null>({
|
||||
export const playgroundApiKeyState = createStateV2<string | null>({
|
||||
key: 'playgroundApiKeyState',
|
||||
default: null,
|
||||
effects: [localStorageEffect()],
|
||||
defaultValue: null,
|
||||
useLocalStorage: true,
|
||||
});
|
||||
|
||||
+2
-3
@@ -6,18 +6,17 @@ import { SettingsPageContainer } from '@/settings/components/SettingsPageContain
|
||||
import { SettingsRoleDefaultRole } from '@/settings/roles/components/SettingsRolesDefaultRole';
|
||||
|
||||
import { SettingsRolesList } from '@/settings/roles/components/SettingsRolesList';
|
||||
import { settingsAllRolesSelector } from '@/settings/roles/states/settingsAllRolesSelector';
|
||||
import { useSettingsAllRoles } from '@/settings/roles/hooks/useSettingsAllRoles';
|
||||
import { settingsRolesIsLoadingStateV2 } from '@/settings/roles/states/settingsRolesIsLoadingStateV2';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { H3Title } from 'twenty-ui/display';
|
||||
|
||||
export const SettingsRolesContainer = () => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const settingsAllRoles = useRecoilValue(settingsAllRolesSelector);
|
||||
const settingsAllRoles = useSettingsAllRoles();
|
||||
const settingsRolesIsLoading = useRecoilValueV2(
|
||||
settingsRolesIsLoadingStateV2,
|
||||
);
|
||||
|
||||
@@ -7,11 +7,10 @@ import { t } from '@lingui/core/macro';
|
||||
|
||||
import { SettingsRolesTableHeader } from '@/settings/roles/components/SettingsRolesTableHeader';
|
||||
import { SettingsRolesTableRow } from '@/settings/roles/components/SettingsRolesTableRow';
|
||||
import { settingsAllRolesSelector } from '@/settings/roles/states/settingsAllRolesSelector';
|
||||
import { useSettingsAllRoles } from '@/settings/roles/hooks/useSettingsAllRoles';
|
||||
import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { useState } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import {
|
||||
H2Title,
|
||||
@@ -61,7 +60,7 @@ export const SettingsRolesList = () => {
|
||||
const [showAgentRoles, setShowAgentRoles] = useState(false);
|
||||
const [showApiKeyRoles, setShowApiKeyRoles] = useState(false);
|
||||
|
||||
const settingsAllRoles = useRecoilValue(settingsAllRolesSelector);
|
||||
const settingsAllRoles = useSettingsAllRoles();
|
||||
|
||||
const sortedSettingsAllRoles = [...settingsAllRoles].sort((a, b) =>
|
||||
sortByAscString(a.label, b.label),
|
||||
|
||||
+21
-28
@@ -1,14 +1,11 @@
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { settingsPersistedRoleFamilyState } from '@/settings/roles/states/settingsPersistedRoleFamilyState';
|
||||
import { settingsRoleIdsState } from '@/settings/roles/states/settingsRoleIdsState';
|
||||
import { settingsRoleIdsStateV2 } from '@/settings/roles/states/settingsRoleIdsStateV2';
|
||||
import { settingsRolesIsLoadingStateV2 } from '@/settings/roles/states/settingsRolesIsLoadingStateV2';
|
||||
import { type RoleWithPartialMembers } from '@/settings/roles/types/RoleWithPartialMembers';
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { useEffect } from 'react';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { useStore } from 'jotai';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useGetRolesQuery } from '~/generated-metadata/graphql';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
@@ -24,34 +21,30 @@ export const SettingsRolesQueryEffect = () => {
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const populateRoles = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(roles: RoleWithPartialMembers[]) => {
|
||||
const roleIds = roles.map((role) => role.id);
|
||||
set(settingsRoleIdsState, roleIds);
|
||||
store.set(settingsRoleIdsStateV2.atom, roleIds);
|
||||
roles.forEach((role) => {
|
||||
const persistedRole = getSnapshotValue(
|
||||
snapshot,
|
||||
settingsPersistedRoleFamilyState(role.id),
|
||||
);
|
||||
const populateRoles = useCallback(
|
||||
(roles: RoleWithPartialMembers[]) => {
|
||||
const roleIds = roles.map((role) => role.id);
|
||||
store.set(settingsRoleIdsState.atom, roleIds);
|
||||
roles.forEach((role) => {
|
||||
const persistedRole = store.get(
|
||||
settingsPersistedRoleFamilyState.atomFamily(role.id),
|
||||
);
|
||||
|
||||
const currentDraftRole = getSnapshotValue(
|
||||
snapshot,
|
||||
settingsDraftRoleFamilyState(role.id),
|
||||
);
|
||||
const currentDraftRole = store.get(
|
||||
settingsDraftRoleFamilyState.atomFamily(role.id),
|
||||
);
|
||||
|
||||
if (isDeeplyEqual(role, persistedRole)) {
|
||||
return;
|
||||
}
|
||||
if (isDeeplyEqual(role, persistedRole)) {
|
||||
return;
|
||||
}
|
||||
|
||||
set(settingsPersistedRoleFamilyState(role.id), role);
|
||||
store.set(settingsPersistedRoleFamilyState.atomFamily(role.id), role);
|
||||
|
||||
if (!isDeeplyEqual(currentDraftRole, role)) {
|
||||
set(settingsDraftRoleFamilyState(role.id), role);
|
||||
}
|
||||
});
|
||||
},
|
||||
if (!isDeeplyEqual(currentDraftRole, role)) {
|
||||
store.set(settingsDraftRoleFamilyState.atomFamily(role.id), role);
|
||||
}
|
||||
});
|
||||
},
|
||||
[store],
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { settingsPersistedRoleFamilyState } from '@/settings/roles/states/settingsPersistedRoleFamilyState';
|
||||
import { settingsRoleIdsState } from '@/settings/roles/states/settingsRoleIdsState';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useStore } from 'jotai';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useSettingsAllRoles = () => {
|
||||
const roleIds = useRecoilValueV2(settingsRoleIdsState);
|
||||
const store = useStore();
|
||||
|
||||
const roles = roleIds
|
||||
.map((roleId) =>
|
||||
store.get(settingsPersistedRoleFamilyState.atomFamily(roleId)),
|
||||
)
|
||||
.filter(isDefined);
|
||||
|
||||
return roles;
|
||||
};
|
||||
@@ -1,13 +1,19 @@
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import {
|
||||
useAssignRoleToAgentMutation,
|
||||
type Agent,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
export const useUpdateAgentRole = (roleId: string) => {
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const [assignRoleToAgentMutation] = useAssignRoleToAgentMutation();
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import {
|
||||
useAssignRoleToApiKeyMutation,
|
||||
type ApiKeyForRole,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
export const useUpdateApiKeyRole = (roleId: string) => {
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const [assignRoleToApiKeyMutation] = useAssignRoleToApiKeyMutation();
|
||||
|
||||
+13
-6
@@ -1,8 +1,9 @@
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { settingsPersistedRoleFamilyState } from '@/settings/roles/states/settingsPersistedRoleFamilyState';
|
||||
import { useRecoilState, useSetRecoilState } from 'recoil';
|
||||
import { useUpdateWorkspaceMemberRoleMutation } from '~/generated-metadata/graphql';
|
||||
import { type PartialWorkspaceMember } from '@/settings/roles/types/RoleWithPartialMembers';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { useUpdateWorkspaceMemberRoleMutation } from '~/generated-metadata/graphql';
|
||||
|
||||
type AddWorkspaceMemberToRoleAndUpdateStateParams = {
|
||||
workspaceMemberId: string;
|
||||
@@ -18,11 +19,17 @@ type AddWorkspaceMembersToRoleParams = {
|
||||
};
|
||||
|
||||
export const useUpdateWorkspaceMemberRole = (roleId: string) => {
|
||||
const setSettingsPersistedRole = useSetRecoilState(
|
||||
settingsPersistedRoleFamilyState(roleId),
|
||||
const setSettingsPersistedRole = useSetFamilyRecoilStateV2(
|
||||
settingsPersistedRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const [updateWorkspaceMemberRoleMutation] =
|
||||
|
||||
+6
-5
@@ -6,14 +6,14 @@ import { useUpdateWorkspaceMemberRole } from '@/settings/roles/hooks/useUpdateWo
|
||||
import { RoleAssignmentSection } from '@/settings/roles/role-assignment/components/RoleAssignmentSection';
|
||||
import { SettingsRoleAssignmentConfirmationModal } from '@/settings/roles/role-assignment/components/SettingsRoleAssignmentConfirmationModal';
|
||||
import { type SettingsRoleAssignmentConfirmationModalSelectedRoleTarget } from '@/settings/roles/role-assignment/types/SettingsRoleAssignmentConfirmationModalSelectedRoleTarget';
|
||||
import { settingsAllRolesSelector } from '@/settings/roles/states/settingsAllRolesSelector';
|
||||
import { useSettingsAllRoles } from '@/settings/roles/hooks/useSettingsAllRoles';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useModal } from '@/ui/layout/modal/hooks/useModal';
|
||||
import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpenedComponentState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useState } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import {
|
||||
@@ -40,8 +40,9 @@ export const SettingsRoleAssignment = ({
|
||||
}: SettingsRoleAssignmentProps) => {
|
||||
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
|
||||
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const navigateSettings = useNavigateSettings();
|
||||
@@ -69,7 +70,7 @@ export const SettingsRoleAssignment = ({
|
||||
currentWorkspaceMembersState,
|
||||
);
|
||||
const currentWorkspaceMember = useRecoilValueV2(currentWorkspaceMemberState);
|
||||
const settingsAllRoles = useRecoilValue(settingsAllRolesSelector);
|
||||
const settingsAllRoles = useSettingsAllRoles();
|
||||
|
||||
const roleMaps = buildRoleMaps(settingsAllRoles);
|
||||
|
||||
|
||||
+4
-3
@@ -4,13 +4,13 @@ import {
|
||||
} from '@/settings/roles/role-assignment/components/SettingsRoleAssignmentTableRow';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { H2Title, IconSearch } from 'twenty-ui/display';
|
||||
import { type Agent, type ApiKeyForRole } from '~/generated-metadata/graphql';
|
||||
@@ -52,8 +52,9 @@ export const SettingsRoleAssignmentTable = <T extends RoleTargetType>({
|
||||
roleTargetType,
|
||||
roleId,
|
||||
}: SettingsRoleAssignmentTableProps<T>) => {
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const [searchFilter, setSearchFilter] = useState('');
|
||||
|
||||
|
||||
+2
-3
@@ -6,7 +6,6 @@ import { useTheme } from '@emotion/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import styled from '@emotion/styled';
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import {
|
||||
Avatar,
|
||||
@@ -15,7 +14,7 @@ import {
|
||||
useIcons,
|
||||
} from 'twenty-ui/display';
|
||||
import { type Agent, type ApiKeyForRole } from '~/generated-metadata/graphql';
|
||||
import { dateLocaleState } from '~/localization/states/dateLocaleState';
|
||||
import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2';
|
||||
import { formatDateString } from '~/utils/string/formatDateString';
|
||||
import { type PartialWorkspaceMember } from '@/settings/roles/types/RoleWithPartialMembers';
|
||||
|
||||
@@ -61,7 +60,7 @@ export const SettingsRoleAssignmentTableRow = ({
|
||||
);
|
||||
const { getIcon } = useIcons();
|
||||
const { dateFormat, timeZone } = useContext(UserContext);
|
||||
const dateLocale = useRecoilValue(dateLocaleState);
|
||||
const dateLocale = useRecoilValueV2(dateLocaleStateV2);
|
||||
|
||||
const renderIcon = () => {
|
||||
switch (roleTarget.type) {
|
||||
|
||||
+4
-3
@@ -1,7 +1,7 @@
|
||||
import { SettingsRoleAssignment } from '@/settings/roles/role-assignment/components/SettingsRoleAssignment';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
||||
import { getRolesMock } from '~/testing/mock-data/roles';
|
||||
@@ -9,8 +9,9 @@ import { getRolesMock } from '~/testing/mock-data/roles';
|
||||
const SettingsRoleAssignmentWrapper = (
|
||||
args: React.ComponentProps<typeof SettingsRoleAssignment>,
|
||||
) => {
|
||||
const setDraftRole = useSetRecoilState(
|
||||
settingsDraftRoleFamilyState(args.roleId),
|
||||
const setDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
args.roleId,
|
||||
);
|
||||
|
||||
const role = getRolesMock().find((role) => role.id === args.roleId);
|
||||
|
||||
+4
-3
@@ -1,7 +1,7 @@
|
||||
import { SettingsRolePermissions } from '@/settings/roles/role-permissions/components/SettingsRolePermissions';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
||||
import { getRolesMock } from '~/testing/mock-data/roles';
|
||||
@@ -9,8 +9,9 @@ import { getRolesMock } from '~/testing/mock-data/roles';
|
||||
const SettingsRolePermissionsWrapper = (
|
||||
args: React.ComponentProps<typeof SettingsRolePermissions>,
|
||||
) => {
|
||||
const setDraftRole = useSetRecoilState(
|
||||
settingsDraftRoleFamilyState(args.roleId),
|
||||
const setDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
args.roleId,
|
||||
);
|
||||
|
||||
const role = getRolesMock().find((role) => role.id === args.roleId);
|
||||
|
||||
+4
-3
@@ -4,9 +4,9 @@ import { PermissionIcon } from '@/settings/roles/role-permissions/objects-permis
|
||||
import { SETTINGS_ROLE_OBJECT_LEVEL_PERMISSION_TO_ROLE_OBJECT_PERMISSION_MAPPING } from '@/settings/roles/role-permissions/objects-permissions/constants/SettingsRoleObjectLevelPermissionToRoleObjectPermissionMapping';
|
||||
import { type SettingsRoleObjectPermissionKey } from '@/settings/roles/role-permissions/objects-permissions/constants/SettingsRoleObjectPermissionIconConfig';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { AppTooltip, TooltipDelay } from 'twenty-ui/display';
|
||||
|
||||
@@ -27,8 +27,9 @@ export const SettingsRolePermissionsObjectLevelOverrideCell = ({
|
||||
roleId,
|
||||
objectLabel,
|
||||
}: SettingsRolePermissionsObjectLevelOverrideCellProps) => {
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const roleLabel = settingsDraftRole.label;
|
||||
|
||||
+4
-3
@@ -5,11 +5,11 @@ import { useFilterObjectMetadataItemsWithPermissionOverride } from '@/settings/r
|
||||
import { useObjectMetadataItemsThatCanHavePermission } from '@/settings/roles/role-permissions/object-level-permissions/hooks/useObjectMetadataItemsThatCanHavePermission';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { Table } from '@/ui/layout/table/components/Table';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useMemo } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconPlus } from 'twenty-ui/display';
|
||||
@@ -49,8 +49,9 @@ export const SettingsRolePermissionsObjectLevelSection = ({
|
||||
}: SettingsRolePermissionsObjectLevelSectionProps) => {
|
||||
const navigateSettings = useNavigateSettings();
|
||||
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const { objectMetadataItemsThatCanHavePermission } =
|
||||
|
||||
+4
-3
@@ -2,8 +2,8 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI
|
||||
import { isHiddenSystemField } from '@/object-metadata/utils/isHiddenSystemField';
|
||||
import { useObjectPermissionDerivedStates } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/hooks/useObjectPermissionDerivedStates';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
type SettingsRolePermissionsObjectLevelSeeFieldsValueForObjectProps = {
|
||||
roleId: string;
|
||||
@@ -16,8 +16,9 @@ export const SettingsRolePermissionsObjectLevelSeeFieldsValueForObject = ({
|
||||
}: SettingsRolePermissionsObjectLevelSeeFieldsValueForObjectProps) => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const objectMetadataItemId = objectMetadataItem.id;
|
||||
|
||||
+4
-3
@@ -2,8 +2,8 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI
|
||||
import { filterUserFacingFieldMetadataItems } from '@/object-metadata/utils/filterUserFacingFieldMetadataItems';
|
||||
import { useObjectPermissionDerivedStates } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/hooks/useObjectPermissionDerivedStates';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
type SettingsRolePermissionsObjectLevelUpdateFieldsValueForObjectProps = {
|
||||
roleId: string;
|
||||
@@ -16,8 +16,9 @@ export const SettingsRolePermissionsObjectLevelUpdateFieldsValueForObject = ({
|
||||
}: SettingsRolePermissionsObjectLevelUpdateFieldsValueForObjectProps) => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const objectMetadataItemId = objectMetadataItem.id;
|
||||
|
||||
+3
-3
@@ -18,7 +18,6 @@ import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFami
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useState } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isNonEmptyArray } from 'twenty-shared/utils';
|
||||
import { H2Title, IconSearch } from 'twenty-ui/display';
|
||||
import { Section } from 'twenty-ui/layout';
|
||||
@@ -70,8 +69,9 @@ export const SettingsRolePermissionsObjectLevelObjectFieldPermissionTable = ({
|
||||
),
|
||||
);
|
||||
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const fieldPermissions =
|
||||
|
||||
+4
-3
@@ -7,9 +7,9 @@ import { useRestrictReadOnAllFieldsOfObject } from '@/settings/roles/role-permis
|
||||
import { useRestrictUpdateOnAllFieldsOfObject } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/hooks/useRestrictUpdateOnAllFieldsOfObject';
|
||||
import { OverridableCheckbox } from '@/settings/roles/role-permissions/object-level-permissions/object-form/components/OverridableCheckbox';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { Label } from 'twenty-ui/display';
|
||||
|
||||
const StyledSectionHeader = styled.div`
|
||||
@@ -40,8 +40,9 @@ export const SettingsRolePermissionsObjectLevelObjectFieldPermissionTableAllHead
|
||||
}) => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const [settingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const { cannotAllowFieldReadRestrict, cannotAllowFieldUpdateRestrict } =
|
||||
|
||||
+4
@@ -5,11 +5,15 @@ import {
|
||||
MOCK_OBJECT_PERMISSION_3_NULL_ALL,
|
||||
MOCK_ROLE_ID_GRANTS_ALL,
|
||||
MOCK_ROLE_ID_REVOKES_ALL,
|
||||
initializeRolesMockJotaiStore,
|
||||
rolesMockHookWrapper,
|
||||
} from '~/testing/mock-data/roles/roles-mock';
|
||||
import { useGetObjectPermissionDerivedStates } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/hooks/useGetObjectPermissionDerivedStates';
|
||||
|
||||
describe('useGetObjectPermissionDerivedStates', () => {
|
||||
beforeEach(() => {
|
||||
initializeRolesMockJotaiStore();
|
||||
});
|
||||
it('should return expected for object that revoke permissions', () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useGetObjectPermissionDerivedStates = ({
|
||||
@@ -7,8 +7,9 @@ export const useGetObjectPermissionDerivedStates = ({
|
||||
}: {
|
||||
roleId: string;
|
||||
}) => {
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const getObjectPermissionDerivedStates = (objectMetadataItemId: string) => {
|
||||
|
||||
+16
-14
@@ -1,23 +1,25 @@
|
||||
import { getRoleWithRemovedFieldPermission } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/utils/getRoleWithRemovedFieldPermission';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const useRemoveFieldPermissionInDraftRole = () => {
|
||||
const removeFieldPermissionInDraftRole = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(roleId: string, fieldPermissionFieldMetadataId: string) => {
|
||||
const currentSettingsDraftRole = snapshot
|
||||
.getLoadable(settingsDraftRoleFamilyState(roleId))
|
||||
.getValue();
|
||||
const store = useStore();
|
||||
|
||||
const newRole = getRoleWithRemovedFieldPermission(
|
||||
currentSettingsDraftRole,
|
||||
fieldPermissionFieldMetadataId,
|
||||
);
|
||||
const removeFieldPermissionInDraftRole = useCallback(
|
||||
(roleId: string, fieldPermissionFieldMetadataId: string) => {
|
||||
const currentSettingsDraftRole = store.get(
|
||||
settingsDraftRoleFamilyState.atomFamily(roleId),
|
||||
);
|
||||
|
||||
set(settingsDraftRoleFamilyState(roleId), newRole);
|
||||
},
|
||||
[],
|
||||
const newRole = getRoleWithRemovedFieldPermission(
|
||||
currentSettingsDraftRole,
|
||||
fieldPermissionFieldMetadataId,
|
||||
);
|
||||
|
||||
store.set(settingsDraftRoleFamilyState.atomFamily(roleId), newRole);
|
||||
},
|
||||
[store],
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
+4
-3
@@ -1,15 +1,16 @@
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { useUpsertFieldPermissionInDraftRole } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/hooks/useUpsertFieldPermissionInDraftRole';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
|
||||
export const useRemoveReadOverrideOnAllFieldsOfObject = ({
|
||||
roleId,
|
||||
}: {
|
||||
roleId: string;
|
||||
}) => {
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const { upsertFieldPermissionInDraftRole } =
|
||||
|
||||
+4
-3
@@ -1,15 +1,16 @@
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { useUpsertFieldPermissionInDraftRole } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/hooks/useUpsertFieldPermissionInDraftRole';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
|
||||
export const useRemoveUpdateOverrideOnAllFieldsOfObject = ({
|
||||
roleId,
|
||||
}: {
|
||||
roleId: string;
|
||||
}) => {
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const { upsertFieldPermissionInDraftRole } =
|
||||
|
||||
+4
-3
@@ -2,7 +2,7 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI
|
||||
import { filterUserFacingFieldMetadataItems } from '@/object-metadata/utils/filterUserFacingFieldMetadataItems';
|
||||
import { useUpsertFieldPermissionInDraftRole } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/hooks/useUpsertFieldPermissionInDraftRole';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
@@ -11,8 +11,9 @@ export const useRestrictReadOnAllFieldsOfObject = ({
|
||||
}: {
|
||||
roleId: string;
|
||||
}) => {
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const { upsertFieldPermissionInDraftRole } =
|
||||
|
||||
+4
-3
@@ -2,7 +2,7 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI
|
||||
import { filterUserFacingFieldMetadataItems } from '@/object-metadata/utils/filterUserFacingFieldMetadataItems';
|
||||
import { useUpsertFieldPermissionInDraftRole } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/hooks/useUpsertFieldPermissionInDraftRole';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
@@ -11,8 +11,9 @@ export const useRestrictUpdateOnAllFieldsOfObject = ({
|
||||
}: {
|
||||
roleId: string;
|
||||
}) => {
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const { upsertFieldPermissionInDraftRole } =
|
||||
|
||||
+4
-3
@@ -1,11 +1,12 @@
|
||||
import { getRoleWithUpsertedFieldPermission } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/utils/getRoleWithUpsertedFieldPermission';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { type FieldPermission } from '~/generated-metadata/graphql';
|
||||
|
||||
export const useUpsertFieldPermissionInDraftRole = (roleId: string) => {
|
||||
const setSettingsDraftRole = useSetRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const upsertFieldPermissionInDraftRole = (
|
||||
|
||||
+4
-3
@@ -2,7 +2,7 @@ import { useUpsertFieldPermissionInDraftRole } from '@/settings/roles/role-permi
|
||||
import { useUpsertObjectPermissionInDraftRole } from '@/settings/roles/role-permissions/object-level-permissions/hooks/useUpsertObjectPermissionInDraftRole';
|
||||
import { type SettingsRoleObjectPermissionKey } from '@/settings/roles/role-permissions/objects-permissions/constants/SettingsRoleObjectPermissionIconConfig';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
type FieldPermission,
|
||||
@@ -17,8 +17,9 @@ const OBJECT_PERMISSION_KEYS: SettingsRoleObjectPermissionKey[] = [
|
||||
];
|
||||
|
||||
export const useResetObjectPermission = (roleId: string) => {
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const { upsertObjectPermissionInDraftRole } =
|
||||
|
||||
+4
-3
@@ -1,13 +1,14 @@
|
||||
import { useUpsertObjectPermissionInDraftRole } from '@/settings/roles/role-permissions/object-level-permissions/hooks/useUpsertObjectPermissionInDraftRole';
|
||||
import { type SettingsRoleObjectPermissionKey } from '@/settings/roles/role-permissions/objects-permissions/constants/SettingsRoleObjectPermissionIconConfig';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type ObjectPermission } from '~/generated-metadata/graphql';
|
||||
|
||||
export const useUpsertObjectPermission = ({ roleId }: { roleId: string }) => {
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const { upsertObjectPermissionInDraftRole } =
|
||||
|
||||
+4
-3
@@ -1,11 +1,12 @@
|
||||
import { getRoleWithUpsertedObjectPermission } from '@/settings/roles/role-permissions/object-level-permissions/hooks/getRoleWithUpsertedObjectPermission';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { type ObjectPermission } from '~/generated-metadata/graphql';
|
||||
|
||||
export const useUpsertObjectPermissionInDraftRole = (roleId: string) => {
|
||||
const setSettingsDraftRole = useSetRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const upsertObjectPermissionInDraftRole = (
|
||||
|
||||
+4
-3
@@ -7,10 +7,10 @@ import { SettingsRolePermissionsObjectLevelObjectFormObjectLevel } from '@/setti
|
||||
import { SettingsRolePermissionsObjectLevelRecordLevelSection } from '@/settings/roles/role-permissions/object-level-permissions/record-level-permissions/components/SettingsRolePermissionsObjectLevelRecordLevelSection';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useFeatureFlagsMap } from '@/workspace/hooks/useFeatureFlagsMap';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { SettingsPath, type ViewFilterOperand } from 'twenty-shared/types';
|
||||
import { getSettingsPath, isDefined } from 'twenty-shared/utils';
|
||||
@@ -36,8 +36,9 @@ export const SettingsRolePermissionsObjectLevelObjectForm = ({
|
||||
|
||||
const currentWorkspace = useRecoilValueV2(currentWorkspaceState);
|
||||
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const { data: agentData } = useFindOneAgentQuery({
|
||||
|
||||
+4
-3
@@ -3,9 +3,9 @@ import { SettingsRolePermissionsObjectLevelObjectFormObjectLevelTableHeader } fr
|
||||
import { SettingsRolePermissionsObjectLevelObjectFormObjectLevelTableRow } from '@/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectFormObjectLevelTableRow';
|
||||
import { type SettingsRolePermissionsObjectLevelPermission } from '@/settings/roles/role-permissions/objects-permissions/types/SettingsRolePermissionsObjectPermission';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { H2Title } from 'twenty-ui/display';
|
||||
import { Section } from 'twenty-ui/layout';
|
||||
|
||||
@@ -27,8 +27,9 @@ export const SettingsRolePermissionsObjectLevelObjectFormObjectLevel = ({
|
||||
roleId,
|
||||
objectMetadataItem,
|
||||
}: SettingsRolePermissionsObjectLevelObjectFormObjectLevelProps) => {
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const settingsDraftRoleObjectPermissions =
|
||||
|
||||
+4
-3
@@ -7,10 +7,10 @@ import { type SettingsRoleObjectPermissionKey } from '@/settings/roles/role-perm
|
||||
import { type SettingsRolePermissionsObjectLevelPermission } from '@/settings/roles/role-permissions/objects-permissions/types/SettingsRolePermissionsObjectPermission';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type ObjectPermission, type Role } from '~/generated-metadata/graphql';
|
||||
|
||||
@@ -70,8 +70,9 @@ export const SettingsRolePermissionsObjectLevelObjectFormObjectLevelTableRow =
|
||||
settingsDraftRoleObjectPermissions,
|
||||
roleId,
|
||||
}: SettingsRolePermissionsObjectLevelObjectFormObjectLevelTableRowProps) => {
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const label = permission.label;
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/o
|
||||
import { SettingsRolePermissionsObjectLevelRecordLevelPermissionFieldSelectFieldMenu } from '@/settings/roles/role-permissions/object-level-permissions/record-level-permissions/components/SettingsRolePermissionsObjectLevelRecordLevelPermissionFieldSelectFieldMenu';
|
||||
import { SettingsRolePermissionsObjectLevelRecordLevelPermissionFieldSelectSubFieldMenu } from '@/settings/roles/role-permissions/object-level-permissions/record-level-permissions/components/SettingsRolePermissionsObjectLevelRecordLevelPermissionFieldSelectSubFieldMenu';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
flex: 2;
|
||||
@@ -28,7 +28,7 @@ export const SettingsRolePermissionsObjectLevelRecordLevelPermissionFieldSelect
|
||||
useAdvancedFilterFieldSelectDropdown(recordFilterId);
|
||||
|
||||
const [objectFilterDropdownIsSelectingCompositeField] =
|
||||
useRecoilComponentState(
|
||||
useRecoilComponentStateV2(
|
||||
objectFilterDropdownIsSelectingCompositeFieldComponentState,
|
||||
);
|
||||
|
||||
|
||||
+9
-8
@@ -24,8 +24,8 @@ import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/Gene
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
|
||||
import { useContext } from 'react';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
@@ -45,7 +45,7 @@ export const SettingsRolePermissionsObjectLevelRecordLevelPermissionFieldSelectF
|
||||
advancedFilterFieldSelectDropdownId,
|
||||
} = useAdvancedFilterFieldSelectDropdown(recordFilterId);
|
||||
|
||||
const [objectFilterDropdownSearchInput] = useRecoilComponentState(
|
||||
const [objectFilterDropdownSearchInput] = useRecoilComponentStateV2(
|
||||
objectFilterDropdownSearchInputComponentState,
|
||||
);
|
||||
|
||||
@@ -77,16 +77,17 @@ export const SettingsRolePermissionsObjectLevelRecordLevelPermissionFieldSelectF
|
||||
const { selectFieldUsedInAdvancedFilterDropdown } =
|
||||
useSelectFieldUsedInAdvancedFilterDropdown();
|
||||
|
||||
const [, setObjectFilterDropdownSubMenuFieldType] = useRecoilComponentState(
|
||||
objectFilterDropdownSubMenuFieldTypeComponentState,
|
||||
);
|
||||
const [, setObjectFilterDropdownSubMenuFieldType] =
|
||||
useRecoilComponentStateV2(
|
||||
objectFilterDropdownSubMenuFieldTypeComponentState,
|
||||
);
|
||||
|
||||
const [, setObjectFilterDropdownIsSelectingCompositeField] =
|
||||
useRecoilComponentState(
|
||||
useRecoilComponentStateV2(
|
||||
objectFilterDropdownIsSelectingCompositeFieldComponentState,
|
||||
);
|
||||
|
||||
const setFieldMetadataItemIdUsedInDropdown = useSetRecoilComponentState(
|
||||
const setFieldMetadataItemIdUsedInDropdown = useSetRecoilComponentStateV2(
|
||||
fieldMetadataItemIdUsedInDropdownComponentState,
|
||||
);
|
||||
|
||||
|
||||
+5
-5
@@ -27,8 +27,8 @@ import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/Gene
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
|
||||
import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
|
||||
type SettingsRolePermissionsObjectLevelRecordLevelPermissionFieldSelectSubFieldMenuProps =
|
||||
@@ -42,19 +42,19 @@ export const SettingsRolePermissionsObjectLevelRecordLevelPermissionFieldSelectS
|
||||
}: SettingsRolePermissionsObjectLevelRecordLevelPermissionFieldSelectSubFieldMenuProps) => {
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValue(
|
||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentSelectorValueV2(
|
||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||
);
|
||||
|
||||
const [, setObjectFilterDropdownIsSelectingCompositeField] =
|
||||
useRecoilComponentState(
|
||||
useRecoilComponentStateV2(
|
||||
objectFilterDropdownIsSelectingCompositeFieldComponentState,
|
||||
);
|
||||
|
||||
const [
|
||||
objectFilterDropdownSubMenuFieldType,
|
||||
setObjectFilterDropdownSubMenuFieldType,
|
||||
] = useRecoilComponentState(
|
||||
] = useRecoilComponentStateV2(
|
||||
objectFilterDropdownSubMenuFieldTypeComponentState,
|
||||
);
|
||||
|
||||
|
||||
+12
-10
@@ -2,7 +2,6 @@
|
||||
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconFilter, IconPlus } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
@@ -23,8 +22,10 @@ import { useRecordLevelPermissionFilterActions } from '@/settings/roles/role-per
|
||||
import { useRecordLevelPermissionFilterInitialization } from '@/settings/roles/role-permissions/object-level-permissions/record-level-permissions/hooks/useRecordLevelPermissionFilterInitialization';
|
||||
import { useRecordLevelPermissionSyncToDraftRole } from '@/settings/roles/role-permissions/object-level-permissions/record-level-permissions/hooks/useRecordLevelPermissionSyncToDraftRole';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: start;
|
||||
@@ -55,34 +56,35 @@ export const SettingsRolePermissionsObjectLevelRecordLevelPermissionFilterBuilde
|
||||
roleId,
|
||||
objectMetadataItem,
|
||||
}: SettingsRolePermissionsObjectLevelRecordLevelPermissionFilterBuilderContentProps) => {
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const { filterableFieldMetadataItems } = useFilterableFieldMetadataItems(
|
||||
objectMetadataItem.id,
|
||||
);
|
||||
|
||||
const setCurrentRecordFilters = useSetRecoilComponentState(
|
||||
const setCurrentRecordFilters = useSetRecoilComponentStateV2(
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const setCurrentRecordFilterGroups = useSetRecoilComponentState(
|
||||
const setCurrentRecordFilterGroups = useSetRecoilComponentStateV2(
|
||||
currentRecordFilterGroupsComponentState,
|
||||
);
|
||||
|
||||
const currentRecordFilters = useRecoilComponentValue(
|
||||
const currentRecordFilters = useRecoilComponentValueV2(
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const currentRecordFilterGroups = useRecoilComponentValue(
|
||||
const currentRecordFilterGroups = useRecoilComponentValueV2(
|
||||
currentRecordFilterGroupsComponentState,
|
||||
);
|
||||
|
||||
const { setRecordFilterUsedInAdvancedFilterDropdownRow } =
|
||||
useSetRecordFilterUsedInAdvancedFilterDropdownRow();
|
||||
|
||||
const rootRecordFilterGroup = useRecoilComponentValue(
|
||||
const rootRecordFilterGroup = useRecoilComponentSelectorValueV2(
|
||||
rootLevelRecordFilterGroupComponentSelector,
|
||||
);
|
||||
|
||||
|
||||
+4
-3
@@ -29,7 +29,8 @@ import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
|
||||
const StyledSearchInput = styled.input`
|
||||
background: transparent;
|
||||
@@ -76,11 +77,11 @@ export const SettingsRolePermissionsObjectLevelRecordLevelPermissionMeValueSelec
|
||||
objectNameSingular: CoreObjectNameSingular.WorkspaceMember,
|
||||
});
|
||||
|
||||
const selectedFieldMetadataItem = useRecoilComponentValue(
|
||||
const selectedFieldMetadataItem = useRecoilComponentSelectorValueV2(
|
||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||
);
|
||||
|
||||
const currentRecordFilters = useRecoilComponentValue(
|
||||
const currentRecordFilters = useRecoilComponentValueV2(
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@ import { FormMultiSelectFieldInput } from '@/object-record/record-field/ui/form-
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { type CompositeFieldType } from '@/settings/data-model/types/CompositeFieldType';
|
||||
import { createRecordLevelPermissionVariablePicker } from '@/settings/roles/role-permissions/object-level-permissions/record-level-permissions/components/SettingsRolePermissionsObjectLevelRecordLevelPermissionVariablePicker';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: stretch;
|
||||
@@ -102,7 +102,7 @@ export const SettingsRolePermissionsObjectLevelRecordLevelPermissionValueInput =
|
||||
|
||||
const { objectMetadataItem } = useContext(AdvancedFilterContext);
|
||||
|
||||
const currentRecordFilters = useRecoilComponentValue(
|
||||
const currentRecordFilters = useRecoilComponentValueV2(
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ import { type RecordFilter } from '@/object-record/record-filter/types/RecordFil
|
||||
import { getDefaultSubFieldNameForCompositeFilterableFieldType } from '@/object-record/record-filter/utils/getDefaultSubFieldNameForCompositeFilterableFieldType';
|
||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
||||
import { RECORD_LEVEL_PERMISSION_PREDICATE_FIELD_TYPES } from '@/settings/roles/role-permissions/object-level-permissions/record-level-permissions/constants/RecordLevelPermissionPredicateFieldTypes';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2';
|
||||
import { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
|
||||
|
||||
type UseRecordLevelPermissionFilterActionsProps = {
|
||||
@@ -49,7 +49,7 @@ export const useRecordLevelPermissionFilterActions = ({
|
||||
},
|
||||
);
|
||||
|
||||
const rootRecordFilterGroup = useRecoilComponentValue(
|
||||
const rootRecordFilterGroup = useRecoilComponentSelectorValueV2(
|
||||
rootLevelRecordFilterGroupComponentSelector,
|
||||
);
|
||||
|
||||
|
||||
+4
-3
@@ -1,7 +1,6 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
@@ -12,6 +11,7 @@ import {
|
||||
convertRecordFilterToPredicate,
|
||||
} from '@/settings/roles/role-permissions/object-level-permissions/record-level-permissions/utils/recordLevelPermissionPredicateConversion';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
|
||||
type UseRecordLevelPermissionSyncToDraftRoleProps = {
|
||||
roleId: string;
|
||||
@@ -28,8 +28,9 @@ export const useRecordLevelPermissionSyncToDraftRole = ({
|
||||
currentRecordFilterGroups,
|
||||
hasInitialized,
|
||||
}: UseRecordLevelPermissionSyncToDraftRoleProps) => {
|
||||
const setSettingsDraftRole = useSetRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const syncToDraftRole = useCallback(() => {
|
||||
|
||||
+9
-3
@@ -2,9 +2,10 @@ import { SettingsRolePermissionsObjectsTableHeader } from '@/settings/roles/role
|
||||
import { SettingsRolePermissionsObjectsTableRow } from '@/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableRow';
|
||||
import { type SettingsRolePermissionsObjectPermission } from '@/settings/roles/role-permissions/objects-permissions/types/SettingsRolePermissionsObjectPermission';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { H2Title } from 'twenty-ui/display';
|
||||
import { Section } from 'twenty-ui/layout';
|
||||
|
||||
@@ -26,8 +27,13 @@ export const SettingsRolePermissionsObjectsSection = ({
|
||||
roleId,
|
||||
isEditable,
|
||||
}: SettingsRolePermissionsObjectsSectionProps) => {
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const objectPermissions = settingsDraftRole.objectPermissions;
|
||||
|
||||
+9
-3
@@ -1,10 +1,11 @@
|
||||
import { type SettingsRolePermissionsObjectPermission } from '@/settings/roles/role-permissions/objects-permissions/types/SettingsRolePermissionsObjectPermission';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { Checkbox } from 'twenty-ui/input';
|
||||
|
||||
const StyledNameHeader = styled(TableHeader)`
|
||||
@@ -29,8 +30,13 @@ export const SettingsRolePermissionsObjectsTableHeader = ({
|
||||
objectPermissionsConfig,
|
||||
isEditable,
|
||||
}: SettingsRolePermissionsObjectsTableHeaderProps) => {
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const allPermissionsEnabled = objectPermissionsConfig.every(
|
||||
|
||||
+9
-3
@@ -3,9 +3,10 @@ import { SettingsRolePermissionsSettingsTableHeader } from '@/settings/roles/rol
|
||||
import { SettingsRolePermissionsSettingsTableRow } from '@/settings/roles/role-permissions/permission-flags/components/SettingsRolePermissionsSettingsTableRow';
|
||||
import { useSettingsRolePermissionFlagConfig } from '@/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { H2Title, IconSettings } from 'twenty-ui/display';
|
||||
import { AnimatedExpandableContainer, Card, Section } from 'twenty-ui/layout';
|
||||
|
||||
@@ -31,8 +32,13 @@ export const SettingsRolePermissionsSettingsSection = ({
|
||||
roleId,
|
||||
isEditable,
|
||||
}: SettingsRolePermissionsSettingsSectionProps) => {
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const settingsPermissionsConfig = useSettingsRolePermissionFlagConfig({
|
||||
|
||||
+9
-3
@@ -6,7 +6,8 @@ import { Checkbox } from 'twenty-ui/input';
|
||||
|
||||
import { type SettingsRolePermissionsSettingPermission } from '@/settings/roles/role-permissions/permission-flags/types/SettingsRolePermissionsSettingPermission';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
type SettingsRolePermissionsSettingsTableHeaderProps = {
|
||||
@@ -27,8 +28,13 @@ export const SettingsRolePermissionsSettingsTableHeader = ({
|
||||
settingsPermissionsConfig,
|
||||
isEditable,
|
||||
}: SettingsRolePermissionsSettingsTableHeaderProps) => {
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const allSettingsPermissionsEnabled = settingsPermissionsConfig.every(
|
||||
(permission) =>
|
||||
|
||||
+9
-3
@@ -1,10 +1,11 @@
|
||||
import { type SettingsRolePermissionsSettingPermission } from '@/settings/roles/role-permissions/permission-flags/types/SettingsRolePermissionsSettingPermission';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { Checkbox } from 'twenty-ui/input';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
@@ -53,8 +54,13 @@ export const SettingsRolePermissionsSettingsTableRow = ({
|
||||
isEditable,
|
||||
}: SettingsRolePermissionsSettingsTableRowProps) => {
|
||||
const theme = useTheme();
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const isPermissionEnabled =
|
||||
|
||||
+9
-3
@@ -3,9 +3,10 @@ import { SettingsRolePermissionsSettingsTableHeader } from '@/settings/roles/rol
|
||||
import { SettingsRolePermissionsSettingsTableRow } from '@/settings/roles/role-permissions/permission-flags/components/SettingsRolePermissionsSettingsTableRow';
|
||||
import { useActionRolePermissionFlagConfig } from '@/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { H2Title, IconTool } from 'twenty-ui/display';
|
||||
import { AnimatedExpandableContainer, Card, Section } from 'twenty-ui/layout';
|
||||
@@ -32,8 +33,13 @@ export const SettingsRolePermissionsToolSection = ({
|
||||
roleId,
|
||||
isEditable,
|
||||
}: SettingsRolePermissionsToolSectionProps) => {
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const toolPermissionsConfig = useActionRolePermissionFlagConfig({
|
||||
|
||||
+9
-3
@@ -1,12 +1,13 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { SettingsRoleApplicability } from '@/settings/roles/role-settings/components/SettingsRoleApplicability';
|
||||
import { SettingsRoleSettingsDeleteRoleConfirmationModal } from '@/settings/roles/role-settings/components/SettingsRoleSettingsDeleteRoleConfirmationModal';
|
||||
import { ROLE_SETTINGS_DELETE_ROLE_CONFIRMATION_MODAL_ID } from '@/settings/roles/role-settings/components/constants/RoleSettingsDeleteRoleConfirmationModalId';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { IconPicker } from '@/ui/input/components/IconPicker';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput';
|
||||
import { TextArea } from '@/ui/input/components/TextArea';
|
||||
import { useModal } from '@/ui/layout/modal/hooks/useModal';
|
||||
@@ -37,8 +38,13 @@ export const SettingsRoleSettings = ({
|
||||
isEditable,
|
||||
isCreateMode,
|
||||
}: SettingsRoleSettingsProps) => {
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const { openModal } = useModal();
|
||||
|
||||
+4
-3
@@ -1,6 +1,6 @@
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
type SettingsRoleSettingsDeleteRoleConfirmationModalSubtitleProps = {
|
||||
roleId: string;
|
||||
@@ -9,8 +9,9 @@ type SettingsRoleSettingsDeleteRoleConfirmationModalSubtitleProps = {
|
||||
export const SettingsRoleSettingsDeleteRoleConfirmationModalSubtitle = ({
|
||||
roleId,
|
||||
}: SettingsRoleSettingsDeleteRoleConfirmationModalSubtitleProps) => {
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const roleName = settingsDraftRole.label;
|
||||
|
||||
|
||||
+4
-3
@@ -1,7 +1,7 @@
|
||||
import { SettingsRoleSettings } from '@/settings/roles/role-settings/components/SettingsRoleSettings';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
||||
import { getRolesMock } from '~/testing/mock-data/roles';
|
||||
@@ -9,8 +9,9 @@ import { getRolesMock } from '~/testing/mock-data/roles';
|
||||
const SettingsRoleSettingsWrapper = (
|
||||
args: React.ComponentProps<typeof SettingsRoleSettings>,
|
||||
) => {
|
||||
const setDraftRole = useSetRecoilState(
|
||||
settingsDraftRoleFamilyState(args.roleId),
|
||||
const setDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
args.roleId,
|
||||
);
|
||||
|
||||
const role = getRolesMock().find((role) => role.id === args.roleId);
|
||||
|
||||
@@ -16,10 +16,11 @@ import { TabList } from '@/ui/layout/tab-list/components/TabList';
|
||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useLoadCurrentUser } from '@/users/hooks/useLoadCurrentUser';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useState } from 'react';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import { getSettingsPath, isDefined } from 'twenty-shared/utils';
|
||||
import { IconLockOpen, IconSettings, IconUserPlus } from 'twenty-ui/display';
|
||||
@@ -48,12 +49,18 @@ export const SettingsRole = ({ roleId, isCreateMode }: SettingsRoleProps) => {
|
||||
settingsRolesIsLoadingStateV2,
|
||||
);
|
||||
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const settingsPersistedRole = useRecoilValue(
|
||||
settingsPersistedRoleFamilyState(roleId),
|
||||
const settingsPersistedRole = useFamilyRecoilValueV2(
|
||||
settingsPersistedRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const { loadCurrentUser } = useLoadCurrentUser();
|
||||
|
||||
+7
-5
@@ -2,10 +2,10 @@ import { SETTINGS_ROLE_DETAIL_TABS } from '@/settings/roles/role/constants/Setti
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { settingsPersistedRoleFamilyState } from '@/settings/roles/states/settingsPersistedRoleFamilyState';
|
||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
type SettingsRoleCreateEffectProps = {
|
||||
roleId: string;
|
||||
@@ -14,12 +14,14 @@ type SettingsRoleCreateEffectProps = {
|
||||
export const SettingsRoleCreateEffect = ({
|
||||
roleId,
|
||||
}: SettingsRoleCreateEffectProps) => {
|
||||
const setSettingsDraftRole = useSetRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const setSettingsPersistedRole = useSetRecoilState(
|
||||
settingsPersistedRoleFamilyState(roleId),
|
||||
const setSettingsPersistedRole = useSetFamilyRecoilStateV2(
|
||||
settingsPersistedRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const setActiveTabId = useSetRecoilComponentStateV2(
|
||||
|
||||
+16
-16
@@ -3,10 +3,10 @@ import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDr
|
||||
import { settingsPersistedRoleFamilyState } from '@/settings/roles/states/settingsPersistedRoleFamilyState';
|
||||
import { type RoleWithPartialMembers } from '@/settings/roles/types/RoleWithPartialMembers';
|
||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useRecoilCallback, useRecoilValue } from 'recoil';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
@@ -19,25 +19,25 @@ export const SettingsRoleEditEffect = ({
|
||||
}: SettingsRoleEditEffectProps) => {
|
||||
const [isInitialized, setIsInitialized] = useState(false);
|
||||
|
||||
const role = useRecoilValue(settingsPersistedRoleFamilyState(roleId));
|
||||
const role = useFamilyRecoilValueV2(settingsPersistedRoleFamilyState, roleId);
|
||||
const setActiveTabId = useSetRecoilComponentStateV2(
|
||||
activeTabIdComponentState,
|
||||
SETTINGS_ROLE_DETAIL_TABS.COMPONENT_INSTANCE_ID + '-' + roleId,
|
||||
);
|
||||
|
||||
const updateDraftRoleIfNeeded = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(newRole: RoleWithPartialMembers) => {
|
||||
const currentPersistedRole = getSnapshotValue(
|
||||
snapshot,
|
||||
settingsPersistedRoleFamilyState(newRole.id),
|
||||
);
|
||||
const store = useStore();
|
||||
|
||||
if (!isDeeplyEqual(newRole, currentPersistedRole)) {
|
||||
set(settingsDraftRoleFamilyState(newRole.id), newRole);
|
||||
}
|
||||
},
|
||||
[],
|
||||
const updateDraftRoleIfNeeded = useCallback(
|
||||
(newRole: RoleWithPartialMembers) => {
|
||||
const currentPersistedRole = store.get(
|
||||
settingsPersistedRoleFamilyState.atomFamily(newRole.id),
|
||||
);
|
||||
|
||||
if (!isDeeplyEqual(newRole, currentPersistedRole)) {
|
||||
store.set(settingsDraftRoleFamilyState.atomFamily(newRole.id), newRole);
|
||||
}
|
||||
},
|
||||
[store],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
+9
-4
@@ -1,6 +1,6 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
|
||||
import { TitleInput } from '@/ui/input/components/TitleInput';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
@@ -23,8 +23,13 @@ type SettingsRoleLabelContainerProps = {
|
||||
export const SettingsRoleLabelContainer = ({
|
||||
roleId,
|
||||
}: SettingsRoleLabelContainerProps) => {
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
const setSettingsDraftRole = useSetFamilyRecoilStateV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const handleChange = (newValue: string) => {
|
||||
|
||||
@@ -7,8 +7,8 @@ import { useRemoveFieldPermissionInDraftRole } from '@/settings/roles/role-permi
|
||||
import { newFieldPermissionsFilter } from '@/settings/roles/role/hooks/utils/newFieldPermissionsFilter.util';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { settingsPersistedRoleFamilyState } from '@/settings/roles/states/settingsPersistedRoleFamilyState';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined, isNonEmptyArray } from 'twenty-shared/utils';
|
||||
import {
|
||||
type RowLevelPermissionPredicateGroupLogicalOperator,
|
||||
@@ -57,12 +57,14 @@ export const useSaveDraftRoleToDB = ({
|
||||
const { addAgentsToRole } = useUpdateAgentRole(roleId);
|
||||
const { addApiKeysToRole } = useUpdateApiKeyRole(roleId);
|
||||
|
||||
const settingsPersistedRole = useRecoilValue(
|
||||
settingsPersistedRoleFamilyState(roleId),
|
||||
const settingsPersistedRole = useFamilyRecoilValueV2(
|
||||
settingsPersistedRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const settingsDraftRole = useRecoilValue(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
const settingsDraftRole = useFamilyRecoilValueV2(
|
||||
settingsDraftRoleFamilyState,
|
||||
roleId,
|
||||
);
|
||||
|
||||
const dirtyFields = getDirtyFields(settingsDraftRole, settingsPersistedRole);
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import { selector } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { settingsPersistedRoleFamilyState } from './settingsPersistedRoleFamilyState';
|
||||
import { settingsRoleIdsState } from './settingsRoleIdsState';
|
||||
|
||||
export const settingsAllRolesSelector = selector({
|
||||
key: 'settingsAllRolesSelector',
|
||||
get: ({ get }) => {
|
||||
const roleIds = get(settingsRoleIdsState);
|
||||
return roleIds
|
||||
.map((roleId) => get(settingsPersistedRoleFamilyState(roleId)))
|
||||
.filter(isDefined);
|
||||
},
|
||||
});
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
|
||||
import { createFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createFamilyStateV2';
|
||||
import { type RoleWithPartialMembers } from '@/settings/roles/types/RoleWithPartialMembers';
|
||||
|
||||
export const settingsDraftRoleFamilyState = createFamilyState<
|
||||
export const settingsDraftRoleFamilyState = createFamilyStateV2<
|
||||
RoleWithPartialMembers,
|
||||
string
|
||||
>({
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
|
||||
import { createFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createFamilyStateV2';
|
||||
import { type RoleWithPartialMembers } from '@/settings/roles/types/RoleWithPartialMembers';
|
||||
|
||||
export const settingsPersistedRoleFamilyState = createFamilyState<
|
||||
export const settingsPersistedRoleFamilyState = createFamilyStateV2<
|
||||
RoleWithPartialMembers | undefined,
|
||||
string
|
||||
>({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
|
||||
export const settingsRoleIdsState = atom<string[]>({
|
||||
export const settingsRoleIdsState = createStateV2<string[]>({
|
||||
key: 'settingsRoleIdsState',
|
||||
default: [],
|
||||
defaultValue: [],
|
||||
});
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
|
||||
export const settingsRoleIdsStateV2 = createStateV2<string[]>({
|
||||
key: 'settingsRoleIdsStateV2',
|
||||
defaultValue: [],
|
||||
});
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
|
||||
import { createFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createFamilyStateV2';
|
||||
import { type Role } from '~/generated-metadata/graphql';
|
||||
|
||||
export const settingsValidateRoleFamilyState = createFamilyState<
|
||||
export const settingsValidateRoleFamilyState = createFamilyStateV2<
|
||||
Record<keyof Pick<Role, 'label'>, boolean>,
|
||||
string
|
||||
>({
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ import { type ApolloError } from '@apollo/client';
|
||||
import isPropValid from '@emotion/is-prop-valid';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { getSettingsPath } from 'twenty-shared/utils';
|
||||
import { IconKey } from 'twenty-ui/display';
|
||||
@@ -33,7 +33,7 @@ export const SettingsSSOIdentitiesProvidersListCard = () => {
|
||||
|
||||
const { t } = useLingui();
|
||||
|
||||
const [SSOIdentitiesProviders, setSSOIdentitiesProviders] = useRecoilState(
|
||||
const [SSOIdentitiesProviders, setSSOIdentitiesProviders] = useRecoilStateV2(
|
||||
SSOIdentitiesProvidersState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -5,14 +5,14 @@ import { SettingsListCard } from '@/settings/components/SettingsListCard';
|
||||
import { SettingsSSOIdentityProviderRowRightContainer } from '@/settings/security/components/SSO/SettingsSSOIdentityProviderRowRightContainer';
|
||||
import { SSOIdentitiesProvidersState } from '@/settings/security/states/SSOIdentitiesProvidersState';
|
||||
import { guessSSOIdentityProviderIconByUrl } from '@/settings/security/utils/guessSSOIdentityProviderIconByUrl';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
|
||||
export const SettingsSSOIdentitiesProvidersListCardWrapper = () => {
|
||||
const navigate = useNavigateSettings();
|
||||
|
||||
const SSOIdentitiesProviders = useRecoilValue(SSOIdentitiesProvidersState);
|
||||
const SSOIdentitiesProviders = useRecoilValueV2(SSOIdentitiesProvidersState);
|
||||
|
||||
return (
|
||||
<SettingsListCard
|
||||
|
||||
+2
-3
@@ -1,10 +1,9 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
import { SettingsSecuritySSORowDropdownMenu } from '@/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu';
|
||||
import { type SSOIdentitiesProvidersState } from '@/settings/security/states/SSOIdentitiesProvidersState';
|
||||
import { type SSOIdentityProvider } from '@/settings/security/types/SSOIdentityProvider';
|
||||
import { getColorBySSOIdentityProviderStatus } from '@/settings/security/utils/getColorBySSOIdentityProviderStatus';
|
||||
import styled from '@emotion/styled';
|
||||
import { type UnwrapRecoilValue } from 'recoil';
|
||||
import { Status } from 'twenty-ui/display';
|
||||
|
||||
const StyledRowRightContainer = styled.div`
|
||||
@@ -16,7 +15,7 @@ const StyledRowRightContainer = styled.div`
|
||||
export const SettingsSSOIdentityProviderRowRightContainer = ({
|
||||
SSOIdp,
|
||||
}: {
|
||||
SSOIdp: UnwrapRecoilValue<typeof SSOIdentitiesProvidersState>[0];
|
||||
SSOIdp: Omit<SSOIdentityProvider, '__typename'>;
|
||||
}) => {
|
||||
return (
|
||||
<StyledRowRightContainer>
|
||||
|
||||
+2
-3
@@ -1,13 +1,12 @@
|
||||
import { useDeleteSSOIdentityProvider } from '@/settings/security/hooks/useDeleteSSOIdentityProvider';
|
||||
import { useUpdateSSOIdentityProvider } from '@/settings/security/hooks/useUpdateSSOIdentityProvider';
|
||||
import { type SSOIdentitiesProvidersState } from '@/settings/security/states/SSOIdentitiesProvidersState';
|
||||
import { type SSOIdentityProvider } from '@/settings/security/types/SSOIdentityProvider';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { type UnwrapRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconArchive, IconDotsVertical, IconTrash } from 'twenty-ui/display';
|
||||
import { LightIconButton } from 'twenty-ui/input';
|
||||
@@ -15,7 +14,7 @@ import { MenuItem } from 'twenty-ui/navigation';
|
||||
import { SsoIdentityProviderStatus } from '~/generated-metadata/graphql';
|
||||
|
||||
type SettingsSecuritySSORowDropdownMenuProps = {
|
||||
SSOIdp: UnwrapRecoilValue<typeof SSOIdentitiesProvidersState>[0];
|
||||
SSOIdp: Omit<SSOIdentityProvider, '__typename'>;
|
||||
};
|
||||
|
||||
export const SettingsSecuritySSORowDropdownMenu = ({
|
||||
|
||||
+1
-2
@@ -6,7 +6,6 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { ApolloError } from '@apollo/client';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
|
||||
import { ConnectedAccountProvider } from 'twenty-shared/types';
|
||||
import { capitalize } from 'twenty-shared/utils';
|
||||
@@ -35,7 +34,7 @@ export const SettingsSecurityAuthProvidersOptionsList = () => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const SSOIdentitiesProviders = useRecoilValue(SSOIdentitiesProvidersState);
|
||||
const SSOIdentitiesProviders = useRecoilValueV2(SSOIdentitiesProvidersState);
|
||||
const authProviders = useRecoilValueV2(authProvidersState);
|
||||
|
||||
const [currentWorkspace, setCurrentWorkspace] = useRecoilStateV2(
|
||||
|
||||
+5
-4
@@ -11,11 +11,12 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { ApolloError } from '@apollo/client';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { getSettingsPath } from 'twenty-shared/utils';
|
||||
import { IconAt, IconMailCog, Status } from 'twenty-ui/display';
|
||||
import { useGetApprovedAccessDomainsQuery } from '~/generated-metadata/graphql';
|
||||
import { dateLocaleState } from '~/localization/states/dateLocaleState';
|
||||
import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2';
|
||||
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
|
||||
|
||||
const StyledLink = styled(Link)`
|
||||
@@ -26,9 +27,9 @@ export const SettingsApprovedAccessDomainsListCard = () => {
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const navigate = useNavigate();
|
||||
const { t } = useLingui();
|
||||
const { localeCatalog } = useRecoilValue(dateLocaleState);
|
||||
const { localeCatalog } = useRecoilValueV2(dateLocaleStateV2);
|
||||
|
||||
const [approvedAccessDomains, setApprovedAccessDomains] = useRecoilState(
|
||||
const [approvedAccessDomains, setApprovedAccessDomains] = useRecoilStateV2(
|
||||
approvedAccessDomainsState,
|
||||
);
|
||||
|
||||
|
||||
+7
-4
@@ -4,16 +4,19 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { type UnwrapRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconDotsVertical, IconTrash } from 'twenty-ui/display';
|
||||
import { LightIconButton } from 'twenty-ui/input';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
import { useDeleteApprovedAccessDomainMutation } from '~/generated-metadata/graphql';
|
||||
import {
|
||||
type ApprovedAccessDomain,
|
||||
useDeleteApprovedAccessDomainMutation,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
type SettingsSecurityApprovedAccessDomainRowDropdownMenuProps = {
|
||||
approvedAccessDomain: UnwrapRecoilValue<typeof approvedAccessDomainsState>[0];
|
||||
approvedAccessDomain: Omit<ApprovedAccessDomain, '__typename'>;
|
||||
};
|
||||
|
||||
export const SettingsSecurityApprovedAccessDomainRowDropdownMenu = ({
|
||||
@@ -21,7 +24,7 @@ export const SettingsSecurityApprovedAccessDomainRowDropdownMenu = ({
|
||||
}: SettingsSecurityApprovedAccessDomainRowDropdownMenuProps) => {
|
||||
const dropdownId = `settings-approved-access-domain-row-${approvedAccessDomain.id}`;
|
||||
|
||||
const setApprovedAccessDomains = useSetRecoilState(
|
||||
const setApprovedAccessDomains = useSetRecoilStateV2(
|
||||
approvedAccessDomainsState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useEffect } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useValidateApprovedAccessDomainMutation } from '~/generated-metadata/graphql';
|
||||
|
||||
@@ -14,7 +14,7 @@ export const SettingsSecurityApprovedAccessDomainValidationEffect = () => {
|
||||
const [searchParams] = useSearchParams();
|
||||
const approvedAccessDomainId = searchParams.get('wtdId');
|
||||
const validationToken = searchParams.get('validationToken');
|
||||
const setApprovedAccessDomains = useSetRecoilState(
|
||||
const setApprovedAccessDomains = useSetRecoilStateV2(
|
||||
approvedAccessDomainsState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
import { SSOIdentitiesProvidersState } from '@/settings/security/states/SSOIdentitiesProvidersState';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import {
|
||||
type CreateOidcIdentityProviderMutationVariables,
|
||||
type CreateSamlIdentityProviderMutationVariables,
|
||||
@@ -15,7 +15,7 @@ export const useCreateSSOIdentityProvider = () => {
|
||||
const [createSamlIdentityProviderMutation] =
|
||||
useCreateSamlIdentityProviderMutation();
|
||||
|
||||
const setSSOIdentitiesProviders = useSetRecoilState(
|
||||
const setSSOIdentitiesProviders = useSetRecoilStateV2(
|
||||
SSOIdentitiesProvidersState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
import { SSOIdentitiesProvidersState } from '@/settings/security/states/SSOIdentitiesProvidersState';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import {
|
||||
type DeleteSsoIdentityProviderMutationVariables,
|
||||
useDeleteSsoIdentityProviderMutation,
|
||||
@@ -11,7 +11,7 @@ export const useDeleteSSOIdentityProvider = () => {
|
||||
const [deleteSsoIdentityProviderMutation] =
|
||||
useDeleteSsoIdentityProviderMutation();
|
||||
|
||||
const setSSOIdentitiesProviders = useSetRecoilState(
|
||||
const setSSOIdentitiesProviders = useSetRecoilStateV2(
|
||||
SSOIdentitiesProvidersState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
import { SSOIdentitiesProvidersState } from '@/settings/security/states/SSOIdentitiesProvidersState';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import {
|
||||
type EditSsoIdentityProviderMutationVariables,
|
||||
useEditSsoIdentityProviderMutation,
|
||||
@@ -11,7 +11,7 @@ export const useUpdateSSOIdentityProvider = () => {
|
||||
const [editSsoIdentityProviderMutation] =
|
||||
useEditSsoIdentityProviderMutation();
|
||||
|
||||
const setSSOIdentitiesProviders = useSetRecoilState(
|
||||
const setSSOIdentitiesProviders = useSetRecoilStateV2(
|
||||
SSOIdentitiesProvidersState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
import { type ApprovedAccessDomain } from '~/generated-metadata/graphql';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export const approvedAccessDomainsState = createState<
|
||||
export const approvedAccessDomainsState = createStateV2<
|
||||
Omit<ApprovedAccessDomain, '__typename'>[]
|
||||
>({
|
||||
key: 'ApprovedAccessDomainsState',
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
import { type SSOIdentityProvider } from '@/settings/security/types/SSOIdentityProvider';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
|
||||
export const SSOIdentitiesProvidersState = createState<
|
||||
export const SSOIdentitiesProvidersState = createStateV2<
|
||||
Omit<SSOIdentityProvider, '__typename'>[]
|
||||
>({
|
||||
key: 'SSOIdentitiesProvidersState',
|
||||
|
||||
Reference in New Issue
Block a user