From e2adb7d1ed2e201b7e4c5e7a7ac52078bd6fe84f Mon Sep 17 00:00:00 2001 From: Nathan Vasse Date: Wed, 21 Aug 2024 16:20:10 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(react)=20make=20optional=20DataGrid?= =?UTF-8?q?=20row=20selection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using the selection feature on another project we realized that we needed to make some row non selectable at all by hiding the checkbox completely. --- .changeset/wise-coins-tan.md | 5 ++ .../DataGrid/SimpleDataGrid.spec.tsx | 65 ++++++++++++++++++- .../react/src/components/DataGrid/index.mdx | 4 ++ .../src/components/DataGrid/index.stories.tsx | 41 ++++++++++++ .../react/src/components/DataGrid/utils.tsx | 23 ++++--- 5 files changed, 128 insertions(+), 10 deletions(-) create mode 100644 .changeset/wise-coins-tan.md diff --git a/.changeset/wise-coins-tan.md b/.changeset/wise-coins-tan.md new file mode 100644 index 000000000..8a439fa73 --- /dev/null +++ b/.changeset/wise-coins-tan.md @@ -0,0 +1,5 @@ +--- +"@openfun/cunningham-react": minor +--- + +make optional DataGrid row selection diff --git a/packages/react/src/components/DataGrid/SimpleDataGrid.spec.tsx b/packages/react/src/components/DataGrid/SimpleDataGrid.spec.tsx index 4b2a55b6e..70765ef02 100644 --- a/packages/react/src/components/DataGrid/SimpleDataGrid.spec.tsx +++ b/packages/react/src/components/DataGrid/SimpleDataGrid.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen, waitFor } from "@testing-library/react"; +import { queryByRole, render, screen, waitFor } from "@testing-library/react"; import React, { useState } from "react"; import { faker } from "@faker-js/faker"; import { getAllByRole, getByRole, within } from "@testing-library/dom"; @@ -267,6 +267,69 @@ describe("", () => { expect(lastRowSelection[rowsToSelect[1].id]).toBe(true); }); }); + it.only("should not render selection checkboxes for unselectable rows", async () => { + const rows = Array.from(Array(2)) + .map(() => ({ + id: faker.string.uuid(), + firstName: faker.person.firstName(), + lastName: faker.person.lastName(), + email: faker.internet.email(), + address: faker.location.streetAddress(), + })) + .sort((a, b) => a.firstName.localeCompare(b.firstName)); + rows[0].email = "admin@example.com"; + + const Wrapper = () => { + const [rowSelection, setRowSelection] = useState({}); + lastRowSelection = rowSelection; + return ( + + + row.original.email !== "admin@example.com" + } + rowSelection={rowSelection} + onRowSelectionChange={setRowSelection} + /> + + ); + }; + + render(); + + // Check first row. + let element = screen.getByTestId(rows[0].id); + expect(queryByRole(element, "checkbox")).not.toBeInTheDocument(); + + // Check second row. + element = screen.getByTestId(rows[1].id); + expect(getByRole(element, "checkbox")).toBeInTheDocument(); + }); it("should render a grid with working sortable columns", async () => { const rows = Array.from(Array(23)) .map(() => ({ diff --git a/packages/react/src/components/DataGrid/index.mdx b/packages/react/src/components/DataGrid/index.mdx index 4f8f3bbd6..c62dcfc79 100644 --- a/packages/react/src/components/DataGrid/index.mdx +++ b/packages/react/src/components/DataGrid/index.mdx @@ -70,6 +70,10 @@ below the table. +You can also make a row non selectable by setting using `enableRowSelection` as a callback function that returns a boolean based on a condition. + + + As you can see, with `SimpleDataGrid` you can easily add pagination, sorting without have to worry about controlling their states. diff --git a/packages/react/src/components/DataGrid/index.stories.tsx b/packages/react/src/components/DataGrid/index.stories.tsx index bfe81daed..365223d08 100644 --- a/packages/react/src/components/DataGrid/index.stories.tsx +++ b/packages/react/src/components/DataGrid/index.stories.tsx @@ -167,6 +167,47 @@ export const ClientSideWithPagination = () => { ); }; +export const RowSelectionOptional = () => { + const [rowSelection, setRowSelection] = useState({}); + + return ( + <> + row.original.year < 2024} + rowSelection={rowSelection} + onRowSelectionChange={setRowSelection} + /> +
Selected rows: {Object.keys(rowSelection).join(", ")}
+ + ); +}; + export const FullServerSide = () => { const database = useMemo(() => [...databaseUsersServer], []); const [rowSelection, setRowSelection] = useState({}); diff --git a/packages/react/src/components/DataGrid/utils.tsx b/packages/react/src/components/DataGrid/utils.tsx index c48070b75..ed3f7d634 100644 --- a/packages/react/src/components/DataGrid/utils.tsx +++ b/packages/react/src/components/DataGrid/utils.tsx @@ -52,15 +52,20 @@ export const useHeadlessColumns = ({ id: HEADER_ID_SELECT, size: 34, header: () => null, - cell: ({ row }) => ( - - ), + cell: ({ row }) => { + if (!row.getCanSelect()) { + return null; + } + return ( + + ); + }, }), ...headlessColumns, ];