@databiosphere/findable-ui 38.1.1 → 38.3.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 +19 -0
- package/lib/components/DataDictionary/components/Description/description.d.ts +2 -0
- package/lib/components/DataDictionary/components/Description/description.js +8 -0
- package/lib/components/DataDictionary/components/Description/description.styles.d.ts +10 -0
- package/lib/components/DataDictionary/components/Description/description.styles.js +51 -0
- package/lib/components/DataDictionary/components/Description/types.d.ts +3 -0
- package/lib/components/DataDictionary/components/Description/types.js +1 -0
- package/lib/components/DataDictionary/components/Layout/components/EntitiesLayout/entitiesLayout.styles.js +2 -0
- package/lib/components/DataDictionary/components/Table/options/expanded/constants.d.ts +1 -1
- package/lib/components/DataDictionary/components/Table/options/expanded/constants.js +1 -0
- package/lib/components/DataDictionary/dataDictionary.js +3 -1
- package/lib/components/DataDictionary/hooks/UseDataDictionaryConfig/hook.js +1 -0
- package/lib/components/DataDictionary/hooks/UseDataDictionaryConfig/types.d.ts +1 -0
- package/lib/components/Detail/components/Table/components/TableRows/tableRows.js +2 -1
- package/lib/components/Filter/components/FilterRange/filterRange.styles.js +1 -0
- package/lib/components/Links/components/Link/components/ExploreViewLink/exploreViewLink.js +2 -2
- package/lib/components/Links/components/Link/link.d.ts +0 -1
- package/lib/components/MarkdownRenderer/components/Anchor/anchor.js +6 -1
- package/lib/components/Table/components/TableCell/components/LinkCell/linkCell.js +6 -1
- package/lib/components/Table/components/TableCell/components/RowSelectionCell/rowSelectionCell.js +6 -1
- package/lib/components/Table/components/TableFeatures/RowExpanding/utils.d.ts +10 -0
- package/lib/components/Table/components/TableFeatures/RowExpanding/utils.js +22 -0
- package/lib/components/Table/components/TableRow/tableRow.styles.d.ts +2 -0
- package/lib/components/Table/components/TableRow/tableRow.styles.js +23 -5
- package/lib/components/Table/components/TableRows/tableRows.js +3 -2
- package/package.json +1 -1
- package/src/components/DataDictionary/components/Description/description.styles.ts +56 -0
- package/src/components/DataDictionary/components/Description/description.tsx +17 -0
- package/src/components/DataDictionary/components/Description/types.ts +3 -0
- package/src/components/DataDictionary/components/Layout/components/EntitiesLayout/entitiesLayout.styles.ts +2 -0
- package/src/components/DataDictionary/components/Table/options/expanded/constants.ts +2 -1
- package/src/components/DataDictionary/dataDictionary.tsx +3 -1
- package/src/components/DataDictionary/hooks/UseDataDictionaryConfig/hook.ts +1 -0
- package/src/components/DataDictionary/hooks/UseDataDictionaryConfig/types.ts +1 -0
- package/src/components/Detail/components/Table/components/TableRows/tableRows.tsx +4 -0
- package/src/components/Filter/components/FilterRange/filterRange.styles.ts +1 -0
- package/src/components/Links/components/Link/components/ExploreViewLink/exploreViewLink.tsx +2 -2
- package/src/components/Links/components/Link/link.tsx +0 -1
- package/src/components/MarkdownRenderer/components/Anchor/anchor.tsx +5 -0
- package/src/components/Table/components/TableCell/components/LinkCell/linkCell.tsx +5 -0
- package/src/components/Table/components/TableCell/components/RowSelectionCell/rowSelectionCell.tsx +5 -0
- package/src/components/Table/components/TableFeatures/RowExpanding/utils.ts +25 -0
- package/src/components/Table/components/TableRow/tableRow.styles.ts +28 -9
- package/src/components/Table/components/TableRows/tableRows.tsx +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [38.3.0](https://github.com/DataBiosphere/findable-ui/compare/v38.2.0...v38.3.0) (2025-07-22)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add table row expansion to table components ([#569](https://github.com/DataBiosphere/findable-ui/issues/569)) ([#570](https://github.com/DataBiosphere/findable-ui/issues/570)) ([d23c5b8](https://github.com/DataBiosphere/findable-ui/commit/d23c5b8c091a899295a3005ff80d7cd297949033))
|
|
9
|
+
|
|
10
|
+
## [38.2.0](https://github.com/DataBiosphere/findable-ui/compare/v38.1.1...v38.2.0) (2025-07-11)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* add 'introduction' section to data dictionary ([#566](https://github.com/DataBiosphere/findable-ui/issues/566)) ([#567](https://github.com/DataBiosphere/findable-ui/issues/567)) ([5aeb758](https://github.com/DataBiosphere/findable-ui/commit/5aeb758792532a78fa4ec71dc0f7b3ad8c80c376))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* align range filter toggle button styles with design ([#563](https://github.com/DataBiosphere/findable-ui/issues/563)) ([#564](https://github.com/DataBiosphere/findable-ui/issues/564)) ([1cc1ffd](https://github.com/DataBiosphere/findable-ui/commit/1cc1ffd88ae3b2f436717b494e425614412cface))
|
|
21
|
+
|
|
3
22
|
## [38.1.1](https://github.com/DataBiosphere/findable-ui/compare/v38.1.0...v38.1.1) (2025-07-09)
|
|
4
23
|
|
|
5
24
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { StyledMarkdownRenderer, StyledRoundedPaper, } from "./description.styles";
|
|
3
|
+
export const Description = ({ description, }) => {
|
|
4
|
+
if (!description)
|
|
5
|
+
return null;
|
|
6
|
+
return (React.createElement(StyledRoundedPaper, { elevation: 0 },
|
|
7
|
+
React.createElement(StyledMarkdownRenderer, { value: description })));
|
|
8
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const StyledRoundedPaper: import("@emotion/styled").StyledComponent<import("../../../types").BaseComponentProps & import("@mui/material").PaperOwnProps & import("@mui/material/OverridableComponent").CommonProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
|
2
|
+
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;
|
|
3
|
+
}, "style" | "className" | "classes" | "children" | "sx" | "elevation" | "square" | "variant"> & {
|
|
4
|
+
component?: React.ElementType;
|
|
5
|
+
} & {
|
|
6
|
+
theme?: import("@emotion/react").Theme;
|
|
7
|
+
}, {}, {}>;
|
|
8
|
+
export declare const StyledMarkdownRenderer: import("@emotion/styled").StyledComponent<import("../../../MarkdownRenderer/types").MarkdownRendererProps & {
|
|
9
|
+
theme?: import("@emotion/react").Theme;
|
|
10
|
+
}, {}, {}>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import styled from "@emotion/styled";
|
|
2
|
+
import { PALETTE } from "../../../../styles/common/constants/palette";
|
|
3
|
+
import { mediaTabletDown, mediaTabletUp, } from "../../../../styles/common/mixins/breakpoints";
|
|
4
|
+
import { textHeadingSmall } from "../../../../styles/common/mixins/fonts";
|
|
5
|
+
import { RoundedPaper } from "../../../common/Paper/components/RoundedPaper/roundedPaper";
|
|
6
|
+
import { MarkdownRenderer } from "../../../MarkdownRenderer/markdownRenderer";
|
|
7
|
+
export const StyledRoundedPaper = styled(RoundedPaper) `
|
|
8
|
+
padding: 20px;
|
|
9
|
+
|
|
10
|
+
${mediaTabletDown} {
|
|
11
|
+
padding: 20px 16px;
|
|
12
|
+
}
|
|
13
|
+
`;
|
|
14
|
+
export const StyledMarkdownRenderer = styled(MarkdownRenderer) `
|
|
15
|
+
align-self: flex-start;
|
|
16
|
+
|
|
17
|
+
code {
|
|
18
|
+
all: unset;
|
|
19
|
+
font: inherit;
|
|
20
|
+
font-family: Roboto Mono, monospace;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
h2,
|
|
24
|
+
h3,
|
|
25
|
+
h4,
|
|
26
|
+
h5,
|
|
27
|
+
h6 {
|
|
28
|
+
margin: 8px 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
h2 {
|
|
32
|
+
${textHeadingSmall};
|
|
33
|
+
font-size: 18px;
|
|
34
|
+
line-height: 26px;
|
|
35
|
+
|
|
36
|
+
${mediaTabletUp} {
|
|
37
|
+
font-size: 18px;
|
|
38
|
+
line-height: 26px;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
hr {
|
|
43
|
+
border: none;
|
|
44
|
+
border-bottom: 1px solid ${PALETTE.SMOKE_MAIN};
|
|
45
|
+
margin: 16px 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
p {
|
|
49
|
+
font: inherit;
|
|
50
|
+
}
|
|
51
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -4,6 +4,8 @@ import { LAYOUT_SPACING } from "../../constants";
|
|
|
4
4
|
const PB = LAYOUT_SPACING.CONTENT_PADDING_BOTTOM; /* bottom padding */
|
|
5
5
|
const PT = LAYOUT_SPACING.CONTENT_PADDING_TOP; /* top padding */
|
|
6
6
|
export const Layout = styled("div") `
|
|
7
|
+
display: grid;
|
|
8
|
+
gap: 16px;
|
|
7
9
|
grid-column: 2;
|
|
8
10
|
grid-row: 1;
|
|
9
11
|
padding-bottom: ${PB}px;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ExpandedOptions, RowData } from "@tanstack/react-table";
|
|
2
|
-
export declare const EXPANDED_OPTIONS: Pick<ExpandedOptions<RowData>, "enableExpanding" | "getExpandedRowModel">;
|
|
2
|
+
export declare const EXPANDED_OPTIONS: Pick<ExpandedOptions<RowData>, "enableExpanding" | "getExpandedRowModel" | "getRowCanExpand">;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Fade } from "@mui/material";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { useLayoutSpacing } from "../../hooks/UseLayoutSpacing/hook";
|
|
4
|
+
import { Description } from "./components/Description/description";
|
|
4
5
|
import { Entities } from "./components/Entities/entities";
|
|
5
6
|
import { ColumnFilterTags } from "./components/Filters/components/ColumnFilterTags/columnFilterTags";
|
|
6
7
|
import { Filters } from "./components/Filters/filters";
|
|
@@ -17,7 +18,7 @@ import { useDataDictionaryConfig } from "./hooks/UseDataDictionaryConfig/hook";
|
|
|
17
18
|
import { useMeasureFilters } from "./hooks/UseMeasureFilters/hook";
|
|
18
19
|
export const DataDictionary = ({ className, dictionary, EntitiesLayout = DefaultEntitiesLayout, FiltersLayout = DefaultFiltersLayout, Outline = DefaultOutline, OutlineLayout = DefaultOutlineLayout, Title = DefaultTitle, TitleLayout = DefaultTitleLayout, }) => {
|
|
19
20
|
// Get dictionary configuration.
|
|
20
|
-
const { classes, tableOptions, title } = useDataDictionaryConfig(dictionary);
|
|
21
|
+
const { classes, description, tableOptions, title } = useDataDictionaryConfig(dictionary);
|
|
21
22
|
// Layout measurements.
|
|
22
23
|
// Get header and footer dimensions.
|
|
23
24
|
const { spacing } = useLayoutSpacing();
|
|
@@ -40,5 +41,6 @@ export const DataDictionary = ({ className, dictionary, EntitiesLayout = Default
|
|
|
40
41
|
React.createElement(ColumnFilterTags, { table: table })),
|
|
41
42
|
React.createElement(Fade, { in: dimensions.height > 0 },
|
|
42
43
|
React.createElement(EntitiesLayout, { spacing: entitiesSpacing },
|
|
44
|
+
React.createElement(Description, { description: description }),
|
|
43
45
|
React.createElement(Entities, { spacing: entitiesSpacing, table: table }))))));
|
|
44
46
|
};
|
|
@@ -20,6 +20,7 @@ export const useDataDictionaryConfig = (dictionary) => {
|
|
|
20
20
|
// exists above and would have thrown an error if undefined.
|
|
21
21
|
return {
|
|
22
22
|
classes: dataDictionaryConfig.dataDictionary.classes,
|
|
23
|
+
description: dataDictionaryConfig.dataDictionary.description,
|
|
23
24
|
tableOptions: dataDictionaryConfig.tableOptions,
|
|
24
25
|
title: dataDictionaryConfig.dataDictionary.title,
|
|
25
26
|
};
|
|
@@ -2,6 +2,7 @@ import { RowData, TableOptions } from "@tanstack/react-table";
|
|
|
2
2
|
import { Attribute, Class } from "../../../../common/entities";
|
|
3
3
|
export interface UseDataDictionaryConfig<T extends RowData = Attribute> {
|
|
4
4
|
classes: Class<T>[];
|
|
5
|
+
description?: string;
|
|
5
6
|
tableOptions: Omit<TableOptions<T>, "data" | "getCoreRowModel">;
|
|
6
7
|
title: string;
|
|
7
8
|
}
|
|
@@ -2,6 +2,7 @@ import { TableCell } from "@mui/material";
|
|
|
2
2
|
import { flexRender } from "@tanstack/react-table";
|
|
3
3
|
import React, { Fragment } from "react";
|
|
4
4
|
import { getTableCellAlign, getTableCellPadding, } from "../../../../../Table/components/TableCell/common/utils";
|
|
5
|
+
import { handleToggleExpanded } from "../../../../../Table/components/TableFeatures/RowExpanding/utils";
|
|
5
6
|
import { StyledTableRow } from "../../../../../Table/components/TableRow/tableRow.styles";
|
|
6
7
|
export const TableRows = ({ rows: leafOrSubRows, tableInstance, tableView, }) => {
|
|
7
8
|
const { getRowModel } = tableInstance;
|
|
@@ -9,7 +10,7 @@ export const TableRows = ({ rows: leafOrSubRows, tableInstance, tableView, }) =>
|
|
|
9
10
|
const { tableCell } = tableView || {};
|
|
10
11
|
const { size: tableCellSize = "medium" } = tableCell || {};
|
|
11
12
|
return (React.createElement(Fragment, null, (leafOrSubRows || rows).map((row) => {
|
|
12
|
-
return (React.createElement(StyledTableRow, { key: row.id, isGrouped: row.getIsGrouped(), isPreview: row.getIsPreview() }, row.getVisibleCells().map((cell) => {
|
|
13
|
+
return (React.createElement(StyledTableRow, { key: row.id, canExpand: row.getCanExpand(), isExpanded: row.getIsExpanded(), isGrouped: row.getIsGrouped(), isPreview: row.getIsPreview(), onClick: () => handleToggleExpanded(row) }, row.getVisibleCells().map((cell) => {
|
|
13
14
|
if (cell.getIsAggregated())
|
|
14
15
|
return null; // Display of aggregated cells is currently not supported.
|
|
15
16
|
if (cell.getIsPlaceholder())
|
|
@@ -15,12 +15,12 @@ export const ExploreViewLink = ({ className, label, onClick, target = ANCHOR_TAR
|
|
|
15
15
|
const filters = getSelectedFilters(url.query);
|
|
16
16
|
const grouping = getGrouping(url.query);
|
|
17
17
|
const sorting = getSorting(url.query);
|
|
18
|
-
return (React.createElement(Link, { className: className, href: url.href, onClick: () => {
|
|
18
|
+
return (React.createElement(Link, { className: className, href: url.href, onClick: (e) => {
|
|
19
19
|
exploreDispatch({
|
|
20
20
|
payload: { entityListType, filters, grouping, sorting },
|
|
21
21
|
type: ExploreActionKind.UpdateEntityFilters,
|
|
22
22
|
});
|
|
23
|
-
onClick?.();
|
|
23
|
+
onClick?.(e);
|
|
24
24
|
}, rel: REL_ATTRIBUTE.NO_OPENER, target: target }, label));
|
|
25
25
|
};
|
|
26
26
|
/**
|
|
@@ -6,7 +6,6 @@ import { ANCHOR_TARGET, Url } from "../../common/entities";
|
|
|
6
6
|
export interface LinkProps extends BaseComponentProps, Omit<MLinkProps, "children" | "component"> {
|
|
7
7
|
copyable?: boolean;
|
|
8
8
|
label: ReactNode;
|
|
9
|
-
onClick?: () => void;
|
|
10
9
|
target?: ANCHOR_TARGET;
|
|
11
10
|
TypographyProps?: TypographyProps;
|
|
12
11
|
url: Url;
|
|
@@ -17,5 +17,10 @@ import { Link } from "../../../Links/components/Link/link";
|
|
|
17
17
|
* Note: This component currently does not support these excluded attributes.
|
|
18
18
|
*/
|
|
19
19
|
export const Anchor = (props) => {
|
|
20
|
-
return (React.createElement(Link, { className: props.className, label: props.children,
|
|
20
|
+
return (React.createElement(Link, { className: props.className, label: props.children,
|
|
21
|
+
/*
|
|
22
|
+
* Prevents click events from bubbling up to parent components
|
|
23
|
+
* (such as CardActionArea or Accordion) when the link is activated.
|
|
24
|
+
*/
|
|
25
|
+
onClick: (e) => e.stopPropagation(), url: props.href || "" }));
|
|
21
26
|
};
|
|
@@ -17,5 +17,10 @@ export const LinkCell = ({ className, getValue, }) => {
|
|
|
17
17
|
if (!isValid)
|
|
18
18
|
return (React.createElement(Typography, { className: className, color: TYPOGRAPHY_PROPS.COLOR.INHERIT, component: "span", variant: TYPOGRAPHY_PROPS.VARIANT.INHERIT, ...linkProps }, children));
|
|
19
19
|
// If the href is valid, return a Link component.
|
|
20
|
-
return (React.createElement(MLink, { className: className, color: color, component: getComponent(href, isClientSide), href: href,
|
|
20
|
+
return (React.createElement(MLink, { className: className, color: color, component: getComponent(href, isClientSide), href: href,
|
|
21
|
+
/*
|
|
22
|
+
* Prevents click events from bubbling up to parent components
|
|
23
|
+
* (such as CardActionArea or Accordion) when the link is activated.
|
|
24
|
+
*/
|
|
25
|
+
onClick: (e) => e.stopPropagation(), rel: getRelAttribute(rel, isClientSide), target: getTargetAttribute(target, isClientSide), underline: underline, ...linkProps }, children));
|
|
21
26
|
};
|
package/lib/components/Table/components/TableCell/components/RowSelectionCell/rowSelectionCell.js
CHANGED
|
@@ -4,5 +4,10 @@ import { CheckedIcon } from "../../../../../common/CustomIcon/components/Checked
|
|
|
4
4
|
import { UncheckedIcon } from "../../../../../common/CustomIcon/components/UncheckedIcon/uncheckedIcon";
|
|
5
5
|
export const RowSelectionCell = ({ row, }) => {
|
|
6
6
|
const { getIsSelected, getToggleSelectedHandler } = row;
|
|
7
|
-
return (React.createElement(MCheckbox, { checked: getIsSelected(), checkedIcon: React.createElement(CheckedIcon, null), icon: React.createElement(UncheckedIcon, null),
|
|
7
|
+
return (React.createElement(MCheckbox, { checked: getIsSelected(), checkedIcon: React.createElement(CheckedIcon, null), icon: React.createElement(UncheckedIcon, null),
|
|
8
|
+
/*
|
|
9
|
+
* Prevents click events from bubbling up to parent components
|
|
10
|
+
* (such as CardActionArea or Accordion) when the checkbox is activated.
|
|
11
|
+
*/
|
|
12
|
+
onClick: (e) => e.stopPropagation(), onChange: getToggleSelectedHandler() }));
|
|
8
13
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Row, RowData } from "@tanstack/react-table";
|
|
2
|
+
/**
|
|
3
|
+
* Handles toggling the expanded state of a row.
|
|
4
|
+
* Rows can not be expanded if:
|
|
5
|
+
* - the row can not be expanded.
|
|
6
|
+
* - the row is grouped (expanded rows are not supported on grouped rows).
|
|
7
|
+
* - the user is selecting text.
|
|
8
|
+
* @param row - Row.
|
|
9
|
+
*/
|
|
10
|
+
export declare function handleToggleExpanded<T extends RowData>(row: Row<T>): void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handles toggling the expanded state of a row.
|
|
3
|
+
* Rows can not be expanded if:
|
|
4
|
+
* - the row can not be expanded.
|
|
5
|
+
* - the row is grouped (expanded rows are not supported on grouped rows).
|
|
6
|
+
* - the user is selecting text.
|
|
7
|
+
* @param row - Row.
|
|
8
|
+
*/
|
|
9
|
+
export function handleToggleExpanded(row) {
|
|
10
|
+
const { getCanExpand, getIsGrouped, toggleExpanded } = row;
|
|
11
|
+
// Row can not be expanded.
|
|
12
|
+
if (!getCanExpand())
|
|
13
|
+
return;
|
|
14
|
+
// Row is grouped - row expansion not supported on a grouped row.
|
|
15
|
+
if (getIsGrouped())
|
|
16
|
+
return;
|
|
17
|
+
// User is selecting text - do not toggle row expanded state.
|
|
18
|
+
if (window.getSelection()?.toString())
|
|
19
|
+
return;
|
|
20
|
+
// Toggle row expanded state.
|
|
21
|
+
toggleExpanded();
|
|
22
|
+
}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { css } from "@emotion/react";
|
|
2
2
|
import styled from "@emotion/styled";
|
|
3
3
|
import { TableRow as MTableRow } from "@mui/material";
|
|
4
|
-
import {
|
|
4
|
+
import { PALETTE } from "../../../../styles/common/constants/palette";
|
|
5
5
|
import { textBodySmall500 } from "../../../../styles/common/mixins/fonts";
|
|
6
6
|
export const StyledTableRow = styled(MTableRow, {
|
|
7
|
-
shouldForwardProp: (prop) => prop !== "
|
|
7
|
+
shouldForwardProp: (prop) => prop !== "canExpand" &&
|
|
8
|
+
prop !== "isExpanded" &&
|
|
9
|
+
prop !== "isPreview" &&
|
|
10
|
+
prop !== "isGrouped",
|
|
8
11
|
}) `
|
|
9
12
|
&& {
|
|
10
13
|
transition: background-color 300ms ease-in;
|
|
11
14
|
|
|
12
15
|
${(props) => props.isGrouped &&
|
|
13
16
|
css `
|
|
14
|
-
background-color: ${
|
|
17
|
+
background-color: ${PALETTE.SMOKE_LIGHTEST};
|
|
15
18
|
|
|
16
19
|
td {
|
|
17
20
|
${textBodySmall500(props)};
|
|
@@ -20,9 +23,24 @@ export const StyledTableRow = styled(MTableRow, {
|
|
|
20
23
|
}
|
|
21
24
|
`}
|
|
22
25
|
|
|
23
|
-
${(
|
|
26
|
+
${({ canExpand, isExpanded, isGrouped }) => !isGrouped &&
|
|
27
|
+
canExpand &&
|
|
24
28
|
css `
|
|
25
|
-
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
|
|
31
|
+
&:hover {
|
|
32
|
+
background-color: #f8fbfd;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
${isExpanded &&
|
|
36
|
+
css `
|
|
37
|
+
background-color: #f8fbfd;
|
|
38
|
+
`}
|
|
39
|
+
`}
|
|
40
|
+
|
|
41
|
+
${({ isPreview }) => isPreview &&
|
|
42
|
+
css `
|
|
43
|
+
background-color: ${PALETTE.PRIMARY_LIGHTEST};
|
|
26
44
|
`}
|
|
27
45
|
}
|
|
28
46
|
`;
|
|
@@ -3,14 +3,15 @@ import { flexRender } from "@tanstack/react-table";
|
|
|
3
3
|
import React, { Fragment } from "react";
|
|
4
4
|
import { TEST_IDS } from "../../../../tests/testIds";
|
|
5
5
|
import { getTableCellAlign, getTableCellPadding, } from "../TableCell/common/utils";
|
|
6
|
+
import { handleToggleExpanded } from "../TableFeatures/RowExpanding/utils";
|
|
6
7
|
import { StyledTableRow } from "../TableRow/tableRow.styles";
|
|
7
8
|
export const TableRows = ({ rows, virtualizer, }) => {
|
|
8
9
|
const virtualItems = virtualizer.getVirtualItems();
|
|
9
10
|
return (React.createElement(Fragment, null, virtualItems.map((virtualRow) => {
|
|
10
11
|
const rowIndex = virtualRow.index;
|
|
11
12
|
const row = rows[rowIndex];
|
|
12
|
-
const { getIsGrouped, getIsPreview } = row;
|
|
13
|
-
return (React.createElement(StyledTableRow, { key: row.id, "data-index": rowIndex, isGrouped: getIsGrouped(), isPreview: getIsPreview(), ref: virtualizer.measureElement }, row.getVisibleCells().map((cell, i) => {
|
|
13
|
+
const { getCanExpand, getIsExpanded, getIsGrouped, getIsPreview } = row;
|
|
14
|
+
return (React.createElement(StyledTableRow, { key: row.id, canExpand: getCanExpand(), "data-index": rowIndex, isExpanded: getIsExpanded(), isGrouped: getIsGrouped(), isPreview: getIsPreview(), onClick: () => handleToggleExpanded(row), ref: virtualizer.measureElement }, row.getVisibleCells().map((cell, i) => {
|
|
14
15
|
if (cell.getIsAggregated())
|
|
15
16
|
return null; // Display of aggregated cells is currently not supported.
|
|
16
17
|
if (cell.getIsPlaceholder())
|
package/package.json
CHANGED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import styled from "@emotion/styled";
|
|
2
|
+
import { PALETTE } from "../../../../styles/common/constants/palette";
|
|
3
|
+
import {
|
|
4
|
+
mediaTabletDown,
|
|
5
|
+
mediaTabletUp,
|
|
6
|
+
} from "../../../../styles/common/mixins/breakpoints";
|
|
7
|
+
import { textHeadingSmall } from "../../../../styles/common/mixins/fonts";
|
|
8
|
+
import { RoundedPaper } from "../../../common/Paper/components/RoundedPaper/roundedPaper";
|
|
9
|
+
import { MarkdownRenderer } from "../../../MarkdownRenderer/markdownRenderer";
|
|
10
|
+
|
|
11
|
+
export const StyledRoundedPaper = styled(RoundedPaper)`
|
|
12
|
+
padding: 20px;
|
|
13
|
+
|
|
14
|
+
${mediaTabletDown} {
|
|
15
|
+
padding: 20px 16px;
|
|
16
|
+
}
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
export const StyledMarkdownRenderer = styled(MarkdownRenderer)`
|
|
20
|
+
align-self: flex-start;
|
|
21
|
+
|
|
22
|
+
code {
|
|
23
|
+
all: unset;
|
|
24
|
+
font: inherit;
|
|
25
|
+
font-family: Roboto Mono, monospace;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
h2,
|
|
29
|
+
h3,
|
|
30
|
+
h4,
|
|
31
|
+
h5,
|
|
32
|
+
h6 {
|
|
33
|
+
margin: 8px 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
h2 {
|
|
37
|
+
${textHeadingSmall};
|
|
38
|
+
font-size: 18px;
|
|
39
|
+
line-height: 26px;
|
|
40
|
+
|
|
41
|
+
${mediaTabletUp} {
|
|
42
|
+
font-size: 18px;
|
|
43
|
+
line-height: 26px;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
hr {
|
|
48
|
+
border: none;
|
|
49
|
+
border-bottom: 1px solid ${PALETTE.SMOKE_MAIN};
|
|
50
|
+
margin: 16px 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
p {
|
|
54
|
+
font: inherit;
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
StyledMarkdownRenderer,
|
|
4
|
+
StyledRoundedPaper,
|
|
5
|
+
} from "./description.styles";
|
|
6
|
+
import { DescriptionProps } from "./types";
|
|
7
|
+
|
|
8
|
+
export const Description = ({
|
|
9
|
+
description,
|
|
10
|
+
}: DescriptionProps): JSX.Element | null => {
|
|
11
|
+
if (!description) return null;
|
|
12
|
+
return (
|
|
13
|
+
<StyledRoundedPaper elevation={0}>
|
|
14
|
+
<StyledMarkdownRenderer value={description} />
|
|
15
|
+
</StyledRoundedPaper>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -7,6 +7,8 @@ const PB = LAYOUT_SPACING.CONTENT_PADDING_BOTTOM; /* bottom padding */
|
|
|
7
7
|
const PT = LAYOUT_SPACING.CONTENT_PADDING_TOP; /* top padding */
|
|
8
8
|
|
|
9
9
|
export const Layout = styled("div")<LayoutSpacing>`
|
|
10
|
+
display: grid;
|
|
11
|
+
gap: 16px;
|
|
10
12
|
grid-column: 2;
|
|
11
13
|
grid-row: 1;
|
|
12
14
|
padding-bottom: ${PB}px;
|
|
@@ -6,8 +6,9 @@ import {
|
|
|
6
6
|
|
|
7
7
|
export const EXPANDED_OPTIONS: Pick<
|
|
8
8
|
ExpandedOptions<RowData>,
|
|
9
|
-
"enableExpanding" | "getExpandedRowModel"
|
|
9
|
+
"enableExpanding" | "getExpandedRowModel" | "getRowCanExpand"
|
|
10
10
|
> = {
|
|
11
11
|
enableExpanding: true,
|
|
12
12
|
getExpandedRowModel: getExpandedRowModel(),
|
|
13
|
+
getRowCanExpand: () => true,
|
|
13
14
|
};
|
|
@@ -3,6 +3,7 @@ import { RowData } from "@tanstack/react-table";
|
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { Attribute } from "../../common/entities";
|
|
5
5
|
import { useLayoutSpacing } from "../../hooks/UseLayoutSpacing/hook";
|
|
6
|
+
import { Description } from "./components/Description/description";
|
|
6
7
|
import { Entities } from "./components/Entities/entities";
|
|
7
8
|
import { ColumnFilterTags } from "./components/Filters/components/ColumnFilterTags/columnFilterTags";
|
|
8
9
|
import { Filters } from "./components/Filters/filters";
|
|
@@ -30,7 +31,7 @@ export const DataDictionary = <T extends RowData = Attribute>({
|
|
|
30
31
|
TitleLayout = DefaultTitleLayout,
|
|
31
32
|
}: DataDictionaryProps): JSX.Element => {
|
|
32
33
|
// Get dictionary configuration.
|
|
33
|
-
const { classes, tableOptions, title } =
|
|
34
|
+
const { classes, description, tableOptions, title } =
|
|
34
35
|
useDataDictionaryConfig<T>(dictionary);
|
|
35
36
|
|
|
36
37
|
// Layout measurements.
|
|
@@ -64,6 +65,7 @@ export const DataDictionary = <T extends RowData = Attribute>({
|
|
|
64
65
|
<Fade in={dimensions.height > 0}>
|
|
65
66
|
{/* Fade in entities when filters are measured. */}
|
|
66
67
|
<EntitiesLayout spacing={entitiesSpacing}>
|
|
68
|
+
<Description description={description} />
|
|
67
69
|
<Entities spacing={entitiesSpacing} table={table} />
|
|
68
70
|
</EntitiesLayout>
|
|
69
71
|
</Fade>
|
|
@@ -31,6 +31,7 @@ export const useDataDictionaryConfig = <T extends RowData = Attribute>(
|
|
|
31
31
|
// exists above and would have thrown an error if undefined.
|
|
32
32
|
return {
|
|
33
33
|
classes: dataDictionaryConfig!.dataDictionary.classes,
|
|
34
|
+
description: dataDictionaryConfig!.dataDictionary.description,
|
|
34
35
|
tableOptions: dataDictionaryConfig!.tableOptions,
|
|
35
36
|
title: dataDictionaryConfig!.dataDictionary.title,
|
|
36
37
|
};
|
|
@@ -3,6 +3,7 @@ import { Attribute, Class } from "../../../../common/entities";
|
|
|
3
3
|
|
|
4
4
|
export interface UseDataDictionaryConfig<T extends RowData = Attribute> {
|
|
5
5
|
classes: Class<T>[];
|
|
6
|
+
description?: string;
|
|
6
7
|
tableOptions: Omit<TableOptions<T>, "data" | "getCoreRowModel">;
|
|
7
8
|
title: string;
|
|
8
9
|
}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
getTableCellAlign,
|
|
6
6
|
getTableCellPadding,
|
|
7
7
|
} from "../../../../../Table/components/TableCell/common/utils";
|
|
8
|
+
import { handleToggleExpanded } from "../../../../../Table/components/TableFeatures/RowExpanding/utils";
|
|
8
9
|
import { StyledTableRow } from "../../../../../Table/components/TableRow/tableRow.styles";
|
|
9
10
|
import { TableView } from "../../table";
|
|
10
11
|
|
|
@@ -34,8 +35,11 @@ export const TableRows = <T extends RowData>({
|
|
|
34
35
|
return (
|
|
35
36
|
<StyledTableRow
|
|
36
37
|
key={row.id}
|
|
38
|
+
canExpand={row.getCanExpand()}
|
|
39
|
+
isExpanded={row.getIsExpanded()}
|
|
37
40
|
isGrouped={row.getIsGrouped()}
|
|
38
41
|
isPreview={row.getIsPreview()}
|
|
42
|
+
onClick={() => handleToggleExpanded(row)}
|
|
39
43
|
>
|
|
40
44
|
{row.getVisibleCells().map((cell) => {
|
|
41
45
|
if (cell.getIsAggregated()) return null; // Display of aggregated cells is currently not supported.
|
|
@@ -46,12 +46,12 @@ export const ExploreViewLink = ({
|
|
|
46
46
|
<Link
|
|
47
47
|
className={className}
|
|
48
48
|
href={url.href}
|
|
49
|
-
onClick={(): void => {
|
|
49
|
+
onClick={(e): void => {
|
|
50
50
|
exploreDispatch({
|
|
51
51
|
payload: { entityListType, filters, grouping, sorting },
|
|
52
52
|
type: ExploreActionKind.UpdateEntityFilters,
|
|
53
53
|
});
|
|
54
|
-
onClick?.();
|
|
54
|
+
onClick?.(e);
|
|
55
55
|
}}
|
|
56
56
|
rel={REL_ATTRIBUTE.NO_OPENER}
|
|
57
57
|
target={target}
|
|
@@ -22,7 +22,6 @@ export interface LinkProps
|
|
|
22
22
|
Omit<MLinkProps, "children" | "component"> {
|
|
23
23
|
copyable?: boolean;
|
|
24
24
|
label: ReactNode /* link label may be an element */;
|
|
25
|
-
onClick?: () => void;
|
|
26
25
|
target?: ANCHOR_TARGET;
|
|
27
26
|
TypographyProps?: TypographyProps;
|
|
28
27
|
url: Url /* url specified as UrlObject with href and query defined, and is currently only used for internal links */;
|
|
@@ -28,6 +28,11 @@ export const Anchor = (
|
|
|
28
28
|
<Link
|
|
29
29
|
className={props.className}
|
|
30
30
|
label={props.children}
|
|
31
|
+
/*
|
|
32
|
+
* Prevents click events from bubbling up to parent components
|
|
33
|
+
* (such as CardActionArea or Accordion) when the link is activated.
|
|
34
|
+
*/
|
|
35
|
+
onClick={(e) => e.stopPropagation()}
|
|
31
36
|
url={props.href || ""}
|
|
32
37
|
/>
|
|
33
38
|
);
|
|
@@ -53,6 +53,11 @@ export const LinkCell = <
|
|
|
53
53
|
color={color}
|
|
54
54
|
component={getComponent(href, isClientSide)}
|
|
55
55
|
href={href}
|
|
56
|
+
/*
|
|
57
|
+
* Prevents click events from bubbling up to parent components
|
|
58
|
+
* (such as CardActionArea or Accordion) when the link is activated.
|
|
59
|
+
*/
|
|
60
|
+
onClick={(e) => e.stopPropagation()}
|
|
56
61
|
rel={getRelAttribute(rel, isClientSide)}
|
|
57
62
|
target={getTargetAttribute(target, isClientSide)}
|
|
58
63
|
underline={underline}
|
package/src/components/Table/components/TableCell/components/RowSelectionCell/rowSelectionCell.tsx
CHANGED
|
@@ -13,6 +13,11 @@ export const RowSelectionCell = <T extends RowData, TValue = unknown>({
|
|
|
13
13
|
checked={getIsSelected()}
|
|
14
14
|
checkedIcon={<CheckedIcon />}
|
|
15
15
|
icon={<UncheckedIcon />}
|
|
16
|
+
/*
|
|
17
|
+
* Prevents click events from bubbling up to parent components
|
|
18
|
+
* (such as CardActionArea or Accordion) when the checkbox is activated.
|
|
19
|
+
*/
|
|
20
|
+
onClick={(e) => e.stopPropagation()}
|
|
16
21
|
onChange={getToggleSelectedHandler()}
|
|
17
22
|
/>
|
|
18
23
|
);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Row, RowData } from "@tanstack/react-table";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Handles toggling the expanded state of a row.
|
|
5
|
+
* Rows can not be expanded if:
|
|
6
|
+
* - the row can not be expanded.
|
|
7
|
+
* - the row is grouped (expanded rows are not supported on grouped rows).
|
|
8
|
+
* - the user is selecting text.
|
|
9
|
+
* @param row - Row.
|
|
10
|
+
*/
|
|
11
|
+
export function handleToggleExpanded<T extends RowData>(row: Row<T>): void {
|
|
12
|
+
const { getCanExpand, getIsGrouped, toggleExpanded } = row;
|
|
13
|
+
|
|
14
|
+
// Row can not be expanded.
|
|
15
|
+
if (!getCanExpand()) return;
|
|
16
|
+
|
|
17
|
+
// Row is grouped - row expansion not supported on a grouped row.
|
|
18
|
+
if (getIsGrouped()) return;
|
|
19
|
+
|
|
20
|
+
// User is selecting text - do not toggle row expanded state.
|
|
21
|
+
if (window.getSelection()?.toString()) return;
|
|
22
|
+
|
|
23
|
+
// Toggle row expanded state.
|
|
24
|
+
toggleExpanded();
|
|
25
|
+
}
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { css } from "@emotion/react";
|
|
2
2
|
import styled from "@emotion/styled";
|
|
3
3
|
import { TableRow as MTableRow } from "@mui/material";
|
|
4
|
-
import {
|
|
5
|
-
primaryLightest,
|
|
6
|
-
smokeLightest,
|
|
7
|
-
} from "../../../../styles/common/mixins/colors";
|
|
4
|
+
import { PALETTE } from "../../../../styles/common/constants/palette";
|
|
8
5
|
import { textBodySmall500 } from "../../../../styles/common/mixins/fonts";
|
|
9
6
|
|
|
10
7
|
export interface StyledTableRowProps {
|
|
8
|
+
canExpand?: boolean;
|
|
9
|
+
isExpanded?: boolean;
|
|
11
10
|
isGrouped?: boolean;
|
|
12
11
|
isPreview?: boolean;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
export const StyledTableRow = styled(MTableRow, {
|
|
16
|
-
shouldForwardProp: (prop) =>
|
|
15
|
+
shouldForwardProp: (prop) =>
|
|
16
|
+
prop !== "canExpand" &&
|
|
17
|
+
prop !== "isExpanded" &&
|
|
18
|
+
prop !== "isPreview" &&
|
|
19
|
+
prop !== "isGrouped",
|
|
17
20
|
})<StyledTableRowProps>`
|
|
18
21
|
&& {
|
|
19
22
|
transition: background-color 300ms ease-in;
|
|
@@ -21,7 +24,7 @@ export const StyledTableRow = styled(MTableRow, {
|
|
|
21
24
|
${(props) =>
|
|
22
25
|
props.isGrouped &&
|
|
23
26
|
css`
|
|
24
|
-
background-color: ${
|
|
27
|
+
background-color: ${PALETTE.SMOKE_LIGHTEST};
|
|
25
28
|
|
|
26
29
|
td {
|
|
27
30
|
${textBodySmall500(props)};
|
|
@@ -30,10 +33,26 @@ export const StyledTableRow = styled(MTableRow, {
|
|
|
30
33
|
}
|
|
31
34
|
`}
|
|
32
35
|
|
|
33
|
-
${(
|
|
34
|
-
|
|
36
|
+
${({ canExpand, isExpanded, isGrouped }) =>
|
|
37
|
+
!isGrouped &&
|
|
38
|
+
canExpand &&
|
|
39
|
+
css`
|
|
40
|
+
cursor: pointer;
|
|
41
|
+
|
|
42
|
+
&:hover {
|
|
43
|
+
background-color: #f8fbfd;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
${isExpanded &&
|
|
47
|
+
css`
|
|
48
|
+
background-color: #f8fbfd;
|
|
49
|
+
`}
|
|
50
|
+
`}
|
|
51
|
+
|
|
52
|
+
${({ isPreview }) =>
|
|
53
|
+
isPreview &&
|
|
35
54
|
css`
|
|
36
|
-
background-color: ${
|
|
55
|
+
background-color: ${PALETTE.PRIMARY_LIGHTEST};
|
|
37
56
|
`}
|
|
38
57
|
}
|
|
39
58
|
`;
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
getTableCellAlign,
|
|
8
8
|
getTableCellPadding,
|
|
9
9
|
} from "../TableCell/common/utils";
|
|
10
|
+
import { handleToggleExpanded } from "../TableFeatures/RowExpanding/utils";
|
|
10
11
|
import { StyledTableRow } from "../TableRow/tableRow.styles";
|
|
11
12
|
|
|
12
13
|
export interface TableRowsProps<T extends RowData> {
|
|
@@ -24,13 +25,16 @@ export const TableRows = <T extends RowData>({
|
|
|
24
25
|
{virtualItems.map((virtualRow) => {
|
|
25
26
|
const rowIndex = virtualRow.index;
|
|
26
27
|
const row = rows[rowIndex] as Row<T>;
|
|
27
|
-
const { getIsGrouped, getIsPreview } = row;
|
|
28
|
+
const { getCanExpand, getIsExpanded, getIsGrouped, getIsPreview } = row;
|
|
28
29
|
return (
|
|
29
30
|
<StyledTableRow
|
|
30
31
|
key={row.id}
|
|
32
|
+
canExpand={getCanExpand()}
|
|
31
33
|
data-index={rowIndex}
|
|
34
|
+
isExpanded={getIsExpanded()}
|
|
32
35
|
isGrouped={getIsGrouped()}
|
|
33
36
|
isPreview={getIsPreview()}
|
|
37
|
+
onClick={() => handleToggleExpanded(row)}
|
|
34
38
|
ref={virtualizer.measureElement}
|
|
35
39
|
>
|
|
36
40
|
{row.getVisibleCells().map((cell, i) => {
|