From d19163660ffe71d5098ade327e3844a24c45dc7b Mon Sep 17 00:00:00 2001 From: Shivanand Sonnad Date: Fri, 7 Mar 2025 06:33:23 +0000 Subject: [PATCH] feat: [AH-547]: support actions at version level (#3516) * feat: [AH-547]: support actions at version level --- web/src/ar/frameworks/Version/Version.tsx | 14 ++++ .../Version/VersionActionsWidget.tsx | 40 +++++++++++ .../ArtifactListTable/ArtifactListTable.tsx | 6 ++ .../ArtifactListTableCell.tsx | 17 ++++- .../DockerVersion/DockerVersionHeader.tsx | 11 ++- .../DockerVersion/DockerVersionType.tsx | 6 ++ .../GenericVersion/GenericVersionType.tsx | 9 ++- .../HelmVersion/HelmVersionType.tsx | 9 ++- .../MavenVersion/MavenVersion.tsx | 11 ++- .../NpmVersion/NpmVersionType.tsx | 11 ++- .../VersionActions/DeleteVersionMenuItem.tsx | 72 +++++++++++++++++++ .../VersionActions/SetupClientMenuItem.tsx | 56 +++++++++++++++ .../VersionActions/VersionActions.tsx | 63 ++++++++++++++++ .../components/VersionActions/types.ts | 28 ++++++++ .../VersionDetailsHeaderContent.tsx | 11 ++- .../hooks/useDeleteVersionModal.tsx | 69 ++++++++++++++++++ .../version-details/strings/strings.en.yaml | 4 ++ .../DockerVersionListTable.module.scss | 4 +- .../DockerVersionListTable.tsx | 7 ++ .../VersionListTable/VersionListCell.tsx | 19 ++++- .../components/VersionListTable/constants.tsx | 6 ++ .../components/VersionListTable/types.ts | 6 +- .../components/VersionListTable/utils.ts | 2 +- .../version-list/strings/strings.en.yaml | 4 +- web/src/ar/strings/types.ts | 6 +- 25 files changed, 469 insertions(+), 22 deletions(-) create mode 100644 web/src/ar/frameworks/Version/VersionActionsWidget.tsx create mode 100644 web/src/ar/pages/version-details/components/VersionActions/DeleteVersionMenuItem.tsx create mode 100644 web/src/ar/pages/version-details/components/VersionActions/SetupClientMenuItem.tsx create mode 100644 web/src/ar/pages/version-details/components/VersionActions/VersionActions.tsx create mode 100644 web/src/ar/pages/version-details/components/VersionActions/types.ts create mode 100644 web/src/ar/pages/version-details/hooks/useDeleteVersionModal.tsx diff --git a/web/src/ar/frameworks/Version/Version.tsx b/web/src/ar/frameworks/Version/Version.tsx index be8743e30..45ada7687 100644 --- a/web/src/ar/frameworks/Version/Version.tsx +++ b/web/src/ar/frameworks/Version/Version.tsx @@ -17,6 +17,8 @@ import type { PaginationProps } from '@harnessio/uicore' import type { ArtifactSummary, + ArtifactVersionMetadata, + ArtifactVersionSummary, ListArtifactVersion, RegistryArtifactMetadata } from '@harnessio/react-har-service-client' @@ -52,6 +54,16 @@ export interface ArtifactActionProps { onClose?: () => void } +export interface VersionActionProps { + data: ArtifactVersionMetadata | ArtifactVersionSummary + pageType: PageType + repoKey: string + artifactKey: string + versionKey: string + readonly?: boolean + onClose?: () => void +} + export abstract class VersionStep { protected abstract packageType: RepositoryPackageType protected abstract allowedVersionDetailsTabs: VersionDetailsTab[] @@ -71,4 +83,6 @@ export abstract class VersionStep { abstract renderVersionDetailsTab(props: VersionDetailsTabProps): JSX.Element abstract renderArtifactActions(props: ArtifactActionProps): JSX.Element + + abstract renderVersionActions(props: VersionActionProps): JSX.Element } diff --git a/web/src/ar/frameworks/Version/VersionActionsWidget.tsx b/web/src/ar/frameworks/Version/VersionActionsWidget.tsx new file mode 100644 index 000000000..ab4b32f04 --- /dev/null +++ b/web/src/ar/frameworks/Version/VersionActionsWidget.tsx @@ -0,0 +1,40 @@ +/* + * Copyright 2024 Harness, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react' +import { Text } from '@harnessio/uicore' + +import { useStrings } from '@ar/frameworks/strings' +import type { RepositoryPackageType } from '@ar/common/types' + +import versionFactory from './VersionFactory' +import type { VersionActionProps } from './Version' +import type { VersionAbstractFactory } from './VersionAbstractFactory' + +interface VersionActionsWidgetProps extends VersionActionProps { + factory?: VersionAbstractFactory + packageType: RepositoryPackageType +} + +export default function VersionActionsWidget(props: VersionActionsWidgetProps): JSX.Element { + const { factory = versionFactory, packageType, ...rest } = props + const { getString } = useStrings() + const repositoryType = factory?.getVersionType(packageType) + if (!repositoryType) { + return {getString('stepNotFound')} + } + return repositoryType.renderVersionActions({ ...rest }) +} diff --git a/web/src/ar/pages/artifact-list/components/ArtifactListTable/ArtifactListTable.tsx b/web/src/ar/pages/artifact-list/components/ArtifactListTable/ArtifactListTable.tsx index acb7dc48c..1ba8fb29e 100644 --- a/web/src/ar/pages/artifact-list/components/ArtifactListTable/ArtifactListTable.tsx +++ b/web/src/ar/pages/artifact-list/components/ArtifactListTable/ArtifactListTable.tsx @@ -107,6 +107,12 @@ export default function ArtifactListTable(props: ArtifactListTableProps): JSX.El accessor: 'lastUpdated', Cell: LatestArtifactCell, serverSortProps: getServerSortProps('lastUpdated') + }, + { + Header: '', + accessor: 'actions', + Cell: LatestArtifactCell, + disableSortBy: true } ].filter(Boolean) as unknown as Column[] }, [currentOrder, currentSort, getString]) diff --git a/web/src/ar/pages/artifact-list/components/ArtifactListTable/ArtifactListTableCell.tsx b/web/src/ar/pages/artifact-list/components/ArtifactListTable/ArtifactListTableCell.tsx index 9f1050432..6f7e8fa22 100644 --- a/web/src/ar/pages/artifact-list/components/ArtifactListTable/ArtifactListTableCell.tsx +++ b/web/src/ar/pages/artifact-list/components/ArtifactListTable/ArtifactListTableCell.tsx @@ -25,11 +25,12 @@ import type { ArtifactMetadata, StoDigestMetadata } from '@harnessio/react-har-s import { useParentComponents, useRoutes } from '@ar/hooks' import TableCells from '@ar/components/TableCells/TableCells' -import { RepositoryPackageType } from '@ar/common/types' +import { PageType, RepositoryPackageType } from '@ar/common/types' import LabelsPopover from '@ar/components/LabelsPopover/LabelsPopover' import RepositoryIcon from '@ar/frameworks/RepositoryStep/RepositoryIcon' import { useStrings } from '@ar/frameworks/strings' import { getShortDigest } from '@ar/pages/digest-list/utils' +import VersionActionsWidget from '@ar/frameworks/Version/VersionActionsWidget' import { VersionDetailsTab } from '@ar/pages/version-details/components/VersionDetailsTabs/constants' import css from './ArtifactListTable.module.scss' @@ -217,3 +218,17 @@ export const LatestArtifactCell: CellType = ({ row }) => { const { original } = row return } + +export const ArtifactVersionActions: CellType = ({ row }) => { + const { original } = row + return ( + + ) +} diff --git a/web/src/ar/pages/version-details/DockerVersion/DockerVersionHeader.tsx b/web/src/ar/pages/version-details/DockerVersion/DockerVersionHeader.tsx index 5eb09c9f3..eac373301 100644 --- a/web/src/ar/pages/version-details/DockerVersion/DockerVersionHeader.tsx +++ b/web/src/ar/pages/version-details/DockerVersion/DockerVersionHeader.tsx @@ -20,10 +20,11 @@ import { useHistory } from 'react-router-dom' import { Layout } from '@harnessio/uicore' import type { ArtifactVersionSummary } from '@harnessio/react-har-service-client' -import type { RepositoryPackageType } from '@ar/common/types' +import { PageType, RepositoryPackageType } from '@ar/common/types' import type { VersionDetailsPathParams } from '@ar/routes/types' import { useDecodedParams, useParentHooks, useRoutes } from '@ar/hooks' import RepositoryIcon from '@ar/frameworks/RepositoryStep/RepositoryIcon' +import VersionActionsWidget from '@ar/frameworks/Version/VersionActionsWidget' import SetupClientButton from '@ar/components/SetupClientButton/SetupClientButton' import DockerVersionName from './components/DockerVersionName/DockerVersionName' @@ -78,6 +79,14 @@ export default function DockerVersionHeader(props: DockerVersionHeaderProps): JS versionIdentifier={pathParams.versionIdentifier} packageType={packageType as RepositoryPackageType} /> + ) } diff --git a/web/src/ar/pages/version-details/DockerVersion/DockerVersionType.tsx b/web/src/ar/pages/version-details/DockerVersion/DockerVersionType.tsx index d92b116f9..410f98412 100644 --- a/web/src/ar/pages/version-details/DockerVersion/DockerVersionType.tsx +++ b/web/src/ar/pages/version-details/DockerVersion/DockerVersionType.tsx @@ -23,6 +23,7 @@ import ArtifactActions from '@ar/pages/artifact-details/components/ArtifactActio import DockerVersionListTable from '@ar/pages/version-list/DockerVersion/VersionListTable/DockerVersionListTable' import { type ArtifactActionProps, + type VersionActionProps, type VersionDetailsHeaderProps, type VersionDetailsTabProps, type VersionListTableProps, @@ -37,6 +38,7 @@ import { VersionDetailsTab } from '../components/VersionDetailsTabs/constants' import DockerArtifactSecurityTestsContent from './DockerArtifactSecurityTestsContent' import DockerVersionOSSContent from './DockerVersionOSSContent/DockerVersionOSSContent' import DockerDeploymentsContent from './DockerDeploymentsContent/DockerDeploymentsContent' +import VersionActions from '../components/VersionActions/VersionActions' export class DockerVersionType extends VersionStep { protected packageType = RepositoryPackageType.DOCKER @@ -78,4 +80,8 @@ export class DockerVersionType extends VersionStep { renderArtifactActions(props: ArtifactActionProps): JSX.Element { return } + + renderVersionActions(props: VersionActionProps): JSX.Element { + return + } } diff --git a/web/src/ar/pages/version-details/GenericVersion/GenericVersionType.tsx b/web/src/ar/pages/version-details/GenericVersion/GenericVersionType.tsx index 728d8b0a4..a9d4b8443 100644 --- a/web/src/ar/pages/version-details/GenericVersion/GenericVersionType.tsx +++ b/web/src/ar/pages/version-details/GenericVersion/GenericVersionType.tsx @@ -18,6 +18,7 @@ import React from 'react' import type { ArtifactVersionSummary } from '@harnessio/react-har-service-client' import { type ArtifactActionProps, + type VersionActionProps, type VersionDetailsHeaderProps, type VersionDetailsTabProps, type VersionListTableProps, @@ -33,6 +34,7 @@ import ArtifactActions from '@ar/pages/artifact-details/components/ArtifactActio import { VersionDetailsTab } from '../components/VersionDetailsTabs/constants' import GenericOverviewPage from './pages/overview/OverviewPage' import OSSContentPage from './pages/oss-details/OSSContentPage' +import VersionActions from '../components/VersionActions/VersionActions' import GenericArtifactDetailsPage from './pages/artifact-details/GenericArtifactDetailsPage' import VersionDetailsHeaderContent from '../components/VersionDetailsHeaderContent/VersionDetailsHeaderContent' @@ -48,7 +50,8 @@ export class GenericVersionType extends VersionStep { [VersionListColumnEnum.Name]: { width: '100%' }, [VersionListColumnEnum.Size]: { width: '100%' }, [VersionListColumnEnum.FileCount]: { width: '100%' }, - [VersionListColumnEnum.LastModified]: { width: '100%' } + [VersionListColumnEnum.LastModified]: { width: '100%' }, + [VersionListColumnEnum.Actions]: { width: '10%' } } renderVersionListTable(props: VersionListTableProps): JSX.Element { @@ -75,4 +78,8 @@ export class GenericVersionType extends VersionStep { renderArtifactActions(props: ArtifactActionProps): JSX.Element { return } + + renderVersionActions(props: VersionActionProps): JSX.Element { + return + } } diff --git a/web/src/ar/pages/version-details/HelmVersion/HelmVersionType.tsx b/web/src/ar/pages/version-details/HelmVersion/HelmVersionType.tsx index 07ba9f233..d30b50ca7 100644 --- a/web/src/ar/pages/version-details/HelmVersion/HelmVersionType.tsx +++ b/web/src/ar/pages/version-details/HelmVersion/HelmVersionType.tsx @@ -26,6 +26,7 @@ import VersionListTable, { import ArtifactActions from '@ar/pages/artifact-details/components/ArtifactActions/ArtifactActions' import { type ArtifactActionProps, + type VersionActionProps, type VersionDetailsHeaderProps, type VersionDetailsTabProps, type VersionListTableProps, @@ -34,6 +35,7 @@ import { import { VersionDetailsTab } from '../components/VersionDetailsTabs/constants' import HelmVersionOverviewContent from './HelmVersionOverviewContent' import HelmArtifactDetailsContent from './HelmArtifactDetailsContent' +import VersionActions from '../components/VersionActions/VersionActions' import HelmVersionOSSContent from './HelmVersionOSSContent/HelmVersionOSSContent' import VersionDetailsHeaderContent from '../components/VersionDetailsHeaderContent/VersionDetailsHeaderContent' @@ -49,7 +51,8 @@ export class HelmVersionType extends VersionStep { [VersionListColumnEnum.Size]: { width: '100%' }, [VersionListColumnEnum.DownloadCount]: { width: '100%' }, [VersionListColumnEnum.LastModified]: { width: '100%' }, - [VersionListColumnEnum.PullCommand]: { width: '100%' } + [VersionListColumnEnum.PullCommand]: { width: '100%' }, + [VersionListColumnEnum.Actions]: { width: '10%' } } renderVersionListTable(props: VersionListTableProps): JSX.Element { @@ -76,4 +79,8 @@ export class HelmVersionType extends VersionStep { renderArtifactActions(props: ArtifactActionProps): JSX.Element { return } + + renderVersionActions(props: VersionActionProps): JSX.Element { + return + } } diff --git a/web/src/ar/pages/version-details/MavenVersion/MavenVersion.tsx b/web/src/ar/pages/version-details/MavenVersion/MavenVersion.tsx index 531761230..b688f9a68 100644 --- a/web/src/ar/pages/version-details/MavenVersion/MavenVersion.tsx +++ b/web/src/ar/pages/version-details/MavenVersion/MavenVersion.tsx @@ -26,17 +26,19 @@ import VersionListTable, { } from '@ar/pages/version-list/components/VersionListTable/VersionListTable' import { type ArtifactActionProps, + type VersionActionProps, type VersionDetailsHeaderProps, type VersionDetailsTabProps, type VersionListTableProps, VersionStep } from '@ar/frameworks/Version/Version' +import OSSContentPage from './pages/oss-details/OSSContentPage' +import VersionActions from '../components/VersionActions/VersionActions' import { VersionDetailsTab } from '../components/VersionDetailsTabs/constants' import MavenArtifactOverviewPage from './pages/overview/MavenArtifactOverviewPage' import MavenArtifactDetailsPage from './pages/artifact-details/MavenArtifactDetailsPage' import VersionDetailsHeaderContent from '../components/VersionDetailsHeaderContent/VersionDetailsHeaderContent' -import OSSContentPage from './pages/oss-details/OSSContentPage' export class MavenVersionType extends VersionStep { protected packageType = RepositoryPackageType.MAVEN @@ -50,7 +52,8 @@ export class MavenVersionType extends VersionStep { [VersionListColumnEnum.Name]: { width: '100%' }, [VersionListColumnEnum.Size]: { width: '100%' }, [VersionListColumnEnum.FileCount]: { width: '100%' }, - [VersionListColumnEnum.LastModified]: { width: '100%' } + [VersionListColumnEnum.LastModified]: { width: '100%' }, + [VersionListColumnEnum.Actions]: { width: '10%' } } renderVersionListTable(props: VersionListTableProps): JSX.Element { @@ -77,4 +80,8 @@ export class MavenVersionType extends VersionStep { renderArtifactActions(props: ArtifactActionProps): JSX.Element { return } + + renderVersionActions(props: VersionActionProps): JSX.Element { + return + } } diff --git a/web/src/ar/pages/version-details/NpmVersion/NpmVersionType.tsx b/web/src/ar/pages/version-details/NpmVersion/NpmVersionType.tsx index 7890fd315..a00bf4927 100644 --- a/web/src/ar/pages/version-details/NpmVersion/NpmVersionType.tsx +++ b/web/src/ar/pages/version-details/NpmVersion/NpmVersionType.tsx @@ -27,16 +27,18 @@ import VersionListTable, { } from '@ar/pages/version-list/components/VersionListTable/VersionListTable' import { type ArtifactActionProps, + type VersionActionProps, type VersionDetailsHeaderProps, type VersionDetailsTabProps, type VersionListTableProps, VersionStep } from '@ar/frameworks/Version/Version' +import VersionActions from '../components/VersionActions/VersionActions' import NpmVersionOverviewPage from './pages/overview/NpmVersionOverviewPage' import { VersionDetailsTab } from '../components/VersionDetailsTabs/constants' -import VersionDetailsHeaderContent from '../components/VersionDetailsHeaderContent/VersionDetailsHeaderContent' import NpmVersionArtifactDetailsPage from './pages/artifact-dertails/NpmVersionArtifactDetailsPage' +import VersionDetailsHeaderContent from '../components/VersionDetailsHeaderContent/VersionDetailsHeaderContent' export class NpmVersionType extends VersionStep { protected packageType = RepositoryPackageType.NPM @@ -51,7 +53,8 @@ export class NpmVersionType extends VersionStep { [VersionListColumnEnum.Size]: { width: '100%' }, [VersionListColumnEnum.DownloadCount]: { width: '100%' }, [VersionListColumnEnum.PullCommand]: { width: '100%' }, - [VersionListColumnEnum.LastModified]: { width: '100%' } + [VersionListColumnEnum.LastModified]: { width: '100%' }, + [VersionListColumnEnum.Actions]: { width: '10%' } } renderVersionListTable(props: VersionListTableProps): JSX.Element { @@ -83,4 +86,8 @@ export class NpmVersionType extends VersionStep { renderArtifactActions(props: ArtifactActionProps): JSX.Element { return } + + renderVersionActions(props: VersionActionProps): JSX.Element { + return + } } diff --git a/web/src/ar/pages/version-details/components/VersionActions/DeleteVersionMenuItem.tsx b/web/src/ar/pages/version-details/components/VersionActions/DeleteVersionMenuItem.tsx new file mode 100644 index 000000000..c1a4fd9e4 --- /dev/null +++ b/web/src/ar/pages/version-details/components/VersionActions/DeleteVersionMenuItem.tsx @@ -0,0 +1,72 @@ +/* + * Copyright 2024 Harness, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react' +import { useHistory } from 'react-router-dom' + +import { useStrings } from '@ar/frameworks/strings' +import { queryClient } from '@ar/utils/queryClient' +import { useParentComponents, useRoutes } from '@ar/hooks' +import { PermissionIdentifier, ResourceType } from '@ar/common/permissionTypes' + +import type { VersionActionProps } from './types' +import useDeleteVersionModal from '../../hooks/useDeleteVersionModal' + +export default function DeleteVersionMenuItem(props: VersionActionProps): JSX.Element { + const { artifactKey, repoKey, readonly, onClose, versionKey } = props + const { getString } = useStrings() + const { RbacMenuItem } = useParentComponents() + const history = useHistory() + const routes = useRoutes() + + const handleAfterDeleteRepository = (): void => { + onClose?.() + queryClient.invalidateQueries(['GetAllArtifactVersions']) + history.push( + routes.toARArtifactDetails({ + repositoryIdentifier: repoKey, + artifactIdentifier: artifactKey + }) + ) + } + + const { triggerDelete } = useDeleteVersionModal({ + artifactKey, + repoKey, + versionKey, + onSuccess: handleAfterDeleteRepository + }) + + const handleDeleteService = (): void => { + triggerDelete() + } + + return ( + + ) +} diff --git a/web/src/ar/pages/version-details/components/VersionActions/SetupClientMenuItem.tsx b/web/src/ar/pages/version-details/components/VersionActions/SetupClientMenuItem.tsx new file mode 100644 index 000000000..9ca6c9ae1 --- /dev/null +++ b/web/src/ar/pages/version-details/components/VersionActions/SetupClientMenuItem.tsx @@ -0,0 +1,56 @@ +/* + * Copyright 2024 Harness, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react' +import { defaultTo } from 'lodash-es' + +import { useParentComponents } from '@ar/hooks' +import { useStrings } from '@ar/frameworks/strings' +import type { RepositoryPackageType } from '@ar/common/types' +import { PermissionIdentifier, ResourceType } from '@ar/common/permissionTypes' +import { useSetupClientModal } from '@ar/pages/repository-details/hooks/useSetupClientModal/useSetupClientModal' + +import type { VersionActionProps } from './types' + +export default function SetupClientMenuItem(props: VersionActionProps): JSX.Element { + const { artifactKey, repoKey, data, readonly, versionKey } = props + const { getString } = useStrings() + const { RbacMenuItem } = useParentComponents() + + const [showSetupClientModal] = useSetupClientModal({ + repoKey, + packageType: data.packageType as RepositoryPackageType, + artifactKey, + versionKey + }) + return ( + <> + + + ) +} diff --git a/web/src/ar/pages/version-details/components/VersionActions/VersionActions.tsx b/web/src/ar/pages/version-details/components/VersionActions/VersionActions.tsx new file mode 100644 index 000000000..abc1ed542 --- /dev/null +++ b/web/src/ar/pages/version-details/components/VersionActions/VersionActions.tsx @@ -0,0 +1,63 @@ +/* + * Copyright 2024 Harness, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { useState } from 'react' + +import { PageType } from '@ar/common/types' +import ActionButton from '@ar/components/ActionButton/ActionButton' + +import type { VersionActionProps } from './types' +import SetupClientMenuItem from './SetupClientMenuItem' +import DeleteVersionMenuItem from './DeleteVersionMenuItem' + +export default function VersionActions({ + data, + repoKey, + artifactKey, + versionKey, + pageType, + readonly, + onClose +}: VersionActionProps): JSX.Element { + const [open, setOpen] = useState(false) + return ( + + { + setOpen(false) + onClose?.() + }} + /> + {pageType === PageType.Table && ( + setOpen(false)} + versionKey={versionKey} + artifactKey={artifactKey} + repoKey={repoKey} + /> + )} + + ) +} diff --git a/web/src/ar/pages/version-details/components/VersionActions/types.ts b/web/src/ar/pages/version-details/components/VersionActions/types.ts new file mode 100644 index 000000000..6adb24627 --- /dev/null +++ b/web/src/ar/pages/version-details/components/VersionActions/types.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2024 Harness, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArtifactVersionMetadata, ArtifactVersionSummary } from '@harnessio/react-har-service-client' +import type { PageType } from '@ar/common/types' + +export interface VersionActionProps { + data: ArtifactVersionSummary | ArtifactVersionMetadata + versionKey: string + artifactKey: string + repoKey: string + pageType: PageType + readonly?: boolean + onClose?: () => void +} diff --git a/web/src/ar/pages/version-details/components/VersionDetailsHeaderContent/VersionDetailsHeaderContent.tsx b/web/src/ar/pages/version-details/components/VersionDetailsHeaderContent/VersionDetailsHeaderContent.tsx index 686922c91..5a96315e0 100644 --- a/web/src/ar/pages/version-details/components/VersionDetailsHeaderContent/VersionDetailsHeaderContent.tsx +++ b/web/src/ar/pages/version-details/components/VersionDetailsHeaderContent/VersionDetailsHeaderContent.tsx @@ -21,9 +21,10 @@ import { Layout } from '@harnessio/uicore' import type { ArtifactVersionSummary } from '@harnessio/react-har-service-client' import { useDecodedParams, useRoutes } from '@ar/hooks' -import type { RepositoryPackageType } from '@ar/common/types' +import { PageType, type RepositoryPackageType } from '@ar/common/types' import type { VersionDetailsPathParams } from '@ar/routes/types' import RepositoryIcon from '@ar/frameworks/RepositoryStep/RepositoryIcon' +import VersionActionsWidget from '@ar/frameworks/Version/VersionActionsWidget' import SetupClientButton from '@ar/components/SetupClientButton/SetupClientButton' import VersionNameContent from './VersionNameContent' @@ -66,6 +67,14 @@ export default function VersionDetailsHeaderContent(props: VersionDetailsHeaderC versionIdentifier={pathParams.versionIdentifier} packageType={packageType as RepositoryPackageType} /> + ) } diff --git a/web/src/ar/pages/version-details/hooks/useDeleteVersionModal.tsx b/web/src/ar/pages/version-details/hooks/useDeleteVersionModal.tsx new file mode 100644 index 000000000..13ede3e48 --- /dev/null +++ b/web/src/ar/pages/version-details/hooks/useDeleteVersionModal.tsx @@ -0,0 +1,69 @@ +/* + * Copyright 2024 Harness, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Intent } from '@blueprintjs/core' +import { getErrorInfoFromErrorObject, useToaster } from '@harnessio/uicore' +import { useDeleteArtifactVersionMutation } from '@harnessio/react-har-service-client' + +import { useGetSpaceRef, useParentHooks } from '@ar/hooks' +import { useStrings } from '@ar/frameworks/strings' +import { encodeRef } from '@ar/hooks/useGetSpaceRef' + +interface useDeleteVersionModalProps { + repoKey: string + artifactKey: string + versionKey: string + onSuccess: () => void +} +export default function useDeleteVersionModal(props: useDeleteVersionModalProps) { + const { repoKey, onSuccess, artifactKey, versionKey } = props + const { getString } = useStrings() + const { showSuccess, showError, clear } = useToaster() + const { useConfirmationDialog } = useParentHooks() + const spaceRef = useGetSpaceRef(repoKey) + + const { mutateAsync: deleteVersion } = useDeleteArtifactVersionMutation() + + const handleDeleteVersion = async (isConfirmed: boolean): Promise => { + if (isConfirmed) { + try { + const response = await deleteVersion({ + registry_ref: spaceRef, + artifact: encodeRef(artifactKey), + version: versionKey + }) + if (response.content.status === 'SUCCESS') { + clear() + showSuccess(getString('versionDetails.versionDeleted')) + onSuccess() + } + } catch (e: any) { + showError(getErrorInfoFromErrorObject(e, true)) + } + } + } + + const { openDialog } = useConfirmationDialog({ + titleText: getString('versionDetails.deleteVersionModal.title'), + contentText: getString('versionDetails.deleteVersionModal.contentText'), + confirmButtonText: getString('delete'), + cancelButtonText: getString('cancel'), + intent: Intent.DANGER, + onCloseDialog: handleDeleteVersion + }) + + return { triggerDelete: openDialog } +} diff --git a/web/src/ar/pages/version-details/strings/strings.en.yaml b/web/src/ar/pages/version-details/strings/strings.en.yaml index b6b48ee93..275512b49 100644 --- a/web/src/ar/pages/version-details/strings/strings.en.yaml +++ b/web/src/ar/pages/version-details/strings/strings.en.yaml @@ -92,3 +92,7 @@ dependencyList: columns: name: Dependency Name version: Dependency Version +versionDeleted: Artifact version deleted successfully! +deleteVersionModal: + title: Delete Artifact Version + contentText: Are you sure you want to delete the artifact version? diff --git a/web/src/ar/pages/version-list/DockerVersion/VersionListTable/DockerVersionListTable.module.scss b/web/src/ar/pages/version-list/DockerVersion/VersionListTable/DockerVersionListTable.module.scss index 1c6223483..e95808e0b 100644 --- a/web/src/ar/pages/version-list/DockerVersion/VersionListTable/DockerVersionListTable.module.scss +++ b/web/src/ar/pages/version-list/DockerVersion/VersionListTable/DockerVersionListTable.module.scss @@ -44,7 +44,7 @@ div[class*='TableV2--cells'], div[class*='TableV2--header'] { display: grid !important; - grid-template-columns: 40px minmax(var(--har-table-name-column-min-width), 1fr) 1fr 1fr 1fr; + grid-template-columns: 40px minmax(var(--har-table-name-column-min-width), 1fr) 1fr 1fr 1fr 50px; } } @@ -52,7 +52,7 @@ div[class*='TableV2--cells'], div[class*='TableV2--header'] { display: grid !important; - grid-template-columns: 40px minmax(var(--har-table-name-column-min-width), 1fr) 1fr 1fr 1fr 1fr; + grid-template-columns: 40px minmax(var(--har-table-name-column-min-width), 1fr) 1fr 1fr 1fr 1fr 50px; } } diff --git a/web/src/ar/pages/version-list/DockerVersion/VersionListTable/DockerVersionListTable.tsx b/web/src/ar/pages/version-list/DockerVersion/VersionListTable/DockerVersionListTable.tsx index 0fe8ded36..d7ef81390 100644 --- a/web/src/ar/pages/version-list/DockerVersion/VersionListTable/DockerVersionListTable.tsx +++ b/web/src/ar/pages/version-list/DockerVersion/VersionListTable/DockerVersionListTable.tsx @@ -31,6 +31,7 @@ import { handleToggleExpandableRow } from '@ar/components/TableCells/utils' import { PullCommandCell, ToggleAccordionCell, + VersionActionsCell, VersionDeploymentsCell, VersionDigestsCell, VersionPublishedAtCell @@ -123,6 +124,12 @@ function DockerVersionListTable(props: DockerVersionListTableProps): JSX.Element accessor: 'pullCommand', Cell: PullCommandCell, serverSortProps: getServerSortProps('pullCommand') + }, + { + Header: '', + accessor: 'actions', + Cell: VersionActionsCell, + disableSortBy: true } ] .filter(Boolean) diff --git a/web/src/ar/pages/version-list/components/VersionListTable/VersionListCell.tsx b/web/src/ar/pages/version-list/components/VersionListTable/VersionListCell.tsx index 575035449..9d5b04795 100644 --- a/web/src/ar/pages/version-list/components/VersionListTable/VersionListCell.tsx +++ b/web/src/ar/pages/version-list/components/VersionListTable/VersionListCell.tsx @@ -16,7 +16,7 @@ import React from 'react' import { defaultTo } from 'lodash-es' -import { Link } from 'react-router-dom' +import { Link, useParams } from 'react-router-dom' import type { Cell, CellValue, ColumnInstance, Renderer, Row, TableInstance, UseExpandedRowProps } from 'react-table' import { Color, FontVariation } from '@harnessio/design-system' import { Icon } from '@harnessio/icons' @@ -27,6 +27,8 @@ import { useStrings } from '@ar/frameworks/strings' import { useDecodedParams, useRoutes } from '@ar/hooks' import TableCells from '@ar/components/TableCells/TableCells' import type { ArtifactDetailsPathParams } from '@ar/routes/types' +import { PageType, type RepositoryPackageType } from '@ar/common/types' +import VersionActionsWidget from '@ar/frameworks/Version/VersionActionsWidget' import { VersionDetailsTab } from '@ar/pages/version-details/components/VersionDetailsTabs/constants' import type { VersionListExpandedColumnProps } from './types' @@ -116,6 +118,17 @@ export const VersionPublishedAtCell: CellType = ({ value }) => { return } -export const VersionActionsCell: CellType = () => { - return <> +export const VersionActionsCell: CellType = ({ row }) => { + const { original } = row + const { artifactIdentifier, repositoryIdentifier } = useParams() + return ( + + ) } diff --git a/web/src/ar/pages/version-list/components/VersionListTable/constants.tsx b/web/src/ar/pages/version-list/components/VersionListTable/constants.tsx index 24e1f4af8..bddd3defa 100644 --- a/web/src/ar/pages/version-list/components/VersionListTable/constants.tsx +++ b/web/src/ar/pages/version-list/components/VersionListTable/constants.tsx @@ -16,6 +16,7 @@ import { PullCommandCell, + VersionActionsCell, VersionDownloadsCell, VersionFileCountCell, VersionNameCell, @@ -54,5 +55,10 @@ export const VERSION_LIST_TABLE_CELL_CONFIG: Record { - Header: keyof StringsMap + Header?: keyof StringsMap accessor: string Cell: Renderer> hidden?: boolean width?: string + disableSortBy?: boolean } diff --git a/web/src/ar/pages/version-list/components/VersionListTable/utils.ts b/web/src/ar/pages/version-list/components/VersionListTable/utils.ts index c32ef4127..de37895f1 100644 --- a/web/src/ar/pages/version-list/components/VersionListTable/utils.ts +++ b/web/src/ar/pages/version-list/components/VersionListTable/utils.ts @@ -29,7 +29,7 @@ export const getVersionListTableCellConfigs = ( const columnConfig = VERSION_LIST_TABLE_CELL_CONFIG[key as VersionListColumnEnum] return { ...columnConfig, - Header: getString(columnConfig.Header), + Header: columnConfig.Header ? getString(columnConfig.Header) : '', serverSortProps: getServerSortProps(columnConfig.accessor), ...columnConfigs[key as VersionListColumnEnum] } diff --git a/web/src/ar/pages/version-list/strings/strings.en.yaml b/web/src/ar/pages/version-list/strings/strings.en.yaml index 8eba24ae5..3c2d05358 100644 --- a/web/src/ar/pages/version-list/strings/strings.en.yaml +++ b/web/src/ar/pages/version-list/strings/strings.en.yaml @@ -12,6 +12,4 @@ table: publishedByAt: '{{ $.versionDetails.artifactDetails.layers.lastPush }}' deployments: '{{ $.versionDetails.tabs.deployments }}' actions: - deleteModal: - title: Delete Version - contentText: Are you sure you want to delete the artifact version? + deleteVersion: Delete Version diff --git a/web/src/ar/strings/types.ts b/web/src/ar/strings/types.ts index f2992e6c8..2e4528c9e 100644 --- a/web/src/ar/strings/types.ts +++ b/web/src/ar/strings/types.ts @@ -197,6 +197,8 @@ export interface StringsMap { 'versionDetails.cards.supplyChain.sbomScore': string 'versionDetails.cards.supplyChain.title': string 'versionDetails.cards.supplyChain.totalComponents': string + 'versionDetails.deleteVersionModal.contentText': string + 'versionDetails.deleteVersionModal.title': string 'versionDetails.dependencyList.table.columns.name': string 'versionDetails.dependencyList.table.columns.version': string 'versionDetails.deploymentsTable.columns.deploymentPipeline': string @@ -231,8 +233,8 @@ export interface StringsMap { 'versionDetails.tabs.overview': string 'versionDetails.tabs.securityTests': string 'versionDetails.tabs.supplyChain': string - 'versionList.actions.deleteModal.contentText': string - 'versionList.actions.deleteModal.title': string + 'versionDetails.versionDeleted': string + 'versionList.actions.deleteVersion': string 'versionList.page': string 'versionList.table.columns.activelyDeployed': string 'versionList.table.columns.deployments': string