From b00a8f16b481185f2d005eeef28b4b2a960ebfbb Mon Sep 17 00:00:00 2001 From: Shivanand Sonnad Date: Tue, 21 Jan 2025 07:08:51 +0000 Subject: [PATCH] feat: [AH-883]: Implement edit webhook page (#3291) * feat: [AH-883]: refetch webhook after update and fix route to webhook details page from webhook list page * feat: [AH-883]: fix breaking css for inline inputs * feat: [AH-883]: implement Edit flow with enterprise secret input * feat: [AH-883]: Implement edit webhook page --- .../ar/frameworks/strings/languageLoader.ts | 4 +- .../ar/gitness/utils/getARRouteDefinitions.ts | 4 +- .../components/Forms/utils.ts | 2 +- .../WebhookDetailsPage.module.scss | 40 ++++++ .../WebhookDetailsPage.module.scss.d.ts | 19 +++ .../webhook-details/WebhookDetailsPage.tsx | 128 ++++++++++++++++++ .../webhook-details/WebhookDetailsTabPage.tsx | 49 +++++++ .../WebhookConfigurationForm.module.scss | 33 +++++ .../WebhookConfigurationForm.module.scss.d.ts | 19 +++ .../WebhookConfigurationForm.tsx | 69 ++++++++++ .../WebhookDetailsPageHeader.tsx | 64 +++++++++ .../ar/pages/webhook-details/constants.tsx | 20 +++ .../context/WebhookDetailsContext.ts | 30 ++++ .../webhook-details/strings/strings.en.yaml | 3 + .../components/Forms/WebhookForm.tsx | 12 +- .../webhook-list/components/Forms/utils.ts | 30 +++- .../WebhookListTable/WebhookListTable.tsx | 6 +- .../webhook-list/strings/strings.en.yaml | 1 + web/src/ar/routes/RouteDefinitions.ts | 6 +- web/src/ar/routes/RouteDestinations.tsx | 17 +++ web/src/ar/routes/types.ts | 5 + web/src/ar/strings/types.ts | 3 + 22 files changed, 553 insertions(+), 11 deletions(-) create mode 100644 web/src/ar/pages/webhook-details/WebhookDetailsPage.module.scss create mode 100644 web/src/ar/pages/webhook-details/WebhookDetailsPage.module.scss.d.ts create mode 100644 web/src/ar/pages/webhook-details/WebhookDetailsPage.tsx create mode 100644 web/src/ar/pages/webhook-details/WebhookDetailsTabPage.tsx create mode 100644 web/src/ar/pages/webhook-details/components/WebhookConfigurationForm/WebhookConfigurationForm.module.scss create mode 100644 web/src/ar/pages/webhook-details/components/WebhookConfigurationForm/WebhookConfigurationForm.module.scss.d.ts create mode 100644 web/src/ar/pages/webhook-details/components/WebhookConfigurationForm/WebhookConfigurationForm.tsx create mode 100644 web/src/ar/pages/webhook-details/components/WebhookDetailsPageHeader/WebhookDetailsPageHeader.tsx create mode 100644 web/src/ar/pages/webhook-details/constants.tsx create mode 100644 web/src/ar/pages/webhook-details/context/WebhookDetailsContext.ts create mode 100644 web/src/ar/pages/webhook-details/strings/strings.en.yaml diff --git a/web/src/ar/frameworks/strings/languageLoader.ts b/web/src/ar/frameworks/strings/languageLoader.ts index 8b010c885..bea00ce17 100644 --- a/web/src/ar/frameworks/strings/languageLoader.ts +++ b/web/src/ar/frameworks/strings/languageLoader.ts @@ -28,6 +28,7 @@ import upstreamProxyDetails from '@ar/pages/upstream-proxy-details/strings/strin import versionDetails from '@ar/pages/version-details/strings/strings.en.yaml' import versionList from '@ar/pages/version-list/strings/strings.en.yaml' import webhookList from '@ar/pages/webhook-list/strings/strings.en.yaml' +import webhookDetails from '@ar/pages/webhook-details/strings/strings.en.yaml' export default function languageLoader() { return { @@ -39,6 +40,7 @@ export default function languageLoader() { upstreamProxyDetails, versionDetails, versionList, - webhookList + webhookList, + webhookDetails } } diff --git a/web/src/ar/gitness/utils/getARRouteDefinitions.ts b/web/src/ar/gitness/utils/getARRouteDefinitions.ts index 69ab37928..91625c0ba 100644 --- a/web/src/ar/gitness/utils/getARRouteDefinitions.ts +++ b/web/src/ar/gitness/utils/getARRouteDefinitions.ts @@ -31,6 +31,8 @@ export default function getARRouteDefinitions(routeParams: Record - `/${params?.repositoryIdentifier}/artifacts/${params?.artifactIdentifier}/versions/${params?.versionIdentifier}` + `/${params?.repositoryIdentifier}/artifacts/${params?.artifactIdentifier}/versions/${params?.versionIdentifier}`, + toARRepositoryWebhookDetailsTab: params => + `/${params?.repositoryIdentifier}/webhooks/${params?.webhookIdentifier}/${params?.tab}` } } diff --git a/web/src/ar/pages/upstream-proxy-details/components/Forms/utils.ts b/web/src/ar/pages/upstream-proxy-details/components/Forms/utils.ts index dbcacd44c..bf5a86cc3 100644 --- a/web/src/ar/pages/upstream-proxy-details/components/Forms/utils.ts +++ b/web/src/ar/pages/upstream-proxy-details/components/Forms/utils.ts @@ -123,7 +123,7 @@ export function getFormattedFormDataForAuthType( }) } -function getSecretScopeDetailsByIdentifier(identifier: string, secretSpacePath: string) { +export function getSecretScopeDetailsByIdentifier(identifier: string, secretSpacePath: string) { const referenceString = getReferenceStringFromSecretSpacePath(identifier, secretSpacePath) const [, orgIdentifier, projectIdentifier] = secretSpacePath.split('/') return { diff --git a/web/src/ar/pages/webhook-details/WebhookDetailsPage.module.scss b/web/src/ar/pages/webhook-details/WebhookDetailsPage.module.scss new file mode 100644 index 000000000..4d24c0ded --- /dev/null +++ b/web/src/ar/pages/webhook-details/WebhookDetailsPage.module.scss @@ -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. + */ + +.tabsContainer { + position: relative !important; + & > :global(.bp3-tabs > .bp3-tab-list) { + border-bottom: 1px solid var(--grey-200); + } + :global { + .bp3-tab-panel { + margin-top: 0; + } + + .bp3-tab-list { + background-color: var(--white); + width: 100%; + border-bottom: 0; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.13); + align-items: center; + padding: 0 var(--spacing-xlarge); + + position: sticky; + top: 0px; + z-index: 2; + } + } +} diff --git a/web/src/ar/pages/webhook-details/WebhookDetailsPage.module.scss.d.ts b/web/src/ar/pages/webhook-details/WebhookDetailsPage.module.scss.d.ts new file mode 100644 index 000000000..104661eb9 --- /dev/null +++ b/web/src/ar/pages/webhook-details/WebhookDetailsPage.module.scss.d.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2023 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. + */ + +/* eslint-disable */ +// This is an auto-generated file +export declare const tabsContainer: string diff --git a/web/src/ar/pages/webhook-details/WebhookDetailsPage.tsx b/web/src/ar/pages/webhook-details/WebhookDetailsPage.tsx new file mode 100644 index 000000000..7c295e502 --- /dev/null +++ b/web/src/ar/pages/webhook-details/WebhookDetailsPage.tsx @@ -0,0 +1,128 @@ +/* + * 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 type { FormikProps } from 'formik' +import { Expander } from '@blueprintjs/core' +import { useGetWebhookQuery, type WebhookRequest } from '@harnessio/react-har-service-client' +import { Redirect, Switch, useHistory, useParams } from 'react-router-dom' +import { Button, ButtonVariation, Container, Layout, Page, Tab, Tabs } from '@harnessio/uicore' + +import { useStrings } from '@ar/frameworks/strings' +import RouteProvider from '@ar/components/RouteProvider/RouteProvider' +import type { RepositoryWebhookDetailsPathParams } from '@ar/routes/types' +import { useGetSpaceRef, useParentComponents, useRoutes } from '@ar/hooks' +import { PermissionIdentifier, ResourceType } from '@ar/common/permissionTypes' +import { repositoryWebhookDetailsPathParams, repositoryWebhookDetailsTabPathParams } from '@ar/routes/RouteDestinations' + +import { WebhookDetailsTab } from './constants' +import WebhookDetailsTabPage from './WebhookDetailsTabPage' +// import { MOCK_WEBHOK_LIST_TABLE } from '../webhook-list/mockData' +import { WebhookDetailsContext } from './context/WebhookDetailsContext' +import { WebhookDetailsPageHeader } from './components/WebhookDetailsPageHeader/WebhookDetailsPageHeader' + +import css from './WebhookDetailsPage.module.scss' + +export default function WebhookDetailsPage() { + const params = useParams() + const { repositoryIdentifier, webhookIdentifier } = params + const history = useHistory() + const routes = useRoutes() + const routeDefinitions = useRoutes(true) + const { RbacButton } = useParentComponents() + + const registryRef = useGetSpaceRef() + const { getString } = useStrings() + const stepRef = React.useRef | null>(null) + + const [activeTab, setActiveTab] = useState(WebhookDetailsTab.Configuration) + const [isDirty, setIsDirty] = useState(false) + const [isUpdating, setUpdating] = useState(false) + + const { isFetching, error, data, refetch } = useGetWebhookQuery({ + registry_ref: registryRef, + webhook_identifier: webhookIdentifier + }) + + const handleChangeTab = (nextTab: WebhookDetailsTab): void => { + setActiveTab(nextTab) + history.push(routes.toARRepositoryWebhookDetailsTab({ ...params, tab: nextTab })) + } + + const renderActionBtns = (): JSX.Element => ( + + +