Refactor Views by cleaning the code, relying on apolloCache and improving performances (#4516)
* Wip refactoring view * Post merge conflicts * Fix review * Add create view capability * Fix create object missing view * Fix tests
This commit is contained in:
@ -0,0 +1,115 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { triggerCreateRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerCreateRecordsOptimisticEffect';
|
||||
import { triggerUpdateRecordOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffect';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { GraphQLView } from '@/views/types/GraphQLView';
|
||||
import { ViewField } from '@/views/types/ViewField';
|
||||
|
||||
export const usePersistViewFieldRecords = () => {
|
||||
const {
|
||||
updateOneRecordMutation,
|
||||
createOneRecordMutation,
|
||||
getRecordFromCache,
|
||||
objectMetadataItem,
|
||||
} = useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.ViewField,
|
||||
});
|
||||
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
const createViewFieldRecords = useCallback(
|
||||
(viewFieldsToCreate: ViewField[], view: GraphQLView) => {
|
||||
if (!viewFieldsToCreate.length) return;
|
||||
return Promise.all(
|
||||
viewFieldsToCreate.map((viewField) =>
|
||||
apolloClient.mutate({
|
||||
mutation: createOneRecordMutation,
|
||||
variables: {
|
||||
input: {
|
||||
fieldMetadataId: viewField.fieldMetadataId,
|
||||
viewId: view.id,
|
||||
isVisible: viewField.isVisible,
|
||||
position: viewField.position,
|
||||
size: viewField.size,
|
||||
id: v4(),
|
||||
},
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
const record = data?.['createViewField'];
|
||||
if (!record) return;
|
||||
|
||||
triggerCreateRecordsOptimisticEffect({
|
||||
cache,
|
||||
objectMetadataItem,
|
||||
recordsToCreate: [record],
|
||||
objectMetadataItems,
|
||||
});
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
},
|
||||
[
|
||||
apolloClient,
|
||||
createOneRecordMutation,
|
||||
objectMetadataItem,
|
||||
objectMetadataItems,
|
||||
],
|
||||
);
|
||||
|
||||
const updateViewFieldRecords = useCallback(
|
||||
(viewFieldsToUpdate: ViewField[]) => {
|
||||
if (!viewFieldsToUpdate.length) return;
|
||||
return Promise.all(
|
||||
viewFieldsToUpdate.map((viewField) =>
|
||||
apolloClient.mutate({
|
||||
mutation: updateOneRecordMutation,
|
||||
variables: {
|
||||
idToUpdate: viewField.id,
|
||||
input: {
|
||||
isVisible: viewField.isVisible,
|
||||
position: viewField.position,
|
||||
size: viewField.size,
|
||||
},
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
const record = data?.['updateViewField'];
|
||||
if (!record) return;
|
||||
const cachedRecord = getRecordFromCache<ObjectRecord>(record.id);
|
||||
|
||||
if (!cachedRecord) return;
|
||||
|
||||
triggerUpdateRecordOptimisticEffect({
|
||||
cache,
|
||||
objectMetadataItem,
|
||||
currentRecord: cachedRecord,
|
||||
updatedRecord: record,
|
||||
objectMetadataItems,
|
||||
});
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
},
|
||||
[
|
||||
apolloClient,
|
||||
getRecordFromCache,
|
||||
objectMetadataItem,
|
||||
objectMetadataItems,
|
||||
updateOneRecordMutation,
|
||||
],
|
||||
);
|
||||
|
||||
return {
|
||||
createViewFieldRecords,
|
||||
updateViewFieldRecords,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,156 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
|
||||
import { triggerCreateRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerCreateRecordsOptimisticEffect';
|
||||
import { triggerDeleteRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerDeleteRecordsOptimisticEffect';
|
||||
import { triggerUpdateRecordOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffect';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { GraphQLView } from '@/views/types/GraphQLView';
|
||||
import { ViewFilter } from '@/views/types/ViewFilter';
|
||||
|
||||
export const usePersistViewFilterRecords = () => {
|
||||
const {
|
||||
updateOneRecordMutation,
|
||||
createOneRecordMutation,
|
||||
deleteOneRecordMutation,
|
||||
objectMetadataItem,
|
||||
getRecordFromCache,
|
||||
} = useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.ViewFilter,
|
||||
});
|
||||
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
const createViewFilterRecords = useCallback(
|
||||
(viewFiltersToCreate: ViewFilter[], view: GraphQLView) => {
|
||||
if (!viewFiltersToCreate.length) return;
|
||||
|
||||
return Promise.all(
|
||||
viewFiltersToCreate.map((viewFilter) =>
|
||||
apolloClient.mutate({
|
||||
mutation: createOneRecordMutation,
|
||||
variables: {
|
||||
input: {
|
||||
fieldMetadataId: viewFilter.fieldMetadataId,
|
||||
viewId: view.id,
|
||||
value: viewFilter.value,
|
||||
displayValue: viewFilter.displayValue,
|
||||
operand: viewFilter.operand,
|
||||
},
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
const record = data?.['createViewFilter'];
|
||||
if (!record) return;
|
||||
|
||||
triggerCreateRecordsOptimisticEffect({
|
||||
cache,
|
||||
objectMetadataItem,
|
||||
recordsToCreate: [record],
|
||||
objectMetadataItems,
|
||||
});
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
},
|
||||
[
|
||||
apolloClient,
|
||||
createOneRecordMutation,
|
||||
objectMetadataItem,
|
||||
objectMetadataItems,
|
||||
],
|
||||
);
|
||||
|
||||
const updateViewFilterRecords = useCallback(
|
||||
(viewFiltersToUpdate: ViewFilter[]) => {
|
||||
if (!viewFiltersToUpdate.length) return;
|
||||
return Promise.all(
|
||||
viewFiltersToUpdate.map((viewFilter) =>
|
||||
apolloClient.mutate({
|
||||
mutation: updateOneRecordMutation,
|
||||
variables: {
|
||||
idToUpdate: viewFilter.id,
|
||||
input: {
|
||||
value: viewFilter.value,
|
||||
displayValue: viewFilter.displayValue,
|
||||
operand: viewFilter.operand,
|
||||
},
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
const record = data?.['updateViewFilter'];
|
||||
if (!record) return;
|
||||
const cachedRecord = getRecordFromCache<ObjectRecord>(record.id);
|
||||
|
||||
if (!cachedRecord) return;
|
||||
|
||||
triggerUpdateRecordOptimisticEffect({
|
||||
cache,
|
||||
objectMetadataItem,
|
||||
currentRecord: cachedRecord,
|
||||
updatedRecord: record,
|
||||
objectMetadataItems,
|
||||
});
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
},
|
||||
[
|
||||
apolloClient,
|
||||
getRecordFromCache,
|
||||
objectMetadataItem,
|
||||
objectMetadataItems,
|
||||
updateOneRecordMutation,
|
||||
],
|
||||
);
|
||||
|
||||
const deleteViewFilterRecords = useCallback(
|
||||
(viewFilterIdsToDelete: string[]) => {
|
||||
if (!viewFilterIdsToDelete.length) return;
|
||||
return Promise.all(
|
||||
viewFilterIdsToDelete.map((viewFilterId) =>
|
||||
apolloClient.mutate({
|
||||
mutation: deleteOneRecordMutation,
|
||||
variables: {
|
||||
idToDelete: viewFilterId,
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
const record = data?.['deleteViewFilter'];
|
||||
|
||||
if (!record) return;
|
||||
|
||||
const cachedRecord = getRecordFromCache(record.id, cache);
|
||||
|
||||
if (!cachedRecord) return;
|
||||
|
||||
triggerDeleteRecordsOptimisticEffect({
|
||||
cache,
|
||||
objectMetadataItem,
|
||||
recordsToDelete: [cachedRecord],
|
||||
objectMetadataItems,
|
||||
});
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
},
|
||||
[
|
||||
apolloClient,
|
||||
deleteOneRecordMutation,
|
||||
getRecordFromCache,
|
||||
objectMetadataItem,
|
||||
objectMetadataItems,
|
||||
],
|
||||
);
|
||||
|
||||
return {
|
||||
createViewFilterRecords,
|
||||
updateViewFilterRecords,
|
||||
deleteViewFilterRecords,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,151 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
|
||||
import { triggerCreateRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerCreateRecordsOptimisticEffect';
|
||||
import { triggerDeleteRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerDeleteRecordsOptimisticEffect';
|
||||
import { triggerUpdateRecordOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffect';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { GraphQLView } from '@/views/types/GraphQLView';
|
||||
import { ViewSort } from '@/views/types/ViewSort';
|
||||
|
||||
export const usePersistViewSortRecords = () => {
|
||||
const {
|
||||
updateOneRecordMutation,
|
||||
createOneRecordMutation,
|
||||
deleteOneRecordMutation,
|
||||
objectMetadataItem,
|
||||
getRecordFromCache,
|
||||
} = useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.ViewSort,
|
||||
});
|
||||
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
const createViewSortRecords = useCallback(
|
||||
(viewSortsToCreate: ViewSort[], view: GraphQLView) => {
|
||||
if (!viewSortsToCreate.length) return;
|
||||
return Promise.all(
|
||||
viewSortsToCreate.map((viewSort) =>
|
||||
apolloClient.mutate({
|
||||
mutation: createOneRecordMutation,
|
||||
variables: {
|
||||
input: {
|
||||
fieldMetadataId: viewSort.fieldMetadataId,
|
||||
viewId: view.id,
|
||||
direction: viewSort.direction,
|
||||
},
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
const record = data?.['createViewSort'];
|
||||
if (!record) return;
|
||||
|
||||
triggerCreateRecordsOptimisticEffect({
|
||||
cache,
|
||||
objectMetadataItem,
|
||||
recordsToCreate: [record],
|
||||
objectMetadataItems,
|
||||
});
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
},
|
||||
[
|
||||
apolloClient,
|
||||
createOneRecordMutation,
|
||||
objectMetadataItem,
|
||||
objectMetadataItems,
|
||||
],
|
||||
);
|
||||
|
||||
const updateViewSortRecords = useCallback(
|
||||
(viewSortsToUpdate: ViewSort[]) => {
|
||||
if (!viewSortsToUpdate.length) return;
|
||||
return Promise.all(
|
||||
viewSortsToUpdate.map((viewSort) =>
|
||||
apolloClient.mutate({
|
||||
mutation: updateOneRecordMutation,
|
||||
variables: {
|
||||
idToUpdate: viewSort.id,
|
||||
input: {
|
||||
direction: viewSort.direction,
|
||||
},
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
const record = data?.['updateViewSort'];
|
||||
if (!record) return;
|
||||
const cachedRecord = getRecordFromCache<ObjectRecord>(record.id);
|
||||
|
||||
if (!cachedRecord) return;
|
||||
|
||||
triggerUpdateRecordOptimisticEffect({
|
||||
cache,
|
||||
objectMetadataItem,
|
||||
currentRecord: cachedRecord,
|
||||
updatedRecord: record,
|
||||
objectMetadataItems,
|
||||
});
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
},
|
||||
[
|
||||
apolloClient,
|
||||
getRecordFromCache,
|
||||
objectMetadataItem,
|
||||
objectMetadataItems,
|
||||
updateOneRecordMutation,
|
||||
],
|
||||
);
|
||||
|
||||
const deleteViewSortRecords = useCallback(
|
||||
(viewSortIdsToDelete: string[]) => {
|
||||
if (!viewSortIdsToDelete.length) return;
|
||||
return Promise.all(
|
||||
viewSortIdsToDelete.map((viewSortId) =>
|
||||
apolloClient.mutate({
|
||||
mutation: deleteOneRecordMutation,
|
||||
variables: {
|
||||
idToDelete: viewSortId,
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
const record = data?.['deleteViewSort'];
|
||||
|
||||
if (!record) return;
|
||||
|
||||
const cachedRecord = getRecordFromCache(record.id, cache);
|
||||
|
||||
if (!cachedRecord) return;
|
||||
|
||||
triggerDeleteRecordsOptimisticEffect({
|
||||
cache,
|
||||
objectMetadataItem,
|
||||
recordsToDelete: [cachedRecord],
|
||||
objectMetadataItems,
|
||||
});
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
},
|
||||
[
|
||||
apolloClient,
|
||||
deleteOneRecordMutation,
|
||||
getRecordFromCache,
|
||||
objectMetadataItem,
|
||||
objectMetadataItems,
|
||||
],
|
||||
);
|
||||
|
||||
return {
|
||||
createViewSortRecords,
|
||||
updateViewSortRecords,
|
||||
deleteViewSortRecords,
|
||||
};
|
||||
};
|
||||
@ -1,160 +0,0 @@
|
||||
import { Reference, useApolloClient } from '@apollo/client';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { ViewField } from '@/views/types/ViewField';
|
||||
import { getViewScopedStatesFromSnapshot } from '@/views/utils/getViewScopedStatesFromSnapshot';
|
||||
import { getViewScopedStateValuesFromSnapshot } from '@/views/utils/getViewScopedStateValuesFromSnapshot';
|
||||
|
||||
export const useViewFields = (viewScopeId: string) => {
|
||||
const { updateOneRecordMutation, createOneRecordMutation } =
|
||||
useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.ViewField,
|
||||
});
|
||||
|
||||
const { modifyRecordFromCache } = useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.View,
|
||||
});
|
||||
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
const persistViewFields = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
async (viewFieldsToPersist: ViewField[], viewId?: string) => {
|
||||
const {
|
||||
viewObjectMetadataId,
|
||||
currentViewId,
|
||||
savedViewFieldsByKey,
|
||||
onViewFieldsChange,
|
||||
views,
|
||||
} = getViewScopedStateValuesFromSnapshot({
|
||||
snapshot,
|
||||
viewScopeId,
|
||||
viewId,
|
||||
});
|
||||
|
||||
const {
|
||||
isPersistingViewState,
|
||||
currentViewFieldsState,
|
||||
savedViewFieldsState,
|
||||
} = getViewScopedStatesFromSnapshot({
|
||||
snapshot,
|
||||
viewScopeId,
|
||||
viewId,
|
||||
});
|
||||
|
||||
const viewIdToPersist = viewId ?? currentViewId;
|
||||
|
||||
if (!currentViewId || !savedViewFieldsByKey || !viewObjectMetadataId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const _createViewFields = (viewFieldsToCreate: ViewField[]) => {
|
||||
if (!viewFieldsToCreate.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
return Promise.all(
|
||||
viewFieldsToCreate.map((viewField) =>
|
||||
apolloClient.mutate({
|
||||
mutation: createOneRecordMutation,
|
||||
variables: {
|
||||
input: {
|
||||
fieldMetadataId: viewField.fieldMetadataId,
|
||||
viewId: viewIdToPersist,
|
||||
isVisible: viewField.isVisible,
|
||||
size: viewField.size,
|
||||
position: viewField.position,
|
||||
},
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
const _updateViewFields = (viewFieldsToUpdate: ViewField[]) => {
|
||||
if (!viewFieldsToUpdate.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
return Promise.all(
|
||||
viewFieldsToUpdate.map((viewField) =>
|
||||
apolloClient.mutate({
|
||||
mutation: updateOneRecordMutation,
|
||||
variables: {
|
||||
idToUpdate: viewField.id,
|
||||
input: {
|
||||
isVisible: viewField.isVisible,
|
||||
size: viewField.size,
|
||||
position: viewField.position,
|
||||
},
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
const viewFieldsToCreate = viewFieldsToPersist.filter(
|
||||
(viewField) => !savedViewFieldsByKey[viewField.fieldMetadataId],
|
||||
);
|
||||
|
||||
const viewFieldsToUpdate = viewFieldsToPersist.filter(
|
||||
(viewFieldToPersit) =>
|
||||
savedViewFieldsByKey[viewFieldToPersit.fieldMetadataId] &&
|
||||
(savedViewFieldsByKey[viewFieldToPersit.fieldMetadataId].size !==
|
||||
viewFieldToPersit.size ||
|
||||
savedViewFieldsByKey[viewFieldToPersit.fieldMetadataId]
|
||||
.position !== viewFieldToPersit.position ||
|
||||
savedViewFieldsByKey[viewFieldToPersit.fieldMetadataId]
|
||||
.isVisible !== viewFieldToPersit.isVisible),
|
||||
);
|
||||
|
||||
set(isPersistingViewState, true);
|
||||
|
||||
await _createViewFields(viewFieldsToCreate);
|
||||
|
||||
await _updateViewFields(viewFieldsToUpdate);
|
||||
|
||||
set(isPersistingViewState, false);
|
||||
set(currentViewFieldsState, viewFieldsToPersist);
|
||||
set(savedViewFieldsState, viewFieldsToPersist);
|
||||
|
||||
const existingView = views.find((view) => view.id === viewIdToPersist);
|
||||
|
||||
if (!existingView) {
|
||||
return;
|
||||
}
|
||||
|
||||
modifyRecordFromCache(viewIdToPersist ?? '', {
|
||||
viewFields: (viewFieldsRef, { readField }) => {
|
||||
const edges = readField<{ node: Reference }[]>(
|
||||
'edges',
|
||||
viewFieldsRef,
|
||||
);
|
||||
|
||||
if (!edges) return viewFieldsRef;
|
||||
|
||||
return {
|
||||
...viewFieldsRef,
|
||||
edges: viewFieldsToPersist.map((viewField) => ({
|
||||
node: viewField,
|
||||
cursor: '',
|
||||
})),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
onViewFieldsChange?.(viewFieldsToPersist);
|
||||
},
|
||||
[
|
||||
viewScopeId,
|
||||
modifyRecordFromCache,
|
||||
apolloClient,
|
||||
createOneRecordMutation,
|
||||
updateOneRecordMutation,
|
||||
],
|
||||
);
|
||||
|
||||
return { persistViewFields };
|
||||
};
|
||||
@ -1,246 +0,0 @@
|
||||
import { Reference, useApolloClient } from '@apollo/client';
|
||||
import { produce } from 'immer';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
|
||||
import { savedViewFiltersScopedFamilyState } from '@/views/states/savedViewFiltersScopedFamilyState';
|
||||
import { ViewFilter } from '@/views/types/ViewFilter';
|
||||
import { getViewScopedStateValuesFromSnapshot } from '@/views/utils/getViewScopedStateValuesFromSnapshot';
|
||||
|
||||
import { useViewScopedStates } from './useViewScopedStates';
|
||||
|
||||
export const useViewFilters = (viewScopeId: string) => {
|
||||
const {
|
||||
updateOneRecordMutation,
|
||||
createOneRecordMutation,
|
||||
deleteOneRecordMutation,
|
||||
} = useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.ViewFilter,
|
||||
});
|
||||
|
||||
const { modifyRecordFromCache } = useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.View,
|
||||
});
|
||||
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
const { currentViewFiltersState } = useViewScopedStates({
|
||||
viewScopeId: viewScopeId,
|
||||
});
|
||||
|
||||
const persistViewFilters = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
async (viewId?: string) => {
|
||||
const {
|
||||
currentViewId,
|
||||
currentViewFilters,
|
||||
savedViewFiltersByKey,
|
||||
views,
|
||||
} = getViewScopedStateValuesFromSnapshot({
|
||||
snapshot,
|
||||
viewScopeId,
|
||||
});
|
||||
|
||||
if (!currentViewId || !currentViewFilters || !savedViewFiltersByKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
const createViewFilters = (viewFiltersToCreate: ViewFilter[]) => {
|
||||
if (!viewFiltersToCreate.length) return;
|
||||
|
||||
return Promise.all(
|
||||
viewFiltersToCreate.map((viewFilter) =>
|
||||
apolloClient.mutate({
|
||||
mutation: createOneRecordMutation,
|
||||
variables: {
|
||||
input: {
|
||||
fieldMetadataId: viewFilter.fieldMetadataId,
|
||||
viewId: viewId ?? currentViewId,
|
||||
value: viewFilter.value,
|
||||
displayValue: viewFilter.displayValue,
|
||||
operand: viewFilter.operand,
|
||||
},
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
const updateViewFilters = (viewFiltersToUpdate: ViewFilter[]) => {
|
||||
if (!viewFiltersToUpdate.length) return;
|
||||
|
||||
return Promise.all(
|
||||
viewFiltersToUpdate.map((viewFilter) =>
|
||||
apolloClient.mutate({
|
||||
mutation: updateOneRecordMutation,
|
||||
variables: {
|
||||
idToUpdate: viewFilter.id,
|
||||
input: {
|
||||
value: viewFilter.value,
|
||||
displayValue: viewFilter.displayValue,
|
||||
operand: viewFilter.operand,
|
||||
},
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
const deleteViewFilters = (viewFilterIdsToDelete: string[]) => {
|
||||
if (!viewFilterIdsToDelete.length) return;
|
||||
|
||||
return Promise.all(
|
||||
viewFilterIdsToDelete.map((viewFilterId) =>
|
||||
apolloClient.mutate({
|
||||
mutation: deleteOneRecordMutation,
|
||||
variables: {
|
||||
idToDelete: viewFilterId,
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
const filtersToCreate = currentViewFilters.filter(
|
||||
(filter) => !savedViewFiltersByKey[filter.fieldMetadataId],
|
||||
);
|
||||
await createViewFilters(filtersToCreate);
|
||||
|
||||
const filtersToUpdate = currentViewFilters.filter(
|
||||
(filter) =>
|
||||
savedViewFiltersByKey[filter.fieldMetadataId] &&
|
||||
(savedViewFiltersByKey[filter.fieldMetadataId].operand !==
|
||||
filter.operand ||
|
||||
savedViewFiltersByKey[filter.fieldMetadataId].value !==
|
||||
filter.value),
|
||||
);
|
||||
await updateViewFilters(filtersToUpdate);
|
||||
|
||||
const filterKeys = currentViewFilters.map(
|
||||
(filter) => filter.fieldMetadataId,
|
||||
);
|
||||
const filterKeysToDelete = Object.keys(savedViewFiltersByKey).filter(
|
||||
(previousFilterKey) => !filterKeys.includes(previousFilterKey),
|
||||
);
|
||||
const filterIdsToDelete = filterKeysToDelete.map(
|
||||
(filterKeyToDelete) =>
|
||||
savedViewFiltersByKey[filterKeyToDelete].id ?? '',
|
||||
);
|
||||
await deleteViewFilters(filterIdsToDelete);
|
||||
set(
|
||||
savedViewFiltersScopedFamilyState({
|
||||
scopeId: viewScopeId,
|
||||
familyKey: viewId ?? currentViewId,
|
||||
}),
|
||||
currentViewFilters,
|
||||
);
|
||||
|
||||
const existingViewId = viewId ?? currentViewId;
|
||||
const existingView = views.find((view) => view.id === existingViewId);
|
||||
|
||||
if (!existingView) {
|
||||
return;
|
||||
}
|
||||
|
||||
modifyRecordFromCache(existingViewId, {
|
||||
viewFilters: (viewFiltersRef, { readField }) => {
|
||||
const edges = readField<{ node: Reference }[]>(
|
||||
'edges',
|
||||
viewFiltersRef,
|
||||
);
|
||||
|
||||
if (!edges) return viewFiltersRef;
|
||||
|
||||
return {
|
||||
...viewFiltersRef,
|
||||
edges: currentViewFilters.map((viewFilter) => ({
|
||||
node: viewFilter,
|
||||
cursor: '',
|
||||
})),
|
||||
};
|
||||
},
|
||||
});
|
||||
},
|
||||
[
|
||||
apolloClient,
|
||||
createOneRecordMutation,
|
||||
deleteOneRecordMutation,
|
||||
modifyRecordFromCache,
|
||||
updateOneRecordMutation,
|
||||
viewScopeId,
|
||||
],
|
||||
);
|
||||
|
||||
const upsertViewFilter = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
(filterToUpsert: Filter) => {
|
||||
const { currentViewId, savedViewFiltersByKey, onViewFiltersChange } =
|
||||
getViewScopedStateValuesFromSnapshot({
|
||||
snapshot,
|
||||
viewScopeId,
|
||||
});
|
||||
|
||||
if (!currentViewId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!savedViewFiltersByKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
const existingSavedFilterId =
|
||||
savedViewFiltersByKey[filterToUpsert.fieldMetadataId]?.id;
|
||||
|
||||
set(currentViewFiltersState, (filters) => {
|
||||
const newViewFilters = produce(filters, (filtersDraft) => {
|
||||
const existingFilterIndex = filtersDraft.findIndex(
|
||||
(filter) =>
|
||||
filter.fieldMetadataId === filterToUpsert.fieldMetadataId,
|
||||
);
|
||||
|
||||
if (existingFilterIndex === -1 && filterToUpsert.value !== '') {
|
||||
filtersDraft.push({
|
||||
...filterToUpsert,
|
||||
id: existingSavedFilterId,
|
||||
});
|
||||
return filtersDraft;
|
||||
}
|
||||
|
||||
filtersDraft[existingFilterIndex] = {
|
||||
...filterToUpsert,
|
||||
id: existingSavedFilterId,
|
||||
};
|
||||
});
|
||||
onViewFiltersChange?.(newViewFilters);
|
||||
return newViewFilters;
|
||||
});
|
||||
},
|
||||
[currentViewFiltersState, viewScopeId],
|
||||
);
|
||||
|
||||
const removeViewFilter = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
(fieldMetadataId: string) => {
|
||||
const { currentViewId, currentViewFilters, onViewFiltersChange } =
|
||||
getViewScopedStateValuesFromSnapshot({
|
||||
snapshot,
|
||||
viewScopeId,
|
||||
});
|
||||
|
||||
if (!currentViewId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newViewFilters = currentViewFilters.filter((filter) => {
|
||||
return filter.fieldMetadataId !== fieldMetadataId;
|
||||
});
|
||||
set(currentViewFiltersState, newViewFilters);
|
||||
onViewFiltersChange?.(newViewFilters);
|
||||
},
|
||||
[currentViewFiltersState, viewScopeId],
|
||||
);
|
||||
|
||||
return { persistViewFilters, removeViewFilter, upsertViewFilter };
|
||||
};
|
||||
@ -19,17 +19,20 @@ import { isDefined } from '~/utils/isDefined';
|
||||
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
||||
|
||||
const filterQueryParamsSchema = z.object({
|
||||
filter: z.record(
|
||||
z.record(
|
||||
z.nativeEnum(ViewFilterOperand),
|
||||
z.string().or(z.array(z.string())),
|
||||
),
|
||||
),
|
||||
view: z.string().optional(),
|
||||
filter: z
|
||||
.record(
|
||||
z.record(
|
||||
z.nativeEnum(ViewFilterOperand),
|
||||
z.string().or(z.array(z.string())),
|
||||
),
|
||||
)
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export type FilterQueryParams = z.infer<typeof filterQueryParamsSchema>;
|
||||
|
||||
export const useFiltersFromQueryParams = () => {
|
||||
export const useViewFromQueryParams = () => {
|
||||
const apolloClient = useApolloClient();
|
||||
const [searchParams] = useSearchParams();
|
||||
const { objectNamePlural = '' } = useParams();
|
||||
@ -39,15 +42,21 @@ export const useFiltersFromQueryParams = () => {
|
||||
const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular });
|
||||
const generateFindManyRecordsQuery = useGenerateFindManyRecordsQuery();
|
||||
|
||||
const filterParamsValidation = filterQueryParamsSchema.safeParse(
|
||||
const queryParamsValidation = filterQueryParamsSchema.safeParse(
|
||||
qs.parse(searchParams.toString()),
|
||||
);
|
||||
|
||||
const filterQueryParams = useMemo(
|
||||
() =>
|
||||
filterParamsValidation.success ? filterParamsValidation.data.filter : {},
|
||||
[filterParamsValidation],
|
||||
queryParamsValidation.success ? queryParamsValidation.data.filter : {},
|
||||
[queryParamsValidation],
|
||||
);
|
||||
const hasFiltersQueryParams = filterParamsValidation.success;
|
||||
const viewIdQueryParam = useMemo(
|
||||
() => queryParamsValidation.success && queryParamsValidation.data.view,
|
||||
[queryParamsValidation],
|
||||
);
|
||||
|
||||
const hasFiltersQueryParams = filterQueryParams;
|
||||
|
||||
const getFiltersFromQueryParams = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
@ -129,6 +138,7 @@ export const useFiltersFromQueryParams = () => {
|
||||
: filterValueFromURL;
|
||||
|
||||
return {
|
||||
__typename: 'ViewFilter',
|
||||
id: `tmp-${[
|
||||
fieldName,
|
||||
filterOperandFromURL,
|
||||
@ -140,6 +150,7 @@ export const useFiltersFromQueryParams = () => {
|
||||
displayValue:
|
||||
relationRecordNames?.join(', ') ?? filterValueAsString,
|
||||
definition: filterDefinition,
|
||||
persistAction: 'NONE',
|
||||
};
|
||||
},
|
||||
),
|
||||
@ -156,6 +167,7 @@ export const useFiltersFromQueryParams = () => {
|
||||
);
|
||||
|
||||
return {
|
||||
viewIdQueryParam,
|
||||
hasFiltersQueryParams,
|
||||
getFiltersFromQueryParams,
|
||||
};
|
||||
@ -1,90 +0,0 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||
import { getScopedStateDeprecated } from '@/ui/utilities/recoil-scope/utils/getScopedStateDeprecated';
|
||||
|
||||
import { UNDEFINED_FAMILY_ITEM_ID } from '../../constants';
|
||||
import { ViewScopeInternalContext } from '../../scopes/scope-internal-context/ViewScopeInternalContext';
|
||||
import { currentViewIdScopedState } from '../../states/currentViewIdScopedState';
|
||||
import { getViewScopedStates } from '../../utils/internal/getViewScopedStates';
|
||||
|
||||
export const useViewScopedStates = (args?: { viewScopeId?: string }) => {
|
||||
const { viewScopeId } = args ?? {};
|
||||
|
||||
const scopeId = useAvailableScopeIdOrThrow(
|
||||
ViewScopeInternalContext,
|
||||
viewScopeId,
|
||||
);
|
||||
|
||||
// View
|
||||
const [currentViewId] = useRecoilState(
|
||||
getScopedStateDeprecated(currentViewIdScopedState, scopeId),
|
||||
);
|
||||
|
||||
const viewId = currentViewId ?? UNDEFINED_FAMILY_ITEM_ID;
|
||||
|
||||
const {
|
||||
availableFieldDefinitionsState,
|
||||
availableFilterDefinitionsState,
|
||||
availableSortDefinitionsState,
|
||||
canPersistFiltersSelector,
|
||||
canPersistSortsSelector,
|
||||
currentViewFieldsState,
|
||||
currentViewFiltersState,
|
||||
currentViewIdState,
|
||||
currentViewSelector,
|
||||
currentViewSortsState,
|
||||
entityCountInCurrentViewState,
|
||||
isViewBarExpandedState,
|
||||
isPersistingViewState,
|
||||
onViewFieldsChangeState,
|
||||
onViewFiltersChangeState,
|
||||
onViewSortsChangeState,
|
||||
onViewTypeChangeState,
|
||||
onViewCompactModeChangeState,
|
||||
savedViewFieldsByKeySelector,
|
||||
savedViewFieldsState,
|
||||
savedViewFiltersByKeySelector,
|
||||
savedViewFiltersState,
|
||||
savedViewSortsByKeySelector,
|
||||
savedViewSortsState,
|
||||
viewEditModeState,
|
||||
viewObjectMetadataIdState,
|
||||
viewTypeState,
|
||||
viewsState,
|
||||
} = getViewScopedStates({
|
||||
viewScopeId: scopeId,
|
||||
viewId,
|
||||
});
|
||||
|
||||
return {
|
||||
availableFieldDefinitionsState,
|
||||
availableFilterDefinitionsState,
|
||||
availableSortDefinitionsState,
|
||||
canPersistFiltersSelector,
|
||||
canPersistSortsSelector,
|
||||
currentViewFieldsState,
|
||||
currentViewFiltersState,
|
||||
currentViewIdState,
|
||||
currentViewSelector,
|
||||
currentViewSortsState,
|
||||
entityCountInCurrentViewState,
|
||||
isViewBarExpandedState,
|
||||
isPersistingViewState,
|
||||
onViewFieldsChangeState,
|
||||
onViewFiltersChangeState,
|
||||
onViewSortsChangeState,
|
||||
onViewTypeChangeState,
|
||||
onViewCompactModeChangeState,
|
||||
savedViewFieldsByKeySelector,
|
||||
savedViewFieldsState,
|
||||
savedViewFiltersByKeySelector,
|
||||
savedViewFiltersState,
|
||||
savedViewSortsByKeySelector,
|
||||
savedViewSortsState,
|
||||
viewEditModeState,
|
||||
viewObjectMetadataIdState,
|
||||
viewTypeState,
|
||||
viewsState,
|
||||
};
|
||||
};
|
||||
@ -1,236 +0,0 @@
|
||||
import { Reference, useApolloClient } from '@apollo/client';
|
||||
import { produce } from 'immer';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { Sort } from '@/object-record/object-sort-dropdown/types/Sort';
|
||||
import { savedViewSortsScopedFamilyState } from '@/views/states/savedViewSortsScopedFamilyState';
|
||||
import { ViewSort } from '@/views/types/ViewSort';
|
||||
import { getViewScopedStateValuesFromSnapshot } from '@/views/utils/getViewScopedStateValuesFromSnapshot';
|
||||
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
||||
|
||||
import { useViewScopedStates } from './useViewScopedStates';
|
||||
|
||||
export const useViewSorts = (viewScopeId: string) => {
|
||||
const {
|
||||
updateOneRecordMutation,
|
||||
createOneRecordMutation,
|
||||
deleteOneRecordMutation,
|
||||
} = useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.ViewSort,
|
||||
});
|
||||
|
||||
const { modifyRecordFromCache } = useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.View,
|
||||
});
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
const { currentViewSortsState } = useViewScopedStates({
|
||||
viewScopeId: viewScopeId,
|
||||
});
|
||||
|
||||
const persistViewSorts = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
async (viewId?: string) => {
|
||||
const { currentViewId, currentViewSorts, savedViewSortsByKey, views } =
|
||||
getViewScopedStateValuesFromSnapshot({
|
||||
snapshot,
|
||||
viewScopeId,
|
||||
});
|
||||
|
||||
if (!currentViewId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isUndefinedOrNull(currentViewSorts)) {
|
||||
return;
|
||||
}
|
||||
if (!savedViewSortsByKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
const createViewSorts = (viewSortsToCreate: ViewSort[]) => {
|
||||
if (!viewSortsToCreate.length) return;
|
||||
|
||||
return Promise.all(
|
||||
viewSortsToCreate.map((viewSort) =>
|
||||
apolloClient.mutate({
|
||||
mutation: createOneRecordMutation,
|
||||
variables: {
|
||||
input: {
|
||||
fieldMetadataId: viewSort.fieldMetadataId,
|
||||
viewId: viewId ?? currentViewId,
|
||||
direction: viewSort.direction,
|
||||
},
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
const updateViewSorts = (viewSortsToUpdate: ViewSort[]) => {
|
||||
if (!viewSortsToUpdate.length) return;
|
||||
|
||||
return Promise.all(
|
||||
viewSortsToUpdate.map((viewSort) =>
|
||||
apolloClient.mutate({
|
||||
mutation: updateOneRecordMutation,
|
||||
variables: {
|
||||
idToUpdate: viewSort.id,
|
||||
input: {
|
||||
direction: viewSort.direction,
|
||||
},
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
const deleteViewSorts = (viewSortIdsToDelete: string[]) => {
|
||||
if (!viewSortIdsToDelete.length) return;
|
||||
|
||||
return Promise.all(
|
||||
viewSortIdsToDelete.map((viewSortId) =>
|
||||
apolloClient.mutate({
|
||||
mutation: deleteOneRecordMutation,
|
||||
variables: {
|
||||
idToDelete: viewSortId,
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
const sortsToCreate = currentViewSorts.filter(
|
||||
(sort) => !savedViewSortsByKey[sort.fieldMetadataId],
|
||||
);
|
||||
|
||||
await createViewSorts(sortsToCreate);
|
||||
|
||||
const sortsToUpdate = currentViewSorts.filter(
|
||||
(sort) =>
|
||||
savedViewSortsByKey[sort.fieldMetadataId] &&
|
||||
savedViewSortsByKey[sort.fieldMetadataId].direction !==
|
||||
sort.direction,
|
||||
);
|
||||
await updateViewSorts(sortsToUpdate);
|
||||
|
||||
const sortKeys = currentViewSorts.map((sort) => sort.fieldMetadataId);
|
||||
const sortKeysToDelete = Object.keys(savedViewSortsByKey).filter(
|
||||
(previousSortKey) => !sortKeys.includes(previousSortKey),
|
||||
);
|
||||
const sortIdsToDelete = sortKeysToDelete.map(
|
||||
(sortKeyToDelete) => savedViewSortsByKey[sortKeyToDelete].id ?? '',
|
||||
);
|
||||
await deleteViewSorts(sortIdsToDelete);
|
||||
set(
|
||||
savedViewSortsScopedFamilyState({
|
||||
scopeId: viewScopeId,
|
||||
familyKey: viewId ?? currentViewId,
|
||||
}),
|
||||
currentViewSorts,
|
||||
);
|
||||
const existingViewId = viewId ?? currentViewId;
|
||||
const existingView = views.find((view) => view.id === existingViewId);
|
||||
|
||||
if (!existingView) {
|
||||
return;
|
||||
}
|
||||
|
||||
modifyRecordFromCache(existingViewId, {
|
||||
viewSorts: (viewSortsRef, { readField }) => {
|
||||
const edges = readField<{ node: Reference }[]>(
|
||||
'edges',
|
||||
viewSortsRef,
|
||||
);
|
||||
|
||||
if (!edges) return viewSortsRef;
|
||||
|
||||
return {
|
||||
...viewSortsRef,
|
||||
edges: currentViewSorts.map((viewSort) => ({
|
||||
node: viewSort,
|
||||
cursor: '',
|
||||
})),
|
||||
};
|
||||
},
|
||||
});
|
||||
},
|
||||
[
|
||||
apolloClient,
|
||||
createOneRecordMutation,
|
||||
deleteOneRecordMutation,
|
||||
modifyRecordFromCache,
|
||||
updateOneRecordMutation,
|
||||
viewScopeId,
|
||||
],
|
||||
);
|
||||
|
||||
const upsertViewSort = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
(sortToUpsert: Sort) => {
|
||||
const { currentViewId, onViewSortsChange, savedViewSortsByKey } =
|
||||
getViewScopedStateValuesFromSnapshot({
|
||||
snapshot,
|
||||
viewScopeId,
|
||||
});
|
||||
|
||||
if (!currentViewId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!savedViewSortsByKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
const existingSavedSortId =
|
||||
savedViewSortsByKey[sortToUpsert.fieldMetadataId]?.id;
|
||||
|
||||
set(currentViewSortsState, (sorts) => {
|
||||
const newViewSorts = produce(sorts, (sortsDraft) => {
|
||||
const existingSortIndex = sortsDraft.findIndex(
|
||||
(sort) => sort.fieldMetadataId === sortToUpsert.fieldMetadataId,
|
||||
);
|
||||
|
||||
if (existingSortIndex === -1) {
|
||||
sortsDraft.push({ ...sortToUpsert, id: existingSavedSortId });
|
||||
return sortsDraft;
|
||||
}
|
||||
|
||||
sortsDraft[existingSortIndex] = {
|
||||
...sortToUpsert,
|
||||
id: existingSavedSortId,
|
||||
};
|
||||
});
|
||||
onViewSortsChange?.(newViewSorts);
|
||||
return newViewSorts;
|
||||
});
|
||||
},
|
||||
[currentViewSortsState, viewScopeId],
|
||||
);
|
||||
|
||||
const removeViewSort = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
(fieldMetadataId: string) => {
|
||||
const { currentViewId, onViewSortsChange, currentViewSorts } =
|
||||
getViewScopedStateValuesFromSnapshot({
|
||||
snapshot,
|
||||
viewScopeId,
|
||||
});
|
||||
|
||||
if (!currentViewId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newViewSorts = currentViewSorts.filter((filter) => {
|
||||
return filter.fieldMetadataId !== fieldMetadataId;
|
||||
});
|
||||
set(currentViewSortsState, newViewSorts);
|
||||
onViewSortsChange?.(newViewSorts);
|
||||
},
|
||||
[currentViewSortsState, viewScopeId],
|
||||
);
|
||||
|
||||
return { persistViewSorts, upsertViewSort, removeViewSort };
|
||||
};
|
||||
@ -0,0 +1,96 @@
|
||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||
import { extractComponentReadOnlySelector } from '@/ui/utilities/state/component-state/utils/extractComponentReadOnlySelector';
|
||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||
import { availableFieldDefinitionsComponentState } from '@/views/states/availableFieldDefinitionsComponentState';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { availableSortDefinitionsComponentState } from '@/views/states/availableSortDefinitionsComponentState';
|
||||
import { currentViewIdComponentState } from '@/views/states/currentViewIdComponentState';
|
||||
import { entityCountInCurrentViewComponentState } from '@/views/states/entityCountInCurrentViewComponentState';
|
||||
import { isCurrentViewKeyIndexComponentState } from '@/views/states/isCurrentViewIndexComponentState';
|
||||
import { isPersistingViewFieldsComponentState } from '@/views/states/isPersistingViewFieldsComponentState';
|
||||
import { isViewBarExpandedComponentState } from '@/views/states/isViewBarExpandedComponentState';
|
||||
import { onCurrentViewChangeComponentState } from '@/views/states/onCurrentViewChangeComponentState';
|
||||
import { canPersistViewComponentSelector } from '@/views/states/selectors/canPersistViewComponentSelector';
|
||||
import { unsavedToDeleteViewFilterIdsComponentState } from '@/views/states/unsavedToDeleteViewFilterIdsComponentState';
|
||||
import { unsavedToDeleteViewSortIdsComponentState } from '@/views/states/unsavedToDeleteViewSortIdsComponentState';
|
||||
import { unsavedToUpsertViewFiltersComponentState } from '@/views/states/unsavedToUpsertViewFiltersComponentState';
|
||||
import { unsavedToUpsertViewSortsComponentState } from '@/views/states/unsavedToUpsertViewSortsComponentState';
|
||||
import { viewEditModeComponentState } from '@/views/states/viewEditModeComponentState';
|
||||
import { viewObjectMetadataIdComponentState } from '@/views/states/viewObjectMetadataIdComponentState';
|
||||
|
||||
import { ViewScopeInternalContext } from '../../scopes/scope-internal-context/ViewScopeInternalContext';
|
||||
|
||||
export const useViewStates = (viewComponentId?: string) => {
|
||||
const componentId = useAvailableScopeIdOrThrow(
|
||||
ViewScopeInternalContext,
|
||||
viewComponentId,
|
||||
);
|
||||
|
||||
return {
|
||||
componentId,
|
||||
currentViewIdState: extractComponentState(
|
||||
currentViewIdComponentState,
|
||||
componentId,
|
||||
),
|
||||
availableFieldDefinitionsState: extractComponentState(
|
||||
availableFieldDefinitionsComponentState,
|
||||
componentId,
|
||||
),
|
||||
availableFilterDefinitionsState: extractComponentState(
|
||||
availableFilterDefinitionsComponentState,
|
||||
componentId,
|
||||
),
|
||||
availableSortDefinitionsState: extractComponentState(
|
||||
availableSortDefinitionsComponentState,
|
||||
componentId,
|
||||
),
|
||||
canPersistViewSelector: extractComponentReadOnlySelector(
|
||||
canPersistViewComponentSelector,
|
||||
componentId,
|
||||
),
|
||||
isViewBarExpandedState: extractComponentState(
|
||||
isViewBarExpandedComponentState,
|
||||
componentId,
|
||||
),
|
||||
onCurrentViewChangeState: extractComponentState(
|
||||
onCurrentViewChangeComponentState,
|
||||
componentId,
|
||||
),
|
||||
entityCountInCurrentViewState: extractComponentState(
|
||||
entityCountInCurrentViewComponentState,
|
||||
componentId,
|
||||
),
|
||||
viewEditModeState: extractComponentState(
|
||||
viewEditModeComponentState,
|
||||
componentId,
|
||||
),
|
||||
viewObjectMetadataIdState: extractComponentState(
|
||||
viewObjectMetadataIdComponentState,
|
||||
componentId,
|
||||
),
|
||||
unsavedToUpsertViewFiltersState: extractComponentState(
|
||||
unsavedToUpsertViewFiltersComponentState,
|
||||
componentId,
|
||||
),
|
||||
unsavedToUpsertViewSortsState: extractComponentState(
|
||||
unsavedToUpsertViewSortsComponentState,
|
||||
componentId,
|
||||
),
|
||||
unsavedToDeleteViewFilterIdsState: extractComponentState(
|
||||
unsavedToDeleteViewFilterIdsComponentState,
|
||||
componentId,
|
||||
),
|
||||
unsavedToDeleteViewSortIdsState: extractComponentState(
|
||||
unsavedToDeleteViewSortIdsComponentState,
|
||||
componentId,
|
||||
),
|
||||
isPersistingViewFieldsState: extractComponentState(
|
||||
isPersistingViewFieldsComponentState,
|
||||
componentId,
|
||||
),
|
||||
isCurrentViewKeyIndexState: extractComponentState(
|
||||
isCurrentViewKeyIndexComponentState,
|
||||
componentId,
|
||||
),
|
||||
};
|
||||
};
|
||||
@ -1,80 +0,0 @@
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { GraphQLView } from '@/views/types/GraphQLView';
|
||||
import { getViewScopedStateValuesFromSnapshot } from '@/views/utils/getViewScopedStateValuesFromSnapshot';
|
||||
|
||||
export const useViews = (scopeId: string) => {
|
||||
const {
|
||||
updateOneRecordMutation: updateOneMutation,
|
||||
createOneRecordMutation: createOneMutation,
|
||||
deleteOneRecordMutation: deleteOneMutation,
|
||||
findManyRecordsQuery: findManyQuery,
|
||||
} = useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.View,
|
||||
});
|
||||
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
const createView = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
async (view: Pick<GraphQLView, 'id' | 'name'>) => {
|
||||
const { viewObjectMetadataId, viewType } =
|
||||
getViewScopedStateValuesFromSnapshot({
|
||||
snapshot,
|
||||
viewScopeId: scopeId,
|
||||
});
|
||||
|
||||
if (!viewObjectMetadataId || !viewType) {
|
||||
return;
|
||||
}
|
||||
await apolloClient.mutate({
|
||||
mutation: createOneMutation,
|
||||
variables: {
|
||||
input: {
|
||||
id: view.id,
|
||||
name: view.name,
|
||||
objectMetadataId: viewObjectMetadataId,
|
||||
type: viewType,
|
||||
},
|
||||
},
|
||||
refetchQueries: [findManyQuery],
|
||||
});
|
||||
},
|
||||
[scopeId, apolloClient, createOneMutation, findManyQuery],
|
||||
);
|
||||
|
||||
const updateView = async (view: GraphQLView) => {
|
||||
await apolloClient.mutate({
|
||||
mutation: updateOneMutation,
|
||||
variables: {
|
||||
idToUpdate: view.id,
|
||||
input: {
|
||||
id: view.id,
|
||||
name: view.name,
|
||||
isCompact: view.isCompact,
|
||||
},
|
||||
},
|
||||
refetchQueries: [findManyQuery],
|
||||
});
|
||||
};
|
||||
|
||||
const deleteView = async (viewId: string) => {
|
||||
await apolloClient.mutate({
|
||||
mutation: deleteOneMutation,
|
||||
variables: {
|
||||
idToDelete: viewId,
|
||||
},
|
||||
refetchQueries: [findManyQuery],
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
createView,
|
||||
deleteView,
|
||||
isFetchingViews: false,
|
||||
updateView,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user