Skip to content

Commit b7555b7

Browse files
♻️ #262 - refactor: use the destruction list items API for destructoin list detail page
1 parent 3d29a9c commit b7555b7

15 files changed

+168
-58
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {
2+
DestructionListItem,
3+
PaginatedDestructionListItems,
4+
} from "../lib/api/destructionListsItem";
5+
import { createArrayFactory, createObjectFactory } from "./factory";
6+
import { zaakFactory } from "./zaak";
7+
8+
export const FIXTURE_DESTRUCTION_LIST_ITEM: DestructionListItem = {
9+
pk: 1,
10+
zaak: zaakFactory().url,
11+
status: "suggested",
12+
extraZaakData: null,
13+
zaakData: zaakFactory(),
14+
processingStatus: "new",
15+
};
16+
17+
export const destructionListItemFactory = createObjectFactory(
18+
FIXTURE_DESTRUCTION_LIST_ITEM,
19+
);
20+
export const destructionListItemsFactory = createArrayFactory([
21+
FIXTURE_DESTRUCTION_LIST_ITEM,
22+
]);
23+
24+
const FIXTURE_PAGINATED_DESTRUCTION_LIST_ITEMS = {
25+
count: 10,
26+
next: null,
27+
previous: null,
28+
results: destructionListItemsFactory(),
29+
};
30+
31+
export const paginatedDestructionListItemsFactory =
32+
createObjectFactory<PaginatedDestructionListItems>(
33+
FIXTURE_PAGINATED_DESTRUCTION_LIST_ITEMS,
34+
);

frontend/src/lib/api/destructionLists.ts

+2-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { isPrimitive } from "@maykin-ui/admin-ui";
22

33
import { Zaak } from "../../types";
44
import { User } from "./auth";
5+
import { ProcessingStatus } from "./processingStatus";
56
import { request } from "./request";
67

