Skip to content

Commit bbfabd3

Browse files
committed
refactor: create wrapper to show and hide notification
1 parent 8b5ae9f commit bbfabd3

2 files changed

Lines changed: 46 additions & 42 deletions

File tree

src/course-outline/data/apiHooks.ts

Lines changed: 12 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import {
99
import { createGlobalState } from '@src/data/apiHooks';
1010
import type { XBlockBase, XblockChildInfo } from '@src/data/types';
1111
import { getBlockType, getCourseKey } from '@src/generic/key-utils';
12-
import { useProcessingNotification } from '@src/generic/processing-notification/context';
12+
import { useMutationWithProcessingNotification } from '@src/generic/processing-notification/data/apiHooks';
1313
import { handleResponseErrors } from '@src/generic/saving-error-alert';
1414
import { ParentIds } from '@src/generic/types';
1515
import {
1616
QueryClient,
17-
skipToken, useMutation, useQuery, useQueryClient,
17+
skipToken, useQuery, useQueryClient,
1818
} from '@tanstack/react-query';
1919
import { useDispatch } from 'react-redux';
2020
import {
@@ -110,11 +110,8 @@ export const useCreateCourseBlock = (
110110
const queryClient = useQueryClient();
111111
const { setData } = useScrollState(courseKey);
112112
const dispatch = useDispatch();
113-
const { setShow } = useProcessingNotification();
114-
return useMutation({
113+
return useMutationWithProcessingNotification({
115114
mutationFn: (variables: CreateCourseXBlockMutationProps) => createCourseXblock(variables),
116-
onMutate: () => setShow(true),
117-
onSettled: () => setShow(false),
118115
onSuccess: async (data: { locator: string; }, variables) => {
119116
await callback?.(data.locator, variables.parentLocator);
120117
queryClient.invalidateQueries({
@@ -189,8 +186,7 @@ export const useCourseDetails = (courseId?: string, enabled: boolean = true) =>
189186
*/
190187
export const useUpdateCourseBlockName = (courseId: string) => {
191188
const queryClient = useQueryClient();
192-
const { setShow } = useProcessingNotification();
193-
return useMutation({
189+
return useMutationWithProcessingNotification({
194190
mutationFn: (variables:{
195191
itemId: string;
196192
displayName: string;
@@ -200,102 +196,82 @@ export const useUpdateCourseBlockName = (courseId: string) => {
200196
queryClient.invalidateQueries({ queryKey: containerComparisonQueryKeys.course(courseId) });
201197
queryClient.invalidateQueries({ queryKey: courseOutlineQueryKeys.courseDetails(courseId) });
202198
},
203-
onMutate: () => setShow(true),
204-
onSettled: () => setShow(false),
205199
});
206200
};
207201

208202
export const usePublishCourseItem = () => {
209203
const queryClient = useQueryClient();
210-
const { setShow } = useProcessingNotification();
211-
return useMutation({
204+
return useMutationWithProcessingNotification({
212205
mutationFn: (variables:{
213206
itemId: string;
214207
} & ParentIds) => publishCourseItem(variables.itemId),
215208
onSettled: (_data, _err, variables) => {
216209
invalidateParentQueries(queryClient, variables).catch((e) => handleResponseErrors(e));
217210
queryClient.invalidateQueries({ queryKey: courseOutlineQueryKeys.courseDetails(getCourseKey(variables.itemId)) });
218-
setShow(false);
219211
},
220-
onMutate: () => setShow(true),
221212
});
222213
};
223214

224215
export const useDeleteCourseItem = () => {
225216
const queryClient = useQueryClient();
226-
const { setShow } = useProcessingNotification();
227-
return useMutation({
217+
return useMutationWithProcessingNotification({
228218
mutationFn: (variables:{
229219
itemId: string;
230220
} & ParentIds) => deleteCourseItem(variables.itemId),
231-
onMutate: () => setShow(true),
232221
onSettled: (_data, _err, variables) => {
233222
queryClient.invalidateQueries({ queryKey: courseOutlineQueryKeys.courseDetails(getCourseKey(variables.itemId)) });
234223
invalidateParentQueries(queryClient, variables).catch((e) => handleResponseErrors(e));
235-
setShow(false);
236224
},
237225
});
238226
};
239227

240228
export const useConfigureSection = () => {
241229
const queryClient = useQueryClient();
242-
const { setShow } = useProcessingNotification();
243-
return useMutation({
230+
return useMutationWithProcessingNotification({
244231
mutationFn: (variables: ConfigureSectionData & ParentIds) => configureCourseSection(variables),
245-
onMutate: () => setShow(true),
246232
onSettled: (_data, _err, variables) => {
247233
queryClient.invalidateQueries({
248234
queryKey: courseOutlineQueryKeys.courseDetails(getCourseKey(variables.sectionId)),
249235
});
250236
invalidateParentQueries(queryClient, variables).catch((e) => handleResponseErrors(e));
251-
setShow(false);
252237
},
253238
});
254239
};
255240

256241
export const useConfigureSubsection = () => {
257242
const queryClient = useQueryClient();
258-
const { setShow } = useProcessingNotification();
259-
return useMutation({
243+
return useMutationWithProcessingNotification({
260244
mutationFn: (variables: ConfigureSubsectionData & ParentIds) => configureCourseSubsection(variables),
261-
onMutate: () => setShow(true),
262245
onSettled: (_data, _err, variables) => {
263246
queryClient.invalidateQueries({ queryKey: courseOutlineQueryKeys.courseDetails(getCourseKey(variables.itemId)) });
264247
invalidateParentQueries(queryClient, variables).catch((e) => handleResponseErrors(e));
265-
setShow(false);
266248
},
267249
});
268250
};
269251

270252
export const useConfigureUnit = () => {
271253
const queryClient = useQueryClient();
272-
const { setShow } = useProcessingNotification();
273-
return useMutation({
254+
return useMutationWithProcessingNotification({
274255
mutationFn: (variables: ConfigureUnitData & ParentIds) => configureCourseUnit(variables),
275-
onMutate: () => setShow(true),
276256
onSettled: (_data, _err, variables) => {
277257
queryClient.invalidateQueries({ queryKey: courseOutlineQueryKeys.courseDetails(getCourseKey(variables.unitId)) });
278258
invalidateParentQueries(queryClient, variables).catch((e) => handleResponseErrors(e));
279-
setShow(false);
280259
},
281260
});
282261
};
283262

284263
export const useUpdateCourseSectionHighlights = () => {
285264
const queryClient = useQueryClient();
286-
const { setShow } = useProcessingNotification();
287-
return useMutation({
265+
return useMutationWithProcessingNotification({
288266
mutationFn: (variables: {
289267
sectionId: string;
290268
highlights: string[];
291269
} & ParentIds) => updateCourseSectionHighlights(variables.sectionId, variables.highlights),
292-
onMutate: () => setShow(true),
293270
onSettled: (_data, _err, variables) => {
294271
queryClient.invalidateQueries({
295272
queryKey: courseOutlineQueryKeys.courseDetails(getCourseKey(variables.sectionId)),
296273
});
297274
invalidateParentQueries(queryClient, variables).catch((e) => handleResponseErrors(e));
298-
setShow(false);
299275
},
300276
});
301277
};
@@ -304,14 +280,11 @@ export const useDuplicateItem = (courseKey: string) => {
304280
const queryClient = useQueryClient();
305281
const dispatch = useDispatch();
306282
const { setData } = useScrollState(courseKey);
307-
const { setShow } = useProcessingNotification();
308-
return useMutation({
283+
return useMutationWithProcessingNotification({
309284
mutationFn: (variables: {
310285
itemId: string;
311286
parentId: string;
312287
} & ParentIds) => duplicateCourseItem(variables.itemId, variables.parentId),
313-
onMutate: () => setShow(true),
314-
onSettled: () => setShow(false),
315288
onSuccess: async (data, variables) => {
316289
await invalidateParentQueries(queryClient, variables);
317290
// add duplicated section to store, subsection and unit are handled by invalidateParentQueries
@@ -338,8 +311,7 @@ export const usePasteItem = (courseId?: string) => {
338311
const queryClient = useQueryClient();
339312
const { setData: setScrollState } = useScrollState(courseId);
340313
const { setData } = usePasteFileNotices(courseId);
341-
const { setShow } = useProcessingNotification();
342-
return useMutation({
314+
return useMutationWithProcessingNotification({
343315
mutationFn: (variables: {
344316
parentLocator: string;
345317
} & ParentIds) => pasteBlock(variables.parentLocator),
@@ -350,7 +322,5 @@ export const usePasteItem = (courseId?: string) => {
350322
// scroll to pasted block
351323
setScrollState({ id: data.locator });
352324
},
353-
onMutate: () => setShow(true),
354-
onSettled: () => setShow(false),
355325
});
356326
};
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { useProcessingNotification } from '../context';
2+
import { useMutation } from '@tanstack/react-query';
3+
import { DefaultError } from '@tanstack/query-core';
4+
5+
6+
/**
7+
* Wraps useMutation to add a processing notification when the mutation is initiated and removes it when the mutation is settled.
8+
*/
9+
export const useMutationWithProcessingNotification = <
10+
TData = unknown,
11+
TError = DefaultError,
12+
TVariables = void,
13+
TOnMutateResult = unknown,
14+
>(...args: Parameters<typeof useMutation<TData, TError, TVariables, TOnMutateResult>>) => {
15+
const { setShow } = useProcessingNotification();
16+
const originalOptions = args[0] || {};
17+
return useMutation({
18+
...originalOptions,
19+
onMutate: async (...onMutateArgs) => {
20+
// Show processing notification
21+
setShow(true);
22+
23+
// Call original onMutate if it exists
24+
return await originalOptions.onMutate?.(...onMutateArgs);
25+
},
26+
onSettled: async (...onSettledArgs) => {
27+
// Call original onSettled if it exists
28+
await originalOptions.onSettled?.(...onSettledArgs);
29+
30+
// Always hide processing notification
31+
setShow(false);
32+
},
33+
})
34+
}

0 commit comments

Comments
 (0)