From 37f045475a0318e7c16e0e8c3eb82e472969025e Mon Sep 17 00:00:00 2001 From: Samir Jha Date: Thu, 12 Oct 2023 15:35:38 +0000 Subject: [PATCH 1/5] Fixes #36807 - UX fixes and add update count action --- .../concerns/smart_proxy_extensions.rb | 14 +- .../katello/pulp3/repository_mirror.rb | 2 +- .../smart_proxies/_content_tab.html.erb | 2 +- .../v2/capsule_content/sync_status.json.rabl | 7 + .../concerns/smart_proxy_extensions_test.rb | 3 +- webpack/scenes/SmartProxy/Content.js | 14 +- .../scenes/SmartProxy/ExpandableCvDetails.js | 3 +- .../ExpandedSmartProxyRepositories.js | 12 +- .../SmartProxy/SmartProxyContentActions.js | 21 ++- .../SmartProxy/SmartProxyContentConstants.js | 1 + .../SmartProxy/SmartProxyContentTable.js | 164 ------------------ .../SmartProxy/SmartProxyExpandableTable.js | 98 +++++++---- .../__tests__/SmartProxyContentTest.js | 4 +- 13 files changed, 125 insertions(+), 220 deletions(-) delete mode 100644 webpack/scenes/SmartProxy/SmartProxyContentTable.js diff --git a/app/models/katello/concerns/smart_proxy_extensions.rb b/app/models/katello/concerns/smart_proxy_extensions.rb index 8ba281c460e..e97348c3ddd 100644 --- a/app/models/katello/concerns/smart_proxy_extensions.rb +++ b/app/models/katello/concerns/smart_proxy_extensions.rb @@ -148,7 +148,11 @@ def update_content_counts! new_content_counts[:content_view_versions][repo.content_view_version_id] ||= { repositories: {}} # Store counts on capsule of archived repos which are reused across environment copies # of the archived repo corresponding to each environment CV version is promoted to. - 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 + if repo.content_view_version.default? + new_content_counts[:content_view_versions][repo.content_view_version_id][:repositories][repo.id] = translated_counts + else + 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 + end end update(content_counts: new_content_counts) end @@ -424,10 +428,12 @@ def last_sync_audit Audited::Audit.where(:auditable_id => self, :auditable_type => SmartProxy.name, action: "sync capsule").order(:created_at).last end - def last_sync_time - task = sync_tasks.where.not(:ended_at => nil).where(:result => 'success').order(:ended_at).last + def last_sync_task + sync_tasks.where.not(:ended_at => nil).where(:result => 'success').order(:ended_at).last + end - task&.ended_at || last_sync_audit&.created_at&.to_s + def last_sync_time + last_sync_task&.ended_at || last_sync_audit&.created_at&.to_s end def environment_syncable?(env) diff --git a/app/services/katello/pulp3/repository_mirror.rb b/app/services/katello/pulp3/repository_mirror.rb index 6164486d89e..3e5fbadcaee 100644 --- a/app/services/katello/pulp3/repository_mirror.rb +++ b/app/services/katello/pulp3/repository_mirror.rb @@ -75,7 +75,7 @@ def fetch_repository end def version_href - fetch_repository.latest_version_href + fetch_repository&.latest_version_href end def publication_href diff --git a/app/views/foreman/smart_proxies/_content_tab.html.erb b/app/views/foreman/smart_proxies/_content_tab.html.erb index 233c548d18f..48000252847 100644 --- a/app/views/foreman/smart_proxies/_content_tab.html.erb +++ b/app/views/foreman/smart_proxies/_content_tab.html.erb @@ -1,3 +1,3 @@ <%= javascript_include_tag *webpack_asset_paths('katello', extension: 'js') %> <% @smartProxyId= @smart_proxy.id %> -<%= react_component('Content', smartProxyId: @smartProxyId,) %> +<%= react_component('Content', smartProxyId: @smartProxyId, organizationId: Organization.current.id,) %> diff --git a/app/views/katello/api/v2/capsule_content/sync_status.json.rabl b/app/views/katello/api/v2/capsule_content/sync_status.json.rabl index d93d10048b1..0baf011cf24 100644 --- a/app/views/katello/api/v2/capsule_content/sync_status.json.rabl +++ b/app/views/katello/api/v2/capsule_content/sync_status.json.rabl @@ -1,6 +1,9 @@ object @capsule attribute :last_sync_time +node :last_sync_words do |_object| + @capsule&.last_sync_time ? time_ago_in_words(Time.parse(@capsule&.last_sync_time&.to_s)) : nil +end attribute :download_policy @@ -15,6 +18,10 @@ child :last_failed_sync_tasks => :last_failed_sync_tasks do extends 'foreman_tasks/api/tasks/show' end +child :last_sync_task => :last_sync_task do + extends 'foreman_tasks/api/tasks/show' +end + child @lifecycle_environments => :lifecycle_environments do extends 'katello/api/v2/common/identifier' extends 'katello/api/v2/common/org_reference' diff --git a/test/models/concerns/smart_proxy_extensions_test.rb b/test/models/concerns/smart_proxy_extensions_test.rb index b8ff5cb3697..b3ed7580b0d 100644 --- a/test/models/concerns/smart_proxy_extensions_test.rb +++ b/test/models/concerns/smart_proxy_extensions_test.rb @@ -95,8 +95,7 @@ def test_update_content_counts python_service.expects(:latest_content_counts).once.returns(python_counts) repos = [yum_repo, file_repo, ansible_repo, container_repo, ostree_repo, deb_repo, python_repo] - yum_repo.content_view_version.expects(:archived_repos).returns(::Katello::Repository.where(id: [yum_repo, file_repo, ansible_repo, container_repo, - ostree_repo, deb_repo, python_repo])) + yum_repo.content_view_version.expects(:default?).returns(true) ::Katello::SmartProxyHelper.any_instance.expects(:repositories_available_to_capsule).once.returns(repos) @proxy.update_content_counts! counts = @proxy.content_counts diff --git a/webpack/scenes/SmartProxy/Content.js b/webpack/scenes/SmartProxy/Content.js index 57c096d0cd1..0d838c4c0d9 100644 --- a/webpack/scenes/SmartProxy/Content.js +++ b/webpack/scenes/SmartProxy/Content.js @@ -2,16 +2,24 @@ import React from 'react'; import PropTypes from 'prop-types'; import SmartProxyExpandableTable from './SmartProxyExpandableTable'; -const Content = ({ smartProxyId }) => ( - +const Content = ({ smartProxyId, organizationId }) => ( + ); Content.propTypes = { - smartProxyId: PropTypes.number, + smartProxyId: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.string, // The API can sometimes return strings + ]), + organizationId: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.string, // The API can sometimes return strings + ]), }; Content.defaultProps = { smartProxyId: null, + organizationId: null, }; export default Content; diff --git a/webpack/scenes/SmartProxy/ExpandableCvDetails.js b/webpack/scenes/SmartProxy/ExpandableCvDetails.js index 31a63adc64e..bbac1f31715 100644 --- a/webpack/scenes/SmartProxy/ExpandableCvDetails.js +++ b/webpack/scenes/SmartProxy/ExpandableCvDetails.js @@ -13,7 +13,7 @@ const ExpandableCvDetails = ({ contentViews, counts }) => { const columnHeaders = [ __('Content view'), __('Last published'), - __('Synced to smart proxy'), + __('Synced'), ]; const { content_counts: contentCounts } = counts; const expandedTableRows = useSet([]); @@ -46,6 +46,7 @@ const ExpandableCvDetails = ({ contentViews, counts }) => { { const getRepositoryNameById = id => (repositories.find(repo => @@ -24,21 +25,22 @@ const ExpandedSmartProxyRepositories = ({ contentCounts, repositories }) => { - {__('Repositories')} + {__('Repository')} , - {__('Packages')}, - {__('Additional Content')}, + {__('Packages')}, + {__('Additional content')}, ]} /> - {Object.keys(contentCounts).map((repo, index) => ( + {Object.keys(contentCounts).length ? Object.keys(contentCounts).map((repo, index) => ( - ))} + )) : + } ); }; diff --git a/webpack/scenes/SmartProxy/SmartProxyContentActions.js b/webpack/scenes/SmartProxy/SmartProxyContentActions.js index 00e21e3b357..ea01be86969 100644 --- a/webpack/scenes/SmartProxy/SmartProxyContentActions.js +++ b/webpack/scenes/SmartProxy/SmartProxyContentActions.js @@ -1,11 +1,14 @@ -import { API_OPERATIONS, get } from 'foremanReact/redux/API'; +import { API_OPERATIONS, get, post } from 'foremanReact/redux/API'; +import { translate as __ } from 'foremanReact/common/I18n'; import api, { foremanApi, orgId } from '../../services/api'; -import SMART_PROXY_CONTENT_KEY, { SMART_PROXY_KEY } from './SmartProxyContentConstants'; +import SMART_PROXY_CONTENT_KEY, { SMART_PROXY_COUNTS_UPDATE_KEY, SMART_PROXY_KEY } from './SmartProxyContentConstants'; +import { renderTaskStartedToast } from '../Tasks/helpers'; +import { getResponseErrorMsgs } from '../../utils/helpers'; -const getSmartProxyContent = ({ smartProxyId }) => get({ +const getSmartProxyContent = ({ smartProxyId, organizationId }) => get({ type: API_OPERATIONS.GET, key: SMART_PROXY_CONTENT_KEY, - url: api.getApiUrl(`/capsules/${smartProxyId}/content/sync?${orgId()}`), + url: api.getApiUrl(`/capsules/${smartProxyId}/content/sync?organization_id=${organizationId}`), }); export const getSmartProxies = () => get({ @@ -15,4 +18,14 @@ export const getSmartProxies = () => get({ params: { organization_id: orgId(), per_page: 'all' }, }); +export const updateSmartProxyContentCounts = smartProxyId => post({ + type: API_OPERATIONS.POST, + key: SMART_PROXY_COUNTS_UPDATE_KEY, + url: api.getApiUrl(`/capsules/${smartProxyId}/content/update_counts`), + handleSuccess: (response) => { + renderTaskStartedToast(response?.data, __('Smart proxy content count refresh has started in the background')); + }, + errorToast: error => __(`Something went wrong while refreshing content counts: ${getResponseErrorMsgs(error.response)}`), +}); + export default getSmartProxyContent; diff --git a/webpack/scenes/SmartProxy/SmartProxyContentConstants.js b/webpack/scenes/SmartProxy/SmartProxyContentConstants.js index 5db4da1414e..14bc5c92630 100644 --- a/webpack/scenes/SmartProxy/SmartProxyContentConstants.js +++ b/webpack/scenes/SmartProxy/SmartProxyContentConstants.js @@ -1,3 +1,4 @@ const SMART_PROXY_CONTENT_KEY = 'SMART_PROXY_CONTENT'; export const SMART_PROXY_KEY = 'SMART_PROXY'; +export const SMART_PROXY_COUNTS_UPDATE_KEY = 'SMART_PROXY_COUNTS_UPDATE_KEY'; export default SMART_PROXY_CONTENT_KEY; diff --git a/webpack/scenes/SmartProxy/SmartProxyContentTable.js b/webpack/scenes/SmartProxy/SmartProxyContentTable.js deleted file mode 100644 index 0fec8661b63..00000000000 --- a/webpack/scenes/SmartProxy/SmartProxyContentTable.js +++ /dev/null @@ -1,164 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import useDeepCompareEffect from 'use-deep-compare-effect'; -import PropTypes from 'prop-types'; -import { useSelector, useDispatch } from 'react-redux'; -import { wrappable } from '@patternfly/react-table'; -import { CheckCircleIcon, TimesCircleIcon } from '@patternfly/react-icons'; -import { STATUS } from 'foremanReact/constants'; -import { translate as __ } from 'foremanReact/common/I18n'; -import { urlBuilder } from 'foremanReact/common/urlHelpers'; -import LongDateTime from 'foremanReact/components/common/dates/LongDateTime'; -import MainTable from '../../components/Table/MainTable'; -import getSmartProxyContent from './SmartProxyContentActions'; -import ContentViewIcon from '../../scenes/ContentViews/components/ContentViewIcon'; -import { - selectSmartProxyContent, - selectSmartProxyContentStatus, - selectSmartProxyContentError, -} from './SmartProxyContentSelectors'; - -const SmartProxyContentTable = ({ smartProxyId }) => { - const dispatch = useDispatch(); - const [rows, setRows] = useState([]); - const response = useSelector(state => selectSmartProxyContent(state)); - const status = useSelector(state => selectSmartProxyContentStatus(state)); - const error = useSelector(state => selectSmartProxyContentError(state)); - const columnHeaders = [ - { - title: __('Environment'), - transforms: [wrappable], - }, - { - title: __('Content view'), - transforms: [wrappable], - }, - { - title: __('Type'), - transforms: [wrappable], - }, - { - title: __('Last published'), - transforms: [wrappable], - }, - { - title: __('Repositories'), - transforms: [wrappable], - }, - { - title: __('Synced to smart proxy'), - transforms: [wrappable], - }, - ]; - - const buildrows = (results) => { - const newRows = []; - let envCount = 0; - results.forEach((env) => { - const { name, content_views: contentViews } = env; - const cellEnv = { - isOpen: false, - cells: [name, null, null, null, null, null], - }; - newRows.push(cellEnv); - contentViews.forEach((cv) => { - const { - id, name: cvName, composite, last_published: lastPublished, up_to_date: upToDate, counts, - } = cv; - const { repositories } = counts; - const cvType = ; - const upToDateVal = upToDate ? : ; - const cellCv = - { - parent: envCount, - cells: [ - { - title: null, - props: { - colSpan: 1, - }, - }, - { - title: {cvName}, - props: { - colSpan: 1, - }, - }, - { - title: cvType, - props: { - colSpan: 1, - }, - }, - { - title: , - props: { - colSpan: 1, - }, - }, - { - title: repositories, - props: { - colSpan: 1, - }, - }, - { - title: upToDateVal, - props: { - colSpan: 1, - }, - }, - ], - }; - newRows.push(cellCv); - }); - envCount = newRows.length; - }); - return newRows; - }; - - const onCollapse = (row, setRow) => (event, rowKey, isOpen) => { - const newRows = [...row]; - newRows[rowKey].isOpen = isOpen; - setRow(newRows); - }; - - useEffect( - () => { - dispatch(getSmartProxyContent({ smartProxyId })); - } - , [dispatch, smartProxyId], - ); - - useDeepCompareEffect(() => { - if (status !== STATUS.PENDING && response) { - const { lifecycle_environments: env } = response; - setRows(buildrows(env)); - } - }, [response, status, error]); - - - return ( - - ); -}; - -SmartProxyContentTable.propTypes = { - smartProxyId: PropTypes.number, -}; - -SmartProxyContentTable.defaultProps = { - smartProxyId: null, -}; - -export default SmartProxyContentTable; diff --git a/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js b/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js index e90663acf60..1f9d463a1f3 100644 --- a/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js +++ b/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js @@ -1,9 +1,9 @@ import React, { useState, useCallback } from 'react'; -import { useSelector } from 'react-redux'; +import { useSelector, useDispatch } from 'react-redux'; import PropTypes from 'prop-types'; import { translate as __ } from 'foremanReact/common/I18n'; import { Thead, Tbody, Th, Tr, Td } from '@patternfly/react-table'; -import getSmartProxyContent from './SmartProxyContentActions'; +import getSmartProxyContent, { updateSmartProxyContentCounts } from './SmartProxyContentActions'; import { selectSmartProxyContent, selectSmartProxyContentStatus, @@ -12,25 +12,39 @@ import { import { useSet } from '../../components/Table/TableHooks'; import TableWrapper from '../../components/Table/TableWrapper'; import ExpandableCvDetails from './ExpandableCvDetails'; +import ComponentEnvironments from '../ContentViews/Details/ComponentContentViews/ComponentEnvironments'; +import LastSync from '../ContentViews/Details/Repositories/LastSync'; -const SmartProxyExpandableTable = ({ smartProxyId }) => { +const SmartProxyExpandableTable = ({ smartProxyId, organizationId }) => { const response = useSelector(selectSmartProxyContent); const status = useSelector(selectSmartProxyContentStatus); const error = useSelector(selectSmartProxyContentError); const [searchQuery, updateSearchQuery] = useState(''); const expandedTableRows = useSet([]); const tableRowIsExpanded = id => expandedTableRows.has(id); + const dispatch = useDispatch(); let metadata = {}; const { - lifecycle_environments: results, + lifecycle_environments: results, last_sync_task: lastTask, last_sync_words: lastSyncWords, } = response; if (results) { metadata = { total: results.length, subtotal: results.length }; } const columnHeaders = [ __('Environment'), + __('Last sync'), ]; - const fetchItems = useCallback(() => getSmartProxyContent({ smartProxyId }), [smartProxyId]); + + const refreshCountAction = { + title: __('Refresh counts'), + onClick: () => { + dispatch(updateSmartProxyContentCounts(smartProxyId)); + }, + }; + const fetchItems = useCallback( + () => getSmartProxyContent({ smartProxyId, organizationId }), + [smartProxyId, organizationId], + ); const emptyContentTitle = __('No content views yet'); const emptyContentBody = __('You currently have no content views to display'); @@ -38,6 +52,7 @@ const SmartProxyExpandableTable = ({ smartProxyId }) => { const emptySearchBody = __('Try changing your search settings.'); const alwaysHideToolbar = true; const hidePagination = true; + return ( { {col} ))} + { - results?.map((env, rowIndex) => { - const { - name, id, content_views: contentViews, counts, - } = env; - const isExpanded = tableRowIsExpanded(id); - return ( - - - - expandedTableRows.onToggle(isOpen, id), - }} - /> - {name} - - - - - - - - ); - }) - } - + results?.map((env, rowIndex) => { + const { + id, content_views: contentViews, counts, + } = env; + const isExpanded = tableRowIsExpanded(id); + return ( + + + + expandedTableRows.onToggle(isOpen, id), + }} + /> + + + + + + + + + + + ); + }) + } + ); }; @@ -106,6 +130,14 @@ SmartProxyExpandableTable.propTypes = { PropTypes.number, PropTypes.string, // The API can sometimes return strings ]).isRequired, + organizationId: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.string, // The API can sometimes return strings + ]), +}; + +SmartProxyExpandableTable.defaultProps = { + organizationId: null, }; export default SmartProxyExpandableTable; diff --git a/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js b/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js index 58a7c4e97bb..e08acc29d5e 100644 --- a/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js +++ b/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js @@ -23,8 +23,8 @@ test('Can display Smart proxy content table', async (done) => { await patientlyWaitFor(() => expect(getByText('Environment')).toBeInTheDocument()); expect(getAllByText('Content view')[0]).toBeInTheDocument(); expect(getAllByText('Last published')[0]).toBeInTheDocument(); - expect(getAllByText('Repositories')[0]).toBeInTheDocument(); - expect(getAllByText('Synced to smart proxy')[0]).toBeInTheDocument(); + expect(getAllByText('Repository')[0]).toBeInTheDocument(); + expect(getAllByText('Synced')[0]).toBeInTheDocument(); expect(getAllByLabelText('Details')[0]).toHaveAttribute('aria-expanded', 'false'); getAllByLabelText('Details')[0].click(); expect(getAllByLabelText('Details')[0]).toHaveAttribute('aria-expanded', 'true'); From fc602a19924583929c89791b9c2b2598b85ddd28 Mon Sep 17 00:00:00 2001 From: Samir Jha Date: Thu, 19 Oct 2023 17:30:08 +0000 Subject: [PATCH 2/5] Fixes #36807 - More fixes --- .../v2/capsule_content/sync_status.json.rabl | 4 ++- .../scenes/SmartProxy/ExpandableCvDetails.js | 21 +++++++++----- .../ExpandedSmartProxyRepositories.js | 29 +++++++++++++------ .../SmartProxy/SmartProxyExpandableTable.js | 4 ++- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/app/views/katello/api/v2/capsule_content/sync_status.json.rabl b/app/views/katello/api/v2/capsule_content/sync_status.json.rabl index 0baf011cf24..30eb72eef57 100644 --- a/app/views/katello/api/v2/capsule_content/sync_status.json.rabl +++ b/app/views/katello/api/v2/capsule_content/sync_status.json.rabl @@ -41,9 +41,11 @@ child @lifecycle_environments => :lifecycle_environments do node :content_views do |env| env.content_views.ignore_generated.map do |content_view| + cvv = ::Katello::ContentViewVersion.in_environment(env).find_by(:content_view => content_view) attributes = { :id => content_view.id, - :cvv_id => ::Katello::ContentViewVersion.in_environment(env).find_by(:content_view => content_view)&.id, + :cvv_id => cvv&.id, + :cvv_version => cvv&.version, :label => content_view.label, :name => content_view.name, :composite => content_view.composite, diff --git a/webpack/scenes/SmartProxy/ExpandableCvDetails.js b/webpack/scenes/SmartProxy/ExpandableCvDetails.js index bbac1f31715..8f8336553f2 100644 --- a/webpack/scenes/SmartProxy/ExpandableCvDetails.js +++ b/webpack/scenes/SmartProxy/ExpandableCvDetails.js @@ -12,6 +12,7 @@ import ExpandedSmartProxyRepositories from './ExpandedSmartProxyRepositories'; const ExpandableCvDetails = ({ contentViews, counts }) => { const columnHeaders = [ __('Content view'), + __('Version'), __('Last published'), __('Synced'), ]; @@ -38,19 +39,21 @@ const ExpandableCvDetails = ({ contentViews, counts }) => { {contentViews.map((cv, rowIndex) => { const { - id, name: cvName, composite, up_to_date: upToDate, cvv_id: version, repositories, + id, name: cvName, composite, up_to_date: upToDate, + cvv_id: versionId, cvv_version: version, repositories, } = cv; - const upToDateVal = upToDate ? : ; - const isExpanded = tableRowIsExpanded(version); + const upToDateVal = upToDate ? : ; + const isExpanded = tableRowIsExpanded(versionId); return ( - - + + expandedTableRows.onToggle(isOpen, version), + onToggle: (_event, _rInx, isOpen) => + expandedTableRows.onToggle(isOpen, versionId), }} /> @@ -59,14 +62,18 @@ const ExpandableCvDetails = ({ contentViews, counts }) => { description={{cvName}} /> + + {__('Version ')}{version} + {upToDateVal} diff --git a/webpack/scenes/SmartProxy/ExpandedSmartProxyRepositories.js b/webpack/scenes/SmartProxy/ExpandedSmartProxyRepositories.js index 95fbc3ed3ee..614970cfc71 100644 --- a/webpack/scenes/SmartProxy/ExpandedSmartProxyRepositories.js +++ b/webpack/scenes/SmartProxy/ExpandedSmartProxyRepositories.js @@ -6,16 +6,19 @@ import { DataList, DataListItem, DataListItemRow, DataListItemCells, DataListCel import AdditionalCapsuleContent from './AdditionalCapsuleContent'; import InactiveText from '../ContentViews/components/InactiveText'; -const ExpandedSmartProxyRepositories = ({ contentCounts, repositories }) => { +const ExpandedSmartProxyRepositories = ({ contentCounts, repositories, syncedToCapsule }) => { const getRepositoryNameById = id => (repositories.find(repo => Number(repo.id) === Number(id)) || {}).name; - const dataListCellLists = (repo) => { const cellList = []; /* eslint-disable max-len */ - cellList.push({getRepositoryNameById(repo)}); - cellList.push({contentCounts[repo].rpm ? `${contentCounts[repo].rpm} Packages` : 'N/A'}); - cellList.push(); + if (syncedToCapsule) { + cellList.push({getRepositoryNameById(repo)}); + cellList.push({contentCounts[repo].rpm ? `${contentCounts[repo].rpm} Packages` : 'N/A'}); + cellList.push(); + } else { + cellList.push(); + } /* eslint-enable max-len */ return cellList; }; @@ -33,13 +36,19 @@ const ExpandedSmartProxyRepositories = ({ contentCounts, repositories }) => { /> - {Object.keys(contentCounts).length ? Object.keys(contentCounts).map((repo, index) => ( - + {Object.keys(contentCounts).length ? + Object.keys(contentCounts).map((repo, index) => ( + + + + + + )) : + - + ]} /> - )) : } ); @@ -48,11 +57,13 @@ const ExpandedSmartProxyRepositories = ({ contentCounts, repositories }) => { ExpandedSmartProxyRepositories.propTypes = { contentCounts: PropTypes.shape({}), repositories: PropTypes.arrayOf(PropTypes.shape({})), + syncedToCapsule: PropTypes.bool, }; ExpandedSmartProxyRepositories.defaultProps = { contentCounts: {}, repositories: [{}], + syncedToCapsule: false, }; export default ExpandedSmartProxyRepositories; diff --git a/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js b/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js index 1f9d463a1f3..91034b79c08 100644 --- a/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js +++ b/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js @@ -114,7 +114,9 @@ const SmartProxyExpandableTable = ({ smartProxyId, organizationId }) => { - + {isExpanded ? + : + <>} From c1a7bd0eb5a4c3f0d8d488009b691119dc18ab97 Mon Sep 17 00:00:00 2001 From: Samir Jha Date: Fri, 20 Oct 2023 00:24:06 +0000 Subject: [PATCH 3/5] Fixes #36807 - Allow update_content_counts without repo being synced to capsule --- .../capsule_content/update_content_counts.rb | 4 + .../concerns/smart_proxy_extensions.rb | 2 +- .../katello/pulp3/repository_mirror.rb | 4 +- .../v2/capsule_content/sync_status.json.rabl | 2 +- .../scenes/SmartProxy/ExpandableCvDetails.js | 1 + .../SmartProxy/SmartProxyExpandableTable.js | 1 + .../__tests__/SmartProxyContent.fixtures.json | 1500 +++++++++++++++++ .../SmartProxyContentResult.fixtures.json | 140 -- .../__tests__/SmartProxyContentTest.js | 35 +- 9 files changed, 1535 insertions(+), 154 deletions(-) create mode 100644 webpack/scenes/SmartProxy/__tests__/SmartProxyContent.fixtures.json delete mode 100644 webpack/scenes/SmartProxy/__tests__/SmartProxyContentResult.fixtures.json diff --git a/app/lib/actions/katello/capsule_content/update_content_counts.rb b/app/lib/actions/katello/capsule_content/update_content_counts.rb index 7833208479e..4bf846bac3f 100644 --- a/app/lib/actions/katello/capsule_content/update_content_counts.rb +++ b/app/lib/actions/katello/capsule_content/update_content_counts.rb @@ -14,6 +14,10 @@ def run smart_proxy = ::SmartProxy.unscoped.find(input[:smart_proxy_id]) smart_proxy.update_content_counts! end + + def rescue_strategy + Dynflow::Action::Rescue::Skip + end end end end diff --git a/app/models/katello/concerns/smart_proxy_extensions.rb b/app/models/katello/concerns/smart_proxy_extensions.rb index e97348c3ddd..3b644a620eb 100644 --- a/app/models/katello/concerns/smart_proxy_extensions.rb +++ b/app/models/katello/concerns/smart_proxy_extensions.rb @@ -132,7 +132,7 @@ def update_content_counts! repo_mirror_service = repo.backend_service(self).with_mirror_adapter repo_content_counts = repo_mirror_service.latest_content_counts translated_counts = {} - repo_content_counts.each do |name, count| + repo_content_counts&.each do |name, count| count = count[:count] # Some content units in Pulp have the same model if name == 'rpm.package' && repo.content_counts['srpm'] > 0 diff --git a/app/services/katello/pulp3/repository_mirror.rb b/app/services/katello/pulp3/repository_mirror.rb index 3e5fbadcaee..5f01be34994 100644 --- a/app/services/katello/pulp3/repository_mirror.rb +++ b/app/services/katello/pulp3/repository_mirror.rb @@ -225,7 +225,9 @@ def count_by_pulpcore_type(service_class) end def latest_content_counts - api.repository_versions_api.read(version_href)&.content_summary&.present + version_pulp_href = version_href + return unless version_pulp_href + api.repository_versions_api.read(version_pulp_href)&.content_summary&.present end def pulp3_enabled_repo_types diff --git a/app/views/katello/api/v2/capsule_content/sync_status.json.rabl b/app/views/katello/api/v2/capsule_content/sync_status.json.rabl index 30eb72eef57..b3d8fca5bc8 100644 --- a/app/views/katello/api/v2/capsule_content/sync_status.json.rabl +++ b/app/views/katello/api/v2/capsule_content/sync_status.json.rabl @@ -41,7 +41,7 @@ child @lifecycle_environments => :lifecycle_environments do node :content_views do |env| env.content_views.ignore_generated.map do |content_view| - cvv = ::Katello::ContentViewVersion.in_environment(env).find_by(:content_view => content_view) + cvv = ::Katello::ContentViewVersion.in_environment(env).find_by(:content_view => content_view) attributes = { :id => content_view.id, :cvv_id => cvv&.id, diff --git a/webpack/scenes/SmartProxy/ExpandableCvDetails.js b/webpack/scenes/SmartProxy/ExpandableCvDetails.js index 8f8336553f2..5ee84dea6d8 100644 --- a/webpack/scenes/SmartProxy/ExpandableCvDetails.js +++ b/webpack/scenes/SmartProxy/ExpandableCvDetails.js @@ -48,6 +48,7 @@ const ExpandableCvDetails = ({ contentViews, counts }) => { { ; -test('Can display Smart proxy content table', async (done) => { +test('Can display Smart proxy content table and expand env and cv details', async (done) => { const detailsScope = nockInstance .get(smartProxyContentPath) .query(true) .reply(200, smartProxyContent); - const { getByText, getAllByText, getAllByLabelText } = renderWithRedux(contentTable); + const { + getByText, getAllByText, getByLabelText, + } = renderWithRedux(contentTable); await patientlyWaitFor(() => expect(getByText('Environment')).toBeInTheDocument()); - expect(getAllByText('Content view')[0]).toBeInTheDocument(); + const tdEnvExpand = getByLabelText('expand-env-1'); + const envExpansion = within(tdEnvExpand).getByLabelText('Details'); + envExpansion.click(); + await patientlyWaitFor(() => expect(getAllByText('Content view')[0]).toBeInTheDocument()); expect(getAllByText('Last published')[0]).toBeInTheDocument(); expect(getAllByText('Repository')[0]).toBeInTheDocument(); expect(getAllByText('Synced')[0]).toBeInTheDocument(); - expect(getAllByLabelText('Details')[0]).toHaveAttribute('aria-expanded', 'false'); - getAllByLabelText('Details')[0].click(); - expect(getAllByLabelText('Details')[0]).toHaveAttribute('aria-expanded', 'true'); + const tdCvExpand = getByLabelText('expand-cv-1'); + const cvExpansion = within(tdCvExpand).getByLabelText('Details'); + expect(cvExpansion).toHaveAttribute('aria-expanded', 'false'); + cvExpansion.click(); + await patientlyWaitFor(() => expect(cvExpansion).toHaveAttribute('aria-expanded', 'true')); expect(getByText('Library')).toBeInTheDocument(); expect(getByText('Default Organization View')).toBeInTheDocument(); - expect(getByText('dev')).toBeInTheDocument(); - - + expect(getAllByText('dev')[0]).toBeInTheDocument(); + expect(getAllByText('Repository')[0]).toBeInTheDocument(); + expect(getAllByText('Packages')[0]).toBeInTheDocument(); + expect(getAllByText('Additional content')[0]).toBeInTheDocument(); + expect(getAllByText('repo1')[0]).toBeInTheDocument(); + expect(getAllByText('22 Packages')[0]).toBeInTheDocument(); + expect(getAllByText(/7 errata/i)[0]).toBeInTheDocument(); + expect(getAllByText(/14 Module streams/i)[0]).toBeInTheDocument(); + expect(getAllByText(/2 Package groups/i)[0]).toBeInTheDocument(); assertNockRequest(detailsScope, done); }); From 82fc4db230d8f7a1e13f0ee9ddfeba8dd3d41b15 Mon Sep 17 00:00:00 2001 From: Samir Jha Date: Fri, 20 Oct 2023 19:46:21 +0000 Subject: [PATCH 4/5] Fixes #36807 - Store env repo content counts with additional metadata for smart proxy --- .../concerns/smart_proxy_extensions.rb | 21 ++++++++----------- .../v2/capsule_content/sync_status.json.rabl | 5 ++++- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/models/katello/concerns/smart_proxy_extensions.rb b/app/models/katello/concerns/smart_proxy_extensions.rb index 3b644a620eb..be7c09650c4 100644 --- a/app/models/katello/concerns/smart_proxy_extensions.rb +++ b/app/models/katello/concerns/smart_proxy_extensions.rb @@ -122,7 +122,7 @@ def alternate_content_sources end def update_content_counts! - # {:content_view_versions=>{87=>{:repositories=>{1=>{:rpms=>98, :module_streams=>9898}}}}} + # {:content_view_versions=>{87=>{:repositories=>{1=>{:metadata=>{},:counts=>{:rpms=>98, :module_streams=>9898}}}}} new_content_counts = { content_view_versions: {} } smart_proxy_helper = ::Katello::SmartProxyHelper.new(self) repos = smart_proxy_helper.repositories_available_to_capsule @@ -131,28 +131,25 @@ def update_content_counts! repos.each do |repo| repo_mirror_service = repo.backend_service(self).with_mirror_adapter repo_content_counts = repo_mirror_service.latest_content_counts - translated_counts = {} + translated_counts = {metadata: {}, counts: {}} + translated_counts[:metadata] = {env_id: repo.environment_id, library_instance_id: repo.library_instance_or_self.id } repo_content_counts&.each do |name, count| count = count[:count] # Some content units in Pulp have the same model if name == 'rpm.package' && repo.content_counts['srpm'] > 0 - translated_counts['srpm'] = repo_mirror_service.count_by_pulpcore_type(::Katello::Pulp3::Srpm) - translated_counts['rpm'] = count - translated_counts['srpm'] + translated_counts[:counts]['srpm'] = repo_mirror_service.count_by_pulpcore_type(::Katello::Pulp3::Srpm) + translated_counts[:counts]['rpm'] = count - translated_counts[:counts]['srpm'] elsif name == 'container.manifest' && repo.content_counts['docker_manifest_list'] > 0 - translated_counts['docker_manifest_list'] = repo_mirror_service.count_by_pulpcore_type(::Katello::Pulp3::DockerManifestList) - translated_counts['docker_manifest'] = count - translated_counts['docker_manifest_list'] + translated_counts[:counts]['docker_manifest_list'] = repo_mirror_service.count_by_pulpcore_type(::Katello::Pulp3::DockerManifestList) + translated_counts[:counts]['docker_manifest'] = count - translated_counts[:counts]['docker_manifest_list'] else - translated_counts[::Katello::Pulp3::PulpContentUnit.katello_name_from_pulpcore_name(name, repo)] = count + translated_counts[:counts][::Katello::Pulp3::PulpContentUnit.katello_name_from_pulpcore_name(name, repo)] = count end end new_content_counts[:content_view_versions][repo.content_view_version_id] ||= { repositories: {}} # Store counts on capsule of archived repos which are reused across environment copies # of the archived repo corresponding to each environment CV version is promoted to. - if repo.content_view_version.default? - new_content_counts[:content_view_versions][repo.content_view_version_id][:repositories][repo.id] = translated_counts - else - 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 - end + new_content_counts[:content_view_versions][repo.content_view_version_id][:repositories][repo.id] = translated_counts end update(content_counts: new_content_counts) end diff --git a/app/views/katello/api/v2/capsule_content/sync_status.json.rabl b/app/views/katello/api/v2/capsule_content/sync_status.json.rabl index b3d8fca5bc8..afdbb1f5dd0 100644 --- a/app/views/katello/api/v2/capsule_content/sync_status.json.rabl +++ b/app/views/katello/api/v2/capsule_content/sync_status.json.rabl @@ -22,6 +22,10 @@ child :last_sync_task => :last_sync_task do extends 'foreman_tasks/api/tasks/show' end +node :content_counts do + @capsule.content_counts +end + child @lifecycle_environments => :lifecycle_environments do extends 'katello/api/v2/common/identifier' extends 'katello/api/v2/common/org_reference' @@ -35,7 +39,6 @@ child @lifecycle_environments => :lifecycle_environments do node :counts do |env| { :content_views => env.content_views.non_default.count, - :content_counts => @capsule.content_counts } end From 46c7d01b04543cecce1ca596628841b3f0213da6 Mon Sep 17 00:00:00 2001 From: Samir Jha Date: Mon, 23 Oct 2023 13:59:32 +0000 Subject: [PATCH 5/5] Fixes #36807 - Update UI for metadata in content counts --- .../concerns/smart_proxy_extensions.rb | 7 +- .../smart_proxies/_content_tab.html.erb | 2 +- .../v2/capsule_content/sync_status.json.rabl | 8 +- .../concerns/smart_proxy_extensions_test.rb | 76 +- .../Details/Repositories/RepoIcon.js | 3 +- .../scenes/SmartProxy/ExpandableCvDetails.js | 17 +- .../ExpandedSmartProxyRepositories.js | 104 +- .../SmartProxy/SmartProxyContentActions.js | 2 +- .../SmartProxy/SmartProxyExpandableTable.js | 9 +- .../__tests__/SmartProxyContent.fixtures.json | 1500 ----------------- .../SmartProxyContentTest.fixtures.json | 799 +++++++++ .../__tests__/SmartProxyContentTest.js | 2 +- 12 files changed, 987 insertions(+), 1542 deletions(-) delete mode 100644 webpack/scenes/SmartProxy/__tests__/SmartProxyContent.fixtures.json create mode 100644 webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.fixtures.json diff --git a/app/models/katello/concerns/smart_proxy_extensions.rb b/app/models/katello/concerns/smart_proxy_extensions.rb index be7c09650c4..c6c2e218f8e 100644 --- a/app/models/katello/concerns/smart_proxy_extensions.rb +++ b/app/models/katello/concerns/smart_proxy_extensions.rb @@ -132,7 +132,12 @@ def update_content_counts! repo_mirror_service = repo.backend_service(self).with_mirror_adapter repo_content_counts = repo_mirror_service.latest_content_counts translated_counts = {metadata: {}, counts: {}} - translated_counts[:metadata] = {env_id: repo.environment_id, library_instance_id: repo.library_instance_or_self.id } + translated_counts[:metadata] = { + env_id: repo.environment_id, + library_instance_id: repo.library_instance_or_self.id, + product_id: repo.product_id, + content_type: repo.content_type + } repo_content_counts&.each do |name, count| count = count[:count] # Some content units in Pulp have the same model diff --git a/app/views/foreman/smart_proxies/_content_tab.html.erb b/app/views/foreman/smart_proxies/_content_tab.html.erb index 48000252847..c54de330c98 100644 --- a/app/views/foreman/smart_proxies/_content_tab.html.erb +++ b/app/views/foreman/smart_proxies/_content_tab.html.erb @@ -1,3 +1,3 @@ <%= javascript_include_tag *webpack_asset_paths('katello', extension: 'js') %> <% @smartProxyId= @smart_proxy.id %> -<%= react_component('Content', smartProxyId: @smartProxyId, organizationId: Organization.current.id,) %> +<%= react_component('Content', smartProxyId: @smartProxyId, organizationId: Organization.current&.id,) %> diff --git a/app/views/katello/api/v2/capsule_content/sync_status.json.rabl b/app/views/katello/api/v2/capsule_content/sync_status.json.rabl index afdbb1f5dd0..d4791c8cd27 100644 --- a/app/views/katello/api/v2/capsule_content/sync_status.json.rabl +++ b/app/views/katello/api/v2/capsule_content/sync_status.json.rabl @@ -23,7 +23,7 @@ child :last_sync_task => :last_sync_task do end node :content_counts do - @capsule.content_counts + @capsule.content_counts end child @lifecycle_environments => :lifecycle_environments do @@ -38,7 +38,7 @@ 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 } end @@ -62,7 +62,9 @@ child @lifecycle_environments => :lifecycle_environments do { :id => repo.id, :name => repo.name, - :library_id => repo.library_instance_id + :library_id => repo.library_instance_id, + :product_id => repo.product_id, + :content_type => repo.content_type } end } diff --git a/test/models/concerns/smart_proxy_extensions_test.rb b/test/models/concerns/smart_proxy_extensions_test.rb index b3ed7580b0d..2000f82371f 100644 --- a/test/models/concerns/smart_proxy_extensions_test.rb +++ b/test/models/concerns/smart_proxy_extensions_test.rb @@ -95,20 +95,80 @@ def test_update_content_counts python_service.expects(:latest_content_counts).once.returns(python_counts) repos = [yum_repo, file_repo, ansible_repo, container_repo, ostree_repo, deb_repo, python_repo] - yum_repo.content_view_version.expects(:default?).returns(true) ::Katello::SmartProxyHelper.any_instance.expects(:repositories_available_to_capsule).once.returns(repos) @proxy.update_content_counts! counts = @proxy.content_counts expected_counts = { "content_view_versions" => { yum_repo.content_view_version.id.to_s => { "repositories" => - { yum_repo.id.to_s => { "erratum" => 4, "srpm" => 1, "rpm" => 31, "module_stream" => 7, "rpm.modulemd_defaults" => 3, "package_group" => 7, "rpm.packagecategory" => 1 }, - file_repo.id.to_s => { "file" => 100 }, - ansible_repo.id.to_s => { "ansible.collection" => 802 }, - container_repo.id.to_s => { "container.blob" => 30, "docker_manifest_list" => 1, "docker_manifest" => 9, "docker_tag" => 5 }, - ostree_repo.id.to_s => {"ostree_ref" => 30 }, - deb_repo.id.to_s => { "deb" => 987 }, - python_repo.id.to_s => { "python_package" => 42 } + { yum_repo.id.to_s => { + "metadata" => { + "env_id" => yum_repo.environment.id, + "library_instance_id" => yum_repo.library_instance_or_self.id, + "product_id" => yum_repo.product_id, + "content_type" => yum_repo.content_type + }, + "counts" => { "erratum" => 4, "srpm" => 1, "rpm" => 31, "module_stream" => 7, "rpm.modulemd_defaults" => 3, "package_group" => 7, "rpm.packagecategory" => 1 } + }, + file_repo.id.to_s => { + "metadata" => { + "env_id" => file_repo.environment.id, + "library_instance_id" => file_repo.library_instance_or_self.id, + "product_id" => file_repo.product_id, + "content_type" => file_repo.content_type + }, + "counts" => + { "file" => 100 } + }, + ansible_repo.id.to_s => { + "metadata" => { + "env_id" => ansible_repo.environment.id, + "library_instance_id" => ansible_repo.library_instance_or_self.id, + "product_id" => ansible_repo.product_id, + "content_type" => ansible_repo.content_type}, + "counts" => + { "ansible.collection" => 802 } + }, + container_repo.id.to_s => { + "metadata" => { + "env_id" => container_repo.environment.id, + "library_instance_id" => container_repo.library_instance_or_self.id, + "product_id" => container_repo.product_id, + "content_type" => container_repo.content_type + }, + "counts" => + { "container.blob" => 30, "docker_manifest_list" => 1, "docker_manifest" => 9, "docker_tag" => 5 } + }, + ostree_repo.id.to_s => { + "metadata" => { + "env_id" => ostree_repo.environment.id, + "library_instance_id" => ostree_repo.library_instance_or_self.id, + "product_id" => ostree_repo.product_id, + "content_type" => ostree_repo.content_type + }, + "counts" => + {"ostree_ref" => 30 } + }, + deb_repo.id.to_s => { + "metadata" => { + "env_id" => deb_repo.environment.id, + "library_instance_id" => deb_repo.library_instance_or_self.id, + "product_id" => deb_repo.product_id, + "content_type" => deb_repo.content_type + }, + "counts" => + { "deb" => 987 } + }, + python_repo.id.to_s => { + "metadata" => { + "env_id" => python_repo.environment.id, + "library_instance_id" => python_repo.library_instance_or_self.id, + "product_id" => python_repo.product_id, + "content_type" => python_repo.content_type + }, + "counts" => + { "python_package" => 42 } + } } } } diff --git a/webpack/scenes/ContentViews/Details/Repositories/RepoIcon.js b/webpack/scenes/ContentViews/Details/Repositories/RepoIcon.js index 8da108f3f6d..30a47cb6692 100644 --- a/webpack/scenes/ContentViews/Details/Repositories/RepoIcon.js +++ b/webpack/scenes/ContentViews/Details/Repositories/RepoIcon.js @@ -1,6 +1,6 @@ import React from 'react'; import { Tooltip } from '@patternfly/react-core'; -import { BundleIcon, MiddlewareIcon, BoxIcon, CodeBranchIcon, FanIcon, TenantIcon } from '@patternfly/react-icons'; +import { BundleIcon, MiddlewareIcon, BoxIcon, CodeBranchIcon, FanIcon, TenantIcon, AnsibleTowerIcon } from '@patternfly/react-icons'; import PropTypes from 'prop-types'; const RepoIcon = ({ type }) => { @@ -10,6 +10,7 @@ const RepoIcon = ({ type }) => { ostree: CodeBranchIcon, file: TenantIcon, deb: FanIcon, + ansible_collection: AnsibleTowerIcon, }; const Icon = iconMap[type] || BoxIcon; diff --git a/webpack/scenes/SmartProxy/ExpandableCvDetails.js b/webpack/scenes/SmartProxy/ExpandableCvDetails.js index 5ee84dea6d8..fcfe8425310 100644 --- a/webpack/scenes/SmartProxy/ExpandableCvDetails.js +++ b/webpack/scenes/SmartProxy/ExpandableCvDetails.js @@ -9,14 +9,14 @@ import ContentViewIcon from '../ContentViews/components/ContentViewIcon'; import { useSet } from '../../components/Table/TableHooks'; import ExpandedSmartProxyRepositories from './ExpandedSmartProxyRepositories'; -const ExpandableCvDetails = ({ contentViews, counts }) => { +const ExpandableCvDetails = ({ contentViews, contentCounts, envId }) => { const columnHeaders = [ __('Content view'), __('Version'), __('Last published'), __('Synced'), ]; - const { content_counts: contentCounts } = counts; + // const { content_counts: contentCounts } = counts; const expandedTableRows = useSet([]); const tableRowIsExpanded = id => expandedTableRows.has(id); @@ -75,6 +75,7 @@ const ExpandableCvDetails = ({ contentViews, counts }) => { contentCounts={contentCounts?.content_view_versions[versionId]?.repositories} repositories={repositories} syncedToCapsule={upToDate} + envId={envId} /> @@ -89,16 +90,18 @@ const ExpandableCvDetails = ({ contentViews, counts }) => { ExpandableCvDetails.propTypes = { contentViews: PropTypes.arrayOf(PropTypes.shape({})), - counts: PropTypes.shape({ - content_counts: PropTypes.shape({ - content_view_versions: PropTypes.shape({}), - }), + contentCounts: PropTypes.shape({ + content_view_versions: PropTypes.shape({}), }), + envId: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.string, // The API can sometimes return strings + ]).isRequired, }; ExpandableCvDetails.defaultProps = { contentViews: [], - counts: {}, + contentCounts: {}, }; export default ExpandableCvDetails; diff --git a/webpack/scenes/SmartProxy/ExpandedSmartProxyRepositories.js b/webpack/scenes/SmartProxy/ExpandedSmartProxyRepositories.js index 614970cfc71..745825c975e 100644 --- a/webpack/scenes/SmartProxy/ExpandedSmartProxyRepositories.js +++ b/webpack/scenes/SmartProxy/ExpandedSmartProxyRepositories.js @@ -5,23 +5,87 @@ import { translate as __ } from 'foremanReact/common/I18n'; import { DataList, DataListItem, DataListItemRow, DataListItemCells, DataListCell } from '@patternfly/react-core'; import AdditionalCapsuleContent from './AdditionalCapsuleContent'; import InactiveText from '../ContentViews/components/InactiveText'; +import RepoIcon from '../ContentViews/Details/Repositories/RepoIcon'; + +const ExpandedSmartProxyRepositories = ({ + contentCounts, repositories, syncedToCapsule, envId, +}) => { + const filterDataByEnvId = () => { + const filteredData = {}; + + Object.keys(contentCounts).forEach((key) => { + const entry = contentCounts[key]; + if (entry.metadata.env_id === envId) { + filteredData[key] = entry; + } + }); + + return filteredData; + }; + const envContentCounts = filterDataByEnvId(); -const ExpandedSmartProxyRepositories = ({ contentCounts, repositories, syncedToCapsule }) => { const getRepositoryNameById = id => (repositories.find(repo => - Number(repo.id) === Number(id)) || {}).name; - const dataListCellLists = (repo) => { + Number(repo.id) === Number(id) || Number(repo.library_id) === Number(id)) || {}).name; + + const dataListCellLists = (repoCounts, repo) => { const cellList = []; /* eslint-disable max-len */ - if (syncedToCapsule) { - cellList.push({getRepositoryNameById(repo)}); - cellList.push({contentCounts[repo].rpm ? `${contentCounts[repo].rpm} Packages` : 'N/A'}); - cellList.push(); - } else { - cellList.push(); - } + cellList.push({getRepositoryNameById(envContentCounts[repo].metadata.library_instance_id)}); + cellList.push(); + cellList.push({envContentCounts[repo].counts.rpm ? `${envContentCounts[repo].counts.rpm} Packages` : 'N/A'}); + cellList.push(); + /* eslint-enable max-len */ + return cellList; + }; + + const dataListCellListsNotSynced = (repo) => { + const cellList = []; + /* eslint-disable max-len */ + cellList.push({repo.name}); + cellList.push(); + cellList.push(); + cellList.push(); /* eslint-enable max-len */ return cellList; }; + if (syncedToCapsule) { + return ( + + + + + {__('Repository')} + , + {__('Type')}, + {__('Packages')}, + {__('Additional content')}, + ]} + /> + + + {Object.keys(envContentCounts).length ? + Object.keys(envContentCounts).map((repo, index) => ( + + + + + + )) : + + + ]} + /> + + + } + + ); + } + return ( @@ -30,34 +94,40 @@ const ExpandedSmartProxyRepositories = ({ contentCounts, repositories, syncedToC {__('Repository')} , + {__('Type')}, {__('Packages')}, {__('Additional content')}, ]} /> - {Object.keys(contentCounts).length ? - Object.keys(contentCounts).map((repo, index) => ( + {repositories.length ? + repositories.map((repo, index) => ( - + )) : - ]} /> + ]} + /> - } - - ); + } + ); }; ExpandedSmartProxyRepositories.propTypes = { contentCounts: PropTypes.shape({}), repositories: PropTypes.arrayOf(PropTypes.shape({})), syncedToCapsule: PropTypes.bool, + envId: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.string, // The API can sometimes return strings + ]).isRequired, }; ExpandedSmartProxyRepositories.defaultProps = { diff --git a/webpack/scenes/SmartProxy/SmartProxyContentActions.js b/webpack/scenes/SmartProxy/SmartProxyContentActions.js index ea01be86969..a9a4b103ab9 100644 --- a/webpack/scenes/SmartProxy/SmartProxyContentActions.js +++ b/webpack/scenes/SmartProxy/SmartProxyContentActions.js @@ -8,7 +8,7 @@ import { getResponseErrorMsgs } from '../../utils/helpers'; const getSmartProxyContent = ({ smartProxyId, organizationId }) => get({ type: API_OPERATIONS.GET, key: SMART_PROXY_CONTENT_KEY, - url: api.getApiUrl(`/capsules/${smartProxyId}/content/sync?organization_id=${organizationId}`), + url: api.getApiUrl(organizationId ? `/capsules/${smartProxyId}/content/sync?organization_id=${organizationId}` : `/capsules/${smartProxyId}/content/sync`), }); export const getSmartProxies = () => get({ diff --git a/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js b/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js index 559186ca170..6da2412b3a2 100644 --- a/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js +++ b/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js @@ -26,6 +26,7 @@ const SmartProxyExpandableTable = ({ smartProxyId, organizationId }) => { let metadata = {}; const { lifecycle_environments: results, last_sync_task: lastTask, last_sync_words: lastSyncWords, + content_counts: contentCounts, } = response; if (results) { metadata = { total: results.length, subtotal: results.length }; @@ -88,7 +89,7 @@ const SmartProxyExpandableTable = ({ smartProxyId, organizationId }) => { { results?.map((env, rowIndex) => { const { - id, content_views: contentViews, counts, + id, content_views: contentViews, } = env; const isExpanded = tableRowIsExpanded(id); return ( @@ -116,7 +117,11 @@ const SmartProxyExpandableTable = ({ smartProxyId, organizationId }) => { {isExpanded ? - : + : <>} diff --git a/webpack/scenes/SmartProxy/__tests__/SmartProxyContent.fixtures.json b/webpack/scenes/SmartProxy/__tests__/SmartProxyContent.fixtures.json deleted file mode 100644 index 25acd2767a3..00000000000 --- a/webpack/scenes/SmartProxy/__tests__/SmartProxyContent.fixtures.json +++ /dev/null @@ -1,1500 +0,0 @@ -{ - "last_sync_time": "2023-10-18 23:17:59 -0400", - "download_policy": "on_demand", - "active_sync_tasks": [], - "last_failed_sync_tasks": [], - "last_sync_task": { - "id": "d2f1e72c-d96a-467f-9c3c-cdf37f6de9a9", - "label": "Actions::Katello::CapsuleContent::Sync", - "pending": false, - "action": "Synchronize smart proxy 'centos8-proxy-devel2.sajha.example.com'", - "username": "admin", - "started_at": "2023-10-18 23:16:55 -0400", - "ended_at": "2023-10-18 23:17:59 -0400", - "state": "stopped", - "result": "success", - "progress": 1, - "input": { - "options": { - "environment_id": null, - "content_view_id": null, - "repository_id": null, - "skip_metadata_check": true - }, - "smart_proxy": { - "id": 2, - "name": "centos8-proxy-devel2.sajha.example.com" - }, - "services_checked": [ - "pulp3" - ], - "smart_proxy_id": 2, - "locale": "en", - "current_request_id": "16b86c86-c972-44b4-8f23-c9990349f365", - "current_timezone": "America/New_York", - "current_organization_id": 1, - "current_location_id": 2, - "current_user_id": 4 - }, - "output": {}, - "humanized": { - "action": "Synchronize smart proxy", - "input": [ - "'centos8-proxy-devel2.sajha.example.com'" - ], - "output": "", - "errors": [] - }, - "cli_example": null, - "start_at": "2023-10-18 23:16:55 -0400", - "available_actions": { - "cancellable": false, - "resumable": false - } - }, - "lifecycle_environments": [ - { - "library": true, - "id": 1, - "name": "Library", - "label": "Library", - "description": null, - "organization_id": 1, - "organization": { - "name": "Default Organization", - "label": "Default_Organization", - "id": 1 - }, - "syncable": false, - "counts": { - "content_views": 7, - "content_counts": { - "content_view_versions": { - "1": { - "repositories": { - "1": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "3": { - "ansible_collection": 10 - }, - "16": { - "file": 3 - }, - "20": { - "rpm": 71, - "erratum": 31, - "rpm.modulemd": 31, - "rpm.repo_metadata_file": 1 - }, - "40": { - "python_package": 275 - }, - "71": {}, - "72": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "10": { - "repositories": { - "59": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "61": { - "python_package": 243 - }, - "62": { - "ansible_collection": 10 - } - } - }, - "12": { - "repositories": { - "73": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "75": {}, - "76": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "13": { - "repositories": { - "84": { - "ansible_collection": 10 - }, - "86": { - "python_package": 243 - } - } - }, - "17": { - "repositories": { - "95": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "18": { - "repositories": { - "97": { - "rpm": 14, - "erratum": 6, - "rpm.modulemd": 14, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "21": { - "repositories": { - "120": { - "ansible_collection": 10 - }, - "121": { - "python_package": 275 - } - } - }, - "22": { - "repositories": { - "122": { - "rpm": 71, - "erratum": 31, - "rpm.modulemd": 31, - "rpm.repo_metadata_file": 1 - }, - "123": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "124": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "23": { - "repositories": { - "125": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "24": { - "repositories": { - "127": { - "rpm": 14, - "erratum": 6, - "rpm.modulemd": 14, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - } - } - } - }, - "content_views": [ - { - "id": 1, - "cvv_id": 1, - "cvv_version": "1.0", - "label": "Default_Organization_View", - "name": "Default Organization View", - "composite": false, - "last_published": "2023-08-22 14:50:34 -0400", - "default": true, - "up_to_date": true, - "counts": { - "repositories": 7 - }, - "repositories": [ - { - "id": 3, - "name": "test_ansible", - "library_id": null - }, - { - "id": 20, - "name": "Advanced Virtualization CodeReady Builder for RHEL 8 Power little endian RPMs", - "library_id": null - }, - { - "id": 1, - "name": "repo1", - "library_id": null - }, - { - "id": 16, - "name": "file_repo", - "library_id": null - }, - { - "id": 40, - "name": "python-pulp", - "library_id": null - }, - { - "id": 71, - "name": "Advanced Virtualization CodeReady Builder for RHEL 8 IBM z Systems RPMs", - "library_id": null - }, - { - "id": 72, - "name": "deb_test", - "library_id": null - } - ] - }, - { - "id": 2, - "cvv_id": 22, - "cvv_version": "7.0", - "label": "test", - "name": "test", - "composite": false, - "last_published": "2023-10-06 11:13:11 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 3 - }, - "repositories": [ - { - "id": 122, - "name": "Advanced Virtualization CodeReady Builder for RHEL 8 Power little endian RPMs", - "library_id": 20 - }, - { - "id": 123, - "name": "repo1", - "library_id": 1 - }, - { - "id": 124, - "name": "deb_test", - "library_id": 72 - } - ] - }, - { - "id": 3, - "cvv_id": 21, - "cvv_version": "8.0", - "label": "dev", - "name": "dev", - "composite": false, - "last_published": "2023-10-06 11:12:57 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 2 - }, - "repositories": [ - { - "id": 121, - "name": "python-pulp", - "library_id": 40 - }, - { - "id": 120, - "name": "test_ansible", - "library_id": 3 - } - ] - }, - { - "id": 4, - "cvv_id": 4, - "cvv_version": "1.0", - "label": "redhat_test", - "name": "redhat_test", - "composite": false, - "last_published": "2023-09-07 17:01:41 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 0 - }, - "repositories": [] - }, - { - "id": 6, - "cvv_id": 10, - "cvv_version": "1.0", - "label": "dup_container", - "name": "dup_container", - "composite": true, - "last_published": "2023-09-15 14:34:29 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 3 - }, - "repositories": [ - { - "id": 59, - "name": "repo1", - "library_id": 1 - }, - { - "id": 61, - "name": "python-pulp", - "library_id": 40 - }, - { - "id": 62, - "name": "test_ansible", - "library_id": 3 - } - ] - }, - { - "id": 7, - "cvv_id": 24, - "cvv_version": "3.0", - "label": "c1", - "name": "c1", - "composite": false, - "last_published": "2023-10-11 12:14:34 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 1 - }, - "repositories": [ - { - "id": 127, - "name": "repo1", - "library_id": 1 - } - ] - }, - { - "id": 8, - "cvv_id": 23, - "cvv_version": "2.0", - "label": "c2", - "name": "c2", - "composite": false, - "last_published": "2023-10-11 11:55:34 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 1 - }, - "repositories": [ - { - "id": 125, - "name": "repo1", - "library_id": 1 - } - ] - }, - { - "id": 9, - "cvv_id": 17, - "cvv_version": "1.0", - "label": "ccv1", - "name": "ccv1", - "composite": true, - "last_published": "2023-10-05 16:08:39 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 1 - }, - "repositories": [ - { - "id": 95, - "name": "repo1", - "library_id": 1 - } - ] - } - ] - }, - { - "library": false, - "id": 2, - "name": "dev", - "label": "dev", - "description": null, - "organization_id": 1, - "organization": { - "name": "Default Organization", - "label": "Default_Organization", - "id": 1 - }, - "syncable": false, - "counts": { - "content_views": 2, - "content_counts": { - "content_view_versions": { - "1": { - "repositories": { - "1": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "3": { - "ansible_collection": 10 - }, - "16": { - "file": 3 - }, - "20": { - "rpm": 71, - "erratum": 31, - "rpm.modulemd": 31, - "rpm.repo_metadata_file": 1 - }, - "40": { - "python_package": 275 - }, - "71": {}, - "72": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "10": { - "repositories": { - "59": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "61": { - "python_package": 243 - }, - "62": { - "ansible_collection": 10 - } - } - }, - "12": { - "repositories": { - "73": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "75": {}, - "76": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "13": { - "repositories": { - "84": { - "ansible_collection": 10 - }, - "86": { - "python_package": 243 - } - } - }, - "17": { - "repositories": { - "95": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "18": { - "repositories": { - "97": { - "rpm": 14, - "erratum": 6, - "rpm.modulemd": 14, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "21": { - "repositories": { - "120": { - "ansible_collection": 10 - }, - "121": { - "python_package": 275 - } - } - }, - "22": { - "repositories": { - "122": { - "rpm": 71, - "erratum": 31, - "rpm.modulemd": 31, - "rpm.repo_metadata_file": 1 - }, - "123": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "124": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "23": { - "repositories": { - "125": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "24": { - "repositories": { - "127": { - "rpm": 14, - "erratum": 6, - "rpm.modulemd": 14, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - } - } - } - }, - "content_views": [ - { - "id": 2, - "cvv_id": 12, - "cvv_version": "5.0", - "label": "test", - "name": "test", - "composite": false, - "last_published": "2023-09-28 14:08:06 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 3 - }, - "repositories": [ - { - "id": 75, - "name": "Advanced Virtualization CodeReady Builder for RHEL 8 Power little endian RPMs", - "library_id": 20 - }, - { - "id": 76, - "name": "deb_test", - "library_id": 72 - }, - { - "id": 73, - "name": "repo1", - "library_id": 1 - } - ] - }, - { - "id": 3, - "cvv_id": 13, - "cvv_version": "5.0", - "label": "dev", - "name": "dev", - "composite": false, - "last_published": "2023-10-03 14:40:03 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 2 - }, - "repositories": [ - { - "id": 84, - "name": "test_ansible", - "library_id": 3 - }, - { - "id": 86, - "name": "python-pulp", - "library_id": 40 - } - ] - } - ] - }, - { - "library": false, - "id": 3, - "name": "test", - "label": "test", - "description": null, - "organization_id": 1, - "organization": { - "name": "Default Organization", - "label": "Default_Organization", - "id": 1 - }, - "syncable": false, - "counts": { - "content_views": 2, - "content_counts": { - "content_view_versions": { - "1": { - "repositories": { - "1": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "3": { - "ansible_collection": 10 - }, - "16": { - "file": 3 - }, - "20": { - "rpm": 71, - "erratum": 31, - "rpm.modulemd": 31, - "rpm.repo_metadata_file": 1 - }, - "40": { - "python_package": 275 - }, - "71": {}, - "72": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "10": { - "repositories": { - "59": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "61": { - "python_package": 243 - }, - "62": { - "ansible_collection": 10 - } - } - }, - "12": { - "repositories": { - "73": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "75": {}, - "76": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "13": { - "repositories": { - "84": { - "ansible_collection": 10 - }, - "86": { - "python_package": 243 - } - } - }, - "17": { - "repositories": { - "95": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "18": { - "repositories": { - "97": { - "rpm": 14, - "erratum": 6, - "rpm.modulemd": 14, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "21": { - "repositories": { - "120": { - "ansible_collection": 10 - }, - "121": { - "python_package": 275 - } - } - }, - "22": { - "repositories": { - "122": { - "rpm": 71, - "erratum": 31, - "rpm.modulemd": 31, - "rpm.repo_metadata_file": 1 - }, - "123": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "124": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "23": { - "repositories": { - "125": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "24": { - "repositories": { - "127": { - "rpm": 14, - "erratum": 6, - "rpm.modulemd": 14, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - } - } - } - }, - "content_views": [ - { - "id": 2, - "cvv_id": 12, - "cvv_version": "5.0", - "label": "test", - "name": "test", - "composite": false, - "last_published": "2023-09-28 14:08:06 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 3 - }, - "repositories": [ - { - "id": 75, - "name": "Advanced Virtualization CodeReady Builder for RHEL 8 Power little endian RPMs", - "library_id": 20 - }, - { - "id": 76, - "name": "deb_test", - "library_id": 72 - }, - { - "id": 73, - "name": "repo1", - "library_id": 1 - } - ] - }, - { - "id": 3, - "cvv_id": 13, - "cvv_version": "5.0", - "label": "dev", - "name": "dev", - "composite": false, - "last_published": "2023-10-03 14:40:03 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 2 - }, - "repositories": [ - { - "id": 84, - "name": "test_ansible", - "library_id": 3 - }, - { - "id": 86, - "name": "python-pulp", - "library_id": 40 - } - ] - } - ] - }, - { - "library": false, - "id": 4, - "name": "qa", - "label": "qa", - "description": null, - "organization_id": 1, - "organization": { - "name": "Default Organization", - "label": "Default_Organization", - "id": 1 - }, - "syncable": false, - "counts": { - "content_views": 4, - "content_counts": { - "content_view_versions": { - "1": { - "repositories": { - "1": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "3": { - "ansible_collection": 10 - }, - "16": { - "file": 3 - }, - "20": { - "rpm": 71, - "erratum": 31, - "rpm.modulemd": 31, - "rpm.repo_metadata_file": 1 - }, - "40": { - "python_package": 275 - }, - "71": {}, - "72": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "10": { - "repositories": { - "59": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "61": { - "python_package": 243 - }, - "62": { - "ansible_collection": 10 - } - } - }, - "12": { - "repositories": { - "73": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "75": {}, - "76": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "13": { - "repositories": { - "84": { - "ansible_collection": 10 - }, - "86": { - "python_package": 243 - } - } - }, - "17": { - "repositories": { - "95": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "18": { - "repositories": { - "97": { - "rpm": 14, - "erratum": 6, - "rpm.modulemd": 14, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "21": { - "repositories": { - "120": { - "ansible_collection": 10 - }, - "121": { - "python_package": 275 - } - } - }, - "22": { - "repositories": { - "122": { - "rpm": 71, - "erratum": 31, - "rpm.modulemd": 31, - "rpm.repo_metadata_file": 1 - }, - "123": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "124": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "23": { - "repositories": { - "125": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "24": { - "repositories": { - "127": { - "rpm": 14, - "erratum": 6, - "rpm.modulemd": 14, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - } - } - } - }, - "content_views": [ - { - "id": 2, - "cvv_id": 22, - "cvv_version": "7.0", - "label": "test", - "name": "test", - "composite": false, - "last_published": "2023-10-06 11:13:11 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 3 - }, - "repositories": [ - { - "id": 122, - "name": "Advanced Virtualization CodeReady Builder for RHEL 8 Power little endian RPMs", - "library_id": 20 - }, - { - "id": 123, - "name": "repo1", - "library_id": 1 - }, - { - "id": 124, - "name": "deb_test", - "library_id": 72 - } - ] - }, - { - "id": 3, - "cvv_id": 21, - "cvv_version": "8.0", - "label": "dev", - "name": "dev", - "composite": false, - "last_published": "2023-10-06 11:12:57 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 2 - }, - "repositories": [ - { - "id": 121, - "name": "python-pulp", - "library_id": 40 - }, - { - "id": 120, - "name": "test_ansible", - "library_id": 3 - } - ] - }, - { - "id": 7, - "cvv_id": 18, - "cvv_version": "2.0", - "label": "c1", - "name": "c1", - "composite": false, - "last_published": "2023-10-06 10:58:24 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 1 - }, - "repositories": [ - { - "id": 97, - "name": "repo1", - "library_id": 1 - } - ] - }, - { - "id": 8, - "cvv_id": 23, - "cvv_version": "2.0", - "label": "c2", - "name": "c2", - "composite": false, - "last_published": "2023-10-11 11:55:34 -0400", - "default": false, - "up_to_date": true, - "counts": { - "repositories": 1 - }, - "repositories": [ - { - "id": 125, - "name": "repo1", - "library_id": 1 - } - ] - } - ] - }, - { - "library": false, - "id": 6, - "name": "qa2", - "label": "qa2", - "description": null, - "organization_id": 1, - "organization": { - "name": "Default Organization", - "label": "Default_Organization", - "id": 1 - }, - "syncable": true, - "counts": { - "content_views": 1, - "content_counts": { - "content_view_versions": { - "1": { - "repositories": { - "1": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "3": { - "ansible_collection": 10 - }, - "16": { - "file": 3 - }, - "20": { - "rpm": 71, - "erratum": 31, - "rpm.modulemd": 31, - "rpm.repo_metadata_file": 1 - }, - "40": { - "python_package": 275 - }, - "71": {}, - "72": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "10": { - "repositories": { - "59": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "61": { - "python_package": 243 - }, - "62": { - "ansible_collection": 10 - } - } - }, - "12": { - "repositories": { - "73": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "75": {}, - "76": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "13": { - "repositories": { - "84": { - "ansible_collection": 10 - }, - "86": { - "python_package": 243 - } - } - }, - "17": { - "repositories": { - "95": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "18": { - "repositories": { - "97": { - "rpm": 14, - "erratum": 6, - "rpm.modulemd": 14, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "21": { - "repositories": { - "120": { - "ansible_collection": 10 - }, - "121": { - "python_package": 275 - } - } - }, - "22": { - "repositories": { - "122": { - "rpm": 71, - "erratum": 31, - "rpm.modulemd": 31, - "rpm.repo_metadata_file": 1 - }, - "123": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - }, - "124": { - "deb": 6, - "deb.release": 2, - "deb.release_file": 2, - "deb.package_index": 5, - "deb.release_component": 2, - "deb.release_architecture": 5, - "deb.package_release_component": 6 - } - } - }, - "23": { - "repositories": { - "125": { - "rpm": 22, - "erratum": 7, - "rpm.modulemd": 14, - "package_group": 2, - "rpm.packagecategory": 1, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - }, - "24": { - "repositories": { - "127": { - "rpm": 14, - "erratum": 6, - "rpm.modulemd": 14, - "rpm.distribution_tree": 1, - "rpm.modulemd_defaults": 3 - } - } - } - } - } - }, - "content_views": [ - { - "id": 8, - "cvv_id": 23, - "cvv_version": "2.0", - "label": "c2", - "name": "c2", - "composite": false, - "last_published": "2023-10-11 11:55:34 -0400", - "default": false, - "up_to_date": false, - "counts": { - "repositories": 1 - }, - "repositories": [ - { - "id": 125, - "name": "repo1", - "library_id": 1 - } - ] - } - ] - } - ], - "last_sync_words": "1 day", - "unsyncable_content_types": [] -} \ No newline at end of file diff --git a/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.fixtures.json b/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.fixtures.json new file mode 100644 index 00000000000..6d24c7ed0f4 --- /dev/null +++ b/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.fixtures.json @@ -0,0 +1,799 @@ +{ + "last_sync_time": "2023-10-23 09:52:53 -0400", + "download_policy": "on_demand", + "active_sync_tasks": [], + "last_failed_sync_tasks": [], + "last_sync_task": { + "id": "d32ad89d-f37b-44d3-9bb0-e64f6758df3e", + "label": "Actions::Katello::CapsuleContent::Sync", + "pending": false, + "action": "Synchronize smart proxy 'centos8-proxy-devel2.sajha.example.com'", + "username": "admin", + "started_at": "2023-10-23 09:52:25 -0400", + "ended_at": "2023-10-23 09:52:53 -0400", + "state": "stopped", + "result": "success", + "progress": 1, + "input": { + "options": { + "content_view_id": 12, + "environment_id": 4 + }, + "smart_proxy": { + "id": 2, + "name": "centos8-proxy-devel2.sajha.example.com" + }, + "services_checked": [ + "pulp3" + ], + "smart_proxy_id": 2, + "locale": "en", + "current_request_id": "a5e3fd5b-daa9-4381-8273-077793a006ec", + "current_timezone": "America/New_York", + "current_organization_id": 1, + "current_location_id": 2, + "current_user_id": 4 + }, + "output": {}, + "humanized": { + "action": "Synchronize smart proxy", + "input": [ + "'centos8-proxy-devel2.sajha.example.com'" + ], + "output": "", + "errors": [] + }, + "cli_example": null, + "start_at": "2023-10-23 09:52:25 -0400", + "available_actions": { + "cancellable": false, + "resumable": false + } + }, + "lifecycle_environments": [ + { + "library": true, + "id": 1, + "name": "Library", + "label": "Library", + "description": null, + "organization_id": 1, + "organization": { + "name": "Default Organization", + "label": "Default_Organization", + "id": 1 + }, + "syncable": false, + "counts": { + "content_views": 3 + }, + "content_views": [ + { + "id": 1, + "cvv_id": 1, + "cvv_version": "1.0", + "label": "Default_Organization_View", + "name": "Default Organization View", + "composite": false, + "last_published": "2023-08-22 14:50:34 -0400", + "default": true, + "up_to_date": true, + "counts": { + "repositories": 7 + }, + "repositories": [ + { + "id": 3, + "name": "test_ansible", + "library_id": null + }, + { + "id": 20, + "name": "Advanced Virtualization CodeReady Builder for RHEL 8 Power little endian RPMs", + "library_id": null + }, + { + "id": 1, + "name": "repo1", + "library_id": null + }, + { + "id": 16, + "name": "file_repo", + "library_id": null + }, + { + "id": 40, + "name": "python-pulp", + "library_id": null + }, + { + "id": 71, + "name": "Advanced Virtualization CodeReady Builder for RHEL 8 IBM z Systems RPMs", + "library_id": null + }, + { + "id": 72, + "name": "deb_test", + "library_id": null + } + ] + }, + { + "id": 12, + "cvv_id": 30, + "cvv_version": "2.0", + "label": "cv1", + "name": "cv1", + "composite": false, + "last_published": "2023-10-23 09:52:08 -0400", + "default": false, + "up_to_date": true, + "counts": { + "repositories": 2 + }, + "repositories": [ + { + "id": 171, + "name": "python-pulp", + "library_id": 40 + }, + { + "id": 170, + "name": "repo1", + "library_id": 1 + } + ] + }, + { + "id": 13, + "cvv_id": 29, + "cvv_version": "2.0", + "label": "cv2", + "name": "cv2", + "composite": false, + "last_published": "2023-10-23 09:48:16 -0400", + "default": false, + "up_to_date": true, + "counts": { + "repositories": 5 + }, + "repositories": [ + { + "id": 163, + "name": "python-pulp", + "library_id": 40 + }, + { + "id": 161, + "name": "repo1", + "library_id": 1 + }, + { + "id": 164, + "name": "deb_test", + "library_id": 72 + }, + { + "id": 160, + "name": "test_ansible", + "library_id": 3 + }, + { + "id": 162, + "name": "file_repo", + "library_id": 16 + } + ] + }, + { + "id": 14, + "cvv_id": 28, + "cvv_version": "1.0", + "label": "ccv1", + "name": "ccv1", + "composite": true, + "last_published": "2023-10-23 09:45:23 -0400", + "default": false, + "up_to_date": true, + "counts": { + "repositories": 5 + }, + "repositories": [ + { + "id": 146, + "name": "repo1", + "library_id": 1 + }, + { + "id": 147, + "name": "test_ansible", + "library_id": 3 + }, + { + "id": 149, + "name": "file_repo", + "library_id": 16 + }, + { + "id": 148, + "name": "deb_test", + "library_id": 72 + }, + { + "id": 145, + "name": "python-pulp", + "library_id": 40 + } + ] + } + ] + }, + { + "library": false, + "id": 2, + "name": "dev", + "label": "dev", + "description": null, + "organization_id": 1, + "organization": { + "name": "Default Organization", + "label": "Default_Organization", + "id": 1 + }, + "syncable": false, + "counts": { + "content_views": 1 + }, + "content_views": [ + { + "id": 12, + "cvv_id": 26, + "cvv_version": "1.0", + "label": "cv1", + "name": "cv1", + "composite": false, + "last_published": "2023-10-20 14:44:49 -0400", + "default": false, + "up_to_date": true, + "counts": { + "repositories": 2 + }, + "repositories": [ + { + "id": 130, + "name": "python-pulp", + "library_id": 40 + }, + { + "id": 129, + "name": "repo1", + "library_id": 1 + } + ] + } + ] + }, + { + "library": false, + "id": 4, + "name": "qa", + "label": "qa", + "description": null, + "organization_id": 1, + "organization": { + "name": "Default Organization", + "label": "Default_Organization", + "id": 1 + }, + "syncable": false, + "counts": { + "content_views": 3 + }, + "content_views": [ + { + "id": 12, + "cvv_id": 30, + "cvv_version": "2.0", + "label": "cv1", + "name": "cv1", + "composite": false, + "last_published": "2023-10-23 09:52:08 -0400", + "default": false, + "up_to_date": true, + "counts": { + "repositories": 2 + }, + "repositories": [ + { + "id": 171, + "name": "python-pulp", + "library_id": 40 + }, + { + "id": 170, + "name": "repo1", + "library_id": 1 + } + ] + }, + { + "id": 13, + "cvv_id": 29, + "cvv_version": "2.0", + "label": "cv2", + "name": "cv2", + "composite": false, + "last_published": "2023-10-23 09:48:16 -0400", + "default": false, + "up_to_date": true, + "counts": { + "repositories": 5 + }, + "repositories": [ + { + "id": 163, + "name": "python-pulp", + "library_id": 40 + }, + { + "id": 161, + "name": "repo1", + "library_id": 1 + }, + { + "id": 164, + "name": "deb_test", + "library_id": 72 + }, + { + "id": 160, + "name": "test_ansible", + "library_id": 3 + }, + { + "id": 162, + "name": "file_repo", + "library_id": 16 + } + ] + }, + { + "id": 14, + "cvv_id": 28, + "cvv_version": "1.0", + "label": "ccv1", + "name": "ccv1", + "composite": true, + "last_published": "2023-10-23 09:45:23 -0400", + "default": false, + "up_to_date": true, + "counts": { + "repositories": 5 + }, + "repositories": [ + { + "id": 146, + "name": "repo1", + "library_id": 1 + }, + { + "id": 147, + "name": "test_ansible", + "library_id": 3 + }, + { + "id": 149, + "name": "file_repo", + "library_id": 16 + }, + { + "id": 148, + "name": "deb_test", + "library_id": 72 + }, + { + "id": 145, + "name": "python-pulp", + "library_id": 40 + } + ] + } + ] + } + ], + "last_sync_words": "3 minutes", + "unsyncable_content_types": [], + "content_counts": { + "content_view_versions": { + "1": { + "repositories": { + "1": { + "counts": { + "rpm": 22, + "erratum": 7, + "rpm.modulemd": 14, + "package_group": 2, + "rpm.packagecategory": 1, + "rpm.distribution_tree": 1, + "rpm.modulemd_defaults": 3 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 1 + } + }, + "3": { + "counts": { + "ansible_collection": 10 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 3 + } + }, + "16": { + "counts": { + "file": 3 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 16 + } + }, + "20": { + "counts": { + "rpm": 71, + "erratum": 31, + "rpm.modulemd": 31, + "rpm.repo_metadata_file": 1 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 20 + } + }, + "40": { + "counts": { + "python_package": 275 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 40 + } + }, + "71": { + "counts": {}, + "metadata": { + "env_id": 1, + "library_instance_id": 71 + } + }, + "72": { + "counts": { + "deb": 6, + "deb.release": 2, + "deb.release_file": 2, + "deb.package_index": 5, + "deb.release_component": 2, + "deb.release_architecture": 5, + "deb.package_release_component": 6 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 72 + } + } + } + }, + "26": { + "repositories": { + "133": { + "counts": { + "rpm": 22, + "erratum": 7, + "rpm.modulemd": 14, + "package_group": 2, + "rpm.packagecategory": 1, + "rpm.distribution_tree": 1, + "rpm.modulemd_defaults": 3 + }, + "metadata": { + "env_id": 2, + "library_instance_id": 1 + } + }, + "134": { + "counts": { + "python_package": 275 + }, + "metadata": { + "env_id": 2, + "library_instance_id": 40 + } + } + } + }, + "28": { + "repositories": { + "150": { + "counts": { + "python_package": 275 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 40 + } + }, + "151": { + "counts": { + "rpm": 22, + "erratum": 7, + "rpm.modulemd": 14, + "package_group": 2, + "rpm.packagecategory": 1, + "rpm.distribution_tree": 1, + "rpm.modulemd_defaults": 3 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 1 + } + }, + "152": { + "counts": { + "ansible_collection": 10 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 3 + } + }, + "153": { + "counts": { + "deb": 6, + "deb.release": 2, + "deb.release_file": 2, + "deb.package_index": 5, + "deb.release_component": 2, + "deb.release_architecture": 5, + "deb.package_release_component": 6 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 72 + } + }, + "154": { + "counts": { + "file": 3 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 16 + } + }, + "155": { + "counts": { + "python_package": 275 + }, + "metadata": { + "env_id": 4, + "library_instance_id": 40 + } + }, + "156": { + "counts": { + "rpm": 22, + "erratum": 7, + "rpm.modulemd": 14, + "package_group": 2, + "rpm.packagecategory": 1, + "rpm.distribution_tree": 1, + "rpm.modulemd_defaults": 3 + }, + "metadata": { + "env_id": 4, + "library_instance_id": 1 + } + }, + "157": { + "counts": { + "ansible_collection": 10 + }, + "metadata": { + "env_id": 4, + "library_instance_id": 3 + } + }, + "158": { + "counts": { + "deb": 6, + "deb.release": 2, + "deb.release_file": 2, + "deb.package_index": 5, + "deb.release_component": 2, + "deb.release_architecture": 5, + "deb.package_release_component": 6 + }, + "metadata": { + "env_id": 4, + "library_instance_id": 72 + } + }, + "159": { + "counts": { + "file": 3 + }, + "metadata": { + "env_id": 4, + "library_instance_id": 16 + } + } + } + }, + "29": { + "repositories": { + "140": { + "counts": { + "rpm": 22, + "erratum": 7, + "rpm.modulemd": 14, + "package_group": 2, + "rpm.packagecategory": 1, + "rpm.distribution_tree": 1, + "rpm.modulemd_defaults": 3 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 1 + } + }, + "141": { + "counts": { + "ansible_collection": 10 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 3 + } + }, + "142": { + "counts": { + "file": 3 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 16 + } + }, + "143": { + "counts": { + "python_package": 275 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 40 + } + }, + "144": { + "counts": { + "deb": 6, + "deb.release": 2, + "deb.release_file": 2, + "deb.package_index": 5, + "deb.release_component": 2, + "deb.release_architecture": 5, + "deb.package_release_component": 6 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 72 + } + }, + "165": { + "counts": { + "ansible_collection": 10 + }, + "metadata": { + "env_id": 4, + "library_instance_id": 3 + } + }, + "166": { + "counts": { + "rpm": 22, + "erratum": 7, + "rpm.modulemd": 14, + "package_group": 2, + "rpm.packagecategory": 1, + "rpm.distribution_tree": 1, + "rpm.modulemd_defaults": 3 + }, + "metadata": { + "env_id": 4, + "library_instance_id": 1 + } + }, + "167": { + "counts": { + "file": 3 + }, + "metadata": { + "env_id": 4, + "library_instance_id": 16 + } + }, + "168": { + "counts": { + "python_package": 275 + }, + "metadata": { + "env_id": 4, + "library_instance_id": 40 + } + }, + "169": { + "counts": { + "deb": 6, + "deb.release": 2, + "deb.release_file": 2, + "deb.package_index": 5, + "deb.release_component": 2, + "deb.release_architecture": 5, + "deb.package_release_component": 6 + }, + "metadata": { + "env_id": 4, + "library_instance_id": 72 + } + } + } + }, + "30": { + "repositories": { + "131": { + "counts": { + "rpm": 14, + "erratum": 6, + "rpm.modulemd": 14, + "rpm.distribution_tree": 1, + "rpm.modulemd_defaults": 3 + }, + "metadata": { + "env_id": 1, + "library_instance_id": 1 + } + }, + "132": { + "counts": {}, + "metadata": { + "env_id": 1, + "library_instance_id": 40 + } + }, + "172": { + "counts": { + "rpm": 14, + "erratum": 6, + "rpm.modulemd": 14, + "rpm.distribution_tree": 1, + "rpm.modulemd_defaults": 3 + }, + "metadata": { + "env_id": 4, + "library_instance_id": 1 + } + }, + "173": { + "counts": {}, + "metadata": { + "env_id": 4, + "library_instance_id": 40 + } + } + } + } + } + } +} \ No newline at end of file diff --git a/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js b/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js index 785f9c8936d..61b3d9ed82c 100644 --- a/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js +++ b/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js @@ -5,7 +5,7 @@ import { nockInstance, assertNockRequest } from '../../../test-utils/nockWrapper import api from '../../../services/api'; import SmartProxyExpandableTable from '../SmartProxyExpandableTable'; -const smartProxyContentData = require('./SmartProxyContent.fixtures.json'); +const smartProxyContentData = require('./SmartProxyContentTest.fixtures.json'); const smartProxyContentPath = api.getApiUrl('/capsules/1/content/sync');