22.2.4 • Published 8 months ago

@linzjs/step-ag-grid v22.2.4

Weekly downloads
-
License
MIT
Repository
github
Last release
8 months ago

step-ag-grid

semantic-release: angular

Reusable ag-grid component for LINZ / Toitū te whenua.

Features

  • ag-grid-community based grid with custom popover components implemented using a modified react-menu.
  • Default components
    • Text input
    • Text area
    • Drop-down
    • Multi-select
    • Multi-select-grid
    • Bearing/Bearing Correction
    • Popover message
    • Custom form
    • Context menu

Please note this requires React >=17, ag-grid-community >=28, and SASS.

Install

with npm

npm install @linzjs/step-ag-grid

or with Yarn

yarn add @linzjs/step-ag-grid

Demo

npm run storybook

Storybook demo deployed at: https://master--633cd0dc2fe91d7df3ed32e4.chromatic.com/

Usage

Check src\stories for more usage examples

import { useMemo } from "react";

import "@linzjs/lui/dist/fonts";
import "@linzjs/lui/dist/scss/base.scss";
import {
  ColDefT,
  GridCell,
  GridCellFiller,
  GridContextProvider,
  GridContextMenuComponentProps,
  GridPopoverEditDropDown,
  GridPopoverMessage,
  GridUpdatingContextProvider,
  GridWrapper,
  GridFilters,
  GridFilterQuick,
  GridFilterButtons
} from "@linzjs/step-ag-grid";
// Only required for LINZ themes otherwise import the default theme from ag-grid
import "@linzjs/step-ag-grid/dist/GridTheme.scss";
import "@linzjs/step-ag-grid/dist/index.css";
import { GridFilterDownloadCsvButton } from "./GridFilterDownloadCsvButton";

const GridDemo = () => {
  interface ITestRow {
    id: number;
    name: number;
    position: string;
  }

  const columnDefs: ColDefT<ITestRow>[] = useMemo(
    () => [
      GridCell({
        field: "id",
        headerName: "Id",
        export: false,
      }),
      // This is the flex column that will expand to fit
      GridCell<ITestRow, string>({
        field: "name",
        headerName: "Name",
        flex: 1,
        cellRendererParams: {
          warning: ({ value }) => value === "Tester" && "Testers are testing",
          info: ({ value }) => value === "Developer" && "Developers are awesome",
        },
      }),
      GridPopoverEditDropDown(
        {
          field: "position",
          headerName: "Position",
        },
        {
          multiEdit: false,
          editorParams: {
            options: ["Architect", "Developer", "Product Owner", "Scrum Master", "Tester", MenuSeparator, "(other)"],
          },
        },
      ),
      GridPopoverMessage(
        {
          headerName: "Popout message",
          cellRenderer: () => <>Click me!</>,
        },
        {
          multiEdit: true,
          editorParams: {
            message: async ({selectedRows}) => {
              return `There are ${selectedRows.length} row(s) selected`;
            },
          },
        },
      ),
      // If your flex column gets hidden this will become active
      GridCellFiller(),
    ],
    [],
  );

  const ContextMenu = ({ selectedRows, colDef, close }: GridContextMenuComponentProps<ITestRow>): ReactElement => {
    const onClick = useCallback(() => {
      selectedRows.forEach((row) => {
        switch (colDef.field) {
          case "name":
            row.name = "";
            break;
          case "distance":
            row.distance = null;
            break;
        }
      });
      close();
    }, [close, colDef.field, selectedRows]);

    return (
      <>
        <button onClick={onClick}>Button - Clear cell</button>
        <MenuItem onClick={onClick}>Menu Item - Clear cell</MenuItem>
      </>
    );
  };
  
  const rowData: ITestRow[] = useMemo(
    () => [
      { id: 1000, name: "Tom", position: "Tester" },
      { id: 1001, name: "Sue", position: "Developer" },
    ],
    [],
  );

  return (
    <GridUpdatingContextProvider>
      <GridContextProvider>
        <GridWrapper>
          <GridFilters>
            <GridFilterQuick/>
            <GridFilterButtons<ITestRow>
              options={[
                {
                  label: "All",
                },
                {
                  label: "Developers",
                  filter: (row) => row.position === "Developer",
                },
                {
                  label: "Testers",
                  filter: (row) => row.position === "Tester",
                },
              ]}
            />
            <GridFilterColumnsToggle/>
            <GridFilterDownloadCsvButton fileName={"exportFile"}/>
          </GridFilters>
          <Grid selectable={true}
                columnDefs={columnDefs}
                rowData={rowData}
                contextMenu={contextMenu}
                contextMenuSelectRow={false}
                onContentSize={({ width }) => setPanelSize(width)} />
        </GridWrapper>
      </GridContextProvider>
    </GridUpdatingContextProvider>
  );
};

Bulk editing

If you are editing a cell and tab out of the cell, the grid will edit the next editable cell.

