Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⬆️ - chore: update @maykin-ui/admin-ui (and migrate code acco… #538

Merged
merged 5 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ async def test_scenario_record_manager_creates_list_with_select_all(self):
await self.when.user_clicks_button(page, "Vernietigingslijst opstellen")
await self.then.path_should_be(page, "/destruction-lists/create")

await self.when.user_clicks_checkbox(page, "(de)selecteer 200 pagina's", index=0)
await self.when.user_clicks_checkbox(page, "(de)selecteer 2 pagina's", index=0)
await self.when.user_clicks_button(page, "Vernietigingslijst opstellen", index=1)
await self.when.user_fills_form_field(page, "Naam", "Destruction list select all")
await self.when.user_fills_form_field(page, "Reviewer", str(reviewer))
Expand Down Expand Up @@ -57,8 +57,9 @@ async def test_scenario_record_manager_creates_list_with_select_all_and_filters(
await self.then.path_should_be(page, "/destruction-lists/create")

await self.when.user_filters_zaken(page, "omschrijving", "Test 1")
await self.when.user_clicks_checkbox(page, "(de)selecteer 5 pagina's", index=0)
await self.then.page_should_contain_text(page, "(de)selecteer 5 rijen")

await self.when.user_clicks_checkbox(page, "(de)selecteer 1 pagina's", index=0)
await self.when.user_clicks_button(page, "Vernietigingslijst opstellen", index=1)
await self.when.user_fills_form_field(page, "Naam", "Destruction list select all with filters")
await self.when.user_fills_form_field(page, "Reviewer", str(reviewer))
Expand Down
24 changes: 12 additions & 12 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@maykin-ui/admin-ui": "^0.0.38",
"@maykin-ui/admin-ui": "^0.0.39",
"@storybook/test-runner": "^0.18.2",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/user-event": "^13.5.0",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ function App() {
/>
}
pad="v"
variant="transparent"
>
<Body>
<Card>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
Button,
FormField,
P,
SerializedFormData,
Solid,
useAlert,
useFormDialog,
Expand Down Expand Up @@ -34,6 +33,12 @@ export type DestructionListReviewerProps = {
destructionList: DestructionList;
};

export type DestructionListReviewerFormType = {
comment: string;
reviewer?: string;
coReviewer?: string[];
};

/**
* Allows viewing/assigning the reviewers of a destruction list.
* @param destructionList
Expand All @@ -45,7 +50,7 @@ export function DestructionListReviewer({
const { state } = useNavigation();
const revalidator = useRevalidator();
const alert = useAlert();
const formDialog = useFormDialog();
const formDialog = useFormDialog<DestructionListReviewerFormType>();
const coReviews = useCoReviews(destructionList);
const reviewers = useReviewers();
const coReviewers = useCoReviewers();
Expand All @@ -55,12 +60,8 @@ export function DestructionListReviewer({
/**
* Gets called when the change is confirmed.
*/
const handleSubmit = (data: SerializedFormData) => {
const { coReviewer, reviewer, comment } = data as {
comment: string;
reviewer?: string;
coReviewer?: string[];
};
const handleSubmit = (data: DestructionListReviewerFormType) => {
const { coReviewer, reviewer, comment } = data;

const promises: Promise<unknown>[] = [];

Expand Down Expand Up @@ -198,6 +199,7 @@ export function DestructionListReviewer({
{reviewer && (
<>
<AttributeTable
compact
labeledObject={{
reviewer: {
label: "Beoordelaar",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import {
Badge,
Body,
Column,
Form,
Grid,
H2,
Tab,
Tabs,
field2Title,
string2Title,
ucFirst,
} from "@maykin-ui/admin-ui";

Expand Down Expand Up @@ -47,6 +48,7 @@ export function DestructionListToolbar({
{destructionList && (
<Column span={3}>
<AttributeTable
compact
labeledObject={{
auteur: {
label: "Auteur",
Expand Down Expand Up @@ -90,6 +92,7 @@ export function DestructionListToolbar({
{review && (
<Column span={3}>
<AttributeTable
compact
object={{
"Laatste review door": review.author && formatUser(review.author),
Opmerking: review.listFeedback,
Expand All @@ -106,6 +109,7 @@ export function DestructionListToolbar({
{reviewResponse && (
<Column span={3}>
<AttributeTable
compact
object={{
"Laatst ingediend": formatDate(
new Date(String(reviewResponse.created)),
Expand All @@ -124,7 +128,7 @@ export function DestructionListToolbar({
<H2>{title}</H2>
) : (
destructionList && (
<H2>{field2Title(destructionList.name, { unHyphen: false })}</H2>
<H2>{string2Title(destructionList.name, { unHyphen: false })}</H2>
)
)}
{logItems?.length ? (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Badge, Outline, field2Title } from "@maykin-ui/admin-ui";
import { Badge, Outline, string2Title } from "@maykin-ui/admin-ui";
import React from "react";

import { ProcessingStatus } from "../../lib/api/processingStatus";
Expand Down Expand Up @@ -41,7 +41,7 @@ export const ProcessingStatusBadge: React.FC<ProcessingStatusBadgeProps> = ({
}
return `Wordt vernietigd ${timeAgo(plannedDestructionDate, { shortFormat: true })}`;
}
return field2Title(PROCESSING_STATUS_MAPPING[processingStatus], {
return string2Title(PROCESSING_STATUS_MAPPING[processingStatus], {
unHyphen: false,
});
};
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/hooks/useFields.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ describe("useFields Hook", () => {
it("should apply filter transformations correctly", async () => {
const { result } = renderHook(() => useFields());

waitFor(() => {
await waitFor(async () => {
const [, , filterTransform] = result.current;

const filterData = {
startdatum: "2023-01-01/2023-01-31",
einddatum: "2023-02-01/2023-02-28",
startdatum: [new Date("2023-01-01"), new Date("2023-01-31")],
einddatum: [new Date("2023-02-01"), new Date("2023-02-28")],
};

const transformedData = filterTransform(filterData);
Expand All @@ -109,11 +109,13 @@ describe("useFields Hook", () => {
});

it("should provide selectielijst klasse options to selectielijst klasse field", async () => {
const { result } = renderHook(() => useFields());
const { result } = await act(async () => renderHook(() => useFields()));

const [fields] = result.current;
const selectielijstKlasse = fields.find(
(f) => f.name === "selectielijstklasse",
);

expect(selectielijstKlasse?.options?.length).toBeTruthy();
expect(selectielijstKlasse?.options?.[0].value).toContain("https://");
});
Expand Down
69 changes: 46 additions & 23 deletions frontend/src/hooks/useFields.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AttributeData, TypedField } from "@maykin-ui/admin-ui";
import { TypedField, TypedSerializedFormData } from "@maykin-ui/admin-ui";
import { useCallback, useEffect, useState } from "react";
import { useSearchParams } from "react-router-dom";

Expand All @@ -16,17 +16,35 @@ import { ExpandZaak, Zaak } from "../types";
import { useSelectielijstKlasseChoices } from "./useSelectielijstKlasseChoices";
import { useZaaktypeChoices } from "./useZaaktypeChoices";

type FilterTransformReturnType<T> = Record<
| "startdatum__gte"
| "startdatum__lte"
| "einddatum__gte"
| "einddatum__lte"
| "archiefactiedatum__gte"
| "archiefactiedatum__lte",
string | null
> &
Partial<
Omit<
TypedSerializedFormData<keyof T & string>,
"startdatum" | "einddatum" | "archiefactiedatum"
>
>;

/**
* Hook resolving zaaktype choices, returns: `[TypedField[], Function]` tuple.
* Hook resolving the base fields for lists.
*/
export function useFields(
export function useFields<T extends Zaak = Zaak>(
destructionList?: DestructionList,
review?: Review,
extraFields?: TypedField[],
extraFields?: TypedField<T>[],
): [
TypedField[],
(fields: TypedField[]) => void,
(filterData: AttributeData) => AttributeData,
TypedField<T>[],
(fields: TypedField<T>[]) => void,
(
filterData: Partial<TypedSerializedFormData<keyof T & string>>,
) => FilterTransformReturnType<T>,
] {
const [fieldSelectionState, setFieldSelectionState] =
useState<FieldSelection>();
Expand All @@ -45,7 +63,7 @@ export function useFields(

// The raw, unfiltered configuration of the available base fields.
// NOTE: This get filtered by `getActiveFields()`.
const fields: TypedField[] = [
const fields: TypedField<T>[] = [
{
name: "identificatie",
filterLookup: "identificatie__icontains",
Expand Down Expand Up @@ -190,7 +208,8 @@ export function useFields(

const getActiveFields = useCallback(() => {
return fields.map((field) => {
const isActiveFromStorage = fieldSelectionState?.[field.name];
const isActiveFromStorage =
fieldSelectionState?.[field.name as keyof typeof fieldSelectionState];
const isActive =
typeof isActiveFromStorage === "undefined"
? field.active !== false
Expand All @@ -204,7 +223,7 @@ export function useFields(
* Pass this to `filterTransform` of a DataGrid component.
* @param fields
*/
const setFields = async (fields: TypedField[]) => {
const setFields = async (fields: TypedField<T>[]) => {
const activeFields = fields.filter((f) => f.active !== false);
const inActiveFields = fields.filter((f) => f.active === false);
await addToFieldSelection(FIELD_SELECTION_STORAGE_KEY, activeFields);
Expand All @@ -218,20 +237,24 @@ export function useFields(
* Pass this to `filterTransform` of a DataGrid component.
* @param filterData
*/
const filterTransform = (filterData: AttributeData) => {
const {
startdatum = "",
einddatum = "",
archiefactiedatum = "",
..._filterData
} = filterData;
const filterTransform = (
filterData: Partial<TypedSerializedFormData<keyof T & string>>,
): FilterTransformReturnType<T> => {
const { startdatum, einddatum, archiefactiedatum, ..._filterData } =
filterData;

const formatDateRange = (dates: Date[] | undefined) =>
dates ? dates.map((d) => formatDate(d, "iso")) : [null, null];

const [startdatum__gte = "", startdatum__lte = ""] =
String(startdatum).split("/");
const [einddatum__gte = "", einddatum__lte = ""] =
String(einddatum).split("/");
const [archiefactiedatum__gte = "", archiefactiedatum__lte = ""] =
String(archiefactiedatum).split("/");
const [startdatum__gte, startdatum__lte] = formatDateRange(
startdatum as Date[] | undefined,
);
const [einddatum__gte, einddatum__lte] = formatDateRange(
einddatum as Date[] | undefined,
);
const [archiefactiedatum__gte, archiefactiedatum__lte] = formatDateRange(
archiefactiedatum as Date[] | undefined,
);

return {
startdatum__gte,
Expand Down
11 changes: 6 additions & 5 deletions frontend/src/hooks/useFilter.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { AttributeData } from "@maykin-ui/admin-ui";

import { useCombinedSearchParams } from "./useCombinedSearchParams";

/**
* Hook providing filter interaction, returns: `[RESERVED, Function]` tuple.
*/
export function useFilter(): [object, (filterData: AttributeData) => void] {
export function useFilter<T extends object>(): [
object,
(filterData: T) => void,
] {
const [, setCombinedSearchParams] = useCombinedSearchParams();
// Reserved for possible future expansion (filter state)
const RESERVED = {};
Expand All @@ -15,9 +16,9 @@ export function useFilter(): [object, (filterData: AttributeData) => void] {
* Pass this to `onFilter` of a DataGrid component.
* @param filterData
*/
const setFilterField = (filterData: AttributeData) => {
const setFilterField = (filterData: T) => {
setCombinedSearchParams({
...(filterData as AttributeData<string>),
...filterData,
page: "1",
});
};
Expand Down
Loading
Loading