diff --git a/app/views/katello/api/v2/hosts/host_collections.json.rabl b/app/views/katello/api/v2/hosts/host_collections.json.rabl index 1d9ebeb30de..229aa16a8ae 100644 --- a/app/views/katello/api/v2/hosts/host_collections.json.rabl +++ b/app/views/katello/api/v2/hosts/host_collections.json.rabl @@ -1,3 +1,3 @@ child :host_collections => :host_collections do - attributes :id, :name + attributes :id, :name, :description, :max_hosts, :unlimited_hosts, :total_hosts end diff --git a/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard.js b/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard.js new file mode 100644 index 00000000000..af6be9a42a8 --- /dev/null +++ b/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard.js @@ -0,0 +1,150 @@ +import React, { useState } from 'react'; +import { + Badge, + Card, + CardHeader, + CardTitle, + CardBody, + Dropdown, + ExpandableSection, + KebabToggle, + Flex, + FlexItem, + GridItem, + DropdownItem, +} from '@patternfly/react-core'; + +import { translate as __ } from 'foremanReact/common/I18n'; +import { propsToCamelCase } from 'foremanReact/common/helpers'; +import PropTypes from 'prop-types'; +import { useSet } from '../../../Table/TableHooks'; + +const HostCollectionsDetails = ({ + hostCollections, +}) => { + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + const toggleBulkAction = () => setIsDropdownOpen(prev => !prev); + + const expandedHostCollections = useSet([]); + const openAddHostCollectionsModal = () => {}; // TODO: implement + const openRemoveHostCollectionsModal = () => {}; // TODO: implement + + const dropdownItems = [ + + {__('Add host to collections')} + , + + {__('Remove host from collections')} + , + ]; + + return ( + + + + + + + + {__('Host collections')} + + + {!!hostCollections?.length && {hostCollections.length}} + + + + + } + isOpen={isDropdownOpen} + isPlain + position="right" + dropdownItems={dropdownItems} + /> + + + + + {hostCollections?.map((hostCollection) => { + const { + id, name, description, maxHosts, unlimitedHosts, totalHosts, + } = propsToCamelCase(hostCollection); + const isExpanded = expandedHostCollections.has(id); + return ( + + + expandedHostCollections.onToggle(!isExpanded, id)} + isExpanded={isExpanded} + isIndented + > +
+ {description || {__('No description provided')}} +
+
+
+ + {totalHosts}/{unlimitedHosts ? 'unlimited' : maxHosts} + +
+ ); + })} +
+
+
+ ); +}; + +const HostCollectionsDetailsCard = ({ hostDetails }) => { + if (hostDetails) { + return ; + } + return null; +}; + +HostCollectionsDetails.propTypes = { + hostCollections: PropTypes.arrayOf(PropTypes.shape({})), +}; + +HostCollectionsDetails.defaultProps = { + hostCollections: [], +}; + +HostCollectionsDetailsCard.propTypes = { + hostDetails: PropTypes.shape({}), +}; + +HostCollectionsDetailsCard.defaultProps = { + hostDetails: null, +}; + +export default HostCollectionsDetailsCard; diff --git a/webpack/global_index.js b/webpack/global_index.js index 89da6409c0d..e26eb6cf077 100644 --- a/webpack/global_index.js +++ b/webpack/global_index.js @@ -14,6 +14,7 @@ import RepositorySetsTab from './components/extensions/HostDetails/Tabs/Reposito import TracesTab from './components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js'; import extendReducer from './components/extensions/reducers'; import rootReducer from './redux/reducers'; +import HostCollectionsDetailsCard from './components/extensions/HostDetails/Cards/HostCollectionsCard'; registerReducer('katelloExtends', extendReducer); registerReducer('katello', rootReducer); @@ -28,8 +29,14 @@ addGlobalFill('host-details-page-tabs', 'Repository sets', , 2000, ); +addGlobalFill( + 'details-cards', + 'Host collections', + , + 700, +); addGlobalFill('details-cards', 'Installable errata', , 1900);