@ansible/ansible-ui-framework 0.0.232 → 0.0.234
Sign up to get free protection for your applications and to get access to all the features.
- package/cjs/BulkActionDialog.js +2 -2
- package/cjs/PageBody.js +1 -1
- package/cjs/PageDataList.js +1 -2
- package/cjs/PageHeader.js +2 -2
- package/cjs/PageTable.js +32 -8
- package/cjs/PageTableCard.js +87 -0
- package/cjs/PageTableCards.js +38 -0
- package/cjs/PageTableList.js +79 -0
- package/cjs/PageTableViewType.js +9 -0
- package/cjs/PageToolbar.js +25 -1
- package/cjs/TypedActions/TypedActions.js +13 -4
- package/cjs/components/Details.js +2 -1
- package/cjs/components/patternfly-colors.js +11 -1
- package/cjs/index.js +1 -1
- package/mjs/BulkActionDialog.js +2 -2
- package/mjs/PageBody.d.ts +1 -0
- package/mjs/PageBody.js +1 -1
- package/mjs/PageDataList.js +1 -2
- package/mjs/PageHeader.d.ts +1 -0
- package/mjs/PageHeader.js +2 -2
- package/mjs/PageTable.d.ts +10 -1
- package/mjs/PageTable.js +28 -7
- package/mjs/PageTableCard.d.ts +33 -0
- package/mjs/PageTableCard.js +69 -0
- package/mjs/PageTableCards.d.ts +4 -0
- package/mjs/PageTableCards.js +23 -0
- package/mjs/PageTableList.d.ts +6 -0
- package/mjs/PageTableList.js +62 -0
- package/mjs/PageTableViewType.d.ts +6 -0
- package/mjs/PageTableViewType.js +6 -0
- package/mjs/PageToolbar.d.ts +3 -0
- package/mjs/PageToolbar.js +27 -3
- package/mjs/TypedActions/TypedActions.d.ts +3 -0
- package/mjs/TypedActions/TypedActions.js +14 -5
- package/mjs/components/Details.d.ts +1 -1
- package/mjs/components/Details.js +2 -2
- package/mjs/components/patternfly-colors.d.ts +10 -0
- package/mjs/components/patternfly-colors.js +10 -0
- package/mjs/index.d.ts +1 -1
- package/mjs/index.js +1 -1
- package/package.json +1 -1
- package/cjs/PageCatalog.js +0 -178
- package/mjs/PageCatalog.d.ts +0 -113
- package/mjs/PageCatalog.js +0 -140
package/mjs/PageHeader.js
CHANGED
@@ -59,7 +59,7 @@ export function PageHeader(props) {
|
|
59
59
|
borderTop: settings.theme !== 'light' && settings.borders
|
60
60
|
? 'thin solid var(--pf-global--BorderColor--100)'
|
61
61
|
: undefined,
|
62
|
-
borderBottom: settings.borders
|
62
|
+
borderBottom: !props.disableBorderBottom && settings.borders
|
63
63
|
? 'thin solid var(--pf-global--BorderColor--100)'
|
64
64
|
: undefined,
|
65
65
|
backgroundColor: 'var(--pf-global--BackgroundColor--100)',
|
@@ -69,7 +69,7 @@ export function PageHeader(props) {
|
|
69
69
|
borderTop: !navigation && settings.theme !== 'light' && settings.borders
|
70
70
|
? 'thin solid var(--pf-global--BorderColor--100)'
|
71
71
|
: undefined,
|
72
|
-
borderBottom: settings.borders
|
72
|
+
borderBottom: !props.disableBorderBottom && settings.borders
|
73
73
|
? 'thin solid var(--pf-global--BorderColor--100)'
|
74
74
|
: undefined,
|
75
75
|
backgroundColor: settings.theme === 'dark'
|
package/mjs/PageTable.d.ts
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import { Dispatch, ReactNode, SetStateAction } from 'react';
|
2
2
|
import { PageHeaderProps } from './PageHeader';
|
3
|
+
import { PageTableViewType } from './PageTableViewType';
|
3
4
|
import { IToolbarFilter } from './PageToolbar';
|
4
5
|
import { ITypedAction } from './TypedActions';
|
5
6
|
export declare type TablePageProps<T extends object> = PageHeaderProps & PageTableProps<T> & {
|
@@ -43,7 +44,12 @@ export declare type PageTableProps<T extends object> = {
|
|
43
44
|
emptyStateButtonClick?: () => void;
|
44
45
|
t?: (t: string) => string;
|
45
46
|
showSelect?: boolean;
|
46
|
-
|
47
|
+
disableTableView?: boolean;
|
48
|
+
disableListView?: boolean;
|
49
|
+
disableCardView?: boolean;
|
50
|
+
defaultTableView?: PageTableViewType;
|
51
|
+
disableBodyPadding?: boolean;
|
52
|
+
defaultCardSubtitle?: ReactNode;
|
47
53
|
};
|
48
54
|
export declare function PageTable<T extends object>(props: PageTableProps<T>): JSX.Element;
|
49
55
|
declare type CellFn<T extends object> = (item: T) => ReactNode;
|
@@ -64,5 +70,8 @@ export interface ITableColumn<T extends object> {
|
|
64
70
|
* @deprecated The method should not be used
|
65
71
|
*/
|
66
72
|
sortFn?: (l: T, r: T) => number;
|
73
|
+
card?: 'description' | 'hidden';
|
74
|
+
list?: 'primary' | 'secondary';
|
75
|
+
hideLabel?: boolean;
|
67
76
|
}
|
68
77
|
export {};
|
package/mjs/PageTable.js
CHANGED
@@ -4,19 +4,41 @@ import { ExclamationCircleIcon, PlusCircleIcon, SearchIcon } from '@patternfly/r
|
|
4
4
|
import { ActionsColumn, TableComposable, Tbody, Td, Th, Thead, Tr, } from '@patternfly/react-table';
|
5
5
|
import useResizeObserver from '@react-hook/resize-observer';
|
6
6
|
import { Fragment, useCallback, useEffect, useRef, useState, } from 'react';
|
7
|
+
import { Scrollable } from './components/Scrollable';
|
7
8
|
import { useBreakpoint } from './components/useBreakPoint';
|
8
9
|
import { PageBody } from './PageBody';
|
9
10
|
import { useColumnModal } from './PageColumnModal';
|
10
11
|
import { PageHeader } from './PageHeader';
|
11
12
|
import { PageLayout } from './PageLayout';
|
12
13
|
import { PagePagination } from './PagePagination';
|
14
|
+
import { PageTableCards } from './PageTableCards';
|
15
|
+
import { PageTableList } from './PageTableList';
|
16
|
+
import { PageTableViewTypeE } from './PageTableViewType';
|
13
17
|
import { PageTableToolbar } from './PageToolbar';
|
14
18
|
import { useSettings } from './Settings';
|
15
19
|
import { TypedActionType, useTypedActionsToTableActions } from './TypedActions';
|
16
20
|
export function TablePage(props) {
|
17
|
-
return (
|
21
|
+
return (_jsxs(PageLayout, { children: [_jsx(PageHeader, { ...props }), _jsx(PageTable, { ...props })] }));
|
18
22
|
}
|
19
23
|
export function PageTable(props) {
|
24
|
+
let { disableBodyPadding } = props;
|
25
|
+
disableBodyPadding = true;
|
26
|
+
const { toolbarActions } = props;
|
27
|
+
const { openColumnModal, columnModal, managedColumns } = useColumnModal(props.tableColumns);
|
28
|
+
const showSelect = toolbarActions?.find((toolbarAction) => TypedActionType.bulk === toolbarAction.type) !==
|
29
|
+
undefined;
|
30
|
+
const hasTableViewType = !props.disableTableView;
|
31
|
+
const hasListViewType = !props.disableListView;
|
32
|
+
// const hasCardViewType = !props.disableCardView
|
33
|
+
const [viewType, setViewType] = useState(() => props.defaultTableView ??
|
34
|
+
(hasTableViewType
|
35
|
+
? PageTableViewTypeE.Table
|
36
|
+
: hasListViewType
|
37
|
+
? PageTableViewTypeE.List
|
38
|
+
: PageTableViewTypeE.Cards));
|
39
|
+
return (_jsxs(_Fragment, { children: [_jsx(PageTableToolbar, { ...props, openColumnModal: openColumnModal, showSelect: showSelect, viewType: viewType, setViewType: setViewType }), viewType === PageTableViewTypeE.Table && (_jsx(PageBody, { disablePadding: disableBodyPadding, children: _jsx(PageTableView, { ...props, tableColumns: managedColumns }) })), viewType === PageTableViewTypeE.List && (_jsx(PageBody, { disablePadding: true, children: _jsx(Scrollable, { children: _jsx(PageTableList, { ...props, showSelect: showSelect }) }) })), viewType === PageTableViewTypeE.Cards && (_jsx(Scrollable, { children: _jsx(PageTableCards, { ...props, showSelect: showSelect }) })), (!props.autoHidePagination || (props.itemCount ?? 0) > props.perPage) && (_jsx(PagePagination, { ...props })), columnModal] }));
|
40
|
+
}
|
41
|
+
function PageTableView(props) {
|
20
42
|
const { tableColumns, pageItems, selectItem, unselectItem, isSelected, keyFn, rowActions, toolbarActions, itemCount, perPage, clearAllFilters, filters, error, onSelect, unselectAll, } = props;
|
21
43
|
let { t } = props;
|
22
44
|
t = t ? t : (t) => t;
|
@@ -44,7 +66,6 @@ export function PageTable(props) {
|
|
44
66
|
useResizeObserver(containerRef, () => updateScroll(containerRef.current));
|
45
67
|
useEffect(() => updateScroll(containerRef.current), [updateScroll]);
|
46
68
|
const settings = useSettings();
|
47
|
-
const { openColumnModal, columnModal, managedColumns } = useColumnModal(tableColumns);
|
48
69
|
if (error) {
|
49
70
|
return (_jsx("div", { style: {
|
50
71
|
backgroundColor: settings.theme === 'dark' ? 'var(--pf-global--BackgroundColor--300)' : undefined,
|
@@ -56,11 +77,11 @@ export function PageTable(props) {
|
|
56
77
|
if (itemCount === 0 && Object.keys(filters ?? {}).length === 0) {
|
57
78
|
return (_jsxs(EmptyState, { variant: EmptyStateVariant.large, style: { paddingTop: 64 }, children: [_jsx(EmptyStateIcon, { icon: PlusCircleIcon }), _jsx(Title, { headingLevel: "h4", size: "lg", children: props.emptyStateTitle }), props.emptyStateDescription && (_jsx(EmptyStateBody, { children: props.emptyStateDescription })), props.emptyStateButtonClick && (_jsx(Button, { variant: "primary", onClick: props.emptyStateButtonClick, children: props.emptyStateButtonText }))] }));
|
58
79
|
}
|
59
|
-
return (_jsxs(
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
80
|
+
return (_jsxs("div", { className: "pf-c-scroll-inner-wrapper", style: { height: '100%', marginBottom: -1 }, ref: containerRef, onScroll: onScroll, children: [_jsxs(TableComposable, { "aria-label": "Simple table", variant: props.compact ? 'compact' : settings.tableLayout === 'compact' ? 'compact' : undefined, gridBreakPoint: "", isStickyHeader: true, children: [itemCount === undefined ? (_jsx(Thead, { children: _jsx(Tr, { children: _jsx(Th, { children: _jsx(Skeleton, {}) }) }) })) : (_jsx(TableHead, { ...props, showSelect: showSelect, scrollLeft: scroll.left > 0, scrollRight: scroll.right > 1, tableColumns: tableColumns, onSelect: onSelect })), _jsx(Tbody, { children: itemCount === undefined
|
81
|
+
? new Array(perPage).fill(0).map((_, index) => (_jsx(Tr, { children: _jsx(Td, { children: _jsx("div", { style: { paddingTop: 5, paddingBottom: 5 }, children: _jsx(Skeleton, { height: "27px" }) }) }) }, index)))
|
82
|
+
: pageItems === undefined
|
83
|
+
? new Array(Math.min(perPage, itemCount)).fill(0).map((_, index) => (_jsxs(Tr, { children: [showSelect && _jsx(Td, {}), _jsx(Td, { colSpan: tableColumns.length, children: _jsx("div", { style: { paddingTop: 5, paddingBottom: 5 }, children: _jsx(Skeleton, { height: "27px" }) }) })] }, index)))
|
84
|
+
: pageItems?.map((item, rowIndex) => (_jsx(TableRow, { columns: tableColumns, item: item, isItemSelected: isSelected?.(item), selectItem: selectItem, unselectItem: unselectItem, rowActions: rowActions, rowIndex: rowIndex, showSelect: showSelect, scrollLeft: scroll.left > 0, scrollRight: scroll.right > 1, unselectAll: unselectAll, onSelect: onSelect }, keyFn ? keyFn(item) : rowIndex))) })] }), itemCount === 0 && (_jsx("div", { style: { margin: 'auto' }, children: _jsxs(EmptyState, { children: [_jsx(EmptyStateIcon, { icon: SearchIcon }), _jsx(Title, { headingLevel: "h2", size: "lg", children: t('No results found') }), _jsx(EmptyStateBody, { children: t('No results match this filter criteria. Adjust your filters and try again.') }), clearAllFilters && (_jsx(EmptyStateSecondaryActions, { children: _jsx(Button, { variant: "link", onClick: clearAllFilters, children: t('Clear all filters') }) }))] }) }))] }));
|
64
85
|
}
|
65
86
|
function TableHead(props) {
|
66
87
|
const { tableColumns: columns, rowActions: itemActions, sort, setSort, sortDirection, setSortDirection, showSelect, onSelect, } = props;
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import { ReactNode } from 'react';
|
2
|
+
import { LabelColor } from './components/patternfly-colors';
|
3
|
+
import { ITableColumn } from './PageTable';
|
4
|
+
import { ITypedAction } from './TypedActions';
|
5
|
+
export interface IPageTableCard {
|
6
|
+
id: string | number;
|
7
|
+
icon?: ReactNode;
|
8
|
+
title: ReactNode;
|
9
|
+
description?: ReactNode;
|
10
|
+
cardBody: ReactNode;
|
11
|
+
labels?: {
|
12
|
+
label: string;
|
13
|
+
color?: LabelColor;
|
14
|
+
}[];
|
15
|
+
badge?: string;
|
16
|
+
badgeColor?: LabelColor;
|
17
|
+
badgeTooltip?: string;
|
18
|
+
badgeTooltipTitle?: string;
|
19
|
+
alertTitle?: string;
|
20
|
+
alertContent?: ReactNode;
|
21
|
+
alertVariant?: 'success' | 'danger' | 'warning' | 'info' | 'default';
|
22
|
+
}
|
23
|
+
export declare function PageTableCard<T extends object>(props: {
|
24
|
+
item: T;
|
25
|
+
itemToCardFn: (item: T) => IPageTableCard;
|
26
|
+
isSelected?: (item: T) => boolean;
|
27
|
+
selectItem?: (item: T) => void;
|
28
|
+
unselectItem?: (item: T) => void;
|
29
|
+
itemActions?: ITypedAction<T>[];
|
30
|
+
showSelect?: boolean;
|
31
|
+
defaultCardSubtitle?: ReactNode;
|
32
|
+
}): JSX.Element;
|
33
|
+
export declare function useColumnsToTableCardFn<T extends object>(columns: ITableColumn<T>[], keyFn: (item: T) => string | number): (item: T) => IPageTableCard;
|
@@ -0,0 +1,69 @@
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
3
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
4
|
+
import { Alert, Card, CardActions, CardBody, CardFooter, CardHeader, CardTitle, Checkbox, DescriptionList, DropdownPosition, Label, LabelGroup, Popover, Split, SplitItem, Stack, Text, Truncate, } from '@patternfly/react-core';
|
5
|
+
import { useCallback, useMemo } from 'react';
|
6
|
+
import { Detail } from './components/Details';
|
7
|
+
import { IconWrapper } from './components/IconWrapper';
|
8
|
+
import { TypedActions } from './TypedActions';
|
9
|
+
export function PageTableCard(props) {
|
10
|
+
const { item, itemToCardFn, isSelected, selectItem, unselectItem, itemActions, showSelect, defaultCardSubtitle, } = props;
|
11
|
+
const card = useMemo(() => itemToCardFn(item), [item, itemToCardFn]);
|
12
|
+
const isItemSelected = !!isSelected?.(item);
|
13
|
+
const onSelectClick = useCallback(() => {
|
14
|
+
if (isSelected?.(item)) {
|
15
|
+
unselectItem?.(item);
|
16
|
+
}
|
17
|
+
else {
|
18
|
+
selectItem?.(item);
|
19
|
+
}
|
20
|
+
}, [isSelected, item, selectItem, unselectItem]);
|
21
|
+
const showDropdown = itemActions !== undefined && itemActions.length > 0;
|
22
|
+
const showActions = showSelect || showDropdown;
|
23
|
+
return (_jsxs(Card, { id: card.id, isFlat: true, isLarge: true, isRounded: true, isSelectable: isItemSelected, isSelected: isItemSelected, style: {
|
24
|
+
transition: 'box-shadow 0.25s',
|
25
|
+
cursor: 'default',
|
26
|
+
}, children: [_jsxs(CardHeader, { children: [_jsxs(Split, { hasGutter: true, style: { width: '100%' }, children: [_jsx(SplitItem, { isFilled: true, children: _jsxs("div", { style: { display: 'flex', alignItems: 'center' }, children: [card.icon && (_jsx("div", { style: {
|
27
|
+
display: 'flex',
|
28
|
+
height: 40,
|
29
|
+
width: 40,
|
30
|
+
marginTop: -20,
|
31
|
+
marginBottom: -20,
|
32
|
+
marginRight: 12,
|
33
|
+
alignItems: 'center',
|
34
|
+
justifyItems: 'stretch',
|
35
|
+
}, children: _jsx(IconWrapper, { size: "lg", children: card.icon }) })), _jsxs(Stack, { children: [_jsx(CardTitle, { children: card.title }), card.description ? (_jsx(Text, { component: "small", style: { opacity: 0.7 }, children: card.description })) : (defaultCardSubtitle && _jsx(Text, { component: "small", children: defaultCardSubtitle }))] })] }) }), card.badge && card.badgeTooltip && (_jsx(SplitItem, { children: _jsx("div", { onClick: (e) => e.stopPropagation(), children: _jsx(Popover, { headerContent: card.badgeTooltipTitle, bodyContent: card.badgeTooltip, removeFindDomNode: true, children: _jsx(Label, { color: card.badgeColor, children: card.badge }) }) }) })), card.badge && !card.badgeTooltip && (_jsx(SplitItem, { children: _jsx(Label, { color: card.badgeColor, children: card.badge }) }))] }), showActions && (_jsxs(CardActions, { children: [itemActions && itemActions.length && (_jsx(TypedActions, { actions: itemActions, position: DropdownPosition.right, selectedItem: item })), showSelect && (_jsx(Checkbox, { isChecked: isSelected?.(item), onChange: onSelectClick,
|
36
|
+
// aria-label="card checkbox example"
|
37
|
+
id: "check-1" }))] }))] }), card.cardBody, card.labels && (_jsx(CardFooter, { children: _jsx("div", { style: {
|
38
|
+
display: 'flex',
|
39
|
+
flexDirection: 'row',
|
40
|
+
alignItems: 'end',
|
41
|
+
gap: 16,
|
42
|
+
}, children: _jsx("div", { style: { flexGrow: 1 }, children: card.labels && (_jsx(LabelGroup, { children: card.labels.map((item) => (_jsx(Label, { color: item.color, children: _jsx(Truncate, { content: item.label, style: { minWidth: 0 } }) }, item.label))) })) }) }) })), card.alertTitle && (_jsx(Alert, { title: card.alertTitle, isInline: true, variant: card.alertVariant, children: card.alertContent }))] }, card.id ?? card.title));
|
43
|
+
}
|
44
|
+
export function useColumnsToTableCardFn(columns, keyFn) {
|
45
|
+
const cardData = useMemo(() => {
|
46
|
+
let cols = columns.filter((column) => column.card !== 'hidden');
|
47
|
+
const nameColumn = cols.shift();
|
48
|
+
const descriptionColumn = cols.find((column) => column.card === 'description');
|
49
|
+
if (descriptionColumn) {
|
50
|
+
cols = cols.filter((column) => column !== descriptionColumn);
|
51
|
+
}
|
52
|
+
return {
|
53
|
+
nameColumn: nameColumn,
|
54
|
+
descriptionColumn: descriptionColumn,
|
55
|
+
columns: cols,
|
56
|
+
};
|
57
|
+
}, [columns]);
|
58
|
+
return useMemo(() => {
|
59
|
+
return (item) => {
|
60
|
+
const pageTableCard = {
|
61
|
+
id: keyFn(item),
|
62
|
+
title: cardData.nameColumn?.cell(item),
|
63
|
+
description: cardData.descriptionColumn?.cell(item),
|
64
|
+
cardBody: (_jsx(CardBody, { children: _jsx(DescriptionList, { isCompact: true, children: cardData.columns.map((column) => (_jsx(Detail, { label: column.hideLabel ? undefined : column.header, children: column.cell(item) }, column.id))) }) })),
|
65
|
+
};
|
66
|
+
return pageTableCard;
|
67
|
+
};
|
68
|
+
}, [cardData.columns, cardData.descriptionColumn, cardData.nameColumn, keyFn]);
|
69
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
import { PageSection } from '@patternfly/react-core';
|
3
|
+
import { useMemo } from 'react';
|
4
|
+
import { Grid } from './components/Grid';
|
5
|
+
import { PageTableCard, useColumnsToTableCardFn } from './PageTableCard';
|
6
|
+
export function PageTableCards(props) {
|
7
|
+
const { keyFn, pageItems: items, tableColumns, isSelected, selectItem, unselectItem, rowActions, showSelect, defaultCardSubtitle, } = props;
|
8
|
+
const itemToCardFn = useColumnsToTableCardFn(tableColumns, keyFn);
|
9
|
+
const catalogCards = useMemo(() => {
|
10
|
+
return (_jsx(Grid, { size: 470, children: items?.map((item) => (_jsx(PageTableCard, { item: item, itemToCardFn: itemToCardFn, isSelected: isSelected, selectItem: selectItem, unselectItem: unselectItem, itemActions: rowActions, showSelect: showSelect, defaultCardSubtitle: defaultCardSubtitle }, keyFn(item)))) }));
|
11
|
+
}, [
|
12
|
+
items,
|
13
|
+
keyFn,
|
14
|
+
itemToCardFn,
|
15
|
+
isSelected,
|
16
|
+
selectItem,
|
17
|
+
unselectItem,
|
18
|
+
rowActions,
|
19
|
+
showSelect,
|
20
|
+
defaultCardSubtitle,
|
21
|
+
]);
|
22
|
+
return _jsx(PageSection, { style: { flexGrow: 1 }, children: catalogCards });
|
23
|
+
}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { ReactNode } from 'react';
|
2
|
+
import { ITableColumn, PageTableProps } from './PageTable';
|
3
|
+
import { ITypedAction } from './TypedActions';
|
4
|
+
export declare type PageTableListProps<T extends object> = PageTableProps<T>;
|
5
|
+
export declare function PageTableList<T extends object>(props: PageTableListProps<T>): JSX.Element;
|
6
|
+
export declare function useColumnsToDataList<T extends object>(tableColumns: ITableColumn<T>[], keyFn: (item: T) => string | number, isSelected?: (item: T) => boolean, selectItem?: (item: T) => void, unselectItem?: (item: T) => void, rowActions?: ITypedAction<T>[], defaultCardSubtitle?: ReactNode, showSelect?: boolean): (item: T) => ReactNode;
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
2
|
+
import { DataList, DataListAction, DataListCell, DataListCheck, DataListItem, DataListItemCells, DataListItemRow, DescriptionList, DescriptionListDescription, DescriptionListGroup, DescriptionListTerm, DropdownPosition, Flex, Stack, Text, Title, } from '@patternfly/react-core';
|
3
|
+
import { useCallback, useMemo } from 'react';
|
4
|
+
import { TypedActions } from './TypedActions';
|
5
|
+
export function PageTableList(props) {
|
6
|
+
const { keyFn, pageItems, tableColumns, isSelected, selectItem, unselectItem, rowActions, defaultCardSubtitle, showSelect, } = props;
|
7
|
+
const columnsToDataList = useColumnsToDataList(tableColumns, keyFn, isSelected, selectItem, unselectItem, rowActions, defaultCardSubtitle, showSelect);
|
8
|
+
return (_jsx(DataList, { "aria-label": "TODO", style: { marginTop: -1 }, children: pageItems?.map(columnsToDataList) }));
|
9
|
+
}
|
10
|
+
export function useColumnsToDataList(tableColumns, keyFn, isSelected, selectItem, unselectItem, rowActions, defaultCardSubtitle, showSelect) {
|
11
|
+
const data = useMemo(() => {
|
12
|
+
let cols = tableColumns.filter((column) => column.card !== 'hidden');
|
13
|
+
const nameColumn = cols.shift();
|
14
|
+
const descriptionColumn = cols.find((column) => column.card === 'description');
|
15
|
+
if (descriptionColumn) {
|
16
|
+
cols = cols.filter((column) => column !== descriptionColumn);
|
17
|
+
}
|
18
|
+
return {
|
19
|
+
nameColumn: nameColumn,
|
20
|
+
descriptionColumn: descriptionColumn,
|
21
|
+
columns: cols.filter((column) => column.list !== 'secondary'),
|
22
|
+
secondary: cols.filter((column) => column.list === 'secondary'),
|
23
|
+
};
|
24
|
+
}, [tableColumns]);
|
25
|
+
const onSelectClick = useCallback((item) => {
|
26
|
+
if (isSelected?.(item)) {
|
27
|
+
unselectItem?.(item);
|
28
|
+
}
|
29
|
+
else {
|
30
|
+
selectItem?.(item);
|
31
|
+
}
|
32
|
+
}, [isSelected, selectItem, unselectItem]);
|
33
|
+
return useCallback((item) => {
|
34
|
+
const key = keyFn(item);
|
35
|
+
const isItemSelected = isSelected?.(item);
|
36
|
+
return (_jsx(DataListItem, { "aria-labelledby": `data-list-${key}`, isExpanded: isItemSelected, children: _jsxs(DataListItemRow, { children: [showSelect && (_jsx(DataListCheck, { "aria-labelledby": `data-list-check-${key}`, name: `data-list-check-${key}`, isChecked: isSelected?.(item), onClick: () => onSelectClick(item) })), _jsx(DataListItemCells, { dataListCells: [
|
37
|
+
_jsx(DataListCell, { children: _jsx(Flex, { children: _jsxs(Stack, { hasGutter: true, children: [_jsxs(Stack, { children: [_jsx(Title, { headingLevel: "h2", style: { marginTop: -4 }, children: _jsx("span", { id: `data-list-${key}`, children: data.nameColumn?.cell(item) }) }), data.descriptionColumn ? (_jsx(Text, { component: "small", style: { opacity: 0.7 }, children: data.descriptionColumn.cell(item) })) : (defaultCardSubtitle && (_jsx(Text, { component: "small", style: { opacity: 0.7 }, children: defaultCardSubtitle })))] }), _jsx(DescriptionList, { isCompact: true, children: data.columns.map((column) => {
|
38
|
+
const value = column.cell(item);
|
39
|
+
if (!value)
|
40
|
+
return _jsx(_Fragment, {});
|
41
|
+
return (_jsxs(DescriptionListGroup, { children: [!column.hideLabel && (_jsx(DescriptionListTerm, { children: _jsx(Text, { component: "small", style: { opacity: 0.7 }, children: column.header }) })), _jsx(DescriptionListDescription, { children: column.cell(item) })] }, column.header));
|
42
|
+
}) })] }) }) }, "primary"),
|
43
|
+
_jsx(DataListCell, { children: _jsx(Flex, { children: _jsx(DescriptionList, { isCompact: true, children: data.secondary.map((column) => {
|
44
|
+
const value = column.cell(item);
|
45
|
+
if (!value)
|
46
|
+
return _jsx(_Fragment, {});
|
47
|
+
return (_jsxs(DescriptionListGroup, { children: [!column.hideLabel && (_jsx(DescriptionListTerm, { children: _jsx(Text, { component: "small", style: { opacity: 0.7 }, children: column.header }) })), _jsx(DescriptionListDescription, { children: column.cell(item) })] }, column.header));
|
48
|
+
}) }) }) }, "secondary"),
|
49
|
+
] }), rowActions && (_jsx(DataListAction, { "aria-labelledby": "check-action-item1 check-action-action1", id: "check-action-action1", "aria-label": "Actions", isPlainButtonAction: true, style: { whiteSpace: 'nowrap' }, children: _jsx(TypedActions, { actions: rowActions, position: DropdownPosition.right, selectedItem: item }) }))] }) }, key));
|
50
|
+
}, [
|
51
|
+
data.columns,
|
52
|
+
data.descriptionColumn,
|
53
|
+
data.nameColumn,
|
54
|
+
data.secondary,
|
55
|
+
defaultCardSubtitle,
|
56
|
+
isSelected,
|
57
|
+
keyFn,
|
58
|
+
onSelectClick,
|
59
|
+
rowActions,
|
60
|
+
showSelect,
|
61
|
+
]);
|
62
|
+
}
|
package/mjs/PageToolbar.d.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import { Dispatch, SetStateAction } from 'react';
|
2
|
+
import { PageTableViewType } from './PageTableViewType';
|
2
3
|
import { ITypedAction } from './TypedActions';
|
3
4
|
export interface IItemFilter<T extends object> {
|
4
5
|
label: string;
|
@@ -53,5 +54,7 @@ export declare type PagetableToolbarProps<T extends object> = {
|
|
53
54
|
onSelect?: (item: T) => void;
|
54
55
|
disableBorderBottom?: boolean;
|
55
56
|
showSelect?: boolean;
|
57
|
+
viewType: PageTableViewType;
|
58
|
+
setViewType: (viewType: PageTableViewType) => void;
|
56
59
|
};
|
57
60
|
export declare function PageTableToolbar<T extends object>(props: PagetableToolbarProps<T>): JSX.Element;
|
package/mjs/PageToolbar.js
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
2
|
-
import { Button, Flex, FlexItem, InputGroup, Pagination, PaginationVariant, Select, SelectOption, SelectVariant, Skeleton, TextInputGroup, TextInputGroupMain, TextInputGroupUtilities, Toolbar, ToolbarContent, ToolbarFilter, ToolbarGroup, ToolbarItem, ToolbarToggleGroup, Tooltip, } from '@patternfly/react-core';
|
3
|
-
import { ArrowRightIcon, ColumnsIcon, FilterIcon, TimesIcon } from '@patternfly/react-icons';
|
2
|
+
import { Button, Flex, FlexItem, InputGroup, Pagination, PaginationVariant, Select, SelectOption, SelectVariant, Skeleton, TextInputGroup, TextInputGroupMain, TextInputGroupUtilities, ToggleGroup, ToggleGroupItem, Toolbar, ToolbarContent, ToolbarFilter, ToolbarGroup, ToolbarItem, ToolbarToggleGroup, Tooltip, } from '@patternfly/react-core';
|
3
|
+
import { ArrowRightIcon, ColumnsIcon, FilterIcon, ListIcon, TableIcon, ThLargeIcon, TimesIcon, } from '@patternfly/react-icons';
|
4
4
|
import { Fragment, useCallback, useState } from 'react';
|
5
5
|
import { useTranslation } from 'react-i18next';
|
6
6
|
import { BulkSelector } from './components/BulkSelector';
|
7
7
|
import { SingleSelect2 } from './components/SingleSelect';
|
8
8
|
import { useBreakpoint } from './components/useBreakPoint';
|
9
|
+
import { PageTableViewTypeE } from './PageTableViewType';
|
9
10
|
import { useSettings } from './Settings';
|
10
11
|
import { TypedActions, TypedActionType } from './TypedActions';
|
11
12
|
export function toolbarActionsHaveBulkActions(actions) {
|
@@ -20,6 +21,7 @@ export function toolbarActionsHaveBulkActions(actions) {
|
|
20
21
|
export function PageTableToolbar(props) {
|
21
22
|
const { itemCount, page, perPage, setPage, setPerPage, toolbarFilters, selectedItems, filters, setFilters, clearAllFilters, openColumnModal, disableBorderBottom, } = props;
|
22
23
|
const sm = useBreakpoint('md');
|
24
|
+
const { viewType, setViewType } = props;
|
23
25
|
let { toolbarActions } = props;
|
24
26
|
toolbarActions = toolbarActions ?? [];
|
25
27
|
const onSetPage = useCallback((_event, page) => setPage(page), [setPage]);
|
@@ -96,7 +98,29 @@ export function PageTableToolbar(props) {
|
|
96
98
|
return newState;
|
97
99
|
});
|
98
100
|
}, showToolbarItem: false, children: _jsx(_Fragment, {}) }, filter.label));
|
99
|
-
})] }) })), _jsx(ToolbarGroup, { variant: "button-group", style: { zIndex: 302 }, children: _jsx(ToolbarItem, { children: _jsx(TypedActions, { actions: toolbarActions, selectedItems: selectedItems, wrapper: ToolbarItem }) }) }), _jsx(ToolbarGroup, { variant: "button-group", style: { zIndex: 302 }, children: openColumnModal && (_jsx(ToolbarItem, { children: _jsx(Tooltip, { content: 'Manage columns', children: _jsx(Button, { variant: "plain", icon: _jsx(ColumnsIcon, {}), onClick: openColumnModal }) }) }))
|
101
|
+
})] }) })), _jsx(ToolbarGroup, { variant: "button-group", style: { zIndex: 302 }, children: _jsx(ToolbarItem, { children: _jsx(TypedActions, { actions: toolbarActions, selectedItems: selectedItems, wrapper: ToolbarItem }) }) }), _jsx("div", { style: { flexGrow: 1 } }), _jsxs(ToolbarGroup, { variant: "button-group", style: { zIndex: 302 }, children: [openColumnModal && viewType === 'table' && (_jsx(ToolbarItem, { children: _jsx(Tooltip, { content: 'Manage columns', children: _jsx(Button, { variant: "plain", icon: _jsx(ColumnsIcon, {}), onClick: openColumnModal }) }) })), _jsx(ToolbarItem, { children: _jsx(ToggleGroup, { children: [PageTableViewTypeE.Table, PageTableViewTypeE.List, PageTableViewTypeE.Cards]
|
102
|
+
// .filter((vt) => {
|
103
|
+
// switch (vt) {
|
104
|
+
// case PageTableViewTypeE.Cards:
|
105
|
+
// return props.itemToCardFn !== undefined
|
106
|
+
// case PageTableViewTypeE.list:
|
107
|
+
// return false
|
108
|
+
// case PageTableViewTypeE.table:
|
109
|
+
// return props.tableColumns !== undefined
|
110
|
+
// default:
|
111
|
+
// return false
|
112
|
+
// }
|
113
|
+
// })
|
114
|
+
.map((vt) => {
|
115
|
+
switch (vt) {
|
116
|
+
case PageTableViewTypeE.Cards:
|
117
|
+
return (_jsx(Tooltip, { content: 'Card view', position: "top-end", enableFlip: false, children: _jsx(ToggleGroupItem, { icon: _jsx(ThLargeIcon, {}), isSelected: viewType === PageTableViewTypeE.Cards, onClick: () => setViewType?.(PageTableViewTypeE.Cards) }) }, vt));
|
118
|
+
case PageTableViewTypeE.List:
|
119
|
+
return (_jsx(Tooltip, { content: 'List view', position: "top-end", enableFlip: false, children: _jsx(ToggleGroupItem, { icon: _jsx(ListIcon, {}), isSelected: viewType === PageTableViewTypeE.List, onClick: () => setViewType?.(PageTableViewTypeE.List) }) }));
|
120
|
+
case PageTableViewTypeE.Table:
|
121
|
+
return (_jsx(Tooltip, { content: 'Table view', position: "top-end", enableFlip: false, children: _jsx(ToggleGroupItem, { icon: _jsx(TableIcon, {}), isSelected: viewType === PageTableViewTypeE.Table, onClick: () => setViewType?.(PageTableViewTypeE.Table) }) }));
|
122
|
+
}
|
123
|
+
}) }) })] }), _jsx(ToolbarItem, { visibility: { default: 'hidden', '2xl': 'visible' }, children: _jsx(Pagination, { variant: PaginationVariant.top, isCompact: true, itemCount: itemCount, perPage: perPage, page: page, onSetPage: onSetPage, onPerPageSelect: onPerPageSelect, style: { marginTop: -8, marginBottom: -8 } }) })] }) }));
|
100
124
|
}
|
101
125
|
function ToolbarFilterInput(props) {
|
102
126
|
const { filter } = props;
|
@@ -45,17 +45,20 @@ export declare function TypedActionsDropdown<T extends object>(props: {
|
|
45
45
|
label?: string;
|
46
46
|
isPrimary?: boolean;
|
47
47
|
selectedItems?: T[];
|
48
|
+
selectedItem?: T;
|
48
49
|
position?: DropdownPosition;
|
49
50
|
}): JSX.Element;
|
50
51
|
export declare function DropdownActionItem<T extends object>(props: {
|
51
52
|
action: ITypedAction<T>;
|
52
53
|
selectedItems: T[];
|
54
|
+
selectedItem?: T;
|
53
55
|
hasIcons: boolean;
|
54
56
|
index: number;
|
55
57
|
}): JSX.Element;
|
56
58
|
export declare function TypedActions<T extends object>(props: {
|
57
59
|
actions: ITypedAction<T>[];
|
58
60
|
selectedItems?: T[];
|
61
|
+
selectedItem?: T;
|
59
62
|
wrapper?: ComponentClass | FunctionComponent;
|
60
63
|
collapse?: WindowSize;
|
61
64
|
noPrimary?: boolean;
|
@@ -3,7 +3,7 @@ import { ButtonVariant, Dropdown, DropdownItem, DropdownSeparator, DropdownToggl
|
|
3
3
|
import { CircleIcon } from '@patternfly/react-icons';
|
4
4
|
import { useCallback, useMemo, useState } from 'react';
|
5
5
|
import { useBreakpoint } from '../components/useBreakPoint';
|
6
|
-
import {
|
6
|
+
import { TypedActionButton, TypedActionsButtons } from './TypedActionsButtons';
|
7
7
|
export var TypedActionType;
|
8
8
|
(function (TypedActionType) {
|
9
9
|
TypedActionType["seperator"] = "seperator";
|
@@ -13,7 +13,7 @@ export var TypedActionType;
|
|
13
13
|
TypedActionType["dropdown"] = "dropdown";
|
14
14
|
})(TypedActionType || (TypedActionType = {}));
|
15
15
|
export function TypedActionsDropdown(props) {
|
16
|
-
const { actions, label, isPrimary = false, selectedItems } = props;
|
16
|
+
const { actions, label, isPrimary = false, selectedItems, selectedItem } = props;
|
17
17
|
const [dropdownOpen, setDropdownOpen] = useState(false);
|
18
18
|
const hasItemActions = useMemo(() => !actions.every((action) => action.type !== TypedActionType.bulk), [actions]);
|
19
19
|
const hasIcons = useMemo(() => actions.find((action) => action.type !== TypedActionType.seperator && action.icon !== undefined) !== undefined, [actions]);
|
@@ -24,12 +24,21 @@ export function TypedActionsDropdown(props) {
|
|
24
24
|
? {
|
25
25
|
color: 'var(--pf-global--Color--light-100)',
|
26
26
|
}
|
27
|
-
: {}, children: label }), isOpen: dropdownOpen, isPlain: !label, dropdownItems: actions.map((action, index) => (_jsx(DropdownActionItem, { action: action, selectedItems: selectedItems ?? [], hasIcons: hasIcons, index: index }, 'label' in action ? action.label : `action-${index}`))), position: props.position, style: { zIndex: 201 } }));
|
27
|
+
: {}, children: label }), isOpen: dropdownOpen, isPlain: !label, dropdownItems: actions.map((action, index) => (_jsx(DropdownActionItem, { action: action, selectedItems: selectedItems ?? [], selectedItem: selectedItem, hasIcons: hasIcons, index: index }, 'label' in action ? action.label : `action-${index}`))), position: props.position, style: { zIndex: 201 } }));
|
28
28
|
}
|
29
29
|
export function DropdownActionItem(props) {
|
30
|
-
const { action, selectedItems, hasIcons, index } = props;
|
31
|
-
// TODO case TypedActionType.single?
|
30
|
+
const { action, selectedItems, selectedItem, hasIcons, index } = props;
|
32
31
|
switch (action.type) {
|
32
|
+
case TypedActionType.single: {
|
33
|
+
let Icon = action.icon;
|
34
|
+
if (!Icon && hasIcons)
|
35
|
+
Icon = TransparentIcon;
|
36
|
+
const tooltip = action.tooltip;
|
37
|
+
const isDisabled = false;
|
38
|
+
return (_jsx(Tooltip, { content: tooltip, trigger: tooltip ? undefined : 'manual', children: _jsx(DropdownItem, { onClick: () => selectedItem && action.onClick(selectedItem), isAriaDisabled: isDisabled, icon: Icon ? (_jsx("span", { style: { paddingRight: 4 }, children: _jsx(Icon, {}) })) : undefined, style: {
|
39
|
+
color: action.isDanger && !isDisabled ? 'var(--pf-global--danger-color--100)' : undefined,
|
40
|
+
}, children: action.label }) }, action.label));
|
41
|
+
}
|
33
42
|
case TypedActionType.button:
|
34
43
|
case TypedActionType.bulk: {
|
35
44
|
let Icon = action.icon;
|
@@ -32,7 +32,7 @@ export declare function DetailsList(props: {
|
|
32
32
|
children?: ReactNode;
|
33
33
|
}): JSX.Element;
|
34
34
|
export declare function Detail(props: {
|
35
|
-
label
|
35
|
+
label?: string;
|
36
36
|
children?: ReactNode;
|
37
37
|
}): JSX.Element;
|
38
38
|
export declare function DetailsSkeleton(): JSX.Element;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
-
import { DescriptionList, DescriptionListDescription, DescriptionListGroup, DescriptionListTerm, Skeleton, Split, SplitItem, Stack, } from '@patternfly/react-core';
|
2
|
+
import { DescriptionList, DescriptionListDescription, DescriptionListGroup, DescriptionListTerm, Skeleton, Split, SplitItem, Stack, Text, } from '@patternfly/react-core';
|
3
3
|
import { Link } from 'react-router-dom';
|
4
4
|
import { CopyCell, SinceCell } from '../PageCells';
|
5
5
|
import { useSettings } from '../Settings';
|
@@ -61,7 +61,7 @@ export function DetailsList(props) {
|
|
61
61
|
export function Detail(props) {
|
62
62
|
if (!props.children)
|
63
63
|
return _jsx(_Fragment, {});
|
64
|
-
return (_jsxs(DescriptionListGroup, { children: [_jsx(DescriptionListTerm, { children: props.label }), _jsx(DescriptionListDescription, { id: props.label
|
64
|
+
return (_jsxs(DescriptionListGroup, { children: [props.label && (_jsx(DescriptionListTerm, { children: _jsx(Text, { component: "small", style: { opacity: 0.7 }, children: props.label }) })), _jsx(DescriptionListDescription, { id: props.label?.toLowerCase().split(' ').join('-'), children: props.children })] }));
|
65
65
|
}
|
66
66
|
export function DetailsSkeleton() {
|
67
67
|
return (_jsxs(Stack, { hasGutter: true, children: [_jsx(Skeleton, {}), _jsx(Skeleton, {}), _jsx(Skeleton, {}), _jsx(Skeleton, {})] }));
|
@@ -11,3 +11,13 @@ export declare const pfDanger = "var(--pf-global--danger-color--100)";
|
|
11
11
|
export declare const pfWarning = "var(--pf-global--warning-color--100)";
|
12
12
|
export declare const pfInfo = "var(--pf-global--info-color--100)";
|
13
13
|
export declare const pfDisabled = "var(--pf-global--disabled-color--100)";
|
14
|
+
export declare enum LabelColorE {
|
15
|
+
blue = "blue",
|
16
|
+
cyan = "cyan",
|
17
|
+
green = "green",
|
18
|
+
orange = "orange",
|
19
|
+
purple = "purple",
|
20
|
+
red = "red",
|
21
|
+
grey = "grey"
|
22
|
+
}
|
23
|
+
export declare type LabelColor = 'blue' | 'cyan' | 'green' | 'orange' | 'purple' | 'red' | 'grey';
|
@@ -26,3 +26,13 @@ export const pfDanger = 'var(--pf-global--danger-color--100)';
|
|
26
26
|
export const pfWarning = 'var(--pf-global--warning-color--100)';
|
27
27
|
export const pfInfo = 'var(--pf-global--info-color--100)';
|
28
28
|
export const pfDisabled = 'var(--pf-global--disabled-color--100)';
|
29
|
+
export var LabelColorE;
|
30
|
+
(function (LabelColorE) {
|
31
|
+
LabelColorE["blue"] = "blue";
|
32
|
+
LabelColorE["cyan"] = "cyan";
|
33
|
+
LabelColorE["green"] = "green";
|
34
|
+
LabelColorE["orange"] = "orange";
|
35
|
+
LabelColorE["purple"] = "purple";
|
36
|
+
LabelColorE["red"] = "red";
|
37
|
+
LabelColorE["grey"] = "grey";
|
38
|
+
})(LabelColorE || (LabelColorE = {}));
|
package/mjs/index.d.ts
CHANGED
@@ -6,7 +6,6 @@ export * from './components/Help';
|
|
6
6
|
export * from './components/patternfly-colors';
|
7
7
|
export * from './components/useBreakPoint';
|
8
8
|
export * from './PageBody';
|
9
|
-
export * from './PageCatalog';
|
10
9
|
export * from './PageCells';
|
11
10
|
export * from './PageDataList';
|
12
11
|
export * from './PageDialog';
|
@@ -15,6 +14,7 @@ export * from './PageFramework';
|
|
15
14
|
export * from './PageHeader';
|
16
15
|
export * from './PageLayout';
|
17
16
|
export * from './PageTable';
|
17
|
+
export * from './PageTableCards';
|
18
18
|
export * from './PageTabs';
|
19
19
|
export * from './PageToolbar';
|
20
20
|
export * from './TypedActions';
|
package/mjs/index.js
CHANGED
@@ -6,7 +6,6 @@ export * from './components/Help';
|
|
6
6
|
export * from './components/patternfly-colors';
|
7
7
|
export * from './components/useBreakPoint';
|
8
8
|
export * from './PageBody';
|
9
|
-
export * from './PageCatalog';
|
10
9
|
export * from './PageCells';
|
11
10
|
export * from './PageDataList';
|
12
11
|
export * from './PageDialog';
|
@@ -15,6 +14,7 @@ export * from './PageFramework';
|
|
15
14
|
export * from './PageHeader';
|
16
15
|
export * from './PageLayout';
|
17
16
|
export * from './PageTable';
|
17
|
+
export * from './PageTableCards';
|
18
18
|
export * from './PageTabs';
|
19
19
|
export * from './PageToolbar';
|
20
20
|
export * from './TypedActions';
|
package/package.json
CHANGED