@databiosphere/findable-ui 32.1.1 → 34.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +27 -0
- package/jest.config.js +4 -0
- package/lib/common/categories/config/utils.d.ts +1 -1
- package/lib/common/categories/config/utils.js +5 -1
- package/lib/common/entities.d.ts +4 -4
- package/lib/components/DataDictionary/components/Entities/entities.d.ts +1 -1
- package/lib/components/DataDictionary/components/Entities/entities.js +3 -2
- package/lib/components/DataDictionary/components/Entities/types.d.ts +3 -4
- package/lib/components/DataDictionary/components/Entity/entity.d.ts +1 -1
- package/lib/components/DataDictionary/components/Entity/entity.js +12 -6
- package/lib/components/DataDictionary/components/Entity/entity.styles.js +7 -1
- package/lib/components/DataDictionary/components/Entity/types.d.ts +4 -4
- package/lib/components/DataDictionary/components/Entity/utils.d.ts +9 -0
- package/lib/components/DataDictionary/components/Entity/utils.js +18 -0
- package/lib/components/DataDictionary/components/Filters/components/ColumnFilters/columnFilters.d.ts +4 -0
- package/lib/components/DataDictionary/components/Filters/components/ColumnFilters/columnFilters.js +9 -0
- package/lib/components/DataDictionary/components/Filters/components/ColumnFilters/types.d.ts +5 -0
- package/lib/components/DataDictionary/components/Filters/components/ColumnFilters/types.js +1 -0
- package/lib/components/DataDictionary/components/Filters/filters.d.ts +4 -0
- package/lib/components/DataDictionary/components/Filters/filters.js +7 -0
- package/lib/components/DataDictionary/components/Filters/filters.styles.d.ts +7 -0
- package/lib/components/DataDictionary/components/Filters/filters.styles.js +13 -0
- package/lib/components/DataDictionary/components/Filters/stories/constants.d.ts +4 -0
- package/lib/components/DataDictionary/components/Filters/stories/constants.js +25 -0
- package/lib/components/DataDictionary/components/Filters/stories/filters.stories.d.ts +6 -0
- package/lib/components/DataDictionary/components/Filters/stories/filters.stories.js +31 -0
- package/lib/components/DataDictionary/components/Filters/stories/hook.d.ts +5 -0
- package/lib/components/DataDictionary/components/Filters/stories/hook.js +5 -0
- package/lib/components/DataDictionary/components/Filters/stories/types.d.ts +4 -0
- package/lib/components/DataDictionary/components/Filters/stories/types.js +1 -0
- package/lib/components/DataDictionary/components/Filters/types.d.ts +5 -0
- package/lib/components/DataDictionary/components/Filters/types.js +1 -0
- package/lib/components/DataDictionary/components/Layout/components/EntitiesLayout/entitiesLayout.styles.js +3 -1
- package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.d.ts +2 -0
- package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.js +5 -0
- package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.styles.d.ts +5 -0
- package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.styles.js +24 -0
- package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/types.d.ts +5 -0
- package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/types.js +1 -0
- package/lib/components/DataDictionary/components/Layout/components/OutlineLayout/outlineLayout.styles.js +1 -1
- package/lib/components/DataDictionary/components/Layout/components/TitleLayout/titleLayout.styles.js +1 -0
- package/lib/components/DataDictionary/components/Layout/constants.d.ts +4 -0
- package/lib/components/DataDictionary/components/Layout/constants.js +4 -0
- package/lib/components/DataDictionary/components/Outline/utils.d.ts +5 -5
- package/lib/components/DataDictionary/components/Outline/utils.js +23 -6
- package/lib/components/DataDictionary/components/Table/hook.d.ts +3 -3
- package/lib/components/DataDictionary/components/Table/hook.js +11 -3
- package/lib/components/DataDictionary/components/Table/options/columnFilters/constants.d.ts +2 -0
- package/lib/components/DataDictionary/components/Table/options/columnFilters/constants.js +8 -0
- package/lib/components/DataDictionary/components/Table/options/columnFilters/hook.d.ts +6 -0
- package/lib/components/DataDictionary/components/Table/options/columnFilters/hook.js +14 -0
- package/lib/components/DataDictionary/components/Table/options/expanded/constants.d.ts +2 -0
- package/lib/components/DataDictionary/components/Table/options/expanded/constants.js +5 -0
- package/lib/components/DataDictionary/components/Table/options/faceted/constants.d.ts +2 -0
- package/lib/components/DataDictionary/components/Table/options/faceted/constants.js +6 -0
- package/lib/components/DataDictionary/components/Table/options/grouping/constants.d.ts +2 -0
- package/lib/components/DataDictionary/components/Table/options/grouping/constants.js +5 -0
- package/lib/components/DataDictionary/components/Table/options/hook.d.ts +1 -1
- package/lib/components/DataDictionary/components/Table/options/hook.js +17 -0
- package/lib/components/DataDictionary/components/Table/options/visibility/constants.d.ts +2 -0
- package/lib/components/DataDictionary/components/Table/options/visibility/constants.js +3 -0
- package/lib/components/DataDictionary/components/Table/table.d.ts +1 -1
- package/lib/components/DataDictionary/components/Table/table.js +2 -2
- package/lib/components/DataDictionary/components/Table/types.d.ts +4 -1
- package/lib/components/DataDictionary/components/Table/utils.d.ts +18 -0
- package/lib/components/DataDictionary/components/Table/utils.js +27 -0
- package/lib/components/DataDictionary/dataDictionary.d.ts +1 -1
- package/lib/components/DataDictionary/dataDictionary.js +9 -7
- package/lib/components/DataDictionary/hooks/UseDataDictionary/hook.js +16 -4
- package/lib/components/DataDictionary/hooks/UseDataDictionary/types.d.ts +6 -4
- package/lib/components/DataDictionary/types.d.ts +1 -0
- package/lib/components/Detail/components/Table/components/TableBody/tableBody.d.ts +8 -2
- package/lib/components/Detail/components/Table/components/TableBody/tableBody.js +2 -2
- package/lib/components/Detail/components/Table/components/TableRows/components/CollapsableRows/collapsableRows.d.ts +8 -2
- package/lib/components/Detail/components/Table/components/TableRows/components/CollapsableRows/collapsableRows.js +2 -2
- package/lib/components/Detail/components/Table/components/TableRows/tableRows.d.ts +8 -2
- package/lib/components/Detail/components/Table/components/TableRows/tableRows.js +2 -2
- package/lib/components/Filter/components/FilterLabel/filterLabel.styles.d.ts +1 -1
- package/lib/components/Filter/components/FilterList/filterList.styles.d.ts +2 -0
- package/lib/components/Filter/components/FilterList/filterList.styles.js +28 -15
- package/lib/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.styles.d.ts +1 -1
- package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Authentication/components/Button/button.styles.d.ts +1 -1
- package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Search/components/Button/button.styles.d.ts +1 -1
- package/lib/components/Layout/components/Header/header.styles.js +4 -1
- package/lib/components/Layout/components/Outline/components/ContentsTab/contentsTab.styles.d.ts +1 -1
- package/lib/components/Layout/components/Outline/outline.styles.d.ts +1 -1
- package/lib/components/Login/components/Button/button.styles.d.ts +1 -1
- package/lib/components/Table/common/utils.d.ts +6 -0
- package/lib/components/Table/common/utils.js +14 -0
- package/lib/components/Table/components/TableFeatures/ColumnFilter/columnFilter.d.ts +7 -0
- package/lib/components/Table/components/TableFeatures/ColumnFilter/columnFilter.js +33 -0
- package/lib/components/Table/components/TableFeatures/ColumnFilter/columnFilter.styles.d.ts +3 -0
- package/lib/components/Table/components/TableFeatures/ColumnFilter/columnFilter.styles.js +19 -0
- package/lib/components/Table/components/TableFeatures/ColumnFilter/constants.d.ts +2 -0
- package/lib/components/Table/components/TableFeatures/ColumnFilter/constants.js +14 -0
- package/lib/components/Table/components/TableFeatures/ColumnFilter/types.d.ts +7 -0
- package/lib/components/Table/components/TableFeatures/ColumnFilter/types.js +1 -0
- package/lib/components/Table/components/TableFeatures/ColumnFilter/utils.d.ts +6 -0
- package/lib/components/Table/components/TableFeatures/ColumnFilter/utils.js +23 -0
- package/lib/components/Table/featureOptions/facetedColumn/utils.d.ts +6 -0
- package/lib/components/Table/featureOptions/facetedColumn/utils.js +9 -0
- package/lib/components/common/ButtonGroup/constants.d.ts +2 -0
- package/lib/components/common/ButtonGroup/constants.js +11 -0
- package/lib/components/common/Tabs/tabs.styles.d.ts +1 -1
- package/lib/mocks/@storybook/addon-actions.d.ts +9 -0
- package/lib/mocks/@storybook/addon-actions.js +9 -0
- package/lib/styles/common/mui/buttonGroup.d.ts +13 -0
- package/lib/styles/common/mui/buttonGroup.js +34 -0
- package/lib/styles/common/mui/typography.js +2 -0
- package/lib/tests/mui/constants.d.ts +1 -0
- package/lib/tests/mui/constants.js +1 -0
- package/lib/tests/utils.d.ts +6 -0
- package/lib/tests/utils.js +8 -0
- package/lib/theme/common/components.d.ts +0 -6
- package/lib/theme/common/components.js +17 -31
- package/lib/theme/components/index.d.ts +1 -0
- package/lib/theme/components/index.js +1 -0
- package/lib/theme/components/muiButtonGroup.d.ts +2 -0
- package/lib/theme/components/muiButtonGroup.js +76 -0
- package/lib/theme/theme.js +1 -1
- package/package.json +1 -1
- package/src/common/categories/config/utils.ts +6 -3
- package/src/common/entities.ts +5 -4
- package/src/components/DataDictionary/components/Entities/entities.tsx +5 -9
- package/src/components/DataDictionary/components/Entities/types.ts +3 -4
- package/src/components/DataDictionary/components/Entity/entity.styles.ts +9 -1
- package/src/components/DataDictionary/components/Entity/entity.tsx +18 -8
- package/src/components/DataDictionary/components/Entity/types.ts +4 -4
- package/src/components/DataDictionary/components/Entity/utils.ts +25 -0
- package/src/components/DataDictionary/components/Filters/components/ColumnFilters/columnFilters.tsx +21 -0
- package/src/components/DataDictionary/components/Filters/components/ColumnFilters/types.ts +6 -0
- package/src/components/DataDictionary/components/Filters/filters.styles.ts +14 -0
- package/src/components/DataDictionary/components/Filters/filters.tsx +16 -0
- package/src/components/DataDictionary/components/Filters/stories/constants.ts +31 -0
- package/src/components/DataDictionary/components/Filters/stories/filters.stories.tsx +42 -0
- package/src/components/DataDictionary/components/Filters/stories/hook.ts +9 -0
- package/src/components/DataDictionary/components/Filters/stories/types.ts +3 -0
- package/src/components/DataDictionary/components/Filters/types.ts +6 -0
- package/src/components/DataDictionary/components/Layout/components/EntitiesLayout/entitiesLayout.styles.ts +4 -1
- package/src/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.styles.ts +27 -0
- package/src/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.tsx +10 -0
- package/src/components/DataDictionary/components/Layout/components/FiltersLayout/types.ts +6 -0
- package/src/components/DataDictionary/components/Layout/components/OutlineLayout/outlineLayout.styles.ts +1 -1
- package/src/components/DataDictionary/components/Layout/components/TitleLayout/titleLayout.styles.ts +1 -0
- package/src/components/DataDictionary/components/Layout/constants.ts +4 -0
- package/src/components/DataDictionary/components/Outline/utils.ts +35 -13
- package/src/components/DataDictionary/components/Table/hook.ts +17 -5
- package/src/components/DataDictionary/components/Table/options/columnFilters/constants.ts +16 -0
- package/src/components/DataDictionary/components/Table/options/columnFilters/hook.ts +32 -0
- package/src/components/DataDictionary/components/Table/options/expanded/constants.ts +13 -0
- package/src/components/DataDictionary/components/Table/options/faceted/constants.ts +14 -0
- package/src/components/DataDictionary/components/Table/options/grouping/constants.ts +9 -0
- package/src/components/DataDictionary/components/Table/options/hook.ts +26 -3
- package/src/components/DataDictionary/components/Table/options/visibility/constants.ts +5 -0
- package/src/components/DataDictionary/components/Table/table.tsx +2 -0
- package/src/components/DataDictionary/components/Table/types.ts +8 -1
- package/src/components/DataDictionary/components/Table/utils.ts +40 -0
- package/src/components/DataDictionary/dataDictionary.tsx +10 -6
- package/src/components/DataDictionary/hooks/UseDataDictionary/hook.ts +19 -4
- package/src/components/DataDictionary/hooks/UseDataDictionary/types.ts +6 -4
- package/src/components/DataDictionary/types.ts +1 -0
- package/src/components/Detail/components/Table/components/TableBody/tableBody.tsx +14 -3
- package/src/components/Detail/components/Table/components/TableRows/components/CollapsableRows/collapsableRows.tsx +9 -2
- package/src/components/Detail/components/Table/components/TableRows/tableRows.tsx +9 -2
- package/src/components/Filter/components/FilterList/filterList.styles.ts +34 -15
- package/src/components/Layout/components/Header/header.styles.ts +6 -1
- package/src/components/Table/common/utils.ts +16 -0
- package/src/components/Table/components/TableFeatures/ColumnFilter/columnFilter.styles.ts +23 -0
- package/src/components/Table/components/TableFeatures/ColumnFilter/columnFilter.tsx +98 -0
- package/src/components/Table/components/TableFeatures/ColumnFilter/constants.ts +16 -0
- package/src/components/Table/components/TableFeatures/ColumnFilter/types.ts +10 -0
- package/src/components/Table/components/TableFeatures/ColumnFilter/utils.ts +27 -0
- package/src/components/Table/featureOptions/facetedColumn/utils.ts +14 -0
- package/src/components/common/ButtonGroup/constants.ts +13 -0
- package/src/mocks/@storybook/addon-actions.ts +10 -0
- package/src/styles/common/mui/buttonGroup.ts +46 -0
- package/src/styles/common/mui/typography.ts +2 -0
- package/src/tests/mui/constants.ts +1 -0
- package/src/tests/utils.ts +9 -0
- package/src/theme/common/components.ts +17 -32
- package/src/theme/components/index.ts +1 -0
- package/src/theme/components/muiButtonGroup.ts +79 -0
- package/src/theme/theme.ts +1 -1
- package/tests/dataDictionaryColumnFilters.test.tsx +101 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Checkbox, ListItemButton, ListItemText, Button as MButton, Typography, } from "@mui/material";
|
|
2
|
+
import React, { Fragment } from "react";
|
|
3
|
+
import { SVG_ICON_PROPS } from "../../../../../styles/common/mui/svgIcon";
|
|
4
|
+
import { TYPOGRAPHY_PROPS } from "../../../../../styles/common/mui/typography";
|
|
5
|
+
import { CheckedIcon } from "../../../../common/CustomIcon/components/CheckedIcon/checkedIcon";
|
|
6
|
+
import { UncheckedIcon } from "../../../../common/CustomIcon/components/UncheckedIcon/uncheckedIcon";
|
|
7
|
+
import { DropDownIcon } from "../../../../common/Form/components/Select/components/DropDownIcon/dropDownIcon";
|
|
8
|
+
import { useMenu } from "../../../../common/Menu/hooks/useMenu";
|
|
9
|
+
import { getColumnHeader } from "../../../common/utils";
|
|
10
|
+
import { getSortedFacetedValues } from "../../../featureOptions/facetedColumn/utils";
|
|
11
|
+
import { StyledMenu } from "./columnFilter.styles";
|
|
12
|
+
import { MENU_PROPS } from "./constants";
|
|
13
|
+
import { updater } from "./utils";
|
|
14
|
+
/**
|
|
15
|
+
* Column filter component with supported filter functions:
|
|
16
|
+
* - `arrIncludesSome`
|
|
17
|
+
*/
|
|
18
|
+
export const ColumnFilter = ({ Button = MButton, className, column, ...props /* MuiMenuProps */ }) => {
|
|
19
|
+
const { anchorEl, onClose, onOpen, open } = useMenu();
|
|
20
|
+
const facetedUniqueValues = column.getFacetedUniqueValues();
|
|
21
|
+
const sortedValues = getSortedFacetedValues(facetedUniqueValues);
|
|
22
|
+
const filterValue = (column.getFilterValue() || []);
|
|
23
|
+
return (React.createElement(Fragment, null,
|
|
24
|
+
React.createElement(Button, { key: column.id, endIcon: React.createElement(DropDownIcon, { color: SVG_ICON_PROPS.COLOR.INK_LIGHT }), onClick: onOpen }, getColumnHeader(column)),
|
|
25
|
+
React.createElement(StyledMenu, { ...MENU_PROPS, ...props, className: className, anchorEl: anchorEl, onClose: onClose, open: open },
|
|
26
|
+
sortedValues.map(([value, occurrence]) => (React.createElement(ListItemButton, { key: String(value), selected: filterValue.includes(value), onClick: () => column.setFilterValue(updater(value)) },
|
|
27
|
+
React.createElement(Checkbox, { checked: filterValue.includes(value), checkedIcon: React.createElement(CheckedIcon, null), icon: React.createElement(UncheckedIcon, null) }),
|
|
28
|
+
React.createElement(ListItemText, { disableTypography: true, primary: React.createElement("span", null, String(value)), secondary: React.createElement(Typography, { color: TYPOGRAPHY_PROPS.COLOR.INK_LIGHT, variant: TYPOGRAPHY_PROPS.VARIANT.TEXT_BODY_SMALL_400 }, occurrence) })))),
|
|
29
|
+
React.createElement(ListItemButton, { disabled: !column.getIsFiltered(), onClick: () => column.setFilterValue(undefined) },
|
|
30
|
+
React.createElement(Typography, { color: column.getIsFiltered()
|
|
31
|
+
? TYPOGRAPHY_PROPS.COLOR.PRIMARY
|
|
32
|
+
: TYPOGRAPHY_PROPS.COLOR.INHERIT, variant: TYPOGRAPHY_PROPS.VARIANT.TEXT_BODY_500 }, "Clear All")))));
|
|
33
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import styled from "@emotion/styled";
|
|
2
|
+
import { Menu, menuClasses, paperClasses } from "@mui/material";
|
|
3
|
+
import { MAX_LIST_HEIGHT_PX } from "../../../../Filter/common/constants";
|
|
4
|
+
import { MuiListItemButtonRoot, MuiListItemTextRoot, } from "../../../../Filter/components/FilterList/filterList.styles";
|
|
5
|
+
export const StyledMenu = styled(Menu) `
|
|
6
|
+
.${paperClasses.root} {
|
|
7
|
+
margin: 4px 0;
|
|
8
|
+
width: 288px;
|
|
9
|
+
|
|
10
|
+
.${menuClasses.list} {
|
|
11
|
+
max-height: ${MAX_LIST_HEIGHT_PX}px;
|
|
12
|
+
overflow-wrap: break-word;
|
|
13
|
+
|
|
14
|
+
${MuiListItemButtonRoot}
|
|
15
|
+
|
|
16
|
+
${MuiListItemTextRoot}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
`;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Button, MenuProps } from "@mui/material";
|
|
2
|
+
import { Column, RowData } from "@tanstack/react-table";
|
|
3
|
+
import { BaseComponentProps } from "../../../../types";
|
|
4
|
+
export interface ColumnFilterProps<T extends RowData> extends BaseComponentProps, Omit<MenuProps, "anchorEl" | "onClose" | "open"> {
|
|
5
|
+
Button?: typeof Button;
|
|
6
|
+
column: Column<T>;
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns an updater function for column filter.
|
|
3
|
+
* @param value - Value.
|
|
4
|
+
* @returns An updater function that returns the new filter value.
|
|
5
|
+
*/
|
|
6
|
+
export function updater(value) {
|
|
7
|
+
return (old) => {
|
|
8
|
+
// If no old value, return new value.
|
|
9
|
+
if (!old)
|
|
10
|
+
return [value];
|
|
11
|
+
// If value already exists, remove it.
|
|
12
|
+
if (old.includes(value)) {
|
|
13
|
+
// Filter out the value.
|
|
14
|
+
const next = old.filter((v) => v !== value);
|
|
15
|
+
// If no values remain, return undefined.
|
|
16
|
+
if (next.length === 0)
|
|
17
|
+
return undefined;
|
|
18
|
+
return next;
|
|
19
|
+
}
|
|
20
|
+
// Otherwise, add the value.
|
|
21
|
+
return [...old, value];
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { COLLATOR_CASE_INSENSITIVE } from "../../../../common/constants";
|
|
2
|
+
/**
|
|
3
|
+
* Sorts Map entries by key.
|
|
4
|
+
* @param facetedValues - Map of faceted values.
|
|
5
|
+
* @returns Sorted array of [key, value] entries.
|
|
6
|
+
*/
|
|
7
|
+
export function getSortedFacetedValues(facetedValues) {
|
|
8
|
+
return [...facetedValues].sort((a, b) => COLLATOR_CASE_INSENSITIVE.compare(String(a), String(b)));
|
|
9
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BUTTON_GROUP_PROPS as MUI_BUTTON_GROUP_PROPS } from "../../../styles/common/mui/buttonGroup";
|
|
2
|
+
export const BUTTON_GROUP_PROPS = {
|
|
3
|
+
PRIMARY_CONTAINED: {
|
|
4
|
+
color: MUI_BUTTON_GROUP_PROPS.COLOR.PRIMARY,
|
|
5
|
+
variant: MUI_BUTTON_GROUP_PROPS.VARIANT.CONTAINED,
|
|
6
|
+
},
|
|
7
|
+
SECONDARY_OUTLINED: {
|
|
8
|
+
color: MUI_BUTTON_GROUP_PROPS.COLOR.SECONDARY,
|
|
9
|
+
variant: MUI_BUTTON_GROUP_PROPS.VARIANT.OUTLINED,
|
|
10
|
+
},
|
|
11
|
+
};
|
|
@@ -9,7 +9,7 @@ export declare const TabScrollFuzz: import("@emotion/styled").StyledComponent<{
|
|
|
9
9
|
} & Props, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, {}>;
|
|
10
10
|
export declare const Tab: import("@emotion/styled").StyledComponent<import("@mui/material").TabOwnProps & Omit<import("@mui/material").ButtonBaseOwnProps, "classes"> & import("@mui/material/OverridableComponent").CommonProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
|
11
11
|
ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
|
|
12
|
-
}, "label" | "style" | "className" | "classes" | "tabIndex" | "children" | "sx" | "disabled" | "value" | "action" | "
|
|
12
|
+
}, "label" | "style" | "className" | "classes" | "tabIndex" | "children" | "sx" | "disabled" | "value" | "action" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "icon" | "wrapped" | "iconPosition"> & {
|
|
13
13
|
theme?: import("@emotion/react").Theme;
|
|
14
14
|
}, {}, {}>;
|
|
15
15
|
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jest } from "@jest/globals";
|
|
2
|
+
/**
|
|
3
|
+
* Mock for Storybook's @storybook/addon-actions function.
|
|
4
|
+
* The mock keeps the same function signature as the real Storybook action,
|
|
5
|
+
* does not trigger any Storybook logic, and simply returns a Jest mock function
|
|
6
|
+
* for use in tests.
|
|
7
|
+
* @returns A Jest mock function.
|
|
8
|
+
*/
|
|
9
|
+
export declare const action: () => jest.Mock;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jest } from "@jest/globals";
|
|
2
|
+
/**
|
|
3
|
+
* Mock for Storybook's @storybook/addon-actions function.
|
|
4
|
+
* The mock keeps the same function signature as the real Storybook action,
|
|
5
|
+
* does not trigger any Storybook logic, and simply returns a Jest mock function
|
|
6
|
+
* for use in tests.
|
|
7
|
+
* @returns A Jest mock function.
|
|
8
|
+
*/
|
|
9
|
+
export const action = () => jest.fn();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ButtonGroupProps } from "@mui/material";
|
|
2
|
+
type ButtonGroupPropsOptions = {
|
|
3
|
+
CLASSES: typeof CLASSES;
|
|
4
|
+
COLOR: typeof COLOR;
|
|
5
|
+
SIZE: typeof SIZE;
|
|
6
|
+
VARIANT: typeof VARIANT;
|
|
7
|
+
};
|
|
8
|
+
declare const CLASSES: Record<string, ButtonGroupProps["classes"]>;
|
|
9
|
+
declare const COLOR: Record<string, ButtonGroupProps["color"]>;
|
|
10
|
+
declare const SIZE: Record<string, ButtonGroupProps["size"]>;
|
|
11
|
+
declare const VARIANT: Record<string, ButtonGroupProps["variant"]>;
|
|
12
|
+
export declare const BUTTON_GROUP_PROPS: ButtonGroupPropsOptions;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { buttonGroupClasses } from "@mui/material";
|
|
2
|
+
const CLASSES = {
|
|
3
|
+
COLOR_PRIMARY: buttonGroupClasses.colorPrimary,
|
|
4
|
+
COLOR_SECONDARY: buttonGroupClasses.colorSecondary,
|
|
5
|
+
CONTAINED: buttonGroupClasses.contained,
|
|
6
|
+
GROUPED: buttonGroupClasses.grouped,
|
|
7
|
+
OUTLINED: buttonGroupClasses.outlined,
|
|
8
|
+
ROOT: buttonGroupClasses.root,
|
|
9
|
+
};
|
|
10
|
+
const COLOR = {
|
|
11
|
+
ERROR: "error",
|
|
12
|
+
INFO: "info",
|
|
13
|
+
INHERIT: "inherit",
|
|
14
|
+
PRIMARY: "primary",
|
|
15
|
+
SECONDARY: "secondary",
|
|
16
|
+
SUCCESS: "success",
|
|
17
|
+
WARNING: "warning",
|
|
18
|
+
};
|
|
19
|
+
const SIZE = {
|
|
20
|
+
LARGE: "large",
|
|
21
|
+
MEDIUM: "medium",
|
|
22
|
+
SMALL: "small",
|
|
23
|
+
};
|
|
24
|
+
const VARIANT = {
|
|
25
|
+
CONTAINED: "contained",
|
|
26
|
+
OUTLINED: "outlined",
|
|
27
|
+
TEXT: "text",
|
|
28
|
+
};
|
|
29
|
+
export const BUTTON_GROUP_PROPS = {
|
|
30
|
+
CLASSES,
|
|
31
|
+
COLOR,
|
|
32
|
+
SIZE,
|
|
33
|
+
VARIANT,
|
|
34
|
+
};
|
|
@@ -3,11 +3,13 @@ const COLOR = {
|
|
|
3
3
|
INHERIT: "inherit",
|
|
4
4
|
INK_LIGHT: "ink.light",
|
|
5
5
|
INK_MAIN: "ink.main",
|
|
6
|
+
PRIMARY: "primary",
|
|
6
7
|
};
|
|
7
8
|
const VARIANT = {
|
|
8
9
|
INHERIT: "inherit",
|
|
9
10
|
TEXT_BODY_400: "text-body-400",
|
|
10
11
|
TEXT_BODY_400_2_LINES: "text-body-400-2lines",
|
|
12
|
+
TEXT_BODY_500: "text-body-500",
|
|
11
13
|
TEXT_BODY_SMALL_400: "text-body-small-400",
|
|
12
14
|
TEXT_HEADING_LARGE: "text-heading-large",
|
|
13
15
|
TEXT_HEADING_SMALL: "text-heading-small",
|
package/lib/tests/utils.d.ts
CHANGED
|
@@ -16,6 +16,12 @@ export declare function getLabelText<T extends HTMLElement = HTMLElement>(text:
|
|
|
16
16
|
* @returns RegExp.
|
|
17
17
|
*/
|
|
18
18
|
export declare function getStartsWithRegex(text: string): RegExp;
|
|
19
|
+
/**
|
|
20
|
+
* Retrieves an element by its role.
|
|
21
|
+
* @param role - The role of the element.
|
|
22
|
+
* @returns The element.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getRole<T extends HTMLElement = HTMLElement>(role: string): T;
|
|
19
25
|
/**
|
|
20
26
|
* Retrieves an element by its text content.
|
|
21
27
|
* @param text - The text content of the element.
|
package/lib/tests/utils.js
CHANGED
|
@@ -24,6 +24,14 @@ export function getLabelText(text) {
|
|
|
24
24
|
export function getStartsWithRegex(text) {
|
|
25
25
|
return new RegExp(`^${escapeRegExp(text)}`);
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Retrieves an element by its role.
|
|
29
|
+
* @param role - The role of the element.
|
|
30
|
+
* @returns The element.
|
|
31
|
+
*/
|
|
32
|
+
export function getRole(role) {
|
|
33
|
+
return screen.getByRole(role);
|
|
34
|
+
}
|
|
27
35
|
/**
|
|
28
36
|
* Retrieves an element by its text content.
|
|
29
37
|
* @param text - The text content of the element.
|
|
@@ -40,12 +40,6 @@ export declare const MuiButton: (theme: Theme) => Components["MuiButton"];
|
|
|
40
40
|
* @returns MuiButtonBase component theme styles.
|
|
41
41
|
*/
|
|
42
42
|
export declare const MuiButtonBase: (theme: Theme) => Components["MuiButtonBase"];
|
|
43
|
-
/**
|
|
44
|
-
* MuiButtonGroup Component
|
|
45
|
-
* @param theme - Theme.
|
|
46
|
-
* @returns MuiButtonGroup component theme styles.
|
|
47
|
-
*/
|
|
48
|
-
export declare const MuiButtonGroup: (theme: Theme) => Components["MuiButtonGroup"];
|
|
49
43
|
/**
|
|
50
44
|
* MuiCard Component
|
|
51
45
|
*/
|
|
@@ -2,6 +2,7 @@ import { DropDownIcon } from "../../components/common/Form/components/Select/com
|
|
|
2
2
|
import { COLOR_MIXES } from "../../styles/common/constants/colorMixes";
|
|
3
3
|
import { PALETTE } from "../../styles/common/constants/palette";
|
|
4
4
|
import { SHADOWS } from "../../styles/common/constants/shadows";
|
|
5
|
+
import { BUTTON_PROPS } from "../../styles/common/mui/button";
|
|
5
6
|
import { CHIP_PROPS } from "../../styles/common/mui/chip";
|
|
6
7
|
import { desktopUp, mobileUp, tabletUp } from "./breakpoints";
|
|
7
8
|
import { TEXT_BODY_400, TEXT_BODY_400_2_LINES, TEXT_BODY_500, TEXT_BODY_SMALL_400, TEXT_BODY_SMALL_500, TEXT_HEADING, TEXT_HEADING_SMALL, } from "./typography";
|
|
@@ -183,6 +184,22 @@ export const MuiButton = (theme) => {
|
|
|
183
184
|
},
|
|
184
185
|
endIcon: {
|
|
185
186
|
margin: 0,
|
|
187
|
+
variants: [
|
|
188
|
+
{
|
|
189
|
+
props: { size: BUTTON_PROPS.SIZE.MEDIUM },
|
|
190
|
+
style: {
|
|
191
|
+
marginLeft: -6,
|
|
192
|
+
marginRight: -6,
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
props: { size: BUTTON_PROPS.SIZE.SMALL },
|
|
197
|
+
style: {
|
|
198
|
+
marginLeft: -6,
|
|
199
|
+
marginRight: -6,
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
],
|
|
186
203
|
},
|
|
187
204
|
outlinedSecondary: {
|
|
188
205
|
backgroundColor: "transparent",
|
|
@@ -298,37 +315,6 @@ export const MuiButtonBase = (theme) => {
|
|
|
298
315
|
},
|
|
299
316
|
};
|
|
300
317
|
};
|
|
301
|
-
/**
|
|
302
|
-
* MuiButtonGroup Component
|
|
303
|
-
* @param theme - Theme.
|
|
304
|
-
* @returns MuiButtonGroup component theme styles.
|
|
305
|
-
*/
|
|
306
|
-
export const MuiButtonGroup = (theme) => {
|
|
307
|
-
return {
|
|
308
|
-
defaultProps: {
|
|
309
|
-
disableElevation: true,
|
|
310
|
-
disableRipple: true,
|
|
311
|
-
},
|
|
312
|
-
styleOverrides: {
|
|
313
|
-
grouped: {
|
|
314
|
-
minWidth: 0,
|
|
315
|
-
padding: "6px 8px",
|
|
316
|
-
},
|
|
317
|
-
groupedContainedPrimary: {
|
|
318
|
-
borderColor: theme.palette.primary.dark,
|
|
319
|
-
boxShadow: `0 1px 0 0 ${theme.palette.primary.dark}`,
|
|
320
|
-
// eslint-disable-next-line sort-keys -- disabling key order for readability
|
|
321
|
-
"&:hover": {
|
|
322
|
-
boxShadow: `0 1px 0 0 ${theme.palette.primary.dark}`,
|
|
323
|
-
},
|
|
324
|
-
// eslint-disable-next-line sort-keys -- disabling key order for readability
|
|
325
|
-
"&:active": {
|
|
326
|
-
boxShadow: "none",
|
|
327
|
-
},
|
|
328
|
-
},
|
|
329
|
-
},
|
|
330
|
-
};
|
|
331
|
-
};
|
|
332
318
|
/**
|
|
333
319
|
* MuiCard Component
|
|
334
320
|
*/
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { COLOR_MIXES } from "../../styles/common/constants/colorMixes";
|
|
2
|
+
import { PALETTE } from "../../styles/common/constants/palette";
|
|
3
|
+
import { BUTTON_GROUP_PROPS } from "../../styles/common/mui/buttonGroup";
|
|
4
|
+
const SELECTORS = {
|
|
5
|
+
GROUPED: `.${BUTTON_GROUP_PROPS.CLASSES.GROUPED}`,
|
|
6
|
+
};
|
|
7
|
+
export const MuiButtonGroup = {
|
|
8
|
+
defaultProps: {
|
|
9
|
+
disableElevation: true,
|
|
10
|
+
disableRipple: true,
|
|
11
|
+
},
|
|
12
|
+
styleOverrides: {
|
|
13
|
+
root: {
|
|
14
|
+
variants: [
|
|
15
|
+
/* PRIMARY CONTAINED */
|
|
16
|
+
{
|
|
17
|
+
props: {
|
|
18
|
+
color: BUTTON_GROUP_PROPS.COLOR.PRIMARY,
|
|
19
|
+
variant: BUTTON_GROUP_PROPS.VARIANT.CONTAINED,
|
|
20
|
+
},
|
|
21
|
+
style: {
|
|
22
|
+
[SELECTORS.GROUPED]: {
|
|
23
|
+
borderColor: PALETTE.PRIMARY_DARK,
|
|
24
|
+
boxShadow: `0 1px 0 0 ${PALETTE.PRIMARY_DARK}`,
|
|
25
|
+
minWidth: 0,
|
|
26
|
+
// eslint-disable-next-line sort-keys -- disabling key order for readability
|
|
27
|
+
"&:hover": {
|
|
28
|
+
boxShadow: `0 1px 0 0 ${PALETTE.PRIMARY_DARK}`,
|
|
29
|
+
},
|
|
30
|
+
// eslint-disable-next-line sort-keys -- disabling key order for readability
|
|
31
|
+
"&:active": {
|
|
32
|
+
boxShadow: "none",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
/* SECONDARY OUTLINED */
|
|
38
|
+
{
|
|
39
|
+
props: {
|
|
40
|
+
color: BUTTON_GROUP_PROPS.COLOR.SECONDARY,
|
|
41
|
+
variant: BUTTON_GROUP_PROPS.VARIANT.OUTLINED,
|
|
42
|
+
},
|
|
43
|
+
style: {
|
|
44
|
+
[SELECTORS.GROUPED]: {
|
|
45
|
+
backgroundColor: PALETTE.COMMON_WHITE,
|
|
46
|
+
boxShadow: `inset 0 0 0 1px ${PALETTE.SMOKE_DARK}, 0 1px 0 0 ${COLOR_MIXES.COMMON_BLACK_08}`,
|
|
47
|
+
color: PALETTE.INK_MAIN,
|
|
48
|
+
minWidth: 0,
|
|
49
|
+
// eslint-disable-next-line sort-keys -- disabling key order for readability
|
|
50
|
+
"&:hover": {
|
|
51
|
+
backgroundColor: PALETTE.SMOKE_LIGHTEST,
|
|
52
|
+
boxShadow: `inset 0 0 0 1px ${PALETTE.SMOKE_DARK}, 0 1px 0 0 ${COLOR_MIXES.COMMON_BLACK_08}`,
|
|
53
|
+
},
|
|
54
|
+
// eslint-disable-next-line sort-keys -- disabling key order for readability
|
|
55
|
+
"&:active": {
|
|
56
|
+
backgroundColor: PALETTE.SMOKE_LIGHTEST,
|
|
57
|
+
boxShadow: `inset 0 0 0 1px ${PALETTE.SMOKE_DARK}`,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
/* SMALL */
|
|
63
|
+
{
|
|
64
|
+
props: {
|
|
65
|
+
size: BUTTON_GROUP_PROPS.SIZE.SMALL,
|
|
66
|
+
},
|
|
67
|
+
style: {
|
|
68
|
+
[SELECTORS.GROUPED]: {
|
|
69
|
+
padding: "6px 8px",
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
package/lib/theme/theme.js
CHANGED
|
@@ -69,7 +69,7 @@ export function createAppTheme(customOptions = {}) {
|
|
|
69
69
|
MuiBreadcrumbs: C.MuiBreadcrumbs(theme),
|
|
70
70
|
MuiButton: C.MuiButton(theme),
|
|
71
71
|
MuiButtonBase: C.MuiButtonBase(theme),
|
|
72
|
-
MuiButtonGroup:
|
|
72
|
+
MuiButtonGroup: M.MuiButtonGroup,
|
|
73
73
|
MuiCard: C.MuiCard,
|
|
74
74
|
MuiCheckbox: C.MuiCheckbox(theme),
|
|
75
75
|
MuiChip: C.MuiChip(theme),
|
package/package.json
CHANGED
|
@@ -13,10 +13,13 @@ export function findCategoryConfig<V extends VIEW_KIND>(
|
|
|
13
13
|
viewKind: V,
|
|
14
14
|
key: Category["key"],
|
|
15
15
|
configs: CategoryConfig[]
|
|
16
|
-
): Extract<CategoryConfig, { viewKind
|
|
16
|
+
): Extract<CategoryConfig, { viewKind?: V }> | undefined {
|
|
17
17
|
return configs.find(
|
|
18
|
-
(c): c is Extract<CategoryConfig, { viewKind
|
|
19
|
-
|
|
18
|
+
(c): c is Extract<CategoryConfig, { viewKind?: V }> =>
|
|
19
|
+
// When `viewKind` is undefined, it corresponds to a `SelectCategoryConfig`.
|
|
20
|
+
// This predicate ensures that `viewKind` is either explicitly matched or treated as undefined
|
|
21
|
+
// for compatibility with `SelectCategoryConfig` and other explicitly defined view kinds.
|
|
22
|
+
(c.viewKind === undefined || c.viewKind === viewKind) && c.key === key
|
|
20
23
|
);
|
|
21
24
|
}
|
|
22
25
|
|
package/src/common/entities.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { ColumnDef, RowData } from "@tanstack/react-table";
|
|
1
|
+
import { ColumnDef, RowData, TableOptions } from "@tanstack/react-table";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Model of a value of a metadata class.
|
|
5
5
|
*/
|
|
6
6
|
export interface Attribute {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
// Prefix to fragment mapping, e.g. cxg: "batch_condition", or, general tags e.g. tier: "Tier 1" and bionetwork: ["gut"]
|
|
8
|
+
annotations?: Record<string, string | string[] | undefined>; // 'undefined' allows for mix of keys across attributes e.g. tier, or tier and cxg, or cxg
|
|
9
|
+
classKey?: string; // Programmatic class name or key (e.g. cell, sample) the attribute belongs to.
|
|
10
10
|
description: string;
|
|
11
11
|
example?: string; // Free text example of attribute
|
|
12
12
|
multivalued: boolean; // True if attribute can have multiple values
|
|
@@ -74,6 +74,7 @@ export interface DataDictionary<T extends RowData = Attribute> {
|
|
|
74
74
|
export interface DataDictionaryConfig<T extends RowData = Attribute> {
|
|
75
75
|
columnDefs: ColumnDef<T, T[keyof T]>[];
|
|
76
76
|
dataDictionary: DataDictionary<T>;
|
|
77
|
+
tableOptions?: Omit<TableOptions<T>, "columns" | "data" | "getCoreRowModel">;
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
/**
|
|
@@ -7,19 +7,15 @@ import { GRID_PROPS } from "./constants";
|
|
|
7
7
|
import { ClassesProps } from "./types";
|
|
8
8
|
|
|
9
9
|
export const Entities = <T extends RowData = Attribute>({
|
|
10
|
-
classes,
|
|
11
|
-
columnDefs,
|
|
12
10
|
spacing,
|
|
11
|
+
table,
|
|
13
12
|
}: ClassesProps<T>): JSX.Element => {
|
|
13
|
+
const { getGroupedRowModel } = table;
|
|
14
14
|
return (
|
|
15
15
|
<Grid {...GRID_PROPS}>
|
|
16
|
-
{
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class={cls}
|
|
20
|
-
columnDefs={columnDefs}
|
|
21
|
-
spacing={spacing}
|
|
22
|
-
/>
|
|
16
|
+
{/* Render grouped rows where each "group" is a class e.g. "donor" */}
|
|
17
|
+
{getGroupedRowModel().rows.map((row) => (
|
|
18
|
+
<Entity key={row.id} row={row} spacing={spacing} table={table} />
|
|
23
19
|
))}
|
|
24
20
|
</Grid>
|
|
25
21
|
);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Attribute
|
|
1
|
+
import { RowData, Table } from "@tanstack/react-table";
|
|
2
|
+
import { Attribute } from "../../../../common/entities";
|
|
3
3
|
import { LayoutSpacing } from "../../hooks/UseLayoutSpacing/types";
|
|
4
4
|
|
|
5
5
|
export interface ClassesProps<T extends RowData = Attribute> {
|
|
6
|
-
classes: Class<T>[];
|
|
7
|
-
columnDefs: ColumnDef<T, T[keyof T]>[];
|
|
8
6
|
spacing?: LayoutSpacing;
|
|
7
|
+
table: Table<T>;
|
|
9
8
|
}
|
|
@@ -2,9 +2,17 @@ import styled from "@emotion/styled";
|
|
|
2
2
|
import { Typography } from "@mui/material";
|
|
3
3
|
import { LayoutSpacing } from "../../hooks/UseLayoutSpacing/types";
|
|
4
4
|
import { ENTITIES_ROW_GAP } from "../Entities/constants";
|
|
5
|
+
import { LAYOUT_SPACING } from "../Layout/constants";
|
|
6
|
+
|
|
7
|
+
const TOP =
|
|
8
|
+
ENTITIES_ROW_GAP +
|
|
9
|
+
LAYOUT_SPACING.TITLE_HEIGHT +
|
|
10
|
+
LAYOUT_SPACING.FILTERS_HEIGHT +
|
|
11
|
+
LAYOUT_SPACING.FILTERS_PADDING_TOP +
|
|
12
|
+
LAYOUT_SPACING.CONTENT_PADDING_TOP;
|
|
5
13
|
|
|
6
14
|
export const StyledTypography = styled(Typography)<Partial<LayoutSpacing>>`
|
|
7
|
-
scroll-margin-top: ${({ top = 0 }) => top +
|
|
15
|
+
scroll-margin-top: ${({ top = 0 }) => top + TOP}px;
|
|
8
16
|
|
|
9
17
|
&:hover a {
|
|
10
18
|
opacity: 1;
|