Skip to content

Commit

Permalink
Apply review suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
djhi committed May 21, 2024
1 parent ac6bbeb commit f0f095c
Show file tree
Hide file tree
Showing 9 changed files with 802 additions and 89 deletions.
4 changes: 2 additions & 2 deletions packages/ra-core/src/controller/create/useCreateController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export const useCreateController = <
} = mutationOptions;
const {
registerMutationMiddleware,
getMutateWithMiddlewares,
mutateWithMiddlewares,
unregisterMutationMiddleware,
} = useMutationMiddlewares();

Expand Down Expand Up @@ -139,7 +139,7 @@ export const useCreateController = <
},
...otherMutationOptions,
returnPromise: true,
getMutateMiddlewares: getMutateWithMiddlewares,
mutateWithMiddlewares,
});

const save = useCallback(
Expand Down
4 changes: 2 additions & 2 deletions packages/ra-core/src/controller/edit/useEditController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const useEditController = <
} = mutationOptions;
const {
registerMutationMiddleware,
getMutateWithMiddlewares,
mutateWithMiddlewares,
unregisterMutationMiddleware,
} = useMutationMiddlewares();
const {
Expand Down Expand Up @@ -192,7 +192,7 @@ export const useEditController = <
...otherMutationOptions,
mutationMode,
returnPromise: mutationMode === 'pessimistic',
getMutateMiddlewares: getMutateWithMiddlewares,
mutateWithMiddlewares,
}
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,11 @@ export const useMutationMiddlewares = <
[]
);

const getMutateWithMiddlewares = useCallback((fn: MutateFunc) => {
return (...args: Parameters<MutateFunc>): ReturnType<MutateFunc> => {
const mutateWithMiddlewares = useCallback(
(
fn: MutateFunc,
...args: Parameters<MutateFunc>
): ReturnType<MutateFunc> => {
let index = callbacks.current.length - 1;

// Called by middlewares to call the next middleware function
Expand All @@ -84,18 +87,19 @@ export const useMutationMiddlewares = <
}

return fn(...args);
};
}, []);
},
[]
);

const functions = useMemo<UseMutationMiddlewaresResult<MutateFunc>>(
() => ({
registerMutationMiddleware,
getMutateWithMiddlewares,
mutateWithMiddlewares,
unregisterMutationMiddleware,
}),
[
registerMutationMiddleware,
getMutateWithMiddlewares,
mutateWithMiddlewares,
unregisterMutationMiddleware,
]
);
Expand All @@ -107,9 +111,10 @@ export interface UseMutationMiddlewaresResult<
MutateFunc extends (...args: any[]) => any = (...args: any[]) => any
> {
registerMutationMiddleware: (callback: Middleware<MutateFunc>) => void;
getMutateWithMiddlewares: (
mutate: MutateFunc
) => (...args: Parameters<MutateFunc>) => ReturnType<MutateFunc>;
mutateWithMiddlewares: (
mutate: MutateFunc,
...args: Parameters<MutateFunc>
) => ReturnType<MutateFunc>;
unregisterMutationMiddleware: (callback: Middleware<MutateFunc>) => void;
}

