## 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
@@ -10,7 +10,8 @@ import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRe
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { getAllRecordFilterDescendantsOfRecordFilterGroup } from '@/object-record/record-filter/utils/getAllRecordFilterDescendantsOfRecordFilterGroup';
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 { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2';
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
import { ViewBarFilterDropdownIds } from '@/views/constants/ViewBarFilterDropdownIds';
import { plural } from '@lingui/core/macro';
@@ -21,11 +22,11 @@ import { IconFilter } from 'twenty-ui/display';
export const AdvancedFilterChip = () => {
const { closeDropdown } = useCloseDropdown();
const currentRecordFilterGroups = useRecoilComponentValue(
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
);
const currentRecordFilters = useRecoilComponentValue(
const currentRecordFilters = useRecoilComponentValueV2(
currentRecordFiltersComponentState,
);
@@ -39,7 +40,7 @@ export const AdvancedFilterChip = () => {
const { removeRootRecordFilterGroupIfEmpty } =
useRemoveRootRecordFilterGroupIfEmpty();
const rootRecordFilterGroup = useRecoilComponentValue(
const rootRecordFilterGroup = useRecoilComponentSelectorValueV2(
rootLevelRecordFilterGroupComponentSelector,
);
@@ -3,13 +3,13 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { AdvancedFilterRootRecordFilterGroup } from '@/object-record/advanced-filter/components/AdvancedFilterRootRecordFilterGroup';
import { useSetAdvancedFilterDropdownStates } from '@/object-record/advanced-filter/hooks/useSetAdvancedFilterDropdownAllRowsStates';
import { rootLevelRecordFilterGroupComponentSelector } from '@/object-record/advanced-filter/states/rootLevelRecordFilterGroupComponentSelector';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2';
import { AdvancedFilterChip } from '@/views/advanced-filter-chip/components/AdvancedFilterChip';
import { ViewBarFilterDropdownIds } from '@/views/constants/ViewBarFilterDropdownIds';
import { isDefined } from 'twenty-shared/utils';
export const AdvancedFilterDropdownButton = () => {
const rootLevelRecordFilterGroup = useRecoilComponentValue(
const rootLevelRecordFilterGroup = useRecoilComponentSelectorValueV2(
rootLevelRecordFilterGroupComponentSelector,
);
@@ -1,6 +1,6 @@
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
import { ViewBarFilterDropdownIds } from '@/views/constants/ViewBarFilterDropdownIds';
import { useLingui } from '@lingui/react/macro';
@@ -11,9 +11,8 @@ export const AnyFieldSearchChip = () => {
const { closeDropdown } = useCloseDropdown();
const [anyFieldFilterValue, setAnyFieldFilterValue] = useRecoilComponentState(
anyFieldFilterValueComponentState,
);
const [anyFieldFilterValue, setAnyFieldFilterValue] =
useRecoilComponentStateV2(anyFieldFilterValueComponentState);
const handleRemoveClick = () => {
closeDropdown();
@@ -6,7 +6,7 @@ import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObje
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { useFiltersFromQueryParams } from '@/views/hooks/internal/useFiltersFromQueryParams';
import { useHasFiltersInQueryParams } from '@/views/hooks/internal/useHasFiltersInQueryParams';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
@@ -31,11 +31,11 @@ export const QueryParamsFiltersEffect = () => {
const { mapViewFiltersToRecordFilters } = useMapViewFiltersToFilters();
const { recordIndexId } = useRecordIndexContextOrThrow();
const setCurrentRecordFilters = useSetRecoilComponentState(
const setCurrentRecordFilters = useSetRecoilComponentStateV2(
currentRecordFiltersComponentState,
recordIndexId,
);
const setCurrentRecordFilterGroups = useSetRecoilComponentState(
const setCurrentRecordFilterGroups = useSetRecoilComponentStateV2(
currentRecordFilterGroupsComponentState,
recordIndexId,
);
@@ -1,7 +1,7 @@
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { isSoftDeleteFilterActiveComponentState } from '@/object-record/record-table/states/isSoftDeleteFilterActiveComponentState';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
import { useIcons } from 'twenty-ui/display';
@@ -14,7 +14,7 @@ export const SoftDeleteFilterChip = ({
recordFilter,
viewBarId,
}: SoftDeleteFilterChipProps) => {
const setIsSoftDeleteFilterActive = useSetRecoilComponentState(
const setIsSoftDeleteFilterActive = useSetRecoilComponentStateV2(
isSoftDeleteFilterActiveComponentState,
viewBarId,
);
@@ -7,8 +7,8 @@ import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
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 { UPDATE_VIEW_BUTTON_DROPDOWN_ID } from '@/views/constants/UpdateViewButtonDropdownId';
import { useHasFiltersInQueryParams } from '@/views/hooks/internal/useHasFiltersInQueryParams';
import { useAreViewFilterGroupsDifferentFromRecordFilterGroups } from '@/views/hooks/useAreViewFilterGroupsDifferentFromRecordFilterGroups';
@@ -45,7 +45,7 @@ export const UpdateViewButtonGroup = () => {
const { setViewPickerMode } = useViewPickerMode();
const currentViewId = useRecoilComponentValue(
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
);
@@ -53,7 +53,7 @@ export const UpdateViewButtonGroup = () => {
const { openDropdown: openViewPickerDropdown } = useOpenDropdown();
const { currentView } = useGetCurrentViewOnly();
const setViewPickerReferenceViewId = useSetRecoilComponentState(
const setViewPickerReferenceViewId = useSetRecoilComponentStateV2(
viewPickerReferenceViewIdComponentState,
);
@@ -1,9 +1,9 @@
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
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 { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
import { hasInitializedAnyFieldFilterComponentFamilyState } from '@/views/states/hasInitializedAnyFieldFilterComponentFamilyState';
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
@@ -11,11 +11,11 @@ import { useEffect } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const ViewBarAnyFieldFilterEffect = () => {
const currentViewId = useRecoilComponentValue(
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
);
const { objectMetadataItem } = useRecordIndexContextOrThrow();
const { objectMetadataItem, recordIndexId } = useRecordIndexContextOrThrow();
const currentView = useFamilySelectorValueV2(
coreViewFromViewIdFamilySelector,
@@ -23,15 +23,16 @@ export const ViewBarAnyFieldFilterEffect = () => {
);
const [hasInitializedAnyFieldFilter, setHasInitializedAnyFieldFilter] =
useRecoilComponentFamilyState(
useRecoilComponentFamilyStateV2(
hasInitializedAnyFieldFilterComponentFamilyState,
{
viewId: currentViewId ?? undefined,
},
);
const setAnyFieldFilterValue = useSetRecoilComponentState(
const setAnyFieldFilterValue = useSetRecoilComponentStateV2(
anyFieldFilterValueComponentState,
recordIndexId,
);
useEffect(() => {
@@ -4,7 +4,6 @@ import { type ReactNode, useMemo } from 'react';
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { useHandleToggleTrashColumnFilter } from '@/object-record/record-index/hooks/useHandleToggleTrashColumnFilter';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { AdvancedFilterDropdownButton } from '@/views/advanced-filter-chip/components/AdvancedFilterDropdownButton';
import { ViewBarDetailsAddFilterButton } from '@/views/components/ViewBarDetailsAddFilterButton';
@@ -107,26 +106,30 @@ export const ViewBarDetails = ({
viewBarId,
objectNamePlural,
}: ViewBarDetailsProps) => {
const isViewBarExpanded = useRecoilComponentValue(
const isViewBarExpanded = useRecoilComponentValueV2(
isViewBarExpandedComponentState,
);
const { hasFiltersQueryParams } = useHasFiltersInQueryParams();
const currentRecordFilterGroups = useRecoilComponentValue(
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
viewBarId,
);
const currentRecordFilters = useRecoilComponentValue(
const currentRecordFilters = useRecoilComponentValueV2(
currentRecordFiltersComponentState,
viewBarId,
);
const currentRecordSorts = useRecoilComponentValue(
const currentRecordSorts = useRecoilComponentValueV2(
currentRecordSortsComponentState,
viewBarId,
);
const anyFieldFilterValue = useRecoilComponentValue(
const anyFieldFilterValue = useRecoilComponentValueV2(
anyFieldFilterValueComponentState,
viewBarId,
);
const { objectNameSingular } = useObjectNameSingularFromPlural({
@@ -5,7 +5,7 @@ import { ViewBarFilterDropdownIds } from '@/views/constants/ViewBarFilterDropdow
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
import { isRecordFilterConsideredEmpty } from '@/object-record/record-filter/utils/isRecordFilterConsideredEmpty';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { ViewBarFilterDropdownContent } from '@/views/components/ViewBarFilterDropdownContent';
import { isDefined } from 'twenty-shared/utils';
import { ViewBarFilterButton } from './ViewBarFilterButton';
@@ -14,7 +14,7 @@ export const ViewBarFilterDropdown = () => {
const { resetFilterDropdown } = useResetFilterDropdown();
const { removeRecordFilter } = useRemoveRecordFilter();
const objectFilterDropdownCurrentRecordFilter = useRecoilComponentValue(
const objectFilterDropdownCurrentRecordFilter = useRecoilComponentValueV2(
objectFilterDropdownCurrentRecordFilterComponentState,
);
@@ -13,7 +13,7 @@ import { useSetRecordFilterUsedInAdvancedFilterDropdownRow } from '@/object-reco
import { useCreateEmptyRecordFilterFromFieldMetadataItem } from '@/object-record/record-filter/hooks/useCreateEmptyRecordFilterFromFieldMetadataItem';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { ViewBarFilterDropdownIds } from '@/views/constants/ViewBarFilterDropdownIds';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import styled from '@emotion/styled';
@@ -67,7 +67,7 @@ export const ViewBarFilterDropdownAdvancedFilterButton = () => {
},
);
const currentRecordFilterGroups = useRecoilComponentValue(
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
);
@@ -1,7 +1,7 @@
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyValueV2';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
import { IconSearch } from 'twenty-ui/display';
@@ -25,7 +25,7 @@ export const ViewBarFilterDropdownAnyFieldSearchButtonMenuItem = ({
}: ViewBarFilterDropdownAnyFieldSearchButtonMenuItemProps) => {
const { t } = useLingui();
const objectFilterDropdownSearchInput = useRecoilComponentValue(
const objectFilterDropdownSearchInput = useRecoilComponentValueV2(
objectFilterDropdownSearchInputComponentState,
);
@@ -1,21 +1,22 @@
import { objectFilterDropdownAnyFieldSearchIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownAnyFieldSearchIsSelectedComponentState';
import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { ViewBarFilterDropdownAnyFieldSearchInput } from '@/views/components/ViewBarFilterDropdownAnyFieldSearchInput';
import { ViewBarFilterDropdownFieldSelectMenu } from '@/views/components/ViewBarFilterDropdownFieldSelectMenu';
import { ViewBarFilterDropdownFilterInput } from '@/views/components/ViewBarFilterDropdownFilterInput';
import { ViewBarFilterDropdownIds } from '@/views/constants/ViewBarFilterDropdownIds';
export const ViewBarFilterDropdownContent = () => {
const [objectFilterDropdownFilterIsSelected] = useRecoilComponentState(
const [objectFilterDropdownFilterIsSelected] = useRecoilComponentStateV2(
objectFilterDropdownFilterIsSelectedComponentState,
ViewBarFilterDropdownIds.MAIN,
);
const objectFilterDropdownAnyFieldSearchIsSelected = useRecoilComponentValue(
objectFilterDropdownAnyFieldSearchIsSelectedComponentState,
);
const objectFilterDropdownAnyFieldSearchIsSelected =
useRecoilComponentValueV2(
objectFilterDropdownAnyFieldSearchIsSelectedComponentState,
);
const isAnyFieldSearchFilter = objectFilterDropdownAnyFieldSearchIsSelected;
@@ -10,7 +10,7 @@ import { FILTER_FIELD_LIST_ID } from '@/object-record/object-filter-dropdown/con
import { useFilterDropdownSelectableFieldMetadataItems } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdownSelectableFieldMetadataItems';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuSectionLabel } from '@/ui/layout/dropdown/components/DropdownMenuSectionLabel';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
import { ViewBarFilterDropdownBottomMenu } from '@/views/components/ViewBarFilterDropdownBottomMenu';
import { ViewBarFilterDropdownFieldSelectMenuItem } from '@/views/components/ViewBarFilterDropdownFieldSelectMenuItem';
@@ -53,7 +53,7 @@ export const StyledInput = styled.input`
export const ViewBarFilterDropdownFieldSelectMenu = () => {
const [objectFilterDropdownSearchInput, setObjectFilterDropdownSearchInput] =
useRecoilComponentState(objectFilterDropdownSearchInputComponentState);
useRecoilComponentStateV2(objectFilterDropdownSearchInputComponentState);
const {
selectableHiddenFieldMetadataItems,
@@ -2,11 +2,11 @@ import { useResetFilterDropdown } from '@/object-record/object-filter-dropdown/h
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2';
import { IconChevronLeft } from 'twenty-ui/display';
export const ViewBarFilterDropdownFilterInputMenuHeader = () => {
const fieldMetadataItemUsedInDropdown = useRecoilComponentValue(
const fieldMetadataItemUsedInDropdown = useRecoilComponentSelectorValueV2(
fieldMetadataItemUsedInDropdownComponentSelector,
);
@@ -1,9 +1,9 @@
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { currentRecordFieldsComponentState } from '@/object-record/record-field/states/currentRecordFieldsComponentState';
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
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 { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
import { hasInitializedCurrentRecordFieldsComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordFieldsComponentFamilyState';
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
@@ -12,7 +12,7 @@ import { useEffect } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const ViewBarRecordFieldEffect = () => {
const currentViewId = useRecoilComponentValue(
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
);
@@ -26,14 +26,14 @@ export const ViewBarRecordFieldEffect = () => {
const [
hasInitializedCurrentRecordFields,
setHasInitializedCurrentRecordFields,
] = useRecoilComponentFamilyState(
] = useRecoilComponentFamilyStateV2(
hasInitializedCurrentRecordFieldsComponentFamilyState,
{
viewId: currentViewId ?? undefined,
},
);
const setCurrentRecordFields = useSetRecoilComponentState(
const setCurrentRecordFields = useSetRecoilComponentStateV2(
currentRecordFieldsComponentState,
);
@@ -1,9 +1,9 @@
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
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 { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
import { useMapViewFiltersToFilters } from '@/views/hooks/useMapViewFiltersToFilters';
import { hasInitializedCurrentRecordFiltersComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordFiltersComponentFamilyState';
@@ -12,11 +12,11 @@ import { useEffect } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const ViewBarRecordFilterEffect = () => {
const currentViewId = useRecoilComponentValue(
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
);
const { objectMetadataItem } = useRecordIndexContextOrThrow();
const { objectMetadataItem, recordIndexId } = useRecordIndexContextOrThrow();
const currentView = useFamilySelectorValueV2(
coreViewFromViewIdFamilySelector,
@@ -26,15 +26,16 @@ export const ViewBarRecordFilterEffect = () => {
const [
hasInitializedCurrentRecordFilters,
setHasInitializedCurrentRecordFilters,
] = useRecoilComponentFamilyState(
] = useRecoilComponentFamilyStateV2(
hasInitializedCurrentRecordFiltersComponentFamilyState,
{
viewId: currentViewId ?? undefined,
},
);
const setCurrentRecordFilters = useSetRecoilComponentState(
const setCurrentRecordFilters = useSetRecoilComponentStateV2(
currentRecordFiltersComponentState,
recordIndexId,
);
const { mapViewFiltersToRecordFilters } = useMapViewFiltersToFilters();
@@ -1,9 +1,9 @@
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
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 { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
import { hasInitializedCurrentRecordFilterGroupsComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordFilterGroupsComponentFamilyState';
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
@@ -12,11 +12,11 @@ import { useEffect } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const ViewBarRecordFilterGroupEffect = () => {
const currentViewId = useRecoilComponentValue(
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
);
const { objectMetadataItem } = useRecordIndexContextOrThrow();
const { objectMetadataItem, recordIndexId } = useRecordIndexContextOrThrow();
const currentView = useFamilySelectorValueV2(
coreViewFromViewIdFamilySelector,
@@ -26,15 +26,16 @@ export const ViewBarRecordFilterGroupEffect = () => {
const [
hasInitializedCurrentRecordFilterGroups,
setHasInitializedCurrentRecordFilterGroups,
] = useRecoilComponentFamilyState(
] = useRecoilComponentFamilyStateV2(
hasInitializedCurrentRecordFilterGroupsComponentFamilyState,
{
viewId: currentViewId ?? undefined,
},
);
const setCurrentRecordFilterGroups = useSetRecoilComponentState(
const setCurrentRecordFilterGroups = useSetRecoilComponentStateV2(
currentRecordFilterGroupsComponentState,
recordIndexId,
);
useEffect(() => {
@@ -1,9 +1,9 @@
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
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 { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
import { hasInitializedCurrentRecordSortsComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordSortsComponentFamilyState';
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
@@ -11,11 +11,11 @@ import { useEffect } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const ViewBarRecordSortEffect = () => {
const currentViewId = useRecoilComponentValue(
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
);
const { objectMetadataItem } = useRecordIndexContextOrThrow();
const { objectMetadataItem, recordIndexId } = useRecordIndexContextOrThrow();
const currentView = useFamilySelectorValueV2(
coreViewFromViewIdFamilySelector,
@@ -25,15 +25,16 @@ export const ViewBarRecordSortEffect = () => {
const [
hasInitializedCurrentRecordSorts,
setHasInitializedCurrentRecordSorts,
] = useRecoilComponentFamilyState(
] = useRecoilComponentFamilyStateV2(
hasInitializedCurrentRecordSortsComponentFamilyState,
{
viewId: currentViewId ?? undefined,
},
);
const setCurrentRecordSorts = useSetRecoilComponentState(
const setCurrentRecordSorts = useSetRecoilComponentStateV2(
currentRecordSortsComponentState,
recordIndexId,
);
useEffect(() => {
@@ -4,7 +4,7 @@ import { ObjectOptionsDropdownContext } from '@/object-record/object-options-dro
import { useChangeRecordFieldVisibility } from '@/object-record/record-field/hooks/useChangeRecordFieldVisibility';
import { currentRecordFieldsComponentState } from '@/object-record/record-field/states/currentRecordFieldsComponentState';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { ViewType } from '@/views/types/ViewType';
import { useContext } from 'react';
import { IconEye, useIcons } from 'twenty-ui/display';
@@ -29,7 +29,7 @@ export const ViewFieldsHiddenDropdownSection = () => {
? handleBoardFieldVisibilityChange
: changeRecordFieldVisibility;
const currentRecordFields = useRecoilComponentValue(
const currentRecordFields = useRecoilComponentValueV2(
currentRecordFieldsComponentState,
);
@@ -11,7 +11,7 @@ import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableIt
import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { dropdownYPositionComponentState } from '@/ui/layout/dropdown/states/internal/dropdownYPositionComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { ViewType } from '@/views/types/ViewType';
import { useContext } from 'react';
@@ -60,7 +60,7 @@ export const ViewFieldsVisibleDropdownSection = () => {
const fieldMetadataItemLabelIdentifier =
getLabelIdentifierFieldMetadataItem(objectMetadataItem);
const visibleRecordFields = useRecoilComponentValue(
const visibleRecordFields = useRecoilComponentSelectorValueV2(
visibleRecordFieldsComponentSelector,
);
@@ -1,4 +1,5 @@
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { useEffect, useMemo, useState } from 'react';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlural';
@@ -6,7 +7,7 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { RecordIndexContextProvider } from '@/object-record/record-index/contexts/RecordIndexContext';
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { ViewBarFilterDropdown } from '@/views/components/ViewBarFilterDropdown';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
@@ -37,7 +38,7 @@ const meta: Meta<typeof ViewBarFilterDropdown> = {
)!;
const instanceId = companyObjectMetadataItem.id;
const setCurrentRecordFields = useSetRecoilComponentState(
const setCurrentRecordFields = useSetRecoilComponentStateV2(
currentRecordFieldsComponentState,
instanceId,
);
@@ -46,27 +47,40 @@ const meta: Meta<typeof ViewBarFilterDropdown> = {
const mockCoreView = mockedCoreViewsData[0];
setCoreViews([mockCoreView]);
const setCurrentViewId = useSetRecoilComponentState(
const setCurrentViewId = useSetRecoilComponentStateV2(
contextStoreCurrentViewIdComponentState,
MAIN_CONTEXT_STORE_INSTANCE_ID,
);
setCurrentViewId(mockCoreView.id);
const columns = companyObjectMetadataItem.fields.map(
(fieldMetadataItem, index) =>
({
id: fieldMetadataItem.id,
fieldMetadataItemId: fieldMetadataItem.id,
isVisible: true,
position: index,
size: 100,
}) satisfies RecordField,
const columns = useMemo(
() =>
companyObjectMetadataItem.fields.map(
(fieldMetadataItem, index) =>
({
id: fieldMetadataItem.id,
fieldMetadataItemId: fieldMetadataItem.id,
isVisible: true,
position: index,
size: 100,
}) satisfies RecordField,
),
[companyObjectMetadataItem.fields],
);
setCurrentRecordFields(columns);
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
setCoreViews([mockCoreView]);
setCurrentViewId(mockCoreView.id);
setCurrentRecordFields(columns);
setIsLoaded(true);
}, [
setCoreViews,
setCurrentViewId,
setCurrentRecordFields,
mockCoreView,
columns,
]);
const {
fieldDefinitionByFieldMetadataItemId,
@@ -78,6 +92,10 @@ const meta: Meta<typeof ViewBarFilterDropdown> = {
instanceId,
);
if (!isLoaded) {
return <></>;
}
return (
<RecordIndexContextProvider
value={{
@@ -2,11 +2,11 @@ import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-recor
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2';
import { IconX } from 'twenty-ui/display';
export const EditableFilterChipDropdownMenuHeader = () => {
const fieldMetadataItemUsedInDropdown = useRecoilComponentValue(
const fieldMetadataItemUsedInDropdown = useRecoilComponentSelectorValueV2(
fieldMetadataItemUsedInDropdownComponentSelector,
);
@@ -3,8 +3,11 @@ import { renderHook } from '@testing-library/react';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import {
jotaiStore,
resetJotaiStore,
} from '@/ui/utilities/state/jotai/jotaiStore';
import { useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups } from '@/views/hooks/useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups';
import { coreViewsState } from '@/views/states/coreViewState';
import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations';
@@ -35,6 +38,10 @@ describe('useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups', () => {
);
}
beforeEach(() => {
resetJotaiStore();
});
afterEach(() => {
jotaiStore.set(coreViewsState.atom, []);
});
@@ -79,8 +86,9 @@ describe('useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups', () => {
const { applyCurrentViewFilterGroupsToCurrentRecordFilterGroups } =
useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups();
const currentRecordFilterGroups = useRecoilComponentValue(
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
'recordIndexId',
);
return {
@@ -129,8 +137,9 @@ describe('useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups', () => {
const { applyCurrentViewFilterGroupsToCurrentRecordFilterGroups } =
useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups();
const currentRecordFilterGroups = useRecoilComponentValue(
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
'recordIndexId',
);
return {
@@ -144,8 +153,8 @@ describe('useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups', () => {
componentInstanceId: 'instanceId',
contextStoreCurrentObjectMetadataNameSingular:
mockObjectMetadataItemNameSingular,
onInitializeRecoilSnapshot: (snapshot) => {
snapshot.set(
onInitializeJotaiStore: (store) => {
store.set(
contextStoreCurrentViewIdComponentState.atomFamily({
instanceId: 'instanceId',
}),
@@ -173,8 +182,9 @@ describe('useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups', () => {
const { applyCurrentViewFilterGroupsToCurrentRecordFilterGroups } =
useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups();
const currentRecordFilterGroups = useRecoilComponentValue(
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
'recordIndexId',
);
return {
@@ -188,8 +198,8 @@ describe('useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups', () => {
componentInstanceId: 'instanceId',
contextStoreCurrentObjectMetadataNameSingular:
mockObjectMetadataItemNameSingular,
onInitializeRecoilSnapshot: (snapshot) => {
snapshot.set(
onInitializeJotaiStore: (store) => {
store.set(
contextStoreCurrentViewIdComponentState.atomFamily({
instanceId: 'instanceId',
}),
@@ -3,8 +3,11 @@ import { renderHook } from '@testing-library/react';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import {
jotaiStore,
resetJotaiStore,
} from '@/ui/utilities/state/jotai/jotaiStore';
import { coreViewsState } from '@/views/states/coreViewState';
import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations';
import { type View } from '@/views/types/View';
@@ -37,6 +40,10 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
);
}
beforeEach(() => {
resetJotaiStore();
});
afterEach(() => {
jotaiStore.set(coreViewsState.atom, []);
});
@@ -90,8 +97,9 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
const { applyCurrentViewFiltersToCurrentRecordFilters } =
useApplyCurrentViewFiltersToCurrentRecordFilters();
const currentFilters = useRecoilComponentValue(
const currentFilters = useRecoilComponentValueV2(
currentRecordFiltersComponentState,
'recordIndexId',
);
return {
@@ -138,8 +146,9 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
const { applyCurrentViewFiltersToCurrentRecordFilters } =
useApplyCurrentViewFiltersToCurrentRecordFilters();
const currentFilters = useRecoilComponentValue(
const currentFilters = useRecoilComponentValueV2(
currentRecordFiltersComponentState,
'recordIndexId',
);
return {
@@ -153,8 +162,8 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
componentInstanceId: 'instanceId',
contextStoreCurrentObjectMetadataNameSingular:
mockObjectMetadataItemNameSingular,
onInitializeRecoilSnapshot: (snapshot) => {
snapshot.set(
onInitializeJotaiStore: (store) => {
store.set(
contextStoreCurrentViewIdComponentState.atomFamily({
instanceId: 'instanceId',
}),
@@ -180,8 +189,9 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
const { applyCurrentViewFiltersToCurrentRecordFilters } =
useApplyCurrentViewFiltersToCurrentRecordFilters();
const currentFilters = useRecoilComponentValue(
const currentFilters = useRecoilComponentValueV2(
currentRecordFiltersComponentState,
'recordIndexId',
);
return {
@@ -195,8 +205,8 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
componentInstanceId: 'instanceId',
contextStoreCurrentObjectMetadataNameSingular:
mockObjectMetadataItemNameSingular,
onInitializeRecoilSnapshot: (snapshot) => {
snapshot.set(
onInitializeJotaiStore: (store) => {
store.set(
contextStoreCurrentViewIdComponentState.atomFamily({
instanceId: 'instanceId',
}),
@@ -2,7 +2,7 @@ import { act, renderHook } from '@testing-library/react';
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
@@ -81,8 +81,9 @@ describe('useApplyCurrentViewSortsToCurrentRecordSorts', () => {
const { applyCurrentViewSortsToCurrentRecordSorts } =
useApplyCurrentViewSortsToCurrentRecordSorts();
const currentSorts = useRecoilComponentValue(
const currentSorts = useRecoilComponentValueV2(
currentRecordSortsComponentState,
'recordIndexId',
);
return {
@@ -122,8 +123,9 @@ describe('useApplyCurrentViewSortsToCurrentRecordSorts', () => {
const { applyCurrentViewSortsToCurrentRecordSorts } =
useApplyCurrentViewSortsToCurrentRecordSorts();
const currentSorts = useRecoilComponentValue(
const currentSorts = useRecoilComponentValueV2(
currentRecordSortsComponentState,
'recordIndexId',
);
return {
@@ -137,8 +139,8 @@ describe('useApplyCurrentViewSortsToCurrentRecordSorts', () => {
componentInstanceId: 'instanceId',
contextStoreCurrentObjectMetadataNameSingular:
mockObjectMetadataItemNameSingular,
onInitializeRecoilSnapshot: (snapshot) => {
snapshot.set(
onInitializeJotaiStore: (store) => {
store.set(
contextStoreCurrentViewIdComponentState.atomFamily({
instanceId: 'instanceId',
}),
@@ -169,8 +171,9 @@ describe('useApplyCurrentViewSortsToCurrentRecordSorts', () => {
const { applyCurrentViewSortsToCurrentRecordSorts } =
useApplyCurrentViewSortsToCurrentRecordSorts();
const currentSorts = useRecoilComponentValue(
const currentSorts = useRecoilComponentValueV2(
currentRecordSortsComponentState,
'recordIndexId',
);
return {
@@ -184,8 +187,8 @@ describe('useApplyCurrentViewSortsToCurrentRecordSorts', () => {
componentInstanceId: 'instanceId',
contextStoreCurrentObjectMetadataNameSingular:
mockObjectMetadataItemNameSingular,
onInitializeRecoilSnapshot: (snapshot) => {
snapshot.set(
onInitializeJotaiStore: (store) => {
store.set(
contextStoreCurrentViewIdComponentState.atomFamily({
instanceId: 'instanceId',
}),
@@ -2,7 +2,7 @@ import { act, renderHook } from '@testing-library/react';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { type ViewFilter } from '@/views/types/ViewFilter';
import { ViewFilterOperand } from 'twenty-shared/types';
import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils';
@@ -42,7 +42,7 @@ describe('useApplyViewFiltersToCurrentRecordFilters', () => {
const { applyViewFiltersToCurrentRecordFilters } =
useApplyViewFiltersToCurrentRecordFilters();
const currentFilters = useRecoilComponentValue(
const currentFilters = useRecoilComponentValueV2(
currentRecordFiltersComponentState,
);
@@ -83,7 +83,7 @@ describe('useApplyViewFiltersToCurrentRecordFilters', () => {
const { applyViewFiltersToCurrentRecordFilters } =
useApplyViewFiltersToCurrentRecordFilters();
const currentFilters = useRecoilComponentValue(
const currentFilters = useRecoilComponentValueV2(
currentRecordFiltersComponentState,
);
@@ -1,7 +1,7 @@
import { act, renderHook } from '@testing-library/react';
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
@@ -45,7 +45,7 @@ describe('useApplyViewSortsToCurrentRecordSorts', () => {
const { applyViewSortsToCurrentRecordSorts } =
useApplyViewSortsToCurrentRecordSorts();
const currentSorts = useRecoilComponentValue(
const currentSorts = useRecoilComponentValueV2(
currentRecordSortsComponentState,
);
@@ -80,7 +80,7 @@ describe('useApplyViewSortsToCurrentRecordSorts', () => {
const { applyViewSortsToCurrentRecordSorts } =
useApplyViewSortsToCurrentRecordSorts();
const currentSorts = useRecoilComponentValue(
const currentSorts = useRecoilComponentValueV2(
currentRecordSortsComponentState,
);
@@ -8,7 +8,10 @@ import { selectedOperandInDropdownComponentState } from '@/object-record/object-
import { useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown } from '@/views/hooks/useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import {
jotaiStore,
resetJotaiStore,
} from '@/ui/utilities/state/jotai/jotaiStore';
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
@@ -17,8 +20,9 @@ import { currentRecordFiltersComponentState } from '@/object-record/record-filte
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { ViewBarFilterDropdownIds } from '@/views/constants/ViewBarFilterDropdownIds';
import { getFilterTypeFromFieldType } from 'twenty-shared/utils';
import { getMockPersonObjectMetadataItem } from '~/testing/mock-data/people';
@@ -66,6 +70,7 @@ const wrapper = ({ children }: { children: React.ReactNode }) => {
describe('useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown', () => {
beforeEach(() => {
resetJotaiStore();
jest.clearAllMocks();
});
@@ -75,13 +80,14 @@ describe('useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown', () =
const { initializeFilterOnFieldMetataItemFromViewBarFilterDropdown } =
useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown();
const fieldMetadataItemUsedInDropdown = useRecoilComponentValue(
fieldMetadataItemUsedInDropdownComponentSelector,
);
const objectFilterDropdownFilterIsSelected = useRecoilComponentValue(
const fieldMetadataItemUsedInDropdown =
useRecoilComponentSelectorValueV2(
fieldMetadataItemUsedInDropdownComponentSelector,
);
const objectFilterDropdownFilterIsSelected = useRecoilComponentValueV2(
objectFilterDropdownFilterIsSelectedComponentState,
);
const selectedOperandInDropdown = useRecoilComponentValue(
const selectedOperandInDropdown = useRecoilComponentValueV2(
selectedOperandInDropdownComponentState,
);
@@ -127,13 +133,14 @@ describe('useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown', () =
const { initializeFilterOnFieldMetataItemFromViewBarFilterDropdown } =
useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown();
const fieldMetadataItemUsedInDropdown = useRecoilComponentValue(
fieldMetadataItemUsedInDropdownComponentSelector,
);
const objectFilterDropdownFilterIsSelected = useRecoilComponentValue(
const fieldMetadataItemUsedInDropdown =
useRecoilComponentSelectorValueV2(
fieldMetadataItemUsedInDropdownComponentSelector,
);
const objectFilterDropdownFilterIsSelected = useRecoilComponentValueV2(
objectFilterDropdownFilterIsSelectedComponentState,
);
const selectedOperandInDropdown = useRecoilComponentValue(
const selectedOperandInDropdown = useRecoilComponentValueV2(
selectedOperandInDropdownComponentState,
);
@@ -188,26 +195,30 @@ describe('useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown', () =
const { initializeFilterOnFieldMetataItemFromViewBarFilterDropdown } =
useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown();
const fieldMetadataItemUsedInDropdown = useRecoilComponentValue(
fieldMetadataItemUsedInDropdownComponentSelector,
);
const objectFilterDropdownFilterIsSelected = useRecoilComponentValue(
const fieldMetadataItemUsedInDropdown =
useRecoilComponentSelectorValueV2(
fieldMetadataItemUsedInDropdownComponentSelector,
);
const objectFilterDropdownFilterIsSelected = useRecoilComponentValueV2(
objectFilterDropdownFilterIsSelectedComponentState,
);
const selectedOperandInDropdown = useRecoilComponentValue(
const selectedOperandInDropdown = useRecoilComponentValueV2(
selectedOperandInDropdownComponentState,
);
const objectFilterDropdownCurrentRecordFilter = useRecoilComponentValue(
objectFilterDropdownCurrentRecordFilterComponentState,
const objectFilterDropdownCurrentRecordFilter =
useRecoilComponentValueV2(
objectFilterDropdownCurrentRecordFilterComponentState,
);
const setCurrentRecordFilters = useSetRecoilComponentStateV2(
currentRecordFiltersComponentState,
'test',
);
const setCurrentRecordFilters = useSetRecoilComponentState(
currentRecordFiltersComponentState,
);
const currentRecordFilters = useRecoilComponentValue(
const currentRecordFilters = useRecoilComponentValueV2(
currentRecordFiltersComponentState,
'test',
);
return {
@@ -268,26 +279,30 @@ describe('useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown', () =
const { initializeFilterOnFieldMetataItemFromViewBarFilterDropdown } =
useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown();
const fieldMetadataItemUsedInDropdown = useRecoilComponentValue(
fieldMetadataItemUsedInDropdownComponentSelector,
);
const objectFilterDropdownFilterIsSelected = useRecoilComponentValue(
const fieldMetadataItemUsedInDropdown =
useRecoilComponentSelectorValueV2(
fieldMetadataItemUsedInDropdownComponentSelector,
);
const objectFilterDropdownFilterIsSelected = useRecoilComponentValueV2(
objectFilterDropdownFilterIsSelectedComponentState,
);
const selectedOperandInDropdown = useRecoilComponentValue(
const selectedOperandInDropdown = useRecoilComponentValueV2(
selectedOperandInDropdownComponentState,
);
const objectFilterDropdownCurrentRecordFilter = useRecoilComponentValue(
objectFilterDropdownCurrentRecordFilterComponentState,
const objectFilterDropdownCurrentRecordFilter =
useRecoilComponentValueV2(
objectFilterDropdownCurrentRecordFilterComponentState,
);
const setCurrentRecordFilters = useSetRecoilComponentStateV2(
currentRecordFiltersComponentState,
'test',
);
const setCurrentRecordFilters = useSetRecoilComponentState(
currentRecordFiltersComponentState,
);
const currentRecordFilters = useRecoilComponentValue(
const currentRecordFilters = useRecoilComponentValueV2(
currentRecordFiltersComponentState,
'test',
);
return {
@@ -5,7 +5,7 @@ import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useGetViewGroupsFilters } from '@/views/hooks/useGetViewGroupsFilters';
import {
computeRecordGqlOperationFilter,
@@ -15,11 +15,11 @@ import {
export const useGetRecordIndexTotalCount = () => {
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
const currentRecordFilterGroups = useRecoilComponentValue(
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
);
const currentRecordFilters = useRecoilComponentValue(
const currentRecordFilters = useRecoilComponentValueV2(
currentRecordFiltersComponentState,
);
@@ -34,7 +34,7 @@ export const useGetRecordIndexTotalCount = () => {
fields: objectMetadataItem.fields,
});
const anyFieldFilterValue = useRecoilComponentValue(
const anyFieldFilterValue = useRecoilComponentValueV2(
anyFieldFilterValueComponentState,
);
@@ -1,18 +1,18 @@
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
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 { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const useApplyCurrentViewAnyFieldFilterToAnyFieldFilter = () => {
const currentViewId = useRecoilComponentValue(
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
);
const setAnyFieldFilterValue = useSetRecoilComponentState(
const setAnyFieldFilterValue = useSetRecoilComponentStateV2(
anyFieldFilterValueComponentState,
);
@@ -1,64 +1,61 @@
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
import { mapViewFilterGroupsToRecordFilterGroups } from '@/views/utils/mapViewFilterGroupsToRecordFilterGroups';
import { useStore } from 'jotai';
import { useRecoilCallback } from 'recoil';
import { useCallback } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
export const useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups =
() => {
const currentViewId = useRecoilComponentValue(
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
);
const setCurrentRecordFilterGroups = useSetRecoilComponentState(
const setCurrentRecordFilterGroups = useSetRecoilComponentStateV2(
currentRecordFilterGroupsComponentState,
);
const currentRecordFilterGroupsCallbackState =
useRecoilComponentCallbackState(currentRecordFilterGroupsComponentState);
const currentRecordFilterGroupsAtom =
useRecoilComponentStateCallbackStateV2(
currentRecordFilterGroupsComponentState,
);
const store = useStore();
const applyCurrentViewFilterGroupsToCurrentRecordFilterGroups =
useRecoilCallback(
({ snapshot }) =>
() => {
const currentView = store.get(
coreViewFromViewIdFamilySelector.selectorFamily({
viewId: currentViewId ?? '',
}),
);
useCallback(() => {
const currentView = store.get(
coreViewFromViewIdFamilySelector.selectorFamily({
viewId: currentViewId ?? '',
}),
);
if (isDefined(currentView)) {
const currentRecordFilterGroups = snapshot
.getLoadable(currentRecordFilterGroupsCallbackState)
.getValue();
if (isDefined(currentView)) {
const currentRecordFilterGroups = store.get(
currentRecordFilterGroupsAtom,
);
const newRecordFilterGroups =
mapViewFilterGroupsToRecordFilterGroups(
currentView.viewFilterGroups ?? [],
);
const newRecordFilterGroups = mapViewFilterGroupsToRecordFilterGroups(
currentView.viewFilterGroups ?? [],
);
if (
!isDeeplyEqual(currentRecordFilterGroups, newRecordFilterGroups)
) {
setCurrentRecordFilterGroups(newRecordFilterGroups);
}
}
},
[
currentViewId,
setCurrentRecordFilterGroups,
currentRecordFilterGroupsCallbackState,
store,
],
);
if (
!isDeeplyEqual(currentRecordFilterGroups, newRecordFilterGroups)
) {
setCurrentRecordFilterGroups(newRecordFilterGroups);
}
}
}, [
currentViewId,
setCurrentRecordFilterGroups,
currentRecordFilterGroupsAtom,
store,
]);
return {
applyCurrentViewFilterGroupsToCurrentRecordFilterGroups,
@@ -1,7 +1,7 @@
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
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 { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
import { useStore } from 'jotai';
import { useCallback } from 'react';
@@ -9,11 +9,11 @@ import { isDefined } from 'twenty-shared/utils';
import { useMapViewFiltersToFilters } from './useMapViewFiltersToFilters';
export const useApplyCurrentViewFiltersToCurrentRecordFilters = () => {
const currentViewId = useRecoilComponentValue(
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
);
const setCurrentRecordFilters = useSetRecoilComponentState(
const setCurrentRecordFilters = useSetRecoilComponentStateV2(
currentRecordFiltersComponentState,
);
@@ -1,13 +1,13 @@
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
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 { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
import { isDefined } from 'twenty-shared/utils';
export const useApplyCurrentViewSortsToCurrentRecordSorts = () => {
const currentViewId = useRecoilComponentValue(
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
);
@@ -16,7 +16,7 @@ export const useApplyCurrentViewSortsToCurrentRecordSorts = () => {
{ viewId: currentViewId ?? '' },
);
const setCurrentRecordSorts = useSetRecoilComponentState(
const setCurrentRecordSorts = useSetRecoilComponentStateV2(
currentRecordSortsComponentState,
);
@@ -1,10 +1,10 @@
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { type ViewFilter } from '@/views/types/ViewFilter';
import { useMapViewFiltersToFilters } from './useMapViewFiltersToFilters';
export const useApplyViewFiltersToCurrentRecordFilters = () => {
const setCurrentRecordFilters = useSetRecoilComponentState(
const setCurrentRecordFilters = useSetRecoilComponentStateV2(
currentRecordFiltersComponentState,
);
@@ -1,9 +1,9 @@
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { type CoreViewSortEssential } from '@/views/types/CoreViewSortEssential';
export const useApplyViewSortsToCurrentRecordSorts = () => {
const setCurrentRecordSorts = useSetRecoilComponentState(
const setCurrentRecordSorts = useSetRecoilComponentStateV2(
currentRecordSortsComponentState,
);
@@ -1,5 +1,5 @@
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { getViewFilterGroupsToCreate } from '@/views/utils/getViewFilterGroupsToCreate';
import { getViewFilterGroupsToDelete } from '@/views/utils/getViewFilterGroupsToDelete';
@@ -10,7 +10,7 @@ import { isDefined } from 'twenty-shared/utils';
export const useAreViewFilterGroupsDifferentFromRecordFilterGroups = () => {
const { currentView } = useGetCurrentViewOnly();
const currentRecordFilterGroups = useRecoilComponentValue(
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
);
@@ -1,5 +1,5 @@
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { getViewFiltersToCreate } from '@/views/utils/getViewFiltersToCreate';
import { getViewFiltersToDelete } from '@/views/utils/getViewFiltersToDelete';
@@ -9,7 +9,7 @@ import { useMemo } from 'react';
export const useAreViewFiltersDifferentFromRecordFilters = () => {
const { currentView } = useGetCurrentViewOnly();
const currentRecordFilters = useRecoilComponentValue(
const currentRecordFilters = useRecoilComponentValueV2(
currentRecordFiltersComponentState,
);
@@ -1,5 +1,5 @@
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { getViewSortsToCreate } from '@/views/utils/getViewSortsToCreate';
import { getViewSortsToDelete } from '@/views/utils/getViewSortsToDelete';
@@ -10,7 +10,7 @@ import { isDefined } from 'twenty-shared/utils';
export const useAreViewSortsDifferentFromRecordSorts = () => {
const { currentView } = useGetCurrentViewOnly();
const currentRecordSorts = useRecoilComponentValue(
const currentRecordSorts = useRecoilComponentValueV2(
currentRecordSortsComponentState,
);
@@ -4,9 +4,8 @@ import { anyFieldFilterValueComponentState } from '@/object-record/record-filter
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { usePerformViewAPIPersist } from '@/views/hooks/internal/usePerformViewAPIPersist';
import { usePerformViewFieldAPIPersist } from '@/views/hooks/internal/usePerformViewFieldAPIPersist';
import { usePerformViewFilterAPIPersist } from '@/views/hooks/internal/usePerformViewFilterAPIPersist';
@@ -23,7 +22,7 @@ import { mapRecordFilterGroupToViewFilterGroup } from '@/views/utils/mapRecordFi
import { mapRecordFilterToViewFilter } from '@/views/utils/mapRecordFilterToViewFilter';
import { mapRecordSortToViewSort } from '@/views/utils/mapRecordSortToViewSort';
import { useStore } from 'jotai';
import { useRecoilCallback } from 'recoil';
import { useCallback } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { v4 } from 'uuid';
import { ViewCalendarLayout } from '~/generated-metadata/graphql';
@@ -32,13 +31,16 @@ import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
const { performViewAPICreate } = usePerformViewAPIPersist();
const currentViewIdCallbackState = useRecoilComponentCallbackState(
const { objectMetadataItem, recordIndexId } = useRecordIndexContextOrThrow();
const currentViewIdAtom = useRecoilComponentStateCallbackStateV2(
contextStoreCurrentViewIdComponentState,
viewBarComponentId,
);
const anyFieldFilterValue = useRecoilComponentValue(
const anyFieldFilterValue = useRecoilComponentValueV2(
anyFieldFilterValueComponentState,
recordIndexId,
);
const { performViewFieldAPICreate } = usePerformViewFieldAPIPersist();
@@ -50,196 +52,193 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
const { performViewFilterGroupAPICreate } =
usePerformViewFilterGroupAPIPersist();
const { objectMetadataItem } = useRecordIndexContextOrThrow();
const store = useStore();
const { refreshCoreViewsByObjectMetadataId } =
useRefreshCoreViewsByObjectMetadataId();
const currentRecordFilterGroups = useRecoilComponentValue(
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
recordIndexId,
);
const currentRecordSorts = useRecoilComponentValue(
const currentRecordSorts = useRecoilComponentValueV2(
currentRecordSortsComponentState,
recordIndexId,
);
const currentRecordFilters = useRecoilComponentValue(
const currentRecordFilters = useRecoilComponentValueV2(
currentRecordFiltersComponentState,
recordIndexId,
);
const createViewFromCurrentView = useRecoilCallback(
({ snapshot }) =>
async (
const createViewFromCurrentView = useCallback(
async (
{
id,
name,
icon,
mainGroupByFieldMetadataId,
calendarFieldMetadataId,
type,
visibility,
}: Partial<
Pick<
GraphQLView,
| 'id'
| 'name'
| 'icon'
| 'mainGroupByFieldMetadataId'
| 'calendarFieldMetadataId'
| 'type'
| 'visibility'
>
>,
shouldCopyFiltersAndSortsAndAggregate?: boolean,
): Promise<string | undefined> => {
const currentViewId = store.get(currentViewIdAtom);
if (!isDefined(currentViewId)) {
return undefined;
}
const sourceView = store.get(
coreViewFromViewIdFamilySelector.selectorFamily({
viewId: currentViewId,
}),
);
if (!isDefined(sourceView)) {
return undefined;
}
const viewType = type ?? sourceView.type;
const result = await performViewAPICreate(
{
id,
name,
icon,
mainGroupByFieldMetadataId,
calendarFieldMetadataId,
type,
visibility,
}: Partial<
Pick<
GraphQLView,
| 'id'
| 'name'
| 'icon'
| 'mainGroupByFieldMetadataId'
| 'calendarFieldMetadataId'
| 'type'
| 'visibility'
>
>,
shouldCopyFiltersAndSortsAndAggregate?: boolean,
): Promise<string | undefined> => {
const currentViewId = getSnapshotValue(
snapshot,
currentViewIdCallbackState,
input: {
id: id ?? v4(),
name: name ?? sourceView.name,
icon: icon ?? sourceView.icon,
key: null,
kanbanAggregateOperation: shouldCopyFiltersAndSortsAndAggregate
? sourceView.kanbanAggregateOperation
: undefined,
kanbanAggregateOperationFieldMetadataId:
shouldCopyFiltersAndSortsAndAggregate
? sourceView.kanbanAggregateOperationFieldMetadataId
: undefined,
mainGroupByFieldMetadataId: shouldCopyFiltersAndSortsAndAggregate
? sourceView.mainGroupByFieldMetadataId
: mainGroupByFieldMetadataId,
type: convertViewTypeToCore(viewType),
objectMetadataId: sourceView.objectMetadataId,
openRecordIn: convertViewOpenRecordInToCore(
sourceView.openRecordIn,
),
anyFieldFilterValue: anyFieldFilterValue,
calendarLayout:
viewType === ViewType.Calendar
? ViewCalendarLayout.MONTH
: undefined,
calendarFieldMetadataId:
viewType === ViewType.Calendar
? calendarFieldMetadataId
: undefined,
visibility,
},
},
objectMetadataItem.id,
);
if (result.status === 'failed') {
return undefined;
}
const newViewId = result.response.data?.createCoreView.id;
if (isUndefinedOrNull(newViewId)) {
throw new Error('Failed to create view');
}
const fieldResult = await performViewFieldAPICreate({
inputs: sourceView.viewFields.map(
({ __typename, id: _id, ...viewField }) => ({
...viewField,
id: v4(),
viewId: newViewId,
}),
),
});
if (fieldResult.status === 'failed') {
return undefined;
}
if (shouldCopyFiltersAndSortsAndAggregate === true) {
const viewFilterGroupsToCopy = currentRecordFilterGroups.map(
(recordFilterGroup) =>
mapRecordFilterGroupToViewFilterGroup({
recordFilterGroup,
view: { id: newViewId },
}),
);
if (!isDefined(currentViewId)) {
return undefined;
}
const viewFiltersToCopy = currentRecordFilters.map(
mapRecordFilterToViewFilter,
);
const sourceView = store.get(
coreViewFromViewIdFamilySelector.selectorFamily({
viewId: currentViewId,
const {
duplicatedViewFilterGroups: viewFilterGroupsToCreate,
duplicatedViewFilters: viewFiltersToCreate,
} = duplicateViewFiltersAndViewFilterGroups({
viewFilterGroupsToDuplicate: viewFilterGroupsToCopy,
viewFiltersToDuplicate: viewFiltersToCopy,
});
const viewSortsToCreate = currentRecordSorts
.map((recordSort) => mapRecordSortToViewSort(recordSort, newViewId))
.map((viewSort) => ({
...viewSort,
id: v4(),
}));
await performViewFilterGroupAPICreate(viewFilterGroupsToCreate, {
id: newViewId,
});
const createViewFilterInputs = viewFiltersToCreate.map(
(viewFilter) => ({
input: {
id: viewFilter.id,
fieldMetadataId: viewFilter.fieldMetadataId,
viewId: newViewId,
value: viewFilter.value,
operand: viewFilter.operand,
viewFilterGroupId: viewFilter.viewFilterGroupId,
positionInViewFilterGroup: viewFilter.positionInViewFilterGroup,
subFieldName: viewFilter.subFieldName ?? null,
},
}),
);
if (!isDefined(sourceView)) {
return undefined;
}
const viewType = type ?? sourceView.type;
const result = await performViewAPICreate(
{
input: {
id: id ?? v4(),
name: name ?? sourceView.name,
icon: icon ?? sourceView.icon,
key: null,
kanbanAggregateOperation: shouldCopyFiltersAndSortsAndAggregate
? sourceView.kanbanAggregateOperation
: undefined,
kanbanAggregateOperationFieldMetadataId:
shouldCopyFiltersAndSortsAndAggregate
? sourceView.kanbanAggregateOperationFieldMetadataId
: undefined,
mainGroupByFieldMetadataId: shouldCopyFiltersAndSortsAndAggregate
? sourceView.mainGroupByFieldMetadataId
: mainGroupByFieldMetadataId,
type: convertViewTypeToCore(viewType),
objectMetadataId: sourceView.objectMetadataId,
openRecordIn: convertViewOpenRecordInToCore(
sourceView.openRecordIn,
),
anyFieldFilterValue: anyFieldFilterValue,
calendarLayout:
viewType === ViewType.Calendar
? ViewCalendarLayout.MONTH
: undefined,
calendarFieldMetadataId:
viewType === ViewType.Calendar
? calendarFieldMetadataId
: undefined,
visibility,
},
},
objectMetadataItem.id,
const filterResult = await performViewFilterAPICreate(
createViewFilterInputs,
);
if (result.status === 'failed') {
if (filterResult.status === 'failed') {
return undefined;
}
const newViewId = result.response.data?.createCoreView.id;
await performViewSortAPICreate(viewSortsToCreate, { id: newViewId });
}
if (isUndefinedOrNull(newViewId)) {
throw new Error('Failed to create view');
}
await refreshCoreViewsByObjectMetadataId(objectMetadataItem.id);
const fieldResult = await performViewFieldAPICreate({
inputs: sourceView.viewFields.map(
({ __typename, id: _id, ...viewField }) => ({
...viewField,
id: v4(),
viewId: newViewId,
}),
),
});
if (fieldResult.status === 'failed') {
return undefined;
}
if (shouldCopyFiltersAndSortsAndAggregate === true) {
const viewFilterGroupsToCopy = currentRecordFilterGroups.map(
(recordFilterGroup) =>
mapRecordFilterGroupToViewFilterGroup({
recordFilterGroup,
view: { id: newViewId },
}),
);
const viewFiltersToCopy = currentRecordFilters.map(
mapRecordFilterToViewFilter,
);
const {
duplicatedViewFilterGroups: viewFilterGroupsToCreate,
duplicatedViewFilters: viewFiltersToCreate,
} = duplicateViewFiltersAndViewFilterGroups({
viewFilterGroupsToDuplicate: viewFilterGroupsToCopy,
viewFiltersToDuplicate: viewFiltersToCopy,
});
const viewSortsToCreate = currentRecordSorts
.map((recordSort) => mapRecordSortToViewSort(recordSort, newViewId))
.map((viewSort) => ({
...viewSort,
id: v4(),
}));
await performViewFilterGroupAPICreate(viewFilterGroupsToCreate, {
id: newViewId,
});
const createViewFilterInputs = viewFiltersToCreate.map(
(viewFilter) => ({
input: {
id: viewFilter.id,
fieldMetadataId: viewFilter.fieldMetadataId,
viewId: newViewId,
value: viewFilter.value,
operand: viewFilter.operand,
viewFilterGroupId: viewFilter.viewFilterGroupId,
positionInViewFilterGroup: viewFilter.positionInViewFilterGroup,
subFieldName: viewFilter.subFieldName ?? null,
},
}),
);
const filterResult = await performViewFilterAPICreate(
createViewFilterInputs,
);
if (filterResult.status === 'failed') {
return undefined;
}
await performViewSortAPICreate(viewSortsToCreate, { id: newViewId });
}
await refreshCoreViewsByObjectMetadataId(objectMetadataItem.id);
return newViewId;
},
return newViewId;
},
[
currentViewIdCallbackState,
currentViewIdAtom,
performViewAPICreate,
anyFieldFilterValue,
objectMetadataItem,
@@ -1,10 +1,10 @@
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
export const useGetCurrentViewOnly = () => {
const currentViewId = useRecoilComponentValue(
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
);
@@ -1,14 +1,14 @@
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { availableFieldDefinitionsComponentState } from '@/views/states/availableFieldDefinitionsComponentState';
import { viewObjectMetadataIdComponentState } from '@/views/states/viewObjectMetadataIdComponentState';
export const useInitViewBar = (viewBarInstanceId?: string) => {
const setAvailableFieldDefinitions = useSetRecoilComponentState(
const setAvailableFieldDefinitions = useSetRecoilComponentStateV2(
availableFieldDefinitionsComponentState,
viewBarInstanceId,
);
const setViewObjectMetadataId = useSetRecoilComponentState(
const setViewObjectMetadataId = useSetRecoilComponentStateV2(
viewObjectMetadataIdComponentState,
viewBarInstanceId,
);
@@ -12,34 +12,38 @@ import { findDuplicateRecordFilterInNonAdvancedRecordFilters } from '@/object-re
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { ViewBarFilterDropdownIds } from '@/views/constants/ViewBarFilterDropdownIds';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils';
import { v4 } from 'uuid';
export const useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown =
() => {
const selectedOperandInDropdownCallbackState =
useRecoilComponentCallbackState(selectedOperandInDropdownComponentState);
useRecoilComponentStateCallbackStateV2(
selectedOperandInDropdownComponentState,
);
const currentRecordFiltersCallbackState = useRecoilComponentCallbackState(
currentRecordFiltersComponentState,
);
const currentRecordFiltersCallbackState =
useRecoilComponentStateCallbackStateV2(
currentRecordFiltersComponentState,
);
const objectFilterDropdownCurrentRecordFilterCallbackState =
useRecoilComponentCallbackState(
useRecoilComponentStateCallbackStateV2(
objectFilterDropdownCurrentRecordFilterComponentState,
);
const fieldMetadataItemUsedInDropdownCallbackState =
useRecoilComponentCallbackState(
useRecoilComponentStateCallbackStateV2(
fieldMetadataItemIdUsedInDropdownComponentState,
);
const objectFilterDropdownFilterIsSelectedCallbackState =
useRecoilComponentCallbackState(
useRecoilComponentStateCallbackStateV2(
objectFilterDropdownFilterIsSelectedComponentState,
);
@@ -49,93 +53,91 @@ export const useInitializeFilterOnFieldMetadataItemFromViewBarFilterDropdown =
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
const { getInitialFilterValue } = useGetInitialFilterValue();
const store = useStore();
const initializeFilterOnFieldMetataItemFromViewBarFilterDropdown =
useRecoilCallback(
({ set, snapshot }) =>
(fieldMetadataItem: FieldMetadataItem) => {
set(
fieldMetadataItemUsedInDropdownCallbackState,
fieldMetadataItem.id,
);
useCallback(
(fieldMetadataItem: FieldMetadataItem) => {
store.set(
fieldMetadataItemUsedInDropdownCallbackState,
fieldMetadataItem.id,
);
const currentRecordFilters = snapshot
.getLoadable(currentRecordFiltersCallbackState)
.getValue();
const currentRecordFilters = store.get(
currentRecordFiltersCallbackState,
);
const filterType = getFilterTypeFromFieldType(
fieldMetadataItem.type,
);
const filterType = getFilterTypeFromFieldType(fieldMetadataItem.type);
if (filterType === 'RELATION' || filterType === 'SELECT') {
pushFocusItemToFocusStack({
focusId: ViewBarFilterDropdownIds.MAIN,
component: {
type: FocusComponentType.DROPDOWN,
instanceId: fieldMetadataItem.id,
},
globalHotkeysConfig: {
enableGlobalHotkeysConflictingWithKeyboard: false,
},
});
}
if (filterType === 'RELATION' || filterType === 'SELECT') {
pushFocusItemToFocusStack({
focusId: ViewBarFilterDropdownIds.MAIN,
component: {
type: FocusComponentType.DROPDOWN,
instanceId: fieldMetadataItem.id,
},
globalHotkeysConfig: {
enableGlobalHotkeysConflictingWithKeyboard: false,
},
});
}
set(objectFilterDropdownFilterIsSelectedCallbackState, true);
store.set(objectFilterDropdownFilterIsSelectedCallbackState, true);
const defaultOperand = getRecordFilterOperands({
filterType,
})[0];
const defaultOperand = getRecordFilterOperands({
filterType,
})[0];
const duplicateFilterInCurrentRecordFilters =
findDuplicateRecordFilterInNonAdvancedRecordFilters({
recordFilters: currentRecordFilters,
fieldMetadataItemId: fieldMetadataItem.id,
});
const duplicateFilterInCurrentRecordFilters =
findDuplicateRecordFilterInNonAdvancedRecordFilters({
recordFilters: currentRecordFilters,
fieldMetadataItemId: fieldMetadataItem.id,
});
const filterIsAlreadyInCurrentRecordFilters = isDefined(
const filterIsAlreadyInCurrentRecordFilters = isDefined(
duplicateFilterInCurrentRecordFilters,
);
if (filterIsAlreadyInCurrentRecordFilters) {
store.set(
objectFilterDropdownCurrentRecordFilterCallbackState,
duplicateFilterInCurrentRecordFilters,
);
if (filterIsAlreadyInCurrentRecordFilters) {
set(
store.set(
selectedOperandInDropdownCallbackState,
duplicateFilterInCurrentRecordFilters.operand,
);
} else {
store.set(selectedOperandInDropdownCallbackState, defaultOperand);
if (filterType === 'DATE' || filterType === 'DATE_TIME') {
const { displayValue, value } = getInitialFilterValue(
filterType,
defaultOperand,
);
const initialDateRecordFilter: RecordFilter = {
id: v4(),
fieldMetadataId: fieldMetadataItem.id,
operand: defaultOperand,
displayValue,
label: fieldMetadataItem.label,
type: filterType,
value,
};
upsertObjectFilterDropdownCurrentFilter(initialDateRecordFilter);
store.set(
objectFilterDropdownCurrentRecordFilterCallbackState,
duplicateFilterInCurrentRecordFilters,
initialDateRecordFilter,
);
set(
selectedOperandInDropdownCallbackState,
duplicateFilterInCurrentRecordFilters.operand,
);
} else {
set(selectedOperandInDropdownCallbackState, defaultOperand);
if (filterType === 'DATE' || filterType === 'DATE_TIME') {
const { displayValue, value } = getInitialFilterValue(
filterType,
defaultOperand,
);
const initialDateRecordFilter: RecordFilter = {
id: v4(),
fieldMetadataId: fieldMetadataItem.id,
operand: defaultOperand,
displayValue,
label: fieldMetadataItem.label,
type: filterType,
value,
};
upsertObjectFilterDropdownCurrentFilter(
initialDateRecordFilter,
);
set(
objectFilterDropdownCurrentRecordFilterCallbackState,
initialDateRecordFilter,
);
}
}
},
}
},
[
store,
fieldMetadataItemUsedInDropdownCallbackState,
currentRecordFiltersCallbackState,
objectFilterDropdownFilterIsSelectedCallbackState,
@@ -1,12 +1,12 @@
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { isNonEmptyString } from '@sniptt/guards';
import { compareNonEmptyStrings } from '~/utils/compareNonEmptyStrings';
export const useIsViewAnyFieldFilterDifferentFromCurrentAnyFieldFilter = () => {
const { currentView } = useGetCurrentViewOnly();
const anyFieldFilterValue = useRecoilComponentValue(
const anyFieldFilterValue = useRecoilComponentValueV2(
anyFieldFilterValueComponentState,
);
@@ -2,24 +2,24 @@ import { objectFilterDropdownAnyFieldSearchIsSelectedComponentState } from '@/ob
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
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 { t } from '@lingui/core/macro';
import { isNonEmptyString } from '@sniptt/guards';
export const useOpenAnyFieldSearchFilterFromViewBar = () => {
const setAnyFieldFilterValue = useSetRecoilComponentState(
const setAnyFieldFilterValue = useSetRecoilComponentStateV2(
anyFieldFilterValueComponentState,
);
const { objectMetadataItem } = useRecordIndexContextOrThrow();
const setObjectFilterDropdownAnyFieldSearchIsSelectedComponentState =
useSetRecoilComponentState(
useSetRecoilComponentStateV2(
objectFilterDropdownAnyFieldSearchIsSelectedComponentState,
);
const objectFilterDropdownSearchInput = useRecoilComponentValue(
const objectFilterDropdownSearchInput = useRecoilComponentValueV2(
objectFilterDropdownSearchInputComponentState,
);
@@ -1,5 +1,5 @@
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { type View } from '@/views/types/View';
import { VIEW_PICKER_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerDropdownId';
import { useViewPickerMode } from '@/views/view-picker/hooks/useViewPickerMode';
@@ -8,7 +8,7 @@ import { viewPickerReferenceViewIdComponentState } from '@/views/view-picker/sta
import { isDefined } from 'twenty-shared/utils';
export const useOpenCreateViewDropdown = (viewBardId?: string) => {
const setViewPickerReferenceViewId = useSetRecoilComponentState(
const setViewPickerReferenceViewId = useSetRecoilComponentStateV2(
viewPickerReferenceViewIdComponentState,
viewBardId,
);
@@ -3,7 +3,7 @@ import { contextStoreRecordShowParentViewComponentState } from '@/context-store/
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { getQueryVariablesFromFiltersAndSorts } from '@/views/utils/getQueryVariablesFromFiltersAndSorts';
export const useQueryVariablesFromParentView = ({
@@ -13,7 +13,7 @@ export const useQueryVariablesFromParentView = ({
}) => {
const { objectMetadataItems } = useObjectMetadataItems();
const recordShowParentView = useRecoilComponentValue(
const recordShowParentView = useRecoilComponentValueV2(
contextStoreRecordShowParentViewComponentState,
MAIN_CONTEXT_STORE_INSTANCE_ID,
);
@@ -11,7 +11,7 @@ import { getFilterableFields } from '@/views/utils/getFilterableFields';
import { mapViewFieldToRecordField } from '@/views/utils/mapViewFieldToRecordField';
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
import { useRecoilCallback } from 'recoil';
import { useCallback } from 'react';
import { isDefined, removePropertiesFromRecord } from 'twenty-shared/utils';
import { useFindManyCoreViewsLazyQuery } from '~/generated-metadata/graphql';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
@@ -19,142 +19,135 @@ import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
export const useRefreshCoreViewsByObjectMetadataId = () => {
const [findManyCoreViewsLazy] = useFindManyCoreViewsLazyQuery();
const refreshCoreViewsByObjectMetadataId = useRecoilCallback(
({ set }) =>
async (objectMetadataId: string) => {
const result = await findManyCoreViewsLazy({
variables: {
objectMetadataId,
},
fetchPolicy: 'network-only',
});
const refreshCoreViewsByObjectMetadataId = useCallback(
async (objectMetadataId: string) => {
const result = await findManyCoreViewsLazy({
variables: {
objectMetadataId,
},
fetchPolicy: 'network-only',
});
if (!isDefined(result.data?.getCoreViews)) {
return;
if (!isDefined(result.data?.getCoreViews)) {
return;
}
const objectMetadataItems = jotaiStore.get(objectMetadataItemsState.atom);
const objectMetadataItem = objectMetadataItems.find(
(objectMetadataItem) => objectMetadataItem.id === objectMetadataId,
);
if (!isDefined(objectMetadataItem)) {
return;
}
const coreViewsForObjectMetadataId = jotaiStore.get(
coreViewsByObjectMetadataIdFamilySelector.selectorFamily(
objectMetadataId,
),
);
const coreViewsFromResult = result.data.getCoreViews;
if (isDeeplyEqual(coreViewsForObjectMetadataId, coreViewsFromResult)) {
return;
}
jotaiStore.set(
coreViewsByObjectMetadataIdFamilySelector.selectorFamily(
objectMetadataId,
),
coreViewsFromResult,
);
for (const coreView of coreViewsFromResult) {
const existingView = coreViewsForObjectMetadataId.find(
(coreViewForObjectMetadata) =>
coreViewForObjectMetadata.id === coreView.id,
);
if (!isDefined(existingView)) {
continue;
}
const objectMetadataItems = jotaiStore.get(
objectMetadataItemsState.atom,
);
const objectMetadataItem = objectMetadataItems.find(
(objectMetadataItem) => objectMetadataItem.id === objectMetadataId,
);
if (!isDefined(objectMetadataItem)) {
return;
}
const coreViewsForObjectMetadataId = jotaiStore.get(
coreViewsByObjectMetadataIdFamilySelector.selectorFamily(
objectMetadataId,
),
);
const coreViewsFromResult = result.data.getCoreViews;
if (isDeeplyEqual(coreViewsForObjectMetadataId, coreViewsFromResult)) {
return;
}
jotaiStore.set(
coreViewsByObjectMetadataIdFamilySelector.selectorFamily(
objectMetadataId,
),
coreViewsFromResult,
);
for (const coreView of coreViewsFromResult) {
const existingView = coreViewsForObjectMetadataId.find(
(coreViewForObjectMetadata) =>
coreViewForObjectMetadata.id === coreView.id,
if (
!isDeeplyEqual(
coreView.viewFields.map((viewField) =>
removePropertiesFromRecord(viewField, ['updatedAt', 'createdAt']),
),
existingView.viewFields,
)
) {
const view = convertCoreViewToView(coreView);
jotaiStore.set(
currentRecordFieldsComponentState.atomFamily({
instanceId: getRecordIndexIdFromObjectNamePluralAndViewId(
objectMetadataItem.namePlural,
view.id,
),
}),
view.viewFields
.filter(isDefined)
.map((viewField) => mapViewFieldToRecordField(viewField)),
);
if (!isDefined(existingView)) {
continue;
}
if (
!isDeeplyEqual(
coreView.viewFields.map((viewField) =>
removePropertiesFromRecord(viewField, [
'updatedAt',
'createdAt',
]),
),
existingView.viewFields,
)
) {
const view = convertCoreViewToView(coreView);
set(
currentRecordFieldsComponentState.atomFamily({
instanceId: getRecordIndexIdFromObjectNamePluralAndViewId(
objectMetadataItem.namePlural,
view.id,
),
}),
view.viewFields
.filter(isDefined)
.map((viewField) => mapViewFieldToRecordField(viewField)),
);
}
if (
!isDeeplyEqual(
coreView.viewFilters.map((viewFilter) =>
removePropertiesFromRecord(viewFilter, [
'createdAt',
'updatedAt',
]),
),
existingView.viewFilters,
)
) {
const view = convertCoreViewToView(coreView);
set(
currentRecordFiltersComponentState.atomFamily({
instanceId: getRecordIndexIdFromObjectNamePluralAndViewId(
objectMetadataItem.namePlural,
view.id,
),
}),
mapViewFiltersToFilters(
view.viewFilters,
getFilterableFields(objectMetadataItem),
),
);
}
if (!isDeeplyEqual(coreView.viewSorts, existingView.viewSorts)) {
const view = convertCoreViewToView(coreView);
set(
currentRecordSortsComponentState.atomFamily({
instanceId: getRecordIndexIdFromObjectNamePluralAndViewId(
objectMetadataItem.namePlural,
view.id,
),
}),
view.viewSorts,
);
}
if (
coreView.shouldHideEmptyGroups !==
existingView.shouldHideEmptyGroups
) {
const view = convertCoreViewToView(coreView);
set(
recordIndexShouldHideEmptyRecordGroupsComponentState.atomFamily({
instanceId: getRecordIndexIdFromObjectNamePluralAndViewId(
objectMetadataItem.namePlural,
view.id,
),
}),
view.shouldHideEmptyGroups,
);
}
}
},
if (
!isDeeplyEqual(
coreView.viewFilters.map((viewFilter) =>
removePropertiesFromRecord(viewFilter, [
'createdAt',
'updatedAt',
]),
),
existingView.viewFilters,
)
) {
const view = convertCoreViewToView(coreView);
jotaiStore.set(
currentRecordFiltersComponentState.atomFamily({
instanceId: getRecordIndexIdFromObjectNamePluralAndViewId(
objectMetadataItem.namePlural,
view.id,
),
}),
mapViewFiltersToFilters(
view.viewFilters,
getFilterableFields(objectMetadataItem),
),
);
}
if (!isDeeplyEqual(coreView.viewSorts, existingView.viewSorts)) {
const view = convertCoreViewToView(coreView);
jotaiStore.set(
currentRecordSortsComponentState.atomFamily({
instanceId: getRecordIndexIdFromObjectNamePluralAndViewId(
objectMetadataItem.namePlural,
view.id,
),
}),
view.viewSorts,
);
}
if (
coreView.shouldHideEmptyGroups !== existingView.shouldHideEmptyGroups
) {
const view = convertCoreViewToView(coreView);
jotaiStore.set(
recordIndexShouldHideEmptyRecordGroupsComponentState.atomFamily({
instanceId: getRecordIndexIdFromObjectNamePluralAndViewId(
objectMetadataItem.namePlural,
view.id,
),
}),
view.shouldHideEmptyGroups,
);
}
}
},
[findManyCoreViewsLazy],
);
@@ -1,10 +1,11 @@
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { usePerformViewAPIUpdate } from '@/views/hooks/internal/usePerformViewAPIUpdate';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { convertUpdateViewInputToCore } from '@/views/utils/convertUpdateViewInputToCore';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const useSaveAnyFieldFilterToView = () => {
@@ -13,40 +14,38 @@ export const useSaveAnyFieldFilterToView = () => {
const { currentView } = useGetCurrentViewOnly();
const anyFieldFilterValueCallbackState = useRecoilComponentCallbackState(
anyFieldFilterValueComponentState,
);
const anyFieldFilterValueCallbackState =
useRecoilComponentStateCallbackStateV2(anyFieldFilterValueComponentState);
const saveAnyFieldFilterToView = useRecoilCallback(
({ snapshot }) =>
async () => {
if (!canPersistChanges || !isDefined(currentView)) {
return;
}
const store = useStore();
const currentViewAnyFieldFilterValue = currentView.anyFieldFilterValue;
const saveAnyFieldFilterToView = useCallback(async () => {
if (!canPersistChanges || !isDefined(currentView)) {
return;
}
const currentAnyFieldFilterValue = snapshot
.getLoadable(anyFieldFilterValueCallbackState)
.getValue();
const currentViewAnyFieldFilterValue = currentView.anyFieldFilterValue;
if (currentAnyFieldFilterValue !== currentViewAnyFieldFilterValue) {
await performViewAPIUpdate({
id: currentView.id,
input: convertUpdateViewInputToCore({
...currentView,
anyFieldFilterValue: currentAnyFieldFilterValue,
}),
});
}
},
[
canPersistChanges,
performViewAPIUpdate,
const currentAnyFieldFilterValue = store.get(
anyFieldFilterValueCallbackState,
currentView,
],
);
);
if (currentAnyFieldFilterValue !== currentViewAnyFieldFilterValue) {
await performViewAPIUpdate({
id: currentView.id,
input: convertUpdateViewInputToCore({
...currentView,
anyFieldFilterValue: currentAnyFieldFilterValue,
}),
});
}
}, [
store,
canPersistChanges,
performViewAPIUpdate,
anyFieldFilterValueCallbackState,
currentView,
]);
return {
saveAnyFieldFilterToView,
@@ -1,7 +1,8 @@
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { usePerformViewFieldAPIPersist } from '@/views/hooks/internal/usePerformViewFieldAPIPersist';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useGetViewFromPrefetchState } from '@/views/hooks/useGetViewFromPrefetchState';
@@ -20,115 +21,115 @@ export const useSaveCurrentViewFields = () => {
const { getViewFromPrefetchState } = useGetViewFromPrefetchState();
const currentViewIdCallbackState = useRecoilComponentCallbackState(
const currentViewIdCallbackState = useRecoilComponentStateCallbackStateV2(
contextStoreCurrentViewIdComponentState,
);
const saveViewFields = useRecoilCallback(
({ snapshot }) =>
async (viewFieldsToSave: Omit<ViewField, 'definition'>[]) => {
if (!canPersistChanges) {
return;
}
const store = useStore();
const currentViewId = snapshot
.getLoadable(currentViewIdCallbackState)
.getValue();
const saveViewFields = useCallback(
async (viewFieldsToSave: Omit<ViewField, 'definition'>[]) => {
if (!canPersistChanges) {
return;
}
if (!currentViewId) {
return;
}
const currentViewId = store.get(currentViewIdCallbackState);
const view = getViewFromPrefetchState(currentViewId);
if (!currentViewId) {
return;
}
if (isUndefinedOrNull(view)) {
return;
}
const view = getViewFromPrefetchState(currentViewId);
const currentViewFields = view.viewFields;
if (isUndefinedOrNull(view)) {
return;
}
const { viewFieldsToCreate, viewFieldsToUpdate } =
viewFieldsToSave.reduce<{
viewFieldsToCreate: CreateViewFieldInput[];
viewFieldsToUpdate: UpdateCoreViewFieldMutationVariables[];
}>(
(
{ viewFieldsToCreate, viewFieldsToUpdate },
{ __typename, ...viewFieldToCreateOrUpdate },
) => {
const createViewFieldInput: CreateViewFieldInput = {
...viewFieldToCreateOrUpdate,
viewId: currentViewId,
const currentViewFields = view.viewFields;
const { viewFieldsToCreate, viewFieldsToUpdate } =
viewFieldsToSave.reduce<{
viewFieldsToCreate: CreateViewFieldInput[];
viewFieldsToUpdate: UpdateCoreViewFieldMutationVariables[];
}>(
(
{ viewFieldsToCreate, viewFieldsToUpdate },
{ __typename, ...viewFieldToCreateOrUpdate },
) => {
const createViewFieldInput: CreateViewFieldInput = {
...viewFieldToCreateOrUpdate,
viewId: currentViewId,
};
const existingField = currentViewFields.find(
(currentViewField) =>
currentViewField.fieldMetadataId ===
createViewFieldInput.fieldMetadataId,
);
if (isUndefinedOrNull(existingField)) {
return {
viewFieldsToCreate: [
...viewFieldsToCreate,
createViewFieldInput,
],
viewFieldsToUpdate,
};
const existingField = currentViewFields.find(
(currentViewField) =>
currentViewField.fieldMetadataId ===
createViewFieldInput.fieldMetadataId,
);
if (isUndefinedOrNull(existingField)) {
return {
viewFieldsToCreate: [
...viewFieldsToCreate,
createViewFieldInput,
],
viewFieldsToUpdate,
};
}
if (
isDeeplyEqual(
{
position: existingField.position,
size: existingField.size,
isVisible: existingField.isVisible,
aggregateOperation: existingField.aggregateOperation,
},
{
position: createViewFieldInput.position,
size: createViewFieldInput.size,
isVisible: createViewFieldInput.isVisible,
aggregateOperation: createViewFieldInput.aggregateOperation,
},
)
) {
return {
viewFieldsToCreate,
viewFieldsToUpdate,
};
}
}
if (
isDeeplyEqual(
{
position: existingField.position,
size: existingField.size,
isVisible: existingField.isVisible,
aggregateOperation: existingField.aggregateOperation,
},
{
position: createViewFieldInput.position,
size: createViewFieldInput.size,
isVisible: createViewFieldInput.isVisible,
aggregateOperation: createViewFieldInput.aggregateOperation,
},
)
) {
return {
viewFieldsToCreate,
viewFieldsToUpdate: [
...viewFieldsToUpdate,
{
input: {
id: existingField.id,
update: {
aggregateOperation:
createViewFieldInput.aggregateOperation,
isVisible: createViewFieldInput.isVisible,
position: createViewFieldInput.position,
size: createViewFieldInput.size,
},
viewFieldsToUpdate,
};
}
return {
viewFieldsToCreate,
viewFieldsToUpdate: [
...viewFieldsToUpdate,
{
input: {
id: existingField.id,
update: {
aggregateOperation:
createViewFieldInput.aggregateOperation,
isVisible: createViewFieldInput.isVisible,
position: createViewFieldInput.position,
size: createViewFieldInput.size,
},
},
],
};
},
{
viewFieldsToUpdate: [],
viewFieldsToCreate: [],
},
);
},
],
};
},
{
viewFieldsToUpdate: [],
viewFieldsToCreate: [],
},
);
await Promise.all([
performViewFieldAPICreate({ inputs: viewFieldsToCreate }),
performViewFieldAPIUpdate(viewFieldsToUpdate),
]);
},
await Promise.all([
performViewFieldAPICreate({ inputs: viewFieldsToCreate }),
performViewFieldAPIUpdate(viewFieldsToUpdate),
]);
},
[
store,
canPersistChanges,
performViewFieldAPICreate,
currentViewIdCallbackState,
@@ -1,7 +1,8 @@
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { usePerformViewGroupAPIPersist } from '@/views/hooks/internal/usePerformViewGroupAPIPersist';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useGetViewFromPrefetchState } from '@/views/hooks/useGetViewFromPrefetchState';
@@ -16,59 +17,125 @@ export const useSaveCurrentViewGroups = () => {
const { getViewFromPrefetchState } = useGetViewFromPrefetchState();
const currentViewIdCallbackState = useRecoilComponentCallbackState(
const currentViewIdCallbackState = useRecoilComponentStateCallbackStateV2(
contextStoreCurrentViewIdComponentState,
);
const saveViewGroup = useRecoilCallback(
({ snapshot }) =>
async (viewGroupToSave: ViewGroup) => {
if (!canPersistChanges) {
return;
}
const store = useStore();
const currentViewId = snapshot
.getLoadable(currentViewIdCallbackState)
.getValue();
const saveViewGroup = useCallback(
async (viewGroupToSave: ViewGroup) => {
if (!canPersistChanges) {
return;
}
if (!currentViewId) {
return;
}
const currentViewId = store.get(currentViewIdCallbackState);
const view = getViewFromPrefetchState(currentViewId);
if (!currentViewId) {
return;
}
if (isUndefinedOrNull(view)) {
return;
}
const view = getViewFromPrefetchState(currentViewId);
const currentViewGroups = view.viewGroups;
if (isUndefinedOrNull(view)) {
return;
}
const existingField = currentViewGroups.find(
(currentViewGroup) =>
currentViewGroup.fieldValue === viewGroupToSave.fieldValue,
);
const currentViewGroups = view.viewGroups;
if (isUndefinedOrNull(existingField)) {
return;
}
const existingField = currentViewGroups.find(
(currentViewGroup) =>
currentViewGroup.fieldValue === viewGroupToSave.fieldValue,
);
if (
isDeeplyEqual(
{
position: existingField.position,
isVisible: existingField.isVisible,
},
{
position: viewGroupToSave.position,
isVisible: viewGroupToSave.isVisible,
},
)
) {
return;
}
if (isUndefinedOrNull(existingField)) {
return;
}
await performViewGroupAPIUpdate([
if (
isDeeplyEqual(
{
position: existingField.position,
isVisible: existingField.isVisible,
},
{
position: viewGroupToSave.position,
isVisible: viewGroupToSave.isVisible,
},
)
) {
return;
}
await performViewGroupAPIUpdate([
{
input: {
id: existingField.id,
update: {
isVisible: viewGroupToSave.isVisible,
position: viewGroupToSave.position,
fieldValue: viewGroupToSave.fieldValue,
},
},
},
]);
},
[
store,
canPersistChanges,
currentViewIdCallbackState,
getViewFromPrefetchState,
performViewGroupAPIUpdate,
],
);
const saveViewGroups = useCallback(
async (viewGroupsToSave: ViewGroup[]) => {
if (!canPersistChanges) {
return;
}
const currentViewId = store.get(currentViewIdCallbackState);
if (!currentViewId) {
return;
}
const view = getViewFromPrefetchState(currentViewId);
if (isUndefinedOrNull(view)) {
return;
}
const currentViewGroups = view.viewGroups;
const viewGroupsToUpdate = viewGroupsToSave
.map((viewGroupToSave) => {
const existingField = currentViewGroups.find(
(currentViewGroup) =>
currentViewGroup.fieldValue === viewGroupToSave.fieldValue,
);
if (isUndefinedOrNull(existingField)) {
return undefined;
}
if (
isDeeplyEqual(
{
position: existingField.position,
isVisible: existingField.isVisible,
},
{
position: viewGroupToSave.position,
isVisible: viewGroupToSave.isVisible,
},
)
) {
return undefined;
}
return {
input: {
id: existingField.id,
update: {
@@ -77,86 +144,18 @@ export const useSaveCurrentViewGroups = () => {
fieldValue: viewGroupToSave.fieldValue,
},
},
},
]);
},
[
canPersistChanges,
currentViewIdCallbackState,
getViewFromPrefetchState,
performViewGroupAPIUpdate,
],
);
const saveViewGroups = useRecoilCallback(
({ snapshot }) =>
async (viewGroupsToSave: ViewGroup[]) => {
if (!canPersistChanges) {
return;
}
const currentViewId = snapshot
.getLoadable(currentViewIdCallbackState)
.getValue();
if (!currentViewId) {
return;
}
const view = getViewFromPrefetchState(currentViewId);
if (isUndefinedOrNull(view)) {
return;
}
const currentViewGroups = view.viewGroups;
const viewGroupsToUpdate = viewGroupsToSave
.map((viewGroupToSave) => {
const existingField = currentViewGroups.find(
(currentViewGroup) =>
currentViewGroup.fieldValue === viewGroupToSave.fieldValue,
);
if (isUndefinedOrNull(existingField)) {
return undefined;
}
if (
isDeeplyEqual(
{
position: existingField.position,
isVisible: existingField.isVisible,
},
{
position: viewGroupToSave.position,
isVisible: viewGroupToSave.isVisible,
},
)
) {
return undefined;
}
return {
input: {
id: existingField.id,
update: {
isVisible: viewGroupToSave.isVisible,
position: viewGroupToSave.position,
fieldValue: viewGroupToSave.fieldValue,
},
},
};
})
.filter(isDefined);
if (!isDefined(view.mainGroupByFieldMetadataId)) {
throw new Error('mainGroupByFieldMetadataId is required');
}
await performViewGroupAPIUpdate(viewGroupsToUpdate);
},
};
})
.filter(isDefined);
if (!isDefined(view.mainGroupByFieldMetadataId)) {
throw new Error('mainGroupByFieldMetadataId is required');
}
await performViewGroupAPIUpdate(viewGroupsToUpdate);
},
[
store,
canPersistChanges,
currentViewIdCallbackState,
getViewFromPrefetchState,
@@ -1,6 +1,5 @@
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
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 { usePerformViewFilterGroupAPIPersist } from '@/views/hooks/internal/usePerformViewFilterGroupAPIPersist';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
@@ -8,7 +7,8 @@ import { getViewFilterGroupsToCreate } from '@/views/utils/getViewFilterGroupsTo
import { getViewFilterGroupsToDelete } from '@/views/utils/getViewFilterGroupsToDelete';
import { getViewFilterGroupsToUpdate } from '@/views/utils/getViewFilterGroupsToUpdate';
import { mapRecordFilterGroupToViewFilterGroup } from '@/views/utils/mapRecordFilterGroupToViewFilterGroup';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const useSaveRecordFilterGroupsToViewFilterGroups = () => {
@@ -22,65 +22,65 @@ export const useSaveRecordFilterGroupsToViewFilterGroups = () => {
const { currentView } = useGetCurrentViewOnly();
const currentRecordFilterGroupsCallbackState =
useRecoilComponentCallbackState(currentRecordFilterGroupsComponentState);
useRecoilComponentStateCallbackStateV2(
currentRecordFilterGroupsComponentState,
);
const saveRecordFilterGroupsToViewFilterGroups = useRecoilCallback(
({ snapshot }) =>
async () => {
if (!canPersistChanges || !isDefined(currentView)) {
return;
}
const store = useStore();
const currentViewFilterGroups = currentView?.viewFilterGroups ?? [];
const saveRecordFilterGroupsToViewFilterGroups = useCallback(async () => {
if (!canPersistChanges || !isDefined(currentView)) {
return;
}
const currentRecordFilterGroups = getSnapshotValue(
snapshot,
currentRecordFilterGroupsCallbackState,
);
const currentViewFilterGroups = currentView?.viewFilterGroups ?? [];
const newViewFilterGroups = currentRecordFilterGroups.map(
(recordFilterGroup) =>
mapRecordFilterGroupToViewFilterGroup({
recordFilterGroup,
view: currentView,
}),
);
const viewFilterGroupsToCreate = getViewFilterGroupsToCreate(
currentViewFilterGroups,
newViewFilterGroups,
);
const viewFilterGroupsToDelete = getViewFilterGroupsToDelete(
currentViewFilterGroups,
newViewFilterGroups,
);
const viewFilterGroupsToUpdate = getViewFilterGroupsToUpdate(
currentViewFilterGroups,
newViewFilterGroups,
);
const viewFilterGroupIdsToDelete = viewFilterGroupsToDelete.map(
(viewFilterGroup) => viewFilterGroup.id,
);
await performViewFilterGroupAPICreate(
viewFilterGroupsToCreate,
currentView,
);
await performViewFilterGroupAPIUpdate(viewFilterGroupsToUpdate);
await performViewFilterGroupAPIDelete(viewFilterGroupIdsToDelete);
},
[
canPersistChanges,
currentView,
const currentRecordFilterGroups = store.get(
currentRecordFilterGroupsCallbackState,
performViewFilterGroupAPICreate,
performViewFilterGroupAPIUpdate,
performViewFilterGroupAPIDelete,
],
);
);
const newViewFilterGroups = currentRecordFilterGroups.map(
(recordFilterGroup) =>
mapRecordFilterGroupToViewFilterGroup({
recordFilterGroup,
view: currentView,
}),
);
const viewFilterGroupsToCreate = getViewFilterGroupsToCreate(
currentViewFilterGroups,
newViewFilterGroups,
);
const viewFilterGroupsToDelete = getViewFilterGroupsToDelete(
currentViewFilterGroups,
newViewFilterGroups,
);
const viewFilterGroupsToUpdate = getViewFilterGroupsToUpdate(
currentViewFilterGroups,
newViewFilterGroups,
);
const viewFilterGroupIdsToDelete = viewFilterGroupsToDelete.map(
(viewFilterGroup) => viewFilterGroup.id,
);
await performViewFilterGroupAPICreate(
viewFilterGroupsToCreate,
currentView,
);
await performViewFilterGroupAPIUpdate(viewFilterGroupsToUpdate);
await performViewFilterGroupAPIDelete(viewFilterGroupIdsToDelete);
}, [
store,
canPersistChanges,
currentView,
currentRecordFilterGroupsCallbackState,
performViewFilterGroupAPICreate,
performViewFilterGroupAPIUpdate,
performViewFilterGroupAPIDelete,
]);
return {
saveRecordFilterGroupsToViewFilterGroups,
@@ -1,6 +1,5 @@
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 { usePerformViewFilterAPIPersist } from '@/views/hooks/internal/usePerformViewFilterAPIPersist';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
@@ -8,7 +7,8 @@ import { getViewFiltersToCreate } from '@/views/utils/getViewFiltersToCreate';
import { getViewFiltersToDelete } from '@/views/utils/getViewFiltersToDelete';
import { getViewFiltersToUpdate } from '@/views/utils/getViewFiltersToUpdate';
import { mapRecordFilterToViewFilter } from '@/views/utils/mapRecordFilterToViewFilter';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const useSaveRecordFiltersToViewFilters = () => {
@@ -21,111 +21,100 @@ export const useSaveRecordFiltersToViewFilters = () => {
const { currentView } = useGetCurrentViewOnly();
const currentRecordFiltersCallbackState = useRecoilComponentCallbackState(
currentRecordFiltersComponentState,
);
const currentRecordFiltersCallbackState =
useRecoilComponentStateCallbackStateV2(currentRecordFiltersComponentState);
const saveRecordFiltersToViewFilters = useRecoilCallback(
({ snapshot }) =>
async () => {
if (!canPersistChanges || !isDefined(currentView)) {
return;
}
const store = useStore();
const currentViewFilters = currentView?.viewFilters ?? [];
const saveRecordFiltersToViewFilters = useCallback(async () => {
if (!canPersistChanges || !isDefined(currentView)) {
return;
}
const currentRecordFilters = getSnapshotValue(
snapshot,
currentRecordFiltersCallbackState,
);
const currentViewFilters = currentView?.viewFilters ?? [];
const newViewFilters = currentRecordFilters.map(
mapRecordFilterToViewFilter,
);
const currentRecordFilters = store.get(currentRecordFiltersCallbackState);
const viewFiltersToCreate = getViewFiltersToCreate(
currentViewFilters,
newViewFilters,
);
const newViewFilters = currentRecordFilters.map(
mapRecordFilterToViewFilter,
);
const viewFiltersToDelete = getViewFiltersToDelete(
currentViewFilters,
newViewFilters,
);
const viewFiltersToCreate = getViewFiltersToCreate(
currentViewFilters,
newViewFilters,
);
const viewFiltersToUpdate = getViewFiltersToUpdate(
currentViewFilters,
newViewFilters,
);
const viewFiltersToDelete = getViewFiltersToDelete(
currentViewFilters,
newViewFilters,
);
const createViewFilterInputs = viewFiltersToCreate.map(
(viewFilter) => ({
input: {
id: viewFilter.id,
fieldMetadataId: viewFilter.fieldMetadataId,
viewId: currentView.id,
value: viewFilter.value,
operand: viewFilter.operand,
viewFilterGroupId: viewFilter.viewFilterGroupId,
positionInViewFilterGroup: viewFilter.positionInViewFilterGroup,
subFieldName: viewFilter.subFieldName ?? null,
},
}),
);
const viewFiltersToUpdate = getViewFiltersToUpdate(
currentViewFilters,
newViewFilters,
);
const updateViewFilterInputs = viewFiltersToUpdate.map(
(viewFilter) => ({
input: {
id: viewFilter.id,
update: {
value: viewFilter.value,
operand: viewFilter.operand,
positionInViewFilterGroup: viewFilter.positionInViewFilterGroup,
viewFilterGroupId: viewFilter.viewFilterGroupId,
subFieldName: viewFilter.subFieldName ?? null,
},
},
}),
);
const deleteViewFilterInputs = viewFiltersToDelete.map(
(viewFilter) => ({
input: {
id: viewFilter.id,
},
}),
);
const createResult = await performViewFilterAPICreate(
createViewFilterInputs,
);
if (createResult.status === 'failed') {
return;
}
const updateResult = await performViewFilterAPIUpdate(
updateViewFilterInputs,
);
if (updateResult.status === 'failed') {
return;
}
const deleteResult = await performViewFilterAPIDelete(
deleteViewFilterInputs,
);
if (deleteResult.status === 'failed') {
return;
}
const createViewFilterInputs = viewFiltersToCreate.map((viewFilter) => ({
input: {
id: viewFilter.id,
fieldMetadataId: viewFilter.fieldMetadataId,
viewId: currentView.id,
value: viewFilter.value,
operand: viewFilter.operand,
viewFilterGroupId: viewFilter.viewFilterGroupId,
positionInViewFilterGroup: viewFilter.positionInViewFilterGroup,
subFieldName: viewFilter.subFieldName ?? null,
},
[
canPersistChanges,
currentView,
currentRecordFiltersCallbackState,
performViewFilterAPICreate,
performViewFilterAPIUpdate,
performViewFilterAPIDelete,
],
);
}));
const updateViewFilterInputs = viewFiltersToUpdate.map((viewFilter) => ({
input: {
id: viewFilter.id,
update: {
value: viewFilter.value,
operand: viewFilter.operand,
positionInViewFilterGroup: viewFilter.positionInViewFilterGroup,
viewFilterGroupId: viewFilter.viewFilterGroupId,
subFieldName: viewFilter.subFieldName ?? null,
},
},
}));
const deleteViewFilterInputs = viewFiltersToDelete.map((viewFilter) => ({
input: {
id: viewFilter.id,
},
}));
const createResult = await performViewFilterAPICreate(
createViewFilterInputs,
);
if (createResult.status === 'failed') {
return;
}
const updateResult = await performViewFilterAPIUpdate(
updateViewFilterInputs,
);
if (updateResult.status === 'failed') {
return;
}
const deleteResult = await performViewFilterAPIDelete(
deleteViewFilterInputs,
);
if (deleteResult.status === 'failed') {
return;
}
}, [
store,
canPersistChanges,
currentView,
currentRecordFiltersCallbackState,
performViewFilterAPICreate,
performViewFilterAPIUpdate,
performViewFilterAPIDelete,
]);
return {
saveRecordFiltersToViewFilters,
@@ -1,6 +1,5 @@
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
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 { usePerformViewSortAPIPersist } from '@/views/hooks/internal/usePerformViewSortAPIPersist';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
@@ -8,7 +7,8 @@ import { getViewSortsToCreate } from '@/views/utils/getViewSortsToCreate';
import { getViewSortsToDelete } from '@/views/utils/getViewSortsToDelete';
import { getViewSortsToUpdate } from '@/views/utils/getViewSortsToUpdate';
import { mapRecordSortToViewSort } from '@/views/utils/mapRecordSortToViewSort';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const useSaveRecordSortsToViewSorts = () => {
@@ -21,56 +21,51 @@ export const useSaveRecordSortsToViewSorts = () => {
const { currentView } = useGetCurrentViewOnly();
const currentRecordSortsCallbackState = useRecoilComponentCallbackState(
currentRecordSortsComponentState,
);
const currentRecordSortsCallbackState =
useRecoilComponentStateCallbackStateV2(currentRecordSortsComponentState);
const saveRecordSortsToViewSorts = useRecoilCallback(
({ snapshot }) =>
async () => {
if (!canPersistChanges || !isDefined(currentView)) {
return;
}
const store = useStore();
const currentViewSorts = currentView?.viewSorts ?? [];
const saveRecordSortsToViewSorts = useCallback(async () => {
if (!canPersistChanges || !isDefined(currentView)) {
return;
}
const currentRecordSorts = getSnapshotValue(
snapshot,
currentRecordSortsCallbackState,
);
const currentViewSorts = currentView?.viewSorts ?? [];
const newViewSorts = currentRecordSorts.map((recordSort) =>
mapRecordSortToViewSort(recordSort, currentView.id),
);
const currentRecordSorts = store.get(currentRecordSortsCallbackState);
const viewSortsToCreate = getViewSortsToCreate(
currentViewSorts,
newViewSorts,
);
const newViewSorts = currentRecordSorts.map((recordSort) =>
mapRecordSortToViewSort(recordSort, currentView.id),
);
const viewSortsToDelete = getViewSortsToDelete(
currentViewSorts,
newViewSorts,
);
const viewSortsToCreate = getViewSortsToCreate(
currentViewSorts,
newViewSorts,
);
const viewSortsToUpdate = getViewSortsToUpdate(
currentViewSorts,
newViewSorts,
);
const viewSortsToDelete = getViewSortsToDelete(
currentViewSorts,
newViewSorts,
);
await performViewSortAPICreate(viewSortsToCreate, currentView);
await performViewSortAPIUpdate(viewSortsToUpdate);
await performViewSortAPIDelete(viewSortsToDelete);
},
[
canPersistChanges,
currentView,
currentRecordSortsCallbackState,
performViewSortAPICreate,
performViewSortAPIUpdate,
performViewSortAPIDelete,
],
);
const viewSortsToUpdate = getViewSortsToUpdate(
currentViewSorts,
newViewSorts,
);
await performViewSortAPICreate(viewSortsToCreate, currentView);
await performViewSortAPIUpdate(viewSortsToUpdate);
await performViewSortAPIDelete(viewSortsToDelete);
}, [
store,
canPersistChanges,
currentView,
currentRecordSortsCallbackState,
performViewSortAPICreate,
performViewSortAPIUpdate,
performViewSortAPIDelete,
]);
return {
saveRecordSortsToViewSorts,
@@ -5,61 +5,62 @@ import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object
import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext';
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { getEditableChipObjectFilterDropdownComponentInstanceId } from '@/views/editable-chip/utils/getEditableChipObjectFilterDropdownComponentInstanceId';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const useSetEditableFilterChipDropdownStates = () => {
const { filterableFieldMetadataItems } =
useFilterableFieldMetadataItemsInRecordIndexContext();
const setEditableFilterChipDropdownStates = useRecoilCallback(
({ set }) =>
(recordFilter: RecordFilter) => {
const fieldMetadataItem = filterableFieldMetadataItems.find(
(fieldMetadataItem) =>
fieldMetadataItem.id === recordFilter.fieldMetadataId,
);
const store = useStore();
if (isDefined(fieldMetadataItem)) {
set(
fieldMetadataItemIdUsedInDropdownComponentState.atomFamily({
instanceId:
getEditableChipObjectFilterDropdownComponentInstanceId({
recordFilterId: recordFilter.id,
}),
}),
fieldMetadataItem.id,
);
}
const setEditableFilterChipDropdownStates = useCallback(
(recordFilter: RecordFilter) => {
const fieldMetadataItem = filterableFieldMetadataItems.find(
(fieldMetadataItem) =>
fieldMetadataItem.id === recordFilter.fieldMetadataId,
);
set(
selectedOperandInDropdownComponentState.atomFamily({
if (isDefined(fieldMetadataItem)) {
store.set(
fieldMetadataItemIdUsedInDropdownComponentState.atomFamily({
instanceId: getEditableChipObjectFilterDropdownComponentInstanceId({
recordFilterId: recordFilter.id,
}),
}),
recordFilter.operand,
fieldMetadataItem.id,
);
}
set(
objectFilterDropdownCurrentRecordFilterComponentState.atomFamily({
instanceId: getEditableChipObjectFilterDropdownComponentInstanceId({
recordFilterId: recordFilter.id,
}),
store.set(
selectedOperandInDropdownComponentState.atomFamily({
instanceId: getEditableChipObjectFilterDropdownComponentInstanceId({
recordFilterId: recordFilter.id,
}),
recordFilter,
);
}),
recordFilter.operand,
);
set(
subFieldNameUsedInDropdownComponentState.atomFamily({
instanceId: getEditableChipObjectFilterDropdownComponentInstanceId({
recordFilterId: recordFilter.id,
}),
store.set(
objectFilterDropdownCurrentRecordFilterComponentState.atomFamily({
instanceId: getEditableChipObjectFilterDropdownComponentInstanceId({
recordFilterId: recordFilter.id,
}),
recordFilter.subFieldName,
);
},
[filterableFieldMetadataItems],
}),
recordFilter,
);
store.set(
subFieldNameUsedInDropdownComponentState.atomFamily({
instanceId: getEditableChipObjectFilterDropdownComponentInstanceId({
recordFilterId: recordFilter.id,
}),
}),
recordFilter.subFieldName,
);
},
[store, filterableFieldMetadataItems],
);
return {
@@ -1,11 +1,11 @@
import { useStore } from 'jotai';
import { useRecoilCallback, useSetRecoilState } from 'recoil';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { useLoadRecordIndexStates } from '@/object-record/record-index/hooks/useLoadRecordIndexStates';
import { recordIndexViewTypeState } from '@/object-record/record-index/states/recordIndexViewTypeState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useRefreshCoreViewsByObjectMetadataId } from '@/views/hooks/useRefreshCoreViewsByObjectMetadataId';
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
@@ -14,19 +14,19 @@ import { type View } from '@/views/types/View';
import { type ViewGroup } from '@/views/types/ViewGroup';
import { type ViewType } from '@/views/types/ViewType';
import { convertUpdateViewInputToCore } from '@/views/utils/convertUpdateViewInputToCore';
import { useMemo } from 'react';
import { useCallback, useMemo } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { v4 } from 'uuid';
import { useUpdateCoreViewMutation } from '~/generated-metadata/graphql';
export const useUpdateCurrentView = () => {
const { canPersistChanges } = useCanPersistViewChanges();
const currentViewIdCallbackState = useRecoilComponentCallbackState(
const currentViewIdCallbackState = useRecoilComponentStateCallbackStateV2(
contextStoreCurrentViewIdComponentState,
);
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
const { loadRecordIndexStates } = useLoadRecordIndexStates();
const setRecordIndexViewType = useSetRecoilState(recordIndexViewTypeState);
const setRecordIndexViewType = useSetRecoilStateV2(recordIndexViewTypeState);
const store = useStore();
@@ -91,66 +91,61 @@ export const useUpdateCurrentView = () => {
};
}, [objectMetadataItem.fields]);
const updateCurrentView = useRecoilCallback(
({ snapshot }) =>
async (view: Partial<GraphQLView> & { type?: ViewType }) => {
if (!canPersistChanges) {
return;
}
const updateCurrentView = useCallback(
async (view: Partial<GraphQLView> & { type?: ViewType }) => {
if (!canPersistChanges) {
return;
}
const currentViewId = snapshot
.getLoadable(currentViewIdCallbackState)
.getValue();
const currentViewId = store.get(currentViewIdCallbackState);
const currentView = store.get(
coreViewFromViewIdFamilySelector.selectorFamily({
viewId: currentViewId ?? '',
}),
);
const currentView = store.get(
coreViewFromViewIdFamilySelector.selectorFamily({
viewId: currentViewId ?? '',
}),
);
if (!isDefined(currentView)) {
return;
}
if (!isDefined(currentView)) {
return;
}
if (isDefined(currentViewId)) {
const input = convertUpdateViewInputToCore(view);
if (isDefined(currentViewId)) {
const input = convertUpdateViewInputToCore(view);
await updateOneCoreView({
variables: {
id: currentViewId,
input,
},
await updateOneCoreView({
variables: {
id: currentViewId,
input,
},
});
if (
input.mainGroupByFieldMetadataId !== undefined &&
currentView.mainGroupByFieldMetadataId !==
input.mainGroupByFieldMetadataId
) {
const { viewGroupsToCreate } = getViewGroupsToCreateAtViewUpdate({
existingView: currentView,
newMainGroupByFieldMetadataId: input.mainGroupByFieldMetadataId,
});
if (
input.mainGroupByFieldMetadataId !== undefined &&
currentView.mainGroupByFieldMetadataId !==
input.mainGroupByFieldMetadataId
) {
const { viewGroupsToCreate } = getViewGroupsToCreateAtViewUpdate({
existingView: currentView,
newMainGroupByFieldMetadataId: input.mainGroupByFieldMetadataId,
});
loadRecordIndexStates(
{
...currentView,
mainGroupByFieldMetadataId: input.mainGroupByFieldMetadataId,
viewGroups: viewGroupsToCreate ?? [],
},
objectMetadataItem,
);
}
if (isDefined(view.type)) {
setRecordIndexViewType(view.type);
}
await refreshCoreViewsByObjectMetadataId(
currentView.objectMetadataId,
loadRecordIndexStates(
{
...currentView,
mainGroupByFieldMetadataId: input.mainGroupByFieldMetadataId,
viewGroups: viewGroupsToCreate ?? [],
},
objectMetadataItem,
);
}
},
if (isDefined(view.type)) {
setRecordIndexViewType(view.type);
}
await refreshCoreViewsByObjectMetadataId(currentView.objectMetadataId);
}
},
[
canPersistChanges,
currentViewIdCallbackState,
@@ -3,7 +3,7 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI
import { useLoadRecordIndexStates } from '@/object-record/record-index/hooks/useLoadRecordIndexStates';
import { type ExtendedAggregateOperations } from '@/object-record/record-table/types/ExtendedAggregateOperations';
import { convertExtendedAggregateOperationToAggregateOperation } from '@/object-record/utils/convertExtendedAggregateOperationToAggregateOperation';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { usePerformViewAPIUpdate } from '@/views/hooks/internal/usePerformViewAPIUpdate';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
@@ -18,7 +18,7 @@ import { type CoreView } from '~/generated-metadata/graphql';
export const useUpdateViewAggregate = () => {
const { canPersistChanges } = useCanPersistViewChanges();
const currentViewId = useRecoilComponentValue(
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
);
const { performViewAPIUpdate } = usePerformViewAPIUpdate();
@@ -1,9 +1,9 @@
import { type FieldMetadata } from '@/object-record/record-field/ui/types/FieldMetadata';
import { type ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
export const availableFieldDefinitionsComponentState = createComponentState<
export const availableFieldDefinitionsComponentState = createComponentStateV2<
ColumnDefinition<FieldMetadata>[]
>({
key: 'availableFieldDefinitionsComponentState',
@@ -1,8 +1,8 @@
import { RecordFiltersComponentInstanceContext } from '@/object-record/record-filter/states/context/RecordFiltersComponentInstanceContext';
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentFamilyStateV2';
export const hasInitializedAnyFieldFilterComponentFamilyState =
createComponentFamilyState<boolean, { viewId?: string }>({
createComponentFamilyStateV2<boolean, { viewId?: string }>({
key: 'hasInitializedAnyFieldFilterComponentFamilyState',
defaultValue: false,
componentInstanceContext: RecordFiltersComponentInstanceContext,
@@ -1,8 +1,8 @@
import { RecordFieldsComponentInstanceContext } from '@/object-record/record-field/states/context/RecordFieldsComponentInstanceContext';
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentFamilyStateV2';
export const hasInitializedCurrentRecordFieldsComponentFamilyState =
createComponentFamilyState<boolean, { viewId?: string }>({
createComponentFamilyStateV2<boolean, { viewId?: string }>({
key: 'hasInitializedCurrentRecordFieldsComponentFamilyState',
defaultValue: false,
componentInstanceContext: RecordFieldsComponentInstanceContext,
@@ -1,8 +1,8 @@
import { RecordFilterGroupsComponentInstanceContext } from '@/object-record/record-filter-group/states/context/RecordFilterGroupsComponentInstanceContext';
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentFamilyStateV2';
export const hasInitializedCurrentRecordFilterGroupsComponentFamilyState =
createComponentFamilyState<boolean, { viewId?: string }>({
createComponentFamilyStateV2<boolean, { viewId?: string }>({
key: 'hasInitializedCurrentRecordFilterGroupsComponentFamilyState',
defaultValue: false,
componentInstanceContext: RecordFilterGroupsComponentInstanceContext,
@@ -1,8 +1,8 @@
import { RecordFiltersComponentInstanceContext } from '@/object-record/record-filter/states/context/RecordFiltersComponentInstanceContext';
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentFamilyStateV2';
export const hasInitializedCurrentRecordFiltersComponentFamilyState =
createComponentFamilyState<boolean, { viewId?: string }>({
createComponentFamilyStateV2<boolean, { viewId?: string }>({
key: 'hasInitializedCurrentRecordFiltersComponentFamilyState',
defaultValue: false,
componentInstanceContext: RecordFiltersComponentInstanceContext,
@@ -1,8 +1,8 @@
import { RecordSortsComponentInstanceContext } from '@/object-record/record-sort/states/context/RecordSortsComponentInstanceContext';
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentFamilyStateV2';
export const hasInitializedCurrentRecordSortsComponentFamilyState =
createComponentFamilyState<boolean, { viewId?: string }>({
createComponentFamilyStateV2<boolean, { viewId?: string }>({
key: 'hasInitializedCurrentRecordSortsComponentFamilyState',
defaultValue: false,
componentInstanceContext: RecordSortsComponentInstanceContext,
@@ -1,8 +1,8 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
export const isCurrentViewKeyIndexComponentState =
createComponentState<boolean>({
createComponentStateV2<boolean>({
key: 'isCurrentViewKeyIndexComponentState',
defaultValue: true,
componentInstanceContext: ViewComponentInstanceContext,
@@ -1,7 +1,7 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
export const isViewBarExpandedComponentState = createComponentState<boolean>({
export const isViewBarExpandedComponentState = createComponentStateV2<boolean>({
key: 'isViewBarExpandedComponentState',
defaultValue: true,
componentInstanceContext: ViewComponentInstanceContext,
@@ -1,7 +1,7 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
export const viewObjectMetadataIdComponentState = createComponentState<
export const viewObjectMetadataIdComponentState = createComponentStateV2<
string | undefined
>({
key: 'viewObjectMetadataIdComponentState',
@@ -11,9 +11,9 @@ import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { viewObjectMetadataIdComponentState } from '@/views/states/viewObjectMetadataIdComponentState';
import { ViewType, viewTypeIconMapping } from '@/views/types/ViewType';
import { ViewPickerCreateButton } from '@/views/view-picker/components/ViewPickerCreateButton';
@@ -53,40 +53,41 @@ export const ViewPickerContentCreateMode = () => {
const { viewPickerMode, setViewPickerMode } = useViewPickerMode();
const [hasManuallySelectedIcon, setHasManuallySelectedIcon] = useState(false);
const viewObjectMetadataId = useRecoilComponentValue(
const viewObjectMetadataId = useRecoilComponentValueV2(
viewObjectMetadataIdComponentState,
);
const { objectMetadataItem } = useObjectMetadataItemById({
objectId: viewObjectMetadataId ?? '',
});
const [viewPickerInputName, setViewPickerInputName] = useRecoilComponentState(
viewPickerInputNameComponentState,
);
const [viewPickerInputName, setViewPickerInputName] =
useRecoilComponentStateV2(viewPickerInputNameComponentState);
const [viewPickerSelectedIcon, setViewPickerSelectedIcon] =
useRecoilComponentState(viewPickerSelectedIconComponentState);
useRecoilComponentStateV2(viewPickerSelectedIconComponentState);
const viewPickerIsPersisting = useRecoilComponentValue(
const viewPickerIsPersisting = useRecoilComponentValueV2(
viewPickerIsPersistingComponentState,
);
const setViewPickerIsDirty = useSetRecoilComponentState(
const setViewPickerIsDirty = useSetRecoilComponentStateV2(
viewPickerIsDirtyComponentState,
);
const [
viewPickerMainGroupByFieldMetadataId,
setViewPickerMainGroupByFieldMetadataId,
] = useRecoilComponentState(
] = useRecoilComponentStateV2(
viewPickerMainGroupByFieldMetadataIdComponentState,
);
const [
viewPickerCalendarFieldMetadataId,
setViewPickerCalendarFieldMetadataId,
] = useRecoilComponentState(viewPickerCalendarFieldMetadataIdComponentState);
] = useRecoilComponentStateV2(
viewPickerCalendarFieldMetadataIdComponentState,
);
const [viewPickerType, setViewPickerType] = useRecoilComponentState(
const [viewPickerType, setViewPickerType] = useRecoilComponentStateV2(
viewPickerTypeComponentState,
);
@@ -8,9 +8,9 @@ import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { ViewPickerEditButton } from '@/views/view-picker/components/ViewPickerEditButton';
import { ViewPickerIconAndNameContainer } from '@/views/view-picker/components/ViewPickerIconAndNameContainer';
import { ViewPickerSaveButtonContainer } from '@/views/view-picker/components/ViewPickerSaveButtonContainer';
@@ -27,16 +27,15 @@ import { IconChevronLeft } from 'twenty-ui/display';
export const ViewPickerContentEditMode = () => {
const { setViewPickerMode } = useViewPickerMode();
const [viewPickerInputName, setViewPickerInputName] = useRecoilComponentState(
viewPickerInputNameComponentState,
);
const [viewPickerInputName, setViewPickerInputName] =
useRecoilComponentStateV2(viewPickerInputNameComponentState);
const [viewPickerSelectedIcon, setViewPickerSelectedIcon] =
useRecoilComponentState(viewPickerSelectedIconComponentState);
useRecoilComponentStateV2(viewPickerSelectedIconComponentState);
const viewPickerIsPersisting = useRecoilComponentValue(
const viewPickerIsPersisting = useRecoilComponentValueV2(
viewPickerIsPersistingComponentState,
);
const setViewPickerIsDirty = useSetRecoilComponentState(
const setViewPickerIsDirty = useSetRecoilComponentStateV2(
viewPickerIsDirtyComponentState,
);
@@ -2,9 +2,9 @@ import { useEffect } from 'react';
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
import { useHasPermissionFlag } from '@/settings/roles/hooks/useHasPermissionFlag';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
import { coreViewsFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/coreViewsFromObjectMetadataItemFamilySelector';
import { viewTypeIconMapping } from '@/views/types/ViewType';
@@ -27,13 +27,13 @@ import {
} from '~/generated-metadata/graphql';
export const ViewPickerContentEffect = () => {
const setViewPickerSelectedIcon = useSetRecoilComponentState(
const setViewPickerSelectedIcon = useSetRecoilComponentStateV2(
viewPickerSelectedIconComponentState,
);
const setViewPickerInputName = useSetRecoilComponentState(
const setViewPickerInputName = useSetRecoilComponentStateV2(
viewPickerInputNameComponentState,
);
const setViewPickerVisibility = useSetRecoilComponentState(
const setViewPickerVisibility = useSetRecoilComponentStateV2(
viewPickerVisibilityComponentState,
);
const { viewPickerMode } = useViewPickerMode();
@@ -41,28 +41,30 @@ export const ViewPickerContentEffect = () => {
const [
viewPickerMainGroupByFieldMetadataId,
setViewPickerMainGroupByFieldMetadataId,
] = useRecoilComponentState(
] = useRecoilComponentStateV2(
viewPickerMainGroupByFieldMetadataIdComponentState,
);
const [
viewPickerCalendarFieldMetadataId,
setViewPickerCalendarFieldMetadataId,
] = useRecoilComponentState(viewPickerCalendarFieldMetadataIdComponentState);
] = useRecoilComponentStateV2(
viewPickerCalendarFieldMetadataIdComponentState,
);
const [viewPickerType, setViewPickerType] = useRecoilComponentState(
const [viewPickerType, setViewPickerType] = useRecoilComponentStateV2(
viewPickerTypeComponentState,
);
const viewPickerReferenceViewId = useRecoilComponentValue(
const viewPickerReferenceViewId = useRecoilComponentValueV2(
viewPickerReferenceViewIdComponentState,
);
const viewPickerIsDirty = useRecoilComponentValue(
const viewPickerIsDirty = useRecoilComponentValueV2(
viewPickerIsDirtyComponentState,
);
const viewPickerIsPersisting = useRecoilComponentValue(
const viewPickerIsPersisting = useRecoilComponentValueV2(
viewPickerIsPersistingComponentState,
);
@@ -1,4 +1,4 @@
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { ViewType } from '@/views/types/ViewType';
import { useCreateViewFromCurrentState } from '@/views/view-picker/hooks/useCreateViewFromCurrentState';
import { useDestroyViewFromCurrentState } from '@/views/view-picker/hooks/useDestroyViewFromCurrentState';
@@ -20,14 +20,16 @@ export const ViewPickerCreateButton = () => {
useGetAvailableFieldsForCalendar();
const { viewPickerMode } = useViewPickerMode();
const viewPickerType = useRecoilComponentValue(viewPickerTypeComponentState);
const viewPickerIsPersisting = useRecoilComponentValue(
const viewPickerType = useRecoilComponentValueV2(
viewPickerTypeComponentState,
);
const viewPickerIsPersisting = useRecoilComponentValueV2(
viewPickerIsPersistingComponentState,
);
const viewPickerMainGroupByFieldMetadataId = useRecoilComponentValue(
const viewPickerMainGroupByFieldMetadataId = useRecoilComponentValueV2(
viewPickerMainGroupByFieldMetadataIdComponentState,
);
const viewPickerCalendarFieldMetadataId = useRecoilComponentValue(
const viewPickerCalendarFieldMetadataId = useRecoilComponentValueV2(
viewPickerCalendarFieldMetadataIdComponentState,
);
@@ -1,4 +1,4 @@
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { ViewType } from '@/views/types/ViewType';
import { useCreateViewFromCurrentState } from '@/views/view-picker/hooks/useCreateViewFromCurrentState';
import { useDestroyViewFromCurrentState } from '@/views/view-picker/hooks/useDestroyViewFromCurrentState';
@@ -15,11 +15,13 @@ export const ViewPickerEditButton = () => {
useGetAvailableFieldsToGroupRecordsBy();
const { viewPickerMode } = useViewPickerMode();
const viewPickerType = useRecoilComponentValue(viewPickerTypeComponentState);
const viewPickerIsPersisting = useRecoilComponentValue(
const viewPickerType = useRecoilComponentValueV2(
viewPickerTypeComponentState,
);
const viewPickerIsPersisting = useRecoilComponentValueV2(
viewPickerIsPersistingComponentState,
);
const viewPickerMainGroupByFieldMetadataId = useRecoilComponentValue(
const viewPickerMainGroupByFieldMetadataId = useRecoilComponentValueV2(
viewPickerMainGroupByFieldMetadataIdComponentState,
);
@@ -1,14 +1,14 @@
import { FavoriteFolderPicker } from '@/favorites/favorite-folder-picker/components/FavoriteFolderPicker';
import { FavoriteFolderPickerEffect } from '@/favorites/favorite-folder-picker/components/FavoriteFolderPickerEffect';
import { FavoriteFolderPickerInstanceContext } from '@/favorites/favorite-folder-picker/states/context/FavoriteFolderPickerInstanceContext';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
import { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
import { VIEW_PICKER_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerDropdownId';
import { viewPickerReferenceViewIdComponentState } from '@/views/view-picker/states/viewPickerReferenceViewIdComponentState';
export const ViewPickerFavoriteFoldersDropdown = () => {
const [viewPickerReferenceViewId] = useRecoilComponentState(
const [viewPickerReferenceViewId] = useRecoilComponentStateV2(
viewPickerReferenceViewIdComponentState,
);
@@ -10,7 +10,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { DropdownMenuSectionLabel } from '@/ui/layout/dropdown/components/DropdownMenuSectionLabel';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
import { usePerformViewAPIUpdate } from '@/views/hooks/internal/usePerformViewAPIUpdate';
import { useChangeView } from '@/views/hooks/useChangeView';
@@ -54,7 +54,7 @@ export const ViewPickerListContent = () => {
const { currentView } = useGetCurrentViewOnly();
const setViewPickerReferenceViewId = useSetRecoilComponentState(
const setViewPickerReferenceViewId = useSetRecoilComponentStateV2(
viewPickerReferenceViewIdComponentState,
);
@@ -6,7 +6,7 @@ import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { MenuItemWithOptionDropdown } from '@/ui/navigation/menu-item/components/MenuItemWithOptionDropdown';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { type View } from '@/views/types/View';
import { useDestroyViewFromCurrentState } from '@/views/view-picker/hooks/useDestroyViewFromCurrentState';
import { useViewPickerMode } from '@/views/view-picker/hooks/useViewPickerMode';
@@ -54,7 +54,7 @@ export const ViewPickerOptionDropdown = ({
const { closeDropdown } = useCloseDropdown();
const { getIcon } = useIcons();
const { destroyViewFromCurrentState } = useDestroyViewFromCurrentState();
const setViewPickerReferenceViewId = useSetRecoilComponentState(
const setViewPickerReferenceViewId = useSetRecoilComponentStateV2(
viewPickerReferenceViewIdComponentState,
);
const { setViewPickerMode } = useViewPickerMode();
@@ -7,7 +7,6 @@ import { renderHook } from '@testing-library/react';
import { type ReactNode } from 'react';
import { Provider as JotaiProvider } from 'jotai';
import { MemoryRouter } from 'react-router-dom';
import { RecoilRoot } from 'recoil';
import { FieldMetadataType } from '~/generated-metadata/graphql';
const mockObjectMetadataId = 'test-object-id';
@@ -24,26 +23,21 @@ const createMockObjectMetadataItem = (fields: any[]) => ({
const createWrapper = (objectMetadataItems: any[]) => {
return ({ children }: { children: ReactNode }) => {
jotaiStore.set(objectMetadataItemsState.atom, objectMetadataItems);
jotaiStore.set(
viewObjectMetadataIdComponentState.atomFamily({
instanceId: mockViewInstanceId,
}),
mockObjectMetadataId,
);
return (
<JotaiProvider store={jotaiStore}>
<RecoilRoot
initializeState={(snapshot) => {
snapshot.set(
viewObjectMetadataIdComponentState.atomFamily({
instanceId: mockViewInstanceId,
}),
mockObjectMetadataId,
);
}}
>
<MemoryRouter>
<ViewComponentInstanceContext.Provider
value={{ instanceId: mockViewInstanceId }}
>
{children}
</ViewComponentInstanceContext.Provider>
</MemoryRouter>
</RecoilRoot>
<MemoryRouter>
<ViewComponentInstanceContext.Provider
value={{ instanceId: mockViewInstanceId }}
>
{children}
</ViewComponentInstanceContext.Provider>
</MemoryRouter>
</JotaiProvider>
);
};
@@ -7,7 +7,6 @@ import { renderHook } from '@testing-library/react';
import { type ReactNode } from 'react';
import { Provider as JotaiProvider } from 'jotai';
import { MemoryRouter } from 'react-router-dom';
import { RecoilRoot } from 'recoil';
import { FieldMetadataType } from '~/generated-metadata/graphql';
const mockObjectMetadataId = 'test-object-id';
@@ -24,26 +23,21 @@ const createMockObjectMetadataItem = (fields: any[]) => ({
const createWrapper = (objectMetadataItems: any[]) => {
return ({ children }: { children: ReactNode }) => {
jotaiStore.set(objectMetadataItemsState.atom, objectMetadataItems);
jotaiStore.set(
viewObjectMetadataIdComponentState.atomFamily({
instanceId: mockViewInstanceId,
}),
mockObjectMetadataId,
);
return (
<JotaiProvider store={jotaiStore}>
<RecoilRoot
initializeState={(snapshot) => {
snapshot.set(
viewObjectMetadataIdComponentState.atomFamily({
instanceId: mockViewInstanceId,
}),
mockObjectMetadataId,
);
}}
>
<MemoryRouter>
<ViewComponentInstanceContext.Provider
value={{ instanceId: mockViewInstanceId }}
>
{children}
</ViewComponentInstanceContext.Provider>
</MemoryRouter>
</RecoilRoot>
<MemoryRouter>
<ViewComponentInstanceContext.Provider
value={{ instanceId: mockViewInstanceId }}
>
{children}
</ViewComponentInstanceContext.Provider>
</MemoryRouter>
</JotaiProvider>
);
};
@@ -1,7 +1,7 @@
import { useCallback } from 'react';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { VIEW_PICKER_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerDropdownId';
import { VIEW_PICKER_KANBAN_FIELD_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerKanbanFieldDropdownId';
import { VIEW_PICKER_VIEW_TYPE_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerViewTypeDropdownId';
@@ -9,11 +9,11 @@ import { viewPickerIsPersistingComponentState } from '@/views/view-picker/states
import { viewPickerModeComponentState } from '@/views/view-picker/states/viewPickerModeComponentState';
export const useCloseAndResetViewPicker = () => {
const setViewPickerMode = useSetRecoilComponentState(
const setViewPickerMode = useSetRecoilComponentStateV2(
viewPickerModeComponentState,
);
const setViewPickerIsPersisting = useSetRecoilComponentState(
const setViewPickerIsPersisting = useSetRecoilComponentStateV2(
viewPickerIsPersistingComponentState,
);
@@ -1,5 +1,4 @@
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 { useChangeView } from '@/views/hooks/useChangeView';
import { useCreateViewFromCurrentView } from '@/views/hooks/useCreateViewFromCurrentView';
import { ViewType } from '@/views/types/ViewType';
@@ -13,122 +12,108 @@ import { viewPickerModeComponentState } from '@/views/view-picker/states/viewPic
import { viewPickerSelectedIconComponentState } from '@/views/view-picker/states/viewPickerSelectedIconComponentState';
import { viewPickerTypeComponentState } from '@/views/view-picker/states/viewPickerTypeComponentState';
import { viewPickerVisibilityComponentState } from '@/views/view-picker/states/viewPickerVisibilityComponentState';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { isDefined } from 'twenty-shared/utils';
export const useCreateViewFromCurrentState = () => {
const { closeAndResetViewPicker } = useCloseAndResetViewPicker();
const viewPickerInputNameCallbackState = useRecoilComponentCallbackState(
viewPickerInputNameComponentState,
);
const viewPickerInputNameCallbackState =
useRecoilComponentStateCallbackStateV2(viewPickerInputNameComponentState);
const viewPickerSelectedIconCallbackState = useRecoilComponentCallbackState(
viewPickerSelectedIconComponentState,
);
const viewPickerSelectedIconCallbackState =
useRecoilComponentStateCallbackStateV2(
viewPickerSelectedIconComponentState,
);
const viewPickerTypeCallbackState = useRecoilComponentCallbackState(
const viewPickerTypeCallbackState = useRecoilComponentStateCallbackStateV2(
viewPickerTypeComponentState,
);
const viewPickerMainGroupByFieldMetadataIdCallbackState =
useRecoilComponentCallbackState(
useRecoilComponentStateCallbackStateV2(
viewPickerMainGroupByFieldMetadataIdComponentState,
);
const viewPickerCalendarFieldMetadataIdCallbackState =
useRecoilComponentCallbackState(
useRecoilComponentStateCallbackStateV2(
viewPickerCalendarFieldMetadataIdComponentState,
);
const viewPickerIsPersistingCallbackState = useRecoilComponentCallbackState(
viewPickerIsPersistingComponentState,
);
const viewPickerIsPersistingCallbackState =
useRecoilComponentStateCallbackStateV2(
viewPickerIsPersistingComponentState,
);
const viewPickerIsDirtyCallbackState = useRecoilComponentCallbackState(
const viewPickerIsDirtyCallbackState = useRecoilComponentStateCallbackStateV2(
viewPickerIsDirtyComponentState,
);
const viewPickerModeCallbackState = useRecoilComponentCallbackState(
const viewPickerModeCallbackState = useRecoilComponentStateCallbackStateV2(
viewPickerModeComponentState,
);
const viewPickerVisibilityCallbackState = useRecoilComponentCallbackState(
viewPickerVisibilityComponentState,
);
const viewPickerVisibilityCallbackState =
useRecoilComponentStateCallbackStateV2(viewPickerVisibilityComponentState);
const { createViewFromCurrentView } = useCreateViewFromCurrentView();
const { changeView } = useChangeView();
const createViewFromCurrentState = useRecoilCallback(
({ snapshot, set }) =>
async () => {
const name = getSnapshotValue(
snapshot,
viewPickerInputNameCallbackState,
);
const iconKey = getSnapshotValue(
snapshot,
viewPickerSelectedIconCallbackState,
);
const type = getSnapshotValue(snapshot, viewPickerTypeCallbackState);
const mainGroupByFieldMetadataId = getSnapshotValue(
snapshot,
viewPickerMainGroupByFieldMetadataIdCallbackState,
);
const calendarFieldMetadataId = getSnapshotValue(
snapshot,
viewPickerCalendarFieldMetadataIdCallbackState,
);
const store = useStore();
const viewPickerMode = getSnapshotValue(
snapshot,
viewPickerModeCallbackState,
);
const visibility = getSnapshotValue(
snapshot,
viewPickerVisibilityCallbackState,
);
const shouldCopyFiltersAndSortsAndAggregate =
viewPickerMode === 'create-from-current';
set(viewPickerIsPersistingCallbackState, true);
set(viewPickerIsDirtyCallbackState, false);
const createdViewId = await createViewFromCurrentView(
{
name,
icon: iconKey,
type,
mainGroupByFieldMetadataId:
type === ViewType.Kanban ? mainGroupByFieldMetadataId : null,
calendarFieldMetadataId,
visibility,
},
shouldCopyFiltersAndSortsAndAggregate,
);
if (isDefined(createdViewId)) {
closeAndResetViewPicker();
changeView(createdViewId);
}
},
[
closeAndResetViewPicker,
createViewFromCurrentView,
changeView,
viewPickerInputNameCallbackState,
viewPickerIsDirtyCallbackState,
viewPickerIsPersistingCallbackState,
const createViewFromCurrentState = useCallback(async () => {
const name = store.get(viewPickerInputNameCallbackState);
const iconKey = store.get(viewPickerSelectedIconCallbackState);
const type = store.get(viewPickerTypeCallbackState);
const mainGroupByFieldMetadataId = store.get(
viewPickerMainGroupByFieldMetadataIdCallbackState,
);
const calendarFieldMetadataId = store.get(
viewPickerCalendarFieldMetadataIdCallbackState,
viewPickerSelectedIconCallbackState,
viewPickerTypeCallbackState,
viewPickerModeCallbackState,
viewPickerVisibilityCallbackState,
],
);
);
const viewPickerMode = store.get(viewPickerModeCallbackState);
const visibility = store.get(viewPickerVisibilityCallbackState);
const shouldCopyFiltersAndSortsAndAggregate =
viewPickerMode === 'create-from-current';
store.set(viewPickerIsPersistingCallbackState, true);
store.set(viewPickerIsDirtyCallbackState, false);
const createdViewId = await createViewFromCurrentView(
{
name,
icon: iconKey,
type,
mainGroupByFieldMetadataId:
type === ViewType.Kanban ? mainGroupByFieldMetadataId : null,
calendarFieldMetadataId,
visibility,
},
shouldCopyFiltersAndSortsAndAggregate,
);
if (isDefined(createdViewId)) {
closeAndResetViewPicker();
changeView(createdViewId);
}
}, [
store,
closeAndResetViewPicker,
createViewFromCurrentView,
changeView,
viewPickerInputNameCallbackState,
viewPickerIsDirtyCallbackState,
viewPickerIsPersistingCallbackState,
viewPickerMainGroupByFieldMetadataIdCallbackState,
viewPickerCalendarFieldMetadataIdCallbackState,
viewPickerSelectedIconCallbackState,
viewPickerTypeCallbackState,
viewPickerModeCallbackState,
viewPickerVisibilityCallbackState,
]);
return { createViewFromCurrentState };
};
@@ -1,15 +1,14 @@
import { useRecoilCallback } from 'recoil';
import { useCallback } from 'react';
import { useStore } from 'jotai';
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { usePerformViewAPIPersist } from '@/views/hooks/internal/usePerformViewAPIPersist';
import { useChangeView } from '@/views/hooks/useChangeView';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { coreViewsByObjectMetadataIdFamilySelector } from '@/views/states/selectors/coreViewsByObjectMetadataIdFamilySelector';
import { coreViewsFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/coreViewsFromObjectMetadataItemFamilySelector';
import { useStore } from 'jotai';
import { useCloseAndResetViewPicker } from '@/views/view-picker/hooks/useCloseAndResetViewPicker';
import { viewPickerIsDirtyComponentState } from '@/views/view-picker/states/viewPickerIsDirtyComponentState';
import { viewPickerIsPersistingComponentState } from '@/views/view-picker/states/viewPickerIsPersistingComponentState';
@@ -18,18 +17,19 @@ import { viewPickerReferenceViewIdComponentState } from '@/views/view-picker/sta
export const useDestroyViewFromCurrentState = (viewBarInstanceId?: string) => {
const { closeAndResetViewPicker } = useCloseAndResetViewPicker();
const viewPickerIsPersistingCallbackState = useRecoilComponentCallbackState(
viewPickerIsPersistingComponentState,
viewBarInstanceId,
);
const viewPickerIsPersistingCallbackState =
useRecoilComponentStateCallbackStateV2(
viewPickerIsPersistingComponentState,
viewBarInstanceId,
);
const viewPickerIsDirtyCallbackState = useRecoilComponentCallbackState(
const viewPickerIsDirtyCallbackState = useRecoilComponentStateCallbackStateV2(
viewPickerIsDirtyComponentState,
viewBarInstanceId,
);
const viewPickerReferenceViewIdCallbackState =
useRecoilComponentCallbackState(
useRecoilComponentStateCallbackStateV2(
viewPickerReferenceViewIdComponentState,
viewBarInstanceId,
);
@@ -49,51 +49,45 @@ export const useDestroyViewFromCurrentState = (viewBarInstanceId?: string) => {
const store = useStore();
const destroyViewFromCurrentState = useRecoilCallback(
({ set, snapshot }) =>
async () => {
set(viewPickerIsPersistingCallbackState, true);
closeAndResetViewPicker();
set(viewPickerIsDirtyCallbackState, false);
const destroyViewFromCurrentState = useCallback(async () => {
store.set(viewPickerIsPersistingCallbackState, true);
closeAndResetViewPicker();
store.set(viewPickerIsDirtyCallbackState, false);
const viewPickerReferenceViewId = getSnapshotValue(
snapshot,
viewPickerReferenceViewIdCallbackState,
);
const shouldChangeView = viewPickerReferenceViewId === currentView?.id;
if (shouldChangeView) {
changeView(
viewsOnCurrentObject.filter(
(view) => view.id !== viewPickerReferenceViewId,
)[0].id,
);
}
store.set(
coreViewsByObjectMetadataIdFamilySelector.selectorFamily(
objectMetadataItem.id,
),
(views) =>
views.filter((view) => view.id !== viewPickerReferenceViewId),
);
await performViewAPIDestroy({ id: viewPickerReferenceViewId });
},
[
currentView,
closeAndResetViewPicker,
objectMetadataItem.id,
changeView,
performViewAPIDestroy,
store,
viewPickerIsDirtyCallbackState,
viewPickerIsPersistingCallbackState,
const viewPickerReferenceViewId = store.get(
viewPickerReferenceViewIdCallbackState,
viewsOnCurrentObject,
],
);
);
const shouldChangeView = viewPickerReferenceViewId === currentView?.id;
if (shouldChangeView) {
changeView(
viewsOnCurrentObject.filter(
(view) => view.id !== viewPickerReferenceViewId,
)[0].id,
);
}
store.set(
coreViewsByObjectMetadataIdFamilySelector.selectorFamily(
objectMetadataItem.id,
),
(views) => views.filter((view) => view.id !== viewPickerReferenceViewId),
);
await performViewAPIDestroy({ id: viewPickerReferenceViewId });
}, [
currentView,
closeAndResetViewPicker,
objectMetadataItem.id,
changeView,
performViewAPIDestroy,
store,
viewPickerIsDirtyCallbackState,
viewPickerIsPersistingCallbackState,
viewPickerReferenceViewIdCallbackState,
viewsOnCurrentObject,
]);
return {
destroyViewFromCurrentState,
@@ -4,7 +4,7 @@ import { useLocation } from 'react-router-dom';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { viewObjectMetadataIdComponentState } from '@/views/states/viewObjectMetadataIdComponentState';
import { FieldMetadataType, SettingsPath } from 'twenty-shared/types';
@@ -12,7 +12,7 @@ import { isDefined, isFieldMetadataDateKind } from 'twenty-shared/utils';
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
export const useGetAvailableFieldsForCalendar = () => {
const viewObjectMetadataId = useRecoilComponentValue(
const viewObjectMetadataId = useRecoilComponentValueV2(
viewObjectMetadataIdComponentState,
);
const objectMetadataItems = useRecoilValueV2(objectMetadataItemsState);
@@ -4,7 +4,7 @@ import { useLocation } from 'react-router-dom';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { viewObjectMetadataIdComponentState } from '@/views/states/viewObjectMetadataIdComponentState';
import { SettingsPath } from 'twenty-shared/types';
@@ -13,7 +13,7 @@ import { FieldMetadataType } from '~/generated-metadata/graphql';
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
export const useGetAvailableFieldsToGroupRecordsBy = () => {
const viewObjectMetadataId = useRecoilComponentValue(
const viewObjectMetadataId = useRecoilComponentValueV2(
viewObjectMetadataIdComponentState,
);
const objectMetadataItems = useRecoilValueV2(objectMetadataItemsState);
@@ -1,5 +1,7 @@
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { useCallback } from 'react';
import { useStore } from 'jotai';
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
import { usePerformViewAPIUpdate } from '@/views/hooks/internal/usePerformViewAPIUpdate';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useCloseAndResetViewPicker } from '@/views/view-picker/hooks/useCloseAndResetViewPicker';
@@ -9,87 +11,79 @@ import { viewPickerIsPersistingComponentState } from '@/views/view-picker/states
import { viewPickerReferenceViewIdComponentState } from '@/views/view-picker/states/viewPickerReferenceViewIdComponentState';
import { viewPickerSelectedIconComponentState } from '@/views/view-picker/states/viewPickerSelectedIconComponentState';
import { viewPickerVisibilityComponentState } from '@/views/view-picker/states/viewPickerVisibilityComponentState';
import { useRecoilCallback } from 'recoil';
export const useUpdateViewFromCurrentState = () => {
const { canPersistChanges } = useCanPersistViewChanges();
const { closeAndResetViewPicker } = useCloseAndResetViewPicker();
const viewPickerInputNameCallbackState = useRecoilComponentCallbackState(
viewPickerInputNameComponentState,
);
const viewPickerInputNameCallbackState =
useRecoilComponentStateCallbackStateV2(viewPickerInputNameComponentState);
const viewPickerSelectedIconCallbackState = useRecoilComponentCallbackState(
viewPickerSelectedIconComponentState,
);
const viewPickerSelectedIconCallbackState =
useRecoilComponentStateCallbackStateV2(
viewPickerSelectedIconComponentState,
);
const viewPickerIsPersistingCallbackState = useRecoilComponentCallbackState(
viewPickerIsPersistingComponentState,
);
const viewPickerIsPersistingCallbackState =
useRecoilComponentStateCallbackStateV2(
viewPickerIsPersistingComponentState,
);
const viewPickerIsDirtyCallbackState = useRecoilComponentCallbackState(
const viewPickerIsDirtyCallbackState = useRecoilComponentStateCallbackStateV2(
viewPickerIsDirtyComponentState,
);
const viewPickerReferenceViewIdCallbackState =
useRecoilComponentCallbackState(viewPickerReferenceViewIdComponentState);
useRecoilComponentStateCallbackStateV2(
viewPickerReferenceViewIdComponentState,
);
const viewPickerVisibilityCallbackState = useRecoilComponentCallbackState(
viewPickerVisibilityComponentState,
);
const viewPickerVisibilityCallbackState =
useRecoilComponentStateCallbackStateV2(viewPickerVisibilityComponentState);
const { performViewAPIUpdate } = usePerformViewAPIUpdate();
const updateViewFromCurrentState = useRecoilCallback(
({ set, snapshot }) =>
async () => {
if (!canPersistChanges) {
closeAndResetViewPicker();
return;
}
const store = useStore();
set(viewPickerIsPersistingCallbackState, true);
set(viewPickerIsDirtyCallbackState, false);
closeAndResetViewPicker();
const updateViewFromCurrentState = useCallback(async () => {
if (!canPersistChanges) {
closeAndResetViewPicker();
return;
}
const viewPickerReferenceViewId = getSnapshotValue(
snapshot,
viewPickerReferenceViewIdCallbackState,
);
const viewPickerInputName = getSnapshotValue(
snapshot,
viewPickerInputNameCallbackState,
);
const viewPickerSelectedIcon = getSnapshotValue(
snapshot,
viewPickerSelectedIconCallbackState,
);
const visibility = getSnapshotValue(
snapshot,
viewPickerVisibilityCallbackState,
);
store.set(viewPickerIsPersistingCallbackState, true);
store.set(viewPickerIsDirtyCallbackState, false);
closeAndResetViewPicker();
await performViewAPIUpdate({
id: viewPickerReferenceViewId,
input: {
name: viewPickerInputName,
icon: viewPickerSelectedIcon,
visibility: visibility,
},
});
},
[
canPersistChanges,
viewPickerIsPersistingCallbackState,
viewPickerIsDirtyCallbackState,
closeAndResetViewPicker,
const viewPickerReferenceViewId = store.get(
viewPickerReferenceViewIdCallbackState,
viewPickerInputNameCallbackState,
);
const viewPickerInputName = store.get(viewPickerInputNameCallbackState);
const viewPickerSelectedIcon = store.get(
viewPickerSelectedIconCallbackState,
viewPickerVisibilityCallbackState,
performViewAPIUpdate,
],
);
);
const visibility = store.get(viewPickerVisibilityCallbackState);
await performViewAPIUpdate({
id: viewPickerReferenceViewId,
input: {
name: viewPickerInputName,
icon: viewPickerSelectedIcon,
visibility: visibility,
},
});
}, [
canPersistChanges,
viewPickerIsPersistingCallbackState,
viewPickerIsDirtyCallbackState,
closeAndResetViewPicker,
viewPickerReferenceViewIdCallbackState,
viewPickerInputNameCallbackState,
viewPickerSelectedIconCallbackState,
viewPickerVisibilityCallbackState,
performViewAPIUpdate,
store,
]);
return {
updateViewFromCurrentState,
@@ -1,8 +1,8 @@
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
import { viewPickerModeComponentState } from '@/views/view-picker/states/viewPickerModeComponentState';
export const useViewPickerMode = (viewBarComponentId?: string) => {
const [viewPickerMode, setViewPickerMode] = useRecoilComponentState(
const [viewPickerMode, setViewPickerMode] = useRecoilComponentStateV2(
viewPickerModeComponentState,
viewBarComponentId,
);
@@ -1,8 +1,8 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
export const viewPickerCalendarFieldMetadataIdComponentState =
createComponentState<string>({
createComponentStateV2<string>({
key: 'viewPickerCalendarFieldMetadataIdComponentState',
defaultValue: '',
componentInstanceContext: ViewComponentInstanceContext,
@@ -1,8 +1,10 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
export const viewPickerInputNameComponentState = createComponentState<string>({
key: 'viewPickerInputNameComponentState',
defaultValue: '',
componentInstanceContext: ViewComponentInstanceContext,
});
export const viewPickerInputNameComponentState = createComponentStateV2<string>(
{
key: 'viewPickerInputNameComponentState',
defaultValue: '',
componentInstanceContext: ViewComponentInstanceContext,
},
);
@@ -1,7 +1,7 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
export const viewPickerIsDirtyComponentState = createComponentState<boolean>({
export const viewPickerIsDirtyComponentState = createComponentStateV2<boolean>({
key: 'viewPickerIsDirtyComponentState',
defaultValue: false,
componentInstanceContext: ViewComponentInstanceContext,
@@ -1,8 +1,8 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
export const viewPickerIsPersistingComponentState =
createComponentState<boolean>({
createComponentStateV2<boolean>({
key: 'viewPickerIsPersistingComponentState',
defaultValue: false,
componentInstanceContext: ViewComponentInstanceContext,
@@ -1,8 +1,8 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
export const viewPickerMainGroupByFieldMetadataIdComponentState =
createComponentState<string>({
createComponentStateV2<string>({
key: 'viewPickerMainGroupByFieldMetadataIdComponentState',
defaultValue: '',
componentInstanceContext: ViewComponentInstanceContext,
@@ -1,9 +1,9 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
import { type ViewPickerMode } from '@/views/view-picker/types/ViewPickerMode';
export const viewPickerModeComponentState =
createComponentState<ViewPickerMode>({
createComponentStateV2<ViewPickerMode>({
key: 'viewPickerModeComponentState',
defaultValue: 'list',
componentInstanceContext: ViewComponentInstanceContext,
@@ -1,8 +1,8 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
export const viewPickerReferenceViewIdComponentState =
createComponentState<string>({
createComponentStateV2<string>({
key: 'viewPickerReferenceViewIdComponentState',
defaultValue: '',
componentInstanceContext: ViewComponentInstanceContext,
@@ -1,8 +1,8 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
export const viewPickerSelectedIconComponentState =
createComponentState<string>({
createComponentStateV2<string>({
key: 'viewPickerSelectedIconComponentState',
defaultValue: '',
componentInstanceContext: ViewComponentInstanceContext,
@@ -1,8 +1,8 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
import { ViewType } from '@/views/types/ViewType';
export const viewPickerTypeComponentState = createComponentState<ViewType>({
export const viewPickerTypeComponentState = createComponentStateV2<ViewType>({
key: 'viewPickerTypeComponentState',
defaultValue: ViewType.Table,
componentInstanceContext: ViewComponentInstanceContext,
@@ -1,9 +1,9 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
import { ViewVisibility } from '~/generated-metadata/graphql';
export const viewPickerVisibilityComponentState =
createComponentState<ViewVisibility>({
createComponentStateV2<ViewVisibility>({
key: 'viewPickerVisibilityComponentState',
defaultValue: ViewVisibility.UNLISTED,
componentInstanceContext: ViewComponentInstanceContext,