Rework atom naming (#18240)
## Summary - **Enhanced the `matching-state-variable` ESLint rule** to enforce consistent naming for `ComponentState`, `FamilyState`, and `ComponentFamilyState` hooks — previously it only covered `useAtomState` and `useAtomStateValue` - **The rule now checks 12 hooks** across three categories: value hooks (`useAtomComponentStateValue`, `useAtomFamilyStateValue`, etc.), state hooks (`useAtomComponentState`, `useAtomComponentFamilyState`), and setter hooks (`useSetAtomState`, `useSetAtomComponentState`, `useSetAtomFamilyState`, `useSetAtomComponentFamilyState`) - **Fixed all 225 resulting lint violations** across 151 files, renaming variables to match their state atom names (e.g. `currentViewId` → `contextStoreCurrentViewId`, `selectedRecord` → `recordStore`). Cases where the same state is accessed with different family keys/instance IDs are suppressed with `eslint-disable-next-line`. ## Naming convention | Hook | State argument | Valid | Invalid | |------|---------------|-------|---------| | `useAtomStateValue` | `fooState` | `const foo = ...` | `const bar = ...` | | `useAtomComponentStateValue` | `fooComponentState` | `const foo = ...` | `const bar = ...` | | `useAtomFamilyStateValue` | `fooFamilyState` | `const foo = ...` | `const bar = ...` | | `useAtomComponentFamilyStateValue` | `fooComponentFamilyState` | `const foo = ...` | `const bar = ...` | | `useAtomState` | `fooState` | `const [foo, setFoo] = ...` | `const [bar, setBar] = ...` | | `useAtomComponentState` | `fooComponentState` | `const [foo, setFoo] = ...` | `const [bar, setBar] = ...` | | `useAtomComponentFamilyState` | `fooComponentFamilyState` | `const [foo, setFoo] = ...` | `const [bar, setBar] = ...` | | `useSetAtomState` | `fooState` | `const setFoo = ...` | `const setBar = ...` | | `useSetAtomComponentState` | `fooComponentState` | `const setFoo = ...` | `const setBar = ...` | | `useSetAtomFamilyState` | `fooFamilyState` | `const setFoo = ...` | `const setBar = ...` | | `useSetAtomComponentFamilyState` | `fooComponentFamilyState` | `const setFoo = ...` | `const setBar = ...` |
This commit is contained in:
@@ -39,17 +39,18 @@ export const CommandMenu = () => {
|
||||
commandMenuSearch,
|
||||
});
|
||||
|
||||
// eslint-disable-next-line twenty/matching-state-variable
|
||||
const previousContextStoreCurrentObjectMetadataItemId =
|
||||
useAtomComponentStateValue(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
'command-menu-previous',
|
||||
);
|
||||
|
||||
const objectMetadataItemId = useAtomComponentStateValue(
|
||||
const contextStoreCurrentObjectMetadataItemId = useAtomComponentStateValue(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
);
|
||||
const currentObjectMetadataItem = objectMetadataItems.find(
|
||||
(item) => item.id === objectMetadataItemId,
|
||||
(item) => item.id === contextStoreCurrentObjectMetadataItemId,
|
||||
);
|
||||
|
||||
const commandGroups: ActionGroupConfig[] = [
|
||||
|
||||
@@ -29,7 +29,7 @@ type CommandMenuContainerProps = {
|
||||
export const CommandMenuContainer = ({
|
||||
children,
|
||||
}: CommandMenuContainerProps) => {
|
||||
const objectMetadataItemId = useAtomComponentStateValue(
|
||||
const contextStoreCurrentObjectMetadataItemId = useAtomComponentStateValue(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
@@ -38,17 +38,18 @@ export const CommandMenuContainer = ({
|
||||
const objectMetadataItems = useAtomStateValue(objectMetadataItemsState);
|
||||
|
||||
const objectMetadataItem = objectMetadataItems.find(
|
||||
(objectMetadataItem) => objectMetadataItem.id === objectMetadataItemId,
|
||||
(objectMetadataItem) =>
|
||||
objectMetadataItem.id === contextStoreCurrentObjectMetadataItemId,
|
||||
);
|
||||
|
||||
const currentViewId = useAtomComponentStateValue(
|
||||
const contextStoreCurrentViewId = useAtomComponentStateValue(
|
||||
contextStoreCurrentViewIdComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const recordIndexId = getRecordIndexIdFromObjectNamePluralAndViewId(
|
||||
objectMetadataItem?.namePlural ?? '',
|
||||
currentViewId ?? '',
|
||||
contextStoreCurrentViewId ?? '',
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -27,11 +27,13 @@ export const CommandMenuFolderInfo = () => {
|
||||
const { t } = useLingui();
|
||||
const { getIcon } = useIcons();
|
||||
const commandMenuPageInfo = useAtomStateValue(commandMenuPageInfoState);
|
||||
const [shouldFocusTitleInput, setShouldFocusTitleInput] =
|
||||
useAtomComponentState(
|
||||
commandMenuShouldFocusTitleInputComponentState,
|
||||
commandMenuPageInfo.instanceId,
|
||||
);
|
||||
const [
|
||||
commandMenuShouldFocusTitleInput,
|
||||
setCommandMenuShouldFocusTitleInput,
|
||||
] = useAtomComponentState(
|
||||
commandMenuShouldFocusTitleInputComponentState,
|
||||
commandMenuPageInfo.instanceId,
|
||||
);
|
||||
const selectedNavigationMenuItemInEditMode = useAtomStateValue(
|
||||
selectedNavigationMenuItemInEditModeState,
|
||||
);
|
||||
@@ -106,8 +108,8 @@ export const CommandMenuFolderInfo = () => {
|
||||
onClickOutside={handleSave}
|
||||
onTab={handleSave}
|
||||
onShiftTab={handleSave}
|
||||
shouldFocus={shouldFocusTitleInput}
|
||||
onFocus={() => setShouldFocusTitleInput(false)}
|
||||
shouldFocus={commandMenuShouldFocusTitleInput}
|
||||
onFocus={() => setCommandMenuShouldFocusTitleInput(false)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
+4
-2
@@ -41,7 +41,9 @@ export const CommandMenuItemWithAddToNavigationDrag = ({
|
||||
dragIndex,
|
||||
}: CommandMenuItemWithAddToNavigationDragProps) => {
|
||||
const { t } = useLingui();
|
||||
const setRegistry = useSetAtomState(addToNavPayloadRegistryState);
|
||||
const setAddToNavPayloadRegistry = useSetAtomState(
|
||||
addToNavPayloadRegistryState,
|
||||
);
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
|
||||
const contextualDescription = isHovered
|
||||
@@ -59,7 +61,7 @@ export const CommandMenuItemWithAddToNavigationDrag = ({
|
||||
|
||||
const registerPayload = () => {
|
||||
if (dragIndex !== undefined) {
|
||||
setRegistry((prev) => new Map(prev).set(id, payload));
|
||||
setAddToNavPayloadRegistry((prev) => new Map(prev).set(id, payload));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -19,11 +19,13 @@ export const CommandMenuLinkInfo = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useLingui();
|
||||
const commandMenuPageInfo = useAtomStateValue(commandMenuPageInfoState);
|
||||
const [shouldFocusTitleInput, setShouldFocusTitleInput] =
|
||||
useAtomComponentState(
|
||||
commandMenuShouldFocusTitleInputComponentState,
|
||||
commandMenuPageInfo.instanceId,
|
||||
);
|
||||
const [
|
||||
commandMenuShouldFocusTitleInput,
|
||||
setCommandMenuShouldFocusTitleInput,
|
||||
] = useAtomComponentState(
|
||||
commandMenuShouldFocusTitleInputComponentState,
|
||||
commandMenuPageInfo.instanceId,
|
||||
);
|
||||
const selectedNavigationMenuItemInEditMode = useAtomStateValue(
|
||||
selectedNavigationMenuItemInEditModeState,
|
||||
);
|
||||
@@ -84,8 +86,8 @@ export const CommandMenuLinkInfo = () => {
|
||||
onClickOutside={handleSave}
|
||||
onTab={handleSave}
|
||||
onShiftTab={handleSave}
|
||||
shouldFocus={shouldFocusTitleInput}
|
||||
onFocus={() => setShouldFocusTitleInput(false)}
|
||||
shouldFocus={commandMenuShouldFocusTitleInput}
|
||||
onFocus={() => setCommandMenuShouldFocusTitleInput(false)}
|
||||
/>
|
||||
}
|
||||
label={t`link`}
|
||||
|
||||
+3
-3
@@ -7,16 +7,16 @@ import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/use
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const CommandMenuPageLayoutInfo = () => {
|
||||
const objectMetadataId = useAtomComponentStateValue(
|
||||
const contextStoreCurrentObjectMetadataItemId = useAtomComponentStateValue(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
);
|
||||
|
||||
if (!isDefined(objectMetadataId)) {
|
||||
if (!isDefined(contextStoreCurrentObjectMetadataItemId)) {
|
||||
throw new Error('Object metadata ID is not defined');
|
||||
}
|
||||
|
||||
const { objectMetadataItem } = useObjectMetadataItemById({
|
||||
objectId: objectMetadataId,
|
||||
objectId: contextStoreCurrentObjectMetadataItemId,
|
||||
});
|
||||
|
||||
const isDashboardContext =
|
||||
|
||||
+13
-11
@@ -30,17 +30,19 @@ export const CommandMenuPageLayoutInfoContent = ({
|
||||
const commandMenuPage = useAtomStateValue(commandMenuPageState);
|
||||
const commandMenuPageInfo = useAtomStateValue(commandMenuPageInfoState);
|
||||
|
||||
const [shouldFocusTitleInput, setShouldFocusTitleInput] =
|
||||
useAtomComponentState(
|
||||
commandMenuShouldFocusTitleInputComponentState,
|
||||
commandMenuPageInfo.instanceId,
|
||||
);
|
||||
const [
|
||||
commandMenuShouldFocusTitleInput,
|
||||
setCommandMenuShouldFocusTitleInput,
|
||||
] = useAtomComponentState(
|
||||
commandMenuShouldFocusTitleInputComponentState,
|
||||
commandMenuPageInfo.instanceId,
|
||||
);
|
||||
|
||||
const handleTitleInputOpen = () => {
|
||||
setShouldFocusTitleInput(false);
|
||||
setCommandMenuShouldFocusTitleInput(false);
|
||||
};
|
||||
|
||||
const draftPageLayout = useAtomComponentStateValue(
|
||||
const pageLayoutDraft = useAtomComponentStateValue(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
@@ -50,7 +52,7 @@ export const CommandMenuPageLayoutInfoContent = ({
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const [openTabId] = useAtomComponentState(
|
||||
const [pageLayoutTabSettingsOpenTabId] = useAtomComponentState(
|
||||
pageLayoutTabSettingsOpenTabIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
@@ -63,9 +65,9 @@ export const CommandMenuPageLayoutInfoContent = ({
|
||||
|
||||
const headerInfo = usePageLayoutHeaderInfo({
|
||||
commandMenuPage,
|
||||
draftPageLayout,
|
||||
draftPageLayout: pageLayoutDraft,
|
||||
pageLayoutEditingWidgetId,
|
||||
openTabId,
|
||||
openTabId: pageLayoutTabSettingsOpenTabId,
|
||||
editedTitle,
|
||||
});
|
||||
|
||||
@@ -136,7 +138,7 @@ export const CommandMenuPageLayoutInfoContent = ({
|
||||
onClickOutside={saveTitle}
|
||||
onTab={saveTitle}
|
||||
onShiftTab={saveTitle}
|
||||
shouldFocus={shouldFocusTitleInput}
|
||||
shouldFocus={commandMenuShouldFocusTitleInput}
|
||||
onFocus={handleTitleInputOpen}
|
||||
/>
|
||||
}
|
||||
|
||||
+5
-5
@@ -39,7 +39,7 @@ export const CommandMenuWorkflowStepInfo = ({
|
||||
|
||||
const workflowId = useCommandMenuWorkflowIdOrThrow();
|
||||
|
||||
const workflowStepId = useAtomComponentStateValue(
|
||||
const commandMenuWorkflowStepId = useAtomComponentStateValue(
|
||||
commandMenuWorkflowStepIdComponentState,
|
||||
commandMenuPageInstanceId,
|
||||
);
|
||||
@@ -71,13 +71,13 @@ export const CommandMenuWorkflowStepInfo = ({
|
||||
id: undefined,
|
||||
};
|
||||
|
||||
const isTriggerStep = workflowStepId === TRIGGER_STEP_ID;
|
||||
const isTriggerStep = commandMenuWorkflowStepId === TRIGGER_STEP_ID;
|
||||
|
||||
const stepDefinition =
|
||||
isDefined(workflowStepId) && isDefined(trigger)
|
||||
isDefined(commandMenuWorkflowStepId) && isDefined(trigger)
|
||||
? isTriggerStep || isDefined(steps)
|
||||
? getStepDefinitionOrThrow({
|
||||
stepId: workflowStepId,
|
||||
stepId: commandMenuWorkflowStepId,
|
||||
trigger,
|
||||
steps,
|
||||
})
|
||||
@@ -109,7 +109,7 @@ export const CommandMenuWorkflowStepInfo = ({
|
||||
|
||||
if (
|
||||
!isDefined(workflowId) ||
|
||||
!isDefined(workflowStepId) ||
|
||||
!isDefined(commandMenuWorkflowStepId) ||
|
||||
!isDefined(workflowWithCurrentVersion?.currentVersion) ||
|
||||
!isDefined(stepDefinition) ||
|
||||
!isDefined(stepDefinition.definition)
|
||||
|
||||
+18
-15
@@ -60,19 +60,20 @@ const renderHooks = () => {
|
||||
viewableRecordNameSingularComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const currentObjectMetadataItemId = useAtomComponentStateValue(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const targetedRecordsRule = useAtomComponentStateValue(
|
||||
const contextStoreCurrentObjectMetadataItemId =
|
||||
useAtomComponentStateValue(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const contextStoreTargetedRecordsRule = useAtomComponentStateValue(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const numberOfSelectedRecords = useAtomComponentStateValue(
|
||||
const contextStoreNumberOfSelectedRecords = useAtomComponentStateValue(
|
||||
contextStoreNumberOfSelectedRecordsComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const currentViewType = useAtomComponentStateValue(
|
||||
const contextStoreCurrentViewType = useAtomComponentStateValue(
|
||||
contextStoreCurrentViewTypeComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
@@ -82,10 +83,10 @@ const renderHooks = () => {
|
||||
openRecordInCommandMenu,
|
||||
viewableRecordId,
|
||||
viewableRecordNameSingular,
|
||||
currentObjectMetadataItemId,
|
||||
targetedRecordsRule,
|
||||
numberOfSelectedRecords,
|
||||
currentViewType,
|
||||
contextStoreCurrentObjectMetadataItemId,
|
||||
contextStoreTargetedRecordsRule,
|
||||
contextStoreNumberOfSelectedRecords,
|
||||
contextStoreCurrentViewType,
|
||||
getIcon,
|
||||
};
|
||||
},
|
||||
@@ -116,15 +117,17 @@ describe('useOpenRecordInCommandMenu', () => {
|
||||
|
||||
expect(result.current.viewableRecordId).toBe(recordId);
|
||||
expect(result.current.viewableRecordNameSingular).toBe(objectNameSingular);
|
||||
expect(result.current.currentObjectMetadataItemId).toBe(
|
||||
expect(result.current.contextStoreCurrentObjectMetadataItemId).toBe(
|
||||
personMockObjectMetadataItem.id,
|
||||
);
|
||||
expect(result.current.targetedRecordsRule).toEqual({
|
||||
expect(result.current.contextStoreTargetedRecordsRule).toEqual({
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [recordId],
|
||||
});
|
||||
expect(result.current.numberOfSelectedRecords).toBe(1);
|
||||
expect(result.current.currentViewType).toBe(ContextStoreViewType.ShowPage);
|
||||
expect(result.current.contextStoreNumberOfSelectedRecords).toBe(1);
|
||||
expect(result.current.contextStoreCurrentViewType).toBe(
|
||||
ContextStoreViewType.ShowPage,
|
||||
);
|
||||
|
||||
const commandMenuNavigationMorphItemsByPage = jotaiStore.get(
|
||||
commandMenuNavigationMorphItemsByPageState.atom,
|
||||
|
||||
+28
-22
@@ -60,44 +60,44 @@ describe('useSetGlobalCommandMenuContext', () => {
|
||||
const { setGlobalCommandMenuContext } =
|
||||
useSetGlobalCommandMenuContext();
|
||||
|
||||
const targetedRecordsRule = useAtomComponentStateValue(
|
||||
const contextStoreTargetedRecordsRule = useAtomComponentStateValue(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const numberOfSelectedRecords = useAtomComponentStateValue(
|
||||
const contextStoreNumberOfSelectedRecords = useAtomComponentStateValue(
|
||||
contextStoreNumberOfSelectedRecordsComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const filters = useAtomComponentStateValue(
|
||||
const contextStoreFilters = useAtomComponentStateValue(
|
||||
contextStoreFiltersComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const filterGroups = useAtomComponentStateValue(
|
||||
const contextStoreFilterGroups = useAtomComponentStateValue(
|
||||
contextStoreFilterGroupsComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const anyFieldFilterValue = useAtomComponentStateValue(
|
||||
const contextStoreAnyFieldFilterValue = useAtomComponentStateValue(
|
||||
contextStoreAnyFieldFilterValueComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const currentViewType = useAtomComponentStateValue(
|
||||
const contextStoreCurrentViewType = useAtomComponentStateValue(
|
||||
contextStoreCurrentViewTypeComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
return {
|
||||
setGlobalCommandMenuContext,
|
||||
targetedRecordsRule,
|
||||
numberOfSelectedRecords,
|
||||
filters,
|
||||
filterGroups,
|
||||
currentViewType,
|
||||
anyFieldFilterValue,
|
||||
contextStoreTargetedRecordsRule,
|
||||
contextStoreNumberOfSelectedRecords,
|
||||
contextStoreFilters,
|
||||
contextStoreFilterGroups,
|
||||
contextStoreCurrentViewType,
|
||||
contextStoreAnyFieldFilterValue,
|
||||
};
|
||||
},
|
||||
{
|
||||
@@ -105,14 +105,16 @@ describe('useSetGlobalCommandMenuContext', () => {
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.targetedRecordsRule).toEqual({
|
||||
expect(result.current.contextStoreTargetedRecordsRule).toEqual({
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [peopleMock[0].id, peopleMock[1].id],
|
||||
});
|
||||
expect(result.current.numberOfSelectedRecords).toBe(2);
|
||||
expect(result.current.filters).toEqual([]);
|
||||
expect(result.current.anyFieldFilterValue).toEqual('');
|
||||
expect(result.current.currentViewType).toBe(ContextStoreViewType.Table);
|
||||
expect(result.current.contextStoreNumberOfSelectedRecords).toBe(2);
|
||||
expect(result.current.contextStoreFilters).toEqual([]);
|
||||
expect(result.current.contextStoreAnyFieldFilterValue).toEqual('');
|
||||
expect(result.current.contextStoreCurrentViewType).toBe(
|
||||
ContextStoreViewType.Table,
|
||||
);
|
||||
const commandMenuPageInfo = jotaiStore.get(commandMenuPageInfoState.atom);
|
||||
expect(commandMenuPageInfo).toEqual({
|
||||
title: undefined,
|
||||
@@ -128,14 +130,16 @@ describe('useSetGlobalCommandMenuContext', () => {
|
||||
result.current.setGlobalCommandMenuContext();
|
||||
});
|
||||
|
||||
expect(result.current.targetedRecordsRule).toEqual({
|
||||
expect(result.current.contextStoreTargetedRecordsRule).toEqual({
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [],
|
||||
});
|
||||
expect(result.current.numberOfSelectedRecords).toBe(0);
|
||||
expect(result.current.filters).toEqual([]);
|
||||
expect(result.current.anyFieldFilterValue).toEqual('');
|
||||
expect(result.current.currentViewType).toBe(ContextStoreViewType.Table);
|
||||
expect(result.current.contextStoreNumberOfSelectedRecords).toBe(0);
|
||||
expect(result.current.contextStoreFilters).toEqual([]);
|
||||
expect(result.current.contextStoreAnyFieldFilterValue).toEqual('');
|
||||
expect(result.current.contextStoreCurrentViewType).toBe(
|
||||
ContextStoreViewType.Table,
|
||||
);
|
||||
const commandMenuPageInfoAfter = jotaiStore.get(
|
||||
commandMenuPageInfoState.atom,
|
||||
);
|
||||
@@ -156,11 +160,13 @@ describe('useSetGlobalCommandMenuContext', () => {
|
||||
const { setGlobalCommandMenuContext } =
|
||||
useSetGlobalCommandMenuContext();
|
||||
|
||||
// eslint-disable-next-line twenty/matching-state-variable
|
||||
const previousTargetedRecordsRule = useAtomComponentStateValue(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
COMMAND_MENU_PREVIOUS_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
// eslint-disable-next-line twenty/matching-state-variable
|
||||
const previousNumberOfSelectedRecords = useAtomComponentStateValue(
|
||||
contextStoreNumberOfSelectedRecordsComponentState,
|
||||
COMMAND_MENU_PREVIOUS_COMPONENT_INSTANCE_ID,
|
||||
|
||||
+24
-26
@@ -2,7 +2,6 @@ import { renderHook } from '@testing-library/react';
|
||||
|
||||
import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/CommandMenuComponentInstanceId';
|
||||
import { useWorkflowCommandMenu } from '@/command-menu/hooks/useWorkflowCommandMenu';
|
||||
import { viewableRecordIdComponentState } from '@/command-menu/pages/record-page/states/viewableRecordIdComponentState';
|
||||
import { viewableRecordNameSingularComponentState } from '@/command-menu/pages/record-page/states/viewableRecordNameSingularComponentState';
|
||||
import { commandMenuWorkflowIdComponentState } from '@/command-menu/pages/workflow/states/commandMenuWorkflowIdComponentState';
|
||||
import { commandMenuWorkflowVersionIdComponentState } from '@/command-menu/pages/workflow/states/commandMenuWorkflowVersionIdComponentState';
|
||||
@@ -65,35 +64,32 @@ const renderHooks = () => {
|
||||
openWorkflowViewStepInCommandMenu,
|
||||
} = useWorkflowCommandMenu();
|
||||
|
||||
const _viewableRecordId = useAtomComponentStateValue(
|
||||
viewableRecordIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const viewableRecordNameSingular = useAtomComponentStateValue(
|
||||
viewableRecordNameSingularComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const currentObjectMetadataItemId = useAtomComponentStateValue(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const targetedRecordsRule = useAtomComponentStateValue(
|
||||
const contextStoreCurrentObjectMetadataItemId =
|
||||
useAtomComponentStateValue(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const contextStoreTargetedRecordsRule = useAtomComponentStateValue(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const numberOfSelectedRecords = useAtomComponentStateValue(
|
||||
const contextStoreNumberOfSelectedRecords = useAtomComponentStateValue(
|
||||
contextStoreNumberOfSelectedRecordsComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const currentViewType = useAtomComponentStateValue(
|
||||
const contextStoreCurrentViewType = useAtomComponentStateValue(
|
||||
contextStoreCurrentViewTypeComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const workflowId = useAtomComponentStateValue(
|
||||
const commandMenuWorkflowId = useAtomComponentStateValue(
|
||||
commandMenuWorkflowIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const workflowVersionId = useAtomComponentStateValue(
|
||||
const commandMenuWorkflowVersionId = useAtomComponentStateValue(
|
||||
commandMenuWorkflowVersionIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
@@ -105,13 +101,13 @@ const renderHooks = () => {
|
||||
openWorkflowEditStepInCommandMenu,
|
||||
openWorkflowEditStepTypeInCommandMenu,
|
||||
openWorkflowViewStepInCommandMenu,
|
||||
workflowId,
|
||||
workflowVersionId,
|
||||
commandMenuWorkflowId,
|
||||
commandMenuWorkflowVersionId,
|
||||
viewableRecordNameSingular,
|
||||
currentObjectMetadataItemId,
|
||||
targetedRecordsRule,
|
||||
numberOfSelectedRecords,
|
||||
currentViewType,
|
||||
contextStoreCurrentObjectMetadataItemId,
|
||||
contextStoreTargetedRecordsRule,
|
||||
contextStoreNumberOfSelectedRecords,
|
||||
contextStoreCurrentViewType,
|
||||
getIcon,
|
||||
};
|
||||
},
|
||||
@@ -134,7 +130,7 @@ describe('useWorkflowCommandMenu', () => {
|
||||
result.current.openWorkflowTriggerTypeInCommandMenu('test-workflow-id');
|
||||
});
|
||||
|
||||
expect(result.current.workflowId).toBe('test-workflow-id');
|
||||
expect(result.current.commandMenuWorkflowId).toBe('test-workflow-id');
|
||||
|
||||
expect(mockNavigateCommandMenu).toHaveBeenCalledWith({
|
||||
page: CommandMenuPages.WorkflowTriggerSelectType,
|
||||
@@ -151,7 +147,7 @@ describe('useWorkflowCommandMenu', () => {
|
||||
result.current.openWorkflowCreateStepInCommandMenu('test-workflow-id');
|
||||
});
|
||||
|
||||
expect(result.current.workflowId).toBe('test-workflow-id');
|
||||
expect(result.current.commandMenuWorkflowId).toBe('test-workflow-id');
|
||||
|
||||
expect(mockNavigateCommandMenu).toHaveBeenCalledWith({
|
||||
page: CommandMenuPages.WorkflowStepCreate,
|
||||
@@ -168,7 +164,7 @@ describe('useWorkflowCommandMenu', () => {
|
||||
result.current.openWorkflowEditStepTypeInCommandMenu('test-workflow-id');
|
||||
});
|
||||
|
||||
expect(result.current.workflowId).toBe('test-workflow-id');
|
||||
expect(result.current.commandMenuWorkflowId).toBe('test-workflow-id');
|
||||
|
||||
expect(mockNavigateCommandMenu).toHaveBeenCalledWith({
|
||||
page: CommandMenuPages.WorkflowStepEditType,
|
||||
@@ -189,7 +185,7 @@ describe('useWorkflowCommandMenu', () => {
|
||||
);
|
||||
});
|
||||
|
||||
expect(result.current.workflowId).toBe('test-workflow-id');
|
||||
expect(result.current.commandMenuWorkflowId).toBe('test-workflow-id');
|
||||
|
||||
expect(mockNavigateCommandMenu).toHaveBeenCalledWith({
|
||||
page: CommandMenuPages.WorkflowStepEdit,
|
||||
@@ -211,8 +207,10 @@ describe('useWorkflowCommandMenu', () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.current.workflowId).toBe('test-workflow-id');
|
||||
expect(result.current.workflowVersionId).toBe('test-workflow-version-id');
|
||||
expect(result.current.commandMenuWorkflowId).toBe('test-workflow-id');
|
||||
expect(result.current.commandMenuWorkflowVersionId).toBe(
|
||||
'test-workflow-version-id',
|
||||
);
|
||||
|
||||
expect(mockNavigateCommandMenu).toHaveBeenCalledWith({
|
||||
page: CommandMenuPages.WorkflowStepView,
|
||||
|
||||
@@ -38,7 +38,7 @@ export const useCommandMenuHotKeys = () => {
|
||||
|
||||
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
|
||||
|
||||
const contextStoreTargetedRecordsRuleComponent = useAtomComponentStateValue(
|
||||
const contextStoreTargetedRecordsRule = useAtomComponentStateValue(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
@@ -101,9 +101,8 @@ export const useCommandMenuHotKeys = () => {
|
||||
if (
|
||||
commandMenuPage === CommandMenuPages.Root &&
|
||||
!(
|
||||
contextStoreTargetedRecordsRuleComponent.mode === 'selection' &&
|
||||
contextStoreTargetedRecordsRuleComponent.selectedRecordIds.length ===
|
||||
0
|
||||
contextStoreTargetedRecordsRule.mode === 'selection' &&
|
||||
contextStoreTargetedRecordsRule.selectedRecordIds.length === 0
|
||||
)
|
||||
) {
|
||||
setGlobalCommandMenuContext();
|
||||
@@ -116,7 +115,7 @@ export const useCommandMenuHotKeys = () => {
|
||||
dependencies: [
|
||||
commandMenuPage,
|
||||
commandMenuSearch,
|
||||
contextStoreTargetedRecordsRuleComponent,
|
||||
contextStoreTargetedRecordsRule,
|
||||
goBackFromCommandMenu,
|
||||
setGlobalCommandMenuContext,
|
||||
],
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ const StyledContainer = styled.div`
|
||||
export const CommandMenuPageLayoutChartSettings = () => {
|
||||
const { pageLayoutId } = usePageLayoutIdFromContextStoreTargetedRecord();
|
||||
|
||||
const draftPageLayout = useAtomComponentStateValue(
|
||||
const pageLayoutDraft = useAtomComponentStateValue(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
@@ -28,7 +28,7 @@ export const CommandMenuPageLayoutChartSettings = () => {
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const widgetInEditMode = draftPageLayout.tabs
|
||||
const widgetInEditMode = pageLayoutDraft.tabs
|
||||
.flatMap((tab) => tab.widgets)
|
||||
.find((widget) => widget.id === pageLayoutEditingWidgetId);
|
||||
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
export const CommandMenuPageLayoutGraphFilter = () => {
|
||||
const { pageLayoutId } = usePageLayoutIdFromContextStoreTargetedRecord();
|
||||
|
||||
const draftPageLayout = useAtomComponentStateValue(
|
||||
const pageLayoutDraft = useAtomComponentStateValue(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
@@ -21,7 +21,7 @@ export const CommandMenuPageLayoutGraphFilter = () => {
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const widgetInEditMode = draftPageLayout.tabs
|
||||
const widgetInEditMode = pageLayoutDraft.tabs
|
||||
.flatMap((tab) => tab.widgets)
|
||||
.find((widget) => widget.id === pageLayoutEditingWidgetId);
|
||||
|
||||
|
||||
+12
-9
@@ -26,26 +26,29 @@ export const CommandMenuPageLayoutTabSettings = () => {
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
const { pageLayoutId } = usePageLayoutIdFromContextStoreTargetedRecord();
|
||||
|
||||
const draft = useAtomComponentStateValue(
|
||||
const pageLayoutDraft = useAtomComponentStateValue(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const [openTabId, setOpenTabId] = useAtomComponentState(
|
||||
pageLayoutTabSettingsOpenTabIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
const [pageLayoutTabSettingsOpenTabId, setPageLayoutTabSettingsOpenTabId] =
|
||||
useAtomComponentState(
|
||||
pageLayoutTabSettingsOpenTabIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const { moveLeft, moveRight } = useMovePageLayoutTab(pageLayoutId);
|
||||
const { deleteTab } = useDeletePageLayoutTab(pageLayoutId);
|
||||
const { duplicateTab } = useDuplicatePageLayoutTab(pageLayoutId);
|
||||
|
||||
if (!isDefined(openTabId)) {
|
||||
if (!isDefined(pageLayoutTabSettingsOpenTabId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tabsSorted = sortTabsByPosition(draft.tabs);
|
||||
const currentIndex = tabsSorted.findIndex((t) => t.id === openTabId);
|
||||
const tabsSorted = sortTabsByPosition(pageLayoutDraft.tabs);
|
||||
const currentIndex = tabsSorted.findIndex(
|
||||
(t) => t.id === pageLayoutTabSettingsOpenTabId,
|
||||
);
|
||||
if (currentIndex < 0) return null;
|
||||
const tab = tabsSorted[currentIndex];
|
||||
const canMoveLeft = currentIndex > 0;
|
||||
@@ -54,7 +57,7 @@ export const CommandMenuPageLayoutTabSettings = () => {
|
||||
|
||||
const handleDelete = () => {
|
||||
deleteTab(tab.id);
|
||||
setOpenTabId(null);
|
||||
setPageLayoutTabSettingsOpenTabId(null);
|
||||
closeCommandMenu();
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -84,13 +84,13 @@ export const CommandMenuPageLayoutWidgetTypeSelect = () => {
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const draftPageLayout = useAtomComponentStateValue(
|
||||
const pageLayoutDraft = useAtomComponentStateValue(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const existingWidget = isDefined(pageLayoutEditingWidgetId)
|
||||
? draftPageLayout.tabs
|
||||
? pageLayoutDraft.tabs
|
||||
.flatMap((tab) => tab.widgets)
|
||||
.find((widget) => widget.id === pageLayoutEditingWidgetId)
|
||||
: undefined;
|
||||
|
||||
+5
-5
@@ -23,21 +23,21 @@ export const WidgetSettingsFooter = ({
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
const { duplicateWidget } = useDuplicatePageLayoutWidget(pageLayoutId);
|
||||
const { deletePageLayoutWidget } = useDeletePageLayoutWidget(pageLayoutId);
|
||||
const editingWidgetId = useAtomComponentStateValue(
|
||||
const pageLayoutEditingWidgetId = useAtomComponentStateValue(
|
||||
pageLayoutEditingWidgetIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const handleDuplicateWidget = () => {
|
||||
if (isDefined(editingWidgetId)) {
|
||||
duplicateWidget(editingWidgetId);
|
||||
if (isDefined(pageLayoutEditingWidgetId)) {
|
||||
duplicateWidget(pageLayoutEditingWidgetId);
|
||||
}
|
||||
closeDropdown(dropdownId);
|
||||
};
|
||||
|
||||
const handleDeleteWidget = () => {
|
||||
if (isDefined(editingWidgetId)) {
|
||||
deletePageLayoutWidget(editingWidgetId);
|
||||
if (isDefined(pageLayoutEditingWidgetId)) {
|
||||
deletePageLayoutWidget(pageLayoutEditingWidgetId);
|
||||
}
|
||||
closeDropdown(dropdownId);
|
||||
};
|
||||
|
||||
+7
-7
@@ -4,22 +4,22 @@ import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAto
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
|
||||
export const usePageLayoutIdFromContextStoreTargetedRecord = () => {
|
||||
const targetedRecordsRule = useAtomComponentStateValue(
|
||||
const contextStoreTargetedRecordsRule = useAtomComponentStateValue(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
);
|
||||
|
||||
if (
|
||||
!(
|
||||
targetedRecordsRule.mode === 'selection' &&
|
||||
targetedRecordsRule.selectedRecordIds.length === 1
|
||||
contextStoreTargetedRecordsRule.mode === 'selection' &&
|
||||
contextStoreTargetedRecordsRule.selectedRecordIds.length === 1
|
||||
)
|
||||
) {
|
||||
throw new Error('Only one record should be selected');
|
||||
throw new Error('Only one recordStore should be selected');
|
||||
}
|
||||
|
||||
const recordId: string = targetedRecordsRule.selectedRecordIds[0];
|
||||
const recordId: string = contextStoreTargetedRecordsRule.selectedRecordIds[0];
|
||||
|
||||
const record = useAtomFamilyStateValue(recordStoreFamilyState, recordId);
|
||||
const recordStore = useAtomFamilyStateValue(recordStoreFamilyState, recordId);
|
||||
|
||||
return { pageLayoutId: record?.pageLayoutId };
|
||||
return { pageLayoutId: recordStore?.pageLayoutId };
|
||||
};
|
||||
|
||||
+6
-6
@@ -7,26 +7,26 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const usePageLayoutIdForRecordPageLayoutFromContextStoreTargetedRecord =
|
||||
() => {
|
||||
const targetedRecordsRule = useAtomComponentStateValue(
|
||||
const contextStoreTargetedRecordsRule = useAtomComponentStateValue(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
);
|
||||
|
||||
const objectMetadataId = useAtomComponentStateValue(
|
||||
const contextStoreCurrentObjectMetadataItemId = useAtomComponentStateValue(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
);
|
||||
|
||||
if (!isDefined(objectMetadataId)) {
|
||||
if (!isDefined(contextStoreCurrentObjectMetadataItemId)) {
|
||||
throw new Error('Object metadata ID is not defined');
|
||||
}
|
||||
|
||||
const { objectMetadataItem } = useObjectMetadataItemById({
|
||||
objectId: objectMetadataId ?? undefined,
|
||||
objectId: contextStoreCurrentObjectMetadataItemId ?? undefined,
|
||||
});
|
||||
|
||||
if (
|
||||
!(
|
||||
targetedRecordsRule.mode === 'selection' &&
|
||||
targetedRecordsRule.selectedRecordIds.length === 1
|
||||
contextStoreTargetedRecordsRule.mode === 'selection' &&
|
||||
contextStoreTargetedRecordsRule.selectedRecordIds.length === 1
|
||||
)
|
||||
) {
|
||||
throw new Error('Only one record should be selected');
|
||||
|
||||
+3
-3
@@ -12,7 +12,7 @@ export const useUpdateCurrentWidgetConfig = (pageLayoutIdFromProps: string) => {
|
||||
pageLayoutIdFromProps,
|
||||
);
|
||||
|
||||
const currentlyEditingWidgetId = useAtomComponentStateValue(
|
||||
const pageLayoutEditingWidgetId = useAtomComponentStateValue(
|
||||
pageLayoutEditingWidgetIdComponentState,
|
||||
pageLayoutIdFromProps,
|
||||
);
|
||||
@@ -33,7 +33,7 @@ export const useUpdateCurrentWidgetConfig = (pageLayoutIdFromProps: string) => {
|
||||
tabs: prev.tabs.map((tab) => ({
|
||||
...tab,
|
||||
widgets: tab.widgets.map((widget) =>
|
||||
widget.id === currentlyEditingWidgetId
|
||||
widget.id === pageLayoutEditingWidgetId
|
||||
? {
|
||||
...widget,
|
||||
objectMetadataId: objectMetadataId ?? widget.objectMetadataId,
|
||||
@@ -47,7 +47,7 @@ export const useUpdateCurrentWidgetConfig = (pageLayoutIdFromProps: string) => {
|
||||
})),
|
||||
});
|
||||
},
|
||||
[pageLayoutDraft, currentlyEditingWidgetId, store],
|
||||
[pageLayoutDraft, pageLayoutEditingWidgetId, store],
|
||||
);
|
||||
|
||||
return { updateCurrentWidgetConfig };
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ import { pageLayoutEditingWidgetIdComponentState } from '@/page-layout/states/pa
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
|
||||
export const useWidgetInEditMode = (pageLayoutId: string) => {
|
||||
const draftPageLayout = useAtomComponentStateValue(
|
||||
const pageLayoutDraft = useAtomComponentStateValue(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
@@ -13,7 +13,7 @@ export const useWidgetInEditMode = (pageLayoutId: string) => {
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const widgetInEditMode = draftPageLayout.tabs
|
||||
const widgetInEditMode = pageLayoutDraft.tabs
|
||||
.flatMap((tab) => tab.widgets)
|
||||
.find((widget) => widget.id === pageLayoutEditingWidgetId);
|
||||
|
||||
|
||||
+3
-3
@@ -3,14 +3,14 @@ import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/use
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useCommandMenuWorkflowIdOrThrow = () => {
|
||||
const workflowId = useAtomComponentStateValue(
|
||||
const commandMenuWorkflowId = useAtomComponentStateValue(
|
||||
commandMenuWorkflowIdComponentState,
|
||||
);
|
||||
if (!isDefined(workflowId)) {
|
||||
if (!isDefined(commandMenuWorkflowId)) {
|
||||
throw new Error(
|
||||
'Expected commandMenuWorkflowIdComponentState to be defined',
|
||||
);
|
||||
}
|
||||
|
||||
return workflowId;
|
||||
return commandMenuWorkflowId;
|
||||
};
|
||||
|
||||
+3
-3
@@ -3,14 +3,14 @@ import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/use
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useCommandMenuWorkflowRunIdOrThrow = () => {
|
||||
const workflowRunId = useAtomComponentStateValue(
|
||||
const commandMenuWorkflowRunId = useAtomComponentStateValue(
|
||||
commandMenuWorkflowRunIdComponentState,
|
||||
);
|
||||
if (!isDefined(workflowRunId)) {
|
||||
if (!isDefined(commandMenuWorkflowRunId)) {
|
||||
throw new Error(
|
||||
'Expected the commandMenuWorkflowRunIdComponentState to be defined.',
|
||||
);
|
||||
}
|
||||
|
||||
return workflowRunId;
|
||||
return commandMenuWorkflowRunId;
|
||||
};
|
||||
|
||||
+3
-3
@@ -3,14 +3,14 @@ import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/use
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useCommandMenuWorkflowVersionIdOrThrow = () => {
|
||||
const workflowVersionId = useAtomComponentStateValue(
|
||||
const commandMenuWorkflowVersionId = useAtomComponentStateValue(
|
||||
commandMenuWorkflowVersionIdComponentState,
|
||||
);
|
||||
if (!isDefined(workflowVersionId)) {
|
||||
if (!isDefined(commandMenuWorkflowVersionId)) {
|
||||
throw new Error(
|
||||
'Expected commandMenuWorkflowVersionIdComponentState to be defined',
|
||||
);
|
||||
}
|
||||
|
||||
return workflowVersionId;
|
||||
return commandMenuWorkflowVersionId;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user