Skip to content

Commit 93b9360

Browse files
authored
Merge pull request #744 from maykinmedia/issue/#739-abort-controllers
✨ [#739] - feat: abort controller
2 parents 276c8cc + 2901a19 commit 93b9360

38 files changed

+403
-148
lines changed

frontend/src/App.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,14 @@ function App() {
6161
);
6262

6363
useAsync(async () => {
64-
const user = await whoAmI();
64+
const abortController = new AbortController();
65+
const user = await whoAmI(abortController.signal);
6566
setUser(user);
6667
}, [state]);
6768

6869
useAsync(async () => {
69-
const info = await getOIDCInfo();
70+
const abortController = new AbortController();
71+
const info = await getOIDCInfo(abortController.signal);
7072
setOidcInfo(info);
7173
}, [state]);
7274

frontend/src/components/DestructionListReviewer/DestructionListReviewer.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ export function DestructionListReviewer({
5252
const alert = useAlert();
5353
const formDialog = useFormDialog<DestructionListReviewerFormType>();
5454
const { data: coReviews } = useDataFetcher(
55-
() => listCoReviews({ destructionList__uuid: destructionList?.uuid }),
55+
(signal) =>
56+
listCoReviews({ destructionList__uuid: destructionList?.uuid }, signal),
5657
{
5758
initialState: [],
5859
errorMessage:
@@ -91,7 +92,7 @@ export function DestructionListReviewer({
9192
[destructionList.uuid],
9293
);
9394
const { data: user } = useDataFetcher(
94-
whoAmI,
95+
(signal) => whoAmI(signal),
9596
{
9697
errorMessage:
9798
"Er is een fout opgetreden bij het ophalen van de huidige gebruiker!",

frontend/src/components/DestructionListToolbar/DestructionListToolbar.tsx

+7-6
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ export function DestructionListToolbar({
6060
review,
6161
}: DestructionListToolbarProps) {
6262
const { data: logItems } = useDataFetcher(
63-
() => {
63+
(signal) => {
6464
if (!destructionList) return Promise.resolve([]);
65-
return listAuditLog(destructionList.uuid);
65+
return listAuditLog(destructionList.uuid, undefined, signal);
6666
},
6767
{
6868
initialState: [],
@@ -73,11 +73,12 @@ export function DestructionListToolbar({
7373
);
7474

7575
const { data: logItemsReadyForFirstReview } = useDataFetcher(
76-
() => {
76+
(signal) => {
7777
if (!destructionList) return Promise.resolve([]);
7878
return listAuditLog(
7979
destructionList.uuid,
8080
"destruction_list_ready_for_first_review",
81+
signal,
8182
);
8283
},
8384
{
@@ -89,9 +90,9 @@ export function DestructionListToolbar({
8990
);
9091

9192
const { data: reviewResponse } = useDataFetcher(
92-
() => {
93+
(signal) => {
9394
if (!review) return Promise.resolve(null);
94-
return getLatestReviewResponse({ review: review.pk });
95+
return getLatestReviewResponse({ review: review.pk }, signal);
9596
},
9697
{
9798
initialState: null,
@@ -104,7 +105,7 @@ export function DestructionListToolbar({
104105
const formDialog = useFormDialog();
105106
const alert = useAlert();
106107
const { data: user } = useDataFetcher(
107-
whoAmI,
108+
(signal) => whoAmI(signal),
108109
{
109110
errorMessage:
110111
"Er is een fout opgetreden bij het ophalen van de huidige gebruiker!",

frontend/src/hooks/useFields.test.ts

+6-24
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import { TypedField } from "@maykin-ui/admin-ui";
22
import { act, renderHook, waitFor } from "@testing-library/react";
33

4-
import { selectieLijstKlasseFactory as mockSelectieLijstKlasseFactory } from "../fixtures/selectieLijstKlasseChoices";
5-
import {
6-
listSelectielijstKlasseChoices,
7-
listZaaktypeChoices,
8-
} from "../lib/api/private";
94
import * as fieldSelection from "../lib/fieldSelection/fieldSelection";
105
import { useDataFetcher } from "./useDataFetcher";
116
import { useFields } from "./useFields";
@@ -28,23 +23,7 @@ jest.mock("react-router-dom", () => ({
2823
describe("useFields Hook", () => {
2924
beforeEach(() => {
3025
jest.clearAllMocks();
31-
32-
// Return different data based on the fetch function
33-
(useDataFetcher as jest.Mock).mockImplementation((fetchFunction) => {
34-
if (fetchFunction === listSelectielijstKlasseChoices) {
35-
return {
36-
data: mockSelectieLijstKlasseFactory(),
37-
loading: false,
38-
error: false,
39-
};
40-
}
41-
if (fetchFunction === listZaaktypeChoices) {
42-
return {
43-
data: undefined,
44-
loading: false,
45-
error: false,
46-
};
47-
}
26+
(useDataFetcher as jest.Mock).mockImplementation(() => {
4827
return { data: [], loading: false, error: false };
4928
});
5029
});
@@ -127,9 +106,12 @@ describe("useFields Hook", () => {
127106
});
128107
});
129108

130-
it("should provide selectielijst klasse options to selectielijst klasse field", async () => {
131-
const { result } = await act(async () => renderHook(() => useFields()));
109+
it.only("should provide selectielijst klasse options to selectielijst klasse field", async () => {
110+
(useDataFetcher as jest.Mock).mockImplementation(() => {
111+
return { data: [{ value: "https://" }], loading: false, error: false };
112+
});
132113

114+
const { result } = await act(async () => renderHook(() => useFields()));
133115
const [fields] = result.current;
134116
const selectielijstKlasse = fields.find(
135117
(f) => f.name === "selectielijstklasse",

frontend/src/hooks/useFields.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export function useFields<T extends Zaak = Zaak>(
9595
}
9696

9797
const { data: selectielijstKlasseChoices } = useDataFetcher(
98-
listSelectielijstKlasseChoices,
98+
(signal) => listSelectielijstKlasseChoices(undefined, signal),
9999
{
100100
errorMessage:
101101
"Er is een fout opgetreden bij het ophalen van selectielijst klassen!",
@@ -105,7 +105,7 @@ export function useFields<T extends Zaak = Zaak>(
105105
);
106106

107107
const { data: zaaktypeChoices } = useDataFetcher(
108-
() => listZaaktypeChoices(zaaktypeParams),
108+
(signal) => listZaaktypeChoices(zaaktypeParams, false, signal),
109109
{
110110
errorMessage: "Er is een fout opgetreden bij het ophalen van zaaktypen!",
111111
initialState: [],

frontend/src/hooks/useSelectielijstKlasseChoices.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { useDataFetcher } from "./useDataFetcher";
66

77
const MockSelectieLijstKlasseChoicesHook = () => {
88
return useDataFetcher(
9-
listSelectielijstKlasseChoices,
9+
(signal) => listSelectielijstKlasseChoices(undefined, signal),
1010
{
1111
initialState: [],
1212
errorMessage:

frontend/src/lib/api/archivist.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ export type Archivist = {
99
/**
1010
* List all the users that have the permission to archive destruction lists.
1111
*/
12-
export async function listArchivists() {
13-
const response = await request("GET", "/users", { role: "archivist" });
12+
export async function listArchivists(signal?: AbortSignal) {
13+
const response = await request(
14+
"GET",
15+
"/users",
16+
{ role: "archivist" },
17+
undefined,
18+
undefined,
19+
signal,
20+
);
1421
const promise: Promise<User[]> = response.json();
1522
return promise;
1623
}

frontend/src/lib/api/auditLog.ts

+17-5
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,24 @@ export type AuditLogItem = {
3838
* Retrieve the audit log for this destruction list.
3939
* @param uuid
4040
* @param event
41+
* @param signal
4142
*/
42-
export async function listAuditLog(uuid: string, event?: string) {
43-
const response = await request("GET", "/logs/", {
44-
destruction_list: uuid,
45-
...(event && { event }),
46-
});
43+
export async function listAuditLog(
44+
uuid: string,
45+
event?: string,
46+
signal?: AbortSignal,
47+
) {
48+
const response = await request(
49+
"GET",
50+
"/logs/",
51+
{
52+
destruction_list: uuid,
53+
...(event && { event }),
54+
},
55+
undefined,
56+
undefined,
57+
signal,
58+
);
4759
const promise: AuditLogItem[] = await response.json();
4860
return promise;
4961
}

frontend/src/lib/api/auth.ts

+44-11
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,54 @@ export type Role = {
2222
* API call for login.
2323
* @param username
2424
* @param password
25+
* @param signal
2526
*/
26-
export async function login(username: string, password: string) {
27-
return request("POST", "/auth/login/", undefined, {
28-
username,
29-
password,
30-
});
27+
export async function login(
28+
username: string,
29+
password: string,
30+
signal?: AbortSignal,
31+
) {
32+
return request(
33+
"POST",
34+
"/auth/login/",
35+
undefined,
36+
{
37+
username,
38+
password,
39+
},
40+
undefined,
41+
signal,
42+
);
3143
}
3244

3345
/**
3446
* API call for logout.
3547
*/
36-
export async function logout() {
48+
export async function logout(signal?: AbortSignal) {
3749
await cacheDelete("whoAmI");
38-
return request("POST", "/auth/logout/");
50+
return request(
51+
"POST",
52+
"/auth/logout/",
53+
undefined,
54+
undefined,
55+
undefined,
56+
signal,
57+
);
3958
}
4059

4160
/**
4261
* API call to get the current logged-in user.
4362
*/
44-
export async function whoAmI() {
63+
export async function whoAmI(signal?: AbortSignal) {
4564
return cacheMemo("whoAmI", async () => {
46-
const response = await request("GET", "/whoami/");
65+
const response = await request(
66+
"GET",
67+
"/whoami/",
68+
undefined,
69+
undefined,
70+
undefined,
71+
signal,
72+
);
4773
const promise: Promise<User> = response.json();
4874
return promise;
4975
});
@@ -52,9 +78,16 @@ export async function whoAmI() {
5278
/**
5379
* API call to get info about OIDC.
5480
*/
55-
export async function getOIDCInfo() {
81+
export async function getOIDCInfo(signal?: AbortSignal) {
5682
return cacheMemo("getOIDCInfo", async () => {
57-
const response = await request("GET", "/oidc-info");
83+
const response = await request(
84+
"GET",
85+
"/oidc-info",
86+
undefined,
87+
undefined,
88+
undefined,
89+
signal,
90+
);
5891
const promise: Promise<OidcConfigContextType> = response.json();
5992
return promise;
6093
});

frontend/src/lib/api/coReview.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ export type CoReview = CoReviewBase & {
1616
/**
1717
* Create a new co-review.
1818
*/
19-
export async function createCoReview(data: CoReviewBase) {
19+
export async function createCoReview(data: CoReviewBase, signal?: AbortSignal) {
2020
const response = await request(
2121
"POST",
2222
"/destruction-list-co-reviews/",
2323
undefined,
2424
{
2525
...data,
2626
},
27+
undefined,
28+
signal,
2729
);
2830
const promise: Promise<unknown> = response.json();
2931
return promise;
@@ -39,11 +41,15 @@ export async function listCoReviews(
3941
destructionList__uuid?: DestructionList["uuid"];
4042
ordering?: "-created" | "created";
4143
},
44+
signal?: AbortSignal,
4245
) {
4346
const response = await request(
4447
"GET",
4548
"/destruction-list-co-reviews/",
4649
params,
50+
undefined,
51+
undefined,
52+
signal,
4753
);
4854
const promise: Promise<CoReview[]> = response.json();
4955
return promise;

frontend/src/lib/api/config.ts

+21-3
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,25 @@ export type ArchiveConfiguration = {
5050
* const archiveConfig = await getArchiveConfig();
5151
* console.log(archiveConfig);
5252
*/
53-
export async function getArchiveConfiguration(): Promise<ArchiveConfiguration> {
54-
const response = await request("GET", "/archive-config");
53+
export async function getArchiveConfiguration(
54+
signal?: AbortSignal,
55+
): Promise<ArchiveConfiguration> {
56+
const response = await request(
57+
"GET",
58+
"/archive-config",
59+
undefined,
60+
undefined,
61+
undefined,
62+
signal,
63+
);
5564
const promise: Promise<ArchiveConfiguration> = response.json();
5665
return promise;
5766
}
5867

5968
/**
6069
* API call to PATCH the archive configuration
6170
* @param {ArchiveConfiguration } archiveConfig The archive configuration
71+
* @param signal
6272
* @returns {Promise<void>} The archive configuration
6373
* @throws {Error} If the request fails
6474
* @example
@@ -67,6 +77,14 @@ export async function getArchiveConfiguration(): Promise<ArchiveConfiguration> {
6777
*/
6878
export async function patchArchiveConfiguration(
6979
archiveConfig: ArchiveConfiguration,
80+
signal?: AbortSignal,
7081
): Promise<void> {
71-
await request("PATCH", "/archive-config", undefined, archiveConfig);
82+
await request(
83+
"PATCH",
84+
"/archive-config",
85+
undefined,
86+
archiveConfig,
87+
undefined,
88+
signal,
89+
);
7290
}

frontend/src/lib/api/destructionLists.ts

+4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export type DestructionListMarkAsFinalData = {
7171
* @param zaakFilters FIXME: Must be a JSON object containing the filter data.
7272
* @param allZakenSelected
7373
* @param comment
74+
* @param signal
7475
*/
7576
export async function createDestructionList(
7677
name: string,
@@ -79,6 +80,7 @@ export async function createDestructionList(
7980
zaakFilters: string,
8081
allZakenSelected: boolean,
8182
comment?: string,
83+
signal?: AbortSignal,
8284
) {
8385
const urls = zaken.map((zaak) => (isPrimitive(zaak) ? zaak : zaak.url));
8486

@@ -96,6 +98,8 @@ export async function createDestructionList(
9698
"/destruction-lists/",
9799
{},
98100
destructionList,
101+
undefined,
102+
signal,
99103
);
100104
const promise: Promise<DestructionList> = response.json();
101105
return promise;

0 commit comments

Comments
 (0)