## 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:
Charles Bochet
2026-02-24 17:37:01 +01:00
committed by GitHub
parent c6ec764b23
commit 0f2af6a6cb
1326 changed files with 19248 additions and 19389 deletions
@@ -22,7 +22,8 @@ import { getStepItemIcon } from '@/workflow/workflow-variables/utils/getStepItem
import { getVariableTemplateFromPath } from '@/workflow/workflow-variables/utils/getVariableTemplateFromPath';
import { searchVariableThroughOutputSchemaV2 } from '@/workflow/workflow-variables/utils/searchVariableThroughOutputSchemaV2';
import { useLingui } from '@lingui/react/macro';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import {
type FilterableAndTSVectorFieldType,
type StepFilter,
@@ -61,71 +62,71 @@ export const WorkflowDropdownStepOutputItems = ({
const { getInitialFilterValue } = useGetInitialFilterValue();
const updateStepFilter = useRecoilCallback(
({ snapshot }) =>
({
const jotaiStore = useStore();
const updateStepFilter = useCallback(
({
rawVariableName,
isFullRecord,
}: {
rawVariableName: string;
isFullRecord: boolean;
}) => {
const stepId = extractRawVariableNamePart({
rawVariableName,
isFullRecord,
}: {
rawVariableName: string;
isFullRecord: boolean;
}) => {
const stepId = extractRawVariableNamePart({
part: 'stepId',
});
const [currentStepOutputSchema] = jotaiStore.get(
stepsOutputSchemaFamilySelector.selectorFamily({
workflowVersionId,
stepIds: [stepId],
}),
);
const { variableType, fieldMetadataId, compositeFieldSubFieldName } =
searchVariableThroughOutputSchemaV2({
stepOutputSchema: currentStepOutputSchema,
stepType: step.type,
rawVariableName,
part: 'stepId',
isFullRecord: false,
});
const [currentStepOutputSchema] = snapshot
.getLoadable(
stepsOutputSchemaFamilySelector({
workflowVersionId,
stepIds: [stepId],
}),
)
.getValue();
const { variableType, fieldMetadataId, compositeFieldSubFieldName } =
searchVariableThroughOutputSchemaV2({
stepOutputSchema: currentStepOutputSchema,
stepType: step.type,
rawVariableName,
isFullRecord: false,
});
const { fieldMetadataItem: filterFieldMetadataItem } = isDefined(
fieldMetadataId,
)
? getFieldMetadataItemByIdOrThrow(fieldMetadataId)
: { fieldMetadataItem: undefined };
const { fieldMetadataItem: filterFieldMetadataItem } = isDefined(
const filterType = isDefined(fieldMetadataId)
? (filterFieldMetadataItem?.type ?? 'unknown')
: variableType;
const availableOperandsForFilter = getStepFilterOperands({
filterType,
subFieldName: compositeFieldSubFieldName,
});
const defaultOperand = availableOperandsForFilter[0];
const { value } = getInitialFilterValue(
filterType as FilterableAndTSVectorFieldType,
defaultOperand,
);
upsertStepFilterSettings({
stepFilterToUpsert: {
...stepFilter,
stepOutputKey: rawVariableName,
isFullRecord,
type: filterType ?? 'unknown',
value: value,
fieldMetadataId,
)
? getFieldMetadataItemByIdOrThrow(fieldMetadataId)
: { fieldMetadataItem: undefined };
const filterType = isDefined(fieldMetadataId)
? (filterFieldMetadataItem?.type ?? 'unknown')
: variableType;
const availableOperandsForFilter = getStepFilterOperands({
filterType,
subFieldName: compositeFieldSubFieldName,
});
const defaultOperand = availableOperandsForFilter[0];
const { value } = getInitialFilterValue(
filterType as FilterableAndTSVectorFieldType,
defaultOperand,
);
upsertStepFilterSettings({
stepFilterToUpsert: {
...stepFilter,
stepOutputKey: rawVariableName,
isFullRecord,
type: filterType ?? 'unknown',
value: value,
fieldMetadataId,
compositeFieldSubFieldName,
operand: defaultOperand,
},
});
},
compositeFieldSubFieldName,
operand: defaultOperand,
},
});
},
[
jotaiStore,
workflowVersionId,
step.type,
getFieldMetadataItemByIdOrThrow,
@@ -1,5 +1,5 @@
import { workflowRunIteratorSubStepIterationIndexComponentState } from '@/command-menu/pages/workflow/step/view-run/states/workflowRunIteratorSubStepIterationIndexComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useWorkflowRun } from '@/workflow/hooks/useWorkflowRun';
import { useWorkflowRunIdOrThrow } from '@/workflow/hooks/useWorkflowRunIdOrThrow';
import { getStepDefinitionOrThrow } from '@/workflow/utils/getStepDefinitionOrThrow';
@@ -29,7 +29,7 @@ export const WorkflowRunStepInputDetail = ({ stepId }: { stepId: string }) => {
(step) => step.id === stepId,
);
const workflowRunIteratorSubStepIterationIndex = useRecoilComponentValue(
const workflowRunIteratorSubStepIterationIndex = useRecoilComponentValueV2(
workflowRunIteratorSubStepIterationIndexComponentState,
);
@@ -1,6 +1,6 @@
import { useRecoilComponentFamilyState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyStateV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { currentStepFilterGroupsComponentState } from '@/workflow/workflow-steps/filters/states/currentStepFilterGroupsComponentState';
import { currentStepFiltersComponentState } from '@/workflow/workflow-steps/filters/states/currentStepFiltersComponentState';
import { hasInitializedCurrentStepFilterGroupsComponentFamilyState } from '@/workflow/workflow-steps/filters/states/hasInitializedCurrentStepFilterGroupsComponentFamilyState';
@@ -31,7 +31,7 @@ export const WorkflowEditActionFilterBodyEffect = ({
const [
hasInitializedCurrentStepFilters,
setHasInitializedCurrentStepFilters,
] = useRecoilComponentFamilyState(
] = useRecoilComponentFamilyStateV2(
hasInitializedCurrentStepFiltersComponentFamilyState,
{ stepId },
);
@@ -39,23 +39,23 @@ export const WorkflowEditActionFilterBodyEffect = ({
const [
hasInitializedCurrentStepFilterGroups,
setHasInitializedCurrentStepFilterGroups,
] = useRecoilComponentFamilyState(
] = useRecoilComponentFamilyStateV2(
hasInitializedCurrentStepFilterGroupsComponentFamilyState,
{ stepId },
);
const currentStepFilters = useRecoilComponentValue(
const currentStepFilters = useRecoilComponentValueV2(
currentStepFiltersComponentState,
);
const currentStepFilterGroups = useRecoilComponentValue(
const currentStepFilterGroups = useRecoilComponentValueV2(
currentStepFilterGroupsComponentState,
);
const setCurrentStepFilters = useSetRecoilComponentState(
const setCurrentStepFilters = useSetRecoilComponentStateV2(
currentStepFiltersComponentState,
);
const setCurrentStepFilterGroups = useSetRecoilComponentState(
const setCurrentStepFilterGroups = useSetRecoilComponentStateV2(
currentStepFilterGroupsComponentState,
);
@@ -1,12 +1,12 @@
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useSetRecoilComponentFamilyState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentFamilyState';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { useSetRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentFamilyStateV2';
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/filters/states/context/WorkflowStepFilterContext';
import { currentStepFilterGroupsComponentState } from '@/workflow/workflow-steps/filters/states/currentStepFilterGroupsComponentState';
import { currentStepFiltersComponentState } from '@/workflow/workflow-steps/filters/states/currentStepFiltersComponentState';
import { hasInitializedCurrentStepFilterGroupsComponentFamilyState } from '@/workflow/workflow-steps/filters/states/hasInitializedCurrentStepFilterGroupsComponentFamilyState';
import { hasInitializedCurrentStepFiltersComponentFamilyState } from '@/workflow/workflow-steps/filters/states/hasInitializedCurrentStepFiltersComponentFamilyState';
import { useContext } from 'react';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback, useContext } from 'react';
import {
type StepFilter,
type StepFilterGroup,
@@ -19,64 +19,64 @@ export const useAddRootStepFilter = () => {
const { stepId, onFilterSettingsUpdate } = useContext(
WorkflowStepFilterContext,
);
const currentStepFilterGroupsCallbackState = useRecoilComponentCallbackState(
const currentStepFilterGroupsAtom = useRecoilComponentStateCallbackStateV2(
currentStepFilterGroupsComponentState,
);
const currentStepFiltersCallbackState = useRecoilComponentCallbackState(
const currentStepFiltersAtom = useRecoilComponentStateCallbackStateV2(
currentStepFiltersComponentState,
);
const setHasInitializedCurrentStepFilters = useSetRecoilComponentFamilyState(
hasInitializedCurrentStepFiltersComponentFamilyState,
{ stepId },
);
const setHasInitializedCurrentStepFilters =
useSetRecoilComponentFamilyStateV2(
hasInitializedCurrentStepFiltersComponentFamilyState,
{ stepId },
);
const setHasInitializedCurrentStepFilterGroups =
useSetRecoilComponentFamilyState(
useSetRecoilComponentFamilyStateV2(
hasInitializedCurrentStepFilterGroupsComponentFamilyState,
{ stepId },
);
const addRootStepFilterRecoilCallback = useRecoilCallback(
({ set }) =>
() => {
const newStepFilterGroup: StepFilterGroup = {
id: v4(),
logicalOperator: StepLogicalOperator.AND,
};
const store = useStore();
const newStepFilter: StepFilter = {
id: v4(),
type: 'unknown',
value: '',
operand: ViewFilterOperand.IS,
stepFilterGroupId: newStepFilterGroup.id,
stepOutputKey: '',
positionInStepFilterGroup: 0,
};
const addRootStepFilter = useCallback(() => {
const newStepFilterGroup: StepFilterGroup = {
id: v4(),
logicalOperator: StepLogicalOperator.AND,
};
set(currentStepFilterGroupsCallbackState, [newStepFilterGroup]);
set(currentStepFiltersCallbackState, [newStepFilter]);
const newStepFilter: StepFilter = {
id: v4(),
type: 'unknown',
value: '',
operand: ViewFilterOperand.IS,
stepFilterGroupId: newStepFilterGroup.id,
stepOutputKey: '',
positionInStepFilterGroup: 0,
};
setHasInitializedCurrentStepFilters(true);
setHasInitializedCurrentStepFilterGroups(true);
store.set(currentStepFilterGroupsAtom, [newStepFilterGroup]);
store.set(currentStepFiltersAtom, [newStepFilter]);
onFilterSettingsUpdate({
stepFilterGroups: [newStepFilterGroup],
stepFilters: [newStepFilter],
});
},
[
onFilterSettingsUpdate,
currentStepFilterGroupsCallbackState,
currentStepFiltersCallbackState,
setHasInitializedCurrentStepFilters,
setHasInitializedCurrentStepFilterGroups,
],
);
setHasInitializedCurrentStepFilters(true);
setHasInitializedCurrentStepFilterGroups(true);
onFilterSettingsUpdate({
stepFilterGroups: [newStepFilterGroup],
stepFilters: [newStepFilter],
});
}, [
onFilterSettingsUpdate,
currentStepFilterGroupsAtom,
currentStepFiltersAtom,
setHasInitializedCurrentStepFilters,
setHasInitializedCurrentStepFilterGroups,
store,
]);
return {
addRootStepFilter: addRootStepFilterRecoilCallback,
addRootStepFilter,
};
};
@@ -1,4 +1,4 @@
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { currentStepFilterGroupsComponentState } from '@/workflow/workflow-steps/filters/states/currentStepFilterGroupsComponentState';
import { currentStepFiltersComponentState } from '@/workflow/workflow-steps/filters/states/currentStepFiltersComponentState';
import { type StepFilter, type StepFilterGroup } from 'twenty-shared/types';
@@ -9,11 +9,13 @@ export const useChildStepFiltersAndChildStepFilterGroups = ({
}: {
stepFilterGroupId: string;
}) => {
const stepFilterGroups = useRecoilComponentValue(
const stepFilterGroups = useRecoilComponentValueV2(
currentStepFilterGroupsComponentState,
);
const stepFilters = useRecoilComponentValue(currentStepFiltersComponentState);
const stepFilters = useRecoilComponentValueV2(
currentStepFiltersComponentState,
);
const currentStepFilterGroup = stepFilterGroups?.find(
(stepFilterGroup) => stepFilterGroup.id === stepFilterGroupId,
@@ -1,11 +1,11 @@
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2';
import { createStepSelector } from '@/workflow/states/selectors/stepSelector';
import { useMemo } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const useFilterCounter = ({ stepId }: { stepId: string }) => {
const stepSelector = useMemo(() => createStepSelector(stepId), [stepId]);
const step = useRecoilComponentValue(stepSelector);
const step = useRecoilComponentSelectorValueV2(stepSelector);
if (!isDefined(step)) {
return {
@@ -1,107 +1,100 @@
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { currentStepFilterGroupsComponentState } from '@/workflow/workflow-steps/filters/states/currentStepFilterGroupsComponentState';
import { currentStepFiltersComponentState } from '@/workflow/workflow-steps/filters/states/currentStepFiltersComponentState';
import { useContext } from 'react';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback, useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/filters/states/context/WorkflowStepFilterContext';
export const useRemoveStepFilter = () => {
const { onFilterSettingsUpdate } = useContext(WorkflowStepFilterContext);
const currentStepFiltersCallbackState = useRecoilComponentCallbackState(
const currentStepFiltersAtom = useRecoilComponentStateCallbackStateV2(
currentStepFiltersComponentState,
);
const currentStepFilterGroupsCallbackState = useRecoilComponentCallbackState(
const currentStepFilterGroupsAtom = useRecoilComponentStateCallbackStateV2(
currentStepFilterGroupsComponentState,
);
const removeStepFilterRecoilCallback = useRecoilCallback(
({ set, snapshot }) =>
(stepFilterId: string) => {
const stepFilters = getSnapshotValue(
snapshot,
currentStepFiltersCallbackState,
);
const store = useStore();
const stepFilterGroups = getSnapshotValue(
snapshot,
currentStepFilterGroupsCallbackState,
);
const removeStepFilter = useCallback(
(stepFilterId: string) => {
const stepFilters = store.get(currentStepFiltersAtom);
const stepFilterGroups = store.get(currentStepFilterGroupsAtom);
const rootStepFilterGroup = stepFilterGroups?.find(
(filterGroup) => !isDefined(filterGroup.parentStepFilterGroupId),
);
const rootStepFilterGroup = stepFilterGroups.find(
(filterGroup) => !isDefined(filterGroup.parentStepFilterGroupId),
);
if (!isDefined(rootStepFilterGroup)) return;
if (!isDefined(rootStepFilterGroup)) return;
const stepFilterToRemove = stepFilters?.find(
(filter) => filter.id === stepFilterId,
);
const stepFilterToRemove = stepFilters.find(
(filter) => filter.id === stepFilterId,
);
if (!isDefined(stepFilterToRemove)) return;
if (!isDefined(stepFilterToRemove)) return;
const updatedStepFilters = (stepFilters ?? []).filter(
(filter) => filter.id !== stepFilterId,
);
const updatedStepFilters = stepFilters.filter(
(filter) => filter.id !== stepFilterId,
);
const parentStepFilterGroup = stepFilterGroups?.find(
(filterGroup) =>
filterGroup.id === stepFilterToRemove.stepFilterGroupId,
);
const parentStepFilterGroup = stepFilterGroups.find(
(filterGroup) =>
filterGroup.id === stepFilterToRemove.stepFilterGroupId,
);
const stepFiltersInParentStepFilterGroup = updatedStepFilters?.filter(
(filter) => filter.stepFilterGroupId === parentStepFilterGroup?.id,
);
const stepFiltersInParentStepFilterGroup = updatedStepFilters.filter(
(filter) => filter.stepFilterGroupId === parentStepFilterGroup?.id,
);
const stepFilterGroupsInParentStepFilterGroup =
stepFilterGroups?.filter(
(g) => g.parentStepFilterGroupId === parentStepFilterGroup?.id,
);
const stepFilterGroupsInParentStepFilterGroup = stepFilterGroups.filter(
(group) => group.parentStepFilterGroupId === parentStepFilterGroup?.id,
);
const shouldDeleteParentStepFilterGroup =
stepFiltersInParentStepFilterGroup?.length === 0 &&
stepFilterGroupsInParentStepFilterGroup?.length === 0;
const shouldDeleteParentStepFilterGroup =
stepFiltersInParentStepFilterGroup.length === 0 &&
stepFilterGroupsInParentStepFilterGroup.length === 0;
const updatedStepFilterGroups = shouldDeleteParentStepFilterGroup
? (stepFilterGroups ?? []).filter(
(filterGroup) => filterGroup.id !== parentStepFilterGroup?.id,
)
: stepFilterGroups;
const updatedStepFilterGroups = shouldDeleteParentStepFilterGroup
? stepFilterGroups.filter(
(filterGroup) => filterGroup.id !== parentStepFilterGroup?.id,
)
: stepFilterGroups;
const shouldResetStepFilterSettings =
updatedStepFilterGroups.length === 1 &&
updatedStepFilterGroups[0].id === rootStepFilterGroup?.id &&
updatedStepFilters.length === 0;
const shouldResetStepFilterSettings =
updatedStepFilterGroups.length === 1 &&
updatedStepFilterGroups[0].id === rootStepFilterGroup?.id &&
updatedStepFilters.length === 0;
if (shouldResetStepFilterSettings) {
set(currentStepFilterGroupsCallbackState, []);
set(currentStepFiltersCallbackState, []);
if (shouldResetStepFilterSettings) {
store.set(currentStepFilterGroupsAtom, []);
store.set(currentStepFiltersAtom, []);
onFilterSettingsUpdate({
stepFilterGroups: [],
stepFilters: [],
});
} else {
set(currentStepFilterGroupsCallbackState, updatedStepFilterGroups);
set(currentStepFiltersCallbackState, updatedStepFilters);
onFilterSettingsUpdate({
stepFilterGroups: [],
stepFilters: [],
});
} else {
store.set(currentStepFilterGroupsAtom, updatedStepFilterGroups);
store.set(currentStepFiltersAtom, updatedStepFilters);
onFilterSettingsUpdate({
stepFilters: updatedStepFilters,
stepFilterGroups: updatedStepFilterGroups,
});
}
},
onFilterSettingsUpdate({
stepFilters: updatedStepFilters,
stepFilterGroups: updatedStepFilterGroups,
});
}
},
[
onFilterSettingsUpdate,
currentStepFilterGroupsCallbackState,
currentStepFiltersCallbackState,
currentStepFilterGroupsAtom,
currentStepFiltersAtom,
store,
],
);
return {
removeStepFilter: removeStepFilterRecoilCallback,
removeStepFilter,
};
};
@@ -1,79 +1,73 @@
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/filters/states/context/WorkflowStepFilterContext';
import { currentStepFilterGroupsComponentState } from '@/workflow/workflow-steps/filters/states/currentStepFilterGroupsComponentState';
import { currentStepFiltersComponentState } from '@/workflow/workflow-steps/filters/states/currentStepFiltersComponentState';
import { useContext } from 'react';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback, useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const useRemoveStepFilterGroup = () => {
const { onFilterSettingsUpdate } = useContext(WorkflowStepFilterContext);
const currentStepFilterGroupsCallbackState = useRecoilComponentCallbackState(
const currentStepFilterGroupsAtom = useRecoilComponentStateCallbackStateV2(
currentStepFilterGroupsComponentState,
);
const currentStepFiltersCallbackState = useRecoilComponentCallbackState(
const currentStepFiltersAtom = useRecoilComponentStateCallbackStateV2(
currentStepFiltersComponentState,
);
const removeStepFilterGroupRecoilCallback = useRecoilCallback(
({ set, snapshot }) =>
(stepFilterGroupId: string) => {
const stepFilterGroups = getSnapshotValue(
snapshot,
currentStepFilterGroupsCallbackState,
);
const store = useStore();
const stepFilters = getSnapshotValue(
snapshot,
currentStepFiltersCallbackState,
);
const removeStepFilterGroup = useCallback(
(stepFilterGroupId: string) => {
const stepFilterGroups = store.get(currentStepFilterGroupsAtom);
const stepFilters = store.get(currentStepFiltersAtom);
const rootStepFilterGroup = stepFilterGroups?.find(
(filterGroup) => !isDefined(filterGroup.parentStepFilterGroupId),
);
const rootStepFilterGroup = stepFilterGroups.find(
(filterGroup) => !isDefined(filterGroup.parentStepFilterGroupId),
);
const updatedStepFilterGroups = (stepFilterGroups ?? []).filter(
(filterGroup) => filterGroup.id !== stepFilterGroupId,
);
const updatedStepFilterGroups = stepFilterGroups.filter(
(filterGroup) => filterGroup.id !== stepFilterGroupId,
);
const updatedStepFilters = (stepFilters ?? []).filter(
(filter) => filter.stepFilterGroupId !== stepFilterGroupId,
);
const updatedStepFilters = stepFilters.filter(
(filter) => filter.stepFilterGroupId !== stepFilterGroupId,
);
const shouldResetStepFilterSettings =
updatedStepFilterGroups.length === 1 &&
updatedStepFilterGroups[0].id === rootStepFilterGroup?.id &&
updatedStepFilters.length === 0;
const shouldResetStepFilterSettings =
updatedStepFilterGroups.length === 1 &&
updatedStepFilterGroups[0].id === rootStepFilterGroup?.id &&
updatedStepFilters.length === 0;
if (shouldResetStepFilterSettings) {
set(currentStepFilterGroupsCallbackState, []);
set(currentStepFiltersCallbackState, []);
if (shouldResetStepFilterSettings) {
store.set(currentStepFilterGroupsAtom, []);
store.set(currentStepFiltersAtom, []);
onFilterSettingsUpdate({
stepFilterGroups: [],
stepFilters: [],
});
} else {
set(currentStepFilterGroupsCallbackState, updatedStepFilterGroups);
set(currentStepFiltersCallbackState, updatedStepFilters);
onFilterSettingsUpdate({
stepFilterGroups: [],
stepFilters: [],
});
} else {
store.set(currentStepFilterGroupsAtom, updatedStepFilterGroups);
store.set(currentStepFiltersAtom, updatedStepFilters);
onFilterSettingsUpdate({
stepFilterGroups: updatedStepFilterGroups,
stepFilters: updatedStepFilters,
});
}
},
onFilterSettingsUpdate({
stepFilterGroups: updatedStepFilterGroups,
stepFilters: updatedStepFilters,
});
}
},
[
onFilterSettingsUpdate,
currentStepFilterGroupsCallbackState,
currentStepFiltersCallbackState,
currentStepFilterGroupsAtom,
currentStepFiltersAtom,
store,
],
);
return {
removeStepFilterGroup: removeStepFilterGroupRecoilCallback,
removeStepFilterGroup,
};
};
@@ -1,84 +1,78 @@
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/filters/states/context/WorkflowStepFilterContext';
import { currentStepFilterGroupsComponentState } from '@/workflow/workflow-steps/filters/states/currentStepFilterGroupsComponentState';
import { currentStepFiltersComponentState } from '@/workflow/workflow-steps/filters/states/currentStepFiltersComponentState';
import { useContext } from 'react';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback, useContext } from 'react';
import { type StepFilter, type StepFilterGroup } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
export const useUpsertStepFilterSettings = () => {
const currentStepFilterGroupsCallbackState = useRecoilComponentCallbackState(
const currentStepFilterGroupsAtom = useRecoilComponentStateCallbackStateV2(
currentStepFilterGroupsComponentState,
);
const currentStepFiltersCallbackState = useRecoilComponentCallbackState(
const currentStepFiltersAtom = useRecoilComponentStateCallbackStateV2(
currentStepFiltersComponentState,
);
const { onFilterSettingsUpdate } = useContext(WorkflowStepFilterContext);
const upsertStepFilterSettingsRecoilCallback = useRecoilCallback(
({ set, snapshot }) =>
({
stepFilterGroupToUpsert,
stepFilterToUpsert,
}: {
stepFilterGroupToUpsert?: StepFilterGroup;
stepFilterToUpsert?: StepFilter;
}) => {
const stepFilterGroups = getSnapshotValue(
snapshot,
currentStepFilterGroupsCallbackState,
const store = useStore();
const upsertStepFilterSettings = useCallback(
({
stepFilterGroupToUpsert,
stepFilterToUpsert,
}: {
stepFilterGroupToUpsert?: StepFilterGroup;
stepFilterToUpsert?: StepFilter;
}) => {
const stepFilterGroups = store.get(currentStepFilterGroupsAtom);
const stepFilters = store.get(currentStepFiltersAtom);
const updatedStepFilterGroups = [...stepFilterGroups];
const updatedStepFilters = [...stepFilters];
if (isDefined(stepFilterGroupToUpsert)) {
const existingIndex = updatedStepFilterGroups.findIndex(
(filterGroup) => filterGroup.id === stepFilterGroupToUpsert.id,
);
const stepFilters = getSnapshotValue(
snapshot,
currentStepFiltersCallbackState,
if (existingIndex >= 0) {
updatedStepFilterGroups[existingIndex] = stepFilterGroupToUpsert;
} else {
updatedStepFilterGroups.push(stepFilterGroupToUpsert);
}
store.set(currentStepFilterGroupsAtom, updatedStepFilterGroups);
}
if (isDefined(stepFilterToUpsert)) {
const existingIndex = updatedStepFilters.findIndex(
(filter) => filter.id === stepFilterToUpsert.id,
);
const updatedStepFilterGroups = [...(stepFilterGroups ?? [])];
const updatedStepFilters = [...(stepFilters ?? [])];
if (isDefined(stepFilterGroupToUpsert)) {
const existingIndex = updatedStepFilterGroups.findIndex(
(filterGroup) => filterGroup.id === stepFilterGroupToUpsert.id,
);
if (existingIndex >= 0) {
updatedStepFilterGroups[existingIndex] = stepFilterGroupToUpsert;
} else {
updatedStepFilterGroups.push(stepFilterGroupToUpsert);
}
set(currentStepFilterGroupsCallbackState, updatedStepFilterGroups);
if (existingIndex >= 0) {
updatedStepFilters[existingIndex] = stepFilterToUpsert;
} else {
updatedStepFilters.push(stepFilterToUpsert);
}
store.set(currentStepFiltersAtom, updatedStepFilters);
}
if (isDefined(stepFilterToUpsert)) {
const existingIndex = updatedStepFilters.findIndex(
(filter) => filter.id === stepFilterToUpsert.id,
);
if (existingIndex >= 0) {
updatedStepFilters[existingIndex] = stepFilterToUpsert;
} else {
updatedStepFilters.push(stepFilterToUpsert);
}
set(currentStepFiltersCallbackState, updatedStepFilters);
}
onFilterSettingsUpdate({
stepFilterGroups: updatedStepFilterGroups,
stepFilters: updatedStepFilters,
});
},
onFilterSettingsUpdate({
stepFilterGroups: updatedStepFilterGroups,
stepFilters: updatedStepFilters,
});
},
[
onFilterSettingsUpdate,
currentStepFilterGroupsCallbackState,
currentStepFiltersCallbackState,
currentStepFilterGroupsAtom,
currentStepFiltersAtom,
store,
],
);
return {
upsertStepFilterSettings: upsertStepFilterSettingsRecoilCallback,
upsertStepFilterSettings,
};
};
@@ -1,8 +1,8 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { StepFilterGroupsComponentInstanceContext } from '@/workflow/workflow-steps/filters/states/context/StepFilterGroupsComponentInstanceContext';
import { type StepFilterGroup } from 'twenty-shared/types';
export const currentStepFilterGroupsComponentState = createComponentState<
export const currentStepFilterGroupsComponentState = createComponentStateV2<
StepFilterGroup[]
>({
key: 'currentStepFilterGroupsComponentState',
@@ -1,8 +1,8 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { StepFiltersComponentInstanceContext } from '@/workflow/workflow-steps/filters/states/context/StepFiltersComponentInstanceContext';
import { type StepFilter } from 'twenty-shared/types';
export const currentStepFiltersComponentState = createComponentState<
export const currentStepFiltersComponentState = createComponentStateV2<
StepFilter[]
>({
key: 'currentStepFiltersComponentState',
@@ -1,8 +1,8 @@
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentFamilyStateV2';
import { StepFilterGroupsComponentInstanceContext } from '@/workflow/workflow-steps/filters/states/context/StepFilterGroupsComponentInstanceContext';
export const hasInitializedCurrentStepFilterGroupsComponentFamilyState =
createComponentFamilyState<boolean, { stepId: string }>({
createComponentFamilyStateV2<boolean, { stepId: string }>({
key: 'hasInitializedCurrentStepFilterGroupsComponentFamilyState',
defaultValue: false,
componentInstanceContext: StepFilterGroupsComponentInstanceContext,
@@ -1,8 +1,8 @@
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentFamilyStateV2';
import { StepFiltersComponentInstanceContext } from '@/workflow/workflow-steps/filters/states/context/StepFiltersComponentInstanceContext';
export const hasInitializedCurrentStepFiltersComponentFamilyState =
createComponentFamilyState<boolean, { stepId: string }>({
createComponentFamilyStateV2<boolean, { stepId: string }>({
key: 'hasInitializedCurrentStepFiltersComponentFamilyState',
defaultValue: false,
componentInstanceContext: StepFiltersComponentInstanceContext,
@@ -1,16 +1,18 @@
import { createComponentSelector } from '@/ui/utilities/state/component-state/utils/createComponentSelector';
import { createComponentSelectorV2 } from '@/ui/utilities/state/jotai/utils/createComponentSelectorV2';
import { StepFilterGroupsComponentInstanceContext } from '@/workflow/workflow-steps/filters/states/context/StepFilterGroupsComponentInstanceContext';
import { currentStepFilterGroupsComponentState } from '@/workflow/workflow-steps/filters/states/currentStepFilterGroupsComponentState';
import { type StepFilterGroup } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
export const rootLevelStepFilterGroupComponentSelector =
createComponentSelector({
createComponentSelectorV2<StepFilterGroup | undefined>({
key: 'rootLevelStepFilterGroupComponentSelector',
get:
({ instanceId }) =>
({ get }) => {
const currentStepFilterGroups = get(
currentStepFilterGroupsComponentState.atomFamily({ instanceId }),
currentStepFilterGroupsComponentState,
{ instanceId },
);
const rootLevelStepFilterGroup = currentStepFilterGroups.find(
@@ -1,4 +1,4 @@
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import { workflowLastCreatedStepIdComponentState } from '@/workflow/states/workflowLastCreatedStepIdComponentState';
import { type WorkflowActionType } from '@/workflow/types/Workflow';
@@ -18,10 +18,10 @@ import { v4 } from 'uuid';
export const useCreateStep = () => {
const [isLoading, setIsLoading] = useState(false);
const { createWorkflowVersionStep } = useCreateWorkflowVersionStep();
const setWorkflowSelectedNode = useSetRecoilComponentState(
const setWorkflowSelectedNode = useSetRecoilComponentStateV2(
workflowSelectedNodeComponentState,
);
const setWorkflowLastCreatedStepId = useSetRecoilComponentState(
const setWorkflowLastCreatedStepId = useSetRecoilComponentStateV2(
workflowLastCreatedStepIdComponentState,
);
@@ -8,7 +8,7 @@ import {
} from '~/generated/graphql';
import { useUpdateWorkflowVersionCache } from '@/workflow/workflow-steps/hooks/useUpdateWorkflowVersionCache';
import { flowComponentState } from '@/workflow/states/flowComponentState';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { isDefined } from 'twenty-shared/utils';
export const useCreateWorkflowVersionStep = () => {
@@ -16,7 +16,7 @@ export const useCreateWorkflowVersionStep = () => {
const { updateWorkflowVersionCache } = useUpdateWorkflowVersionCache();
const setFlow = useSetRecoilComponentState(flowComponentState);
const setFlow = useSetRecoilComponentStateV2(flowComponentState);
const [mutate] = useMutation<
CreateWorkflowVersionStepMutation,
@@ -1,5 +1,5 @@
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
@@ -17,7 +17,7 @@ export const useDeleteStep = () => {
const { getUpdatableWorkflowVersion } =
useGetUpdatableWorkflowVersionOrThrow();
const { closeCommandMenu } = useCommandMenu();
const workflowVisualizerWorkflowId = useRecoilComponentValue(
const workflowVisualizerWorkflowId = useRecoilComponentValueV2(
workflowVisualizerWorkflowIdComponentState,
);
const workflow = useWorkflowWithCurrentVersion(workflowVisualizerWorkflowId);
@@ -1,4 +1,4 @@
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import { workflowLastCreatedStepIdComponentState } from '@/workflow/states/workflowLastCreatedStepIdComponentState';
import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeComponentState';
@@ -10,10 +10,10 @@ import { isDefined } from 'twenty-shared/utils';
export const useDuplicateStep = () => {
const [isLoading, setIsLoading] = useState(false);
const { duplicateWorkflowVersionStep } = useDuplicateWorkflowVersionStep();
const setWorkflowSelectedNode = useSetRecoilComponentState(
const setWorkflowSelectedNode = useSetRecoilComponentStateV2(
workflowSelectedNodeComponentState,
);
const setWorkflowLastCreatedStepId = useSetRecoilComponentState(
const setWorkflowLastCreatedStepId = useSetRecoilComponentStateV2(
workflowLastCreatedStepIdComponentState,
);
@@ -1,5 +1,5 @@
import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { DUPLICATE_WORKFLOW_VERSION_STEP } from '@/workflow/graphql/mutations/duplicateWorkflowVersionStep';
import { flowComponentState } from '@/workflow/states/flowComponentState';
import { useUpdateWorkflowVersionCache } from '@/workflow/workflow-steps/hooks/useUpdateWorkflowVersionCache';
@@ -16,7 +16,7 @@ export const useDuplicateWorkflowVersionStep = () => {
const { updateWorkflowVersionCache } = useUpdateWorkflowVersionCache();
const setFlow = useSetRecoilComponentState(flowComponentState);
const setFlow = useSetRecoilComponentStateV2(flowComponentState);
const [mutate] = useMutation<
DuplicateWorkflowVersionStepMutation,
@@ -1,5 +1,5 @@
import { workflowRunIteratorSubStepIterationIndexComponentState } from '@/command-menu/pages/workflow/step/view-run/states/workflowRunIteratorSubStepIterationIndexComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useWorkflowRun } from '@/workflow/hooks/useWorkflowRun';
import { useWorkflowRunIdOrThrow } from '@/workflow/hooks/useWorkflowRunIdOrThrow';
import { isDefined } from 'twenty-shared/utils';
@@ -9,7 +9,7 @@ export const useWorkflowRunStepInfo = ({ stepId }: { stepId: string }) => {
const workflowRunId = useWorkflowRunIdOrThrow();
const workflowRun = useWorkflowRun({ workflowRunId });
const workflowRunIteratorSubStepIterationIndex = useRecoilComponentValue(
const workflowRunIteratorSubStepIterationIndex = useRecoilComponentValueV2(
workflowRunIteratorSubStepIterationIndexComponentState,
);
@@ -1,4 +1,4 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { WorkflowVisualizerComponentInstanceContext } from '@/workflow/workflow-diagram/states/contexts/WorkflowVisualizerComponentInstanceContext';
import { type WorkflowStepConnectionOptions } from '@/workflow/workflow-diagram/workflow-iterator/types/WorkflowStepConnectionOptions';
@@ -10,7 +10,7 @@ type WorkflowInsertStepIdsState = {
};
export const workflowInsertStepIdsComponentState =
createComponentState<WorkflowInsertStepIdsState>({
createComponentStateV2<WorkflowInsertStepIdsState>({
key: 'workflowInsertStepIdsComponentState',
defaultValue: {
parentStepId: undefined,
@@ -17,16 +17,14 @@ import { TabList } from '@/ui/layout/tab-list/components/TabList';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowCodeEditor } from '@/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowCodeEditor';
import { WorkflowEditActionCodeFields } from '@/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCodeFields';
import { WORKFLOW_LOGIC_FUNCTION_TAB_LIST_COMPONENT_ID } from '@/workflow/workflow-steps/workflow-actions/code-action/constants/WorkflowLogicFunctionTabListComponentId';
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 { WorkflowLogicFunctionTabId } from '@/workflow/workflow-steps/workflow-actions/code-action/types/WorkflowLogicFunctionTabId';
import { getWrongExportedFunctionMarkers } from '@/workflow/workflow-steps/workflow-actions/code-action/utils/getWrongExportedFunctionMarkers';
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
@@ -39,7 +37,6 @@ import { type Monaco } from '@monaco-editor/react';
import { type editor } from 'monaco-editor';
import { AutoTypings } from 'monaco-editor-auto-typings';
import { useState } from 'react';
import { useRecoilState } from 'recoil';
import { Key } from 'ts-key-enum';
import { isDefined } from 'twenty-shared/utils';
import {
@@ -105,7 +102,7 @@ export const WorkflowEditActionCode = ({
const { getUpdatableWorkflowVersion } =
useGetUpdatableWorkflowVersionOrThrow();
const workflowVisualizerWorkflowId = useRecoilComponentValue(
const workflowVisualizerWorkflowId = useRecoilComponentValueV2(
workflowVisualizerWorkflowIdComponentState,
);
const workflow = useWorkflowWithCurrentVersion(workflowVisualizerWorkflowId);
@@ -131,10 +128,14 @@ export const WorkflowEditActionCode = ({
id: logicFunctionId,
});
const [logicFunctionTestData, setLogicFunctionTestData] =
useRecoilState<LogicFunctionTestData>(
logicFunctionTestDataFamilyState(logicFunctionId),
);
const logicFunctionTestData = useFamilyRecoilValueV2(
logicFunctionTestDataFamilyState,
logicFunctionId,
);
const setLogicFunctionTestData = useSetFamilyRecoilStateV2(
logicFunctionTestDataFamilyState,
logicFunctionId,
);
const [functionInput, setFunctionInput] =
useState<LogicFunctionInputFormData>(
@@ -1,4 +1,4 @@
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
import { createFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createFamilyStateV2';
import { LogicFunctionExecutionStatus } from '~/generated-metadata/graphql';
export type LogicFunctionTestData = {
@@ -21,7 +21,7 @@ export const DEFAULT_OUTPUT_VALUE = {
status: LogicFunctionExecutionStatus.IDLE,
};
export const logicFunctionTestDataFamilyState = createFamilyState<
export const logicFunctionTestDataFamilyState = createFamilyStateV2<
LogicFunctionTestData,
string
>({
@@ -17,7 +17,7 @@ import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent
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 { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
@@ -62,7 +62,7 @@ export const WorkflowEditActionEmailBase = ({
const { enqueueErrorSnackBar } = useSnackBar();
const { uploadAttachmentFile } = useUploadAttachmentFile();
const workflowVisualizerWorkflowId = useRecoilComponentValue(
const workflowVisualizerWorkflowId = useRecoilComponentValueV2(
workflowVisualizerWorkflowIdComponentState,
);
@@ -1,5 +1,5 @@
import { InputLabel } from '@/ui/input/components/InputLabel';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2';
import { type WorkflowFilterAction } from '@/workflow/types/Workflow';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowStepFilterAddFilterRuleSelect } from '@/workflow/workflow-steps/filters/components/WorkflowStepFilterAddFilterRuleSelect';
@@ -49,7 +49,7 @@ export const WorkflowEditActionFilterBody = ({
action,
actionOptions,
}: WorkflowEditActionFilterBodyProps) => {
const rootStepFilterGroup = useRecoilComponentValue(
const rootStepFilterGroup = useRecoilComponentSelectorValueV2(
rootLevelStepFilterGroupComponentSelector,
);
@@ -3,13 +3,13 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI
import { AdvancedFilterCommandMenuContainer } from '@/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuContainer';
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { type FindRecordsActionFilter } from '@/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords';
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
export const WorkflowFindRecordsFilters = ({
objectMetadataItem,
@@ -20,39 +20,33 @@ export const WorkflowFindRecordsFilters = ({
onChange: (filter: FindRecordsActionFilter) => void;
readonly?: boolean;
}) => {
const currentRecordFilterGroupsCallbackState =
useRecoilComponentCallbackState(currentRecordFilterGroupsComponentState);
const currentRecordFilterGroupsAtom = useRecoilComponentStateCallbackStateV2(
currentRecordFilterGroupsComponentState,
);
const currentRecordFiltersCallbackState = useRecoilComponentCallbackState(
const currentRecordFiltersAtom = useRecoilComponentStateCallbackStateV2(
currentRecordFiltersComponentState,
);
const onUpdate = useRecoilCallback(
({ snapshot }) =>
() => {
const currentRecordFilterGroups = getSnapshotValue(
snapshot,
currentRecordFilterGroupsCallbackState,
);
const store = useStore();
const currentRecordFilters = getSnapshotValue(
snapshot,
currentRecordFiltersCallbackState,
);
const onUpdate = useCallback(() => {
const currentRecordFilterGroups = store.get(currentRecordFilterGroupsAtom);
const newFilter = {
recordFilterGroups: currentRecordFilterGroups,
recordFilters: currentRecordFilters,
} satisfies FindRecordsActionFilter;
const currentRecordFilters = store.get(currentRecordFiltersAtom);
onChange(newFilter);
},
[
currentRecordFilterGroupsCallbackState,
currentRecordFiltersCallbackState,
onChange,
],
);
const newFilter = {
recordFilterGroups: currentRecordFilterGroups,
recordFilters: currentRecordFilters,
} satisfies FindRecordsActionFilter;
onChange(newFilter);
}, [
currentRecordFilterGroupsAtom,
currentRecordFiltersAtom,
onChange,
store,
]);
return (
<AdvancedFilterCommandMenuContainer
@@ -1,8 +1,8 @@
import { useSetAdvancedFilterDropdownStates } from '@/object-record/advanced-filter/hooks/useSetAdvancedFilterDropdownAllRowsStates';
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { useRecoilComponentFamilyState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyState';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyStateV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { hasInitializedCurrentRecordFilterGroupsComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordFilterGroupsComponentFamilyState';
import { hasInitializedCurrentRecordFiltersComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordFiltersComponentFamilyState';
import { type FindRecordsActionFilter } from '@/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords';
@@ -17,7 +17,7 @@ export const WorkflowFindRecordsFiltersEffect = ({
const [
hasInitializedCurrentRecordFilters,
setHasInitializedCurrentRecordFilters,
] = useRecoilComponentFamilyState(
] = useRecoilComponentFamilyStateV2(
hasInitializedCurrentRecordFiltersComponentFamilyState,
{},
);
@@ -25,16 +25,16 @@ export const WorkflowFindRecordsFiltersEffect = ({
const [
hasInitializedCurrentRecordFilterGroups,
setHasInitializedCurrentRecordFilterGroups,
] = useRecoilComponentFamilyState(
] = useRecoilComponentFamilyStateV2(
hasInitializedCurrentRecordFilterGroupsComponentFamilyState,
{},
);
const setCurrentRecordFilters = useSetRecoilComponentState(
const setCurrentRecordFilters = useSetRecoilComponentStateV2(
currentRecordFiltersComponentState,
);
const setCurrentRecordFilterGroups = useSetRecoilComponentState(
const setCurrentRecordFilterGroups = useSetRecoilComponentStateV2(
currentRecordFilterGroupsComponentState,
);
@@ -3,10 +3,11 @@ import { FormTextFieldInput } from '@/object-record/record-field/ui/form-types/c
import { type WorkflowStep } from '@/workflow/types/Workflow';
import { getWorkflowVariablesUsedInStep } from '@/workflow/workflow-steps/utils/getWorkflowVariablesUsedInStep';
import { type HttpRequestFormData } from '@/workflow/workflow-steps/workflow-actions/http-request-action/constants/HttpRequest';
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
import { httpRequestTestDataFamilyState } from '@/workflow/workflow-steps/workflow-actions/http-request-action/states/httpRequestTestDataFamilyState';
import { t } from '@lingui/core/macro';
import styled from '@emotion/styled';
import { useRecoilState } from 'recoil';
const StyledVariableInputsContainer = styled.div`
display: flex;
@@ -25,8 +26,13 @@ export const HttpRequestTestVariableInput = ({
actionId,
readonly,
}: HttpRequestTestVariableInputProps) => {
const [httpRequestTestData, setHttpRequestTestData] = useRecoilState(
httpRequestTestDataFamilyState(actionId),
const httpRequestTestData = useFamilyRecoilValueV2(
httpRequestTestDataFamilyState,
actionId,
);
const setHttpRequestTestData = useSetFamilyRecoilStateV2(
httpRequestTestDataFamilyState,
actionId,
);
const mockStep: WorkflowStep = {
id: 'test-step',
@@ -4,12 +4,13 @@ import {
type HttpRequestFormData,
} from '@/workflow/workflow-steps/workflow-actions/http-request-action/constants/HttpRequest';
import { TEST_HTTP_REQUEST } from '@/workflow/workflow-steps/workflow-actions/http-request-action/graphql/mutations/testHttpRequest';
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
import { httpRequestTestDataFamilyState } from '@/workflow/workflow-steps/workflow-actions/http-request-action/states/httpRequestTestDataFamilyState';
import { useMutation } from '@apollo/client';
import { t } from '@lingui/core/macro';
import { isObject, isString } from '@sniptt/guards';
import { useState } from 'react';
import { useRecoilState } from 'recoil';
import { isDefined, parseJson, resolveInput } from 'twenty-shared/utils';
import {
type TestHttpRequestInput,
@@ -43,8 +44,13 @@ const convertFlatVariablesToNestedContext = (flatVariables: {
export const useTestHttpRequest = (actionId: string) => {
const apolloCoreClient = useApolloCoreClient();
const [isTesting, setIsTesting] = useState(false);
const [httpRequestTestData, setHttpRequestTestData] = useRecoilState(
httpRequestTestDataFamilyState(actionId),
const httpRequestTestData = useFamilyRecoilValueV2(
httpRequestTestDataFamilyState,
actionId,
);
const setHttpRequestTestData = useSetFamilyRecoilStateV2(
httpRequestTestDataFamilyState,
actionId,
);
const [mutate] = useMutation<
@@ -1,8 +1,8 @@
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
import { createFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createFamilyStateV2';
import { DEFAULT_HTTP_REQUEST_OUTPUT_VALUE } from '@/workflow/workflow-steps/workflow-actions/http-request-action/constants/HttpRequest';
import { type HttpRequestTestData } from '@/workflow/workflow-steps/workflow-actions/http-request-action/types/HttpRequestTestData';
export const httpRequestTestDataFamilyState = createFamilyState<
export const httpRequestTestDataFamilyState = createFamilyStateV2<
HttpRequestTestData,
string
>({
@@ -1,6 +1,6 @@
import { InputLabel } from '@/ui/input/components/InputLabel';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
@@ -68,21 +68,21 @@ export const WorkflowEditActionIfElseBody = ({
const { updateWorkflowVersionPosition } = useTidyUpWorkflowVersion();
const { deleteWorkflowVersionStep } = useDeleteWorkflowVersionStep();
const { deleteStepsOutputSchema } = useStepsOutputSchema();
const workflowVisualizerWorkflowId = useRecoilComponentValue(
const workflowVisualizerWorkflowId = useRecoilComponentValueV2(
workflowVisualizerWorkflowIdComponentState,
);
const workflow = useWorkflowWithCurrentVersion(workflowVisualizerWorkflowId);
const currentStepFilters = useRecoilComponentValue(
const currentStepFilters = useRecoilComponentValueV2(
currentStepFiltersComponentState,
);
const currentStepFilterGroups = useRecoilComponentValue(
const currentStepFilterGroups = useRecoilComponentValueV2(
currentStepFilterGroupsComponentState,
);
const setCurrentStepFilters = useSetRecoilComponentState(
const setCurrentStepFilters = useSetRecoilComponentStateV2(
currentStepFiltersComponentState,
);
const setCurrentStepFilterGroups = useSetRecoilComponentState(
const setCurrentStepFilterGroups = useSetRecoilComponentStateV2(
currentStepFilterGroupsComponentState,
);
@@ -1,5 +1,5 @@
import { workflowRunIteratorSubStepIterationIndexComponentState } from '@/command-menu/pages/workflow/step/view-run/states/workflowRunIteratorSubStepIterationIndexComponentState';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow';
import { useWorkflowRun } from '@/workflow/hooks/useWorkflowRun';
import { useWorkflowRunIdOrThrow } from '@/workflow/hooks/useWorkflowRunIdOrThrow';
@@ -37,7 +37,7 @@ export const WorkflowIteratorSubStepSwitcher = ({
const [
workflowRunIteratorSubStepIterationIndex,
setWorkflowRunIteratorSubStepIterationIndex,
] = useRecoilComponentState(
] = useRecoilComponentStateV2(
workflowRunIteratorSubStepIterationIndexComponentState,
);