import React, { useState } from 'react'; import { Modal, Button, Dropdown, DropdownItem, DropdownToggle, DropdownDirection, DropdownToggleAction } from '@patternfly/react-core'; import { CaretDownIcon, CaretUpIcon } from '@patternfly/react-icons'; import { useSelector } from 'react-redux'; import { FormattedMessage } from 'react-intl'; import { Thead, Th, Tbody, Tr, Td, TableVariant } from '@patternfly/react-table'; import { noop } from 'foremanReact/common/helpers'; import { translate as __ } from 'foremanReact/common/I18n'; import { urlBuilder } from 'foremanReact/common/urlHelpers'; import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors'; import { useBulkSelect } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks'; import PropTypes from 'prop-types'; import TableWrapper from '../../../../Table/TableWrapper'; import { HOST_INSTALLABLE_DEBS_KEY } from './InstallableDebsConstants'; import { selectHostInstallableDebsStatus } from './InstallableDebsSelectors'; import { getHostInstallableDebs } from './InstallableDebsActions'; import './DebInstallModal.scss'; import { katelloPackageInstallBySearchUrl, katelloPackageInstallUrl } from '../customizedRexUrlHelpers'; import hostIdNotReady from '../../HostDetailsActions'; const InstallDropdown = ({ isDisabled, installViaRex, bulkCustomizedRexUrl, }) => { const [isActionOpen, setIsActionOpen] = useState(false); const onActionSelect = () => { setIsActionOpen(false); }; const onActionToggle = () => { setIsActionOpen(prev => !prev); }; const dropdownItems = [ {__('Install via remote execution')} , {__('Install via customized remote execution')} , ]; return ( Install , ]} splitButtonVariant="action" toggleVariant="primary" toggleIndicator={isActionOpen ? CaretUpIcon : CaretDownIcon} onToggle={onActionToggle} /> } isOpen={isActionOpen} dropdownItems={dropdownItems} /> ); }; InstallDropdown.propTypes = { isDisabled: PropTypes.bool, installViaRex: PropTypes.func, bulkCustomizedRexUrl: PropTypes.string, }; InstallDropdown.defaultProps = { isDisabled: false, installViaRex: noop, bulkCustomizedRexUrl: '', }; const DebInstallModal = ({ isOpen, closeModal, hostId, hostName, triggerPackageInstall, }) => { const emptyContentTitle = __('No packages available to install'); const emptyContentBody = __('No packages available to install on this host. Please check the host\'s content view and lifecycle environment.'); const emptySearchTitle = __('No matching packages found'); const emptySearchBody = __('Try changing your search settings.'); const columnHeaders = ['', __('Package'), __('Version')]; const response = useSelector(state => selectAPIResponse(state, HOST_INSTALLABLE_DEBS_KEY)); const status = useSelector(state => selectHostInstallableDebsStatus(state)); const { results, ...metadata } = response; const [suppressFirstFetch, setSuppressFirstFetch] = useState(false); const { searchQuery, updateSearchQuery, isSelected, selectOne, selectNone, fetchBulkParams, isSelectable, selectedCount, selectedResults, ...selectAll } = useBulkSelect({ results, metadata }); const fetchItems = (params) => { if (!hostId) return hostIdNotReady; if (results?.length > 0 && suppressFirstFetch) { // If the modal has already been opened, no need to re-fetch the data that's already present setSuppressFirstFetch(false); return { type: 'HOST_APPLICABLE_PACKAGES_NOOP' }; } return getHostInstallableDebs(hostId, params); }; const selectedPackageNames = () => selectedResults.map(({ name }) => name); const installViaRex = () => { triggerPackageInstall(fetchBulkParams()); selectNone(); closeModal(); }; const handleModalClose = () => { setSuppressFirstFetch(true); closeModal(); }; const bulkCustomizedRexUrl = selectedCount ? katelloPackageInstallBySearchUrl({ hostname: hostName, search: fetchBulkParams() }) : '#'; const simpleBulkCustomizedRexUrl = katelloPackageInstallUrl({ hostname: hostName, packages: selectedPackageNames() }); const enableSimpleRexUrl = !!selectedResults.length; const modalActions = ([ , Cancel , ]); return ( {hostName}, }} /> {columnHeaders.map(col => {col})} {results?.map((pkg, rowIndex) => { const { id, name: packageName, deb_id: debId, version, } = pkg; return ( selectOne(selected, id, pkg), rowIndex, variant: 'checkbox', }} /> {debId ? {packageName} : packageName } {version} ); }) } ); }; DebInstallModal.propTypes = { isOpen: PropTypes.bool.isRequired, closeModal: PropTypes.func.isRequired, hostId: PropTypes.number.isRequired, hostName: PropTypes.string.isRequired, triggerPackageInstall: PropTypes.func.isRequired, }; export default DebInstallModal;