Skip to content

Commit

Permalink
Fixes #36758 - Add content counts to capsule content view UI
Browse files Browse the repository at this point in the history
(cherry picked from commit ad08dad)
  • Loading branch information
sjha4 committed Sep 26, 2023
1 parent 4b7c5d2 commit f4871aa
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 27 deletions.
2 changes: 1 addition & 1 deletion app/models/katello/concerns/smart_proxy_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def update_content_counts!
end
end
new_content_counts[:content_view_versions][repo.content_view_version_id] ||= { repositories: {}, cv_version_content_counts: {}}
new_content_counts[:content_view_versions][repo.content_view_version_id][:repositories][repo.id] = translated_counts
new_content_counts[:content_view_versions][repo.content_view_version_id][:repositories][repo.content_view_version.archived_repos.find_by(library_instance_id: repo.library_instance_id)&.id] = translated_counts
new_content_counts = aggregated_cv_version_count!(repo.content_view_version_id, new_content_counts, translated_counts)
end
update(content_counts: new_content_counts)
Expand Down
16 changes: 12 additions & 4 deletions app/views/katello/api/v2/capsule_content/sync_status.json.rabl
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,32 @@ child @lifecycle_environments => :lifecycle_environments do
if @capsule.has_feature?(SmartProxy::PULP_NODE_FEATURE) || @capsule.has_feature?(SmartProxy::PULP3_FEATURE)
node :counts do |env|
{
:content_views => env.content_views.non_default.count
:content_views => env.content_views.non_default.count,
:content_counts => @capsule.content_counts
}
end

