import React, { useState, useCallback } from 'react';
import useDeepCompareEffect from 'use-deep-compare-effect';
import { useSelector, shallowEqual, useDispatch } from 'react-redux';
import {
Bullseye,
Split,
SplitItem,
Button,
ActionList,
ActionListItem,
Dropdown,
DropdownItem,
KebabToggle,
} from '@patternfly/react-core';
import { TableVariant, fitContent } from '@patternfly/react-table';
import { omit } from 'lodash';
import { STATUS } from 'foremanReact/constants';
import { translate as __ } from 'foremanReact/common/I18n';
import { urlBuilder } from 'foremanReact/common/urlHelpers';
import PropTypes from 'prop-types';
import onSelect from '../../../../../components/Table/helpers';
import { editCVFilter, getCVFilterDetails, getFilterRepositories } from '../../ContentViewDetailActions';
import { selectCVFilterRepos, selectCVFilterReposStatus, selectCVFilterReposError, selectCVFilterDetails } from '../../ContentViewDetailSelectors';
import ContentCounts from '../../Repositories/ContentCounts';
import LastSync from '../../Repositories/LastSync';
import AddedStatusLabel from '../../../../../components/AddedStatusLabel';
import TableWrapper from '../../../../../components/Table/TableWrapper';
import RepoIcon from '../../Repositories/RepoIcon';
import SelectableDropdown from '../../../../../components/SelectableDropdown/SelectableDropdown';
import { hasPermission } from '../../../helpers';
const allProducts = 'All products';
const AffectedRepositoryTable = ({
cvId, filterId, repoType, setShowAffectedRepos, details,
}) => {
const dispatch = useDispatch();
const response = useSelector(state => selectCVFilterRepos(state, filterId), shallowEqual);
const [initialResponse, setInitialResponse] = useState(response);
const status = useSelector(state => selectCVFilterReposStatus(state, filterId), shallowEqual);
const error = useSelector(state => selectCVFilterReposError(state, filterId), shallowEqual);
const filterDetails = useSelector(state =>
selectCVFilterDetails(state, cvId, filterId), shallowEqual);
const { repositories = [] } = filterDetails;
const [rows, setRows] = useState([]);
const [searchQuery, updateSearchQuery] = useState('');
const [productSelected, setProductSelected] = useState(allProducts);
const [repoProducts, setRepoProducts] = useState({});
const [bulkActionOpen, setBulkActionOpen] = useState(false);
const hasAddedSelected = rows.some(({ selected, added }) => selected && added);
const hasNotAddedSelected = rows.some(({ selected, added }) => selected && !added);
const deselectAll = () => setRows(rows.map(row => ({ ...row, selected: false })));
const metadata = omit(response, ['results']);
const { permissions } = details;
const columnHeaders = [
{ title: __('Type'), transforms: [fitContent] },
__('Name'),
__('Product'),
__('Sync state'),
__('Content'),
{ title: __('Status') },
];
const loading = status === STATUS.PENDING;
const buildRows = useCallback((results) => {
const isAddedToFilter = repoId => (!!repositories.filter(repo => repo.id === repoId).length);
const newRows = [];
results.forEach((repo) => {
const {
id,
content_type: contentType,
name,
product: { id: productId, name: productName },
content_counts: counts,
last_sync_words: lastSyncWords,
last_sync: lastSync,
} = repo;
const addedToFilter = isAddedToFilter(id);
const cells = [
{ title: },
{ title: {name} },
productName,
{ title: },
{ title: },
{
title: ,
},
];
newRows.push({
repoId: id,
cells,
added: addedToFilter,
});
});
return newRows.sort(({ added: addedA }, { added: addedB }) => {
if (addedA === addedB) return 0;
return addedA ? -1 : 1;
});
}, [repositories]);
useDeepCompareEffect(() => {
const { results } = response;
if (!loading && results) {
if (Object.keys(initialResponse).length === 0 || !Object.keys(repoProducts).length) {
setInitialResponse(response);
const allRepoProducts = {};
allRepoProducts[allProducts] = 'all';
results.forEach((repo) => {
const { product = {} } = repo;
const { name, id } = product;
allRepoProducts[name] = id;
});
setRepoProducts(allRepoProducts);
}
const newRows = buildRows(results);
setRows(newRows);
}
}, [response, loading, buildRows, initialResponse,
setInitialResponse, repoProducts, setRepoProducts]);
const toggleBulkAction = () => {
setBulkActionOpen(!bulkActionOpen);
};
const onAdd = (repos) => {
const repositoryIds = repositories.map(repo => repo.id);
dispatch(editCVFilter(
filterId,
{ id: filterId, repository_ids: repositoryIds.concat(repos) }, () => {
dispatch(getCVFilterDetails(cvId, filterId));
},
));
};
const onRemove = (repos) => {
const reposToDelete = [].concat(repos);
const repositoryIds = repositories.map(repo => repo.id);
const deletedRepos = repositoryIds.filter(x => !reposToDelete.includes(x));
dispatch(editCVFilter(
filterId,
{ id: filterId, repository_ids: deletedRepos },
() => dispatch(getCVFilterDetails(cvId, filterId, {})),
));
if (deletedRepos.length === 0) setShowAffectedRepos(false);
};
const addBulk = () => {
setBulkActionOpen(false);
const reposToAdd = rows.filter(({ selected, added }) =>
selected && !added).map(({ repoId }) => repoId);
deselectAll();
onAdd(reposToAdd);
};
const removeBulk = () => {
setBulkActionOpen(false);
const reposToDelete = rows.filter(({ selected, added }) =>
selected && added).map(({ repoId }) => repoId);
deselectAll();
onRemove(reposToDelete);
};
const getCVReposWithOptions = useCallback((params = {}) => {
const allParams = { ...params };
allParams.content_type = repoType;
if (productSelected !== allProducts) {
allParams.product_id = repoProducts[productSelected];
}
return getFilterRepositories(cvId, filterId, allParams);
}, [cvId, filterId, repoType, productSelected, repoProducts]);
const emptyContentTitle = __("You currently don't have any repositories to add to this filter.");
const emptyContentBody = __('Please add some repositories.');
const emptySearchTitle = __('No matching repositories found');
const emptySearchBody = __('Try changing your search settings.');
const activeFilters = [productSelected];
const defaultFilters = [allProducts];
const dropdownItems = [
{__('Remove')}
,
];
return (
getCVReposWithOptions(params), [getCVReposWithOptions])}
additionalListeners={[productSelected]}
actionButtons={
<>
{hasPermission(permissions, 'edit_content_views') &&
}
isOpen={bulkActionOpen}
isPlain
dropdownItems={dropdownItems}
/>
}
>
}
/>
);
};
AffectedRepositoryTable.propTypes = {
cvId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
filterId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
repoType: PropTypes.string.isRequired,
setShowAffectedRepos: PropTypes.func.isRequired,
details: PropTypes.shape({
permissions: PropTypes.shape({}),
}).isRequired,
};
export default AffectedRepositoryTable;