|
|
@@ -1,3 +1,4 @@
|
|
|
+import { NEW_ENTITY_PATH } from '@/constants.js';
|
|
|
import { api } from '@/graphql/api.js';
|
|
|
import type { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
|
import { queryOptions, useMutation, useQueryClient, useSuspenseQuery } from '@tanstack/react-query';
|
|
|
@@ -5,14 +6,15 @@ import { ResultOf, VariablesOf } from 'gql.tada';
|
|
|
import { DocumentNode } from 'graphql';
|
|
|
import { Variables } from 'graphql-request';
|
|
|
|
|
|
-import { getQueryName } from '../document-introspection/get-document-structure.js';
|
|
|
+import { getMutationName, getQueryName } from '../document-introspection/get-document-structure.js';
|
|
|
import { useGeneratedForm } from '../form-engine/use-generated-form.js';
|
|
|
|
|
|
export interface DetailPageOptions<
|
|
|
T extends TypedDocumentNode<any, any>,
|
|
|
+ C extends TypedDocumentNode<any, any>,
|
|
|
U extends TypedDocumentNode<any, any>,
|
|
|
EntityField extends keyof ResultOf<T> = keyof ResultOf<T>,
|
|
|
- VarName extends keyof VariablesOf<U> = 'input',
|
|
|
+ VarNameUpdate extends keyof VariablesOf<U> = 'input',
|
|
|
> {
|
|
|
/**
|
|
|
* @description
|
|
|
@@ -31,6 +33,11 @@ export interface DetailPageOptions<
|
|
|
params: {
|
|
|
id: string;
|
|
|
};
|
|
|
+ /**
|
|
|
+ * @description
|
|
|
+ * The document to create the entity.
|
|
|
+ */
|
|
|
+ createDocument: C;
|
|
|
/**
|
|
|
* @description
|
|
|
* The document to update the entity.
|
|
|
@@ -40,12 +47,12 @@ export interface DetailPageOptions<
|
|
|
* @description
|
|
|
* The function to set the values for the update document.
|
|
|
*/
|
|
|
- setValuesForUpdate: (entity: NonNullable<ResultOf<T>[EntityField]>) => VariablesOf<U>[VarName];
|
|
|
+ setValuesForUpdate: (entity: NonNullable<ResultOf<T>[EntityField]>) => VariablesOf<U>[VarNameUpdate];
|
|
|
/**
|
|
|
* @description
|
|
|
* The function to call when the update is successful.
|
|
|
*/
|
|
|
- onSuccess?: () => void;
|
|
|
+ onSuccess?: (entity: ResultOf<C>[keyof ResultOf<C>] | ResultOf<U>[keyof ResultOf<U>]) => void;
|
|
|
/**
|
|
|
* @description
|
|
|
* The function to call when the update is successful.
|
|
|
@@ -71,34 +78,58 @@ export function getDetailQueryOptions<T, V extends Variables = Variables>(
|
|
|
*/
|
|
|
export function useDetailPage<
|
|
|
T extends TypedDocumentNode<any, any>,
|
|
|
+ C extends TypedDocumentNode<any, any>,
|
|
|
U extends TypedDocumentNode<any, any>,
|
|
|
EntityField extends keyof ResultOf<T> = keyof ResultOf<T>,
|
|
|
- VarName extends keyof VariablesOf<U> = 'input',
|
|
|
->(options: DetailPageOptions<T, U, EntityField, VarName>) {
|
|
|
- const { queryDocument, updateDocument, setValuesForUpdate, params, entityField, onSuccess, onError } =
|
|
|
- options;
|
|
|
+ VarNameUpdate extends keyof VariablesOf<U> = 'input',
|
|
|
+ VarNameCreate extends keyof VariablesOf<C> = 'input',
|
|
|
+>(options: DetailPageOptions<T, C, U, EntityField, VarNameUpdate>) {
|
|
|
+ const {
|
|
|
+ queryDocument,
|
|
|
+ createDocument,
|
|
|
+ updateDocument,
|
|
|
+ setValuesForUpdate,
|
|
|
+ params,
|
|
|
+ entityField,
|
|
|
+ onSuccess,
|
|
|
+ onError,
|
|
|
+ } = options;
|
|
|
+ const isNew = params.id === NEW_ENTITY_PATH;
|
|
|
const queryClient = useQueryClient();
|
|
|
- const detailQueryOptions = getDetailQueryOptions(queryDocument, { id: params.id });
|
|
|
+ const detailQueryOptions = getDetailQueryOptions(queryDocument, { id: isNew ? '__NEW__' : params.id });
|
|
|
const detailQuery = useSuspenseQuery(detailQueryOptions);
|
|
|
- const entity = detailQuery.data[entityField];
|
|
|
+ const entity = detailQuery?.data[entityField];
|
|
|
+
|
|
|
+ const createMutation = useMutation({
|
|
|
+ mutationFn: api.mutate(createDocument),
|
|
|
+ onSuccess: data => {
|
|
|
+ const createMutationName = getMutationName(createDocument);
|
|
|
+ onSuccess?.((data as any)[createMutationName]);
|
|
|
+ },
|
|
|
+ });
|
|
|
|
|
|
const updateMutation = useMutation({
|
|
|
mutationFn: api.mutate(updateDocument),
|
|
|
- onSuccess: () => {
|
|
|
- onSuccess?.();
|
|
|
+ onSuccess: data => {
|
|
|
+ const updateMutationName = getMutationName(updateDocument);
|
|
|
+ onSuccess?.((data as any)[updateMutationName]);
|
|
|
void queryClient.invalidateQueries({ queryKey: detailQueryOptions.queryKey });
|
|
|
},
|
|
|
onError,
|
|
|
});
|
|
|
|
|
|
const { form, submitHandler } = useGeneratedForm({
|
|
|
- document: updateDocument,
|
|
|
+ document: isNew ? createDocument : updateDocument,
|
|
|
entity,
|
|
|
setValues: setValuesForUpdate,
|
|
|
onSubmit(values: any) {
|
|
|
- updateMutation.mutate({ input: values });
|
|
|
+ if (isNew) {
|
|
|
+ createMutation.mutate({ input: values });
|
|
|
+ } else {
|
|
|
+ updateMutation.mutate({ input: values });
|
|
|
+ }
|
|
|
},
|
|
|
});
|
|
|
|
|
|
- return { form, submitHandler, entity, isPending: updateMutation.isPending || detailQuery.isPending };
|
|
|
+ return { form, submitHandler, entity, isPending: updateMutation.isPending || detailQuery?.isPending };
|
|
|
}
|