mirror of
https://github.com/harness/drone.git
synced 2025-05-31 03:32:44 +00:00
feat: [AH-881]: Implement webhook listing page (#3262)
* feat: [AH-881]: show ALL when no triggers * feat: [AH-881]: new API changes integration * feat: [AH-881]: update status column mapping * feat: [AH-881]: remove mock data * feat: [AH-881]: Implement webhook listing page
This commit is contained in:
parent
19e099a2c1
commit
6643c377ca
@ -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",
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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 <WebhookListPage />
|
||||
default:
|
||||
return <Text intent="warning">{getString('stepNotFound')}</Text>
|
||||
}
|
||||
|
20
web/src/ar/pages/webhook-list/WebhookListPage.module.scss
Normal file
20
web/src/ar/pages/webhook-list/WebhookListPage.module.scss
Normal file
@ -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;
|
||||
}
|
19
web/src/ar/pages/webhook-list/WebhookListPage.module.scss.d.ts
vendored
Normal file
19
web/src/ar/pages/webhook-list/WebhookListPage.module.scss.d.ts
vendored
Normal file
@ -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
|
151
web/src/ar/pages/webhook-list/WebhookListPage.tsx
Normal file
151
web/src/ar/pages/webhook-list/WebhookListPage.tsx
Normal file
@ -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<RepositoryDetailsTabPathParams>()
|
||||
const { useQueryParams, useUpdateQueryParams, usePermission, usePreferenceStore } = useParentHooks()
|
||||
const { updateQueryParams } = useUpdateQueryParams<Partial<WebhookListPageQueryParams>>()
|
||||
|
||||
const queryParamOptions = useListWebhooksQueryParamOptions()
|
||||
const queryParams = useQueryParams<WebhookListPageQueryParams>(queryParamOptions)
|
||||
|
||||
const { page, size, searchTerm } = queryParams
|
||||
const { accountId, orgIdentifier, projectIdentifier } = scope
|
||||
|
||||
const { preference: sortingPreference, setPreference: setSortingPreference } = usePreferenceStore<string | undefined>(
|
||||
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 (
|
||||
<>
|
||||
<Page.SubHeader>
|
||||
<CreateWebhookButton />
|
||||
<Expander />
|
||||
<ExpandingSearchInput
|
||||
alwaysExpanded
|
||||
width={200}
|
||||
ref={searchRef}
|
||||
placeholder={getString('search')}
|
||||
defaultValue={searchTerm ?? ''}
|
||||
onChange={text => {
|
||||
updateQueryParams({ searchTerm: text || undefined, page: DEFAULT_PAGE_INDEX })
|
||||
}}
|
||||
/>
|
||||
</Page.SubHeader>
|
||||
<Page.Body
|
||||
className={css.pageBody}
|
||||
loading={isFetching}
|
||||
error={error?.message || error}
|
||||
retryOnError={() => refetch()}
|
||||
noData={{
|
||||
when: () => !response?.itemCount,
|
||||
icon: 'code-webhook',
|
||||
noIconColor: true,
|
||||
messageTitle: hasFilter ? getString('noResultsFound') : getString('webhookList.table.noWebhooksTitle'),
|
||||
button: hasFilter ? (
|
||||
<Button text={getString('clearFilters')} variation={ButtonVariation.LINK} onClick={handleClearFilters} />
|
||||
) : (
|
||||
<CreateWebhookButton />
|
||||
)
|
||||
}}>
|
||||
{response && (
|
||||
<WebhookListTable
|
||||
data={response}
|
||||
refetchList={refetch}
|
||||
gotoPage={pageNumber => 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}
|
||||
/>
|
||||
)}
|
||||
</Page.Body>
|
||||
</>
|
||||
)
|
||||
}
|
@ -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 (
|
||||
<Button variation={ButtonVariation.PRIMARY} icon="plus" iconProps={{ size: 10 }}>
|
||||
{getString('webhookList.newWebhook')}
|
||||
</Button>
|
||||
)
|
||||
}
|
@ -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;
|
||||
}
|
20
web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTable.module.scss.d.ts
vendored
Normal file
20
web/src/ar/pages/webhook-list/components/WebhookListTable/WebhookListTable.module.scss.d.ts
vendored
Normal file
@ -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
|
@ -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<Webhook>[] = 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<Webhook>[]
|
||||
}, [currentOrder, currentSort, getString, readonly])
|
||||
|
||||
return (
|
||||
<TableV2
|
||||
className={classNames(css.table)}
|
||||
columns={columns}
|
||||
data={webhooks}
|
||||
pagination={paginationProps}
|
||||
sortable
|
||||
getRowClassName={() => css.tableRow}
|
||||
onRowClick={rowDetails => {
|
||||
// TODO: navigate to webhook details page
|
||||
history.push(
|
||||
routes.toARRepositoryDetailsTab({
|
||||
repositoryIdentifier: rowDetails.identifier,
|
||||
tab: RepositoryDetailsTab.WEBHOOKS
|
||||
})
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
@ -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<D extends Record<string, any>, V = any> = TableInstance<D> & {
|
||||
column: ColumnInstance<D>
|
||||
row: Row<D>
|
||||
cell: Cell<D, V>
|
||||
value: CellValue<V>
|
||||
}
|
||||
|
||||
type CellType = Renderer<CellTypeWithActions<Webhook>>
|
||||
|
||||
export interface WebhookListColumnActions {
|
||||
refetchList?: () => void
|
||||
readonly?: boolean
|
||||
}
|
||||
|
||||
export const WebhookNameCell: Renderer<{
|
||||
row: Row<Webhook>
|
||||
column: ColumnInstance<Webhook> & 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 (
|
||||
<Layout.Horizontal spacing="small" flex={{ alignItems: 'center', justifyContent: 'flex-start' }}>
|
||||
<Icon name="code-webhook" size={24} />
|
||||
<Container onClick={killEvent}>
|
||||
<Toggle disabled={readonly} checked={isEnabled} onToggle={handleUpdateToggle} />
|
||||
</Container>
|
||||
<Text lineClamp={1} font={{ variation: FontVariation.BODY }} color={Color.PRIMARY_7}>
|
||||
{name}
|
||||
</Text>
|
||||
</Layout.Horizontal>
|
||||
)
|
||||
}
|
||||
|
||||
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 (
|
||||
<Text lineClamp={2} font={{ variation: FontVariation.BODY }} color={Color.GREY_500}>
|
||||
{getDisplayText()}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
|
||||
export const WebhookStatusCell: CellType = ({ row }) => {
|
||||
const { original } = row
|
||||
const { latestExecutionResult } = original
|
||||
const iconProps: IconProps =
|
||||
latestExecutionResult && WebhookStatusIconMap[latestExecutionResult]
|
||||
? WebhookStatusIconMap[latestExecutionResult]
|
||||
: DefaultStatusIconMap
|
||||
return <Icon {...iconProps} size={18} />
|
||||
}
|
||||
|
||||
export const WebhookActionsCell: CellType = () => {
|
||||
const [open, setOpen] = useState(false)
|
||||
return (
|
||||
<ActionButton isOpen={open} setOpen={setOpen}>
|
||||
{/* TODO: Add webhook actions here */}
|
||||
<>Option 1</>
|
||||
</ActionButton>
|
||||
)
|
||||
}
|
35
web/src/ar/pages/webhook-list/constants.ts
Normal file
35
web/src/ar/pages/webhook-list/constants.ts
Normal file
@ -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<Trigger, StringKeys> = {
|
||||
ARTIFACT_CREATION: 'webhookList.triggers.artifactCreation',
|
||||
ARTIFACT_DELETION: 'webhookList.triggers.artifactDeletion',
|
||||
ARTIFACT_MODIFICATION: 'webhookList.triggers.artifactModification'
|
||||
}
|
||||
|
||||
export const WebhookStatusIconMap: Record<WebhookExecResult, IconProps> = {
|
||||
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 }
|
50
web/src/ar/pages/webhook-list/mockData.ts
Normal file
50
web/src/ar/pages/webhook-list/mockData.ts
Normal file
@ -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
|
||||
}
|
||||
]
|
||||
}
|
10
web/src/ar/pages/webhook-list/strings/strings.en.yaml
Normal file
10
web/src/ar/pages/webhook-list/strings/strings.en.yaml
Normal file
@ -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
|
42
web/src/ar/pages/webhook-list/utils.ts
Normal file
42
web/src/ar/pages/webhook-list/utils.ts
Normal file
@ -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<WebhookListPageQueryParams> => {
|
||||
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
|
||||
}
|
@ -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 }}'
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user