import React, { useState, useEffect, useCallback } from 'react';
import useDeepCompareEffect from 'use-deep-compare-effect';
import PropTypes from 'prop-types';
import { shallowEqual, useSelector, useDispatch } from 'react-redux';
import { TableVariant } from '@patternfly/react-table';
import {
Tabs, Tab, TabTitleText, Split, SplitItem, Button,
Select, SelectVariant, SelectOption, Dropdown, DropdownItem, KebabToggle,
} from '@patternfly/react-core';
import { STATUS } from 'foremanReact/constants';
import { translate as __ } from 'foremanReact/common/I18n';
import onSelect from '../../../../components/Table/helpers';
import TableWrapper from '../../../../components/Table/TableWrapper';
import {
selectCVFilterPackageGroups,
selectCVFilterPackageGroupStatus,
selectCVFilterPackageGroupError,
selectCVFilters, selectCVFilterDetails,
} from '../ContentViewDetailSelectors';
import AddedStatusLabel from '../../../../components/AddedStatusLabel';
import getContentViewDetails, {
addCVFilterRule, removeCVFilterRule, getCVFilterPackageGroups,
deleteContentViewFilterRules, addContentViewFilterRules,
} from '../ContentViewDetailActions';
import AffectedRepositoryTable from './AffectedRepositories/AffectedRepositoryTable';
import { ADDED, ALL_STATUSES, NOT_ADDED } from '../../ContentViewsConstants';
import { hasPermission } from '../../helpers';
const CVPackageGroupFilterContent = ({
cvId, filterId, showAffectedRepos, setShowAffectedRepos, details,
}) => {
const dispatch = useDispatch();
const { results: filterResults } =
useSelector(state => selectCVFilters(state, cvId), shallowEqual);
const response = useSelector(state =>
selectCVFilterPackageGroups(state, cvId, filterId), shallowEqual);
const status = useSelector(state =>
selectCVFilterPackageGroupStatus(state, cvId, filterId), shallowEqual);
const error = useSelector(state =>
selectCVFilterPackageGroupError(state, cvId, filterId), shallowEqual);
const filterDetails = useSelector(state =>
selectCVFilterDetails(state, cvId, filterId), shallowEqual);
const { repositories = [] } = filterDetails;
const [rows, setRows] = useState([]);
const [searchQuery, updateSearchQuery] = useState('');
const [activeTabKey, setActiveTabKey] = useState(0);
const loading = status === STATUS.PENDING;
const [bulkActionOpen, setBulkActionOpen] = useState(false);
const [selectOpen, setSelectOpen] = useState(false);
const [selectedIndex, setSelectedIndex] = useState(0);
const deselectAll = () => setRows(rows.map(row => ({ ...row, selected: false })));
const toggleBulkAction = () => setBulkActionOpen(prevState => !prevState);
const hasAddedSelected = rows.some(({ selected, added }) => selected && added);
const hasNotAddedSelected = rows.some(({ selected, added }) => selected && !added);
const { results, ...metadata } = response;
const { permissions } = details;
const columnHeaders = [
__('Name'),
__('Product'),
__('Repository'),
__('Description'),
__('Status'),
];
const allAddedNotAdded = [
ALL_STATUSES,
ADDED,
NOT_ADDED,
];
const selectedAdded = allAddedNotAdded[selectedIndex];
const fetchItems = useCallback((params) => {
const adjustedParams = { ...params };
switch (selectedIndex) {
case 0:
adjustedParams.show_all_for = 'content_view_filter';
adjustedParams.available_for = undefined;
break;
case 1:
adjustedParams.show_all_for = undefined;
adjustedParams.available_for = undefined;
break;
case 2:
adjustedParams.show_all_for = undefined;
adjustedParams.available_for = 'content_view_filter';
break;
default:
}
return getCVFilterPackageGroups(cvId, filterId, adjustedParams);
}, [cvId, filterId, selectedIndex]);
const buildRows = useCallback(() => {
const newRows = [];
const filterRules = filterResults.find(({ id }) => id === Number(filterId))?.rules || [];
results.forEach((packageGroups) => {
const {
name,
description,
repository: {
name: repositoryName,
product: { name: productName },
},
filter_ids: filterIds,
...rest
} = packageGroups;
const cells = [
{ title: name },
{ title: productName },
{ title: repositoryName },
{ title: description },
{ title: },
];
newRows.push({
cells,
packagefilterId: filterRules?.find(({ uuid }) => uuid === rest.uuid)?.id,
added: filterIds.includes(parseInt(filterId, 10)),
...rest,
name,
});
});
return newRows.sort(({ added: addedA }, { added: addedB }) => {
if (addedA === addedB) return 0;
return addedA ? -1 : 1;
});
}, [filterResults, filterId, results]);
const bulkAdd = () => {
setBulkActionOpen(false);
const addData = rows.filter(({ selected, added }) =>
selected && !added).map(({ uuid }) => ({ uuid }));
dispatch(addContentViewFilterRules(filterId, addData, () =>
dispatch(getContentViewDetails(cvId))));
deselectAll();
};
const bulkRemove = () => {
setBulkActionOpen(false);
const packageFilterIds =
rows.filter(({ selected, added }) =>
selected && added).map(({ packagefilterId }) => packagefilterId);
dispatch(deleteContentViewFilterRules(filterId, packageFilterIds, () =>
dispatch(getContentViewDetails(cvId))));
deselectAll();
};
useEffect(() => {
if (!repositories.length && showAffectedRepos) {
setActiveTabKey(1);
} else {
setActiveTabKey(0);
}
}, [showAffectedRepos, repositories.length]);
useDeepCompareEffect(() => {
if (!loading && results) {
const newRows = buildRows();
setRows(newRows);
}
}, [response, loading, buildRows, results]);
const actionResolver = ({ added }) => [
{
title: __('Add'),
isDisabled: added,
onClick: (_event, _rowId, { uuid }) => {
dispatch(addCVFilterRule(filterId, { uuid }, () =>
dispatch(getContentViewDetails(cvId))));
},
},
{
title: __('Remove'),
isDisabled: !added,
onClick: (_event, _rowId, { packagefilterId }) => {
dispatch(removeCVFilterRule(filterId, packagefilterId, () =>
dispatch(getContentViewDetails(cvId))));
},
},
];
const emptyContentTitle = __('No package groups yet');
const emptyContentBody = __('Add repositories with package groups to content view to select them here.');
const emptySearchTitle = __('No matching filter rules found.');
const emptySearchBody = __('Try changing your search settings.');
const resetFilters = () => setSelectedIndex(0);
return (
setActiveTabKey(eventKey)}
>
{__('Package groups')}}
>
}
isOpen={bulkActionOpen}
ouiaId="cv-package-group-filter-bulk-actions-dropdown"
isPlain
dropdownItems={[
{__('Remove')}
]
}
/>
}
/>
{(repositories.length || showAffectedRepos) &&
{__('Affected repositories')}}
>
}
);
};
CVPackageGroupFilterContent.propTypes = {
cvId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
filterId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
showAffectedRepos: PropTypes.bool.isRequired,
setShowAffectedRepos: PropTypes.func.isRequired,
details: PropTypes.shape({
permissions: PropTypes.shape({}),
}).isRequired,
};
export default CVPackageGroupFilterContent;