Expand Down
28 changes: 16 additions & 12 deletions packages/ra-core/src/dataProvider/useCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const useCreate = <
const hasCallTimeOnError = useRef(false);
const hasCallTimeOnSuccess = useRef(false);
const hasCallTimeOnSettled = useRef(false);
const { getMutateMiddlewares, ...mutationOptions } = options;
const { mutateWithMiddlewares, ...mutationOptions } = options;
const mutation = useMutation<
ResultRecordType,
MutationError,
Expand All @@ -107,14 +107,15 @@ export const useCreate = <
'useCreate mutation requires a non-empty data object'
);
}
if (getMutateMiddlewares) {
const updateMiddleware = getMutateMiddlewares(
dataProvider.create
);
return updateMiddleware(callTimeResource, {
data: callTimeData,
meta: callTimeMeta,
}).then(({ data }) => data);
if (mutateWithMiddlewares) {
return mutateWithMiddlewares(
dataProvider.create.bind(dataProvider),
callTimeResource,
{
data: callTimeData,
meta: callTimeMeta,
}
).then(({ data }) => data);
}
return dataProvider
.create<RecordType, ResultRecordType>(callTimeResource, {
Expand Down Expand Up @@ -226,9 +227,12 @@ export type UseCreateOptions<
'mutationFn'
> & {
returnPromise?: boolean;
getMutateMiddlewares?: (
mutate: DataProvider['create']
) => DataProvider['create'];
mutateWithMiddlewares?: <
CreateFunctionType extends DataProvider['create'] = DataProvider['create']
>(
mutate: CreateFunctionType,
...Params: Parameters<CreateFunctionType>
) => ReturnType<CreateFunctionType>;
};

export type CreateMutationFunction<
Expand Down
172 changes: 172 additions & 0 deletions packages/ra-core/src/dataProvider/useUpdate.optimistic.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,175 @@ const ErrorCore = () => {
</>
);
};

export const WithMiddlewaresSuccess = ({ timeout = 1000 }) => {
const posts = [{ id: 1, title: 'Hello', author: 'John Doe' }];
const dataProvider = {
getOne: (resource, params) => {
console.log('getOne', resource, params);
return Promise.resolve({
data: posts.find(p => p.id === params.id),
});
},
update: (resource, params) => {
console.log('update', resource, params);
return new Promise(resolve => {
setTimeout(() => {
const post = posts.find(p => p.id === params.id);
if (post) {
post.title = params.data.title;
}
resolve({ data: post });
}, timeout);
});
},
} as any;
return (
<CoreAdminContext
queryClient={new QueryClient()}
dataProvider={dataProvider}
>
<WithMiddlewaresSuccessCore />
</CoreAdminContext>
);
};

const WithMiddlewaresSuccessCore = () => {
const isMutating = useIsMutating();
const [success, setSuccess] = useState<string>();
const { data, refetch } = useGetOne('posts', { id: 1 });
const [update, { isPending }] = useUpdate(
'posts',
{
id: 1,
data: { title: 'Hello World' },
},
{
mutateWithMiddlewares: async (update, resource, params) => {
return update(resource, {
...params,
data: { title: `${params.data.title} from middleware` },
});
},
}
);
const handleClick = () => {
update(
'posts',
{
id: 1,
data: { title: 'Hello World' },
},
{
onSuccess: () => setSuccess('success'),
}
);
};
return (
<>
<dl>
<dt>title</dt>
<dd>{data?.title}</dd>
<dt>author</dt>
<dd>{data?.author}</dd>
</dl>
<div>
<button onClick={handleClick} disabled={isPending}>
Update title
</button>
&nbsp;
<button onClick={() => refetch()}>Refetch</button>
</div>
{success && <div>{success}</div>}
{isMutating !== 0 && <div>mutating</div>}
</>
);
};

export const WithMiddlewaresError = ({ timeout = 1000 }) => {
const posts = [{ id: 1, title: 'Hello', author: 'John Doe' }];
const dataProvider = {
getOne: (resource, params) => {
console.log('getOne', resource, params);
return Promise.resolve({
data: posts.find(p => p.id === params.id),
});
},
update: (resource, params) => {
console.log('update', resource, params);
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('something went wrong'));
}, timeout);
});
},
} as any;
return (
<CoreAdminContext
queryClient={new QueryClient()}
dataProvider={dataProvider}
>
<WithMiddlewaresErrorCore />
</CoreAdminContext>
);
};

const WithMiddlewaresErrorCore = () => {
const isMutating = useIsMutating();
const [success, setSuccess] = useState<string>();
const [error, setError] = useState<any>();
const { data, refetch } = useGetOne('posts', { id: 1 });
const [update, { isPending }] = useUpdate(
'posts',
{
id: 1,
data: { title: 'Hello World' },
},
{
mutationMode: 'optimistic',
mutateWithMiddlewares: async (update, resource, params) => {
return update(resource, {
...params,
data: { title: `${params.data.title} from middleware` },
});
},
}
);
const handleClick = () => {
setError(undefined);
update(
'posts',
{
id: 1,
data: { title: 'Hello World' },
},
{
onSuccess: () => setSuccess('success'),
onError: e => {
setError(e);
setSuccess('');
},
}
);
};
return (
<>
<dl>
<dt>title</dt>
<dd>{data?.title}</dd>
<dt>author</dt>
<dd>{data?.author}</dd>
</dl>
<div>
<button onClick={handleClick} disabled={isPending}>
Update title
</button>
&nbsp;
<button onClick={() => refetch()}>Refetch</button>
</div>
{error && <div>{error.message}</div>}
{success && <div>{success}</div>}
{isMutating !== 0 && <div>mutating</div>}
</>
);
};
Loading

0 comments on commit f0f095c

Please sign in to comment.