Feat/pagination front (#2387)

* Finished renaming and scope

* wip

* WIP update

* Ok

* Cleaned

* Finished infinite scroll

* Clean

* Fixed V1 tables

* Fix post merge

* Removed ScrollWrapper

* Put back ScrollWrapper

* Put back in the right place
This commit is contained in:
Lucas Bordeau
2023-11-10 12:43:14 +01:00
committed by GitHub
parent e0289ba9f2
commit 9c29c436b9
29 changed files with 630 additions and 158 deletions

View File

@ -4,9 +4,12 @@ import {
OperationVariables,
useApolloClient,
} from '@apollo/client';
import { isNonEmptyArray } from '@sniptt/guards';
import { useRecoilCallback } from 'recoil';
import { GET_COMPANIES } from '@/companies/graphql/queries/getCompanies';
import { ObjectMetadataItem } from '@/metadata/types/ObjectMetadataItem';
import { generateFindManyCustomObjectsQuery } from '@/metadata/utils/generateFindManyCustomObjectsQuery';
import { GET_PEOPLE } from '@/people/graphql/queries/getPeople';
import { GET_API_KEYS } from '@/settings/developers/graphql/queries/getApiKeys';
import {
@ -16,6 +19,7 @@ import {
} from '~/generated/graphql';
import { optimisticEffectState } from '../states/optimisticEffectState';
import { OptimisticEffect } from '../types/internal/OptimisticEffect';
import { OptimisticEffectDefinition } from '../types/OptimisticEffectDefinition';
export const useOptimisticEffect = () => {
@ -28,7 +32,7 @@ export const useOptimisticEffect = () => {
definition,
}: {
variables: OperationVariables;
definition: OptimisticEffectDefinition<T>;
definition: OptimisticEffectDefinition;
}) => {
const optimisticEffects = snapshot
.getLoadable(optimisticEffectState)
@ -39,12 +43,47 @@ export const useOptimisticEffect = () => {
newData,
query,
variables,
isUsingFlexibleBackend,
objectMetadataItem,
}: {
cache: ApolloCache<unknown>;
newData: unknown[];
newData: unknown;
variables: OperationVariables;
query: DocumentNode;
isUsingFlexibleBackend?: boolean;
objectMetadataItem?: ObjectMetadataItem;
}) => {
if (isUsingFlexibleBackend && objectMetadataItem) {
const generatedQuery = generateFindManyCustomObjectsQuery({
objectMetadataItem,
});
const existingData = cache.readQuery({
query: generatedQuery,
variables,
});
if (!existingData) {
return;
}
cache.writeQuery({
query: generatedQuery,
variables,
data: {
[objectMetadataItem.namePlural]: definition.resolver({
currentData: (existingData as any)?.[
objectMetadataItem.namePlural
],
newData,
variables,
}),
},
});
return;
}
const existingData = cache.readQuery({
query,
variables,
@ -82,6 +121,7 @@ export const useOptimisticEffect = () => {
},
});
}
if (query === GET_API_KEYS) {
cache.writeQuery({
query,
@ -104,7 +144,9 @@ export const useOptimisticEffect = () => {
typename: definition.typename,
query: definition.query,
writer: optimisticEffectWriter,
};
objectMetadataItem: definition.objectMetadataItem,
isUsingFlexibleBackend: definition.isUsingFlexibleBackend,
} satisfies OptimisticEffect<T>;
set(optimisticEffectState, {
...optimisticEffects,
@ -115,26 +157,31 @@ export const useOptimisticEffect = () => {
const triggerOptimisticEffects = useRecoilCallback(
({ snapshot }) =>
(typename: string, newData: any[]) => {
(typename: string, newData: unknown) => {
const optimisticEffects = snapshot
.getLoadable(optimisticEffectState)
.getValue();
Object.values(optimisticEffects).forEach((optimisticEffect) => {
for (const optimisticEffect of Object.values(optimisticEffects)) {
// We need to update the typename when createObject type differs from listObject types
// It is the case for apiKey, where the creation route returns an ApiKeyToken type
const formattedNewData = newData.map((data) => {
return { ...data, __typename: typename };
});
const formattedNewData = isNonEmptyArray(newData)
? newData.map((data: any) => {
return { ...data, __typename: typename };
})
: newData;
if (optimisticEffect.typename === typename) {
optimisticEffect.writer({
cache: apolloClient.cache,
query: optimisticEffect.query,
query: optimisticEffect.query ?? ({} as DocumentNode),
newData: formattedNewData,
variables: optimisticEffect.variables,
isUsingFlexibleBackend: optimisticEffect.isUsingFlexibleBackend,
objectMetadataItem: optimisticEffect.objectMetadataItem,
});
}
});
}
},
);

View File

@ -1,10 +1,14 @@
import { DocumentNode } from 'graphql';
import { ObjectMetadataItem } from '@/metadata/types/ObjectMetadataItem';
import { OptimisticEffectResolver } from './OptimisticEffectResolver';
export type OptimisticEffectDefinition<T> = {
export type OptimisticEffectDefinition = {
key: string;
query: DocumentNode;
query?: DocumentNode;
typename: string;
resolver: OptimisticEffectResolver<T>;
resolver: OptimisticEffectResolver;
objectMetadataItem?: ObjectMetadataItem;
isUsingFlexibleBackend?: boolean;
};

View File

@ -1,11 +1,11 @@
import { OperationVariables } from '@apollo/client';
export type OptimisticEffectResolver<T> = ({
export type OptimisticEffectResolver = ({
currentData,
newData,
variables,
}: {
currentData: T[];
newData: T[];
currentData: any; //TODO: Change when decommissioning v1
newData: any; //TODO: Change when decommissioning v1
variables: OperationVariables;
}) => void;

View File

@ -1,5 +1,7 @@
import { ApolloCache, DocumentNode, OperationVariables } from '@apollo/client';
import { ObjectMetadataItem } from '@/metadata/types/ObjectMetadataItem';
type OptimisticEffectWriter<T> = ({
cache,
newData,
@ -8,14 +10,18 @@ type OptimisticEffectWriter<T> = ({
}: {
cache: ApolloCache<T>;
query: DocumentNode;
newData: T[];
newData: T;
variables: OperationVariables;
objectMetadataItem?: ObjectMetadataItem;
isUsingFlexibleBackend?: boolean;
}) => void;
export type OptimisticEffect<T> = {
key: string;
query: DocumentNode;
query?: DocumentNode;
typename: string;
variables: OperationVariables;
writer: OptimisticEffectWriter<T>;
objectMetadataItem?: ObjectMetadataItem;
isUsingFlexibleBackend?: boolean;
};