node :content_views do |env|
env.content_views.ignore_generated.map do |content_view|
attributes = {
:id => content_view.id,
:cvv_id => ::Katello::ContentViewVersion.in_environment(env).find_by(:content_view => content_view)&.id,
:label => content_view.label,
:name => content_view.name,
:composite => content_view.composite,
:last_published => content_view.versions.empty? ? nil : content_view.versions.in_environment(env).first&.created_at,
:default => content_view.default,
:up_to_date => @capsule.repos_pending_sync(env, content_view).empty?,
:counts => {
:repositories => ::Katello::ContentViewVersion.in_environment(env).find_by(:content_view => content_view)&.archived_repos&.count
},
:content_counts => @capsule.content_counts
:repositories => ::Katello::ContentViewVersion.in_environment(env).find_by(:content_view => content_view)&.archived_repos&.count
},
:repositories => ::Katello::ContentViewVersion.in_environment(env)&.find_by(:content_view => content_view)&.archived_repos&.map do |repo|
{
:id => repo.id,
:name => repo.name,
:library_id => repo.library_instance_id
}
end
}
attributes
end
Expand Down
3 changes: 3 additions & 0 deletions webpack/scenes/Content/ContentConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default [
singularLowercase: __('Python package'),
pluralLabel: 'python_packages',
singularLabel: 'python_package',
capsuleCountLabel: 'python_package',
},
columnHeaders: [
{ title: __('Name'), getProperty: unit => (<a href={urlBuilder(`content/python_packages/${unit?.id}`, '')}>{unit?.name}</a>) },
Expand Down Expand Up @@ -81,6 +82,7 @@ export default [
singularLowercase: __('OSTree ref'),
pluralLabel: 'ostree_refs',
singularLabel: 'ostree_ref',
capsuleCountLabel: 'ostree.refs',
},
columnHeaders: [
{ title: __('Name'), getProperty: unit => (<a href={urlBuilder(`content/ostree_refs/${unit?.id}`, '')}>{unit?.name}</a>) },
Expand Down Expand Up @@ -142,6 +144,7 @@ export default [
singularLowercase: __('Ansible collection'),
pluralLabel: 'ansible_collections',
singularLabel: 'ansible_collection',
capsuleCountLabel: 'ansible.collection_version',
},
columnHeaders: [
{ title: __('Name'), getProperty: unit => (<a href={urlBuilder(`content/ansible_collections/${unit?.id}`, '')}>{unit?.name}</a>) },
Expand Down
80 changes: 80 additions & 0 deletions webpack/scenes/SmartProxy/AdditionalCapsuleContent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React from 'react';
import PropTypes from 'prop-types';
import { translate as __ } from 'foremanReact/common/I18n';
import ContentConfig from '../Content/ContentConfig';

const AdditionalCapsuleContent = ({ counts }) => {
//console.log(counts);
const {
'deb.package': debPackageCount = 0,
docker_manifest: dockerManifestCount = 0,
docker_tag: dockerTagCount = 0,
file: fileCount = 0,
erratum: errataCount = 0,
package_group: packageGroup = 0,
'rpm.modulemd': moduleStreamCount = 0,
} = counts;

const contentConfigTypes = ContentConfig.filter(({ names: { capsuleCountLabel } }) =>
!!counts[`${capsuleCountLabel}`])
.map(({
names: {
capsuleCountLabel, pluralLowercase,
},
}) => {
const countParam = `${capsuleCountLabel}`;
const count = counts[countParam];
return {
pluralLowercase,
count,
};
});
//console.log(contentConfigTypes);

return (
<>
{errataCount > 0 &&
<>
{`${errataCount} Errata`}<br />
</>
}
{moduleStreamCount > 0 &&
<>
{`${moduleStreamCount} Module streams`}<br />
</>
}
{packageGroup > 0 &&
<>
{`${packageGroup} Package groups`}<br />
</>
}
{dockerTagCount > 0 &&
<>
{`${dockerTagCount} Container tags`}<br />
</>
}
{dockerManifestCount > 0 &&
<>
{`${dockerManifestCount} Container manifests`}<br />
</>
}
{fileCount > 0 &&
<>
{`${fileCount} Files`}<br />
</>
}
{debPackageCount > 0 &&
<>
{`${debPackageCount} Debian packages`}<br />
</>}
{contentConfigTypes?.length > 0 &&
contentConfigTypes.map(({ count, pluralLowercase }) => (
<React.Fragment key={pluralLowercase}>
{`${count} ${pluralLowercase}`}<br />
</React.Fragment>))
}
</>
);
};

export default AdditionalCapsuleContent;
60 changes: 40 additions & 20 deletions webpack/scenes/SmartProxy/ExpandableCvDetails.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,80 @@
import React from 'react';
import PropTypes from 'prop-types';
import { translate as __ } from 'foremanReact/common/I18n';
import { TableComposable, Thead, Tr, Th, Tbody, Td, TableVariant } from '@patternfly/react-table';
import { TableComposable, Thead, Tr, Th, Tbody, Td, TableVariant, ExpandableRowContent } from '@patternfly/react-table';
import { CheckCircleIcon, TimesCircleIcon } from '@patternfly/react-icons';
import LongDateTime from 'foremanReact/components/common/dates/LongDateTime';
import { urlBuilder } from 'foremanReact/common/urlHelpers';
import ContentViewIcon from '../ContentViews/components/ContentViewIcon';
import AdditionalCapsuleContent from './AdditionalCapsuleContent';
import {useSet} from "../../components/Table/TableHooks";
import ExpandedSmartProxyRepositories from "./ExpandedSmartProxyRepositories";

const ExpandableCvDetails = ({ contentViews }) => {
const ExpandableCvDetails = ({ contentViews, counts }) => {
const columnHeaders = [
__('Content view'),
__('Last published'),
__('Repositories'),
__('Synced to smart proxy'),
];
const { content_counts: contentCounts } = counts;
//console.log(contentCounts);
const expandedTableRows = useSet([]);
const tableRowIsExpanded = id => expandedTableRows.has(id);

return (
<TableComposable
variant={TableVariant.compact}
aria-label="expandable-content-views"
ouiaId="expandable-content-views"
>
<Thead>
<Tr ouiaId="column-headers">
<Th/>
{columnHeaders.map(col => (
<Th
modifier="fitContent"
key={col}
>
{col}
</Th>
))}
</Tr>
</Thead>
<Tbody>
{contentViews.map((cv) => {
{contentViews.map((cv, rowIndex) => {
const {
id, name: cvName, composite, up_to_date: upToDate, counts,
id, name: cvName, composite, up_to_date: upToDate, counts, cvv_id: version, repositories
} = cv;
const { repositories } = counts;
const { repositories: repositoryCount } = counts;
//console.log(contentCounts.content_view_versions[version]);

const upToDateVal = upToDate ? <CheckCircleIcon /> : <TimesCircleIcon />;
const isExpanded = tableRowIsExpanded(version);
return (
<Tr key={cv.name} ouiaId={cv.name}>
<Td>
<ContentViewIcon
composite={composite}
description={<a href={cv.default ? urlBuilder('products', '') : urlBuilder('content_views', '', id)}>{cvName}</a>}
<Tbody isExpanded={isExpanded}>
<Tr key={version} ouiaId={cv.name}>
<Td
expand={{
rowIndex,
isExpanded,
onToggle: (_event, _rInx, isOpen) => expandedTableRows.onToggle(isOpen, version),
}}
/>
</Td>
<Td><LongDateTime date={cv.last_published} showRelativeTimeTooltip /></Td>
<Td>{repositories}</Td>
<Td>{upToDateVal}</Td>
</Tr>
<Td>
<ContentViewIcon
composite={composite}
description={<a href={cv.default ? urlBuilder('products', '') : urlBuilder('content_views', '', id)}>{cvName}</a>}
/>
</Td>
<Td><LongDateTime date={cv.last_published} showRelativeTimeTooltip /></Td>
<Td>{upToDateVal}</Td>
</Tr>
<Tr key="child_row" ouiaId={`ContentViewTableRowChild-${id}`} isExpanded={isExpanded}>
<Td colSpan={12}>
<ExpandedSmartProxyRepositories contentCounts={contentCounts.content_view_versions[version].repositories} repositories={repositories} />
</Td>
</Tr>
</Tbody>
);
})}
</Tbody>

</TableComposable>

);
Expand Down
62 changes: 62 additions & 0 deletions webpack/scenes/SmartProxy/ExpandedSmartProxyRepositories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react';
import PropTypes from 'prop-types';
import { translate as __ } from 'foremanReact/common/I18n';
import {DataList, DataListItem, DataListItemRow, DataListItemCells, DataListCell} from '@patternfly/react-core';
import { CheckCircleIcon, TimesCircleIcon } from '@patternfly/react-icons';
import LongDateTime from 'foremanReact/components/common/dates/LongDateTime';
import { urlBuilder } from 'foremanReact/common/urlHelpers';
import ContentViewIcon from '../ContentViews/components/ContentViewIcon';
import AdditionalCapsuleContent from './AdditionalCapsuleContent';
import {useSet} from "../../components/Table/TableHooks";

const ExpandedSmartProxyRepositories = ({ contentCounts, repositories }) => {
const getRepositoryNameById = (id) => {
console.log("repos", repositories, typeof repositories);
console.log("id", id, typeof id);
console.log((repositories.find(repo => repo.id == id)));
console.log((repositories[id] || {}).name);
return (repositories.find(repo => repo.id == id) || {}).name;
};

const dataListCellLists = (repo) => {
var cellList= [];
//console.log("contentCounts",contentCounts, typeof contentCounts);
//console.log("repositories", repositories);
cellList.push(<DataListCell><span>{getRepositoryNameById(repo)}</span></DataListCell>)
cellList.push(<DataListCell><span>{contentCounts[repo].rpm ? contentCounts[repo].rpm + " Packages" : "N/A"}</span></DataListCell>)
cellList.push(<DataListCell><AdditionalCapsuleContent counts={contentCounts[repo]} /></DataListCell>)
return cellList;
}
return (
<DataList aria-label="Expanded repository details" isCompact>
<DataListItem aria-labelledby="simple-item1">
<DataListItemRow>
<DataListItemCells dataListCells={[
<DataListCell key="primary content">
<b>{__('Repositories')}</b>
</DataListCell>,
<DataListCell key="Packages"><b>{__('Packages')}</b></DataListCell>,
<DataListCell key="Additional Content"><b>{__('Additional Content')}</b></DataListCell>
]} />
</DataListItemRow>
</DataListItem>
{Object.keys(contentCounts).map((repo) => (
<DataListItem aria-labelledby="simple-item2">
<DataListItemRow>
<DataListItemCells dataListCells={dataListCellLists(repo)} />
</DataListItemRow>
</DataListItem>
))}
</DataList>
);
};

ExpandedSmartProxyRepositories.propTypes = {
contentViews: PropTypes.arrayOf(PropTypes.shape({})),
};

ExpandedSmartProxyRepositories.defaultProps = {
contentViews: [],
};

export default ExpandedSmartProxyRepositories;
6 changes: 4 additions & 2 deletions webpack/scenes/SmartProxy/SmartProxyExpandableTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ const SmartProxyExpandableTable = ({ smartProxyId }) => {
</Thead>
{
results?.map((env, rowIndex) => {
const { name, id, content_views: contentViews } = env;
const {
name, id, content_views: contentViews, counts,
} = env;
const isExpanded = tableRowIsExpanded(id);
return (
<Tbody isExpanded={isExpanded} key={id}>
Expand All @@ -88,7 +90,7 @@ const SmartProxyExpandableTable = ({ smartProxyId }) => {
</Tr>
<Tr key="child_row" ouiaId={`ContentViewTableRowChild-${id}`} isExpanded={isExpanded}>
<Td colSpan={2}>
<ExpandableCvDetails contentViews={contentViews} />
<ExpandableCvDetails contentViews={contentViews} counts={counts} />
</Td>
</Tr>
</Tbody>
Expand Down

0 comments on commit f4871aa

Please sign in to comment.