From a8689572499c0ef710c1119615056d58ebb59334 Mon Sep 17 00:00:00 2001 From: Sven van de Scheur Date: Tue, 1 Oct 2024 15:09:59 +0200 Subject: [PATCH 1/5] :recycle: - refactor: migrate detail process review to BaseListView --- .../test_feature_list_process_review.py | 5 +- .../openarchiefbeheer/utils/tests/gherkin.py | 28 +- frontend/.storybook/playFunctions.ts | 14 - .../destructionlist/abstract/BaseListView.tsx | 5 +- .../detail/DestructionListDetail.stories.tsx | 25 +- .../detail/DestructionListDetail.tsx | 16 +- .../DestructionListProcessReview.tsx | 289 +++++---- .../DestructionListProcessZaakReviewModal.tsx | 6 +- .../src/pages/destructionlist/hooks/index.ts | 3 +- .../hooks/useDataGridProps.tsx | 568 ------------------ .../hooks/useZaakReviewStatusBadges.tsx | 58 ++ .../hooks/useZaakReviewStatuses.tsx | 60 ++ .../destructionlist/hooks/useZaakSelection.ts | 47 +- .../review/DestructionListReview.loader.ts | 30 +- .../review/DestructionListReview.stories.tsx | 2 +- .../review/DestructionListReview.tsx | 75 +-- 16 files changed, 354 insertions(+), 877 deletions(-) delete mode 100644 frontend/src/pages/destructionlist/hooks/useDataGridProps.tsx create mode 100644 frontend/src/pages/destructionlist/hooks/useZaakReviewStatusBadges.tsx create mode 100644 frontend/src/pages/destructionlist/hooks/useZaakReviewStatuses.tsx diff --git a/backend/src/openarchiefbeheer/destruction/tests/e2e/features/test_feature_list_process_review.py b/backend/src/openarchiefbeheer/destruction/tests/e2e/features/test_feature_list_process_review.py index 057ac9cd..d19a0f88 100644 --- a/backend/src/openarchiefbeheer/destruction/tests/e2e/features/test_feature_list_process_review.py +++ b/backend/src/openarchiefbeheer/destruction/tests/e2e/features/test_feature_list_process_review.py @@ -51,8 +51,7 @@ async def test_scenario_record_manager_process_review(self): await self.when.user_clicks_button(page, "Destruction list to process") await self.then.path_should_be(page, "/destruction-lists/00000000-0000-0000-0000-000000000000") - # TODO - await self.when.user_clicks_checkbox(page, "(de)selecteer rij") + await self.when.user_clicks_button(page, "Muteren") # Fill selectielijstklasse as it's probably missing. await self.when.user_clicks_radio(page, "Aanpassen van selectielijstklasse") @@ -66,7 +65,7 @@ async def test_scenario_record_manager_process_review(self): await self.when.user_fills_form_field(page, "Reden", "Andere datum") await self.when.user_clicks_button(page, "muteren") await self.when.user_clicks_button(page, "Opnieuw indienen") - await self.when.user_fills_form_field(page, "Opmerking", "Datum aangepast") + await self.when.user_fills_form_field(page, "Opmerking", "Datum aangepast", None, 1) await self.when.user_clicks_button(page, "Opnieuw indienen", 1) await self.then.path_should_be(page, "/destruction-lists") diff --git a/backend/src/openarchiefbeheer/utils/tests/gherkin.py b/backend/src/openarchiefbeheer/utils/tests/gherkin.py index c138a7de..46a69846 100644 --- a/backend/src/openarchiefbeheer/utils/tests/gherkin.py +++ b/backend/src/openarchiefbeheer/utils/tests/gherkin.py @@ -344,25 +344,31 @@ async def _user_clicks(self, role, page, name, index=0): await element.wait_for() await element.click() - async def user_fills_form_field(self, page, label, value, role=None): - select = await page.query_selector(f'.mykn-select[title="{label}"]') - if select: # has content so select? - await select.click() - options = await select.query_selector_all(".mykn-option") + async def user_fills_form_field(self, page, label, value, role=None, index=0): + selects = await page.query_selector_all(f'.mykn-select[title="{label}"]') + try: + select = selects[index] + + if select: # has content so select? + await select.click() + options = await select.query_selector_all(".mykn-option") - for option in options: - text_content = await option.text_content() - if text_content == value: - return await option.click() + for option in options: + text_content = await option.text_content() + if text_content == value: + return await option.click() - return + return + except IndexError: + pass if role: locator = page.get_by_label(label).and_(page.get_by_role("textbox")) else: locator = page.get_by_label(label) - await locator.fill(value) + elements = await locator.all() + await elements[index].fill(value) async def user_filters_zaken(self, page, name, value): locator = page.get_by_role("textbox", name=name) diff --git a/frontend/.storybook/playFunctions.ts b/frontend/.storybook/playFunctions.ts index 11e8d89c..7a274aaf 100644 --- a/frontend/.storybook/playFunctions.ts +++ b/frontend/.storybook/playFunctions.ts @@ -279,20 +279,6 @@ export const fillButtonConfirmationForm: PlayFunction = async ( }); }; -/** - * Clicks element at position `elementIndex`, within if `inTbody` is truthy. - * Then fills in dialog form, submits if `submitForm` is truthy. - * @param context - */ -export const fillCheckboxConfirmationForm: PlayFunction = async ( - context, -) => { - await fillConfirmationForm({ - ...context, - parameters: { ...context.parameters, checked: true, role: "checkbox" }, - }); -}; - /** * Clicks element at position `elementIndex`, within if `inTbody` is truthy. * Then fills in dialog form, submits if `submitForm` is truthy. diff --git a/frontend/src/pages/destructionlist/abstract/BaseListView.tsx b/frontend/src/pages/destructionlist/abstract/BaseListView.tsx index aa9f45c2..269ff650 100644 --- a/frontend/src/pages/destructionlist/abstract/BaseListView.tsx +++ b/frontend/src/pages/destructionlist/abstract/BaseListView.tsx @@ -35,7 +35,8 @@ export type BaseListViewProps = React.PropsWithChildren<{ paginatedZaken: PaginatedZaken; secondaryNavigationItems?: ListTemplateProps["secondaryNavigationItems"]; - selectable?: boolean; + // Visible means that no checkboxes appear, but the zaken are marked if selected (via another route). + selectable?: boolean | "visible"; allowSelectAllPages?: boolean; selectionActions?: ButtonProps[]; initiallySelectedZakenOnPage?: Zaak[]; @@ -164,7 +165,7 @@ export function BaseListView({ fieldsSelectable: true, pageSize: 100, showPaginator: true, - selectable: selectable, + selectable: selectable === true, filterable: true, tableLayout: "fixed", diff --git a/frontend/src/pages/destructionlist/detail/DestructionListDetail.stories.tsx b/frontend/src/pages/destructionlist/detail/DestructionListDetail.stories.tsx index 8b3a4b82..83ad1690 100644 --- a/frontend/src/pages/destructionlist/detail/DestructionListDetail.stories.tsx +++ b/frontend/src/pages/destructionlist/detail/DestructionListDetail.stories.tsx @@ -6,9 +6,7 @@ import { ReactRouterDecorator } from "../../../../.storybook/decorators"; import { assertColumnSelection, clickButton, - clickElement, fillButtonConfirmationForm, - fillCheckboxConfirmationForm, fillForm, } from "../../../../.storybook/playFunctions"; import { auditLogFactory } from "../../../fixtures/auditLog"; @@ -25,7 +23,7 @@ import { FIXTURE_SELECTIELIJSTKLASSE_CHOICES_MAP, selectieLijstKlasseFactory, } from "../../../fixtures/selectieLijstKlasseChoices"; -import { usersFactory } from "../../../fixtures/user"; +import { userFactory, usersFactory } from "../../../fixtures/user"; import { clearZaakSelection, getZaakSelection, @@ -83,6 +81,12 @@ const meta: Meta = { status: 200, response: FIXTURE_SELECTIELIJSTKLASSE_CHOICES, }, + { + url: "http://localhost:8000/api/v1/whoami/?", + method: "GET", + status: 200, + response: userFactory(), + }, ], }, }; @@ -240,10 +244,11 @@ export const ProcessReview: Story = { }, }, play: async (context) => { - await fillCheckboxConfirmationForm({ + await fillButtonConfirmationForm({ ...context, parameters: { elementIndex: 0, + name: "Muteren", formValues: { "Aanpassen van selectielijstklasse": true, Selectielijstklasse: selectieLijstKlasseFactory()[0].label, @@ -252,10 +257,11 @@ export const ProcessReview: Story = { }, }); - await fillCheckboxConfirmationForm({ + await fillButtonConfirmationForm({ ...context, parameters: { elementIndex: 1, + name: "Muteren", formValues: { "Aanpassen van selectielijstklasse": true, Selectielijstklasse: selectieLijstKlasseFactory()[1].label, @@ -264,10 +270,11 @@ export const ProcessReview: Story = { }, }); - await fillCheckboxConfirmationForm({ + await fillButtonConfirmationForm({ ...context, parameters: { elementIndex: 2, + name: "Muteren", formValues: { "Aanpassen van selectielijstklasse": true, Selectielijstklasse: selectieLijstKlasseFactory()[2].label, @@ -328,12 +335,10 @@ export const CheckSelectielijstklasseSelection: Story = { }, }, play: async (context) => { - await clickElement({ + await clickButton({ ...context, parameters: { - elementIndex: 0, - role: "checkbox", - checked: true, + name: "Muteren", }, }); diff --git a/frontend/src/pages/destructionlist/detail/DestructionListDetail.tsx b/frontend/src/pages/destructionlist/detail/DestructionListDetail.tsx index ef678618..6a0e0308 100644 --- a/frontend/src/pages/destructionlist/detail/DestructionListDetail.tsx +++ b/frontend/src/pages/destructionlist/detail/DestructionListDetail.tsx @@ -1,12 +1,9 @@ -import { CardBaseTemplate } from "@maykin-ui/admin-ui"; import React from "react"; import { useLoaderData } from "react-router-dom"; import { DestructionListDetailContext } from "./DestructionListDetail.loader"; import { DestructionListEdit } from "./components/DestructionListEdit/DestructionListEdit"; import { DestructionListProcessReview } from "./components/DestructionListProcessReview/DestructionListProcessReview"; -import { DestructionListToolbar } from "./components/DestructionListToolbar/DestructionListToolbar"; -import { useSecondaryNavigation } from "./hooks/useSecondaryNavigation"; /** * Destruction list detail page @@ -14,18 +11,11 @@ import { useSecondaryNavigation } from "./hooks/useSecondaryNavigation"; export function DestructionListDetailPage() { const { destructionList } = useLoaderData() as DestructionListDetailContext; const isInReview = destructionList.status === "changes_requested"; - const secondaryNavigationItems = useSecondaryNavigation(); - // TODO: SEPARATE ROUTE? + // TODO: SEPARATE ROUTES? if (!isInReview) { return ; + } else { + return ; } - - // FIXME: MIGRATE TO NEW APPROACH (NEW URL?) - return ( - - - - - ); } diff --git a/frontend/src/pages/destructionlist/detail/components/DestructionListProcessReview/DestructionListProcessReview.tsx b/frontend/src/pages/destructionlist/detail/components/DestructionListProcessReview/DestructionListProcessReview.tsx index 81b72a31..fcd93094 100644 --- a/frontend/src/pages/destructionlist/detail/components/DestructionListProcessReview/DestructionListProcessReview.tsx +++ b/frontend/src/pages/destructionlist/detail/components/DestructionListProcessReview/DestructionListProcessReview.tsx @@ -1,77 +1,164 @@ -import { - AttributeData, - AttributeTable, - DataGrid, - Outline, -} from "@maykin-ui/admin-ui"; -import React, { useState } from "react"; -import { useLoaderData, useNavigation, useRevalidator } from "react-router-dom"; -import { useAsync } from "react-use"; +import { ButtonProps, Outline, Toolbar, TypedField } from "@maykin-ui/admin-ui"; +import React, { useMemo, useState } from "react"; +import { useLoaderData, useRevalidator } from "react-router-dom"; +import { PaginatedDestructionListItems } from "../../../../../lib/api/destructionListsItem"; +import { PaginatedZaken } from "../../../../../lib/api/zaken"; import { ZaakSelection, addToZaakSelection, removeFromZaakSelection, } from "../../../../../lib/zaakSelection/zaakSelection"; import { Zaak } from "../../../../../types"; -import { DataGridAction, useDataGridProps } from "../../../hooks"; +import { BaseListView } from "../../../abstract"; +import { useZaakReviewStatuses } from "../../../hooks"; import { DestructionListDetailContext } from "../../DestructionListDetail.loader"; -import { DestructionListProcessZaakReviewModal } from "../index"; +import { useSecondaryNavigation } from "../../hooks/useSecondaryNavigation"; +import { + DestructionListProcessZaakReviewModal, + ProcessReviewAction, +} from "../DestructionListProcessZaakReviewModal"; -/** - * The interface for the zaken modal state - */ -interface ZaakModalDataState { +type ZaakModalDataState = { open: boolean; zaak?: Zaak; -} +}; -const LABEL_CHANGE_SELECTION_LIST_CLASS = "Aanpassen van selectielijstklasse"; -const LABEL_POSTPONE_DESTRUCTION = "Verlengen bewaartermijn"; -const LABEL_KEEP = "Afwijzen van het voorstel"; - -interface ProcessZaakReviewSelectionDetail { +type ProcessZaakReviewSelectionDetail = { comment: string; action: ProcessReviewAction; selectielijstklasse: string; archiefactiedatum: string; -} - -export type ProcessReviewAction = - | "change_selectielijstklasse" - | "change_archiefactiedatum" - | "keep"; +}; /** * Show items of a destruction list review. * Allows processing feedback of the destruction list. */ export function DestructionListProcessReview() { - const { state } = useNavigation(); - const { storageKey, + destructionList, destructionListItems, zaakSelection, review, reviewItems = [], selectieLijstKlasseChoicesMap, } = useLoaderData() as DestructionListDetailContext; + const zakenOnPage = reviewItems?.map((ri) => ri.zaak) || []; + + const [selectionClearedState, setSelectionClearedState] = useState(false); const revalidator = useRevalidator(); - const [ - processZaakReviewSelectionDetailState, - setProcessZaakReviewSelectionDetailState, - ] = useState(); + const secondaryNavigationItems = useSecondaryNavigation(); + const zaakReviewStatuses = useZaakReviewStatuses(storageKey, zakenOnPage); + + // State to manage the state of the zaak modal (when clicking a checkbox) + const [processZaakReviewModalState, setProcessZaakReviewModalState] = + useState({ + open: false, + }); + + // The zaak selection typed correctly for use when providing feedback on a review. + const processZaakReviewSelectionState = + zaakSelection as ZaakSelection; + + // The details possibly provided by the user after processing a review for a zaak. + const processZaakReviewDetail = + processZaakReviewSelectionState?.[ + processZaakReviewModalState.zaak?.url || "" + ]?.detail; + + // The initially select items. + const initiallySelectedZakenOnPage = useMemo( + () => + selectionClearedState + ? [] + : paginatedDestructionListItems2paginatedZaken(destructionListItems) + .results, + [selectionClearedState, destructionListItems], + ); + + /** + * Converts `PaginatedDestructionListItems` to `PaginatedZaken`. + */ + function paginatedDestructionListItems2paginatedZaken( + paginatedDestructionListItems: PaginatedDestructionListItems, + ): PaginatedZaken { + return { + ...paginatedDestructionListItems, + results: paginatedDestructionListItems.results + .map((dli) => ({ ...dli.zaak, processingStatus: dli.processingStatus })) + // @ts-expect-error - FIXME: Adding "processingStatus" to zaak. + .filter((v): v is Zaak => Boolean(v)) as Zaak[], + }; + } + + // Whether extra fields should be rendered. + const extraFields: TypedField[] = [ + { filterable: false, name: "Opmerking", type: "text" }, + { filterable: false, name: "Acties", type: "text" }, + ]; + + // The object list of the current page with review actions appended. + const objectList = useMemo(() => { + return zakenOnPage.map((z, i) => ({ + ...z, + Opmerking: reviewItems?.[i]?.feedback, + Acties: ( + + + Muteren + + ), + pad: "h", + variant: "primary", + wrap: false, + onClick: () => + handleProcessReviewZaakSelect( + z, + (z.url as string) in zaakReviewStatuses, + ), + }, + ]} + /> + ), + })); + }, [reviewItems, zaakReviewStatuses]); + + // DataGrid (paginated) results. + const paginatedZaken = useMemo(() => { + return { + count: reviewItems?.length || 0, + next: null, + previous: null, + results: objectList, + }; + }, [reviewItems, objectList]); + + // Selection actions based on `editingState`. + const selectionActions: ButtonProps[] = useMemo(() => [], []); + + /** + * Gets called when te selection is cleared. + */ + const handleClearSelection = async () => { + setSelectionClearedState(true); + }; /** * Get called when the user selects a zaak when a review is received. */ const handleProcessReviewZaakSelect = async ( - data: AttributeData[], + zaak: Zaak, selected: boolean, ) => { - const zaak = data[0] as unknown as Zaak; - // Remove from selection. // // Remove the zaak from the selection in the background. @@ -131,109 +218,19 @@ export function DestructionListProcessReview() { revalidator.revalidate(); }; - // State to manage the state of the zaak modal (when clicking a checkbox) - const [processZaakReviewModalState, setProcessZaakReviewModalState] = - useState({ - open: false, - }); - - // The zaak selection typed correctly for use when providing feedback on a review. - const processZaakReviewSelectionState = - zaakSelection as ZaakSelection; - - // The details possibly provided by the user after processing a review for a zaak. - const processZaakReviewDetail = - processZaakReviewSelectionState?.[ - processZaakReviewModalState.zaak?.url || "" - ]?.detail; - - const processZaakReviewZaakActions: DataGridAction[] = [ - { - children: , - title: "Muteren", - tooltip: - (processZaakReviewSelectionDetailState?.action === - "change_selectielijstklasse" && ( - - )) || - (processZaakReviewSelectionDetailState?.action === - "change_archiefactiedatum" && ( - - )) || - (processZaakReviewSelectionDetailState?.action === "keep" && ( - - )), - onInteract: (_, detail) => { - setProcessZaakReviewSelectionDetailState( - detail as ProcessZaakReviewSelectionDetail, - ); - }, - onClick: (zaak) => { - handleProcessReviewZaakSelect( - [zaak] as unknown as AttributeData[], - true, - ); - }, - }, - ]; - - // - // RENDERING - // - - // Get the base props for the DataGrid component. - const { props: dataGridProps } = useDataGridProps( - storageKey, - { - count: reviewItems?.length || 0, - next: null, - previous: null, - results: reviewItems?.map((ri) => ri.zaak) || [], - }, - Object.entries(zaakSelection) - .filter(([, { selected }]) => selected) - .map(([url]) => url), - undefined, - processZaakReviewZaakActions, - undefined, - review?.pk, - ); - - // Update the selected zaken to session storage. - useAsync(async () => { - await addToZaakSelection( - storageKey, - destructionListItems.results - .map((di) => di.zaak) - .filter((v): v is Zaak => Boolean(v)), - ); - }, []); - return ( - <> + {/* The "feedback" modal */} - - {/* DataGrid */} - - + ); } diff --git a/frontend/src/pages/destructionlist/detail/components/DestructionListProcessZaakReviewModal/DestructionListProcessZaakReviewModal.tsx b/frontend/src/pages/destructionlist/detail/components/DestructionListProcessZaakReviewModal/DestructionListProcessZaakReviewModal.tsx index 55a2b8b1..ca633b3c 100644 --- a/frontend/src/pages/destructionlist/detail/components/DestructionListProcessZaakReviewModal/DestructionListProcessZaakReviewModal.tsx +++ b/frontend/src/pages/destructionlist/detail/components/DestructionListProcessZaakReviewModal/DestructionListProcessZaakReviewModal.tsx @@ -19,7 +19,6 @@ import React, { FormEvent, useEffect, useState } from "react"; import { ReviewItem } from "../../../../../lib/api/review"; import { addDuration, formatDate } from "../../../../../lib/format/date"; import { Zaak } from "../../../../../types"; -import { ProcessReviewAction } from "../DestructionListProcessReview/DestructionListProcessReview"; export const LABEL_CHANGE_SELECTION_LIST_CLASS = "Aanpassen van selectielijstklasse"; @@ -47,6 +46,11 @@ export type DestructionListProcessZaakReviewModalProps = { ) => void; }; +export type ProcessReviewAction = + | "change_selectielijstklasse" + | "change_archiefactiedatum" + | "keep"; + type ProcessZaakFormState = { zaakUrl: string; action: ProcessReviewAction | ""; diff --git a/frontend/src/pages/destructionlist/hooks/index.ts b/frontend/src/pages/destructionlist/hooks/index.ts index aa155771..71ddf39b 100644 --- a/frontend/src/pages/destructionlist/hooks/index.ts +++ b/frontend/src/pages/destructionlist/hooks/index.ts @@ -1,9 +1,10 @@ export * from "./useCombinedSearchParams"; -export * from "./useDataGridProps"; export * from "./useFields"; export * from "./useFilter"; export * from "./usePage"; export * from "./useSelectielijstKlasseChoices"; export * from "./useSort"; +export * from "./useZaakReviewStatusBadges"; +export * from "./useZaakReviewStatuses"; export * from "./useZaakSelection"; export * from "./useZaaktypeChoices"; diff --git a/frontend/src/pages/destructionlist/hooks/useDataGridProps.tsx b/frontend/src/pages/destructionlist/hooks/useDataGridProps.tsx deleted file mode 100644 index cf56879c..00000000 --- a/frontend/src/pages/destructionlist/hooks/useDataGridProps.tsx +++ /dev/null @@ -1,568 +0,0 @@ -import { - AttributeData, - Button, - ButtonProps, - DataGridProps, - Option, - Solid, - Tooltip, - TypedField, - formatMessage, -} from "@maykin-ui/admin-ui"; -import { ReactNode, useEffect, useMemo, useRef, useState } from "react"; -import { - useNavigation, - useRevalidator, - useSearchParams, -} from "react-router-dom"; - -import { ProcessingStatusBadge } from "../../../components/ProcessingStatusBadge"; -import { DestructionList } from "../../../lib/api/destructionLists"; -import { - DestructionListItem, - PaginatedDestructionListItems, - ZaakItem, -} from "../../../lib/api/destructionListsItem"; -import { - ZaaktypeChoice, - listSelectielijstKlasseChoices, - listZaaktypeChoices, -} from "../../../lib/api/private"; -import { Review } from "../../../lib/api/review"; -import { PaginatedZaken } from "../../../lib/api/zaken"; -import { - FieldSelection, - addToFieldSelection, - getFieldSelection, - removeFromFieldSelection, -} from "../../../lib/fieldSelection/fieldSelection"; -import { formatDate } from "../../../lib/format/date"; -import { - addToZaakSelection, - clearZaakSelection, - getZaakSelection, - removeFromZaakSelection, - setAllZakenSelected, -} from "../../../lib/zaakSelection/zaakSelection"; -import { ExpandZaak, Zaak } from "../../../types"; -import { FIELD_SELECTION_STORAGE_KEY } from "../../constants"; - -/** The template used to format urls to an external application providing zaak details. */ -const REACT_APP_ZAAK_URL_TEMPLATE = process.env.REACT_APP_ZAAK_URL_TEMPLATE; - -export interface DataGridAction extends Omit { - title: string; - tooltip?: ReactNode; - onInteract?: (zaak: Zaak, detail?: unknown) => void; - onClick?: (zaak: Zaak, detail?: unknown) => void; -} - -/** - * @deprecated use and or various other hooks. - */ -export function useDataGridProps( - storageKey: string, - paginatedResults: PaginatedDestructionListItems | PaginatedZaken, - selectedUrls: string[], - allZakenSelected?: boolean, - actions?: DataGridAction[], - destructionListUuid?: DestructionList["uuid"], - reviewPk?: Review["pk"], - onClearSelection?: () => void | Promise, -): { props: DataGridProps; error: unknown } { - if (process.env.NODE_ENV === "development") { - console.warn( - "useDataGridProps is deprecated, use and or various other hooks.", - ); - } - - const { state } = useNavigation(); - const revalidator = useRevalidator(); - const [searchParams, setSearchParams] = useSearchParams(); - const [errorState, setErrorState] = useState(); - - // - // List available zaaktype choices. - // - const [zaaktypeChoicesState, setZaaktypeChoicesState] = useState< - ZaaktypeChoice[] - >([]); - const [selectieLijstKlasseChoicesState, setSelectieLijstKlasseChoicesState] = - useState([]); - - useEffect(() => { - const fetchChoices = async () => { - try { - const [selectieLijstKlasseChoices, zaaktypeChoices] = await Promise.all( - [ - // TODO (possibly): This curreently isn't performant. It's returning 600+ results, of which we most likely only need a few per page - listSelectielijstKlasseChoices(), - listZaaktypeChoices(destructionListUuid, reviewPk), - ], - ); - - setSelectieLijstKlasseChoicesState(selectieLijstKlasseChoices); - setZaaktypeChoicesState(zaaktypeChoices); - } catch (error) { - setErrorState(error); - } - }; - fetchChoices(); - }, []); - - /** - * Renders a special set of action buttons as column data for `zaak`. - * @param zaak - * @param actions - */ - const renderActionButtons = (zaak: Zaak, actions?: DataGridAction[]) => { - return actions?.map( - ({ onClick, onInteract, tooltip, ...action }, index) => { - const handleAction = async ( - zaak: Zaak, - actionFn?: (zaak: Zaak, detail?: unknown) => void, - ) => { - const foundZaak = await getSpecificZaakSelection(zaak.url as string); - actionFn?.(zaak, foundZaak); - }; - - const ButtonComponent = ( -