Refactor/finish activities optimistic (#4106)
* Finished optimistic effects * Fixed tests * Added unit test on useActivityConnectionUtils to prepare for refactor * Fixed console.log
This commit is contained in:
@ -5,7 +5,7 @@ import { useSetRecoilState } from 'recoil';
|
|||||||
|
|
||||||
import { ActivityActionBar } from '@/activities/right-drawer/components/ActivityActionBar';
|
import { ActivityActionBar } from '@/activities/right-drawer/components/ActivityActionBar';
|
||||||
import { viewableActivityIdState } from '@/activities/states/viewableActivityIdState';
|
import { viewableActivityIdState } from '@/activities/states/viewableActivityIdState';
|
||||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
|
||||||
import { avatarUrl } from '~/testing/mock-data/users';
|
import { avatarUrl } from '~/testing/mock-data/users';
|
||||||
|
|
||||||
import { CommentHeader } from '../CommentHeader';
|
import { CommentHeader } from '../CommentHeader';
|
||||||
@ -32,7 +32,7 @@ const meta: Meta<typeof CommentHeader> = {
|
|||||||
<Story />
|
<Story />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
ComponentDecorator,
|
ComponentWithRouterDecorator,
|
||||||
],
|
],
|
||||||
argTypes: {
|
argTypes: {
|
||||||
actionBar: {
|
actionBar: {
|
||||||
|
|||||||
@ -0,0 +1,119 @@
|
|||||||
|
import { renderHook } from '@testing-library/react';
|
||||||
|
import { RecoilRoot } from 'recoil';
|
||||||
|
|
||||||
|
import { useActivityConnectionUtils } from '@/activities/hooks/useActivityConnectionUtils';
|
||||||
|
import { Comment } from '@/activities/types/Comment';
|
||||||
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
|
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||||
|
import { ObjectRecordEdge } from '@/object-record/types/ObjectRecordEdge';
|
||||||
|
|
||||||
|
const mockActivityWithConnectionRelation = {
|
||||||
|
activityTargets: {
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
__typename: 'ActivityTargetEdge',
|
||||||
|
node: {
|
||||||
|
id: '20202020-1029-4661-9e91-83bad932bdff',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
pageInfo: {
|
||||||
|
hasNextPage: false,
|
||||||
|
hasPreviousPage: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
comments: {
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
__typename: 'CommentEdge',
|
||||||
|
node: {
|
||||||
|
id: '20202020-1029-4661-9e91-83bad932bdee',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as ObjectRecordEdge<Comment>[],
|
||||||
|
pageInfo: {
|
||||||
|
hasNextPage: false,
|
||||||
|
hasPreviousPage: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockActivityWithArrayRelation = {
|
||||||
|
activityTargets: [
|
||||||
|
{
|
||||||
|
id: '20202020-1029-4661-9e91-83bad932bdff',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
comments: [
|
||||||
|
{
|
||||||
|
id: '20202020-1029-4661-9e91-83bad932bdee',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('useActivityConnectionUtils', () => {
|
||||||
|
it('Should turn activity with connection relation in activity with array relation', async () => {
|
||||||
|
const { result } = renderHook(() => useActivityConnectionUtils(), {
|
||||||
|
wrapper: ({ children }) => (
|
||||||
|
<RecoilRoot
|
||||||
|
initializeState={(snapshot) => {
|
||||||
|
snapshot.set(
|
||||||
|
objectMetadataItemsState,
|
||||||
|
getObjectMetadataItemsMock(),
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</RecoilRoot>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
const { makeActivityWithoutConnection } = result.current;
|
||||||
|
|
||||||
|
const { activity: activityWithArrayRelation } =
|
||||||
|
makeActivityWithoutConnection(mockActivityWithConnectionRelation as any);
|
||||||
|
|
||||||
|
expect(activityWithArrayRelation).toBeDefined();
|
||||||
|
|
||||||
|
expect(activityWithArrayRelation.activityTargets[0].id).toEqual(
|
||||||
|
mockActivityWithArrayRelation.activityTargets[0].id,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should turn activity with connection relation in activity with array relation', async () => {
|
||||||
|
const { result } = renderHook(() => useActivityConnectionUtils(), {
|
||||||
|
wrapper: ({ children }) => (
|
||||||
|
<RecoilRoot
|
||||||
|
initializeState={(snapshot) => {
|
||||||
|
snapshot.set(
|
||||||
|
objectMetadataItemsState,
|
||||||
|
getObjectMetadataItemsMock(),
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</RecoilRoot>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
const { makeActivityWithConnection } = result.current;
|
||||||
|
|
||||||
|
const { activityWithConnection } = makeActivityWithConnection(
|
||||||
|
mockActivityWithArrayRelation as any,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(activityWithConnection).toBeDefined();
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
JSON.stringify({
|
||||||
|
mockActivityWithConnectionRelation,
|
||||||
|
activityWithConnection,
|
||||||
|
mockActivityWithArrayRelation,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(activityWithConnection.activityTargets.edges[0].node.id).toEqual(
|
||||||
|
mockActivityWithConnectionRelation.activityTargets.edges[0].node.id,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -2,10 +2,10 @@ import { useEffect, useState } from 'react';
|
|||||||
import { isNonEmptyArray, isNonEmptyString } from '@sniptt/guards';
|
import { isNonEmptyArray, isNonEmptyString } from '@sniptt/guards';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
|
import { useActivityConnectionUtils } from '@/activities/hooks/useActivityConnectionUtils';
|
||||||
import { useActivityTargetsForTargetableObjects } from '@/activities/hooks/useActivityTargetsForTargetableObjects';
|
import { useActivityTargetsForTargetableObjects } from '@/activities/hooks/useActivityTargetsForTargetableObjects';
|
||||||
import { Activity } from '@/activities/types/Activity';
|
import { Activity } from '@/activities/types/Activity';
|
||||||
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { useActivityConnectionUtils } from '@/activities/utils/useActivityConnectionUtils';
|
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { OrderByField } from '@/object-metadata/types/OrderByField';
|
import { OrderByField } from '@/object-metadata/types/OrderByField';
|
||||||
import { getRecordsFromRecordConnection } from '@/object-record/cache/utils/getRecordsFromRecordConnection';
|
import { getRecordsFromRecordConnection } from '@/object-record/cache/utils/getRecordsFromRecordConnection';
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useActivityConnectionUtils } from '@/activities/utils/useActivityConnectionUtils';
|
import { useActivityConnectionUtils } from '@/activities/hooks/useActivityConnectionUtils';
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import { isNonEmptyArray } from '@sniptt/guards';
|
import { isNonEmptyArray } from '@sniptt/guards';
|
||||||
|
|
||||||
import { useModifyActivityTargetsOnActivityCache } from '@/activities/hooks/useModifyActivityTargetsOnActivityCache';
|
import { useActivityConnectionUtils } from '@/activities/hooks/useActivityConnectionUtils';
|
||||||
import { ActivityForEditor } from '@/activities/types/ActivityForEditor';
|
import { ActivityForEditor } from '@/activities/types/ActivityForEditor';
|
||||||
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
||||||
import { useActivityConnectionUtils } from '@/activities/utils/useActivityConnectionUtils';
|
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { useCreateManyRecords } from '@/object-record/hooks/useCreateManyRecords';
|
import { useCreateManyRecords } from '@/object-record/hooks/useCreateManyRecords';
|
||||||
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
|
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
|
||||||
@ -20,9 +19,6 @@ export const useCreateActivityInDB = () => {
|
|||||||
|
|
||||||
const { makeActivityWithConnection } = useActivityConnectionUtils();
|
const { makeActivityWithConnection } = useActivityConnectionUtils();
|
||||||
|
|
||||||
const { modifyActivityTargetsOnActivityCache } =
|
|
||||||
useModifyActivityTargetsOnActivityCache();
|
|
||||||
|
|
||||||
const createActivityInDB = async (activityToCreate: ActivityForEditor) => {
|
const createActivityInDB = async (activityToCreate: ActivityForEditor) => {
|
||||||
const { activityWithConnection } = makeActivityWithConnection(
|
const { activityWithConnection } = makeActivityWithConnection(
|
||||||
activityToCreate as any, // TODO: fix type
|
activityToCreate as any, // TODO: fix type
|
||||||
@ -45,12 +41,6 @@ export const useCreateActivityInDB = () => {
|
|||||||
skipOptimisticEffect: true,
|
skipOptimisticEffect: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: replace by trigger optimistic effect
|
|
||||||
modifyActivityTargetsOnActivityCache({
|
|
||||||
activityId: activityToCreate.id,
|
|
||||||
activityTargets: activityTargetsToCreate,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useApolloClient } from '@apollo/client';
|
import { useApolloClient } from '@apollo/client';
|
||||||
|
|
||||||
|
import { useActivityConnectionUtils } from '@/activities/hooks/useActivityConnectionUtils';
|
||||||
import { ActivityForEditor } from '@/activities/types/ActivityForEditor';
|
import { ActivityForEditor } from '@/activities/types/ActivityForEditor';
|
||||||
import { useActivityConnectionUtils } from '@/activities/utils/useActivityConnectionUtils';
|
|
||||||
import { triggerDeleteRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerDeleteRecordsOptimisticEffect';
|
import { triggerDeleteRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerDeleteRecordsOptimisticEffect';
|
||||||
import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly';
|
import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly';
|
||||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||||
|
|||||||
@ -0,0 +1,175 @@
|
|||||||
|
import { isNonEmptyArray, isNonEmptyString } from '@sniptt/guards';
|
||||||
|
|
||||||
|
import { Activity } from '@/activities/types/Activity';
|
||||||
|
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
||||||
|
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||||
|
import { getActivityTargetsFilter } from '@/activities/utils/getActivityTargetsFilter';
|
||||||
|
import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly';
|
||||||
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
|
import { OrderByField } from '@/object-metadata/types/OrderByField';
|
||||||
|
import { useReadFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useReadFindManyRecordsQueryInCache';
|
||||||
|
import { useUpsertFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useUpsertFindManyRecordsQueryInCache';
|
||||||
|
import { ObjectRecordQueryFilter } from '@/object-record/record-filter/types/ObjectRecordQueryFilter';
|
||||||
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
|
import { sortByAscString } from '~/utils/array/sortByAscString';
|
||||||
|
|
||||||
|
// TODO: create a generic hook from this
|
||||||
|
export const useInjectIntoActivitiesQueries = () => {
|
||||||
|
const { objectMetadataItem: objectMetadataItemActivity } =
|
||||||
|
useObjectMetadataItemOnly({
|
||||||
|
objectNameSingular: CoreObjectNameSingular.Activity,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
upsertFindManyRecordsQueryInCache: overwriteFindManyActivitiesInCache,
|
||||||
|
} = useUpsertFindManyRecordsQueryInCache({
|
||||||
|
objectMetadataItem: objectMetadataItemActivity,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { objectMetadataItem: objectMetadataItemActivityTarget } =
|
||||||
|
useObjectMetadataItemOnly({
|
||||||
|
objectNameSingular: CoreObjectNameSingular.ActivityTarget,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
readFindManyRecordsQueryInCache: readFindManyActivityTargetsQueryInCache,
|
||||||
|
} = useReadFindManyRecordsQueryInCache({
|
||||||
|
objectMetadataItem: objectMetadataItemActivityTarget,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
readFindManyRecordsQueryInCache: readFindManyActivitiesQueryInCache,
|
||||||
|
} = useReadFindManyRecordsQueryInCache({
|
||||||
|
objectMetadataItem: objectMetadataItemActivity,
|
||||||
|
});
|
||||||
|
|
||||||
|
const injectActivitiesQueries = ({
|
||||||
|
activityToInject,
|
||||||
|
activityTargetsToInject,
|
||||||
|
targetableObjects,
|
||||||
|
activitiesFilters,
|
||||||
|
activitiesOrderByVariables,
|
||||||
|
injectOnlyInIdFilter,
|
||||||
|
}: {
|
||||||
|
activityToInject: Activity;
|
||||||
|
activityTargetsToInject: ActivityTarget[];
|
||||||
|
targetableObjects: ActivityTargetableObject[];
|
||||||
|
activitiesFilters?: ObjectRecordQueryFilter;
|
||||||
|
activitiesOrderByVariables?: OrderByField;
|
||||||
|
injectOnlyInIdFilter?: boolean;
|
||||||
|
}) => {
|
||||||
|
const hasActivityTargets = isNonEmptyArray(targetableObjects);
|
||||||
|
|
||||||
|
if (hasActivityTargets) {
|
||||||
|
const findManyActivitiyTargetsQueryFilter = getActivityTargetsFilter({
|
||||||
|
targetableObjects,
|
||||||
|
});
|
||||||
|
|
||||||
|
const findManyActivitiyTargetsQueryVariables = {
|
||||||
|
filter: findManyActivitiyTargetsQueryFilter,
|
||||||
|
};
|
||||||
|
|
||||||
|
const existingActivityTargetsWithMaybeDuplicates =
|
||||||
|
readFindManyActivityTargetsQueryInCache({
|
||||||
|
queryVariables: findManyActivitiyTargetsQueryVariables,
|
||||||
|
});
|
||||||
|
|
||||||
|
const existingActivityTargetsWithoutDuplicates: ObjectRecord[] =
|
||||||
|
existingActivityTargetsWithMaybeDuplicates.filter(
|
||||||
|
(existingActivityTarget) =>
|
||||||
|
!activityTargetsToInject.some(
|
||||||
|
(activityTargetToInject) =>
|
||||||
|
activityTargetToInject.id === existingActivityTarget.id,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const existingActivityIdsFromTargets =
|
||||||
|
existingActivityTargetsWithoutDuplicates
|
||||||
|
?.map((activityTarget) => activityTarget.activityId)
|
||||||
|
.filter(isNonEmptyString);
|
||||||
|
|
||||||
|
const currentFindManyActivitiesQueryVariables = {
|
||||||
|
filter: {
|
||||||
|
id: {
|
||||||
|
in: existingActivityIdsFromTargets.toSorted(sortByAscString),
|
||||||
|
},
|
||||||
|
...activitiesFilters,
|
||||||
|
},
|
||||||
|
orderBy: activitiesOrderByVariables,
|
||||||
|
};
|
||||||
|
|
||||||
|
const existingActivities = readFindManyActivitiesQueryInCache({
|
||||||
|
queryVariables: currentFindManyActivitiesQueryVariables,
|
||||||
|
});
|
||||||
|
|
||||||
|
const nextActivityIds = [
|
||||||
|
...existingActivityIdsFromTargets,
|
||||||
|
activityToInject.id,
|
||||||
|
];
|
||||||
|
|
||||||
|
const nextFindManyActivitiesQueryVariables = {
|
||||||
|
filter: {
|
||||||
|
id: {
|
||||||
|
in: nextActivityIds.toSorted(sortByAscString),
|
||||||
|
},
|
||||||
|
...activitiesFilters,
|
||||||
|
},
|
||||||
|
orderBy: activitiesOrderByVariables,
|
||||||
|
};
|
||||||
|
|
||||||
|
const newActivities = [...existingActivities];
|
||||||
|
|
||||||
|
if (!injectOnlyInIdFilter) {
|
||||||
|
const newActivity = {
|
||||||
|
...activityToInject,
|
||||||
|
__typename: 'Activity',
|
||||||
|
};
|
||||||
|
|
||||||
|
newActivities.unshift(newActivity);
|
||||||
|
}
|
||||||
|
|
||||||
|
overwriteFindManyActivitiesInCache({
|
||||||
|
objectRecordsToOverwrite: newActivities,
|
||||||
|
queryVariables: nextFindManyActivitiesQueryVariables,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const currentFindManyActivitiesQueryVariables = {
|
||||||
|
filter: {
|
||||||
|
...activitiesFilters,
|
||||||
|
},
|
||||||
|
orderBy: activitiesOrderByVariables,
|
||||||
|
};
|
||||||
|
|
||||||
|
const existingActivities = readFindManyActivitiesQueryInCache({
|
||||||
|
queryVariables: currentFindManyActivitiesQueryVariables,
|
||||||
|
});
|
||||||
|
|
||||||
|
const nextFindManyActivitiesQueryVariables = {
|
||||||
|
filter: {
|
||||||
|
...activitiesFilters,
|
||||||
|
},
|
||||||
|
orderBy: activitiesOrderByVariables,
|
||||||
|
};
|
||||||
|
|
||||||
|
const newActivities = [...existingActivities];
|
||||||
|
|
||||||
|
if (!injectOnlyInIdFilter) {
|
||||||
|
const newActivity = {
|
||||||
|
...activityToInject,
|
||||||
|
__typename: 'Activity',
|
||||||
|
};
|
||||||
|
|
||||||
|
newActivities.unshift(newActivity);
|
||||||
|
}
|
||||||
|
|
||||||
|
overwriteFindManyActivitiesInCache({
|
||||||
|
objectRecordsToOverwrite: newActivities,
|
||||||
|
queryVariables: nextFindManyActivitiesQueryVariables,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
injectActivitiesQueries,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -1,133 +0,0 @@
|
|||||||
import { isNonEmptyString } from '@sniptt/guards';
|
|
||||||
|
|
||||||
import { Activity } from '@/activities/types/Activity';
|
|
||||||
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
|
||||||
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
|
||||||
import { getActivityTargetsFilter } from '@/activities/utils/getActivityTargetsFilter';
|
|
||||||
import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly';
|
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
|
||||||
import { OrderByField } from '@/object-metadata/types/OrderByField';
|
|
||||||
import { useReadFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useReadFindManyRecordsQueryInCache';
|
|
||||||
import { useUpsertFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useUpsertFindManyRecordsQueryInCache';
|
|
||||||
import { ObjectRecordQueryFilter } from '@/object-record/record-filter/types/ObjectRecordQueryFilter';
|
|
||||||
import { sortByAscString } from '~/utils/array/sortByAscString';
|
|
||||||
|
|
||||||
// TODO: create a generic hook from this
|
|
||||||
export const useInjectIntoActivitiesQuery = () => {
|
|
||||||
const { objectMetadataItem: objectMetadataItemActivity } =
|
|
||||||
useObjectMetadataItemOnly({
|
|
||||||
objectNameSingular: CoreObjectNameSingular.Activity,
|
|
||||||
});
|
|
||||||
|
|
||||||
const {
|
|
||||||
upsertFindManyRecordsQueryInCache: overwriteFindManyActivitiesInCache,
|
|
||||||
} = useUpsertFindManyRecordsQueryInCache({
|
|
||||||
objectMetadataItem: objectMetadataItemActivity,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { objectMetadataItem: objectMetadataItemActivityTarget } =
|
|
||||||
useObjectMetadataItemOnly({
|
|
||||||
objectNameSingular: CoreObjectNameSingular.ActivityTarget,
|
|
||||||
});
|
|
||||||
|
|
||||||
const {
|
|
||||||
readFindManyRecordsQueryInCache: readFindManyActivityTargetsQueryInCache,
|
|
||||||
} = useReadFindManyRecordsQueryInCache({
|
|
||||||
objectMetadataItem: objectMetadataItemActivityTarget,
|
|
||||||
});
|
|
||||||
|
|
||||||
const {
|
|
||||||
readFindManyRecordsQueryInCache: readFindManyActivitiesQueryInCache,
|
|
||||||
} = useReadFindManyRecordsQueryInCache({
|
|
||||||
objectMetadataItem: objectMetadataItemActivity,
|
|
||||||
});
|
|
||||||
|
|
||||||
const {
|
|
||||||
upsertFindManyRecordsQueryInCache:
|
|
||||||
overwriteFindManyActivityTargetsQueryInCache,
|
|
||||||
} = useUpsertFindManyRecordsQueryInCache({
|
|
||||||
objectMetadataItem: objectMetadataItemActivityTarget,
|
|
||||||
});
|
|
||||||
|
|
||||||
const injectActivitiesQueries = ({
|
|
||||||
activityToInject,
|
|
||||||
activityTargetsToInject,
|
|
||||||
targetableObjects,
|
|
||||||
activitiesFilters,
|
|
||||||
activitiesOrderByVariables,
|
|
||||||
}: {
|
|
||||||
activityToInject: Activity;
|
|
||||||
activityTargetsToInject: ActivityTarget[];
|
|
||||||
targetableObjects: ActivityTargetableObject[];
|
|
||||||
activitiesFilters: ObjectRecordQueryFilter;
|
|
||||||
activitiesOrderByVariables: OrderByField;
|
|
||||||
}) => {
|
|
||||||
const newActivity = {
|
|
||||||
...activityToInject,
|
|
||||||
__typename: 'Activity',
|
|
||||||
};
|
|
||||||
|
|
||||||
const findManyActivitiyTargetsQueryFilter = getActivityTargetsFilter({
|
|
||||||
targetableObjects,
|
|
||||||
});
|
|
||||||
|
|
||||||
const findManyActivitiyTargetsQueryVariables = {
|
|
||||||
filter: findManyActivitiyTargetsQueryFilter,
|
|
||||||
};
|
|
||||||
|
|
||||||
const existingActivityTargets = readFindManyActivityTargetsQueryInCache({
|
|
||||||
queryVariables: findManyActivitiyTargetsQueryVariables,
|
|
||||||
});
|
|
||||||
|
|
||||||
const newActivityTargets = [
|
|
||||||
...existingActivityTargets,
|
|
||||||
...activityTargetsToInject,
|
|
||||||
];
|
|
||||||
|
|
||||||
const existingActivityIds = existingActivityTargets
|
|
||||||
?.map((activityTarget) => activityTarget.activityId)
|
|
||||||
.filter(isNonEmptyString);
|
|
||||||
|
|
||||||
const currentFindManyActivitiesQueryVariables = {
|
|
||||||
filter: {
|
|
||||||
id: {
|
|
||||||
in: existingActivityIds.toSorted(sortByAscString),
|
|
||||||
},
|
|
||||||
...activitiesFilters,
|
|
||||||
},
|
|
||||||
orderBy: activitiesOrderByVariables,
|
|
||||||
};
|
|
||||||
|
|
||||||
const existingActivities = readFindManyActivitiesQueryInCache({
|
|
||||||
queryVariables: currentFindManyActivitiesQueryVariables,
|
|
||||||
});
|
|
||||||
|
|
||||||
const nextActivityIds = [...existingActivityIds, newActivity.id];
|
|
||||||
|
|
||||||
const nextFindManyActivitiesQueryVariables = {
|
|
||||||
filter: {
|
|
||||||
id: {
|
|
||||||
in: nextActivityIds.toSorted(sortByAscString),
|
|
||||||
},
|
|
||||||
...activitiesFilters,
|
|
||||||
},
|
|
||||||
orderBy: activitiesOrderByVariables,
|
|
||||||
};
|
|
||||||
|
|
||||||
overwriteFindManyActivityTargetsQueryInCache({
|
|
||||||
objectRecordsToOverwrite: newActivityTargets,
|
|
||||||
queryVariables: findManyActivitiyTargetsQueryVariables,
|
|
||||||
});
|
|
||||||
|
|
||||||
const newActivities = [newActivity, ...existingActivities];
|
|
||||||
|
|
||||||
overwriteFindManyActivitiesInCache({
|
|
||||||
objectRecordsToOverwrite: newActivities,
|
|
||||||
queryVariables: nextFindManyActivitiesQueryVariables,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
injectActivitiesQueries,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
import { isNonEmptyArray } from '@sniptt/guards';
|
||||||
|
|
||||||
|
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
||||||
|
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||||
|
import { getActivityTargetsFilter } from '@/activities/utils/getActivityTargetsFilter';
|
||||||
|
import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly';
|
||||||
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
|
import { useReadFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useReadFindManyRecordsQueryInCache';
|
||||||
|
import { useUpsertFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useUpsertFindManyRecordsQueryInCache';
|
||||||
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
|
|
||||||
|
// TODO: create a generic hook from this
|
||||||
|
export const useInjectIntoActivityTargetsQueries = () => {
|
||||||
|
const { objectMetadataItem: objectMetadataItemActivityTarget } =
|
||||||
|
useObjectMetadataItemOnly({
|
||||||
|
objectNameSingular: CoreObjectNameSingular.ActivityTarget,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
readFindManyRecordsQueryInCache: readFindManyActivityTargetsQueryInCache,
|
||||||
|
} = useReadFindManyRecordsQueryInCache({
|
||||||
|
objectMetadataItem: objectMetadataItemActivityTarget,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
upsertFindManyRecordsQueryInCache:
|
||||||
|
overwriteFindManyActivityTargetsQueryInCache,
|
||||||
|
} = useUpsertFindManyRecordsQueryInCache({
|
||||||
|
objectMetadataItem: objectMetadataItemActivityTarget,
|
||||||
|
});
|
||||||
|
|
||||||
|
const injectActivityTargetsQueries = ({
|
||||||
|
activityTargetsToInject,
|
||||||
|
targetableObjects,
|
||||||
|
}: {
|
||||||
|
activityTargetsToInject: ActivityTarget[];
|
||||||
|
targetableObjects: ActivityTargetableObject[];
|
||||||
|
}) => {
|
||||||
|
const hasActivityTargets = isNonEmptyArray(targetableObjects);
|
||||||
|
|
||||||
|
if (!hasActivityTargets) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const findManyActivitiyTargetsQueryFilter = getActivityTargetsFilter({
|
||||||
|
targetableObjects,
|
||||||
|
});
|
||||||
|
|
||||||
|
const findManyActivitiyTargetsQueryVariables = {
|
||||||
|
filter: findManyActivitiyTargetsQueryFilter,
|
||||||
|
};
|
||||||
|
|
||||||
|
const existingActivityTargetsWithMaybeDuplicates =
|
||||||
|
readFindManyActivityTargetsQueryInCache({
|
||||||
|
queryVariables: findManyActivitiyTargetsQueryVariables,
|
||||||
|
});
|
||||||
|
|
||||||
|
const existingActivityTargetsWithoutDuplicates: ObjectRecord[] =
|
||||||
|
existingActivityTargetsWithMaybeDuplicates.filter(
|
||||||
|
(existingActivityTarget) =>
|
||||||
|
!activityTargetsToInject.some(
|
||||||
|
(activityTargetToInject) =>
|
||||||
|
activityTargetToInject.id === existingActivityTarget.id,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const newActivityTargets = [
|
||||||
|
...existingActivityTargetsWithoutDuplicates,
|
||||||
|
...activityTargetsToInject,
|
||||||
|
];
|
||||||
|
|
||||||
|
overwriteFindManyActivityTargetsQueryInCache({
|
||||||
|
objectRecordsToOverwrite: newActivityTargets,
|
||||||
|
queryVariables: findManyActivitiyTargetsQueryVariables,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
injectActivityTargetsQueries,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -1,6 +1,5 @@
|
|||||||
import { isNonEmptyArray, isNonEmptyString } from '@sniptt/guards';
|
import { isNonEmptyArray, isNonEmptyString } from '@sniptt/guards';
|
||||||
|
|
||||||
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
|
||||||
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { getActivityTargetsFilter } from '@/activities/utils/getActivityTargetsFilter';
|
import { getActivityTargetsFilter } from '@/activities/utils/getActivityTargetsFilter';
|
||||||
import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly';
|
import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly';
|
||||||
@ -9,8 +8,10 @@ import { OrderByField } from '@/object-metadata/types/OrderByField';
|
|||||||
import { useReadFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useReadFindManyRecordsQueryInCache';
|
import { useReadFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useReadFindManyRecordsQueryInCache';
|
||||||
import { useUpsertFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useUpsertFindManyRecordsQueryInCache';
|
import { useUpsertFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useUpsertFindManyRecordsQueryInCache';
|
||||||
import { ObjectRecordQueryFilter } from '@/object-record/record-filter/types/ObjectRecordQueryFilter';
|
import { ObjectRecordQueryFilter } from '@/object-record/record-filter/types/ObjectRecordQueryFilter';
|
||||||
|
import { ObjectRecordQueryVariables } from '@/object-record/types/ObjectRecordQueryVariables';
|
||||||
import { sortByAscString } from '~/utils/array/sortByAscString';
|
import { sortByAscString } from '~/utils/array/sortByAscString';
|
||||||
|
|
||||||
|
// TODO: improve, no bug if query to inject doesn't exist
|
||||||
export const useRemoveFromActivitiesQueries = () => {
|
export const useRemoveFromActivitiesQueries = () => {
|
||||||
const { objectMetadataItem: objectMetadataItemActivity } =
|
const { objectMetadataItem: objectMetadataItemActivity } =
|
||||||
useObjectMetadataItemOnly({
|
useObjectMetadataItemOnly({
|
||||||
@ -40,22 +41,13 @@ export const useRemoveFromActivitiesQueries = () => {
|
|||||||
objectMetadataItem: objectMetadataItemActivity,
|
objectMetadataItem: objectMetadataItemActivity,
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
|
||||||
upsertFindManyRecordsQueryInCache:
|
|
||||||
overwriteFindManyActivityTargetsQueryInCache,
|
|
||||||
} = useUpsertFindManyRecordsQueryInCache({
|
|
||||||
objectMetadataItem: objectMetadataItemActivityTarget,
|
|
||||||
});
|
|
||||||
|
|
||||||
const removeFromActivitiesQueries = ({
|
const removeFromActivitiesQueries = ({
|
||||||
activityIdToRemove,
|
activityIdToRemove,
|
||||||
activityTargetsToRemove,
|
|
||||||
targetableObjects,
|
targetableObjects,
|
||||||
activitiesFilters,
|
activitiesFilters,
|
||||||
activitiesOrderByVariables,
|
activitiesOrderByVariables,
|
||||||
}: {
|
}: {
|
||||||
activityIdToRemove: string;
|
activityIdToRemove: string;
|
||||||
activityTargetsToRemove: ActivityTarget[];
|
|
||||||
targetableObjects: ActivityTargetableObject[];
|
targetableObjects: ActivityTargetableObject[];
|
||||||
activitiesFilters?: ObjectRecordQueryFilter;
|
activitiesFilters?: ObjectRecordQueryFilter;
|
||||||
activitiesOrderByVariables?: OrderByField;
|
activitiesOrderByVariables?: OrderByField;
|
||||||
@ -64,28 +56,15 @@ export const useRemoveFromActivitiesQueries = () => {
|
|||||||
targetableObjects,
|
targetableObjects,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const findManyActivityTargetsQueryVariables = {
|
||||||
|
filter: findManyActivitiyTargetsQueryFilter,
|
||||||
|
} as ObjectRecordQueryVariables;
|
||||||
|
|
||||||
const existingActivityTargetsForTargetableObject =
|
const existingActivityTargetsForTargetableObject =
|
||||||
readFindManyActivityTargetsQueryInCache({
|
readFindManyActivityTargetsQueryInCache({
|
||||||
queryVariables: findManyActivitiyTargetsQueryFilter,
|
queryVariables: findManyActivityTargetsQueryVariables,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newActivityTargetsForTargetableObject = isNonEmptyArray(
|
|
||||||
activityTargetsToRemove,
|
|
||||||
)
|
|
||||||
? existingActivityTargetsForTargetableObject.filter(
|
|
||||||
(existingActivityTarget) =>
|
|
||||||
activityTargetsToRemove.some(
|
|
||||||
(activityTargetToRemove) =>
|
|
||||||
activityTargetToRemove.id !== existingActivityTarget.id,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: existingActivityTargetsForTargetableObject;
|
|
||||||
|
|
||||||
overwriteFindManyActivityTargetsQueryInCache({
|
|
||||||
objectRecordsToOverwrite: newActivityTargetsForTargetableObject,
|
|
||||||
queryVariables: findManyActivitiyTargetsQueryFilter,
|
|
||||||
});
|
|
||||||
|
|
||||||
const existingActivityIds = existingActivityTargetsForTargetableObject
|
const existingActivityIds = existingActivityTargetsForTargetableObject
|
||||||
?.map((activityTarget) => activityTarget.activityId)
|
?.map((activityTarget) => activityTarget.activityId)
|
||||||
.filter(isNonEmptyString);
|
.filter(isNonEmptyString);
|
||||||
@ -104,6 +83,10 @@ export const useRemoveFromActivitiesQueries = () => {
|
|||||||
queryVariables: currentFindManyActivitiesQueryVariables,
|
queryVariables: currentFindManyActivitiesQueryVariables,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!isNonEmptyArray(existingActivities)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const activityIdsAfterRemoval = existingActivityIds.filter(
|
const activityIdsAfterRemoval = existingActivityIds.filter(
|
||||||
(existingActivityId) => existingActivityId !== activityIdToRemove,
|
(existingActivityId) => existingActivityId !== activityIdToRemove,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -0,0 +1,72 @@
|
|||||||
|
import { isNonEmptyArray } from '@sniptt/guards';
|
||||||
|
|
||||||
|
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
||||||
|
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||||
|
import { getActivityTargetsFilter } from '@/activities/utils/getActivityTargetsFilter';
|
||||||
|
import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly';
|
||||||
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
|
import { useReadFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useReadFindManyRecordsQueryInCache';
|
||||||
|
import { useUpsertFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useUpsertFindManyRecordsQueryInCache';
|
||||||
|
import { ObjectRecordQueryVariables } from '@/object-record/types/ObjectRecordQueryVariables';
|
||||||
|
|
||||||
|
export const useRemoveFromActivityTargetsQueries = () => {
|
||||||
|
const { objectMetadataItem: objectMetadataItemActivityTarget } =
|
||||||
|
useObjectMetadataItemOnly({
|
||||||
|
objectNameSingular: CoreObjectNameSingular.ActivityTarget,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
readFindManyRecordsQueryInCache: readFindManyActivityTargetsQueryInCache,
|
||||||
|
} = useReadFindManyRecordsQueryInCache({
|
||||||
|
objectMetadataItem: objectMetadataItemActivityTarget,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
upsertFindManyRecordsQueryInCache:
|
||||||
|
overwriteFindManyActivityTargetsQueryInCache,
|
||||||
|
} = useUpsertFindManyRecordsQueryInCache({
|
||||||
|
objectMetadataItem: objectMetadataItemActivityTarget,
|
||||||
|
});
|
||||||
|
|
||||||
|
const removeFromActivityTargetsQueries = ({
|
||||||
|
activityTargetsToRemove,
|
||||||
|
targetableObjects,
|
||||||
|
}: {
|
||||||
|
activityTargetsToRemove: ActivityTarget[];
|
||||||
|
targetableObjects: ActivityTargetableObject[];
|
||||||
|
}) => {
|
||||||
|
const findManyActivitiyTargetsQueryFilter = getActivityTargetsFilter({
|
||||||
|
targetableObjects,
|
||||||
|
});
|
||||||
|
|
||||||
|
const findManyActivityTargetsQueryVariables = {
|
||||||
|
filter: findManyActivitiyTargetsQueryFilter,
|
||||||
|
} as ObjectRecordQueryVariables;
|
||||||
|
|
||||||
|
const existingActivityTargetsForTargetableObject =
|
||||||
|
readFindManyActivityTargetsQueryInCache({
|
||||||
|
queryVariables: findManyActivityTargetsQueryVariables,
|
||||||
|
});
|
||||||
|
|
||||||
|
const newActivityTargetsForTargetableObject = isNonEmptyArray(
|
||||||
|
activityTargetsToRemove,
|
||||||
|
)
|
||||||
|
? existingActivityTargetsForTargetableObject.filter(
|
||||||
|
(existingActivityTarget) =>
|
||||||
|
activityTargetsToRemove.some(
|
||||||
|
(activityTargetToRemove) =>
|
||||||
|
activityTargetToRemove.id !== existingActivityTarget.id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: existingActivityTargetsForTargetableObject;
|
||||||
|
|
||||||
|
overwriteFindManyActivityTargetsQueryInCache({
|
||||||
|
objectRecordsToOverwrite: newActivityTargetsForTargetableObject,
|
||||||
|
queryVariables: findManyActivityTargetsQueryVariables,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
removeFromActivityTargetsQueries,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -1,16 +1,22 @@
|
|||||||
import { useApolloClient } from '@apollo/client';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { useActivityConnectionUtils } from '@/activities/hooks/useActivityConnectionUtils';
|
||||||
import { useCreateActivityInDB } from '@/activities/hooks/useCreateActivityInDB';
|
import { useCreateActivityInDB } from '@/activities/hooks/useCreateActivityInDB';
|
||||||
|
import { useInjectIntoActivitiesQueries } from '@/activities/hooks/useInjectIntoActivitiesQueries';
|
||||||
|
import { useInjectIntoActivityTargetsQueries } from '@/activities/hooks/useInjectIntoActivityTargetsQueries';
|
||||||
|
import { currentNotesQueryVariablesState } from '@/activities/notes/states/currentNotesQueryVariablesState';
|
||||||
import { activityInDrawerState } from '@/activities/states/activityInDrawerState';
|
import { activityInDrawerState } from '@/activities/states/activityInDrawerState';
|
||||||
import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState';
|
import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState';
|
||||||
import { isUpsertingActivityInDBState } from '@/activities/states/isCreatingActivityInDBState';
|
import { isUpsertingActivityInDBState } from '@/activities/states/isCreatingActivityInDBState';
|
||||||
|
import { currentCompletedTaskQueryVariablesState } from '@/activities/tasks/states/currentCompletedTaskQueryVariablesState';
|
||||||
|
import { currentIncompleteTaskQueryVariablesState } from '@/activities/tasks/states/currentIncompleteTaskQueryVariablesState';
|
||||||
import { useInjectIntoTimelineActivitiesQueries } from '@/activities/timeline/hooks/useInjectIntoTimelineActivitiesQueries';
|
import { useInjectIntoTimelineActivitiesQueries } from '@/activities/timeline/hooks/useInjectIntoTimelineActivitiesQueries';
|
||||||
import { timelineTargetableObjectState } from '@/activities/timeline/states/timelineTargetableObjectState';
|
import { objectShowPageTargetableObjectState } from '@/activities/timeline/states/objectShowPageTargetableObjectState';
|
||||||
import { Activity } from '@/activities/types/Activity';
|
import { Activity } from '@/activities/types/Activity';
|
||||||
import { useActivityConnectionUtils } from '@/activities/utils/useActivityConnectionUtils';
|
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||||
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
// TODO: create a generic way to have records only in cache for create mode and delete them afterwards ?
|
// TODO: create a generic way to have records only in cache for create mode and delete them afterwards ?
|
||||||
export const useUpsertActivity = () => {
|
export const useUpsertActivity = () => {
|
||||||
@ -30,16 +36,35 @@ export const useUpsertActivity = () => {
|
|||||||
|
|
||||||
const setActivityInDrawer = useSetRecoilState(activityInDrawerState);
|
const setActivityInDrawer = useSetRecoilState(activityInDrawerState);
|
||||||
|
|
||||||
const timelineTargetableObject = useRecoilValue(
|
const objectShowPageTargetableObject = useRecoilValue(
|
||||||
timelineTargetableObjectState,
|
objectShowPageTargetableObjectState,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { injectActivitiesQueries } = useInjectIntoActivitiesQueries();
|
||||||
|
const { injectActivityTargetsQueries } =
|
||||||
|
useInjectIntoActivityTargetsQueries();
|
||||||
|
|
||||||
|
const { pathname } = useLocation();
|
||||||
|
|
||||||
|
const weAreOnObjectShowPage = pathname.startsWith('/object');
|
||||||
|
const weAreOnTaskPage = pathname.startsWith('/tasks');
|
||||||
|
|
||||||
const { injectIntoTimelineActivitiesQueries } =
|
const { injectIntoTimelineActivitiesQueries } =
|
||||||
useInjectIntoTimelineActivitiesQueries();
|
useInjectIntoTimelineActivitiesQueries();
|
||||||
|
|
||||||
const { makeActivityWithConnection } = useActivityConnectionUtils();
|
const { makeActivityWithConnection } = useActivityConnectionUtils();
|
||||||
|
|
||||||
const apolloClient = useApolloClient();
|
const currentCompletedTaskQueryVariables = useRecoilValue(
|
||||||
|
currentCompletedTaskQueryVariablesState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentIncompleteTaskQueryVariables = useRecoilValue(
|
||||||
|
currentIncompleteTaskQueryVariablesState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentNotesQueryVariables = useRecoilValue(
|
||||||
|
currentNotesQueryVariablesState,
|
||||||
|
);
|
||||||
|
|
||||||
const upsertActivity = async ({
|
const upsertActivity = async ({
|
||||||
activity,
|
activity,
|
||||||
@ -59,21 +84,91 @@ export const useUpsertActivity = () => {
|
|||||||
const { activityWithConnection } =
|
const { activityWithConnection } =
|
||||||
makeActivityWithConnection(activityToCreate);
|
makeActivityWithConnection(activityToCreate);
|
||||||
|
|
||||||
|
if (weAreOnTaskPage) {
|
||||||
|
if (isDefined(activityWithConnection.completedAt)) {
|
||||||
|
injectActivitiesQueries({
|
||||||
|
activitiesFilters: currentCompletedTaskQueryVariables?.filter,
|
||||||
|
activitiesOrderByVariables:
|
||||||
|
currentCompletedTaskQueryVariables?.orderBy,
|
||||||
|
activityTargetsToInject: activityToCreate.activityTargets,
|
||||||
|
activityToInject: activityWithConnection,
|
||||||
|
targetableObjects: [],
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
injectActivitiesQueries({
|
||||||
|
activitiesFilters: currentIncompleteTaskQueryVariables?.filter,
|
||||||
|
activitiesOrderByVariables:
|
||||||
|
currentIncompleteTaskQueryVariables?.orderBy,
|
||||||
|
activityTargetsToInject: activityToCreate.activityTargets,
|
||||||
|
activityToInject: activityWithConnection,
|
||||||
|
targetableObjects: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
injectActivityTargetsQueries({
|
||||||
|
activityTargetsToInject: activityToCreate.activityTargets,
|
||||||
|
targetableObjects: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Call optimistic effects
|
// Call optimistic effects
|
||||||
if (timelineTargetableObject) {
|
if (weAreOnObjectShowPage && objectShowPageTargetableObject) {
|
||||||
injectIntoTimelineActivitiesQueries({
|
injectIntoTimelineActivitiesQueries({
|
||||||
timelineTargetableObject: timelineTargetableObject,
|
timelineTargetableObject: objectShowPageTargetableObject,
|
||||||
activityToInject: activityWithConnection,
|
activityToInject: activityWithConnection,
|
||||||
activityTargetsToInject: activityToCreate.activityTargets,
|
activityTargetsToInject: activityToCreate.activityTargets,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const injectOnlyInIdFilterForTaskQueries =
|
||||||
|
activityWithConnection.type !== 'Task';
|
||||||
|
|
||||||
|
const injectOnlyInIdFilterForNotesQueries =
|
||||||
|
activityWithConnection.type !== 'Note';
|
||||||
|
|
||||||
|
if (isDefined(currentCompletedTaskQueryVariables)) {
|
||||||
|
injectActivitiesQueries({
|
||||||
|
activitiesFilters: currentCompletedTaskQueryVariables?.filter,
|
||||||
|
activitiesOrderByVariables:
|
||||||
|
currentCompletedTaskQueryVariables?.orderBy,
|
||||||
|
activityTargetsToInject: activityToCreate.activityTargets,
|
||||||
|
activityToInject: activityWithConnection,
|
||||||
|
targetableObjects: [objectShowPageTargetableObject],
|
||||||
|
injectOnlyInIdFilter: injectOnlyInIdFilterForTaskQueries,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDefined(currentIncompleteTaskQueryVariables)) {
|
||||||
|
injectActivitiesQueries({
|
||||||
|
activitiesFilters:
|
||||||
|
currentIncompleteTaskQueryVariables?.filter ?? {},
|
||||||
|
activitiesOrderByVariables:
|
||||||
|
currentIncompleteTaskQueryVariables?.orderBy ?? {},
|
||||||
|
activityTargetsToInject: activityToCreate.activityTargets,
|
||||||
|
activityToInject: activityWithConnection,
|
||||||
|
targetableObjects: [objectShowPageTargetableObject],
|
||||||
|
injectOnlyInIdFilter: injectOnlyInIdFilterForTaskQueries,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDefined(currentNotesQueryVariables)) {
|
||||||
|
injectActivitiesQueries({
|
||||||
|
activitiesFilters: currentNotesQueryVariables?.filter,
|
||||||
|
activitiesOrderByVariables: currentNotesQueryVariables?.orderBy,
|
||||||
|
activityTargetsToInject: activityToCreate.activityTargets,
|
||||||
|
activityToInject: activityWithConnection,
|
||||||
|
targetableObjects: [objectShowPageTargetableObject],
|
||||||
|
injectOnlyInIdFilter: injectOnlyInIdFilterForNotesQueries,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
injectActivityTargetsQueries({
|
||||||
|
activityTargetsToInject: activityToCreate.activityTargets,
|
||||||
|
targetableObjects: [objectShowPageTargetableObject],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await createActivityInDB(activityToCreate);
|
await createActivityInDB(activityToCreate);
|
||||||
|
|
||||||
await apolloClient.refetchQueries({
|
|
||||||
include: ['FindManyActivities', 'FindManyActivityTargets'],
|
|
||||||
});
|
|
||||||
|
|
||||||
setActivityInDrawer(activityToCreate);
|
setActivityInDrawer(activityToCreate);
|
||||||
|
|
||||||
setIsActivityInCreateMode(false);
|
setIsActivityInCreateMode(false);
|
||||||
|
|||||||
@ -1,18 +1,47 @@
|
|||||||
|
import { useEffect, useMemo } from 'react';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { useActivities } from '@/activities/hooks/useActivities';
|
import { useActivities } from '@/activities/hooks/useActivities';
|
||||||
|
import { currentNotesQueryVariablesState } from '@/activities/notes/states/currentNotesQueryVariablesState';
|
||||||
import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY';
|
import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY';
|
||||||
import { Note } from '@/activities/types/Note';
|
import { Note } from '@/activities/types/Note';
|
||||||
|
import { ObjectRecordQueryVariables } from '@/object-record/types/ObjectRecordQueryVariables';
|
||||||
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
|
|
||||||
import { ActivityTargetableObject } from '../../types/ActivityTargetableEntity';
|
import { ActivityTargetableObject } from '../../types/ActivityTargetableEntity';
|
||||||
|
|
||||||
export const useNotes = (targetableObject: ActivityTargetableObject) => {
|
export const useNotes = (targetableObject: ActivityTargetableObject) => {
|
||||||
|
const notesQueryVariables = useMemo(
|
||||||
|
() =>
|
||||||
|
({
|
||||||
|
filter: {
|
||||||
|
type: { eq: 'Note' },
|
||||||
|
},
|
||||||
|
orderBy: FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY,
|
||||||
|
}) as ObjectRecordQueryVariables,
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
const { activities, initialized, loading } = useActivities({
|
const { activities, initialized, loading } = useActivities({
|
||||||
activitiesFilters: {
|
activitiesFilters: notesQueryVariables.filter ?? {},
|
||||||
type: { eq: 'Note' },
|
activitiesOrderByVariables: notesQueryVariables.orderBy ?? {},
|
||||||
},
|
|
||||||
activitiesOrderByVariables: FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY,
|
|
||||||
targetableObjects: [targetableObject],
|
targetableObjects: [targetableObject],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [currentNotesQueryVariables, setCurrentNotesQueryVariables] =
|
||||||
|
useRecoilState(currentNotesQueryVariablesState);
|
||||||
|
|
||||||
|
// TODO: fix useEffect, remove with better pattern
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isDeeplyEqual(notesQueryVariables, currentNotesQueryVariables)) {
|
||||||
|
setCurrentNotesQueryVariables(notesQueryVariables);
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
notesQueryVariables,
|
||||||
|
currentNotesQueryVariables,
|
||||||
|
setCurrentNotesQueryVariables,
|
||||||
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
notes: activities as Note[],
|
notes: activities as Note[],
|
||||||
initialized,
|
initialized,
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
|
import { ObjectRecordQueryVariables } from '@/object-record/types/ObjectRecordQueryVariables';
|
||||||
|
|
||||||
|
export const currentNotesQueryVariablesState =
|
||||||
|
atom<ObjectRecordQueryVariables | null>({
|
||||||
|
default: null,
|
||||||
|
key: 'currentNotesQueryVariablesState',
|
||||||
|
});
|
||||||
@ -1,17 +1,23 @@
|
|||||||
|
import { useLocation } from 'react-router-dom';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { isNonEmptyArray } from '@sniptt/guards';
|
import { isNonEmptyArray } from '@sniptt/guards';
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useDeleteActivityFromCache } from '@/activities/hooks/useDeleteActivityFromCache';
|
import { useDeleteActivityFromCache } from '@/activities/hooks/useDeleteActivityFromCache';
|
||||||
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
||||||
|
import { useRemoveFromActivitiesQueries } from '@/activities/hooks/useRemoveFromActivitiesQueries';
|
||||||
|
import { useRemoveFromActivityTargetsQueries } from '@/activities/hooks/useRemoveFromActivityTargetsQueries';
|
||||||
|
import { currentNotesQueryVariablesState } from '@/activities/notes/states/currentNotesQueryVariablesState';
|
||||||
import { activityInDrawerState } from '@/activities/states/activityInDrawerState';
|
import { activityInDrawerState } from '@/activities/states/activityInDrawerState';
|
||||||
import { activityTargetableEntityArrayState } from '@/activities/states/activityTargetableEntityArrayState';
|
import { activityTargetableEntityArrayState } from '@/activities/states/activityTargetableEntityArrayState';
|
||||||
import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState';
|
import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState';
|
||||||
import { isUpsertingActivityInDBState } from '@/activities/states/isCreatingActivityInDBState';
|
import { isUpsertingActivityInDBState } from '@/activities/states/isCreatingActivityInDBState';
|
||||||
import { temporaryActivityForEditorState } from '@/activities/states/temporaryActivityForEditorState';
|
import { temporaryActivityForEditorState } from '@/activities/states/temporaryActivityForEditorState';
|
||||||
import { viewableActivityIdState } from '@/activities/states/viewableActivityIdState';
|
import { viewableActivityIdState } from '@/activities/states/viewableActivityIdState';
|
||||||
import { useRemoveFromTimelineActivitiesQueries } from '@/activities/timeline/hooks/useRemoveFromTimelineActivitiesQueries';
|
import { currentCompletedTaskQueryVariablesState } from '@/activities/tasks/states/currentCompletedTaskQueryVariablesState';
|
||||||
import { timelineTargetableObjectState } from '@/activities/timeline/states/timelineTargetableObjectState';
|
import { currentIncompleteTaskQueryVariablesState } from '@/activities/tasks/states/currentIncompleteTaskQueryVariablesState';
|
||||||
|
import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY';
|
||||||
|
import { objectShowPageTargetableObjectState } from '@/activities/timeline/states/objectShowPageTargetableObjectState';
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords';
|
import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords';
|
||||||
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
|
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
|
||||||
@ -37,13 +43,11 @@ export const ActivityActionBar = () => {
|
|||||||
const [, setIsRightDrawerOpen] = useRecoilState(isRightDrawerOpenState);
|
const [, setIsRightDrawerOpen] = useRecoilState(isRightDrawerOpenState);
|
||||||
const { deleteOneRecord: deleteOneActivity } = useDeleteOneRecord({
|
const { deleteOneRecord: deleteOneActivity } = useDeleteOneRecord({
|
||||||
objectNameSingular: CoreObjectNameSingular.Activity,
|
objectNameSingular: CoreObjectNameSingular.Activity,
|
||||||
refetchFindManyQuery: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { deleteManyRecords: deleteManyActivityTargets } = useDeleteManyRecords(
|
const { deleteManyRecords: deleteManyActivityTargets } = useDeleteManyRecords(
|
||||||
{
|
{
|
||||||
objectNameSingular: CoreObjectNameSingular.ActivityTarget,
|
objectNameSingular: CoreObjectNameSingular.ActivityTarget,
|
||||||
refetchFindManyQuery: true,
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -56,15 +60,34 @@ export const ActivityActionBar = () => {
|
|||||||
const [isUpsertingActivityInDB] = useRecoilState(
|
const [isUpsertingActivityInDB] = useRecoilState(
|
||||||
isUpsertingActivityInDBState,
|
isUpsertingActivityInDBState,
|
||||||
);
|
);
|
||||||
const timelineTargetableObject = useRecoilValue(
|
const objectShowPageTargetableObject = useRecoilValue(
|
||||||
timelineTargetableObjectState,
|
objectShowPageTargetableObjectState,
|
||||||
);
|
);
|
||||||
const openCreateActivity = useOpenCreateActivityDrawer();
|
const openCreateActivity = useOpenCreateActivityDrawer();
|
||||||
|
|
||||||
const { removeFromTimelineActivitiesQueries } =
|
const currentCompletedTaskQueryVariables = useRecoilValue(
|
||||||
useRemoveFromTimelineActivitiesQueries();
|
currentCompletedTaskQueryVariablesState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentIncompleteTaskQueryVariables = useRecoilValue(
|
||||||
|
currentIncompleteTaskQueryVariablesState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentNotesQueryVariables = useRecoilValue(
|
||||||
|
currentNotesQueryVariablesState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { pathname } = useLocation();
|
||||||
|
const { removeFromActivitiesQueries } = useRemoveFromActivitiesQueries();
|
||||||
|
const { removeFromActivityTargetsQueries } =
|
||||||
|
useRemoveFromActivityTargetsQueries();
|
||||||
|
|
||||||
|
const weAreOnObjectShowPage = pathname.startsWith('/object');
|
||||||
|
const weAreOnTaskPage = pathname.startsWith('/tasks');
|
||||||
|
|
||||||
|
const deleteActivity = async () => {
|
||||||
|
setIsRightDrawerOpen(false);
|
||||||
|
|
||||||
const deleteActivity = () => {
|
|
||||||
if (viewableActivityId) {
|
if (viewableActivityId) {
|
||||||
if (isActivityInCreateMode && isDefined(temporaryActivityForEditor)) {
|
if (isActivityInCreateMode && isDefined(temporaryActivityForEditor)) {
|
||||||
deleteActivityFromCache(temporaryActivityForEditor);
|
deleteActivityFromCache(temporaryActivityForEditor);
|
||||||
@ -74,22 +97,77 @@ export const ActivityActionBar = () => {
|
|||||||
const activityTargetIdsToDelete =
|
const activityTargetIdsToDelete =
|
||||||
activityInDrawer?.activityTargets.map(mapToRecordId) ?? [];
|
activityInDrawer?.activityTargets.map(mapToRecordId) ?? [];
|
||||||
|
|
||||||
if (isDefined(timelineTargetableObject)) {
|
if (weAreOnTaskPage) {
|
||||||
removeFromTimelineActivitiesQueries({
|
removeFromActivitiesQueries({
|
||||||
activityTargetsToRemove: activityInDrawer?.activityTargets ?? [],
|
|
||||||
activityIdToRemove: viewableActivityId,
|
activityIdToRemove: viewableActivityId,
|
||||||
|
targetableObjects: [],
|
||||||
|
activitiesFilters: currentCompletedTaskQueryVariables?.filter,
|
||||||
|
activitiesOrderByVariables:
|
||||||
|
currentCompletedTaskQueryVariables?.orderBy,
|
||||||
|
});
|
||||||
|
|
||||||
|
removeFromActivitiesQueries({
|
||||||
|
activityIdToRemove: viewableActivityId,
|
||||||
|
targetableObjects: [],
|
||||||
|
activitiesFilters: currentIncompleteTaskQueryVariables?.filter,
|
||||||
|
activitiesOrderByVariables:
|
||||||
|
currentIncompleteTaskQueryVariables?.orderBy,
|
||||||
|
});
|
||||||
|
} else if (
|
||||||
|
weAreOnObjectShowPage &&
|
||||||
|
isDefined(objectShowPageTargetableObject)
|
||||||
|
) {
|
||||||
|
removeFromActivitiesQueries({
|
||||||
|
activityIdToRemove: viewableActivityId,
|
||||||
|
targetableObjects: [objectShowPageTargetableObject],
|
||||||
|
activitiesFilters: {},
|
||||||
|
activitiesOrderByVariables:
|
||||||
|
FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isDefined(currentCompletedTaskQueryVariables)) {
|
||||||
|
removeFromActivitiesQueries({
|
||||||
|
activityIdToRemove: viewableActivityId,
|
||||||
|
targetableObjects: [objectShowPageTargetableObject],
|
||||||
|
activitiesFilters: currentCompletedTaskQueryVariables?.filter,
|
||||||
|
activitiesOrderByVariables:
|
||||||
|
currentCompletedTaskQueryVariables?.orderBy,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDefined(currentIncompleteTaskQueryVariables)) {
|
||||||
|
removeFromActivitiesQueries({
|
||||||
|
activityIdToRemove: viewableActivityId,
|
||||||
|
targetableObjects: [objectShowPageTargetableObject],
|
||||||
|
activitiesFilters: currentIncompleteTaskQueryVariables?.filter,
|
||||||
|
activitiesOrderByVariables:
|
||||||
|
currentIncompleteTaskQueryVariables?.orderBy,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDefined(currentNotesQueryVariables)) {
|
||||||
|
removeFromActivitiesQueries({
|
||||||
|
activityIdToRemove: viewableActivityId,
|
||||||
|
targetableObjects: [objectShowPageTargetableObject],
|
||||||
|
activitiesFilters: currentNotesQueryVariables?.filter,
|
||||||
|
activitiesOrderByVariables: currentNotesQueryVariables?.orderBy,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
removeFromActivityTargetsQueries({
|
||||||
|
activityTargetsToRemove: activityInDrawer?.activityTargets ?? [],
|
||||||
|
targetableObjects: [objectShowPageTargetableObject],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNonEmptyArray(activityTargetIdsToDelete)) {
|
if (isNonEmptyArray(activityTargetIdsToDelete)) {
|
||||||
deleteManyActivityTargets(activityTargetIdsToDelete);
|
await deleteManyActivityTargets(activityTargetIdsToDelete);
|
||||||
}
|
}
|
||||||
deleteOneActivity?.(viewableActivityId);
|
|
||||||
|
await deleteOneActivity?.(viewableActivityId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsRightDrawerOpen(false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const record = useRecoilValue(
|
const record = useRecoilValue(
|
||||||
@ -98,7 +176,7 @@ export const ActivityActionBar = () => {
|
|||||||
|
|
||||||
const addActivity = () => {
|
const addActivity = () => {
|
||||||
setIsRightDrawerOpen(false);
|
setIsRightDrawerOpen(false);
|
||||||
if (record && timelineTargetableObject) {
|
if (record && objectShowPageTargetableObject) {
|
||||||
openCreateActivity({
|
openCreateActivity({
|
||||||
type: record.type,
|
type: record.type,
|
||||||
customAssignee: record.assignee,
|
customAssignee: record.assignee,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Meta, StoryObj } from '@storybook/react';
|
import { Meta, StoryObj } from '@storybook/react';
|
||||||
|
|
||||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
|
||||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||||
|
|
||||||
import { RightDrawerActivityTopBar } from '../RightDrawerActivityTopBar';
|
import { RightDrawerActivityTopBar } from '../RightDrawerActivityTopBar';
|
||||||
@ -14,7 +14,7 @@ const meta: Meta<typeof RightDrawerActivityTopBar> = {
|
|||||||
<Story />
|
<Story />
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
ComponentDecorator,
|
ComponentWithRouterDecorator,
|
||||||
],
|
],
|
||||||
parameters: {
|
parameters: {
|
||||||
msw: graphqlMocks,
|
msw: graphqlMocks,
|
||||||
|
|||||||
@ -1,12 +1,18 @@
|
|||||||
|
import { useEffect, useMemo } from 'react';
|
||||||
import { isNonEmptyArray } from '@sniptt/guards';
|
import { isNonEmptyArray } from '@sniptt/guards';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { useActivities } from '@/activities/hooks/useActivities';
|
import { useActivities } from '@/activities/hooks/useActivities';
|
||||||
|
import { currentCompletedTaskQueryVariablesState } from '@/activities/tasks/states/currentCompletedTaskQueryVariablesState';
|
||||||
|
import { currentIncompleteTaskQueryVariablesState } from '@/activities/tasks/states/currentIncompleteTaskQueryVariablesState';
|
||||||
import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY';
|
import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY';
|
||||||
import { Activity } from '@/activities/types/Activity';
|
import { Activity } from '@/activities/types/Activity';
|
||||||
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
|
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
|
import { ObjectRecordQueryVariables } from '@/object-record/types/ObjectRecordQueryVariables';
|
||||||
import { parseDate } from '~/utils/date-utils';
|
import { parseDate } from '~/utils/date-utils';
|
||||||
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
|
|
||||||
type UseTasksProps = {
|
type UseTasksProps = {
|
||||||
filterDropdownId?: string;
|
filterDropdownId?: string;
|
||||||
@ -21,27 +27,94 @@ export const useTasks = ({
|
|||||||
filterDropdownId,
|
filterDropdownId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const assigneeIdFilter = selectedFilter
|
const assigneeIdFilter = useMemo(
|
||||||
? {
|
() =>
|
||||||
assigneeId: {
|
selectedFilter
|
||||||
in: JSON.parse(selectedFilter.value),
|
? {
|
||||||
},
|
assigneeId: {
|
||||||
}
|
in: JSON.parse(selectedFilter.value),
|
||||||
: undefined;
|
},
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
[selectedFilter],
|
||||||
|
);
|
||||||
|
|
||||||
const skipActivityTargets = !isNonEmptyArray(targetableObjects);
|
const skipActivityTargets = !isNonEmptyArray(targetableObjects);
|
||||||
|
|
||||||
|
const completedQueryVariables = useMemo(
|
||||||
|
() =>
|
||||||
|
({
|
||||||
|
filter: {
|
||||||
|
completedAt: { is: 'NOT_NULL' },
|
||||||
|
type: { eq: 'Task' },
|
||||||
|
...assigneeIdFilter,
|
||||||
|
},
|
||||||
|
orderBy: FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY,
|
||||||
|
}) as ObjectRecordQueryVariables,
|
||||||
|
[assigneeIdFilter],
|
||||||
|
);
|
||||||
|
|
||||||
|
const incompleteQueryVariables = useMemo(
|
||||||
|
() =>
|
||||||
|
({
|
||||||
|
filter: {
|
||||||
|
completedAt: { is: 'NULL' },
|
||||||
|
type: { eq: 'Task' },
|
||||||
|
...assigneeIdFilter,
|
||||||
|
},
|
||||||
|
orderBy: FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY,
|
||||||
|
}) as ObjectRecordQueryVariables,
|
||||||
|
[assigneeIdFilter],
|
||||||
|
);
|
||||||
|
|
||||||
|
const [
|
||||||
|
currentCompletedTaskQueryVariables,
|
||||||
|
setCurrentCompletedTaskQueryVariables,
|
||||||
|
] = useRecoilState(currentCompletedTaskQueryVariablesState);
|
||||||
|
|
||||||
|
const [
|
||||||
|
currentIncompleteTaskQueryVariables,
|
||||||
|
setCurrentIncompleteTaskQueryVariables,
|
||||||
|
] = useRecoilState(currentIncompleteTaskQueryVariablesState);
|
||||||
|
|
||||||
|
// TODO: fix useEffect, remove with better pattern
|
||||||
|
useEffect(() => {
|
||||||
|
if (
|
||||||
|
!isDeeplyEqual(
|
||||||
|
completedQueryVariables,
|
||||||
|
currentCompletedTaskQueryVariables,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
setCurrentCompletedTaskQueryVariables(completedQueryVariables);
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
completedQueryVariables,
|
||||||
|
currentCompletedTaskQueryVariables,
|
||||||
|
setCurrentCompletedTaskQueryVariables,
|
||||||
|
]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (
|
||||||
|
!isDeeplyEqual(
|
||||||
|
incompleteQueryVariables,
|
||||||
|
currentIncompleteTaskQueryVariables,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
setCurrentIncompleteTaskQueryVariables(incompleteQueryVariables);
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
incompleteQueryVariables,
|
||||||
|
currentIncompleteTaskQueryVariables,
|
||||||
|
setCurrentIncompleteTaskQueryVariables,
|
||||||
|
]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
activities: completeTasksData,
|
activities: completeTasksData,
|
||||||
initialized: initializedCompleteTasks,
|
initialized: initializedCompleteTasks,
|
||||||
} = useActivities({
|
} = useActivities({
|
||||||
targetableObjects,
|
targetableObjects,
|
||||||
activitiesFilters: {
|
activitiesFilters: completedQueryVariables.filter ?? {},
|
||||||
completedAt: { is: 'NOT_NULL' },
|
activitiesOrderByVariables: completedQueryVariables.orderBy ?? {},
|
||||||
type: { eq: 'Task' },
|
|
||||||
...assigneeIdFilter,
|
|
||||||
},
|
|
||||||
activitiesOrderByVariables: FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY,
|
|
||||||
skipActivityTargets,
|
skipActivityTargets,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -50,12 +123,8 @@ export const useTasks = ({
|
|||||||
initialized: initializedIncompleteTasks,
|
initialized: initializedIncompleteTasks,
|
||||||
} = useActivities({
|
} = useActivities({
|
||||||
targetableObjects,
|
targetableObjects,
|
||||||
activitiesFilters: {
|
activitiesFilters: incompleteQueryVariables.filter ?? {},
|
||||||
completedAt: { is: 'NULL' },
|
activitiesOrderByVariables: incompleteQueryVariables.orderBy ?? {},
|
||||||
type: { eq: 'Task' },
|
|
||||||
...assigneeIdFilter,
|
|
||||||
},
|
|
||||||
activitiesOrderByVariables: FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY,
|
|
||||||
skipActivityTargets,
|
skipActivityTargets,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
|
import { ObjectRecordQueryVariables } from '@/object-record/types/ObjectRecordQueryVariables';
|
||||||
|
|
||||||
|
export const currentCompletedTaskQueryVariablesState =
|
||||||
|
atom<ObjectRecordQueryVariables | null>({
|
||||||
|
default: null,
|
||||||
|
key: 'currentCompletedTaskQueryVariablesState',
|
||||||
|
});
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
|
import { ObjectRecordQueryVariables } from '@/object-record/types/ObjectRecordQueryVariables';
|
||||||
|
|
||||||
|
export const currentIncompleteTaskQueryVariablesState =
|
||||||
|
atom<ObjectRecordQueryVariables | null>({
|
||||||
|
default: null,
|
||||||
|
key: 'currentIncompleteTaskQueryVariablesState',
|
||||||
|
});
|
||||||
@ -5,7 +5,7 @@ import { useSetRecoilState } from 'recoil';
|
|||||||
import { useActivities } from '@/activities/hooks/useActivities';
|
import { useActivities } from '@/activities/hooks/useActivities';
|
||||||
import { TimelineCreateButtonGroup } from '@/activities/timeline/components/TimelineCreateButtonGroup';
|
import { TimelineCreateButtonGroup } from '@/activities/timeline/components/TimelineCreateButtonGroup';
|
||||||
import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY';
|
import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY';
|
||||||
import { timelineTargetableObjectState } from '@/activities/timeline/states/timelineTargetableObjectState';
|
import { objectShowPageTargetableObjectState } from '@/activities/timeline/states/objectShowPageTargetableObjectState';
|
||||||
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import AnimatedPlaceholder from '@/ui/layout/animated-placeholder/components/AnimatedPlaceholder';
|
import AnimatedPlaceholder from '@/ui/layout/animated-placeholder/components/AnimatedPlaceholder';
|
||||||
import {
|
import {
|
||||||
@ -44,7 +44,7 @@ export const Timeline = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const setTimelineTargetableObject = useSetRecoilState(
|
const setTimelineTargetableObject = useSetRecoilState(
|
||||||
timelineTargetableObjectState,
|
objectShowPageTargetableObjectState,
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { useInjectIntoActivitiesQuery } from '@/activities/hooks/useInjectIntoActivitiesQuery';
|
import { useInjectIntoActivitiesQueries } from '@/activities/hooks/useInjectIntoActivitiesQueries';
|
||||||
import { Activity } from '@/activities/types/Activity';
|
import { Activity } from '@/activities/types/Activity';
|
||||||
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
||||||
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||||
|
|
||||||
export const useInjectIntoTimelineActivitiesQueries = () => {
|
export const useInjectIntoTimelineActivitiesQueries = () => {
|
||||||
const { injectActivitiesQueries } = useInjectIntoActivitiesQuery();
|
const { injectActivitiesQueries } = useInjectIntoActivitiesQueries();
|
||||||
|
|
||||||
const injectIntoTimelineActivitiesQueries = ({
|
const injectIntoTimelineActivitiesQueries = ({
|
||||||
activityToInject,
|
activityToInject,
|
||||||
|
|||||||
@ -1,138 +0,0 @@
|
|||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
import { useRemoveFromActivitiesQueries } from '@/activities/hooks/useRemoveFromActivitiesQueries';
|
|
||||||
import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY';
|
|
||||||
import { timelineTargetableObjectState } from '@/activities/timeline/states/timelineTargetableObjectState';
|
|
||||||
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
|
||||||
|
|
||||||
export const useRemoveFromTimelineActivitiesQueries = () => {
|
|
||||||
const timelineTargetableObject = useRecoilValue(
|
|
||||||
timelineTargetableObjectState,
|
|
||||||
);
|
|
||||||
|
|
||||||
// const { objectMetadataItem: objectMetadataItemActivity } =
|
|
||||||
// useObjectMetadataItemOnly({
|
|
||||||
// objectNameSingular: CoreObjectNameSingular.Activity,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const {
|
|
||||||
// upsertFindManyRecordsQueryInCache: overwriteFindManyActivitiesInCache,
|
|
||||||
// } = useUpsertFindManyRecordsQueryInCache({
|
|
||||||
// objectMetadataItem: objectMetadataItemActivity,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const { objectMetadataItem: objectMetadataItemActivityTarget } =
|
|
||||||
// useObjectMetadataItemOnly({
|
|
||||||
// objectNameSingular: CoreObjectNameSingular.ActivityTarget,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const {
|
|
||||||
// readFindManyRecordsQueryInCache: readFindManyActivityTargetsQueryInCache,
|
|
||||||
// } = useReadFindManyRecordsQueryInCache({
|
|
||||||
// objectMetadataItem: objectMetadataItemActivityTarget,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const {
|
|
||||||
// readFindManyRecordsQueryInCache: readFindManyActivitiesQueryInCache,
|
|
||||||
// } = useReadFindManyRecordsQueryInCache({
|
|
||||||
// objectMetadataItem: objectMetadataItemActivity,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const {
|
|
||||||
// upsertFindManyRecordsQueryInCache:
|
|
||||||
// overwriteFindManyActivityTargetsQueryInCache,
|
|
||||||
// } = useUpsertFindManyRecordsQueryInCache({
|
|
||||||
// objectMetadataItem: objectMetadataItemActivityTarget,
|
|
||||||
// });
|
|
||||||
|
|
||||||
const { removeFromActivitiesQueries } = useRemoveFromActivitiesQueries();
|
|
||||||
|
|
||||||
const removeFromTimelineActivitiesQueries = ({
|
|
||||||
activityIdToRemove,
|
|
||||||
activityTargetsToRemove,
|
|
||||||
}: {
|
|
||||||
activityIdToRemove: string;
|
|
||||||
activityTargetsToRemove: ActivityTarget[];
|
|
||||||
}) => {
|
|
||||||
if (!timelineTargetableObject) {
|
|
||||||
throw new Error('Timeline targetable object is not defined');
|
|
||||||
}
|
|
||||||
|
|
||||||
removeFromActivitiesQueries({
|
|
||||||
activityIdToRemove,
|
|
||||||
activityTargetsToRemove,
|
|
||||||
targetableObjects: [timelineTargetableObject],
|
|
||||||
activitiesFilters: {},
|
|
||||||
activitiesOrderByVariables: FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY,
|
|
||||||
});
|
|
||||||
|
|
||||||
// const targetObjectFieldName = getActivityTargetObjectFieldIdName({
|
|
||||||
// nameSingular: timelineTargetableObject.targetObjectNameSingular,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const activitiyTargetsForTargetableObjectQueryVariables = {
|
|
||||||
// filter: {
|
|
||||||
// [targetObjectFieldName]: {
|
|
||||||
// eq: timelineTargetableObject.id,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// };
|
|
||||||
|
|
||||||
// const existingActivityTargetsForTargetableObject =
|
|
||||||
// readFindManyActivityTargetsQueryInCache({
|
|
||||||
// queryVariables: activitiyTargetsForTargetableObjectQueryVariables,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const newActivityTargetsForTargetableObject = isNonEmptyArray(
|
|
||||||
// activityTargetsToRemove,
|
|
||||||
// )
|
|
||||||
// ? existingActivityTargetsForTargetableObject.filter(
|
|
||||||
// (existingActivityTarget) =>
|
|
||||||
// activityTargetsToRemove.some(
|
|
||||||
// (activityTargetToRemove) =>
|
|
||||||
// activityTargetToRemove.id !== existingActivityTarget.id,
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
// : existingActivityTargetsForTargetableObject;
|
|
||||||
|
|
||||||
// overwriteFindManyActivityTargetsQueryInCache({
|
|
||||||
// objectRecordsToOverwrite: newActivityTargetsForTargetableObject,
|
|
||||||
// queryVariables: activitiyTargetsForTargetableObjectQueryVariables,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const existingActivityIds = existingActivityTargetsForTargetableObject
|
|
||||||
// ?.map((activityTarget) => activityTarget.activityId)
|
|
||||||
// .filter(isNonEmptyString);
|
|
||||||
|
|
||||||
// const timelineActivitiesQueryVariablesBeforeDrawerMount =
|
|
||||||
// makeTimelineActivitiesQueryVariables({
|
|
||||||
// activityIds: existingActivityIds,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const existingActivities = readFindManyActivitiesQueryInCache({
|
|
||||||
// queryVariables: timelineActivitiesQueryVariablesBeforeDrawerMount,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const activityIdsAfterRemoval = existingActivityIds.filter(
|
|
||||||
// (existingActivityId) => existingActivityId !== activityIdToRemove,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// const timelineActivitiesQueryVariablesAfterRemoval =
|
|
||||||
// makeTimelineActivitiesQueryVariables({
|
|
||||||
// activityIds: activityIdsAfterRemoval,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const newActivities = existingActivities
|
|
||||||
// .filter((existingActivity) => existingActivity.id !== activityIdToRemove)
|
|
||||||
// .toSorted(sortObjectRecordByDateField('createdAt', 'DescNullsFirst'));
|
|
||||||
|
|
||||||
// overwriteFindManyActivitiesInCache({
|
|
||||||
// objectRecordsToOverwrite: newActivities,
|
|
||||||
// queryVariables: timelineActivitiesQueryVariablesAfterRemoval,
|
|
||||||
// });
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
removeFromTimelineActivitiesQueries,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -2,12 +2,12 @@ import { useEffect, useState } from 'react';
|
|||||||
import { isNonEmptyArray, isNonEmptyString } from '@sniptt/guards';
|
import { isNonEmptyArray, isNonEmptyString } from '@sniptt/guards';
|
||||||
import { useRecoilCallback, useRecoilState } from 'recoil';
|
import { useRecoilCallback, useRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { useActivityConnectionUtils } from '@/activities/hooks/useActivityConnectionUtils';
|
||||||
import { useActivityTargetsForTargetableObject } from '@/activities/hooks/useActivityTargetsForTargetableObject';
|
import { useActivityTargetsForTargetableObject } from '@/activities/hooks/useActivityTargetsForTargetableObject';
|
||||||
import { timelineTargetableObjectState } from '@/activities/timeline/states/timelineTargetableObjectState';
|
import { objectShowPageTargetableObjectState } from '@/activities/timeline/states/objectShowPageTargetableObjectState';
|
||||||
import { makeTimelineActivitiesQueryVariables } from '@/activities/timeline/utils/makeTimelineActivitiesQueryVariables';
|
import { makeTimelineActivitiesQueryVariables } from '@/activities/timeline/utils/makeTimelineActivitiesQueryVariables';
|
||||||
import { Activity } from '@/activities/types/Activity';
|
import { Activity } from '@/activities/types/Activity';
|
||||||
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { useActivityConnectionUtils } from '@/activities/utils/useActivityConnectionUtils';
|
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { getRecordsFromRecordConnection } from '@/object-record/cache/utils/getRecordsFromRecordConnection';
|
import { getRecordsFromRecordConnection } from '@/object-record/cache/utils/getRecordsFromRecordConnection';
|
||||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||||
@ -22,15 +22,15 @@ export const useTimelineActivities = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { makeActivityWithoutConnection } = useActivityConnectionUtils();
|
const { makeActivityWithoutConnection } = useActivityConnectionUtils();
|
||||||
|
|
||||||
const [, setTimelineTargetableObject] = useRecoilState(
|
const [, setObjectShowPageTargetableObject] = useRecoilState(
|
||||||
timelineTargetableObjectState,
|
objectShowPageTargetableObjectState,
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isDefined(targetableObject)) {
|
if (isDefined(targetableObject)) {
|
||||||
setTimelineTargetableObject(targetableObject);
|
setObjectShowPageTargetableObject(targetableObject);
|
||||||
}
|
}
|
||||||
}, [targetableObject, setTimelineTargetableObject]);
|
}, [targetableObject, setObjectShowPageTargetableObject]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
activityTargets,
|
activityTargets,
|
||||||
|
|||||||
@ -2,8 +2,8 @@ import { atom } from 'recoil';
|
|||||||
|
|
||||||
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||||
|
|
||||||
export const timelineTargetableObjectState =
|
export const objectShowPageTargetableObjectState =
|
||||||
atom<ActivityTargetableObject | null>({
|
atom<ActivityTargetableObject | null>({
|
||||||
key: 'timelineTargetableObjectState',
|
key: 'objectShowPageTargetableObjectState',
|
||||||
default: null,
|
default: null,
|
||||||
});
|
});
|
||||||
@ -117,7 +117,10 @@ export const triggerUpdateRecordOptimisticEffect = ({
|
|||||||
|
|
||||||
const rootQueryNextEdgesShouldBeSorted = isDefined(rootQueryOrderBy);
|
const rootQueryNextEdgesShouldBeSorted = isDefined(rootQueryOrderBy);
|
||||||
|
|
||||||
if (rootQueryNextEdgesShouldBeSorted) {
|
if (
|
||||||
|
rootQueryNextEdgesShouldBeSorted &&
|
||||||
|
Object.getOwnPropertyNames(rootQueryOrderBy).length > 0
|
||||||
|
) {
|
||||||
rootQueryNextEdges = sortCachedObjectEdges({
|
rootQueryNextEdges = sortCachedObjectEdges({
|
||||||
edges: rootQueryNextEdges,
|
edges: rootQueryNextEdges,
|
||||||
orderBy: rootQueryOrderBy,
|
orderBy: rootQueryOrderBy,
|
||||||
|
|||||||
Reference in New Issue
Block a user