diff --git a/packages/react-core/src/demos/DataListDemo.md b/packages/react-core/src/demos/DataListDemo.md index 1ea2844f6c8..fbf29dd0f20 100644 --- a/packages/react-core/src/demos/DataListDemo.md +++ b/packages/react-core/src/demos/DataListDemo.md @@ -9,6 +9,14 @@ import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-i import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon'; import { css } from '@patternfly/react-styles'; +import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon'; +import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon'; +import ExclamationTriangleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-triangle-icon'; +import CheckCircleIcon from '@patternfly/react-icons/dist/esm/icons/check-circle-icon'; +import TimesCircleIcon from '@patternfly/react-icons/dist/esm/icons/times-circle-icon'; +import AngleDownIcon from '@patternfly/react-icons/dist/esm/icons/angle-down-icon'; +import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon'; + ## Demos ### Expandable control in toolbar @@ -418,3 +426,899 @@ class ExpandableDataList extends React.Component { } } ``` +### Card view + +```js isFullscreen +import React from 'react'; +import { + Badge, + Button, + DataList, + DataListItem, + DataListCell, + DataListItemRow, + DataListItemCells, + Dropdown, + DropdownItem, + DropdownList, + Flex, + FlexItem, + MenuToggle, + OverflowMenu, + OverflowMenuControl, + OverflowMenuItem, + PageSection, + PageSectionVariants, + Pagination, + TextContent, + Text, + TextContent, + TextVariants, + Toolbar, + ToolbarItem, + ToolbarFilter, + ToolbarContent, + Select, + SelectList, +} from '@patternfly/react-core'; +import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon'; +import DashboardWrapper from '@patternfly/react-core/src/demos/examples/DashboardWrapper'; + +import CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon'; +import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon'; +import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon'; +import ExclamationTriangleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-triangle-icon'; +import CheckCircleIcon from '@patternfly/react-icons/dist/esm/icons/check-circle-icon'; +import TimesCircleIcon from '@patternfly/react-icons/dist/esm/icons/times-circle-icon'; + +class DataListViewBasic extends React.Component { + constructor(props) { + super(props); + + this.state = { + filters: { + products: [] + }, + res: [], + isChecked: false, + selectedItems: [], + areAllSelected: false, + isUpperToolbarDropdownOpen: false, + isUpperToolbarKebabDropdownOpen: false, + isLowerToolbarDropdownOpen: false, + isLowerToolbarKebabDropdownOpen: false, + isCardKebabDropdownOpen: false, + activeItem: 0, + splitButtonDropdownIsOpen: false, + page: 1, + perPage: 10, + totalItemCount: 10 + }; + + this.checkAllSelected = (selected, total) => { + if (selected && selected < total) { + return null; + } + return selected === total; + }; + + this.onToolbarDropdownToggle = () => { + this.setState((prevState) => ({ + isLowerToolbarDropdownOpen: !prevState.isLowerToolbarDropdownOpen + })); + }; + + this.onToolbarKebabDropdownToggle = () => { + this.setState({ + isOpen: !this.state.isLowerToolbarKebabDropdownOpen + }); + }; + + this.onToolbarKebabDropdownSelect = (event) => { + this.setState({ + isLowerToolbarKebabDropdownOpen: !this.state.isLowerToolbarKebabDropdownOpen + }); + }; + + this.onCardKebabDropdownToggle = (key) => { + this.setState((prevState) => ({ + [key]: !prevState[key] + })); + }; + + this.onCardKebabDropdownSelect = (key, event) => { + this.setState({ + [key]: !this.state[key] + }); + }; + + this.deleteItem = (item) => (event) => { + const filter = (getter) => (val) => getter(val) !== item.id; + this.setState({ + res: this.state.res.filter(filter(({ id }) => id)), + selectedItems: this.state.selectedItems.filter(filter((id) => id)) + }); + }; + + this.onSetPage = (_event, pageNumber) => { + this.setState({ + page: pageNumber + }); + }; + + this.onPerPageSelect = (_event, perPage) => { + this.setState({ + perPage + }); + }; + + this.onSplitButtonToggle = () => { + this.setState((prevState) => ({ + splitButtonDropdownIsOpen: !prevState.splitButtonDropdownIsOpen + })); + }; + + this.onSplitButtonSelect = () => { + this.setState({ + splitButtonDropdownIsOpen: false + }); + }; + + this.onNameSelect = (event, selection) => { + const checked = event.target.checked; + this.setState((prevState) => { + const prevSelections = prevState.filters['products']; + return { + filters: { + ...prevState.filters, + ['products']: checked + ? [...prevSelections, selection] + : prevSelections.filter((value) => value !== selection) + } + }; + }); + }; + + this.onDelete = (type = '', id = '') => { + if (type) { + this.setState((prevState) => { + prevState.filters[type.toLowerCase()] = prevState.filters[type.toLowerCase()].filter((s) => s !== id); + return { + filters: prevState.filters + }; + }); + } else { + this.setState({ + filters: { + products: [] + } + }); + } + }; + + this.onKeyDown = (event, productId) => { + if (event.target !== event.currentTarget) { + return; + } + if ([' ', 'Enter'].includes(event.key)) { + event.preventDefault(); + this.setState((prevState) => { + return prevState.selectedItems.includes(productId * 1) + ? { + selectedItems: [...prevState.selectedItems.filter((id) => productId * 1 != id)], + areAllSelected: this.checkAllSelected(prevState.selectedItems.length - 1, prevState.totalItemCount) + } + : { + selectedItems: [...prevState.selectedItems, productId * 1], + areAllSelected: this.checkAllSelected(prevState.selectedItems.length + 1, prevState.totalItemCount) + }; + }); + } + }; + + this.onClick = (productId) => { + this.setState((prevState) => { + return prevState.selectedItems.includes(productId * 1) + ? { + selectedItems: [...prevState.selectedItems.filter((id) => productId * 1 != id)], + areAllSelected: this.checkAllSelected(prevState.selectedItems.length - 1, prevState.totalItemCount) + } + : { + selectedItems: [...prevState.selectedItems, productId * 1], + areAllSelected: this.checkAllSelected(prevState.selectedItems.length + 1, prevState.totalItemCount) + }; + }); + }; + } + + selectedItems(e) { + const { value, checked } = e.target; + let { selectedItems } = this.state; + + if (checked) { + selectedItems = [...selectedItems, value]; + } else { + selectedItems = selectedItems.filter((el) => el !== value); + if (this.state.areAllSelected) { + this.setState({ + areAllSelected: !this.state.areAllSelected + }); + } + } + this.setState({ selectedItems }); + } + + splitCheckboxSelectAll(e) { + const { checked } = e.target; + const { isChecked, res } = this.state; + let collection = []; + + if (checked) { + for (var i = 0; i <= 9; i++) collection = [...collection, i]; + } + + this.setState( + { + selectedItems: collection, + isChecked: isChecked, + areAllSelected: checked + }, + this.updateSelected + ); + } + + selectPage(e) { + const { checked } = e.target; + const { isChecked, totalItemCount, perPage } = this.state; + let collection = []; + + collection = this.getAllItems(); + + this.setState( + { + selectedItems: collection, + isChecked: checked, + areAllSelected: totalItemCount === perPage ? true : false + }, + this.updateSelected + ); + } + + selectAll(e) { + const { checked } = e.target; + const { isChecked } = this.state; + + let collection = []; + for (var i = 0; i <= 9; i++) collection = [...collection, i]; + + this.setState( + { + selectedItems: collection, + isChecked: true, + areAllSelected: true + }, + this.updateSelected + ); + } + + selectNone(e) { + const { checked } = e.target; + const { isChecked, selectedItems } = this.state; + this.setState( + { + selectedItems: [], + isChecked: false, + areAllSelected: false + }, + this.updateSelected + ); + } + + getAllItems() { + const { res } = this.state; + const collection = []; + for (const items of res) { + collection.push(items.id); + } + + return collection; + } + + updateSelected() { + const { res, selectedItems } = this.state; + let rows = res.map((post) => { + post.selected = selectedItems.includes(post.id); + return post; + }); + + this.setState({ + res: rows + }); + } + + fetch(page, perPage) { + fetch(`https://my-json-server.typicode.com/jenny-s51/cardviewdata/posts?_page=${page}&_limit=${perPage}`) + .then((resp) => resp.json()) + .then((resp) => this.setState({ res: resp, perPage, page })) + .then(() => this.updateSelected()) + .catch((err) => this.setState({ error: err })); + } + + componentDidMount() { + this.fetch(this.state.page, this.state.perPage); + } + + renderPagination() { + const { page, perPage, totalItemCount } = this.state; + + const defaultPerPageOptions = [ + { + title: '1', + value: 1 + }, + { + title: '5', + value: 5 + }, + { + title: '10', + value: 10 + } + ]; + + return ( + { + this.fetch(value, perPage); + }} + onPerPageSelect={(_evt, value) => { + this.fetch(1, value); + }} + variant="top" + isCompact + /> + ); + } + + buildSelectDropdown() { + const { splitButtonDropdownIsOpen, selectedItems, areAllSelected } = this.state; + const numSelected = selectedItems.length; + const allSelected = areAllSelected; + const anySelected = numSelected > 0; + const someChecked = anySelected ? null : false; + const isChecked = allSelected ? true : someChecked; + const splitButtonDropdownItems = ( + <> + + Select none (0 items) + + + Select page ({this.state.perPage} items) + + + Select all ({this.state.totalItemCount} items) + + + ); + return ( + this.setState({ splitButtonDropdownIsOpen: isOpen })} + toggle={(toggleRef) => ( + + {numSelected !== 0 && `${numSelected} selected`} + + ] + }} + > + )} + > + {splitButtonDropdownItems} + + ); + } + + buildFilterDropdown() { + const { isLowerToolbarDropdownOpen, filters } = this.state; + + const filterDropdownItems = ( + + PatternFly + ActiveMQ + Apache Spark + Avro + Azure Services + Crypto + DropBox + JBoss Data Grid + REST + SWAGGER + + ); + + return ( + + + + ); + } + + render() { + const { + isUpperToolbarDropdownOpen, + isLowerToolbarDropdownOpen, + isUpperToolbarKebabDropdownOpen, + isLowerToolbarKebabDropdownOpen, + isCardKebabDropdownOpen, + splitButtonDropdownIsOpen, + activeItem, + filters, + res, + checked, + selectedItems, + areAllSelected, + isChecked, + page, + perPage + } = this.state; + + const toolbarKebabDropdownItems = [ + + Link + , + + Action + , + + Disabled Link + , + + Disabled Action + , + , + + Separated Link + , + + Separated Action + + ]; + + const toolbarItems = ( + + {this.buildSelectDropdown()} + {this.buildFilterDropdown()} + + + + + + + ( + + + + )} + isOpen={isLowerToolbarKebabDropdownOpen} + onOpenChange={(isOpen) => this.setState({ isLowerToolbarKebabDropdownOpen: isOpen })} + > + {toolbarKebabDropdownItems} + + + + + + {this.renderPagination()} + + + ); + + const filtered = + filters.products.length > 0 + ? res.filter((card) => { + return filters.products.length === 0 || filters.products.includes(card.name); + }) + : res; + + const icons = { + pfIcon, + activeMQIcon, + sparkIcon, + avroIcon, + azureIcon, + saxonIcon, + dropBoxIcon, + infinispanIcon, + restIcon, + swaggerIcon + }; + + + return ( + + + + ); + } + + render() { + const { + isLowerToolbarKebabDropdownOpen, + + page + } = this.state; + + const toolbarKebabDropdownItems = []; + + const toolbarItems = ( + + {this.buildSelectDropdown()} + {this.buildFilterDropdown()} + + + + + + + ( + + + + )} + isOpen={isLowerToolbarKebabDropdownOpen} + > + {toolbarKebabDropdownItems} + + + + + + {this.renderPagination()} + + + ); + + return ( + + + + + Projects + This is a demo that showcases PatternFly DataList. + + + + + {toolbarItems} + + + + + + + + patternfly + + + + Working repo for PatternFly 4{' '} + + + + + + + \xa0 10 + + + \xa0 \xa0 4 + + + \xa0 \xa0 5 + + \xa0 \xa0 Updated 2 days ago + + + + , + + + + + + + + + + + ]} + /> + + + + + + + + patternfly-elements + + + PatternFly elements + + + + + \xa0 5 + + + \xa0 \xa0 9 + + + \xa0 \xa0 2 + + + \xa0 + \xa0 11 + + + \xa0 \xa0 4 + + + \xa0 + \xa0 1 + + \xa0 \xa0 Updated 2 days ago + + + + , + + + + + + + + + + + ]} + /> + + + + + + + + patternfly-unified-design-kit + + + , + + + + + + + + + + + ]} + /> + + + + + + + + patternfly + + + + Working repo for PatternFly 4{' '} + + + + + + + + \xa0 10 + + + \xa0 \xa0 4 + + + \xa0 \xa0 5 + + \xa0 \xa0 Updated 2 days ago + + + + , + + + + + + + + + + + ]} + /> + + + + + + + + patternfly-elements + + + PatternFly elements + + + + + \xa0 5 + + + \xa0 \xa0 9 + + + \xa0 \xa0 2 + + + \xa0 + \xa0 11 + + + \xa0 \xa0 4 + + + \xa0 \xa0 1 + + \xa0 \xa0 Updated 2 days ago + + + + , + + + + + + + + + + + ]} + /> + + + + + + + + + + ); + } +} +``` \ No newline at end of file