import React, { useState, useEffect, useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { TableVariant, TableText, Tbody, Thead, Td, Tr, Th } from '@patternfly/react-table';
import { Checkbox, Dropdown, DropdownItem, Grid, KebabToggle, GridItem, Button } from '@patternfly/react-core';
import { translate as __ } from 'foremanReact/common/I18n';
import { urlBuilder } from 'foremanReact/common/urlHelpers';
import { STATUS } from 'foremanReact/constants';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { first } from 'lodash';
import { useSelectionSet } from '../../../../components/Table/TableHooks';
import TableWrapper from '../../../../components/Table/TableWrapper';
import InactiveText from '../../components/InactiveText';
import ContentViewVersionEnvironments from './ContentViewVersionEnvironments';
import ContentViewVersionErrata from './ContentViewVersionErrata';
import ContentViewVersionContent from './ContentViewVersionContent';
import getContentViewDetails, { getContentViewVersions } from '../ContentViewDetailActions';
import {
selectCVVersions,
selectCVVersionsStatus,
selectCVVersionsError,
selectCVDetails, selectCVNeedsPublish,
} from '../ContentViewDetailSelectors';
import getEnvironmentPaths from '../../components/EnvironmentPaths/EnvironmentPathActions';
import ContentViewVersionPromote from '../Promote/ContentViewVersionPromote';
import TaskPresenter from '../../components/TaskPresenter/TaskPresenter';
import RemoveCVVersionWizard from './Delete/RemoveCVVersionWizard';
import { hasPermission } from '../../helpers';
import BulkDeleteModal from './BulkDelete/BulkDeleteModal';
import { selectEnvironmentPathsStatus } from '../../components/EnvironmentPaths/EnvironmentPathSelectors';
import PublishContentViewWizard from '../../Publish/PublishContentViewWizard';
import CVVersionCompare from './Compare/CVVersionCompare';
import NeedsPublishIcon from '../../components/NeedsPublishIcon';
import FiltersAppliedIcon from '../../components/FiltersAppliedIcon';
const ContentViewVersions = ({ cvId, details }) => {
const response = useSelector(state => selectCVVersions(state, cvId));
const { results, ...metadata } = response;
const { versions: cvDetails } = useSelector(state => selectCVDetails(state, cvId));
const firstIdWithActiveHistory =
results?.find(({ active_history: activeHistory }) =>
activeHistory?.length)?.id;
const status = useSelector(state => selectCVVersionsStatus(state, cvId));
const error = useSelector(state => selectCVVersionsError(state, cvId));
const envStatus = useSelector(state => selectEnvironmentPathsStatus(state, cvId));
const dispatch = useDispatch();
const [searchQuery, updateSearchQuery] = useState('');
const [versionIdToPromote, setVersionIdToPromote] = useState('');
const [versionNameToPromote, setVersionNameToPromote] = useState('');
const [versionIdToRemove, setVersionIdToRemove] = useState('');
const [versionNameToRemove, setVersionNameToRemove] = useState('');
const [versionEnvironments, setVersionEnvironments] = useState([]);
const [bulkDeleteModalOpen, setBulkDeleteModalOpen] = useState(false);
const [isPublishModalOpen, setIsPublishModalOpen] = useState(false);
const [promoting, setPromoting] = useState(false);
const [removingFromEnv, setRemovingFromEnv] = useState(false);
const [deleteVersion, setDeleteVersion] = useState(false);
const [currentStep, setCurrentStep] = useState(1);
const {
permissions, needs_publish: needsPublish, composite, latest_version_id: latestVersionId,
} = details;
const needsPublishLocal = useSelector(state => selectCVNeedsPublish(state));
const [kebabOpen, setKebabOpen] = useState(false);
const hasActionPermissions = hasPermission(permissions, 'promote_or_remove_content_views');
const hasPublishCvPermissions = hasPermission(permissions, 'publish_content_views');
const renderActionButtons =
hasActionPermissions && status === STATUS.RESOLVED && !!results?.length;
const renderPublishCvModal =
hasPublishCvPermissions && status === STATUS.RESOLVED && isPublishModalOpen;
const {
selectOne, isSelected, isSelectable: _isSelectable,
selectedCount, selectionSet, ...selectionSetVars
} = useSelectionSet({
results,
metadata,
});
const showPrimaryAction = true;
const primaryActionButton =
(
);
const versionOneId = String([...selectionSet].sort()[0]);
const versionTwoId = String([...selectionSet].sort()[1]);
const fetchItems = useCallback((params) => {
selectionSet.clear();
return getContentViewVersions(cvId, params);
}, [cvId, selectionSet]);
const columnHeaders = [
'',
__('Version'),
__('Environments'),
__('Packages'),
__('Errata'),
__('Additional content'),
__('Description'),
];
const versionOneLabel = String(cvDetails?.find(version =>
Number(version.id) === Number(versionOneId))?.version);
const versionTwoLabel = String(cvDetails?.find(version =>
Number(version.id) === Number(versionTwoId))?.version);
useEffect(
() => {
if (envStatus !== STATUS.RESOLVED) { dispatch(getEnvironmentPaths()); }
},
// We only want this to fire once
// eslint-disable-next-line react-hooks/exhaustive-deps
[dispatch],
);
const buildCells = (cvVersion) => {
const {
version,
description,
id: versionId,
environments,
rpm_count: packageCount,
errata_counts: errataCounts,
active_history: activeHistory,
filters_applied: filtersApplied,
} = cvVersion;
if (activeHistory?.length) {
return [
'',
{__('Version ')}{version},
,
'',
'',
'',
description ? {description} : ,
];
}
return [
selectOne(selected, versionId)}
/>,
<>
{__('Version ')}{version}
{(latestVersionId === versionId &&
(needsPublish === null || needsPublish || needsPublishLocal)) &&
}
{(filtersApplied) &&
}
>,
,
Number(packageCount) ?
{packageCount} :
,
,
,
description ? {description} : ,
];
};
const onPromote = ({ cvVersionId, cvVersionName, cvVersionEnvironments }) => {
setVersionIdToPromote(cvVersionId);
setVersionNameToPromote(cvVersionName);
setVersionEnvironments(cvVersionEnvironments);
setPromoting(true);
};
const onRemoveFromEnv = ({
cvVersionId, cvVersionName, cvVersionEnvironments, deleting,
}) => {
setVersionIdToRemove(cvVersionId);
setVersionNameToRemove(cvVersionName);
setVersionEnvironments(cvVersionEnvironments);
setRemovingFromEnv(true);
setDeleteVersion(deleting);
};
const rowDropdownItems = ({
version,
id: versionId,
environments,
}) =>
[
{
title: __('Promote'),
onClick: () => {
onPromote({
cvVersionId: versionId,
cvVersionName: version,
cvVersionEnvironments: environments,
});
},
},
{
title: __('Remove from environments'),
onClick: () => {
onRemoveFromEnv({
cvVersionId: versionId,
cvVersionName: version,
cvVersionEnvironments: environments,
deleting: false,
});
},
},
{
title: __('Delete'),
onClick: () => {
selectionSet.clear();
selectOne(true, versionId);
setBulkDeleteModalOpen(true);
},
},
];
const emptyContentTitle = __('No versions yet');
const emptyContentBody = __('Versions will appear here when the content view is published.');
const emptySearchTitle = __('No matching version found');
const emptySearchBody = __('Try changing your search settings.');
const selectedVersionIds = {
versionOneId,
versionTwoId,
};
const [hasTwoVersions, setHasTwoVersions] = useState(false);
if (hasTwoVersions) {
const versionLabels = {
versionOneLabel,
versionTwoLabel,
};
return (
);
}
return (
{renderPublishCvModal &&
{
if (step3) dispatch(getContentViewDetails(cvId));
setIsPublishModalOpen(false);
}}
aria-label="publish_content_view_modal"
/>}
{renderActionButtons && (
}
isOpen={kebabOpen}
ouiaId="cv-versions-bulk-actions"
isPlain
dropdownItems={[
{
setKebabOpen(false);
setBulkDeleteModalOpen(true);
}}
>
{__('Delete')}
]}
/>
)}
>
}
displaySelectAllCheckbox={renderActionButtons}
>
{bulkDeleteModalOpen &&
selectionSet.has(id))}
onClose={() => {
selectionSet.clear();
setBulkDeleteModalOpen(false);
}}
/>
}
{promoting &&
}
{removingFromEnv &&
}
{columnHeaders.map((title, index) => {
if (index === 0 && !hasActionPermissions) return undefined;
return {title} | ;
})}
{results?.map((cvVersion) => {
const hasHistory = !!cvVersion?.active_history?.length;
const cells = buildCells(cvVersion);
return (
{cells.map((cell, index) => {
if (index === 0 && !hasActionPermissions) return undefined;
return (
{cell}
| );
})}
{(!hasHistory && hasActionPermissions) &&
| }
);
})}
);
};
ContentViewVersions.propTypes = {
cvId: PropTypes.number.isRequired,
details: PropTypes.shape({
permissions: PropTypes.shape({}),
needs_publish: PropTypes.bool,
composite: PropTypes.bool,
latest_version_id: PropTypes.number,
}).isRequired,
};
export default ContentViewVersions;