import React, { useState, useCallback } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { Link } from 'react-router-dom'; import { omit } from 'lodash'; import { translate as __ } from 'foremanReact/common/I18n'; import LongDateTime from 'foremanReact/components/common/dates/LongDateTime'; import { useSet } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks'; import { useTableSort } from 'foremanReact/components/PF4/Helpers/useTableSort'; import { Button } from '@patternfly/react-core'; import { TableVariant, Thead, Tbody, Th, Tr, Td, ExpandableRowContent } from '@patternfly/react-table'; import TableWrapper from '../../../components/Table/TableWrapper'; import getContentViews from '../ContentViewsActions'; import CreateContentViewModal from '../Create/CreateContentViewModal'; import CopyContentViewModal from '../Copy/CopyContentViewModal'; import PublishContentViewWizard from '../Publish/PublishContentViewWizard'; import { selectContentViews, selectContentViewStatus, selectContentViewError } from '../ContentViewSelectors'; import ContentViewVersionPromote from '../Details/Promote/ContentViewVersionPromote'; import getEnvironmentPaths from '../components/EnvironmentPaths/EnvironmentPathActions'; import { hasPermission } from '../helpers'; import ContentViewIcon from '../components/ContentViewIcon'; import { urlBuilder } from '../../../__mocks__/foremanReact/common/urlHelpers'; import LastSync from '../Details/Repositories/LastSync'; import InactiveText from '../components/InactiveText'; import ContentViewVersionCell from './ContentViewVersionCell'; import DetailsExpansion from '../expansions/DetailsExpansion'; import ContentViewDeleteWizard from '../Delete/ContentViewDeleteWizard'; import { truncate } from '../../../utils/helpers'; const ContentViewTable = () => { const response = useSelector(selectContentViews); const status = useSelector(selectContentViewStatus); const error = useSelector(selectContentViewError); const [searchQuery, updateSearchQuery] = useState(''); const [isModalOpen, setIsModalOpen] = useState(false); const [copy, setCopy] = useState(false); const expandedTableRows = useSet([]); const tableRowIsExpanded = id => expandedTableRows.has(id); const [isPublishModalOpen, setIsPublishModalOpen] = useState(false); const [isPromoteModalOpen, setIsPromoteModalOpen] = useState(false); const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [actionableCvDetails, setActionableCvDetails] = useState({}); const [actionableCvId, setActionableCvId] = useState(''); const [actionableCvName, setActionableCvName] = useState(''); const dispatch = useDispatch(); const metadata = omit(response, ['results']); const { can_create: canCreate = false, can_view: canView = false, results, } = response; const columnHeaders = [ __('Type'), __('Name'), __('Last published'), __('Last task'), __('Latest version'), ]; const COLUMNS_TO_SORT_PARAMS = { [columnHeaders[1]]: 'name', }; const { pfSortParams, apiSortParams, activeSortColumn, activeSortDirection, } = useTableSort({ allColumns: columnHeaders, columnsToSortParams: COLUMNS_TO_SORT_PARAMS, initialSortColumnName: 'Name', }); const openForm = () => setIsModalOpen(true); const openPublishModal = (cvInfo) => { setActionableCvDetails(cvInfo); setIsPublishModalOpen(true); }; const openPromoteModal = (cvInfo) => { dispatch(getEnvironmentPaths()); setActionableCvDetails(cvInfo); setIsPromoteModalOpen(true); }; const openDeleteModal = (cvInfo) => { setActionableCvDetails(cvInfo); setIsDeleteModalOpen(true); }; const actionsWithPermissions = (cvInfo) => { const { version_count: cvVersionCount, generated_for: generatedFor, permissions } = cvInfo; const publishAction = { title: __('Publish'), isDisabled: generatedFor !== 'none', onClick: () => openPublishModal(cvInfo), }; const promoteAction = { title: __('Promote'), isDisabled: !cvVersionCount, onClick: () => openPromoteModal(cvInfo), }; const copyAction = { title: __('Copy'), onClick: () => { setCopy(true); setActionableCvId(cvInfo.id.toString()); setActionableCvName(cvInfo.name); }, }; const deleteAction = { title: __('Delete'), onClick: () => openDeleteModal(cvInfo), }; return [ ...(hasPermission(permissions, 'publish_content_views') ? [publishAction] : []), ...(hasPermission(permissions, 'promote_or_remove_content_views') ? [promoteAction] : []), ...(canCreate ? [copyAction] : []), ...(hasPermission(permissions, 'destroy_content_views') ? [deleteAction] : []), ]; }; const fetchItems = useCallback( params => getContentViews({ ...apiSortParams, ...params, }), [apiSortParams], ); const emptyContentTitle = __('No content views yet'); const emptyContentBody = __('You currently have no content views to display'); const emptySearchTitle = __('No matching content views found'); const emptySearchBody = __('Try changing your search settings.'); const showPrimaryAction = true; const { id, latest_version_id: latestVersionId, latest_version: latestVersionName, latest_version_environments: latestVersionEnvironments, environments, versions, } = actionableCvDetails; return ( {__('Create content view')} ) : undefined} actionButtons={ <> {results?.length !== 0 && canCreate && } { isPublishModalOpen && { if (makeCallback) { dispatch(getContentViews(apiSortParams)); } setIsPublishModalOpen(false); }} aria-label="publish_content_view_modal" /> } { isPromoteModalOpen && } { isDeleteModalOpen && } } > {columnHeaders.map(col => ( {col} ))} { results?.map((cvInfo, rowIndex) => { const { composite, name, id: cvId, last_published: lastPublished, latest_version: latestVersion, latest_version_id: cvLatestVersionId, latest_version_environments: cvLatestVersionEnvironments, last_task: lastTask, activation_keys: activationKeys, hosts, related_cv_count: relatedCVCount, related_composite_cvs: relatedCompositeCVs, description, createdAt, } = cvInfo; const { last_sync_words: lastSyncWords, started_at: startedAt } = lastTask ?? {}; const isExpanded = tableRowIsExpanded(cvId); return ( expandedTableRows.onToggle(isOpen, cvId), }} /> {truncate(name)} {lastPublished ? : } {latestVersion ? : } {description || } ); }) } ); }; export default ContentViewTable;