diff --git a/web/package.json b/web/package.json
index fb46fce4b..50f9b267a 100644
--- a/web/package.json
+++ b/web/package.json
@@ -51,7 +51,7 @@
"@codemirror/view": "^6.9.6",
"@harnessio/design-system": "^2.1.1",
"@harnessio/icons": "^2.1.9",
- "@harnessio/react-har-service-client": "^0.4.0",
+ "@harnessio/react-har-service-client": "^0.6.0",
"@harnessio/react-ssca-manager-client": "^0.65.0",
"@harnessio/uicore": "^4.1.2",
"@tanstack/react-query": "4.20.4",
diff --git a/web/src/ar/frameworks/strings/languageLoader.ts b/web/src/ar/frameworks/strings/languageLoader.ts
index b0e80e413..8b010c885 100644
--- a/web/src/ar/frameworks/strings/languageLoader.ts
+++ b/web/src/ar/frameworks/strings/languageLoader.ts
@@ -27,6 +27,7 @@ import repositoryList from '@ar/pages/repository-list/strings/strings.en.yaml'
import upstreamProxyDetails from '@ar/pages/upstream-proxy-details/strings/strings.en.yaml'
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'
export default function languageLoader() {
return {
@@ -37,6 +38,7 @@ export default function languageLoader() {
repositoryList,
upstreamProxyDetails,
versionDetails,
- versionList
+ versionList,
+ webhookList
}
}
diff --git a/web/src/ar/pages/repository-details/RepositoryDetailsTabPage.tsx b/web/src/ar/pages/repository-details/RepositoryDetailsTabPage.tsx
index 1d5e35ec6..5abf836bf 100644
--- a/web/src/ar/pages/repository-details/RepositoryDetailsTabPage.tsx
+++ b/web/src/ar/pages/repository-details/RepositoryDetailsTabPage.tsx
@@ -26,6 +26,7 @@ import type { RepositoryConfigType, RepositoryPackageType } from '@ar/common/typ
import RepositoryConfigurationFormWidget from '@ar/frameworks/RepositoryStep/RepositoryConfigurationFormWidget'
import { RepositoryDetailsTab } from './constants'
+import WebhookListPage from '../webhook-list/WebhookListPage'
import { RepositoryProviderContext } from './context/RepositoryProvider'
import RegistryArtifactListPage from '../artifact-list/RegistryArtifactListPage'
@@ -58,6 +59,8 @@ export default function RepositoryDetailsTabPage(props: RepositoryDetailsTabPage
readonly={isReadonly}
/>
)
+ case RepositoryDetailsTab.WEBHOOKS:
+ return
default:
return {getString('stepNotFound')}
}
diff --git a/web/src/ar/pages/webhook-list/WebhookListPage.module.scss b/web/src/ar/pages/webhook-list/WebhookListPage.module.scss
new file mode 100644
index 000000000..04d0a82eb
--- /dev/null
+++ b/web/src/ar/pages/webhook-list/WebhookListPage.module.scss
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+.pageBody {
+ --page-header-height: 253px;
+ background-color: var(--primary-bg) !important;
+}
diff --git a/web/src/ar/pages/webhook-list/WebhookListPage.module.scss.d.ts b/web/src/ar/pages/webhook-list/WebhookListPage.module.scss.d.ts
new file mode 100644
index 000000000..ed71a64c0
--- /dev/null
+++ b/web/src/ar/pages/webhook-list/WebhookListPage.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 pageBody: string
diff --git a/web/src/ar/pages/webhook-list/WebhookListPage.tsx b/web/src/ar/pages/webhook-list/WebhookListPage.tsx
new file mode 100644
index 000000000..9176bb835
--- /dev/null
+++ b/web/src/ar/pages/webhook-list/WebhookListPage.tsx
@@ -0,0 +1,151 @@
+/*
+ * 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, { useMemo, useRef } from 'react'
+import { flushSync } from 'react-dom'
+import { useParams } from 'react-router-dom'
+import { Expander } from '@blueprintjs/core'
+import { useListWebhooksQuery } from '@harnessio/react-har-service-client'
+import { Button, ButtonVariation, ExpandingSearchInput, ExpandingSearchInputHandle, Page } from '@harnessio/uicore'
+
+import { DEFAULT_PAGE_INDEX, PreferenceScope } from '@ar/constants'
+import { useStrings } from '@ar/frameworks/strings'
+import type { RepositoryDetailsTabPathParams } from '@ar/routes/types'
+import { useAppStore, useGetSpaceRef, useParentHooks } from '@ar/hooks'
+import { PermissionIdentifier, ResourceType } from '@ar/common/permissionTypes'
+
+import WebhookListTable from './components/WebhookListTable/WebhookListTable'
+import CreateWebhookButton from './components/CreateWebhookButton/CreateWebhookButton'
+import { useListWebhooksQueryParamOptions, type WebhookListPageQueryParams } from './utils'
+
+import css from './WebhookListPage.module.scss'
+
+export default function WebhookListPage() {
+ const { getString } = useStrings()
+ const registryRef = useGetSpaceRef()
+ const searchRef = useRef({} as ExpandingSearchInputHandle)
+
+ const { scope } = useAppStore()
+ const { repositoryIdentifier } = useParams()
+ const { useQueryParams, useUpdateQueryParams, usePermission, usePreferenceStore } = useParentHooks()
+ const { updateQueryParams } = useUpdateQueryParams>()
+
+ const queryParamOptions = useListWebhooksQueryParamOptions()
+ const queryParams = useQueryParams(queryParamOptions)
+
+ const { page, size, searchTerm } = queryParams
+ const { accountId, orgIdentifier, projectIdentifier } = scope
+
+ const { preference: sortingPreference, setPreference: setSortingPreference } = usePreferenceStore(
+ PreferenceScope.USER,
+ 'ArtifactWebhooksSortingPreference'
+ )
+ const sort = useMemo(
+ () => (sortingPreference ? JSON.parse(sortingPreference) : queryParams.sort),
+ [queryParams.sort, sortingPreference]
+ )
+
+ const [sortField, sortOrder] = sort || []
+
+ const [isEdit] = usePermission(
+ {
+ resourceScope: {
+ accountIdentifier: accountId,
+ orgIdentifier,
+ projectIdentifier
+ },
+ resource: {
+ resourceType: ResourceType.ARTIFACT_REGISTRY,
+ resourceIdentifier: repositoryIdentifier
+ },
+ permissions: [PermissionIdentifier.EDIT_ARTIFACT_REGISTRY]
+ },
+ [accountId, projectIdentifier, orgIdentifier, repositoryIdentifier]
+ )
+
+ const { isFetching, data, error, refetch } = useListWebhooksQuery({
+ registry_ref: registryRef,
+ queryParams: {
+ page,
+ size,
+ search_term: searchTerm,
+ sort_field: sortField,
+ sort_order: sortOrder
+ }
+ })
+
+ const handleClearFilters = (): void => {
+ flushSync(searchRef.current.clear)
+ updateQueryParams({
+ page: undefined,
+ size: undefined,
+ searchTerm: undefined
+ })
+ }
+
+ const response = data?.content.data
+
+ const hasFilter = !!searchTerm
+ return (
+ <>
+
+
+
+ {
+ updateQueryParams({ searchTerm: text || undefined, page: DEFAULT_PAGE_INDEX })
+ }}
+ />
+
+ refetch()}
+ noData={{
+ when: () => !response?.itemCount,
+ icon: 'code-webhook',
+ noIconColor: true,
+ messageTitle: hasFilter ? getString('noResultsFound') : getString('webhookList.table.noWebhooksTitle'),
+ button: hasFilter ? (
+
+ ) : (
+
+ )
+ }}>
+ {response && (
+ updateQueryParams({ page: pageNumber })}
+ onPageSizeChange={newSize => updateQueryParams({ size: newSize, page: DEFAULT_PAGE_INDEX })}
+ sortBy={sort}
+ setSortBy={sortArray => {
+ setSortingPreference(JSON.stringify(sortArray))
+ updateQueryParams({ sort: sortArray, page: DEFAULT_PAGE_INDEX })
+ }}
+ readonly={!isEdit}
+ />
+ )}
+
+ >
+ )
+}
diff --git a/web/src/ar/pages/webhook-list/components/CreateWebhookButton/CreateWebhookButton.tsx b/web/src/ar/pages/webhook-list/components/CreateWebhookButton/CreateWebhookButton.tsx
new file mode 100644
index 000000000..20afd394c
--- /dev/null
+++ b/web/src/ar/pages/webhook-list/components/CreateWebhookButton/CreateWebhookButton.tsx
@@ -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 React from 'react'
+import { Button, ButtonVariation } from '@harnessio/uicore'
+import { useStrings } from '@ar/frameworks/strings'
+
+export default function CreateWebhookButton() {
+ const { getString } = useStrings()
+ return (
+
+ )
+}
diff --git a/web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTable.module.scss b/web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTable.module.scss
new file mode 100644
index 000000000..0947a6315
--- /dev/null
+++ b/web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTable.module.scss
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+.table {
+ --typography-size: 12px;
+ --typography-weight: 400;
+ --line-height: 20px;
+ padding: var(--spacing-large);
+
+ [role='cell'],
+ [role='columnheader'] {
+ width: auto !important;
+ padding-right: var(--spacing-small);
+ }
+
+ div[class*='TableV2--cells'],
+ div[class*='TableV2--header'] {
+ display: grid !important;
+ grid-template-columns: minmax(var(--har-table-name-column-min-width), 1fr) 1fr 50px 50px;
+ }
+}
+
+.tableRow {
+ position: relative;
+}
diff --git a/web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTable.module.scss.d.ts b/web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTable.module.scss.d.ts
new file mode 100644
index 000000000..03f6c3aff
--- /dev/null
+++ b/web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTable.module.scss.d.ts
@@ -0,0 +1,20 @@
+/*
+ * 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 table: string
+export declare const tableRow: string
diff --git a/web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTable.tsx b/web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTable.tsx
new file mode 100644
index 000000000..49db3664d
--- /dev/null
+++ b/web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTable.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 from 'react'
+import classNames from 'classnames'
+import type { Column } from 'react-table'
+import { useHistory } from 'react-router-dom'
+import { type PaginationProps, TableV2 } from '@harnessio/uicore'
+import type { ListWebhooks, Webhook } from '@harnessio/react-har-service-client'
+
+import { useStrings } from '@ar/frameworks/strings'
+import { useParentHooks, useRoutes } from '@ar/hooks'
+import { RepositoryDetailsTab } from '@ar/pages/repository-details/constants'
+
+import {
+ WebhookActionsCell,
+ WebhookListColumnActions,
+ WebhookNameCell,
+ WebhookStatusCell,
+ WebhookTriggerCell
+} from './WebhookListTableCells'
+
+import css from './WebhookListTable.module.scss'
+
+interface WebhookListSortBy {
+ sort: 'name'
+}
+
+export interface WebhookListTableProps extends WebhookListColumnActions {
+ data: ListWebhooks
+ gotoPage: (pageNumber: number) => void
+ onPageSizeChange?: PaginationProps['onPageSizeChange']
+ setSortBy: (sortBy: string[]) => void
+ sortBy: string[]
+ minimal?: boolean
+}
+
+export default function WebhookListTable(props: WebhookListTableProps): JSX.Element {
+ const { data, gotoPage, onPageSizeChange, readonly, sortBy, setSortBy } = props
+ const { useDefaultPaginationProps } = useParentHooks()
+ const { getString } = useStrings()
+ const history = useHistory()
+ const routes = useRoutes()
+ const [currentSort, currentOrder] = sortBy || []
+
+ const { webhooks, itemCount = 0, pageCount = 0, pageIndex, pageSize = 0 } = data
+ const paginationProps = useDefaultPaginationProps({
+ itemCount,
+ pageSize,
+ pageCount,
+ pageIndex,
+ gotoPage,
+ onPageSizeChange
+ })
+
+ const columns: Column[] = React.useMemo(() => {
+ const getServerSortProps = (id: string) => {
+ return {
+ enableServerSort: true,
+ isServerSorted: currentSort === id,
+ isServerSortedDesc: currentOrder === 'DESC',
+ getSortedColumn: ({ sort }: WebhookListSortBy) => {
+ setSortBy([sort, currentOrder === 'DESC' ? 'ASC' : 'DESC'])
+ }
+ }
+ }
+ return [
+ {
+ Header: getString('webhookList.table.columns.name'),
+ accessor: 'name',
+ Cell: WebhookNameCell,
+ serverSortProps: getServerSortProps('name'),
+ readonly: readonly
+ },
+ {
+ Header: getString('webhookList.table.columns.trigger'),
+ accessor: 'triggers',
+ Cell: WebhookTriggerCell,
+ disableSortBy: true
+ },
+ {
+ Header: '',
+ accessor: 'latestExecutionResult',
+ Cell: WebhookStatusCell,
+ disableSortBy: true
+ },
+ {
+ Header: '',
+ accessor: 'menu',
+ Cell: WebhookActionsCell,
+ disableSortBy: true
+ }
+ ].filter(Boolean) as unknown as Column[]
+ }, [currentOrder, currentSort, getString, readonly])
+
+ return (
+ css.tableRow}
+ onRowClick={rowDetails => {
+ // TODO: navigate to webhook details page
+ history.push(
+ routes.toARRepositoryDetailsTab({
+ repositoryIdentifier: rowDetails.identifier,
+ tab: RepositoryDetailsTab.WEBHOOKS
+ })
+ )
+ }}
+ />
+ )
+}
diff --git a/web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTableCells.tsx b/web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTableCells.tsx
new file mode 100644
index 000000000..6848666ed
--- /dev/null
+++ b/web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTableCells.tsx
@@ -0,0 +1,123 @@
+/*
+ * 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 { Icon, IconProps } from '@harnessio/icons'
+import { Color, FontVariation } from '@harnessio/design-system'
+import { Container, getErrorInfoFromErrorObject, Layout, Text, Toggle, useToaster } from '@harnessio/uicore'
+import { updateWebhook, type Trigger, type Webhook } from '@harnessio/react-har-service-client'
+import type { Cell, CellValue, ColumnInstance, Renderer, Row, TableInstance } from 'react-table'
+
+import { useGetSpaceRef } from '@ar/hooks'
+import { killEvent } from '@ar/common/utils'
+import { useStrings } from '@ar/frameworks/strings'
+import ActionButton from '@ar/components/ActionButton/ActionButton'
+
+import { DefaultStatusIconMap, WebhookStatusIconMap, WebhookTriggerLabelMap } from '../../constants'
+
+type CellTypeWithActions, V = any> = TableInstance & {
+ column: ColumnInstance
+ row: Row
+ cell: Cell
+ value: CellValue
+}
+
+type CellType = Renderer>
+
+export interface WebhookListColumnActions {
+ refetchList?: () => void
+ readonly?: boolean
+}
+
+export const WebhookNameCell: Renderer<{
+ row: Row
+ column: ColumnInstance & WebhookListColumnActions
+}> = ({ row, column }) => {
+ const { name, enabled, identifier } = row.original
+ const { readonly } = column
+ const [isEnabled, setIsEnabled] = useState(enabled)
+ const registryRef = useGetSpaceRef()
+
+ const { showError, clear } = useToaster()
+
+ const handleUpdateToggle = async (checked: boolean) => {
+ setIsEnabled(checked)
+ try {
+ await updateWebhook({
+ registry_ref: registryRef,
+ webhook_identifier: identifier,
+ body: {
+ ...row.original,
+ enabled: checked
+ }
+ })
+ } catch (e) {
+ clear()
+ showError(getErrorInfoFromErrorObject(e as Error))
+ setIsEnabled(enabled)
+ }
+ }
+
+ return (
+
+
+
+
+
+
+ {name}
+
+
+ )
+}
+
+export const WebhookTriggerCell: CellType = ({ value }) => {
+ const { getString } = useStrings()
+ const getDisplayText = () => {
+ if (!value || !value.length) return getString('all')
+ return value
+ .map((each: Trigger) => {
+ if (WebhookTriggerLabelMap[each]) return getString(WebhookTriggerLabelMap[each])
+ return each
+ })
+ .join(', ')
+ }
+ return (
+
+ {getDisplayText()}
+
+ )
+}
+
+export const WebhookStatusCell: CellType = ({ row }) => {
+ const { original } = row
+ const { latestExecutionResult } = original
+ const iconProps: IconProps =
+ latestExecutionResult && WebhookStatusIconMap[latestExecutionResult]
+ ? WebhookStatusIconMap[latestExecutionResult]
+ : DefaultStatusIconMap
+ return
+}
+
+export const WebhookActionsCell: CellType = () => {
+ const [open, setOpen] = useState(false)
+ return (
+
+ {/* TODO: Add webhook actions here */}
+ <>Option 1>
+
+ )
+}
diff --git a/web/src/ar/pages/webhook-list/constants.ts b/web/src/ar/pages/webhook-list/constants.ts
new file mode 100644
index 000000000..1dde82552
--- /dev/null
+++ b/web/src/ar/pages/webhook-list/constants.ts
@@ -0,0 +1,35 @@
+/*
+ * 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 { Color } from '@harnessio/design-system'
+import type { IconProps } from '@harnessio/icons'
+import type { Trigger, WebhookExecResult } from '@harnessio/react-har-service-client'
+
+import type { StringKeys } from '@ar/frameworks/strings'
+
+export const WebhookTriggerLabelMap: Record = {
+ ARTIFACT_CREATION: 'webhookList.triggers.artifactCreation',
+ ARTIFACT_DELETION: 'webhookList.triggers.artifactDeletion',
+ ARTIFACT_MODIFICATION: 'webhookList.triggers.artifactModification'
+}
+
+export const WebhookStatusIconMap: Record = {
+ SUCCESS: { name: 'dot', color: Color.SUCCESS },
+ RETRIABLE_ERROR: { name: 'dot', color: Color.WARNING },
+ FATAL_ERROR: { name: 'dot', color: Color.ERROR }
+}
+
+export const DefaultStatusIconMap: IconProps = { name: 'dot', color: Color.GREY_500 }
diff --git a/web/src/ar/pages/webhook-list/mockData.ts b/web/src/ar/pages/webhook-list/mockData.ts
new file mode 100644
index 000000000..5e623db29
--- /dev/null
+++ b/web/src/ar/pages/webhook-list/mockData.ts
@@ -0,0 +1,50 @@
+/*
+ * 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 { ListWebhooks } from '@harnessio/react-har-service-client'
+
+export const MOCK_WEBHOK_LIST_TABLE: ListWebhooks = {
+ itemCount: 10,
+ pageCount: 1,
+ pageIndex: 0,
+ pageSize: 10,
+ webhooks: [
+ {
+ name: 'Webhook 1',
+ identifier: 'webhook-1',
+ triggers: ['ARTIFACT_CREATION'],
+ url: 'https://webhook-1.com',
+ insecure: false,
+ enabled: true
+ },
+ {
+ name: 'Webhook 2',
+ identifier: 'webhook-2',
+ triggers: ['ARTIFACT_CREATION', 'ARTIFACT_DELETION'],
+ url: 'https://webhook-2.com',
+ insecure: false,
+ enabled: true
+ },
+ {
+ name: 'Webhook 3',
+ identifier: 'webhook-3',
+ triggers: ['ARTIFACT_CREATION', 'ARTIFACT_DELETION', 'ARTIFACT_MODIFICATION'],
+ url: 'https://webhook-3.com',
+ insecure: false,
+ enabled: true
+ }
+ ]
+}
diff --git a/web/src/ar/pages/webhook-list/strings/strings.en.yaml b/web/src/ar/pages/webhook-list/strings/strings.en.yaml
new file mode 100644
index 000000000..a5b28006d
--- /dev/null
+++ b/web/src/ar/pages/webhook-list/strings/strings.en.yaml
@@ -0,0 +1,10 @@
+newWebhook: New Webhook
+triggers:
+ artifactCreation: 'Artifact Creation'
+ artifactDeletion: 'Artifact Deletion'
+ artifactModification: 'Artifact Modification'
+table:
+ columns:
+ name: Webhook
+ trigger: Event
+ noWebhooksTitle: There are no webhooks available
diff --git a/web/src/ar/pages/webhook-list/utils.ts b/web/src/ar/pages/webhook-list/utils.ts
new file mode 100644
index 000000000..34fc307c3
--- /dev/null
+++ b/web/src/ar/pages/webhook-list/utils.ts
@@ -0,0 +1,42 @@
+/*
+ * 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 { useMemo } from 'react'
+import type { ListWebhooksQueryQueryParams } from '@harnessio/react-har-service-client'
+
+import { useParentHooks } from '@ar/hooks'
+import { DEFAULT_PAGE_INDEX, DEFAULT_PAGE_SIZE } from '@ar/constants'
+import type { UseQueryParamsOptions } from '@ar/__mocks__/hooks'
+
+export type WebhookListPageQueryParams = ListWebhooksQueryQueryParams & {
+ searchTerm?: string
+ sort: string[]
+}
+
+export const useListWebhooksQueryParamOptions = (): UseQueryParamsOptions => {
+ const { useQueryParamsOptions } = useParentHooks()
+ const _options = useQueryParamsOptions(
+ {
+ page: DEFAULT_PAGE_INDEX,
+ size: DEFAULT_PAGE_SIZE,
+ sort: []
+ },
+ { ignoreEmptyString: false }
+ )
+ const options = useMemo(() => ({ ..._options, strictNullHandling: true }), [_options])
+
+ return options
+}
diff --git a/web/src/ar/strings/strings.en.yaml b/web/src/ar/strings/strings.en.yaml
index 568c66ca4..b86adc90f 100644
--- a/web/src/ar/strings/strings.en.yaml
+++ b/web/src/ar/strings/strings.en.yaml
@@ -26,6 +26,7 @@ na: N/A
cancel: Cancel
comingSoon: Coming Soon.
failedToLoadData: Failed to load data. Please try again!
+all: All
noResultsFound: No results found
optionalField: '{{name}} (optional)'
description: '{{ $.versionDetails.overview.generalInformation.description }}'
diff --git a/web/src/ar/strings/types.ts b/web/src/ar/strings/types.ts
index 3b5789acd..d58d4f1b3 100644
--- a/web/src/ar/strings/types.ts
+++ b/web/src/ar/strings/types.ts
@@ -228,6 +228,13 @@ export interface StringsMap {
'versionList.table.columns.size': string
'versionList.table.columns.version': string
'versionList.table.noVersionsTitle': string
+ 'webhookList.newWebhook': string
+ 'webhookList.table.columns.name': string
+ 'webhookList.table.columns.trigger': string
+ 'webhookList.table.noWebhooksTitle': string
+ 'webhookList.triggers.artifactCreation': string
+ 'webhookList.triggers.artifactDeletion': string
+ 'webhookList.triggers.artifactModification': string
'actions.delete': string
'actions.edit': string
'actions.quarantine': string
@@ -235,6 +242,7 @@ export interface StringsMap {
'actions.scan': string
'actions.setupClient': string
add: string
+ all: string
'badges.artifactRegistry': string
'badges.upstreamProxy': string
'breadcrumbs.artifacts': string
diff --git a/web/yarn.lock b/web/yarn.lock
index 0b6b5bb66..85a0bc8c2 100644
--- a/web/yarn.lock
+++ b/web/yarn.lock
@@ -1945,10 +1945,10 @@
yargs "^17.6.2"
zod "^3.19.1"
-"@harnessio/react-har-service-client@^0.4.0":
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/@harnessio/react-har-service-client/-/react-har-service-client-0.4.0.tgz#ad0deb70502f8ff51c7199d72dd67aa7a13640b4"
- integrity sha512-ndVz0Ig0FHHwgDy1oZVQ7I2epFgM0dnYLLAUHOLMzaqvcV6pN8RCuawtygcFi9K2DKMfFQieWTuI9UjVoB8M+w==
+"@harnessio/react-har-service-client@^0.6.0":
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/@harnessio/react-har-service-client/-/react-har-service-client-0.6.0.tgz#25253fd935fe6a28a5d26d98148ba0ba51d545ef"
+ integrity sha512-jCCCInwmVoCWrambIop6dK8SvJXHpsq+8MdZNPbguMPjJgqR0d6i6Ms+4lpfBswJ/5TVVEvo/uFJhlAUVtf2fQ==
dependencies:
"@harnessio/oats-cli" "^3.0.0"