diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleRecordGroupField.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleRecordGroupField.ts
index 58a3543b5d1..473a62d7287 100644
--- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleRecordGroupField.ts
+++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleRecordGroupField.ts
@@ -4,7 +4,7 @@ import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataIte
import { useSetRecordGroups } from '@/object-record/record-group/hooks/useSetRecordGroups';
import { useLoadRecordIndexStates } from '@/object-record/record-index/hooks/useLoadRecordIndexStates';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
-import { usePersistView } from '@/views/hooks/internal/usePersistView';
+import { usePerformViewAPIUpdate } from '@/views/hooks/internal/usePerformViewAPIUpdate';
import { useGetViewFromPrefetchState } from '@/views/hooks/useGetViewFromPrefetchState';
import { useRefreshCoreViewsByObjectMetadataId } from '@/views/hooks/useRefreshCoreViewsByObjectMetadataId';
import { type ViewGroup } from '@/views/types/ViewGroup';
@@ -26,7 +26,7 @@ export const useHandleRecordGroupField = () => {
const { setRecordGroupsFromViewGroups } = useSetRecordGroups();
- const { updateView } = usePersistView();
+ const { performViewAPIUpdate } = usePerformViewAPIUpdate();
const { loadRecordIndexStates } = useLoadRecordIndexStates();
const { refreshCoreViewsByObjectMetadataId } =
useRefreshCoreViewsByObjectMetadataId();
@@ -55,7 +55,7 @@ export const useHandleRecordGroupField = () => {
return;
}
- const updatedViewResult = await updateView({
+ const updatedViewResult = await performViewAPIUpdate({
id: view.id,
input: {
mainGroupByFieldMetadataId: fieldMetadataItem.id,
@@ -133,7 +133,7 @@ export const useHandleRecordGroupField = () => {
[
currentViewIdCallbackState,
getViewFromPrefetchState,
- updateView,
+ performViewAPIUpdate,
setRecordGroupsFromViewGroups,
objectMetadataItem,
refreshCoreViewsByObjectMetadataId,
@@ -162,14 +162,18 @@ export const useHandleRecordGroupField = () => {
return;
}
- await updateView({
+ await performViewAPIUpdate({
id: view.id,
input: {
mainGroupByFieldMetadataId: null,
},
});
},
- [currentViewIdCallbackState, getViewFromPrefetchState, updateView],
+ [
+ currentViewIdCallbackState,
+ getViewFromPrefetchState,
+ performViewAPIUpdate,
+ ],
);
return { handleRecordGroupFieldChange, resetRecordGroupField };
diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useViewFieldAggregateOperation.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useViewFieldAggregateOperation.tsx
index 66bb50a250c..717ed5dd337 100644
--- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useViewFieldAggregateOperation.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useViewFieldAggregateOperation.tsx
@@ -3,7 +3,7 @@ import { RecordTableColumnAggregateFooterDropdownContext } from '@/object-record
import { viewFieldAggregateOperationState } from '@/object-record/record-table/record-table-footer/states/viewFieldAggregateOperationState';
import { type ExtendedAggregateOperations } from '@/object-record/record-table/types/ExtendedAggregateOperations';
import { convertExtendedAggregateOperationToAggregateOperation } from '@/object-record/utils/convertExtendedAggregateOperationToAggregateOperation';
-import { usePersistViewField } from '@/views/hooks/internal/usePersistViewField';
+import { usePerformViewFieldAPIPersist } from '@/views/hooks/internal/usePerformViewFieldAPIPersist';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { useRefreshCoreViewsByObjectMetadataId } from '@/views/hooks/useRefreshCoreViewsByObjectMetadataId';
import { useContext } from 'react';
@@ -24,14 +24,14 @@ export const useViewFieldAggregateOperation = () => {
useRefreshCoreViewsByObjectMetadataId();
const { objectMetadataItem } = useRecordIndexContextOrThrow();
- const { updateViewFields } = usePersistViewField();
+ const { performViewFieldAPIUpdate } = usePerformViewFieldAPIPersist();
const updateViewFieldAggregateOperation = async (
aggregateOperation: ExtendedAggregateOperations | null,
) => {
if (!currentViewField) {
throw new Error('ViewField not found');
}
- await updateViewFields([
+ await performViewFieldAPIUpdate([
{
input: {
id: currentViewField.id,
diff --git a/packages/twenty-front/src/modules/ui/input/components/IconPicker.tsx b/packages/twenty-front/src/modules/ui/input/components/IconPicker.tsx
index f963294ff79..408c00f846e 100644
--- a/packages/twenty-front/src/modules/ui/input/components/IconPicker.tsx
+++ b/packages/twenty-front/src/modules/ui/input/components/IconPicker.tsx
@@ -9,6 +9,8 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { arrayToChunks } from '~/utils/array/arrayToChunks';
import { ICON_PICKER_DROPDOWN_CONTENT_WIDTH } from '@/ui/input/components/constants/IconPickerDropdownContentWidth';
+import { IconPickerScrollEffect } from '@/ui/input/hooks/IconPickerScrollEffect';
+import { iconPickerVisibleCountState } from '@/ui/input/states/iconPickerVisibleCountState';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { type DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
@@ -25,8 +27,6 @@ import {
type IconButtonVariant,
LightIconButton,
} from 'twenty-ui/input';
-import { IconPickerScrollEffect } from '@/ui/input/hooks/IconPickerScrollEffect';
-import { iconPickerVisibleCountState } from '@/ui/input/states/iconPickerVisibleCountState';
export type IconPickerProps = {
disabled?: boolean;
@@ -86,7 +86,7 @@ const convertIconKeyToLabel = (iconKey: string) =>
type IconPickerIconProps = {
iconKey: string;
- onClick: () => void;
+ onSelect: () => void;
selectedIconKey?: string;
Icon: IconComponent;
focusedIconKey?: string;
@@ -94,7 +94,7 @@ type IconPickerIconProps = {
const IconPickerIcon = ({
iconKey,
- onClick,
+ onSelect,
selectedIconKey,
Icon,
focusedIconKey,
@@ -106,7 +106,7 @@ const IconPickerIcon = ({
return (
-
+
@@ -301,7 +301,7 @@ export const IconPicker = ({
{
+ onSelect={() => {
onChange({ iconKey, Icon: getIcon(iconKey) });
closeDropdown(dropdownId);
}}
diff --git a/packages/twenty-front/src/modules/ui/layout/resizable-panel/components/ResizablePanelEdge.tsx b/packages/twenty-front/src/modules/ui/layout/resizable-panel/components/ResizablePanelEdge.tsx
index b3e648d8a7b..7c75379d585 100644
--- a/packages/twenty-front/src/modules/ui/layout/resizable-panel/components/ResizablePanelEdge.tsx
+++ b/packages/twenty-front/src/modules/ui/layout/resizable-panel/components/ResizablePanelEdge.tsx
@@ -19,7 +19,7 @@ const StyledEdge = styled.div`
side === 'right' ? 'right' : 'left'}: -${RESIZE_EDGE_WIDTH_PX / 2}px;
width: ${RESIZE_EDGE_WIDTH_PX}px;
cursor: col-resize;
- z-index: 100;
+
display: flex;
align-items: center;
justify-content: center;
diff --git a/packages/twenty-front/src/modules/views/hooks/internal/usePersistView.ts b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
similarity index 76%
rename from packages/twenty-front/src/modules/views/hooks/internal/usePersistView.ts
rename to packages/twenty-front/src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
index 700c6b67263..a9a6f1eb602 100644
--- a/packages/twenty-front/src/modules/views/hooks/internal/usePersistView.ts
+++ b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
@@ -12,16 +12,13 @@ import { v4 } from 'uuid';
import {
type CreateCoreViewMutationVariables,
type DestroyCoreViewMutationVariables,
- type UpdateCoreViewMutationVariables,
useCreateCoreViewMutation,
useDestroyCoreViewMutation,
- useUpdateCoreViewMutation,
ViewType,
} from '~/generated/graphql';
-export const usePersistView = () => {
+export const usePerformViewAPIPersist = () => {
const [createCoreViewMutation] = useCreateCoreViewMutation();
- const [updateCoreViewMutation] = useUpdateCoreViewMutation();
const [destroyCoreViewMutation] = useDestroyCoreViewMutation();
const { triggerViewGroupOptimisticEffectAtViewCreation } =
useViewsSideEffectsOnViewGroups();
@@ -29,7 +26,7 @@ export const usePersistView = () => {
const { handleMetadataError } = useMetadataErrorHandler();
const { enqueueErrorSnackBar } = useSnackBar();
- const createView = useCallback(
+ const performViewAPICreate = useCallback(
async (
variables: CreateCoreViewMutationVariables,
objectMetadataItemId: string,
@@ -93,41 +90,7 @@ export const usePersistView = () => {
],
);
- const updateView = useCallback(
- async (
- variables: UpdateCoreViewMutationVariables,
- ): Promise<
- MetadataRequestResult>>
- > => {
- try {
- const result = await updateCoreViewMutation({
- variables,
- });
-
- return {
- status: 'successful',
- response: result,
- };
- } catch (error) {
- if (error instanceof ApolloError) {
- handleMetadataError(error, {
- primaryMetadataName: 'view',
- operationType: CrudOperationType.UPDATE,
- });
- } else {
- enqueueErrorSnackBar({ message: t`An error occurred.` });
- }
-
- return {
- status: 'failed',
- error,
- };
- }
- },
- [updateCoreViewMutation, handleMetadataError, enqueueErrorSnackBar],
- );
-
- const destroyView = useCallback(
+ const performViewAPIDestroy = useCallback(
async (
variables: DestroyCoreViewMutationVariables,
): Promise<
@@ -162,8 +125,7 @@ export const usePersistView = () => {
);
return {
- createView,
- updateView,
- destroyView,
+ performViewAPICreate,
+ performViewAPIDestroy,
};
};
diff --git a/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewAPIUpdate.ts b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewAPIUpdate.ts
new file mode 100644
index 00000000000..3d51b024394
--- /dev/null
+++ b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewAPIUpdate.ts
@@ -0,0 +1,86 @@
+import { useCallback } from 'react';
+
+import { useMetadataErrorHandler } from '@/metadata-error-handler/hooks/useMetadataErrorHandler';
+import { type MetadataRequestResult } from '@/object-metadata/types/MetadataRequestResult.type';
+import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
+import { coreViewsState } from '@/views/states/coreViewState';
+import { ApolloError } from '@apollo/client';
+import { t } from '@lingui/core/macro';
+import { useSetRecoilState } from 'recoil';
+import { CrudOperationType } from 'twenty-shared/types';
+import { upsertPropertiesOfItemIntoArrayOfObjectsComparingId } from 'twenty-shared/utils';
+import {
+ type CoreView,
+ type UpdateCoreViewMutationVariables,
+ useUpdateCoreViewMutation,
+} from '~/generated/graphql';
+
+export const usePerformViewAPIUpdate = () => {
+ const [updateCoreViewMutation] = useUpdateCoreViewMutation();
+
+ const { handleMetadataError } = useMetadataErrorHandler();
+ const { enqueueErrorSnackBar } = useSnackBar();
+
+ const setCoreViews = useSetRecoilState(coreViewsState);
+
+ const performViewAPIUpdate = useCallback(
+ async (
+ variables: UpdateCoreViewMutationVariables,
+ ): Promise<
+ MetadataRequestResult>>
+ > => {
+ try {
+ setCoreViews((currentCoreViews) =>
+ upsertPropertiesOfItemIntoArrayOfObjectsComparingId(
+ currentCoreViews,
+ {
+ ...variables.input,
+ id: variables.id,
+ } as CoreView,
+ ),
+ );
+
+ const result = await updateCoreViewMutation({
+ variables,
+ });
+
+ setCoreViews((currentCoreViews) =>
+ upsertPropertiesOfItemIntoArrayOfObjectsComparingId(
+ currentCoreViews,
+ {
+ ...result.data?.updateCoreView,
+ id: variables.id,
+ } as CoreView,
+ ),
+ );
+
+ return {
+ status: 'successful',
+ response: result,
+ };
+ } catch (error) {
+ if (error instanceof ApolloError) {
+ handleMetadataError(error, {
+ primaryMetadataName: 'view',
+ operationType: CrudOperationType.UPDATE,
+ });
+ } else {
+ enqueueErrorSnackBar({ message: t`An error occurred.` });
+ }
+
+ return {
+ status: 'failed',
+ error,
+ };
+ }
+ },
+ [
+ setCoreViews,
+ updateCoreViewMutation,
+ handleMetadataError,
+ enqueueErrorSnackBar,
+ ],
+ );
+
+ return { performViewAPIUpdate };
+};
diff --git a/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewField.ts b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
similarity index 95%
rename from packages/twenty-front/src/modules/views/hooks/internal/usePersistViewField.ts
rename to packages/twenty-front/src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
index f8614fcb1ff..6932f6198c2 100644
--- a/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewField.ts
+++ b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
@@ -18,7 +18,7 @@ import {
useDestroyCoreViewFieldMutation,
useUpdateCoreViewFieldMutation,
} from '~/generated/graphql';
-export const usePersistViewField = () => {
+export const usePerformViewFieldAPIPersist = () => {
const { triggerViewFieldOptimisticEffect } =
useTriggerViewFieldOptimisticEffect();
@@ -31,7 +31,7 @@ export const usePersistViewField = () => {
const { handleMetadataError } = useMetadataErrorHandler();
const { enqueueErrorSnackBar } = useSnackBar();
- const createViewFields = useCallback(
+ const performViewFieldAPICreate = useCallback(
async (
createCoreViewFieldInputs: CreateManyCoreViewFieldsMutationVariables,
): Promise<
@@ -92,7 +92,7 @@ export const usePersistViewField = () => {
],
);
- const updateViewFields = useCallback(
+ const performViewFieldAPIUpdate = useCallback(
async (
createCoreViewFieldInputs: UpdateCoreViewFieldMutationVariables[],
): Promise<
@@ -154,7 +154,7 @@ export const usePersistViewField = () => {
],
);
- const deleteViewFields = useCallback(
+ const performViewFieldAPIDelete = useCallback(
async (
deleteCoreViewFieldInputs: DeleteCoreViewFieldMutationVariables[],
): Promise<
@@ -216,7 +216,7 @@ export const usePersistViewField = () => {
],
);
- const destroyViewFields = useCallback(
+ const performViewFieldAPIDestroy = useCallback(
async (
destroyCoreViewFieldInputs: DestroyCoreViewFieldMutationVariables[],
): Promise<
@@ -264,9 +264,9 @@ export const usePersistViewField = () => {
);
return {
- createViewFields,
- updateViewFields,
- deleteViewFields,
- destroyViewFields,
+ performViewFieldAPICreate,
+ performViewFieldAPIUpdate,
+ performViewFieldAPIDelete,
+ performViewFieldAPIDestroy,
};
};
diff --git a/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFilter.ts b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
similarity index 95%
rename from packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFilter.ts
rename to packages/twenty-front/src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
index ec61b7b3ee9..d7ea4734331 100644
--- a/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFilter.ts
+++ b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
@@ -19,7 +19,7 @@ import {
useUpdateCoreViewFilterMutation,
} from '~/generated/graphql';
-export const usePersistViewFilterRecords = () => {
+export const usePerformViewFilterAPIPersist = () => {
const { triggerViewFilterOptimisticEffect } =
useTriggerViewFilterOptimisticEffect();
const [createCoreViewFilterMutation] = useCreateCoreViewFilterMutation();
@@ -30,7 +30,7 @@ export const usePersistViewFilterRecords = () => {
const { handleMetadataError } = useMetadataErrorHandler();
const { enqueueErrorSnackBar } = useSnackBar();
- const createViewFilters = useCallback(
+ const performViewFilterAPICreate = useCallback(
async (
createCoreViewFilterInputs: CreateCoreViewFilterMutationVariables[],
): Promise<
@@ -92,7 +92,7 @@ export const usePersistViewFilterRecords = () => {
],
);
- const updateViewFilters = useCallback(
+ const performViewFilterAPIUpdate = useCallback(
async (
updateCoreViewFilterInputs: UpdateCoreViewFilterMutationVariables[],
): Promise<
@@ -154,7 +154,7 @@ export const usePersistViewFilterRecords = () => {
],
);
- const deleteViewFilters = useCallback(
+ const performViewFilterAPIDelete = useCallback(
async (
deleteCoreViewFilterInputs: DeleteCoreViewFilterMutationVariables[],
): Promise<
@@ -216,7 +216,7 @@ export const usePersistViewFilterRecords = () => {
],
);
- const destroyViewFilters = useCallback(
+ const performViewFilterAPIDestroy = useCallback(
async (
destroyCoreViewFilterInputs: DestroyCoreViewFilterMutationVariables[],
): Promise<
@@ -264,9 +264,9 @@ export const usePersistViewFilterRecords = () => {
);
return {
- createViewFilters,
- updateViewFilters,
- deleteViewFilters,
- destroyViewFilters,
+ performViewFilterAPICreate,
+ performViewFilterAPIUpdate,
+ performViewFilterAPIDelete,
+ performViewFilterAPIDestroy,
};
};
diff --git a/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFilterGroup.ts b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewFilterGroupAPIPersist.ts
similarity index 92%
rename from packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFilterGroup.ts
rename to packages/twenty-front/src/modules/views/hooks/internal/usePerformViewFilterGroupAPIPersist.ts
index b4e2282d9b2..2269d68710a 100644
--- a/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewFilterGroup.ts
+++ b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewFilterGroupAPIPersist.ts
@@ -9,7 +9,7 @@ import { useApolloClient } from '@apollo/client';
import { isDefined } from 'twenty-shared/utils';
import { type CoreViewFilterGroup } from '~/generated/graphql';
-export const usePersistViewFilterGroupRecords = () => {
+export const usePerformViewFilterGroupAPIPersist = () => {
const apolloClient = useApolloClient();
const createCoreViewFilterGroupRecord = useCallback(
@@ -39,7 +39,7 @@ export const usePersistViewFilterGroupRecords = () => {
[apolloClient],
);
- const createViewFilterGroups = useCallback(
+ const performViewFilterGroupAPICreate = useCallback(
async (
viewFilterGroupsToCreate: ViewFilterGroup[],
view: Pick,
@@ -80,7 +80,7 @@ export const usePersistViewFilterGroupRecords = () => {
[createCoreViewFilterGroupRecord],
);
- const updateViewFilterGroups = useCallback(
+ const performViewFilterGroupAPIUpdate = useCallback(
(viewFilterGroupsToUpdate: ViewFilterGroup[]) => {
if (!viewFilterGroupsToUpdate.length) return;
return Promise.all(
@@ -104,7 +104,7 @@ export const usePersistViewFilterGroupRecords = () => {
[apolloClient],
);
- const deleteViewFilterGroups = useCallback(
+ const performViewFilterGroupAPIDelete = useCallback(
(viewFilterGroupIdsToDelete: string[]) => {
if (!viewFilterGroupIdsToDelete.length) return;
return Promise.all(
@@ -122,8 +122,8 @@ export const usePersistViewFilterGroupRecords = () => {
);
return {
- createViewFilterGroups,
- updateViewFilterGroups,
- deleteViewFilterGroups,
+ performViewFilterGroupAPICreate,
+ performViewFilterGroupAPIUpdate,
+ performViewFilterGroupAPIDelete,
};
};
diff --git a/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewGroup.ts b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewGroupAPIPersist.ts
similarity index 95%
rename from packages/twenty-front/src/modules/views/hooks/internal/usePersistViewGroup.ts
rename to packages/twenty-front/src/modules/views/hooks/internal/usePerformViewGroupAPIPersist.ts
index d7dd66f4baf..6d6437a95e3 100644
--- a/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewGroup.ts
+++ b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewGroupAPIPersist.ts
@@ -13,7 +13,7 @@ import {
useUpdateCoreViewGroupMutation,
} from '~/generated/graphql';
-export const usePersistViewGroupRecords = () => {
+export const usePerformViewGroupAPIPersist = () => {
const { triggerViewGroupOptimisticEffect } =
useTriggerViewGroupOptimisticEffect();
@@ -22,7 +22,7 @@ export const usePersistViewGroupRecords = () => {
const { handleMetadataError } = useMetadataErrorHandler();
const { enqueueErrorSnackBar } = useSnackBar();
- const updateViewGroups = useCallback(
+ const performViewGroupAPIUpdate = useCallback(
async (
updateCoreViewGroupInputs: UpdateCoreViewGroupMutationVariables[],
): Promise<
@@ -85,6 +85,6 @@ export const usePersistViewGroupRecords = () => {
);
return {
- updateViewGroups,
+ performViewGroupAPIUpdate,
};
};
diff --git a/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewSort.ts b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewSortAPIPersist.ts
similarity index 91%
rename from packages/twenty-front/src/modules/views/hooks/internal/usePersistViewSort.ts
rename to packages/twenty-front/src/modules/views/hooks/internal/usePerformViewSortAPIPersist.ts
index c300ec37cdc..ae9fd481eea 100644
--- a/packages/twenty-front/src/modules/views/hooks/internal/usePersistViewSort.ts
+++ b/packages/twenty-front/src/modules/views/hooks/internal/usePerformViewSortAPIPersist.ts
@@ -10,13 +10,13 @@ import { useApolloClient } from '@apollo/client';
import { isDefined } from 'twenty-shared/utils';
import { type CoreViewSort } from '~/generated/graphql';
-export const usePersistViewSortRecords = () => {
+export const usePerformViewSortAPIPersist = () => {
const apolloClient = useApolloClient();
const { triggerViewSortOptimisticEffect } =
useTriggerViewSortOptimisticEffect();
- const createViewSorts = useCallback(
+ const performViewSortAPICreate = useCallback(
(
viewSortsToCreate: CoreViewSortEssential[],
view: Pick,
@@ -49,7 +49,7 @@ export const usePersistViewSortRecords = () => {
[apolloClient, triggerViewSortOptimisticEffect],
);
- const updateViewSorts = useCallback(
+ const performViewSortAPIUpdate = useCallback(
(viewSortsToUpdate: CoreViewSortEssential[]) => {
if (!viewSortsToUpdate.length) return;
return Promise.all(
@@ -77,7 +77,7 @@ export const usePersistViewSortRecords = () => {
[apolloClient, triggerViewSortOptimisticEffect],
);
- const deleteViewSorts = useCallback(
+ const performViewSortAPIDelete = useCallback(
(viewSortsToDelete: Pick[]) => {
if (!viewSortsToDelete.length) return;
return Promise.all(
@@ -100,8 +100,8 @@ export const usePersistViewSortRecords = () => {
);
return {
- createViewSorts,
- updateViewSorts,
- deleteViewSorts,
+ performViewSortAPICreate,
+ performViewSortAPIUpdate,
+ performViewSortAPIDelete,
};
};
diff --git a/packages/twenty-front/src/modules/views/hooks/useCreateViewFromCurrentView.ts b/packages/twenty-front/src/modules/views/hooks/useCreateViewFromCurrentView.ts
index b17abae067e..5f28265c71b 100644
--- a/packages/twenty-front/src/modules/views/hooks/useCreateViewFromCurrentView.ts
+++ b/packages/twenty-front/src/modules/views/hooks/useCreateViewFromCurrentView.ts
@@ -7,11 +7,11 @@ import { currentRecordSortsComponentState } from '@/object-record/record-sort/st
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 { usePersistView } from '@/views/hooks/internal/usePersistView';
-import { usePersistViewField } from '@/views/hooks/internal/usePersistViewField';
-import { usePersistViewFilterRecords } from '@/views/hooks/internal/usePersistViewFilter';
-import { usePersistViewFilterGroupRecords } from '@/views/hooks/internal/usePersistViewFilterGroup';
-import { usePersistViewSortRecords } from '@/views/hooks/internal/usePersistViewSort';
+import { usePerformViewAPIPersist } from '@/views/hooks/internal/usePerformViewAPIPersist';
+import { usePerformViewFieldAPIPersist } from '@/views/hooks/internal/usePerformViewFieldAPIPersist';
+import { usePerformViewFilterAPIPersist } from '@/views/hooks/internal/usePerformViewFilterAPIPersist';
+import { usePerformViewFilterGroupAPIPersist } from '@/views/hooks/internal/usePerformViewFilterGroupAPIPersist';
+import { usePerformViewSortAPIPersist } from '@/views/hooks/internal/usePerformViewSortAPIPersist';
import { useRefreshCoreViewsByObjectMetadataId } from '@/views/hooks/useRefreshCoreViewsByObjectMetadataId';
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
import { type GraphQLView } from '@/views/types/GraphQLView';
@@ -29,7 +29,7 @@ import { ViewCalendarLayout } from '~/generated-metadata/graphql';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
- const { createView } = usePersistView();
+ const { performViewAPICreate } = usePerformViewAPIPersist();
const currentViewIdCallbackState = useRecoilComponentCallbackState(
contextStoreCurrentViewIdComponentState,
@@ -40,13 +40,14 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
anyFieldFilterValueComponentState,
);
- const { createViewFields } = usePersistViewField();
+ const { performViewFieldAPICreate } = usePerformViewFieldAPIPersist();
- const { createViewSorts } = usePersistViewSortRecords();
+ const { performViewSortAPICreate } = usePerformViewSortAPIPersist();
- const { createViewFilters } = usePersistViewFilterRecords();
+ const { performViewFilterAPICreate } = usePerformViewFilterAPIPersist();
- const { createViewFilterGroups } = usePersistViewFilterGroupRecords();
+ const { performViewFilterGroupAPICreate } =
+ usePerformViewFilterGroupAPIPersist();
const { objectMetadataItem } = useRecordIndexContextOrThrow();
@@ -113,7 +114,7 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
const viewType = type ?? sourceView.type;
- const result = await createView(
+ const result = await performViewAPICreate(
{
input: {
id: id ?? v4(),
@@ -160,7 +161,7 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
throw new Error('Failed to create view');
}
- const fieldResult = await createViewFields({
+ const fieldResult = await performViewFieldAPICreate({
inputs: sourceView.viewFields.map(
({ __typename, id: _id, ...viewField }) => ({
...viewField,
@@ -202,7 +203,7 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
id: v4(),
}));
- await createViewFilterGroups(viewFilterGroupsToCreate, {
+ await performViewFilterGroupAPICreate(viewFilterGroupsToCreate, {
id: newViewId,
});
@@ -221,13 +222,15 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
}),
);
- const filterResult = await createViewFilters(createViewFilterInputs);
+ const filterResult = await performViewFilterAPICreate(
+ createViewFilterInputs,
+ );
if (filterResult.status === 'failed') {
return undefined;
}
- await createViewSorts(viewSortsToCreate, { id: newViewId });
+ await performViewSortAPICreate(viewSortsToCreate, { id: newViewId });
}
await refreshCoreViewsByObjectMetadataId(objectMetadataItem.id);
@@ -236,17 +239,17 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
},
[
currentViewIdCallbackState,
- createView,
+ performViewAPICreate,
anyFieldFilterValue,
objectMetadataItem,
- createViewFields,
+ performViewFieldAPICreate,
refreshCoreViewsByObjectMetadataId,
currentRecordFilterGroups,
currentRecordFilters,
currentRecordSorts,
- createViewFilterGroups,
- createViewFilters,
- createViewSorts,
+ performViewFilterGroupAPICreate,
+ performViewFilterAPICreate,
+ performViewSortAPICreate,
],
);
diff --git a/packages/twenty-front/src/modules/views/hooks/useSaveAnyFieldFilterToView.ts b/packages/twenty-front/src/modules/views/hooks/useSaveAnyFieldFilterToView.ts
index 3d5d98258de..981e25a8a2f 100644
--- a/packages/twenty-front/src/modules/views/hooks/useSaveAnyFieldFilterToView.ts
+++ b/packages/twenty-front/src/modules/views/hooks/useSaveAnyFieldFilterToView.ts
@@ -1,6 +1,6 @@
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
-import { usePersistView } from '@/views/hooks/internal/usePersistView';
+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';
@@ -9,7 +9,7 @@ import { isDefined } from 'twenty-shared/utils';
export const useSaveAnyFieldFilterToView = () => {
const { canPersistChanges } = useCanPersistViewChanges();
- const { updateView } = usePersistView();
+ const { performViewAPIUpdate } = usePerformViewAPIUpdate();
const { currentView } = useGetCurrentViewOnly();
@@ -31,7 +31,7 @@ export const useSaveAnyFieldFilterToView = () => {
.getValue();
if (currentAnyFieldFilterValue !== currentViewAnyFieldFilterValue) {
- await updateView({
+ await performViewAPIUpdate({
id: currentView.id,
input: convertUpdateViewInputToCore({
...currentView,
@@ -42,7 +42,7 @@ export const useSaveAnyFieldFilterToView = () => {
},
[
canPersistChanges,
- updateView,
+ performViewAPIUpdate,
anyFieldFilterValueCallbackState,
currentView,
],
diff --git a/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFields.ts b/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFields.ts
index d54635d5869..ced04f275a7 100644
--- a/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFields.ts
+++ b/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewFields.ts
@@ -2,7 +2,7 @@ import { useRecoilCallback } from 'recoil';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
-import { usePersistViewField } from '@/views/hooks/internal/usePersistViewField';
+import { usePerformViewFieldAPIPersist } from '@/views/hooks/internal/usePerformViewFieldAPIPersist';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useGetViewFromPrefetchState } from '@/views/hooks/useGetViewFromPrefetchState';
import { type ViewField } from '@/views/types/ViewField';
@@ -15,7 +15,8 @@ import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
export const useSaveCurrentViewFields = () => {
const { canPersistChanges } = useCanPersistViewChanges();
- const { createViewFields, updateViewFields } = usePersistViewField();
+ const { performViewFieldAPICreate, performViewFieldAPIUpdate } =
+ usePerformViewFieldAPIPersist();
const { getViewFromPrefetchState } = useGetViewFromPrefetchState();
@@ -123,16 +124,16 @@ export const useSaveCurrentViewFields = () => {
);
await Promise.all([
- createViewFields({ inputs: viewFieldsToCreate }),
- updateViewFields(viewFieldsToUpdate),
+ performViewFieldAPICreate({ inputs: viewFieldsToCreate }),
+ performViewFieldAPIUpdate(viewFieldsToUpdate),
]);
},
[
canPersistChanges,
- createViewFields,
+ performViewFieldAPICreate,
currentViewIdCallbackState,
getViewFromPrefetchState,
- updateViewFields,
+ performViewFieldAPIUpdate,
],
);
diff --git a/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewGroups.ts b/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewGroups.ts
index c7ee2ef48db..28668cf0054 100644
--- a/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewGroups.ts
+++ b/packages/twenty-front/src/modules/views/hooks/useSaveCurrentViewGroups.ts
@@ -2,7 +2,7 @@ import { useRecoilCallback } from 'recoil';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
-import { usePersistViewGroupRecords } from '@/views/hooks/internal/usePersistViewGroup';
+import { usePerformViewGroupAPIPersist } from '@/views/hooks/internal/usePerformViewGroupAPIPersist';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useGetViewFromPrefetchState } from '@/views/hooks/useGetViewFromPrefetchState';
import { type ViewGroup } from '@/views/types/ViewGroup';
@@ -12,7 +12,7 @@ import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
export const useSaveCurrentViewGroups = () => {
const { canPersistChanges } = useCanPersistViewChanges();
- const { updateViewGroups } = usePersistViewGroupRecords();
+ const { performViewGroupAPIUpdate } = usePerformViewGroupAPIPersist();
const { getViewFromPrefetchState } = useGetViewFromPrefetchState();
@@ -67,7 +67,7 @@ export const useSaveCurrentViewGroups = () => {
return;
}
- await updateViewGroups([
+ await performViewGroupAPIUpdate([
{
input: {
id: existingField.id,
@@ -84,7 +84,7 @@ export const useSaveCurrentViewGroups = () => {
canPersistChanges,
currentViewIdCallbackState,
getViewFromPrefetchState,
- updateViewGroups,
+ performViewGroupAPIUpdate,
],
);
@@ -154,13 +154,13 @@ export const useSaveCurrentViewGroups = () => {
throw new Error('mainGroupByFieldMetadataId is required');
}
- await updateViewGroups(viewGroupsToUpdate);
+ await performViewGroupAPIUpdate(viewGroupsToUpdate);
},
[
canPersistChanges,
currentViewIdCallbackState,
getViewFromPrefetchState,
- updateViewGroups,
+ performViewGroupAPIUpdate,
],
);
diff --git a/packages/twenty-front/src/modules/views/hooks/useSaveRecordFilterGroupsToViewFilterGroups.ts b/packages/twenty-front/src/modules/views/hooks/useSaveRecordFilterGroupsToViewFilterGroups.ts
index 48e775159f5..d8a3a2b977d 100644
--- a/packages/twenty-front/src/modules/views/hooks/useSaveRecordFilterGroupsToViewFilterGroups.ts
+++ b/packages/twenty-front/src/modules/views/hooks/useSaveRecordFilterGroupsToViewFilterGroups.ts
@@ -1,7 +1,7 @@
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 { usePersistViewFilterGroupRecords } from '@/views/hooks/internal/usePersistViewFilterGroup';
+import { usePerformViewFilterGroupAPIPersist } from '@/views/hooks/internal/usePerformViewFilterGroupAPIPersist';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { getViewFilterGroupsToCreate } from '@/views/utils/getViewFilterGroupsToCreate';
@@ -14,10 +14,10 @@ import { isDefined } from 'twenty-shared/utils';
export const useSaveRecordFilterGroupsToViewFilterGroups = () => {
const { canPersistChanges } = useCanPersistViewChanges();
const {
- createViewFilterGroups,
- updateViewFilterGroups,
- deleteViewFilterGroups,
- } = usePersistViewFilterGroupRecords();
+ performViewFilterGroupAPICreate,
+ performViewFilterGroupAPIUpdate,
+ performViewFilterGroupAPIDelete,
+ } = usePerformViewFilterGroupAPIPersist();
const { currentView } = useGetCurrentViewOnly();
@@ -65,17 +65,20 @@ export const useSaveRecordFilterGroupsToViewFilterGroups = () => {
(viewFilterGroup) => viewFilterGroup.id,
);
- await createViewFilterGroups(viewFilterGroupsToCreate, currentView);
- await updateViewFilterGroups(viewFilterGroupsToUpdate);
- await deleteViewFilterGroups(viewFilterGroupIdsToDelete);
+ await performViewFilterGroupAPICreate(
+ viewFilterGroupsToCreate,
+ currentView,
+ );
+ await performViewFilterGroupAPIUpdate(viewFilterGroupsToUpdate);
+ await performViewFilterGroupAPIDelete(viewFilterGroupIdsToDelete);
},
[
canPersistChanges,
currentView,
currentRecordFilterGroupsCallbackState,
- createViewFilterGroups,
- updateViewFilterGroups,
- deleteViewFilterGroups,
+ performViewFilterGroupAPICreate,
+ performViewFilterGroupAPIUpdate,
+ performViewFilterGroupAPIDelete,
],
);
diff --git a/packages/twenty-front/src/modules/views/hooks/useSaveRecordFiltersToViewFilters.ts b/packages/twenty-front/src/modules/views/hooks/useSaveRecordFiltersToViewFilters.ts
index 2fe47022eac..d2423c2c4ca 100644
--- a/packages/twenty-front/src/modules/views/hooks/useSaveRecordFiltersToViewFilters.ts
+++ b/packages/twenty-front/src/modules/views/hooks/useSaveRecordFiltersToViewFilters.ts
@@ -1,7 +1,7 @@
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 { usePersistViewFilterRecords } from '@/views/hooks/internal/usePersistViewFilter';
+import { usePerformViewFilterAPIPersist } from '@/views/hooks/internal/usePerformViewFilterAPIPersist';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { getViewFiltersToCreate } from '@/views/utils/getViewFiltersToCreate';
@@ -13,8 +13,11 @@ import { isDefined } from 'twenty-shared/utils';
export const useSaveRecordFiltersToViewFilters = () => {
const { canPersistChanges } = useCanPersistViewChanges();
- const { createViewFilters, updateViewFilters, deleteViewFilters } =
- usePersistViewFilterRecords();
+ const {
+ performViewFilterAPICreate,
+ performViewFilterAPIUpdate,
+ performViewFilterAPIDelete,
+ } = usePerformViewFilterAPIPersist();
const { currentView } = useGetCurrentViewOnly();
@@ -93,17 +96,23 @@ export const useSaveRecordFiltersToViewFilters = () => {
}),
);
- const createResult = await createViewFilters(createViewFilterInputs);
+ const createResult = await performViewFilterAPICreate(
+ createViewFilterInputs,
+ );
if (createResult.status === 'failed') {
return;
}
- const updateResult = await updateViewFilters(updateViewFilterInputs);
+ const updateResult = await performViewFilterAPIUpdate(
+ updateViewFilterInputs,
+ );
if (updateResult.status === 'failed') {
return;
}
- const deleteResult = await deleteViewFilters(deleteViewFilterInputs);
+ const deleteResult = await performViewFilterAPIDelete(
+ deleteViewFilterInputs,
+ );
if (deleteResult.status === 'failed') {
return;
}
@@ -112,9 +121,9 @@ export const useSaveRecordFiltersToViewFilters = () => {
canPersistChanges,
currentView,
currentRecordFiltersCallbackState,
- createViewFilters,
- updateViewFilters,
- deleteViewFilters,
+ performViewFilterAPICreate,
+ performViewFilterAPIUpdate,
+ performViewFilterAPIDelete,
],
);
diff --git a/packages/twenty-front/src/modules/views/hooks/useSaveRecordSortsToViewSorts.ts b/packages/twenty-front/src/modules/views/hooks/useSaveRecordSortsToViewSorts.ts
index ed0afb24fa8..a9217bce89d 100644
--- a/packages/twenty-front/src/modules/views/hooks/useSaveRecordSortsToViewSorts.ts
+++ b/packages/twenty-front/src/modules/views/hooks/useSaveRecordSortsToViewSorts.ts
@@ -1,7 +1,7 @@
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 { usePersistViewSortRecords } from '@/views/hooks/internal/usePersistViewSort';
+import { usePerformViewSortAPIPersist } from '@/views/hooks/internal/usePerformViewSortAPIPersist';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { getViewSortsToCreate } from '@/views/utils/getViewSortsToCreate';
@@ -13,8 +13,11 @@ import { isDefined } from 'twenty-shared/utils';
export const useSaveRecordSortsToViewSorts = () => {
const { canPersistChanges } = useCanPersistViewChanges();
- const { createViewSorts, updateViewSorts, deleteViewSorts } =
- usePersistViewSortRecords();
+ const {
+ performViewSortAPICreate,
+ performViewSortAPIUpdate,
+ performViewSortAPIDelete,
+ } = usePerformViewSortAPIPersist();
const { currentView } = useGetCurrentViewOnly();
@@ -55,17 +58,17 @@ export const useSaveRecordSortsToViewSorts = () => {
newViewSorts,
);
- await createViewSorts(viewSortsToCreate, currentView);
- await updateViewSorts(viewSortsToUpdate);
- await deleteViewSorts(viewSortsToDelete);
+ await performViewSortAPICreate(viewSortsToCreate, currentView);
+ await performViewSortAPIUpdate(viewSortsToUpdate);
+ await performViewSortAPIDelete(viewSortsToDelete);
},
[
canPersistChanges,
currentView,
currentRecordSortsCallbackState,
- createViewSorts,
- updateViewSorts,
- deleteViewSorts,
+ performViewSortAPICreate,
+ performViewSortAPIUpdate,
+ performViewSortAPIDelete,
],
);
diff --git a/packages/twenty-front/src/modules/views/hooks/useUpdateViewAggregate.ts b/packages/twenty-front/src/modules/views/hooks/useUpdateViewAggregate.ts
index 83a8d5d5cb1..2eaf2fe90a6 100644
--- a/packages/twenty-front/src/modules/views/hooks/useUpdateViewAggregate.ts
+++ b/packages/twenty-front/src/modules/views/hooks/useUpdateViewAggregate.ts
@@ -4,7 +4,7 @@ import { useLoadRecordIndexStates } from '@/object-record/record-index/hooks/use
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 { usePersistView } from '@/views/hooks/internal/usePersistView';
+import { usePerformViewAPIUpdate } from '@/views/hooks/internal/usePerformViewAPIUpdate';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { coreViewsState } from '@/views/states/coreViewState';
import { convertCoreViewToView } from '@/views/utils/convertCoreViewToView';
@@ -20,7 +20,7 @@ export const useUpdateViewAggregate = () => {
const currentViewId = useRecoilComponentValue(
contextStoreCurrentViewIdComponentState,
);
- const { updateView } = usePersistView();
+ const { performViewAPIUpdate } = usePerformViewAPIUpdate();
const { loadRecordIndexStates } = useLoadRecordIndexStates();
const updateViewAggregate = useRecoilCallback(
@@ -50,7 +50,7 @@ export const useUpdateViewAggregate = () => {
return;
}
- const updatedViewResult = await updateView({
+ const updatedViewResult = await performViewAPIUpdate({
id: currentViewId,
input: {
kanbanAggregateOperationFieldMetadataId,
@@ -78,7 +78,12 @@ export const useUpdateViewAggregate = () => {
loadRecordIndexStates(updatedView, objectMetadataItem);
}
},
- [canPersistChanges, currentViewId, updateView, loadRecordIndexStates],
+ [
+ canPersistChanges,
+ currentViewId,
+ performViewAPIUpdate,
+ loadRecordIndexStates,
+ ],
);
return {
diff --git a/packages/twenty-front/src/modules/views/utils/convertCoreViewToView.ts b/packages/twenty-front/src/modules/views/utils/convertCoreViewToView.ts
index 10ff2a85a50..c5032f6a03b 100644
--- a/packages/twenty-front/src/modules/views/utils/convertCoreViewToView.ts
+++ b/packages/twenty-front/src/modules/views/utils/convertCoreViewToView.ts
@@ -25,13 +25,13 @@ export const convertCoreViewToView = (
key: convertedKey,
objectMetadataId: coreView.objectMetadataId,
isCompact: coreView.isCompact,
- viewFields: coreView.viewFields.map((viewField) =>
+ viewFields: coreView.viewFields?.map((viewField) =>
convertCoreViewFieldToViewField(viewField),
),
- viewGroups: coreView.viewGroups.map((viewGroup) =>
+ viewGroups: coreView.viewGroups?.map((viewGroup) =>
convertCoreViewGroupToViewGroup(viewGroup),
),
- viewFilters: coreView.viewFilters.map((viewFilter) =>
+ viewFilters: coreView.viewFilters?.map((viewFilter) =>
convertCoreViewFilterToViewFilter(viewFilter),
),
viewFilterGroups: coreView.viewFilterGroups?.map(
diff --git a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx
index 07328e61963..1fb6b5ba39c 100644
--- a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx
+++ b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx
@@ -11,7 +11,7 @@ import { DropdownMenuSectionLabel } from '@/ui/layout/dropdown/components/Dropdo
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 { usePersistView } from '@/views/hooks/internal/usePersistView';
+import { usePerformViewAPIUpdate } from '@/views/hooks/internal/usePerformViewAPIUpdate';
import { useChangeView } from '@/views/hooks/useChangeView';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { useOpenCreateViewDropdown } from '@/views/hooks/useOpenCreateViewDropown';
@@ -61,7 +61,7 @@ export const ViewPickerListContent = () => {
const { setViewPickerMode } = useViewPickerMode();
- const { updateView } = usePersistView();
+ const { performViewAPIUpdate } = usePerformViewAPIUpdate();
const { changeView } = useChangeView();
const { closeDropdown } = useCloseDropdown();
@@ -98,12 +98,15 @@ export const ViewPickerListContent = () => {
Promise.all(
viewsReordered.map(async (view, index) => {
if (view.position !== index) {
- await updateView({ id: view.id, input: { position: index } });
+ await performViewAPIUpdate({
+ id: view.id,
+ input: { position: index },
+ });
}
}),
);
},
- [updateView, workspaceViews],
+ [performViewAPIUpdate, workspaceViews],
);
const handleUnlistedDragEnd = useCallback(
@@ -118,12 +121,15 @@ export const ViewPickerListContent = () => {
Promise.all(
viewsReordered.map(async (view, index) => {
if (view.position !== index) {
- await updateView({ id: view.id, input: { position: index } });
+ await performViewAPIUpdate({
+ id: view.id,
+ input: { position: index },
+ });
}
}),
);
},
- [updateView, unlistedViews],
+ [performViewAPIUpdate, unlistedViews],
);
return (
diff --git a/packages/twenty-front/src/modules/views/view-picker/hooks/useDestroyViewFromCurrentState.ts b/packages/twenty-front/src/modules/views/view-picker/hooks/useDestroyViewFromCurrentState.ts
index 01ae7e5606e..cf3a6833780 100644
--- a/packages/twenty-front/src/modules/views/view-picker/hooks/useDestroyViewFromCurrentState.ts
+++ b/packages/twenty-front/src/modules/views/view-picker/hooks/useDestroyViewFromCurrentState.ts
@@ -3,7 +3,7 @@ import { useRecoilCallback, useRecoilValue } from 'recoil';
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
-import { usePersistView } from '@/views/hooks/internal/usePersistView';
+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';
@@ -44,7 +44,7 @@ export const useDestroyViewFromCurrentState = (viewBarInstanceId?: string) => {
const { changeView } = useChangeView();
- const { destroyView } = usePersistView();
+ const { performViewAPIDestroy } = usePerformViewAPIPersist();
const destroyViewFromCurrentState = useRecoilCallback(
({ set, snapshot }) =>
@@ -74,14 +74,14 @@ export const useDestroyViewFromCurrentState = (viewBarInstanceId?: string) => {
views.filter((view) => view.id !== viewPickerReferenceViewId),
);
- await destroyView({ id: viewPickerReferenceViewId });
+ await performViewAPIDestroy({ id: viewPickerReferenceViewId });
},
[
currentView,
closeAndResetViewPicker,
objectMetadataItem.id,
changeView,
- destroyView,
+ performViewAPIDestroy,
viewPickerIsDirtyCallbackState,
viewPickerIsPersistingCallbackState,
viewPickerReferenceViewIdCallbackState,
diff --git a/packages/twenty-front/src/modules/views/view-picker/hooks/useUpdateViewFromCurrentState.ts b/packages/twenty-front/src/modules/views/view-picker/hooks/useUpdateViewFromCurrentState.ts
index 5e8443e8931..74c2ceb1c7a 100644
--- a/packages/twenty-front/src/modules/views/view-picker/hooks/useUpdateViewFromCurrentState.ts
+++ b/packages/twenty-front/src/modules/views/view-picker/hooks/useUpdateViewFromCurrentState.ts
@@ -1,8 +1,7 @@
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
-import { usePersistView } from '@/views/hooks/internal/usePersistView';
+import { usePerformViewAPIUpdate } from '@/views/hooks/internal/usePerformViewAPIUpdate';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
-import { useChangeView } from '@/views/hooks/useChangeView';
import { useCloseAndResetViewPicker } from '@/views/view-picker/hooks/useCloseAndResetViewPicker';
import { viewPickerInputNameComponentState } from '@/views/view-picker/states/viewPickerInputNameComponentState';
import { viewPickerIsDirtyComponentState } from '@/views/view-picker/states/viewPickerIsDirtyComponentState';
@@ -39,8 +38,7 @@ export const useUpdateViewFromCurrentState = () => {
viewPickerVisibilityComponentState,
);
- const { updateView } = usePersistView();
- const { changeView } = useChangeView();
+ const { performViewAPIUpdate } = usePerformViewAPIUpdate();
const updateViewFromCurrentState = useRecoilCallback(
({ set, snapshot }) =>
@@ -71,7 +69,7 @@ export const useUpdateViewFromCurrentState = () => {
viewPickerVisibilityCallbackState,
);
- await updateView({
+ await performViewAPIUpdate({
id: viewPickerReferenceViewId,
input: {
name: viewPickerInputName,
@@ -79,7 +77,6 @@ export const useUpdateViewFromCurrentState = () => {
visibility: visibility,
},
});
- changeView(viewPickerReferenceViewId);
},
[
canPersistChanges,
@@ -90,8 +87,7 @@ export const useUpdateViewFromCurrentState = () => {
viewPickerInputNameCallbackState,
viewPickerSelectedIconCallbackState,
viewPickerVisibilityCallbackState,
- updateView,
- changeView,
+ performViewAPIUpdate,
],
);
diff --git a/packages/twenty-shared/src/utils/array/__tests__/upsertIntoArrayOfObjectComparingId.test.ts b/packages/twenty-shared/src/utils/array/__tests__/upsertIntoArrayOfObjectsComparingId.test.ts
similarity index 96%
rename from packages/twenty-shared/src/utils/array/__tests__/upsertIntoArrayOfObjectComparingId.test.ts
rename to packages/twenty-shared/src/utils/array/__tests__/upsertIntoArrayOfObjectsComparingId.test.ts
index 2dd64554b8f..78a4ccec8ec 100644
--- a/packages/twenty-shared/src/utils/array/__tests__/upsertIntoArrayOfObjectComparingId.test.ts
+++ b/packages/twenty-shared/src/utils/array/__tests__/upsertIntoArrayOfObjectsComparingId.test.ts
@@ -1,4 +1,4 @@
-import { upsertIntoArrayOfObjectsComparingId } from '@/utils/array/upsertIntoArrayOfObjectComparingId';
+import { upsertIntoArrayOfObjectsComparingId } from '@/utils/array/upsertIntoArrayOfObjectsComparingId';
type TestObject = {
id: string;
diff --git a/packages/twenty-shared/src/utils/array/__tests__/upsertPropertiesOfItemIntoArrayOfObjectsComparingId.test.ts b/packages/twenty-shared/src/utils/array/__tests__/upsertPropertiesOfItemIntoArrayOfObjectsComparingId.test.ts
new file mode 100644
index 00000000000..c4d9acfb290
--- /dev/null
+++ b/packages/twenty-shared/src/utils/array/__tests__/upsertPropertiesOfItemIntoArrayOfObjectsComparingId.test.ts
@@ -0,0 +1,107 @@
+import { upsertPropertiesOfItemIntoArrayOfObjectsComparingId } from '@/utils/array/upsertPropertiesOfItemIntoArrayOfObjectsComparingId';
+
+type TestObject = {
+ id: string;
+ name: string;
+ value: number;
+};
+
+const mockTestObjects: TestObject[] = [
+ {
+ id: '1',
+ name: 'Test 1',
+ value: 100,
+ },
+ {
+ id: '2',
+ name: 'Test 2',
+ value: 200,
+ },
+ {
+ id: '3',
+ name: 'Test 3',
+ value: 300,
+ },
+];
+
+describe('upsertPropertiesOfItemIntoArrayOfObjectsComparingId', () => {
+ it('should insert partial properties into empty array', () => {
+ const partialItem = { id: '1', name: 'New Item' };
+
+ expect(
+ upsertPropertiesOfItemIntoArrayOfObjectsComparingId(
+ [],
+ partialItem,
+ ),
+ ).toStrictEqual([partialItem]);
+ });
+
+ it('should append item when id does not exist', () => {
+ const newItem: TestObject = {
+ id: '4',
+ name: 'Test 4',
+ value: 400,
+ };
+
+ expect(
+ upsertPropertiesOfItemIntoArrayOfObjectsComparingId(
+ mockTestObjects,
+ newItem,
+ ),
+ ).toStrictEqual([...mockTestObjects, newItem]);
+ });
+
+ it('should merge partial properties into existing item', () => {
+ const partialUpdate = { id: '2', name: 'Updated Test 2' };
+
+ expect(
+ upsertPropertiesOfItemIntoArrayOfObjectsComparingId(
+ mockTestObjects,
+ partialUpdate,
+ ),
+ ).toStrictEqual([
+ mockTestObjects[0],
+ { id: '2', name: 'Updated Test 2', value: 200 },
+ mockTestObjects[2],
+ ]);
+ });
+
+ it('should replace all properties when full item is provided', () => {
+ const fullUpdate: TestObject = {
+ id: '1',
+ name: 'Replaced Test 1',
+ value: 999,
+ };
+
+ expect(
+ upsertPropertiesOfItemIntoArrayOfObjectsComparingId(
+ mockTestObjects,
+ fullUpdate,
+ ),
+ ).toStrictEqual([fullUpdate, mockTestObjects[1], mockTestObjects[2]]);
+ });
+
+ it('should not mutate original array when updating', () => {
+ const originalArray = [...mockTestObjects];
+ const partialUpdate = { id: '2', value: 999 };
+
+ upsertPropertiesOfItemIntoArrayOfObjectsComparingId(
+ mockTestObjects,
+ partialUpdate,
+ );
+
+ expect(mockTestObjects).toStrictEqual(originalArray);
+ });
+
+ it('should not mutate original array when inserting', () => {
+ const originalArray = [...mockTestObjects];
+ const newItem: TestObject = { id: '5', name: 'Test 5', value: 500 };
+
+ upsertPropertiesOfItemIntoArrayOfObjectsComparingId(
+ mockTestObjects,
+ newItem,
+ );
+
+ expect(mockTestObjects).toStrictEqual(originalArray);
+ });
+});
diff --git a/packages/twenty-shared/src/utils/array/upsertIntoArrayOfObjectComparingId.ts b/packages/twenty-shared/src/utils/array/upsertIntoArrayOfObjectsComparingId.ts
similarity index 100%
rename from packages/twenty-shared/src/utils/array/upsertIntoArrayOfObjectComparingId.ts
rename to packages/twenty-shared/src/utils/array/upsertIntoArrayOfObjectsComparingId.ts
diff --git a/packages/twenty-shared/src/utils/array/upsertPropertiesOfItemIntoArrayOfObjectsComparingId.ts b/packages/twenty-shared/src/utils/array/upsertPropertiesOfItemIntoArrayOfObjectsComparingId.ts
new file mode 100644
index 00000000000..503ff2af070
--- /dev/null
+++ b/packages/twenty-shared/src/utils/array/upsertPropertiesOfItemIntoArrayOfObjectsComparingId.ts
@@ -0,0 +1,31 @@
+import { findById } from '@/utils/array/findById';
+
+export const upsertPropertiesOfItemIntoArrayOfObjectsComparingId = <
+ T extends { id: string },
+>(
+ arrayToUpsertInto: T[],
+ propertiesToUpsert: Partial & { id: string },
+): T[] => {
+ const alreadyExistingItemIndex = arrayToUpsertInto.findIndex(
+ findById(propertiesToUpsert.id),
+ );
+
+ const shouldReplaceItem = alreadyExistingItemIndex > -1;
+
+ if (shouldReplaceItem) {
+ const newArray = [...arrayToUpsertInto];
+
+ const itemToUpsert = {
+ ...arrayToUpsertInto[alreadyExistingItemIndex],
+ ...propertiesToUpsert,
+ } as T;
+
+ newArray.splice(alreadyExistingItemIndex, 1, itemToUpsert);
+
+ return newArray;
+ } else {
+ return arrayToUpsertInto.concat({
+ ...propertiesToUpsert,
+ } as T);
+ }
+};
diff --git a/packages/twenty-shared/src/utils/index.ts b/packages/twenty-shared/src/utils/index.ts
index 3a0385a0405..6f0a7964f68 100644
--- a/packages/twenty-shared/src/utils/index.ts
+++ b/packages/twenty-shared/src/utils/index.ts
@@ -17,7 +17,8 @@ export { isNonEmptyArray } from './array/isNonEmptyArray';
export { mapById } from './array/mapById';
export { mapByProperty } from './array/mapByProperty';
export { sumByProperty } from './array/sumByProperty';
-export { upsertIntoArrayOfObjectsComparingId } from './array/upsertIntoArrayOfObjectComparingId';
+export { upsertIntoArrayOfObjectsComparingId } from './array/upsertIntoArrayOfObjectsComparingId';
+export { upsertPropertiesOfItemIntoArrayOfObjectsComparingId } from './array/upsertPropertiesOfItemIntoArrayOfObjectsComparingId';
export { assertUnreachable } from './assertUnreachable';
export { computeDiffBetweenObjects } from './compute-diff-between-objects';
export { isPlainDateAfter } from './date/isPlainDateAfter';