diff --git a/src/api/collection.ts b/src/api/collection.ts index cccb5e65af..34fe33caa5 100644 --- a/src/api/collection.ts +++ b/src/api/collection.ts @@ -232,6 +232,12 @@ export class API extends HubAPI { `pulp/api/v3/content/ansible/collection_versions/`, ); } + + getDetail(distroBasePath, namespace, name) { + return this.http.get( + `v3/plugin/ansible/content/${distroBasePath}/collections/index/${namespace}/${name}/`, + ); + } } export const CollectionAPI = new API(); diff --git a/src/api/response-types/collection.ts b/src/api/response-types/collection.ts index df70785052..3dbe5096d7 100644 --- a/src/api/response-types/collection.ts +++ b/src/api/response-types/collection.ts @@ -222,6 +222,8 @@ export class CollectionDetailType { company: string; related_fields: { my_permissions?: string[] }; }; + + download_count: number; } export class CollectionUsedByDependencies extends CollectionDetailType { diff --git a/src/components/headers/collection-header.tsx b/src/components/headers/collection-header.tsx index 9a80dad77d..7415575449 100644 --- a/src/components/headers/collection-header.tsx +++ b/src/components/headers/collection-header.tsx @@ -21,6 +21,7 @@ import { Navigate } from 'react-router-dom'; import { CertificateUploadAPI, CollectionAPI, + CollectionDetailType, CollectionVersionAPI, CollectionVersionContentType, CollectionVersionSearch, @@ -37,6 +38,7 @@ import { Breadcrumbs, CopyCollectionToRepositoryModal, DeleteCollectionModal, + DownloadCount, ImportModal, LinkTabs, Logo, @@ -68,6 +70,7 @@ interface IProps { collections: CollectionVersionSearch[]; collectionsCount: number; collection: CollectionVersionSearch; + actuallyCollection: CollectionDetailType; content: CollectionVersionContentType; params: { version?: string; @@ -164,15 +167,16 @@ export class CollectionHeader extends React.Component { render() { const { + activeTab, + actuallyCollection, + breadcrumbs, + className, + collection, collections, collectionsCount, - collection, content, params, updateParams, - breadcrumbs, - activeTab, - className, } = this.props; const { @@ -545,20 +549,28 @@ export class CollectionHeader extends React.Component { } pageControls={ - - {DEPLOYMENT_MODE === Constants.INSIGHTS_DEPLOYMENT_MODE ? ( - - - {t`Create issue`} - {' '} - - - ) : null} - {dropdownItems.length > 0 ? ( - - - - ) : null} + + + {DEPLOYMENT_MODE === Constants.INSIGHTS_DEPLOYMENT_MODE ? ( + + + {t`Create issue`} + {' '} + + + ) : null} + {dropdownItems.length > 0 ? ( + + + + ) : null} + + + + } > diff --git a/src/components/shared/download-count.tsx b/src/components/shared/download-count.tsx index f33d44d1f0..1b1f537415 100644 --- a/src/components/shared/download-count.tsx +++ b/src/components/shared/download-count.tsx @@ -1,13 +1,18 @@ -import { Trans } from '@lingui/macro'; +import { Trans, t } from '@lingui/macro'; import { DownloadIcon } from '@patternfly/react-icons'; import React from 'react'; +import { Tooltip } from 'src/components'; +import { Constants } from 'src/constants'; import { language } from 'src/l10n'; interface IProps { item?: { download_count?: number }; } -export const DownloadCount = ({ item }) => { +export const DownloadCount = ({ item }: IProps) => { + if (DEPLOYMENT_MODE === Constants.INSIGHTS_DEPLOYMENT_MODE) { + return null; + } if (!item?.download_count) { return null; } @@ -17,8 +22,10 @@ export const DownloadCount = ({ item }) => { ); return ( - <> + {downloadCount} Downloads - + ); }; diff --git a/src/containers/collection-detail/base.ts b/src/containers/collection-detail/base.ts index 412d1d5b35..a5a8dd243f 100644 --- a/src/containers/collection-detail/base.ts +++ b/src/containers/collection-detail/base.ts @@ -1,5 +1,6 @@ import { CollectionAPI, + CollectionDetailType, CollectionVersionAPI, CollectionVersionContentType, CollectionVersionSearch, @@ -8,17 +9,18 @@ import { AlertType } from 'src/components'; import { Paths, formatPath } from 'src/paths'; export interface IBaseCollectionState { + actuallyCollection?: CollectionDetailType; + alerts?: AlertType[]; + collection?: CollectionVersionSearch; + collections?: CollectionVersionSearch[]; + collectionsCount?: number; + content?: CollectionVersionContentType; + distroBasePath?: string; params: { version?: string; showing?: string; keywords?: string; }; - collections?: CollectionVersionSearch[]; - collectionsCount?: number; - collection?: CollectionVersionSearch; - content?: CollectionVersionContentType; - alerts?: AlertType[]; - distroBasePath?: string; } // Caches the collection data when matching, prevents redundant fetches between collection detail tabs @@ -28,9 +30,10 @@ const cache = { name: null, version: null, + actuallyCollection: null, + collection: null, collections: [], collectionsCount: 0, - collection: null, content: null, }; @@ -57,6 +60,7 @@ export function loadCollection({ cache.collection, cache.content, cache.collectionsCount, + cache.actuallyCollection, ); return; } @@ -94,7 +98,19 @@ export function loadCollection({ .then(({ data }) => data) .catch(() => ({ data: [], meta: { count: 0 } })); - return Promise.all([versions, currentVersion, content]).then( + // FIXME: repo -> base_path + const actuallyCollection = CollectionAPI.getDetail( + repo, + namespace, + name, + ).then(({ data }) => data); + + return Promise.all([ + versions, + currentVersion, + content, + actuallyCollection, + ]).then( ([ { data: collections, @@ -102,17 +118,25 @@ export function loadCollection({ }, collection, content, + actuallyCollection, ]) => { - setCollection(collections, collection, content, collectionsCount); + setCollection( + collections, + collection, + content, + collectionsCount, + actuallyCollection, + ); cache.repository = repo; cache.namespace = namespace; cache.name = name; cache.version = version; + cache.actuallyCollection = actuallyCollection; + cache.collection = collection; cache.collections = collections; cache.collectionsCount = collectionsCount; - cache.collection = collection; cache.content = content; }, ); diff --git a/src/containers/collection-detail/collection-content.tsx b/src/containers/collection-detail/collection-content.tsx index b29c39c46d..c9e24de97a 100644 --- a/src/containers/collection-detail/collection-content.tsx +++ b/src/containers/collection-detail/collection-content.tsx @@ -23,11 +23,12 @@ class CollectionContent extends React.Component< const params = ParamHelper.parseParamString(props.location.search); this.state = { + actuallyCollection: null, + collection: null, collections: [], collectionsCount: 0, - collection: null, content: null, - params: params, + params, }; } @@ -36,8 +37,14 @@ class CollectionContent extends React.Component< } render() { - const { collections, collectionsCount, collection, params, content } = - this.state; + const { + actuallyCollection, + collection, + collections, + collectionsCount, + content, + params, + } = this.state; if (collections.length <= 0) { return ; @@ -67,17 +74,18 @@ class CollectionContent extends React.Component< return ( this.loadCollections(true)} + activeTab='contents' + actuallyCollection={actuallyCollection} + breadcrumbs={breadcrumbs} + collection={collection} collections={collections} collectionsCount={collectionsCount} - collection={collection} content={content} params={params} + reload={() => this.loadCollections(true)} updateParams={(params) => this.updateParams(params, () => this.loadCollections(true)) } - breadcrumbs={breadcrumbs} - activeTab='contents' />
@@ -98,8 +106,20 @@ class CollectionContent extends React.Component< forceReload, matchParams: this.props.routeParams, navigate: this.props.navigate, - setCollection: (collections, collection, content, collectionsCount) => - this.setState({ collections, collection, content, collectionsCount }), + setCollection: ( + collections, + collection, + content, + collectionsCount, + actuallyCollection, + ) => + this.setState({ + collections, + collection, + content, + collectionsCount, + actuallyCollection, + }), stateParams: this.state.params, }); } diff --git a/src/containers/collection-detail/collection-dependencies.tsx b/src/containers/collection-detail/collection-dependencies.tsx index 83f0cdcff6..0c851d003e 100644 --- a/src/containers/collection-detail/collection-dependencies.tsx +++ b/src/containers/collection-detail/collection-dependencies.tsx @@ -52,16 +52,17 @@ class CollectionDependencies extends React.Component { params['sort'] = !params['sort'] ? '-collection' : 'collection'; this.state = { + actuallyCollection: null, + alerts: [], + collection: null, collections: [], collectionsCount: 0, - collection: null, content: null, dependencies_repos: [], - params: params, + params, usedByDependencies: [], usedByDependenciesCount: 0, usedByDependenciesLoading: true, - alerts: [], }; } @@ -71,15 +72,16 @@ class CollectionDependencies extends React.Component { render() { const { + actuallyCollection, + alerts, + collection, collections, collectionsCount, - collection, content, params, usedByDependencies, usedByDependenciesCount, usedByDependenciesLoading, - alerts, } = this.state; if (collections.length <= 0) { @@ -117,20 +119,21 @@ class CollectionDependencies extends React.Component { this.closeAlert(i)} /> this.loadData(true)} + activeTab='dependencies' + actuallyCollection={actuallyCollection} + breadcrumbs={breadcrumbs} + collection={collection} collections={collections} collectionsCount={collectionsCount} - collection={collection} content={content} params={headerParams} + reload={() => this.loadData(true)} + repo={repository.name} updateParams={(p) => { this.updateParams(this.combineParams(this.state.params, p), () => this.loadData(true), ); }} - breadcrumbs={breadcrumbs} - activeTab='dependencies' - repo={repository.name} />
@@ -291,9 +294,21 @@ class CollectionDependencies extends React.Component { forceReload, matchParams: this.props.routeParams, navigate: this.props.navigate, - setCollection: (collections, collection, content, collectionsCount) => + setCollection: ( + collections, + collection, + content, + collectionsCount, + actuallyCollection, + ) => this.setState( - { collections, collection, content, collectionsCount }, + { + collections, + collection, + content, + collectionsCount, + actuallyCollection, + }, callback, ), stateParams: this.state.params.version diff --git a/src/containers/collection-detail/collection-detail.tsx b/src/containers/collection-detail/collection-detail.tsx index f787834ecf..31f68522f7 100644 --- a/src/containers/collection-detail/collection-detail.tsx +++ b/src/containers/collection-detail/collection-detail.tsx @@ -25,13 +25,14 @@ class CollectionDetail extends React.Component< const params = ParamHelper.parseParamString(props.location.search); this.state = { + actuallyCollection: null, + alerts: [], + collection: null, collections: [], collectionsCount: 0, - collection: null, content: null, distroBasePath: null, - params: params, - alerts: [], + params, }; } @@ -47,12 +48,13 @@ class CollectionDetail extends React.Component< render() { const { + actuallyCollection, + alerts, + collection, collections, collectionsCount, - collection, content, params, - alerts, } = this.state; if (collections.length <= 0) { @@ -78,18 +80,19 @@ class CollectionDetail extends React.Component< this.closeAlert(i)} /> this.loadCollections(true)} + activeTab='install' + actuallyCollection={actuallyCollection} + breadcrumbs={breadcrumbs} + collection={collection} collections={collections} collectionsCount={collectionsCount} - collection={collection} content={content} params={params} + reload={() => this.loadCollections(true)} + repo={this.props.routeParams.repo} updateParams={(p) => this.updateParams(p, () => this.loadCollections(true)) } - breadcrumbs={breadcrumbs} - activeTab='install' - repo={this.props.routeParams.repo} />
@@ -122,12 +125,19 @@ class CollectionDetail extends React.Component< forceReload, matchParams: this.props.routeParams, navigate: this.props.navigate, - setCollection: (collections, collection, content, collectionsCount) => + setCollection: ( + collections, + collection, + content, + collectionsCount, + actuallyCollection, + ) => this.setState({ collections, collection, content, collectionsCount, + actuallyCollection, }), stateParams: this.state.params, }); diff --git a/src/containers/collection-detail/collection-distributions.tsx b/src/containers/collection-detail/collection-distributions.tsx index bd7e1d19cb..8e8520c94a 100644 --- a/src/containers/collection-detail/collection-distributions.tsx +++ b/src/containers/collection-detail/collection-distributions.tsx @@ -29,16 +29,15 @@ import { loadCollection } from './base'; const CollectionDistributions = (props: RouteProps) => { const routeParams = ParamHelper.parseParamString(props.location.search); + const [actuallyCollection, setActuallyCollection] = useState(null); + const [collection, setCollection] = useState(null); const [collections, setCollections] = useState([]); const [collectionsCount, setCollectionsCount] = useState(0); - const [collection, setCollection] = useState(null); const [content, setContent] = useState(null); - const [inputText, setInputText] = useState(''); - - const [distributions, setDistributions] = useState(null); const [count, setCount] = useState(0); + const [distributions, setDistributions] = useState(null); + const [inputText, setInputText] = useState(''); const [loading, setLoading] = useState(true); - const [params, setParams] = useState( Object.keys(routeParams).length ? routeParams @@ -46,15 +45,23 @@ const CollectionDistributions = (props: RouteProps) => { sort: '-pulp_created', }, ); + const loadCollections = (forceReload) => { loadCollection({ forceReload, matchParams: props.routeParams, navigate: props.navigate, - setCollection: (collections, collection, content, collectionsCount) => { + setCollection: ( + collections, + collection, + content, + collectionsCount, + actuallyCollection, + ) => { + setActuallyCollection(actuallyCollection); + setCollection(collection); setCollections(collections); setCollectionsCount(collectionsCount); - setCollection(collection); setContent(content); loadDistributions(collection.repository.pulp_href); @@ -201,19 +208,20 @@ const CollectionDistributions = (props: RouteProps) => { return ( loadCollections(true)} + activeTab='distributions' + actuallyCollection={actuallyCollection} + breadcrumbs={breadcrumbs} + collection={collection} collections={collections} collectionsCount={collectionsCount} - collection={collection} content={content} params={params} + reload={() => loadCollections(true)} updateParams={(params) => { updateParamsMixin( ParamHelper.setParam(params, 'version', params.version), ); }} - breadcrumbs={breadcrumbs} - activeTab='distributions' />
diff --git a/src/containers/collection-detail/collection-docs.tsx b/src/containers/collection-detail/collection-docs.tsx index 6fb36e6dc0..549e0bc113 100644 --- a/src/containers/collection-detail/collection-docs.tsx +++ b/src/containers/collection-detail/collection-docs.tsx @@ -33,11 +33,12 @@ class CollectionDocs extends React.Component { const params = ParamHelper.parseParamString(props.location.search); this.state = { + actuallyCollection: null, + collection: null, collections: [], collectionsCount: 0, - collection: null, content: null, - params: params, + params, }; this.docsRef = React.createRef(); this.searchBarRef = React.createRef(); @@ -48,8 +49,14 @@ class CollectionDocs extends React.Component { } render() { - const { params, collection, collections, collectionsCount, content } = - this.state; + const { + actuallyCollection, + collection, + collections, + collectionsCount, + content, + params, + } = this.state; const urlFields = this.props.routeParams; if (!collection || !content) { @@ -117,30 +124,22 @@ class CollectionDocs extends React.Component { { name: t`Documentation` }, ]; - // scroll to top of page - - // if ( - // this.docsRef.current && - // this.searchBarRef.current !== window.document.activeElement - // ) { - // this.docsRef.current.scrollIntoView(); - // } - return ( this.loadCollection(true)} + activeTab='documentation' + actuallyCollection={actuallyCollection} + breadcrumbs={breadcrumbs} + className='header' + collection={collection} collections={collections} collectionsCount={collectionsCount} - collection={collection} content={content} params={params} + reload={() => this.loadCollection(true)} updateParams={(p) => this.updateParams(p, () => this.loadCollection(true)) } - breadcrumbs={breadcrumbs} - activeTab='documentation' - className='header' />
@@ -305,8 +304,20 @@ class CollectionDocs extends React.Component { forceReload, matchParams: this.props.routeParams, navigate: this.props.navigate, - setCollection: (collections, collection, content, collectionsCount) => - this.setState({ collections, collection, content, collectionsCount }), + setCollection: ( + collections, + collection, + content, + collectionsCount, + actuallyCollection, + ) => + this.setState({ + collections, + collection, + content, + collectionsCount, + actuallyCollection, + }), stateParams: this.state.params, }); } diff --git a/src/containers/collection-detail/collection-import-log.tsx b/src/containers/collection-detail/collection-import-log.tsx index 0a9abe8ae6..5a81fa990f 100644 --- a/src/containers/collection-detail/collection-import-log.tsx +++ b/src/containers/collection-detail/collection-import-log.tsx @@ -27,15 +27,16 @@ class CollectionImportLog extends React.Component { const params = ParamHelper.parseParamString(props.location.search); this.state = { + actuallyCollection: null, + apiError: undefined, collection: null, collections: [], collectionsCount: 0, content: null, - params: params, loadingImports: true, - selectedImportDetail: undefined, + params, selectedImport: undefined, - apiError: undefined, + selectedImportDetail: undefined, }; } @@ -45,15 +46,16 @@ class CollectionImportLog extends React.Component { render() { const { + actuallyCollection, + apiError, collection, collections, collectionsCount, - params, + content, loadingImports, - selectedImportDetail, + params, selectedImport, - apiError, - content, + selectedImportDetail, } = this.state; if (!collection) { @@ -84,17 +86,18 @@ class CollectionImportLog extends React.Component { return ( this.loadData(true)} + activeTab='import-log' + actuallyCollection={actuallyCollection} + breadcrumbs={breadcrumbs} + collection={collection} collections={collections} collectionsCount={collectionsCount} - collection={collection} content={content} params={params} + reload={() => this.loadData(true)} updateParams={(params) => this.updateParams(params, () => this.loadData(true)) } - breadcrumbs={breadcrumbs} - activeTab='import-log' />
@@ -157,9 +160,21 @@ class CollectionImportLog extends React.Component { forceReload, matchParams: this.props.routeParams, navigate: this.props.navigate, - setCollection: (collections, collection, content, collectionsCount) => + setCollection: ( + collections, + collection, + content, + collectionsCount, + actuallyCollection, + ) => this.setState( - { collections, collection, content, collectionsCount }, + { + collections, + collection, + content, + collectionsCount, + actuallyCollection, + }, callback, ), stateParams: this.state.params,