@patternfly/react-core 5.2.0-prerelease.26 → 5.2.0-prerelease.28
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/CHANGELOG.md +8 -0
- package/components/package.json +1 -1
- package/deprecated/package.json +1 -1
- package/dist/dynamic/components/AboutModal/package.json +1 -1
- package/dist/dynamic/components/Accordion/package.json +1 -1
- package/dist/dynamic/components/ActionList/package.json +1 -1
- package/dist/dynamic/components/Alert/package.json +1 -1
- package/dist/dynamic/components/Avatar/package.json +1 -1
- package/dist/dynamic/components/BackToTop/package.json +1 -1
- package/dist/dynamic/components/Backdrop/package.json +1 -1
- package/dist/dynamic/components/BackgroundImage/package.json +1 -1
- package/dist/dynamic/components/Badge/package.json +1 -1
- package/dist/dynamic/components/Banner/package.json +1 -1
- package/dist/dynamic/components/Brand/package.json +1 -1
- package/dist/dynamic/components/Breadcrumb/package.json +1 -1
- package/dist/dynamic/components/Button/package.json +1 -1
- package/dist/dynamic/components/CalendarMonth/package.json +1 -1
- package/dist/dynamic/components/Card/package.json +1 -1
- package/dist/dynamic/components/Checkbox/package.json +1 -1
- package/dist/dynamic/components/Chip/package.json +1 -1
- package/dist/dynamic/components/ClipboardCopy/package.json +1 -1
- package/dist/dynamic/components/CodeBlock/package.json +1 -1
- package/dist/dynamic/components/DataList/package.json +1 -1
- package/dist/dynamic/components/DatePicker/package.json +1 -1
- package/dist/dynamic/components/DescriptionList/package.json +1 -1
- package/dist/dynamic/components/Divider/package.json +1 -1
- package/dist/dynamic/components/DragDrop/package.json +1 -1
- package/dist/dynamic/components/Drawer/package.json +1 -1
- package/dist/dynamic/components/Dropdown/package.json +1 -1
- package/dist/dynamic/components/DualListSelector/package.json +1 -1
- package/dist/dynamic/components/EmptyState/package.json +1 -1
- package/dist/dynamic/components/ExpandableSection/package.json +1 -1
- package/dist/dynamic/components/FileUpload/package.json +1 -1
- package/dist/dynamic/components/Form/package.json +1 -1
- package/dist/dynamic/components/FormSelect/package.json +1 -1
- package/dist/dynamic/components/HelperText/package.json +1 -1
- package/dist/dynamic/components/Hint/package.json +1 -1
- package/dist/dynamic/components/Icon/package.json +1 -1
- package/dist/dynamic/components/InputGroup/package.json +1 -1
- package/dist/dynamic/components/JumpLinks/package.json +1 -1
- package/dist/dynamic/components/Label/package.json +1 -1
- package/dist/dynamic/components/List/package.json +1 -1
- package/dist/dynamic/components/LoginPage/package.json +1 -1
- package/dist/dynamic/components/Masthead/package.json +1 -1
- package/dist/dynamic/components/Menu/package.json +1 -1
- package/dist/dynamic/components/MenuToggle/package.json +1 -1
- package/dist/dynamic/components/Modal/package.json +1 -1
- package/dist/dynamic/components/MultipleFileUpload/package.json +1 -1
- package/dist/dynamic/components/Nav/package.json +1 -1
- package/dist/dynamic/components/NotificationBadge/package.json +1 -1
- package/dist/dynamic/components/NotificationDrawer/package.json +1 -1
- package/dist/dynamic/components/NumberInput/package.json +1 -1
- package/dist/dynamic/components/OverflowMenu/package.json +1 -1
- package/dist/dynamic/components/Page/package.json +1 -1
- package/dist/dynamic/components/Pagination/package.json +1 -1
- package/dist/dynamic/components/Panel/package.json +1 -1
- package/dist/dynamic/components/Popover/package.json +1 -1
- package/dist/dynamic/components/Progress/package.json +1 -1
- package/dist/dynamic/components/ProgressStepper/package.json +1 -1
- package/dist/dynamic/components/Radio/package.json +1 -1
- package/dist/dynamic/components/SearchInput/package.json +1 -1
- package/dist/dynamic/components/Select/package.json +1 -1
- package/dist/dynamic/components/Sidebar/package.json +1 -1
- package/dist/dynamic/components/SimpleList/package.json +1 -1
- package/dist/dynamic/components/Skeleton/package.json +1 -1
- package/dist/dynamic/components/SkipToContent/package.json +1 -1
- package/dist/dynamic/components/Slider/package.json +1 -1
- package/dist/dynamic/components/Spinner/package.json +1 -1
- package/dist/dynamic/components/Switch/package.json +1 -1
- package/dist/dynamic/components/Tabs/package.json +1 -1
- package/dist/dynamic/components/Text/package.json +1 -1
- package/dist/dynamic/components/TextArea/package.json +1 -1
- package/dist/dynamic/components/TextInput/package.json +1 -1
- package/dist/dynamic/components/TextInputGroup/package.json +1 -1
- package/dist/dynamic/components/Tile/package.json +1 -1
- package/dist/dynamic/components/TimePicker/package.json +1 -1
- package/dist/dynamic/components/Timestamp/package.json +1 -1
- package/dist/dynamic/components/Title/package.json +1 -1
- package/dist/dynamic/components/ToggleGroup/package.json +1 -1
- package/dist/dynamic/components/Toolbar/package.json +1 -1
- package/dist/dynamic/components/Tooltip/package.json +1 -1
- package/dist/dynamic/components/TreeView/package.json +1 -1
- package/dist/dynamic/components/Truncate/package.json +1 -1
- package/dist/dynamic/components/Wizard/hooks/package.json +1 -1
- package/dist/dynamic/components/Wizard/package.json +1 -1
- package/dist/dynamic/deprecated/components/ApplicationLauncher/package.json +1 -1
- package/dist/dynamic/deprecated/components/ContextSelector/package.json +1 -1
- package/dist/dynamic/deprecated/components/Dropdown/package.json +1 -1
- package/dist/dynamic/deprecated/components/OptionsMenu/package.json +1 -1
- package/dist/dynamic/deprecated/components/PageHeader/package.json +1 -1
- package/dist/dynamic/deprecated/components/Select/package.json +1 -1
- package/dist/dynamic/deprecated/components/Wizard/package.json +1 -1
- package/dist/dynamic/deprecated/components/package.json +1 -1
- package/dist/dynamic/helpers/FocusTrap/FocusTrap/package.json +1 -1
- package/dist/dynamic/helpers/GenerateId/GenerateId/package.json +1 -1
- package/dist/dynamic/helpers/KeyboardHandler/package.json +1 -1
- package/dist/dynamic/helpers/OUIA/ouia/package.json +1 -1
- package/dist/dynamic/helpers/Popper/Popper/package.json +1 -1
- package/dist/dynamic/helpers/constants/package.json +1 -1
- package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
- package/dist/dynamic/helpers/favorites/package.json +1 -1
- package/dist/dynamic/helpers/fileUtils/package.json +1 -1
- package/dist/dynamic/helpers/htmlConstants/package.json +1 -1
- package/dist/dynamic/helpers/package.json +1 -1
- package/dist/dynamic/helpers/resizeObserver/package.json +1 -1
- package/dist/dynamic/helpers/typeUtils/package.json +1 -1
- package/dist/dynamic/helpers/useInterval/package.json +1 -1
- package/dist/dynamic/helpers/useIsomorphicLayout/package.json +1 -1
- package/dist/dynamic/helpers/useUnmountEffect/package.json +1 -1
- package/dist/dynamic/helpers/util/package.json +1 -1
- package/dist/dynamic/layouts/Bullseye/package.json +1 -1
- package/dist/dynamic/layouts/Flex/package.json +1 -1
- package/dist/dynamic/layouts/Gallery/package.json +1 -1
- package/dist/dynamic/layouts/Grid/package.json +1 -1
- package/dist/dynamic/layouts/Level/package.json +1 -1
- package/dist/dynamic/layouts/Split/package.json +1 -1
- package/dist/dynamic/layouts/Stack/package.json +1 -1
- package/dist/dynamic/next/components/package.json +1 -1
- package/helpers/package.json +1 -1
- package/layouts/package.json +1 -1
- package/next/package.json +1 -1
- package/package.json +2 -2
- package/src/components/Nav/examples/NavFlyout.tsx +1 -1
- package/src/components/Nav/examples/NavHorizontalSubNav.tsx +1 -1
- package/src/components/Nav/examples/NavLegacyTertiary.tsx +1 -1
- package/src/components/Pagination/examples/PaginationSticky.tsx +2 -2
- package/src/demos/Banner.md +4 -4
- package/src/demos/PrimaryDetail.md +3 -975
- package/src/demos/examples/BackToTop/BackToTopNameDemo.tsx +3 -3
- package/src/demos/examples/Masthead/MastheadWithUtilitiesAndUserDropdownMenu.tsx +2 -2
- package/src/demos/examples/Nav/NavDefault.tsx +1 -1
- package/src/demos/examples/Nav/NavExpandable.tsx +1 -1
- package/src/demos/examples/Nav/NavHorizontal.tsx +1 -1
- package/src/demos/examples/Nav/NavHorizontalWithSubnav.tsx +1 -1
- package/src/demos/examples/Nav/NavManual.tsx +1 -1
- package/src/demos/examples/Nav/NavWithSubnav.tsx +1 -1
- package/src/demos/examples/Nav/deprecated/NavLight.tsx +1 -1
- package/src/demos/examples/Nav/deprecated/NavTertiary.tsx +1 -1
- package/src/demos/examples/Page/PageStickySectionBreadcrumb.tsx +2 -2
- package/src/demos/examples/Page/PageStickySectionGroup.tsx +2 -2
- package/src/demos/examples/Page/PageStickySectionGroupAlternate.tsx +2 -2
- package/src/demos/examples/PrimaryDetail/PrimaryDetailCardView.tsx +659 -0
- package/src/demos/examples/PrimaryDetail/PrimaryDetailDataListInCard.tsx +207 -0
- package/src/demos/examples/PrimaryDetail/PrimaryDetailSimpleListInCard.tsx +116 -0
- package/src/demos/examples/Wizard/InModal.tsx +2 -2
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Badge,
|
|
4
|
+
Button,
|
|
5
|
+
Card,
|
|
6
|
+
CardHeader,
|
|
7
|
+
CardBody,
|
|
8
|
+
CardTitle,
|
|
9
|
+
Divider,
|
|
10
|
+
Drawer,
|
|
11
|
+
DrawerActions,
|
|
12
|
+
DrawerPanelBody,
|
|
13
|
+
DrawerCloseButton,
|
|
14
|
+
DrawerContent,
|
|
15
|
+
DrawerContentBody,
|
|
16
|
+
DrawerHead,
|
|
17
|
+
DrawerPanelContent,
|
|
18
|
+
Dropdown,
|
|
19
|
+
DropdownItem,
|
|
20
|
+
DropdownList,
|
|
21
|
+
Flex,
|
|
22
|
+
FlexItem,
|
|
23
|
+
Gallery,
|
|
24
|
+
MenuToggle,
|
|
25
|
+
MenuToggleCheckbox,
|
|
26
|
+
PageSection,
|
|
27
|
+
PageSectionVariants,
|
|
28
|
+
Pagination,
|
|
29
|
+
Progress,
|
|
30
|
+
Select,
|
|
31
|
+
SelectList,
|
|
32
|
+
SelectOption,
|
|
33
|
+
TextContent,
|
|
34
|
+
Text,
|
|
35
|
+
Title,
|
|
36
|
+
Toolbar,
|
|
37
|
+
ToolbarFilter,
|
|
38
|
+
ToolbarItem,
|
|
39
|
+
ToolbarContent,
|
|
40
|
+
MenuToggleElement
|
|
41
|
+
} from '@patternfly/react-core';
|
|
42
|
+
import TrashIcon from '@patternfly/react-icons/dist/esm/icons/trash-icon';
|
|
43
|
+
import pfIcon from './assets/pf-logo-small.svg';
|
|
44
|
+
import activeMQIcon from './assets/activemq-core_200x150.png';
|
|
45
|
+
import avroIcon from './assets/camel-avro_200x150.png';
|
|
46
|
+
import dropBoxIcon from './assets/camel-dropbox_200x150.png';
|
|
47
|
+
import infinispanIcon from './assets/camel-infinispan_200x150.png';
|
|
48
|
+
import saxonIcon from './assets/camel-saxon_200x150.png';
|
|
49
|
+
import sparkIcon from './assets/camel-spark_200x150.png';
|
|
50
|
+
import swaggerIcon from './assets/camel-swagger-java_200x150.png';
|
|
51
|
+
import azureIcon from './assets/FuseConnector_Icons_AzureServices.png';
|
|
52
|
+
import restIcon from './assets/FuseConnector_Icons_REST.png';
|
|
53
|
+
import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
|
|
54
|
+
import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper';
|
|
55
|
+
import { data } from '@patternfly/react-core/src/demos/CardView/examples/CardViewData.jsx';
|
|
56
|
+
|
|
57
|
+
export const PrimaryDetailCardView: React.FunctionComponent = () => {
|
|
58
|
+
const [totalItemCount, setTotalItemCount] = React.useState(10);
|
|
59
|
+
const [cardData, setCardData] = React.useState(data);
|
|
60
|
+
const [isChecked, setIsChecked] = React.useState(false);
|
|
61
|
+
const [isDrawerExpanded, setIsDrawerExpanded] = React.useState(false);
|
|
62
|
+
const [selectedItems, setSelectedItems] = React.useState<number[]>([]);
|
|
63
|
+
const [areAllSelected, setAreAllSelected] = React.useState<boolean>(false);
|
|
64
|
+
const [splitButtonDropdownIsOpen, setSplitButtonDropdownIsOpen] = React.useState(false);
|
|
65
|
+
const [isLowerToolbarDropdownOpen, setIsLowerToolbarDropdownOpen] = React.useState(false);
|
|
66
|
+
const [isLowerToolbarKebabDropdownOpen, setIsLowerToolbarKebabDropdownOpen] = React.useState(false);
|
|
67
|
+
const [page, setPage] = React.useState(1);
|
|
68
|
+
const [perPage, setPerPage] = React.useState(10);
|
|
69
|
+
const [filters, setFilters] = React.useState<Record<string, string[]>>({ products: [] });
|
|
70
|
+
const [state, setState] = React.useState({});
|
|
71
|
+
const [activeCard, setActiveCard] = React.useState(-1);
|
|
72
|
+
|
|
73
|
+
interface ProductType {
|
|
74
|
+
id: number;
|
|
75
|
+
name: string;
|
|
76
|
+
icon: string;
|
|
77
|
+
description: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const onToolbarDropdownToggle = () => {
|
|
81
|
+
setIsLowerToolbarDropdownOpen(!isLowerToolbarDropdownOpen);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const onToolbarKebabDropdownToggle = () => {
|
|
85
|
+
setIsLowerToolbarKebabDropdownOpen(!isLowerToolbarKebabDropdownOpen);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const onToolbarKebabDropdownSelect = () => {
|
|
89
|
+
setIsLowerToolbarKebabDropdownOpen(!isLowerToolbarKebabDropdownOpen);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const onCardKebabDropdownToggle = (
|
|
93
|
+
event: React.MouseEvent<HTMLButtonElement, MouseEvent> | React.MouseEvent<HTMLDivElement, MouseEvent>,
|
|
94
|
+
key: string
|
|
95
|
+
) => {
|
|
96
|
+
setState({
|
|
97
|
+
[key]: !state[key as keyof Object]
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const checkAllSelected = (selected: number, total: number) => {
|
|
102
|
+
if (selected && selected < total) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
return selected === total;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const onNameSelect = (event: any, selection = '') => {
|
|
109
|
+
const checked = event.target.checked;
|
|
110
|
+
const prevSelections = filters.products;
|
|
111
|
+
|
|
112
|
+
setFilters({
|
|
113
|
+
...filters,
|
|
114
|
+
products: checked ? [...prevSelections, selection] : prevSelections.filter((value) => value !== selection)
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const onDelete = (type = '', _id = '') => {
|
|
119
|
+
if (type) {
|
|
120
|
+
setFilters(filters);
|
|
121
|
+
} else {
|
|
122
|
+
setFilters({ products: [] });
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const deleteItem = (item: ProductType) => {
|
|
127
|
+
const filter = (getter) => (val) => getter(val) !== item.id;
|
|
128
|
+
|
|
129
|
+
setCardData(cardData.filter(filter(({ id }) => id)));
|
|
130
|
+
|
|
131
|
+
setSelectedItems(selectedItems.filter(filter((id) => id)));
|
|
132
|
+
|
|
133
|
+
setTotalItemCount(totalItemCount - 1);
|
|
134
|
+
setIsDrawerExpanded(false);
|
|
135
|
+
setActiveCard(-1);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const onSetPage = (_event: any, pageNumber: number) => {
|
|
139
|
+
setPage(pageNumber);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const onPerPageSelect = (_event: any, perPage: number) => {
|
|
143
|
+
setPerPage(perPage);
|
|
144
|
+
setPage(1);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const onSplitButtonToggle = () => {
|
|
148
|
+
setSplitButtonDropdownIsOpen(!splitButtonDropdownIsOpen);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const onSplitButtonSelect = () => {
|
|
152
|
+
setSplitButtonDropdownIsOpen(false);
|
|
153
|
+
setIsDrawerExpanded(false);
|
|
154
|
+
setActiveCard(-1);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const onCloseDrawerClick = () => {
|
|
158
|
+
setActiveCard(-1);
|
|
159
|
+
setIsDrawerExpanded(false);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const onChange = (event: React.FormEvent<HTMLInputElement>) => {
|
|
163
|
+
const name = event.currentTarget.name;
|
|
164
|
+
const productId = Number(name.charAt(name.length - 1));
|
|
165
|
+
|
|
166
|
+
if (selectedItems.includes(productId * 1)) {
|
|
167
|
+
setSelectedItems(selectedItems.filter((id) => productId * 1 !== id));
|
|
168
|
+
|
|
169
|
+
const checkAll = checkAllSelected(selectedItems.length - 1, totalItemCount);
|
|
170
|
+
setAreAllSelected(!!checkAll);
|
|
171
|
+
} else {
|
|
172
|
+
setSelectedItems([...selectedItems, productId * 1]);
|
|
173
|
+
const checkAll = checkAllSelected(selectedItems.length + 1, totalItemCount);
|
|
174
|
+
setAreAllSelected(!!checkAll);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const onCardClick = (productId) => {
|
|
179
|
+
if (productId === activeCard) {
|
|
180
|
+
setIsDrawerExpanded(!isDrawerExpanded);
|
|
181
|
+
setActiveCard(-1);
|
|
182
|
+
} else {
|
|
183
|
+
setActiveCard(productId);
|
|
184
|
+
setIsDrawerExpanded(true);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const selectPage = (e: { target: { checked: any } }) => {
|
|
189
|
+
const { checked } = e.target;
|
|
190
|
+
let collection: number[] = [];
|
|
191
|
+
|
|
192
|
+
collection = getAllItems();
|
|
193
|
+
|
|
194
|
+
setSelectedItems(collection);
|
|
195
|
+
setIsChecked(checked);
|
|
196
|
+
setAreAllSelected(totalItemCount === perPage ? true : false);
|
|
197
|
+
|
|
198
|
+
updateSelected();
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
const selectAll = () => {
|
|
202
|
+
let collection: number[] = [];
|
|
203
|
+
for (let i = 0; i <= 9; i++) {
|
|
204
|
+
collection = [...collection, i];
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
setSelectedItems(collection);
|
|
208
|
+
setIsChecked(true);
|
|
209
|
+
setAreAllSelected(true);
|
|
210
|
+
|
|
211
|
+
updateSelected();
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const selectNone = () => {
|
|
215
|
+
setSelectedItems([]);
|
|
216
|
+
setIsChecked(false);
|
|
217
|
+
setAreAllSelected(false);
|
|
218
|
+
setIsDrawerExpanded(false);
|
|
219
|
+
setActiveCard(-1);
|
|
220
|
+
|
|
221
|
+
updateSelected();
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const updateSelected = () => {
|
|
225
|
+
const rows = cardData.map((post) => {
|
|
226
|
+
post.selected = selectedItems.includes(post.id);
|
|
227
|
+
return post;
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
setCardData(rows);
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
const getAllItems = () => {
|
|
234
|
+
const collection: number[] = [];
|
|
235
|
+
for (const items of cardData) {
|
|
236
|
+
collection.push(items.id);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return collection;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const splitCheckboxSelectAll = (e: any) => {
|
|
243
|
+
let collection: number[] = [];
|
|
244
|
+
|
|
245
|
+
if (e.target.checked) {
|
|
246
|
+
for (let i = 0; i <= 9; i++) {
|
|
247
|
+
collection = [...collection, i];
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
setSelectedItems(collection);
|
|
252
|
+
setIsChecked(isChecked);
|
|
253
|
+
setAreAllSelected(e.target.checked);
|
|
254
|
+
setIsDrawerExpanded(false);
|
|
255
|
+
setActiveCard(-1);
|
|
256
|
+
|
|
257
|
+
updateSelected();
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const renderPagination = () => {
|
|
261
|
+
const defaultPerPageOptions = [
|
|
262
|
+
{
|
|
263
|
+
title: '1',
|
|
264
|
+
value: 1
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
title: '5',
|
|
268
|
+
value: 5
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
title: '10',
|
|
272
|
+
value: 10
|
|
273
|
+
}
|
|
274
|
+
];
|
|
275
|
+
|
|
276
|
+
return (
|
|
277
|
+
<Pagination
|
|
278
|
+
itemCount={totalItemCount}
|
|
279
|
+
page={page}
|
|
280
|
+
perPage={perPage}
|
|
281
|
+
perPageOptions={defaultPerPageOptions}
|
|
282
|
+
onSetPage={onSetPage}
|
|
283
|
+
onPerPageSelect={onPerPageSelect}
|
|
284
|
+
variant="top"
|
|
285
|
+
isCompact
|
|
286
|
+
/>
|
|
287
|
+
);
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const buildSelectDropdown = () => {
|
|
291
|
+
const numSelected = selectedItems.length;
|
|
292
|
+
const anySelected = numSelected > 0;
|
|
293
|
+
const splitButtonDropdownItems = (
|
|
294
|
+
<>
|
|
295
|
+
<DropdownItem key="item-1" onClick={selectNone}>
|
|
296
|
+
Select none (0 items)
|
|
297
|
+
</DropdownItem>
|
|
298
|
+
<DropdownItem key="item-2" onClick={selectPage}>
|
|
299
|
+
Select page ({perPage} items)
|
|
300
|
+
</DropdownItem>
|
|
301
|
+
<DropdownItem key="item-3" onClick={selectAll}>
|
|
302
|
+
Select all ({totalItemCount} items)
|
|
303
|
+
</DropdownItem>
|
|
304
|
+
</>
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
return (
|
|
308
|
+
<Dropdown
|
|
309
|
+
onSelect={onSplitButtonSelect}
|
|
310
|
+
isOpen={splitButtonDropdownIsOpen}
|
|
311
|
+
onOpenChange={(isOpen) => setSplitButtonDropdownIsOpen(isOpen)}
|
|
312
|
+
toggle={(toggleRef) => (
|
|
313
|
+
<MenuToggle
|
|
314
|
+
ref={toggleRef}
|
|
315
|
+
isExpanded={splitButtonDropdownIsOpen}
|
|
316
|
+
onClick={onSplitButtonToggle}
|
|
317
|
+
aria-label="Select cards"
|
|
318
|
+
splitButtonOptions={{
|
|
319
|
+
items: [
|
|
320
|
+
<MenuToggleCheckbox
|
|
321
|
+
id="split-dropdown-checkbox"
|
|
322
|
+
key="split-dropdown-checkbox"
|
|
323
|
+
aria-label={anySelected ? 'Deselect all cards' : 'Select all cards'}
|
|
324
|
+
isChecked={areAllSelected}
|
|
325
|
+
onClick={splitCheckboxSelectAll.bind(this)}
|
|
326
|
+
>
|
|
327
|
+
{numSelected !== 0 && `${numSelected} selected`}
|
|
328
|
+
</MenuToggleCheckbox>
|
|
329
|
+
]
|
|
330
|
+
}}
|
|
331
|
+
></MenuToggle>
|
|
332
|
+
)}
|
|
333
|
+
>
|
|
334
|
+
<DropdownList>{splitButtonDropdownItems}</DropdownList>
|
|
335
|
+
</Dropdown>
|
|
336
|
+
);
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
const buildFilterDropdown = () => {
|
|
340
|
+
const filterDropdownItems = (
|
|
341
|
+
<SelectList>
|
|
342
|
+
<SelectOption
|
|
343
|
+
hasCheckbox
|
|
344
|
+
key="patternfly"
|
|
345
|
+
value="PatternFly"
|
|
346
|
+
isSelected={filters.products.includes('PatternFly')}
|
|
347
|
+
>
|
|
348
|
+
PatternFly
|
|
349
|
+
</SelectOption>
|
|
350
|
+
<SelectOption hasCheckbox key="activemq" value="ActiveMQ" isSelected={filters.products.includes('ActiveMQ')}>
|
|
351
|
+
ActiveMQ
|
|
352
|
+
</SelectOption>
|
|
353
|
+
<SelectOption
|
|
354
|
+
hasCheckbox
|
|
355
|
+
key="apachespark"
|
|
356
|
+
value="Apache Spark"
|
|
357
|
+
isSelected={filters.products.includes('Apache Spark')}
|
|
358
|
+
>
|
|
359
|
+
Apache Spark
|
|
360
|
+
</SelectOption>
|
|
361
|
+
<SelectOption hasCheckbox key="avro" value="Avro" isSelected={filters.products.includes('Avro')}>
|
|
362
|
+
Avro
|
|
363
|
+
</SelectOption>
|
|
364
|
+
<SelectOption
|
|
365
|
+
hasCheckbox
|
|
366
|
+
key="azureservices"
|
|
367
|
+
value="Azure Services"
|
|
368
|
+
isSelected={filters.products.includes('Azure Services')}
|
|
369
|
+
>
|
|
370
|
+
Azure Services
|
|
371
|
+
</SelectOption>
|
|
372
|
+
<SelectOption hasCheckbox key="crypto" value="Crypto" isSelected={filters.products.includes('Crypto')}>
|
|
373
|
+
Crypto
|
|
374
|
+
</SelectOption>
|
|
375
|
+
<SelectOption hasCheckbox key="dropbox" value="DropBox" isSelected={filters.products.includes('DropBox')}>
|
|
376
|
+
DropBox
|
|
377
|
+
</SelectOption>
|
|
378
|
+
<SelectOption
|
|
379
|
+
hasCheckbox
|
|
380
|
+
key="jbossdatagrid"
|
|
381
|
+
value="JBoss Data Grid"
|
|
382
|
+
isSelected={filters.products.includes('JBoss Data Grid')}
|
|
383
|
+
>
|
|
384
|
+
JBoss Data Grid
|
|
385
|
+
</SelectOption>
|
|
386
|
+
<SelectOption hasCheckbox key="rest" value="REST" isSelected={filters.products.includes('REST')}>
|
|
387
|
+
REST
|
|
388
|
+
</SelectOption>
|
|
389
|
+
<SelectOption hasCheckbox key="swagger" value="SWAGGER" isSelected={filters.products.includes('SWAGGER')}>
|
|
390
|
+
SWAGGER
|
|
391
|
+
</SelectOption>
|
|
392
|
+
</SelectList>
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
return (
|
|
396
|
+
<ToolbarFilter
|
|
397
|
+
categoryName="Products"
|
|
398
|
+
chips={filters.products}
|
|
399
|
+
deleteChip={(type, id) => onDelete(type as string, id as string)}
|
|
400
|
+
>
|
|
401
|
+
<Select
|
|
402
|
+
aria-label="Products"
|
|
403
|
+
role="menu"
|
|
404
|
+
toggle={(toggleRef) => (
|
|
405
|
+
<MenuToggle ref={toggleRef} onClick={onToolbarDropdownToggle} isExpanded={isLowerToolbarDropdownOpen}>
|
|
406
|
+
Filter by creator name
|
|
407
|
+
{filters.products.length > 0 && <Badge isRead>{filters.products.length}</Badge>}
|
|
408
|
+
</MenuToggle>
|
|
409
|
+
)}
|
|
410
|
+
onSelect={(event, selection) => onNameSelect(event, selection?.toString())}
|
|
411
|
+
onOpenChange={(isOpen) => {
|
|
412
|
+
setIsLowerToolbarDropdownOpen(isOpen);
|
|
413
|
+
}}
|
|
414
|
+
selected={filters.products}
|
|
415
|
+
isOpen={isLowerToolbarDropdownOpen}
|
|
416
|
+
>
|
|
417
|
+
{filterDropdownItems}
|
|
418
|
+
</Select>
|
|
419
|
+
</ToolbarFilter>
|
|
420
|
+
);
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
const toolbarKebabDropdownItems = (
|
|
424
|
+
<>
|
|
425
|
+
<DropdownItem value={0} key="action">
|
|
426
|
+
Action
|
|
427
|
+
</DropdownItem>
|
|
428
|
+
<DropdownItem
|
|
429
|
+
value={1}
|
|
430
|
+
key="link"
|
|
431
|
+
to="#default-link2"
|
|
432
|
+
// Prevent the default onClick functionality for example purposes
|
|
433
|
+
onClick={(ev) => ev.preventDefault()}
|
|
434
|
+
>
|
|
435
|
+
Link
|
|
436
|
+
</DropdownItem>
|
|
437
|
+
<DropdownItem value={2} isDisabled key="disabled action">
|
|
438
|
+
Disabled Action
|
|
439
|
+
</DropdownItem>
|
|
440
|
+
<DropdownItem value={3} isDisabled key="disabled link" to="#default-link4">
|
|
441
|
+
Disabled Link
|
|
442
|
+
</DropdownItem>
|
|
443
|
+
<Divider component="li" key="separator" />
|
|
444
|
+
<DropdownItem value={4} key="separated action">
|
|
445
|
+
Separated Action
|
|
446
|
+
</DropdownItem>
|
|
447
|
+
<DropdownItem value={5} key="separated link" to="#default-link6" onClick={(ev) => ev.preventDefault()}>
|
|
448
|
+
Separated Link
|
|
449
|
+
</DropdownItem>
|
|
450
|
+
</>
|
|
451
|
+
);
|
|
452
|
+
const toolbarItems = (
|
|
453
|
+
<React.Fragment>
|
|
454
|
+
<ToolbarItem>{buildSelectDropdown()}</ToolbarItem>
|
|
455
|
+
<ToolbarItem>{buildFilterDropdown()}</ToolbarItem>
|
|
456
|
+
<ToolbarItem>
|
|
457
|
+
<Button variant="primary">Create instance</Button>
|
|
458
|
+
</ToolbarItem>
|
|
459
|
+
<ToolbarItem>
|
|
460
|
+
<Button variant="secondary">Action</Button>
|
|
461
|
+
</ToolbarItem>
|
|
462
|
+
<ToolbarItem>
|
|
463
|
+
<Dropdown
|
|
464
|
+
onSelect={onToolbarKebabDropdownSelect}
|
|
465
|
+
isOpen={isLowerToolbarKebabDropdownOpen}
|
|
466
|
+
onOpenChange={(isOpen) => setIsLowerToolbarKebabDropdownOpen(isOpen)}
|
|
467
|
+
toggle={(toggleRef) => (
|
|
468
|
+
<MenuToggle
|
|
469
|
+
ref={toggleRef}
|
|
470
|
+
isExpanded={isLowerToolbarKebabDropdownOpen}
|
|
471
|
+
variant="plain"
|
|
472
|
+
onClick={onToolbarKebabDropdownToggle}
|
|
473
|
+
aria-label="Toolbar actions"
|
|
474
|
+
>
|
|
475
|
+
<EllipsisVIcon aria-hidden="true" />
|
|
476
|
+
</MenuToggle>
|
|
477
|
+
)}
|
|
478
|
+
>
|
|
479
|
+
<DropdownList>{toolbarKebabDropdownItems}</DropdownList>
|
|
480
|
+
</Dropdown>
|
|
481
|
+
</ToolbarItem>
|
|
482
|
+
<ToolbarItem variant="pagination" align={{ default: 'alignRight' }}>
|
|
483
|
+
{renderPagination()}
|
|
484
|
+
</ToolbarItem>
|
|
485
|
+
</React.Fragment>
|
|
486
|
+
);
|
|
487
|
+
|
|
488
|
+
const filtered =
|
|
489
|
+
filters.products.length > 0
|
|
490
|
+
? data.filter((card: { name: string }) => filters.products.length === 0 || filters.products.includes(card.name))
|
|
491
|
+
: cardData.slice((page - 1) * perPage, perPage === 1 ? page * perPage : page * perPage - 1);
|
|
492
|
+
|
|
493
|
+
const icons = {
|
|
494
|
+
pfIcon,
|
|
495
|
+
activeMQIcon,
|
|
496
|
+
sparkIcon,
|
|
497
|
+
avroIcon,
|
|
498
|
+
azureIcon,
|
|
499
|
+
saxonIcon,
|
|
500
|
+
dropBoxIcon,
|
|
501
|
+
infinispanIcon,
|
|
502
|
+
restIcon,
|
|
503
|
+
swaggerIcon
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
const drawerContent = (
|
|
507
|
+
<Gallery hasGutter role="region" aria-label="Selectable card container">
|
|
508
|
+
{filtered.map((product, key) => (
|
|
509
|
+
<Card
|
|
510
|
+
key={product.name}
|
|
511
|
+
id={'card-view-' + key}
|
|
512
|
+
isClickable
|
|
513
|
+
isSelectable
|
|
514
|
+
isSelected={activeCard === product.id}
|
|
515
|
+
>
|
|
516
|
+
<CardHeader
|
|
517
|
+
actions={{
|
|
518
|
+
actions: (
|
|
519
|
+
<>
|
|
520
|
+
<Dropdown
|
|
521
|
+
isOpen={!!state[key] ?? false}
|
|
522
|
+
onOpenChange={(isOpen) => setState({ [key]: isOpen })}
|
|
523
|
+
popperProps={{ position: 'right' }}
|
|
524
|
+
toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
|
|
525
|
+
<MenuToggle
|
|
526
|
+
ref={toggleRef}
|
|
527
|
+
aria-label={`${product.name} actions`}
|
|
528
|
+
variant="plain"
|
|
529
|
+
onClick={(e) => {
|
|
530
|
+
onCardKebabDropdownToggle(e, key.toString());
|
|
531
|
+
}}
|
|
532
|
+
isExpanded={!!state[key]}
|
|
533
|
+
>
|
|
534
|
+
<EllipsisVIcon />
|
|
535
|
+
</MenuToggle>
|
|
536
|
+
)}
|
|
537
|
+
>
|
|
538
|
+
<DropdownList>
|
|
539
|
+
<DropdownItem
|
|
540
|
+
key="trash"
|
|
541
|
+
onClick={() => {
|
|
542
|
+
deleteItem(product);
|
|
543
|
+
}}
|
|
544
|
+
>
|
|
545
|
+
<TrashIcon />
|
|
546
|
+
Delete
|
|
547
|
+
</DropdownItem>
|
|
548
|
+
</DropdownList>
|
|
549
|
+
</Dropdown>
|
|
550
|
+
</>
|
|
551
|
+
)
|
|
552
|
+
}}
|
|
553
|
+
selectableActions={{
|
|
554
|
+
isChecked: selectedItems.includes(product.id),
|
|
555
|
+
selectableActionId: `selectable-actions-item-${product.id}`,
|
|
556
|
+
selectableActionAriaLabelledby: `${'card-view-' + key}`,
|
|
557
|
+
name: `check-${product.id}`,
|
|
558
|
+
onChange
|
|
559
|
+
}}
|
|
560
|
+
>
|
|
561
|
+
<img src={icons[product.icon]} alt={`${product.name} icon`} style={{ height: '50px' }} />
|
|
562
|
+
</CardHeader>
|
|
563
|
+
<CardTitle>
|
|
564
|
+
<Flex direction={{ default: 'column' }} spaceItems={{ default: 'spaceItemsNone' }}>
|
|
565
|
+
<FlexItem>
|
|
566
|
+
<Button
|
|
567
|
+
variant="link"
|
|
568
|
+
isInline
|
|
569
|
+
onClick={() => onCardClick(product.id)}
|
|
570
|
+
aria-expanded={activeCard === product.id}
|
|
571
|
+
>
|
|
572
|
+
{product.name}
|
|
573
|
+
</Button>
|
|
574
|
+
</FlexItem>
|
|
575
|
+
<FlexItem>
|
|
576
|
+
<TextContent>
|
|
577
|
+
<Text component="small" className="pf-v5-u-color-200 pf-v5-u-font-family-text">
|
|
578
|
+
Provided by Red Hat
|
|
579
|
+
</Text>
|
|
580
|
+
</TextContent>
|
|
581
|
+
</FlexItem>
|
|
582
|
+
</Flex>
|
|
583
|
+
</CardTitle>
|
|
584
|
+
|
|
585
|
+
<CardBody>{product.description}</CardBody>
|
|
586
|
+
</Card>
|
|
587
|
+
))}
|
|
588
|
+
</Gallery>
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
const panelContent = (
|
|
592
|
+
<DrawerPanelContent>
|
|
593
|
+
<DrawerHead>
|
|
594
|
+
<Title headingLevel="h2" size="xl">
|
|
595
|
+
node-{activeCard}
|
|
596
|
+
</Title>
|
|
597
|
+
<DrawerActions>
|
|
598
|
+
<DrawerCloseButton onClick={onCloseDrawerClick} />
|
|
599
|
+
</DrawerActions>
|
|
600
|
+
</DrawerHead>
|
|
601
|
+
<DrawerPanelBody>
|
|
602
|
+
<Flex spaceItems={{ default: 'spaceItemsLg' }} direction={{ default: 'column' }}>
|
|
603
|
+
<FlexItem>
|
|
604
|
+
<p>
|
|
605
|
+
The content of the drawer really is up to you. It could have form fields, definition lists, text lists,
|
|
606
|
+
labels, charts, progress bars, etc. Spacing recommendation is 24px margins. You can put tabs in here, and
|
|
607
|
+
can also make the drawer scrollable.
|
|
608
|
+
</p>
|
|
609
|
+
</FlexItem>
|
|
610
|
+
<FlexItem>
|
|
611
|
+
<Progress value={activeCard * 10} title="Title" />
|
|
612
|
+
</FlexItem>
|
|
613
|
+
<FlexItem>
|
|
614
|
+
<Progress value={activeCard * 5} title="Title" />
|
|
615
|
+
</FlexItem>
|
|
616
|
+
</Flex>
|
|
617
|
+
</DrawerPanelBody>
|
|
618
|
+
</DrawerPanelContent>
|
|
619
|
+
);
|
|
620
|
+
|
|
621
|
+
return (
|
|
622
|
+
<DashboardWrapper mainContainerId="main-content-card-view-default-nav" breadcrumb={null}>
|
|
623
|
+
<PageSection variant={PageSectionVariants.light}>
|
|
624
|
+
<TextContent>
|
|
625
|
+
<Text component="h1">Projects</Text>
|
|
626
|
+
<Text component="p">This is a demo that showcases Patternfly Cards.</Text>
|
|
627
|
+
</TextContent>
|
|
628
|
+
</PageSection>
|
|
629
|
+
<PageSection isFilled padding={{ default: 'noPadding' }}>
|
|
630
|
+
<Toolbar id="card-view-data-toolbar-group-types" usePageInsets clearAllFilters={onDelete}>
|
|
631
|
+
<ToolbarContent>{toolbarItems}</ToolbarContent>
|
|
632
|
+
</Toolbar>
|
|
633
|
+
<Divider component="div" />
|
|
634
|
+
</PageSection>
|
|
635
|
+
<PageSection isFilled padding={{ default: 'noPadding' }}>
|
|
636
|
+
<Drawer isExpanded={isDrawerExpanded} className={'pf-m-inline-on-2xl'}>
|
|
637
|
+
<DrawerContent panelContent={panelContent} colorVariant="no-background">
|
|
638
|
+
<DrawerContentBody hasPadding>{drawerContent}</DrawerContentBody>
|
|
639
|
+
</DrawerContent>
|
|
640
|
+
</Drawer>
|
|
641
|
+
</PageSection>
|
|
642
|
+
<PageSection
|
|
643
|
+
isFilled={false}
|
|
644
|
+
stickyOnBreakpoint={{ default: 'bottom' }}
|
|
645
|
+
padding={{ default: 'noPadding' }}
|
|
646
|
+
variant="light"
|
|
647
|
+
>
|
|
648
|
+
<Pagination
|
|
649
|
+
itemCount={filtered.length}
|
|
650
|
+
page={page}
|
|
651
|
+
perPage={perPage}
|
|
652
|
+
onPerPageSelect={onPerPageSelect}
|
|
653
|
+
onSetPage={onSetPage}
|
|
654
|
+
variant="bottom"
|
|
655
|
+
/>
|
|
656
|
+
</PageSection>
|
|
657
|
+
</DashboardWrapper>
|
|
658
|
+
);
|
|
659
|
+
};
|