78
export type DestructionList = {
@@ -13,7 +14,7 @@ export type DestructionList = {
1314
created: string;
1415
name: string;
1516
status: DestructionListStatus;
16-
processingStatus: DestructionListProcessingStatus;
17+
processingStatus: ProcessingStatus;
1718
statusChanged: string | null;
1819
uuid: string;
1920
};
@@ -35,13 +36,6 @@ export const DESTRUCTION_LIST_STATUSES = [
3536
// Inferring the type of the array, so that we don't have to repeat the same.
3637
export type DestructionListStatus = (typeof DESTRUCTION_LIST_STATUSES)[number];
3738

38-
export type DestructionListProcessingStatus =
39-
| "new"
40-
| "queued"
41-
| "processing"
42-
| "failed"
43-
| "succeeded";
44-
4539
export type DestructionListUpdateData = {
4640
assignees?: DestructionListAssigneeUpdate[];
4741
items?: DestructionListItemUpdate[];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Zaak } from "../../types";
2+
import { PaginatedResults } from "./paginatedResults";
3+
import { ProcessingStatus } from "./processingStatus";
4+
import { request } from "./request";
5+
6+
export type DestructionListItem = {
7+
pk: number;
8+
zaak: Zaak["url"];
9+
status?: DestructionListItemStatus;
10+
extraZaakData?: Record<string, unknown> | null;
11+
zaakData: Zaak | null;
12+
processingStatus?: ProcessingStatus;
13+
};
14+
15+
export type DestructionListItemStatus = "removed" | "suggested";
16+
17+
export type PaginatedDestructionListItems =
18+
PaginatedResults<DestructionListItem>;
19+
20+
/**
21+
* List destruction lists.
22+
*/
23+
export async function listDestructionListItems(
24+
destructionListUuid: string,
25+
params?:
26+
| URLSearchParams
27+
| {
28+
page?: number;
29+
page_size?: number;
30+
processing_status?: ProcessingStatus;
31+
status: DestructionListItemStatus; // TODO ?
32+
},
33+
) {
34+
const response = await request("GET", "/destruction-list-items/", {
35+
destruction_list: destructionListUuid,
36+
status: "suggested",
37+
...params,
38+
} as typeof params & { destruction_list: string });
39+
const promise: Promise<PaginatedDestructionListItems> = response.json();
40+
return promise;
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export type PaginatedResults<T> = {
2+
count: number;
3+
next: string | null;
4+
previous: string | null;
5+
results: T[];
6+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export type ProcessingStatus =
2+
| "new"
3+
| "queued"
4+
| "processing"
5+
| "failed"
6+
| "succeeded";

frontend/src/lib/api/reviewResponse.ts

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { DestructionList } from "./destructionLists";
21
import { request } from "./request";
32
import { Review, ReviewItem } from "./review";
43

frontend/src/lib/api/zaken.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import { Zaak } from "../../types";
2+
import { PaginatedResults } from "./paginatedResults";
23
import { request } from "./request";
34

4-
export type PaginatedZaken = {
5-
count: number;
6-
next: string | null;
7-
previous: string | null;
8-
results: Zaak[];
9-
};
5+
export type PaginatedZaken = PaginatedResults<Zaak>;
106

117
/**
128
* Retrieve zaken using the configured ZRC service. For information over the query parameters accepted and the schema of

frontend/src/pages/constants.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { BadgeProps, Outline } from "@maykin-ui/admin-ui";
22

33
import {
44
DESTRUCTION_LIST_STATUSES,
5-
DestructionListProcessingStatus,
65
DestructionListStatus,
76
} from "../lib/api/destructionLists";
7+
import { ProcessingStatus } from "../lib/api/processingStatus";
88
import { Review } from "../lib/api/review";
99

1010
export const REVIEW_DECISION_MAPPING: Record<Review["decision"], string> = {
@@ -45,7 +45,7 @@ export const STATUS_LEVEL_MAPPING: {
4545
};
4646

4747
export const PROCESSING_STATUS_MAPPING: {
48-
[key in DestructionListProcessingStatus]: string;
48+
[key in ProcessingStatus]: string;
4949
} = {
5050
new: "new",
5151
queued: "queued",
@@ -55,7 +55,7 @@ export const PROCESSING_STATUS_MAPPING: {
5555
};
5656

5757
export const PROCESSING_STATUS_ICON_MAPPING: {
58-
[key in DestructionListProcessingStatus]: React.ReactNode;
58+
[key in ProcessingStatus]: React.ReactNode;
5959
} = {
6060
new: <Outline.PlusCircleIcon />,
6161
queued: <Outline.CircleStackIcon />,
@@ -65,7 +65,7 @@ export const PROCESSING_STATUS_ICON_MAPPING: {
6565
};
6666

6767
export const PROCESSING_STATUS_LEVEL_MAPPING: {
68-
[key in DestructionListProcessingStatus]: BadgeProps["level"];
68+
[key in ProcessingStatus]: BadgeProps["level"];
6969
} = {
7070
new: "info",
7171
queued: "info",

frontend/src/pages/destructionlist/detail/DestructionListDetail.loader.ts

+14-7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import {
77
DestructionList,
88
getDestructionList,
99
} from "../../../lib/api/destructionLists";
10+
import {
11+
PaginatedDestructionListItems,
12+
listDestructionListItems,
13+
} from "../../../lib/api/destructionListsItem";
1014
import { listSelectieLijstKlasseChoices } from "../../../lib/api/private";
1115
import {
1216
Review,
@@ -32,7 +36,7 @@ export interface DestructionListDetailContext {
3236
reviewers: User[];
3337
archivists: User[];
3438
user: User;
35-
zaken: PaginatedZaken;
39+
destructionListItems: PaginatedDestructionListItems;
3640
selectableZaken: PaginatedZaken;
3741
zaakSelection: ZaakSelection;
3842
review: Review | null;
@@ -81,13 +85,16 @@ export const destructionListDetailLoader = loginRequired(
8185
// Fetch selectable zaken: empty array if review collected OR all zaken not in another destruction list.
8286
// FIXME: Accept no/implement real pagination?
8387
reviewItems
84-
? ({
88+
? {
8589
count: reviewItems.length,
8690
next: null,
8791
previous: null,
8892
results: [],
89-
} as PaginatedZaken)
90-
: listZaken({ ...searchParams, in_destruction_list: uuid }).catch(
93+
}
94+
: listDestructionListItems(
95+
uuid,
96+
searchParams as unknown as URLSearchParams,
97+
).catch(
9198
// Intercept (and ignore) 404 due to the following scenario cause by shared `page` parameter:
9299
//
93100
// User navigates to destruction list with 1 page of items.
@@ -148,15 +155,15 @@ export const destructionListDetailLoader = loginRequired(
148155
reviewers,
149156
archivists,
150157
user,
151-
zaken,
158+
destructionListItems,
152159
allZaken,
153160
zaakSelection,
154161
selectieLijstKlasseChoicesMap,
155162
] = (await Promise.all(promises)) as [
156163
User[],
157164
User[],
158165
User,
159-
PaginatedZaken,
166+
PaginatedDestructionListItems,
160167
PaginatedZaken,
161168
ZaakSelection,
162169
Record<string, Option[]>,
@@ -175,7 +182,7 @@ export const destructionListDetailLoader = loginRequired(
175182
reviewers,
176183
archivists: filteredArchivists,
177184
user,
178-
zaken,
185+
destructionListItems: destructionListItems,
179186
selectableZaken: allZaken,
180187
zaakSelection,
181188
review: review,

frontend/src/pages/destructionlist/detail/DestructionListDetail.stories.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
fillForm,
1313
} from "../../../../.storybook/playFunctions";
1414
import { destructionListFactory } from "../../../fixtures/destructionList";
15+
import { paginatedDestructionListItemsFactory } from "../../../fixtures/destructionListItem";
1516
import { paginatedZakenFactory } from "../../../fixtures/paginatedZaken";
1617
import { reviewFactory } from "../../../fixtures/review";
1718
import { reviewItemsFactory } from "../../../fixtures/reviewItem";
@@ -123,7 +124,7 @@ const FIXTURE_EDIT: DestructionListDetailContext = {
123124
reviewers: usersFactory(),
124125
archivists: usersFactory(),
125126
user: usersFactory()[0],
126-
zaken: paginatedZakenFactory(),
127+
destructionListItems: paginatedDestructionListItemsFactory(),
127128
selectableZaken: paginatedZakenFactory(),
128129
zaakSelection: {},
129130
review: null,
@@ -164,7 +165,7 @@ const FIXTURE_PROCESS_REVIEW: DestructionListDetailContext = {
164165
reviewers: usersFactory(),
165166
archivists: usersFactory(),
166167
user: usersFactory()[0],
167-
zaken: {
168+
destructionListItems: {
168169
count: reviewItemsFactory().length,
169170
next: null,
170171
previous: null,
@@ -274,7 +275,7 @@ const FIXTURE_FINAL_DESTRUCTION: DestructionListDetailContext = {
274275
reviewers: usersFactory(),
275276
archivists: usersFactory(),
276277
user: usersFactory()[0],
277-
zaken: {
278+
destructionListItems: {
278279
count: reviewItemsFactory().length,
279280
next: null,
280281
previous: null,
@@ -346,7 +347,7 @@ const FIXTURE_DELETE: DestructionListDetailContext = {
346347
reviewers: usersFactory(),
347348
archivists: usersFactory(),
348349
user: usersFactory()[0],
349-
zaken: paginatedZakenFactory(),
350+
destructionListItems: paginatedDestructionListItemsFactory(),
350351
selectableZaken: paginatedZakenFactory(),
351352
zaakSelection: {},
352353
review: null,

frontend/src/pages/destructionlist/detail/DestructionListDetail.tsx

+12-7
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ import {
1212
field2Title,
1313
} from "@maykin-ui/admin-ui";
1414
import { FormEvent, useState } from "react";
15-
import { useLoaderData, useRevalidator } from "react-router-dom";
15+
import { useLoaderData } from "react-router-dom";
1616

1717
import { useSubmitAction } from "../../../hooks";
18-
import { usePoll } from "../../../hooks/usePoll";
1918
import {
2019
canMarkListAsFinal,
2120
canTriggerDestruction,
@@ -35,8 +34,14 @@ import { DestructionListToolbar } from "./components/DestructionListToolbar/Dest
3534
* Destruction list detail page
3635
*/
3736
export function DestructionListDetailPage() {
38-
const { archivists, destructionList, review, reviewers, user, zaken } =
39-
useLoaderData() as DestructionListDetailContext;
37+
const {
38+
archivists,
39+
destructionList,
40+
review,
41+
reviewers,
42+
user,
43+
destructionListItems,
44+
} = useLoaderData() as DestructionListDetailContext;
4045
const submitAction = useSubmitAction<UpdateDestructionListAction>();
4146

4247
const [archivistModalOpenState, setArchivistModalOpenState] = useState(false);
@@ -194,8 +199,8 @@ export function DestructionListDetailPage() {
194199
>
195200
<Body>
196201
<P>
197-
U staat op het punt om {zaken.count} zaken definitief te
198-
vernietigen.
202+
U staat op het punt om {destructionListItems.count} zaken
203+
definitief te vernietigen.
199204
</P>
200205
</Body>
201206
<Body>
@@ -204,7 +209,7 @@ export function DestructionListDetailPage() {
204209
variant: "danger",
205210
}}
206211
fields={destroyModalFormFields}
207-
labelSubmit={`${zaken.count} zaken vernietigen`}
212+
labelSubmit={`${destructionListItems.count} zaken vernietigen`}
208213
validate={validateDestroy}
209214
validateOnChange={true}
210215
role="form"

frontend/src/pages/destructionlist/detail/components/DestructionListEdit/DestructionListEdit.tsx

+11-5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
addToZaakSelection,
1414
getZaakSelection,
1515
} from "../../../../../lib/zaakSelection/zaakSelection";
16+
import { Zaak } from "../../../../../types";
1617
import { useDataGridProps } from "../../../hooks";
1718
import { UpdateDestructionListAction } from "../../DestructionListDetail.action";
1819
import { DestructionListDetailContext } from "../../DestructionListDetail.loader";
@@ -29,13 +30,16 @@ export function DestructionListEdit() {
2930
const {
3031
storageKey,
3132
destructionList,
32-
zaken,
33+
destructionListItems,
3334
user,
3435
selectableZaken,
3536
zaakSelection,
3637
review,
3738
reviewItems,
3839
} = useLoaderData() as DestructionListDetailContext;
40+
const zakenOnPage = destructionListItems.results
41+
.map((dt) => dt.zaakData)
42+
.filter((v): v is Zaak => Boolean(v));
3943

4044
// Whether the user is adding/removing items from the destruction list.
4145
const isEditingState = !review && Boolean(urlSearchParams.get("is_editing"));
@@ -126,20 +130,22 @@ export function DestructionListEdit() {
126130
}
127131
: isEditingState
128132
? selectableZaken
129-
: zaken,
130-
isEditingState ? [...zaken.results, ...selectedUrls] : [],
133+
: destructionListItems,
134+
isEditingState ? [...zakenOnPage, ...selectedUrls] : [],
131135
);
132136

133137
// Update the selected zaken to session storage.
134138
useAsync(async () => {
135-
await addToZaakSelection(storageKey, zaken.results);
139+
await addToZaakSelection(storageKey, zakenOnPage);
136140
}, []);
137141

138142
return (
139143
<DataGrid
140144
{...dataGridProps}
141145
boolProps={{ explicit: true }}
142-
count={isEditingState ? selectableZaken.count : zaken.count}
146+
count={
147+
isEditingState ? selectableZaken.count : destructionListItems.count
148+
}
143149
filterable={isEditingState}
144150
loading={state === "loading"}
145151
selectable={Boolean(isEditingState)}

0 commit comments

Comments
 (0)