Prefetching views and favorites (#4421)

* wip

* Push

* Complete work on prefetch

* Add comment

* Fix

* Fix

* Fix

* Fix

* Remove dead code

* Simplify

* Fix tests

* Fix tests

* Fix according to review

* Fix according to review

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
Charles Bochet
2024-03-15 18:35:40 +01:00
committed by GitHub
parent 38f28de4a6
commit afb9b3e375
21 changed files with 279 additions and 129 deletions

View File

@ -1,47 +0,0 @@
import { useApolloClient } from '@apollo/client/react/hooks/useApolloClient';
import gql from 'graphql-tag';
import { useRecoilValue } from 'recoil';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { QueryMethodName } from '@/object-metadata/types/QueryMethodName';
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
export const useCachedRootQuery = ({
objectMetadataItem,
queryMethodName,
}: {
objectMetadataItem: ObjectMetadataItem | undefined;
queryMethodName: QueryMethodName;
}) => {
const apolloClient = useApolloClient();
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
if (!objectMetadataItem) {
return { cachedRootQuery: null };
}
const cacheReadFragment = gql`
fragment RootQuery on Query {
${
QueryMethodName.FindMany === queryMethodName
? objectMetadataItem.namePlural
: objectMetadataItem.nameSingular
}
${QueryMethodName.FindMany === queryMethodName ? '{ edges { node ' : ''}
${mapObjectMetadataToGraphQLQuery({
objectMetadataItems,
objectMetadataItem,
depth: 0,
})}
${QueryMethodName.FindMany === queryMethodName ? '}}' : ''}
}
`;
const cachedRootQuery = apolloClient.readFragment({
id: 'ROOT_QUERY',
fragment: cacheReadFragment,
});
return { cachedRootQuery };
};

View File

@ -10,7 +10,10 @@ import { ObjectRecordQueryVariables } from '@/object-record/types/ObjectRecordQu
export const useUpsertFindManyRecordsQueryInCache = ({
objectMetadataItem,
}: {
objectMetadataItem: ObjectMetadataItem;
objectMetadataItem: Pick<
ObjectMetadataItem,
'fields' | 'namePlural' | 'nameSingular'
>;
}) => {
const apolloClient = useApolloClient();

View File

@ -1,5 +1,6 @@
import { getEdgeTypename } from '@/object-record/cache/utils/getEdgeTypename';
import { getNodeTypename } from '@/object-record/cache/utils/getNodeTypename';
import { getRecordConnectionFromRecords } from '@/object-record/cache/utils/getRecordConnectionFromRecords';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { ObjectRecordEdge } from '@/object-record/types/ObjectRecordEdge';
@ -10,11 +11,26 @@ export const getRecordEdgeFromRecord = <T extends ObjectRecord>({
objectNameSingular: string;
record: T;
}) => {
const nestedRecord = Object.fromEntries(
Object.entries(record).map(([key, value]) => {
if (Array.isArray(value)) {
return [
key,
getRecordConnectionFromRecords({
objectNameSingular: key,
records: value as ObjectRecord[],
}),
];
}
return [key, value];
}),
) as T; // Todo fix typing once we have investigated apollo edges / nodes removal
return {
__typename: getEdgeTypename({ objectNameSingular }),
node: {
__typename: getNodeTypename({ objectNameSingular }),
...record,
...nestedRecord,
},
cursor: '',
} as ObjectRecordEdge<T>;

View File

@ -1,5 +1,7 @@
import { gql } from '@apollo/client';
import { useRecoilValue } from 'recoil';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
import { isNonEmptyArray } from '~/utils/isNonEmptyArray';
@ -12,6 +14,7 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({
objectMetadataItems: ObjectMetadataItem[];
depth?: number;
}) => {
const allObjectMetadataItems = useRecoilValue(objectMetadataItemsState());
const capitalizedObjectNameSingulars = objectMetadataItems.map(
({ nameSingular }) => capitalize(nameSingular),
);
@ -44,7 +47,7 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({
const limitPerMetadataItemArray = capitalizedObjectNameSingulars
.map(
(capitalizedObjectNameSingular) =>
`$limit${capitalizedObjectNameSingular}: Float = 5`,
`$limit${capitalizedObjectNameSingular}: Float`,
)
.join(', ');
@ -69,7 +72,7 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({
)}){
edges {
node ${mapObjectMetadataToGraphQLQuery({
objectMetadataItems,
objectMetadataItems: allObjectMetadataItems,
objectMetadataItem,
depth,
})}
@ -80,6 +83,7 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({
startCursor
endCursor
}
totalCount
}`,
)
.join('\n')}

View File

@ -0,0 +1,7 @@
import { ObjectRecordQueryVariables } from '@/object-record/types/ObjectRecordQueryVariables';
export type QueryKey = {
objectNameSingular: string;
variables: ObjectRecordQueryVariables;
depth: number;
};

View File

@ -13,7 +13,7 @@ const query = gql`
$filterNameSingular: NameSingularFilterInput
$orderByNameSingular: NameSingularOrderByInput
$lastCursorNameSingular: String
$limitNameSingular: Float = 5
$limitNameSingular: Float
) {
namePlural(
filter: $filterNameSingular
@ -33,6 +33,7 @@ const query = gql`
startCursor
endCursor
}
totalCount
}
}
`;