At this point you can send the change to the back-end immediately and then wait for an update response OR you could cache the required change, update then cell locally, and then wait for the callback <Grid onCellEditingComplete={fn}/> which will get invoked when the grid cannot find any more editable cells on the grid row, which will speed up editing.

Grid sizing

Grid uses <Grid sizeColumns="auto"/> which sizes by cell content by default. To ignore cell content use "fit", to disable use "none".

If you are within a resizable window/dialog/container there is a callback parameter <Grid onContentSize={({ width }) => setPanelSize(width)}/> to receive the recommended container width.

CSV Download

CSV download relies on column valueFormatters vs ag-grid's default valueGetter implementation. If you use a customRenderer for a column be sure to include a valueFormatter. To disable this behaviour pass undefined to processCellCallback. <GridFilterDownloadCsvButton processCellCallback={undefined}/>

To exclude a column from CSV download add export: false to the GridCell definition.

Writing tests

The following testing calls can be imported from step-ag-grid:

  • findRow
  • queryRow
  • selectRow
  • deselectRow
  • findCell
  • selectCell
  • editCell
  • findOpenMenu
  • validateMenuOptions
  • queryMenuOption
  • findMenuOption
  • clickMenuOption
  • openAndClickMenuOption
  • getMultiSelectOptions
  • findMultiSelectOption
  • clickMultiSelectOption
  • typeOnlyInput
  • typeInputByLabel
  • typeInputByPlaceholder
  • typeOtherInput
  • typeOtherTextArea
  • closeMenu
  • findActionButton
  • clickActionButton
import { render, screen } from "@testing-library/react";
import { waitFor } from "@testing-library/react";
import { findRow, GridUpdatingContextProvider, openAndClickMenuOption } from "@linzjs/step-ag-grid";

const TestComponent = (): JSX.Element => {
  return (
    <GridUpdatingContextProvider>
      <MyGrid />
    </GridUpdatingContextProvider>
  );
};

test("click Delete menu option removes row from the table", async () => {
  await render(<TestComponent />);
  await screen.findByText("My component header");
  expect((await findRow(12345)).getAttribute("row-index")).toBe("1");
  await openAndClickMenuOption(12345, "actions", "Delete");
  await waitFor(async () => expect((await queryRow(12345)).not.toBeDefined()));
});

Playwright support

If your grid has a data-testid a global will be exposed in window with the helper scrollRowIntoViewById. This will throw an exception if the row id is not found.

window.__stepAgGrid.grids[dataTestId].scrollRowIntoViewById("1000")
22.2.4

8 months ago

22.2.3

8 months ago

22.2.1

9 months ago

22.2.0

9 months ago

22.2.2

9 months ago

22.1.1

9 months ago

22.1.0

9 months ago

22.0.1

10 months ago

22.0.0

10 months ago

21.3.0

10 months ago

21.0.2

1 year ago

21.0.4

1 year ago

21.0.3

1 year ago

21.1.1

1 year ago

21.1.0

1 year ago

21.1.3

1 year ago

21.1.2

1 year ago

21.1.4

1 year ago

21.2.0

12 months ago

21.2.1

12 months ago

21.0.1

1 year ago

21.0.0

1 year ago

20.0.0

1 year ago

19.1.1

1 year ago

19.1.0

1 year ago

19.0.0

1 year ago

18.1.0

1 year ago

18.0.0

2 years ago

14.9.4

2 years ago

14.9.3

2 years ago

14.9.2

2 years ago

14.9.1

2 years ago

17.3.0

2 years ago

15.0.2

2 years ago

15.0.0

2 years ago

15.0.1

2 years ago

17.4.1

2 years ago

17.4.0

2 years ago

17.4.7

2 years ago

17.4.6

2 years ago

17.4.9

2 years ago

17.4.8

2 years ago

17.4.3

2 years ago

17.4.2

2 years ago

17.4.5

2 years ago

17.4.4

2 years ago

17.1.0

2 years ago

17.9.0

2 years ago

17.2.0

2 years ago

17.12.0

2 years ago

17.7.0

2 years ago

17.13.0

2 years ago

17.0.3

2 years ago

17.0.2

2 years ago

17.0.5

2 years ago

17.0.4

2 years ago

17.0.1

2 years ago

17.0.0

2 years ago

17.0.7

2 years ago

17.0.6

2 years ago

17.8.0

2 years ago

15.1.1

2 years ago

15.1.2

2 years ago

15.1.0

2 years ago

15.1.3

2 years ago

17.4.10

2 years ago

17.10.0

2 years ago

14.10.0

2 years ago

17.5.0

2 years ago

17.5.2

2 years ago

17.5.1

2 years ago

17.5.3

2 years ago

17.11.0

2 years ago

17.6.1

2 years ago

17.6.0

2 years ago

16.0.0

2 years ago

14.9.0

2 years ago

14.7.1

2 years ago

14.8.0

2 years ago

13.3.2

2 years ago

14.1.0

2 years ago

14.1.1

