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

Generics and tests for DataView #2425

Merged
merged 28 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
070a744
test: flesh out DataView tests
jordankoschei-okta Oct 10, 2024
562a82c
test: removing vestigial expects
jordankoschei-okta Oct 10, 2024
dbbe101
test: remove testID selectors
jordankoschei-okta Oct 10, 2024
a67781f
Merge branch 'main' into jk-dataview-tests
jordankoschei-okta Oct 20, 2024
5307584
Merge branch 'main' into jk-dataview-tests
jordankoschei-okta Oct 25, 2024
35d1a28
fix: fix broken test
jordankoschei-okta Oct 25, 2024
c038d00
refactor: remove circular references
jordankoschei-okta Oct 25, 2024
ab44311
refactor: changing a11y roles
jordankoschei-okta Nov 1, 2024
97511a0
Merge branch 'main' into jk-dataview-tests
jordankoschei-okta Nov 1, 2024
9013090
test: refactor all the DataView tests
jordankoschei-okta Nov 4, 2024
6f3c279
refactor: replace "it" with "test"
jordankoschei-okta Nov 4, 2024
7c3b875
Merge branch 'main' into jk-dataview-tests
jordankoschei-okta Nov 13, 2024
24aaf81
fix: update one test
jordankoschei-okta Nov 13, 2024
7b1e533
refactor: update aria-controls on closed menus
jordankoschei-okta Nov 13, 2024
92fe969
Merge branch 'main' into jk-dataview-tests
jordankoschei-okta Nov 13, 2024
abe29fd
chore: adding generics to everything
jordankoschei-okta Nov 18, 2024
092e67d
refactor: remove generics that break consumers
jordankoschei-okta Nov 18, 2024
5a82cbb
Merge branch 'main' into jk-dataview-generics
jordankoschei-okta Nov 18, 2024
38e3ca6
Merge branch 'main' into jk-dataview-tests
jordankoschei-okta Nov 19, 2024
07c4efb
fix: add proper TValue generic to DataColumns
jordankoschei-okta Nov 19, 2024
6a41bf2
fix: add tabindex to tableBody
jordankoschei-okta Nov 19, 2024
05fdfe8
fix: fix broken ariaControls on datafilter menu
jordankoschei-okta Nov 20, 2024
8908f33
fix: update broken type
jordankoschei-okta Nov 20, 2024
65b6706
Merge branch 'jk-dataview-tests' into jk-dataview-generics-and-tests
jordankoschei-okta Nov 20, 2024
2dcf590
Merge branch 'jk-dataview-generics' into jk-dataview-generics-and-tests
jordankoschei-okta Nov 20, 2024
f8708f7
fix: update imports
jordankoschei-okta Nov 20, 2024
5ea515c
Merge branch 'main' into jk-dataview-generics-and-tests
jordankoschei-okta Nov 20, 2024
8f6cdaa
refactor: improve tests based on Kevin feedback
jordankoschei-okta Nov 21, 2024
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 @@ -20,15 +20,15 @@ import { MRT_RowData } from "material-react-table";
* @param newIndex - The new index to move the row to.
* @returns A new array of data with the row moved to the specified index.
*/
export const reorderDataRowsLocally = ({
export const reorderDataRowsLocally = <TData extends MRT_RowData>({
currentData,
rowId,
newRowIndex,
}: {
currentData: MRT_RowData[];
currentData: TData[];
rowId: string;
newRowIndex: number;
}): MRT_RowData[] => {
}): TData[] => {
const updatedData = [...currentData];
const rowIndex = updatedData.findIndex((row) => row.id === rowId);

Expand Down
39 changes: 16 additions & 23 deletions packages/odyssey-react-mui/src/DataTable/useRowReordering.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { reorderDataRowsLocally } from "./reorderDataRowsLocally";
import { useOdysseyDesignTokens } from "../OdysseyDesignTokensContext";
import { MRT_Row, MRT_RowData, MRT_TableInstance } from "material-react-table";

export const useRowReordering = ({
export const useRowReordering = <TData extends MRT_RowData>({
totalRows,
onReorderRows,
data,
Expand All @@ -28,12 +28,10 @@ export const useRowReordering = ({
}: {
totalRows: DataTableProps["totalRows"];
onReorderRows: DataTableProps["onReorderRows"];
data: MRT_RowData[];
setData: Dispatch<SetStateAction<MRT_RowData[]>>;
draggingRow?: MRT_Row<MRT_RowData> | null;
setDraggingRow: Dispatch<
SetStateAction<MRT_Row<MRT_RowData> | null | undefined>
>;
data: TData[];
setData: Dispatch<SetStateAction<TData[]>>;
draggingRow?: MRT_Row<TData> | null;
setDraggingRow: Dispatch<SetStateAction<MRT_Row<TData> | null | undefined>>;
resultsPerPage: number;
page: number;
}) => {
Expand Down Expand Up @@ -68,7 +66,6 @@ export const useRowReordering = ({
const dragHandleStyles = {
padding: odysseyDesignTokens.Spacing1,
borderRadius: odysseyDesignTokens.BorderRadiusMain,

"&:focus-visible": {
boxShadow: `0 0 0 2px ${odysseyDesignTokens.HueNeutralWhite}, 0 0 0 4px ${odysseyDesignTokens.PalettePrimaryMain}`,
outline: "2px solid transparent",
Expand Down Expand Up @@ -106,12 +103,12 @@ export const useRowReordering = ({
return undefined;
};

const setHoveredRow = (
table: MRT_TableInstance<MRT_RowData>,
id: MRT_RowData["id"],
) => {
const setHoveredRow = (table: MRT_TableInstance<TData>, id: TData["id"]) => {
if (id) {
const nextRow: MRT_RowData = table.getRow(id);
// The `as MRT_Row<TData>` is necessary here to overcome some type/generic
// issues with the type of `setHoveredRow` defined by MRT. It's not ideal code,
// but it's the only way that works without a much larger rewrite.
const nextRow = table.getRow(id) as MRT_Row<TData>;

if (nextRow) {
table.setHoveredRow(nextRow);
Expand All @@ -120,8 +117,8 @@ export const useRowReordering = ({
};

type HandleDragHandleKeyDownArgs = {
table: MRT_TableInstance<MRT_RowData>;
row: MRT_Row<MRT_RowData>;
table: MRT_TableInstance<TData>;
row: MRT_Row<TData>;
event: KeyboardEvent<HTMLButtonElement>;
};

Expand Down Expand Up @@ -192,32 +189,28 @@ export const useRowReordering = ({
}
};

const handleDragHandleOnDragEnd = (table: MRT_TableInstance<MRT_RowData>) => {
const handleDragHandleOnDragEnd = (table: MRT_TableInstance<TData>) => {
const cols = table.getAllColumns();
cols[0].toggleVisibility();

const { draggingRow, hoveredRow } = table.getState();
if (draggingRow) {
updateRowOrder({
rowId: draggingRow.id,
newRowIndex: (hoveredRow as MRT_RowData).index,
newRowIndex: (hoveredRow as TData).index,
});
}

setDraggingRow(null);
};

const handleDragHandleOnDragCapture = (
table: MRT_TableInstance<MRT_RowData>,
) => {
const handleDragHandleOnDragCapture = (table: MRT_TableInstance<TData>) => {
if (!draggingRow && table.getState().draggingRow?.id) {
setDraggingRow(table.getState().draggingRow);
}
};

const resetDraggingAndHoveredRow = (
table: MRT_TableInstance<MRT_RowData>,
) => {
const resetDraggingAndHoveredRow = (table: MRT_TableInstance<TData>) => {
setDraggingRow(null);
table.setHoveredRow(null);
};
Expand Down
4 changes: 2 additions & 2 deletions packages/odyssey-react-mui/src/Pagination/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { paginationTypeValues } from "./constants";
import { usePagination } from "./usePagination";
import { useTranslation } from "react-i18next";

const PaginationContainer = styled("div")({
const PaginationContainer = styled("nav")({
display: "flex",
alignItems: "center",
justifyContent: "space-between",
Expand Down Expand Up @@ -330,7 +330,7 @@ const Pagination = ({
);

return variant === "paged" ? (
<PaginationContainer>
<PaginationContainer aria-label={t("pagination.label")}>
<PaginationSegment odysseyDesignTokens={odysseyDesignTokens}>
{hasRowCountInput && (
<Box>
Expand Down
10 changes: 7 additions & 3 deletions packages/odyssey-react-mui/src/labs/DataFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -433,9 +433,9 @@ const DataFilters = ({
<>
<Box>
<Button
aria-controls={isFiltersMenuOpen ? "filters-menu" : undefined}
aria-expanded={isFiltersMenuOpen ? "true" : undefined}
aria-haspopup="true"
ariaControls={isFiltersMenuOpen ? "filters-menu" : undefined}
ariaExpanded={isFiltersMenuOpen ? "true" : undefined}
ariaHasPopup="true"
ariaLabel={t("filters.filters.arialabel")}
isDisabled={isDisabled}
endIcon={<FilterIcon />}
Expand Down Expand Up @@ -469,6 +469,7 @@ const DataFilters = ({
return (
<MuiMenuItem
key={filter.id}
aria-controls={isFilterPopoverOpen ? "filter-form" : undefined}
onClick={(event) => {
setIsFilterPopoverOpen(true);
setFilterPopoverAnchorElement(event.currentTarget);
Expand Down Expand Up @@ -563,6 +564,7 @@ const DataFilters = ({
{filterMenu}
{/* Filter popover */}
<MuiPopover
id="filter-form"
anchorEl={filterPopoverAnchorElement}
// Positions the popover flush with the edge of the parent menu
// and at the right shadow elevation. These magic values are simply
Expand Down Expand Up @@ -630,6 +632,7 @@ const DataFilters = ({
variant="primary"
endIcon={<CheckIcon />}
type="submit"
ariaLabel={t("filters.submit.label")}
/>
</AutocompleteOuterContainer>
)}
Expand Down Expand Up @@ -697,6 +700,7 @@ const DataFilters = ({
variant="primary"
endIcon={<CheckIcon />}
type="submit"
ariaLabel={t("filters.submit.label")}
/>
</Box>
)}
Expand Down
59 changes: 30 additions & 29 deletions packages/odyssey-react-mui/src/labs/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export type {

// The shape of the table columns,
// with props named to match their MRT_ColumnDef counterparts
export type DataTableColumn = {
export type DataTableColumn<TData extends MRT_RowData> = {
/**
* The unique ID of the column
*/
Expand All @@ -82,12 +82,12 @@ export type DataTableColumn = {
* Customize the way each cell in the column is
* displayed via a custom React component.
*/
Cell?: MRT_ColumnDef<MRT_RowData>["Cell"];
Cell?: MRT_ColumnDef<TData>["Cell"];
/**
* The UI control that will be used to filter the column.
* Defaults to a standard text input.
*/
filterVariant?: MRT_ColumnDef<MRT_RowData>["filterVariant"];
filterVariant?: MRT_ColumnDef<TData>["filterVariant"];
/**
* If the filter control has preset options (such as a select or multi-select),
* these are the options provided.
Expand Down Expand Up @@ -127,16 +127,16 @@ export type DataTableColumn = {
enableHiding?: boolean;
};

export type DataTableProps = {
export type DataTableProps<TData extends MRT_RowData> = {
/**
* The columns that make up the table
*/
columns: DataTableColumn[];
columns: DataTableColumn<TData>[];
/**
* The data that goes into the table, which will be displayed
* as the table rows
*/
data: MRT_TableOptions<MRT_RowData>["data"];
data: MRT_TableOptions<TData>["data"];
/**
* The total number of rows in the table. Optional, because it's sometimes impossible
* to calculate. Used in table pagination to know when to disable the "next"/"more" button.
Expand All @@ -145,7 +145,7 @@ export type DataTableProps = {
/**
* The function to get the ID of a row
*/
getRowId?: MRT_TableOptions<MRT_RowData>["getRowId"];
getRowId?: MRT_TableOptions<TData>["getRowId"];
/**
* The initial density of the table. This is available even if the table density
* isn't changeable.
Expand Down Expand Up @@ -219,7 +219,7 @@ export type DataTableProps = {
search?: string;
filters?: DataFilter[];
sort?: MRT_SortingState;
}) => MRT_TableOptions<MRT_RowData>["data"];
}) => MRT_TableOptions<TData>["data"];
/**
* Callback that fires when the user reorders rows within the table. Can be used
* to propogate order change to the backend.
Expand Down Expand Up @@ -248,24 +248,24 @@ export type DataTableProps = {
* Action buttons to display in each row
*/
rowActionButtons?: (
row: MRT_RowData,
row: TData,
) => ReactElement<typeof Button | typeof Fragment>;
/**
* Menu items to include in the optional actions menu on each row.
*/
rowActionMenuItems?: (
row: MRT_RowData,
row: TData,
) => ReactElement<typeof MenuItem | typeof Fragment>;
};

type TableType = MRT_TableInstance<MRT_RowData>;
type TableType<TData extends MRT_RowData> = MRT_TableInstance<TData>;

const reorderDataRowsLocally = ({
const reorderDataRowsLocally = <TData extends MRT_RowData>({
currentData,
rowId,
newIndex,
}: {
currentData: MRT_TableOptions<MRT_RowData>["data"];
currentData: MRT_TableOptions<TData>["data"];
rowId: string;
newIndex: number;
}) => {
Expand All @@ -284,7 +284,7 @@ const reorderDataRowsLocally = ({
return updatedData;
};

const DataTable = ({
const DataTable = <TData extends MRT_RowData>({
columns,
data: dataProp,
getRowId,
Expand All @@ -309,13 +309,12 @@ const DataTable = ({
hasRowSelection,
hasSearch,
hasSorting,
}: DataTableProps) => {
}: DataTableProps<TData>) => {
const odysseyDesignTokens = useOdysseyDesignTokens();
const { t } = useTranslation();
const [draggingRow, setDraggingRow] = useState<MRT_Row<MRT_RowData> | null>();
const [draggingRow, setDraggingRow] = useState<MRT_Row<TData> | null>();
const [showSkeletons, setShowSkeletons] = useState<boolean>(true);
const [data, setData] =
useState<MRT_TableOptions<MRT_RowData>["data"]>(dataProp);
const [data, setData] = useState<MRT_TableOptions<TData>["data"]>(dataProp);
const [page, setPage] = useState<number>(pageProp);
const [resultsPerPage, setResultsPerPage] =
useState<number>(resultsPerPageProp);
Expand Down Expand Up @@ -428,24 +427,24 @@ const DataTable = ({
const rowVirtualizerInstanceRef =
useRef<MRT_RowVirtualizer<HTMLDivElement, HTMLTableRowElement>>(null);

const setHoveredRow = (table: TableType, id: MRT_RowData["id"]) => {
const setHoveredRow = (table: TableType<TData>, id: TData["id"]) => {
if (id) {
const nextRow: MRT_RowData = table.getRow(id);
const nextRow = table.getRow(id) as MRT_Row<TData>;

if (nextRow) {
table.setHoveredRow(nextRow);
}
}
};

const resetDraggingAndHoveredRow = (table: TableType) => {
const resetDraggingAndHoveredRow = (table: TableType<TData>) => {
setDraggingRow(null);
table.setHoveredRow(null);
};

type HandleDragHandleKeyDownArgs = {
table: TableType;
row: MRT_Row<MRT_RowData>;
table: TableType<TData>;
row: MRT_Row<TData>;
event: KeyboardEvent<HTMLButtonElement>;
};

Expand Down Expand Up @@ -515,23 +514,25 @@ const DataTable = ({
[
data,
draggingRow,
odysseyDesignTokens,
odysseyDesignTokens.TransitionDurationMainAsNumber,
page,
resetDraggingAndHoveredRow,
resultsPerPage,
setHoveredRow,
updateRowOrder,
],
);

const handleDragHandleOnDragEnd = useCallback(
(table: TableType) => {
(table: TableType<TData>) => {
const cols = table.getAllColumns();
cols[0].toggleVisibility();

const { draggingRow, hoveredRow } = table.getState();
if (draggingRow) {
updateRowOrder({
rowId: draggingRow.id,
newIndex: (hoveredRow as MRT_RowData).index,
newIndex: (hoveredRow as TData).index,
});
}

Expand All @@ -541,7 +542,7 @@ const DataTable = ({
);

const handleDragHandleOnDragCapture = useCallback(
(table: TableType) => {
(table: TableType<TData>) => {
if (!draggingRow && table.getState().draggingRow?.id) {
setDraggingRow(table.getState().draggingRow);
}
Expand Down Expand Up @@ -683,7 +684,7 @@ const DataTable = ({

return (
<Box sx={{ display: "flex" }}>
{rowActionButtons?.(row)}
{rowActionButtons?.(row.original)}
{(rowActionMenuItems || hasRowReordering) && (
<MenuButton
endIcon={<MoreIcon />}
Expand All @@ -694,7 +695,7 @@ const DataTable = ({
>
{rowActionMenuItems && (
<>
{rowActionMenuItems(row)}
{rowActionMenuItems(row.original)}
<hr />
</>
)}
Expand Down
Loading