Skip to content

Commit 9a0aba5

Browse files
♻️ #187 - refactor: create separate (sub)pages for editing and processing a review of a destruction list
1 parent f8ea71b commit 9a0aba5

File tree

4 files changed

+449
-371
lines changed

4 files changed

+449
-371
lines changed

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ import {
4040
getZaakSelection,
4141
} from "../../../lib/zaakSelection/zaakSelection";
4242
import "./DestructionListDetail.css";
43-
import { DestructionListItems } from "./DestructionListItems";
43+
import { DestructionListEdit } from "./DestructionListEdit";
44+
import { DestructionListProcessReview } from "./DestructionListProcessReview";
4445
import { DestructionListDetailContext } from "./types";
4546

4647
/**
@@ -95,7 +96,7 @@ export function DestructionListDetailPage() {
9596
review={review}
9697
reviewers={reviewers}
9798
/>
98-
<DestructionListItems />
99+
{review ? <DestructionListProcessReview /> : <DestructionListEdit />}
99100
<Modal
100101
title="Markeer als definitief"
101102
open={modalOpenState}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import { ButtonProps, DataGrid, Outline } from "@maykin-ui/admin-ui";
2+
import React from "react";
3+
import {
4+
useLoaderData,
5+
useNavigation,
6+
useSearchParams,
7+
} from "react-router-dom";
8+
import { useAsync } from "react-use";
9+
10+
import { useSubmitAction } from "../../../hooks/useSubmitAction";
11+
import { canUpdateDestructionList } from "../../../lib/auth/permissions";
12+
import {
13+
addToZaakSelection,
14+
getZaakSelection,
15+
} from "../../../lib/zaakSelection/zaakSelection";
16+
import { useDataGridProps } from "../hooks";
17+
import { UpdateDestructionListAction } from "./DestructionListDetail";
18+
import "./DestructionListDetail.css";
19+
import { DestructionListDetailContext } from "./types";
20+
21+
/**
22+
* Show items of a destruction list.
23+
* Allows viewing, adding and removing destruction list items.
24+
*/
25+
export function DestructionListEdit() {
26+
const { state } = useNavigation();
27+
const [urlSearchParams, setUrlSearchParams] = useSearchParams();
28+
const submitAction = useSubmitAction();
29+
30+
const {
31+
storageKey,
32+
destructionList,
33+
zaken,
34+
user,
35+
selectableZaken,
36+
zaakSelection,
37+
review,
38+
reviewItems,
39+
} = useLoaderData() as DestructionListDetailContext;
40+
41+
// Whether the user is adding/removing items from the destruction list.
42+
const isEditingState = !review && Boolean(urlSearchParams.get("is_editing"));
43+
44+
//
45+
// SHARED VARS
46+
//
47+
48+
// An object of {url: string} items used to indicate (additional) selected zaken.
49+
const selectedUrls = Object.entries(zaakSelection)
50+
.filter(([, { selected }]) => selected)
51+
.map(([url]) => ({ url }));
52+
53+
//
54+
// EDITING MODE VARS
55+
//
56+
57+
/**
58+
* Gets called when the user clicks the edit button (user intents to adds/remove zaken to/from the destruction list
59+
* or escape such flow).
60+
* @param value
61+
*/
62+
const handleEditSetEditing = (value: boolean) => {
63+
urlSearchParams.set("page", "1");
64+
value
65+
? urlSearchParams.set("is_editing", "true")
66+
: urlSearchParams.delete("is_editing");
67+
setUrlSearchParams(urlSearchParams);
68+
};
69+
70+
/**
71+
* Gets called when the user updates the zaak selection (adds/remove zaken to/from the destruction list).
72+
*/
73+
const handleEditUpdate = async () => {
74+
const zaakSelection = await getZaakSelection(storageKey);
75+
const zaakUrls = Object.entries(zaakSelection)
76+
.filter(([, selection]) => selection.selected)
77+
.map(([url]) => url);
78+
79+
const action: UpdateDestructionListAction<Record<string, string[]>> = {
80+
type: "UPDATE_ZAKEN",
81+
payload: {
82+
zaakUrls,
83+
},
84+
};
85+
submitAction(action);
86+
};
87+
88+
// Selection actions allowing the user to add/remove zaken to/from the destruction list or escape such flow.
89+
const editSelectionActions: ButtonProps[] = isEditingState
90+
? [
91+
{
92+
children: "Vernietigingslijst aanpassen",
93+
onClick: handleEditUpdate,
94+
wrap: false,
95+
},
96+
{
97+
children: "Annuleren",
98+
onClick: () => handleEditSetEditing(false),
99+
wrap: false,
100+
},
101+
]
102+
: canUpdateDestructionList(user, destructionList)
103+
? [
104+
{
105+
"aria-label": "Bewerken",
106+
children: <Outline.PencilIcon />,
107+
onClick: () => handleEditSetEditing(true),
108+
wrap: false,
109+
},
110+
]
111+
: [];
112+
113+
//
114+
// RENDERING
115+
//
116+
117+
// Get the base props for the DataGrid component.
118+
const { props: dataGridProps } = useDataGridProps(
119+
storageKey,
120+
reviewItems
121+
? // FIXME: Accept no/implement real pagination?
122+
{
123+
count: reviewItems.length,
124+
next: null,
125+
previous: null,
126+
results: reviewItems.map((ri) => ri.zaak),
127+
}
128+
: isEditingState
129+
? selectableZaken
130+
: zaken,
131+
isEditingState ? [...zaken.results, ...selectedUrls] : [],
132+
);
133+
134+
// Update the selected zaken to session storage.
135+
useAsync(async () => {
136+
await addToZaakSelection(storageKey, zaken.results);
137+
}, []);
138+
139+
return (
140+
<DataGrid
141+
{...dataGridProps}
142+
boolProps={{ explicit: true }}
143+
count={isEditingState ? selectableZaken.count : zaken.count}
144+
filterable={isEditingState}
145+
loading={state === "loading"}
146+
selectable={Boolean(isEditingState)}
147+
allowSelectAll={!reviewItems}
148+
selectionActions={editSelectionActions}
149+
showPaginator={true}
150+
sort={isEditingState}
151+
title="Zaakdossiers"
152+
/>
153+
);
154+
}

0 commit comments

Comments
 (0)