2 years ago

14.1.2

2 years ago

14.5.0

2 years ago

14.5.1

2 years ago

13.4.0

2 years ago

14.2.0

2 years ago

14.6.0

2 years ago

13.5.1

2 years ago

13.5.0

2 years ago

14.3.0

2 years ago

14.3.1

2 years ago

14.3.2

2 years ago

14.3.3

2 years ago

14.7.0

2 years ago

14.0.0

2 years ago

14.0.1

2 years ago

14.0.2

2 years ago

14.0.3

2 years ago

14.4.0

2 years ago

13.3.1

2 years ago

13.3.0

2 years ago

13.0.0

2 years ago

13.1.3

2 years ago

13.1.1

2 years ago

13.1.2

2 years ago

13.1.0

2 years ago

13.2.0

2 years ago

12.1.2

2 years ago

10.0.0

2 years ago

10.0.1

2 years ago

10.0.2

2 years ago

12.0.0

2 years ago

12.0.1

2 years ago

9.0.0

2 years ago

8.4.1

2 years ago

8.4.0

2 years ago

8.4.3

2 years ago

8.4.2

2 years ago

11.0.0

2 years ago

12.1.0

2 years ago

12.1.1

2 years ago

7.18.0

2 years ago

6.1.0

3 years ago

6.1.1

3 years ago

2.4.1

3 years ago

2.4.0

3 years ago

2.4.3

3 years ago

8.2.2

2 years ago

2.4.2

3 years ago

2.4.5

3 years ago

2.4.4

3 years ago

7.3.1

3 years ago

7.3.0

3 years ago

7.8.0

3 years ago

7.8.1

3 years ago

8.1.0

2 years ago

4.0.1

3 years ago

4.0.0

3 years ago

4.0.3

3 years ago

4.0.2

3 years ago

7.17.0

2 years ago

7.13.1

3 years ago

7.13.0

3 years ago

5.0.1

3 years ago

7.17.1

2 years ago

5.0.0

3 years ago

2.3.0

3 years ago

2.3.1

3 years ago

8.3.2

2 years ago

8.3.1

2 years ago

7.0.0

3 years ago

2.4.10

3 years ago

2.4.11

3 years ago

7.4.0

3 years ago

7.0.4

3 years ago

7.0.3

3 years ago

7.0.2

3 years ago

7.0.1

3 years ago

7.5.2

3 years ago

7.5.1

3 years ago

7.5.0

3 years ago

7.9.0

3 years ago

2.4.7

3 years ago

2.4.6

3 years ago

8.2.1

2 years ago

2.4.9

3 years ago

8.2.0

2 years ago

2.4.8

3 years ago

7.11.10

3 years ago

7.11.11

3 years ago

7.16.0

2 years ago

7.11.12

3 years ago

7.16.1

2 years ago

7.11.13

3 years ago

7.12.0

3 years ago

7.16.6

2 years ago

7.16.4

2 years ago

7.16.5

2 years ago

7.16.2

2 years ago

7.16.3

2 years ago

2.2.1

3 years ago

2.2.0

3 years ago

2.2.2

3 years ago

7.1.1

3 years ago

7.1.0

3 years ago

7.6.2

3 years ago

7.6.1

3 years ago

7.6.0

3 years ago

3.0.2

3 years ago

3.0.1

3 years ago

8.3.0

2 years ago

3.0.0

3 years ago

7.11.5

3 years ago

7.11.6

3 years ago

7.11.3

3 years ago

7.15.0

2 years ago

7.11.4

3 years ago

7.11.1

3 years ago

7.11.2

3 years ago

7.11.0

3 years ago

7.19.5

2 years ago

7.19.6

2 years ago

7.19.3

2 years ago

7.19.4

2 years ago

7.19.1

2 years ago

7.11.9

3 years ago

7.19.2

2 years ago

7.11.7

3 years ago

7.19.0

2 years ago

7.11.8

3 years ago

6.0.0

3 years ago

2.5.0

3 years ago

2.1.3

3 years ago

7.2.0

3 years ago

7.7.0

3 years ago

7.3.2

3 years ago

8.0.0

2 years ago

7.14.0

3 years ago

7.10.2

3 years ago

7.10.0

3 years ago

7.10.1

3 years ago

2.1.2

3 years ago

2.1.1

3 years ago

2.1.0

3 years ago

2.0.1

3 years ago

2.0.0

3 years ago

1.5.4

3 years ago

1.5.3

3 years ago

1.5.2

3 years ago

1.5.1

3 years ago

1.5.0

3 years ago

1.4.10

3 years ago

1.4.9

3 years ago

1.4.8

3 years ago

1.4.7

3 years ago

1.4.6

3 years ago

1.4.5

3 years ago

1.4.4

3 years ago

1.4.2

3 years ago

1.4.1

3 years ago

1.4.0

3 years ago

1.3.0

3 years ago

1.2.0

3 years ago

1.1.1

3 years ago