mirror of
https://github.com/harness/drone.git
synced 2025-05-12 23:20:10 +08:00
pipeline settings WIP
This commit is contained in:
parent
86bc727825
commit
6c9eff97cc
@ -47,6 +47,7 @@ export interface CODERoutes {
|
|||||||
toCODESpaceSettings: (args: Required<Pick<CODEProps, 'space'>>) => string
|
toCODESpaceSettings: (args: Required<Pick<CODEProps, 'space'>>) => string
|
||||||
toCODEPipelines: (args: Required<Pick<CODEProps, 'repoPath'>>) => string
|
toCODEPipelines: (args: Required<Pick<CODEProps, 'repoPath'>>) => string
|
||||||
toCODEPipelineEdit: (args: Required<Pick<CODEProps, 'repoPath' | 'pipeline'>>) => string
|
toCODEPipelineEdit: (args: Required<Pick<CODEProps, 'repoPath' | 'pipeline'>>) => string
|
||||||
|
toCODEPipelineSettings: (args: Required<Pick<CODEProps, 'repoPath' | 'pipeline'>>) => string
|
||||||
toCODESecrets: (args: Required<Pick<CODEProps, 'space'>>) => string
|
toCODESecrets: (args: Required<Pick<CODEProps, 'space'>>) => string
|
||||||
|
|
||||||
toCODEGlobalSettings: () => string
|
toCODEGlobalSettings: () => string
|
||||||
@ -98,6 +99,7 @@ export const routes: CODERoutes = {
|
|||||||
toCODESpaceSettings: ({ space }) => `/settings/${space}`,
|
toCODESpaceSettings: ({ space }) => `/settings/${space}`,
|
||||||
toCODEPipelines: ({ repoPath }) => `/${repoPath}/pipelines`,
|
toCODEPipelines: ({ repoPath }) => `/${repoPath}/pipelines`,
|
||||||
toCODEPipelineEdit: ({ repoPath, pipeline }) => `/${repoPath}/pipelines/${pipeline}/edit`,
|
toCODEPipelineEdit: ({ repoPath, pipeline }) => `/${repoPath}/pipelines/${pipeline}/edit`,
|
||||||
|
toCODEPipelineSettings: ({ repoPath, pipeline }) => `/${repoPath}/pipelines/${pipeline}/triggers`,
|
||||||
toCODESecrets: ({ space }) => `/secrets/${space}`,
|
toCODESecrets: ({ space }) => `/secrets/${space}`,
|
||||||
|
|
||||||
toCODEGlobalSettings: () => '/settings',
|
toCODEGlobalSettings: () => '/settings',
|
||||||
|
@ -33,6 +33,7 @@ import Secret from 'pages/Secret/Secret'
|
|||||||
import Search from 'pages/Search/Search'
|
import Search from 'pages/Search/Search'
|
||||||
import AddUpdatePipeline from 'pages/AddUpdatePipeline/AddUpdatePipeline'
|
import AddUpdatePipeline from 'pages/AddUpdatePipeline/AddUpdatePipeline'
|
||||||
import { useAppContext } from 'AppContext'
|
import { useAppContext } from 'AppContext'
|
||||||
|
import PipelineSettings from 'components/PipelineSettings/PipelineSettings'
|
||||||
|
|
||||||
export const RouteDestinations: React.FC = React.memo(function RouteDestinations() {
|
export const RouteDestinations: React.FC = React.memo(function RouteDestinations() {
|
||||||
const { getString } = useStrings()
|
const { getString } = useStrings()
|
||||||
@ -194,6 +195,14 @@ export const RouteDestinations: React.FC = React.memo(function RouteDestinations
|
|||||||
</Route>
|
</Route>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{standalone && (
|
||||||
|
<Route path={routes.toCODEPipelineSettings({ repoPath, pipeline: pathProps.pipeline })} exact>
|
||||||
|
<LayoutWithSideNav title={getString('pageTitle.pipelines')}>
|
||||||
|
<PipelineSettings />
|
||||||
|
</LayoutWithSideNav>
|
||||||
|
</Route>
|
||||||
|
)}
|
||||||
|
|
||||||
{standalone && (
|
{standalone && (
|
||||||
<Route path={routes.toCODEPipelines({ repoPath })} exact>
|
<Route path={routes.toCODEPipelines({ repoPath })} exact>
|
||||||
<LayoutWithSideNav title={getString('pageTitle.pipelines')}>
|
<LayoutWithSideNav title={getString('pageTitle.pipelines')}>
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
.main {
|
||||||
|
min-height: var(--page-height);
|
||||||
|
background-color: var(--primary-bg) !important;
|
||||||
|
|
||||||
|
.layout {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.generalContainer {
|
||||||
|
width: 100%;
|
||||||
|
background: var(--grey-0) !important;
|
||||||
|
box-shadow: 0px 0px 1px rgba(40, 41, 61, 0.08), 0px 0.5px 2px rgba(96, 97, 112, 0.16);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yellowContainer {
|
||||||
|
background: var(--yellow-100) !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textContainer {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.withError {
|
||||||
|
display: grid;
|
||||||
|
}
|
8
web/src/components/PipelineSettings/PipelineSettings.module.scss.d.ts
vendored
Normal file
8
web/src/components/PipelineSettings/PipelineSettings.module.scss.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// This is an auto-generated file
|
||||||
|
export declare const generalContainer: string
|
||||||
|
export declare const layout: string
|
||||||
|
export declare const main: string
|
||||||
|
export declare const textContainer: string
|
||||||
|
export declare const withError: string
|
||||||
|
export declare const yellowContainer: string
|
247
web/src/components/PipelineSettings/PipelineSettings.tsx
Normal file
247
web/src/components/PipelineSettings/PipelineSettings.tsx
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonVariation,
|
||||||
|
Container,
|
||||||
|
FormInput,
|
||||||
|
Formik,
|
||||||
|
FormikForm,
|
||||||
|
Layout,
|
||||||
|
PageBody,
|
||||||
|
Text,
|
||||||
|
useToaster
|
||||||
|
} from '@harnessio/uicore'
|
||||||
|
import React from 'react'
|
||||||
|
import { useHistory, useParams } from 'react-router-dom'
|
||||||
|
import { Color, Intent } from '@harnessio/design-system'
|
||||||
|
import { useGet, useMutate } from 'restful-react'
|
||||||
|
import cx from 'classnames'
|
||||||
|
import * as yup from 'yup'
|
||||||
|
import PipelineSettingsPageHeader from 'components/PipelineSettingsPageHeader/PipelineSettingsPageHeader'
|
||||||
|
import { String, useStrings } from 'framework/strings'
|
||||||
|
import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
|
||||||
|
import { routes, type CODEProps } from 'RouteDefinitions'
|
||||||
|
import { useConfirmAct } from 'hooks/useConfirmAction'
|
||||||
|
import { getErrorMessage, voidFn } from 'utils/Utils'
|
||||||
|
import type { OpenapiUpdatePipelineRequest, TypesPipeline } from 'services/code'
|
||||||
|
import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner'
|
||||||
|
import css from './PipelineSettings.module.scss'
|
||||||
|
|
||||||
|
export enum TabOptions {
|
||||||
|
SETTINGS = 'Settings',
|
||||||
|
TRIGGERS = 'Triggers'
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SettingsContentProps {
|
||||||
|
pipeline: string
|
||||||
|
repoPath: string
|
||||||
|
yamlPath: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SettingsFormData {
|
||||||
|
name: string
|
||||||
|
yamlPath: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const SettingsContent = ({ pipeline, repoPath, yamlPath }: SettingsContentProps) => {
|
||||||
|
const { getString } = useStrings()
|
||||||
|
const { mutate: updatePipeline } = useMutate<TypesPipeline>({
|
||||||
|
verb: 'PATCH',
|
||||||
|
path: `/api/v1/repos/${repoPath}/+/pipelines/${pipeline}`
|
||||||
|
})
|
||||||
|
const { mutate: deletePipeline } = useMutate<TypesPipeline>({
|
||||||
|
verb: 'DELETE',
|
||||||
|
path: `/api/v1/repos/${repoPath}/+/pipelines/${pipeline}`
|
||||||
|
})
|
||||||
|
const { showSuccess, showError } = useToaster()
|
||||||
|
const confirmDeletePipeline = useConfirmAct()
|
||||||
|
const history = useHistory()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout.Vertical padding={'medium'} spacing={'medium'}>
|
||||||
|
<Container padding={'large'} className={css.generalContainer}>
|
||||||
|
<Formik<SettingsFormData>
|
||||||
|
initialValues={{
|
||||||
|
name: pipeline,
|
||||||
|
yamlPath
|
||||||
|
}}
|
||||||
|
formName="pipelineSettings"
|
||||||
|
enableReinitialize={true}
|
||||||
|
validationSchema={yup.object().shape({
|
||||||
|
name: yup
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.required(`${getString('name')} ${getString('isRequired')}`),
|
||||||
|
yamlPath: yup
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.required(`${getString('pipelines.yamlPath')} ${getString('isRequired')}`)
|
||||||
|
})}
|
||||||
|
validateOnChange
|
||||||
|
validateOnBlur
|
||||||
|
onSubmit={async formData => {
|
||||||
|
const { name, yamlPath: newYamlPath } = formData
|
||||||
|
try {
|
||||||
|
const payload: OpenapiUpdatePipelineRequest = {
|
||||||
|
config_path: newYamlPath,
|
||||||
|
uid: name
|
||||||
|
}
|
||||||
|
await updatePipeline(payload, {
|
||||||
|
pathParams: { path: `/api/v1/repos/${repoPath}/+/pipelines/${pipeline}` }
|
||||||
|
})
|
||||||
|
history.push(
|
||||||
|
routes.toCODEPipelineSettings({
|
||||||
|
repoPath,
|
||||||
|
pipeline: name
|
||||||
|
})
|
||||||
|
)
|
||||||
|
showSuccess(getString('pipelines.updatePipelineSuccess', { pipeline }))
|
||||||
|
} catch (exception) {
|
||||||
|
showError(getErrorMessage(exception), 0, 'pipelines.failedToUpdatePipeline')
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
{() => {
|
||||||
|
return (
|
||||||
|
<FormikForm>
|
||||||
|
<Layout.Vertical spacing={'large'}>
|
||||||
|
<Layout.Horizontal spacing={'large'} flex={{ alignItems: 'center', justifyContent: 'flex-start' }}>
|
||||||
|
<FormInput.Text
|
||||||
|
name="name"
|
||||||
|
className={css.textContainer}
|
||||||
|
label={
|
||||||
|
<Text color={Color.GREY_800} font={{ size: 'small' }}>
|
||||||
|
{getString('name')}
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Layout.Horizontal>
|
||||||
|
<Layout.Horizontal spacing={'large'} flex={{ alignItems: 'center', justifyContent: 'flex-start' }}>
|
||||||
|
<FormInput.Text
|
||||||
|
name="yamlPath"
|
||||||
|
className={css.textContainer}
|
||||||
|
label={
|
||||||
|
<Text color={Color.GREY_800} font={{ size: 'small' }}>
|
||||||
|
{getString('pipelines.yamlPath')}
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Layout.Horizontal>
|
||||||
|
<Layout.Horizontal spacing={'large'}>
|
||||||
|
<Button intent={Intent.PRIMARY} type="submit" text={getString('save')} />
|
||||||
|
<Button variation={ButtonVariation.TERTIARY} type="reset" text={getString('cancel')} />
|
||||||
|
</Layout.Horizontal>
|
||||||
|
</Layout.Vertical>
|
||||||
|
</FormikForm>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</Formik>
|
||||||
|
</Container>
|
||||||
|
<Container padding={'large'} className={css.generalContainer}>
|
||||||
|
<Layout.Vertical>
|
||||||
|
<Text icon="main-trash" color={Color.GREY_600} font={{ size: 'normal' }}>
|
||||||
|
{getString('dangerDeleteRepo')}
|
||||||
|
</Text>
|
||||||
|
<Layout.Horizontal padding={{ top: 'medium', left: 'medium' }} flex={{ justifyContent: 'space-between' }}>
|
||||||
|
<Container intent="warning" padding={'small'} className={css.yellowContainer}>
|
||||||
|
<Text
|
||||||
|
icon="main-issue"
|
||||||
|
iconProps={{ size: 18, color: Color.ORANGE_700, margin: { right: 'small' } }}
|
||||||
|
color={Color.WARNING}>
|
||||||
|
{getString('pipelines.deletePipelineWarning', {
|
||||||
|
pipeline
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
|
</Container>
|
||||||
|
<Button
|
||||||
|
margin={{ right: 'medium' }}
|
||||||
|
intent={Intent.DANGER}
|
||||||
|
onClick={() => {
|
||||||
|
confirmDeletePipeline({
|
||||||
|
title: getString('pipelines.deletePipelineButton'),
|
||||||
|
confirmText: getString('delete'),
|
||||||
|
intent: Intent.DANGER,
|
||||||
|
message: <String useRichText stringID="pipelines.deletePipelineConfirm" vars={{ pipeline }} />,
|
||||||
|
action: async () => {
|
||||||
|
try {
|
||||||
|
await deletePipeline(null)
|
||||||
|
history.push(
|
||||||
|
routes.toCODEPipelines({
|
||||||
|
repoPath
|
||||||
|
})
|
||||||
|
)
|
||||||
|
showSuccess(getString('pipelines.deletePipelineSuccess', { pipeline }))
|
||||||
|
} catch (e) {
|
||||||
|
showError(getString('pipelines.deletePipelineError'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
variation={ButtonVariation.PRIMARY}
|
||||||
|
text={getString('pipelines.deletePipelineButton')}></Button>
|
||||||
|
</Layout.Horizontal>
|
||||||
|
</Layout.Vertical>
|
||||||
|
</Container>
|
||||||
|
</Layout.Vertical>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const TriggersContent = () => {
|
||||||
|
return <div>Triggers</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const PipelineSettings = () => {
|
||||||
|
const { getString } = useStrings()
|
||||||
|
|
||||||
|
const { pipeline } = useParams<CODEProps>()
|
||||||
|
const { repoMetadata, error, loading, refetch } = useGetRepositoryMetadata()
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: pipelineData,
|
||||||
|
error: pipelineError,
|
||||||
|
loading: pipelineLoading
|
||||||
|
} = useGet<TypesPipeline>({
|
||||||
|
path: `/api/v1/repos/${repoMetadata?.path}/+/pipelines/${pipeline}`,
|
||||||
|
lazy: !repoMetadata
|
||||||
|
})
|
||||||
|
|
||||||
|
const [selectedTab, setSelectedTab] = React.useState<TabOptions>(TabOptions.SETTINGS)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container className={css.main}>
|
||||||
|
<PipelineSettingsPageHeader
|
||||||
|
repoMetadata={repoMetadata}
|
||||||
|
title={`${pipeline} settings`}
|
||||||
|
dataTooltipId="pipelineSettings"
|
||||||
|
selectedTab={selectedTab}
|
||||||
|
setSelectedTab={setSelectedTab}
|
||||||
|
extraBreadcrumbLinks={
|
||||||
|
repoMetadata && [
|
||||||
|
{
|
||||||
|
label: getString('pageTitle.pipelines'),
|
||||||
|
url: routes.toCODEPipelines({ repoPath: repoMetadata.path as string })
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: pipeline as string,
|
||||||
|
url: routes.toCODEExecutions({ repoPath: repoMetadata.path as string, pipeline: pipeline as string })
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<PageBody
|
||||||
|
className={cx({ [css.withError]: !!error })}
|
||||||
|
error={error ? getErrorMessage(error || pipelineError) : null}
|
||||||
|
retryOnError={voidFn(refetch)}>
|
||||||
|
<LoadingSpinner visible={loading || pipelineLoading} withBorder={!!pipeline} />
|
||||||
|
{selectedTab === TabOptions.SETTINGS && (
|
||||||
|
<SettingsContent
|
||||||
|
pipeline={pipeline as string}
|
||||||
|
repoPath={repoMetadata?.path as string}
|
||||||
|
yamlPath={pipelineData?.config_path as string}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{selectedTab === TabOptions.TRIGGERS && <TriggersContent />}
|
||||||
|
</PageBody>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PipelineSettings
|
@ -0,0 +1,31 @@
|
|||||||
|
.pageHeader {
|
||||||
|
height: auto !important;
|
||||||
|
flex-direction: column !important;
|
||||||
|
align-items: flex-start !important;
|
||||||
|
gap: var(--spacing-small) !important;
|
||||||
|
padding-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb {
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
color: var(--primary-7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
display: flex !important;
|
||||||
|
gap: 1rem !important;
|
||||||
|
.tab {
|
||||||
|
padding: 0.5rem 1rem !important;
|
||||||
|
cursor: pointer !important;
|
||||||
|
color: var(--grey-700) !important;
|
||||||
|
&.active {
|
||||||
|
color: var(--grey-900) !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
|
border-bottom: 2px solid var(--primary-7) !important; // example of an active tab indicator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
web/src/components/PipelineSettingsPageHeader/PipelineSettingsPageHeader.module.scss.d.ts
vendored
Normal file
7
web/src/components/PipelineSettingsPageHeader/PipelineSettingsPageHeader.module.scss.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// This is an auto-generated file
|
||||||
|
export declare const active: string
|
||||||
|
export declare const breadcrumb: string
|
||||||
|
export declare const pageHeader: string
|
||||||
|
export declare const tab: string
|
||||||
|
export declare const tabs: string
|
@ -0,0 +1,82 @@
|
|||||||
|
import React, { Fragment } from 'react'
|
||||||
|
import { Layout, PageHeader, Container } from '@harnessio/uicore'
|
||||||
|
import { Icon } from '@harnessio/icons'
|
||||||
|
import { Color } from '@harnessio/design-system'
|
||||||
|
import { Link, useParams } from 'react-router-dom'
|
||||||
|
import { useStrings } from 'framework/strings'
|
||||||
|
import { useAppContext } from 'AppContext'
|
||||||
|
import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
|
||||||
|
import type { CODEProps } from 'RouteDefinitions'
|
||||||
|
import type { GitInfoProps } from 'utils/GitUtils'
|
||||||
|
import { TabOptions } from 'components/PipelineSettings/PipelineSettings'
|
||||||
|
import css from './PipelineSettingsPageHeader.module.scss'
|
||||||
|
|
||||||
|
interface BreadcrumbLink {
|
||||||
|
label: string
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PipelineSettingsPageHeaderProps extends Optional<Pick<GitInfoProps, 'repoMetadata'>, 'repoMetadata'> {
|
||||||
|
title: string | JSX.Element
|
||||||
|
dataTooltipId: string
|
||||||
|
extraBreadcrumbLinks?: BreadcrumbLink[]
|
||||||
|
selectedTab: TabOptions
|
||||||
|
setSelectedTab: (tab: TabOptions) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const PipelineSettingsPageHeader = ({
|
||||||
|
repoMetadata,
|
||||||
|
title,
|
||||||
|
extraBreadcrumbLinks = [],
|
||||||
|
selectedTab,
|
||||||
|
setSelectedTab
|
||||||
|
}: PipelineSettingsPageHeaderProps) => {
|
||||||
|
const { gitRef } = useParams<CODEProps>()
|
||||||
|
const { getString } = useStrings()
|
||||||
|
const space = useGetSpaceParam()
|
||||||
|
const { routes } = useAppContext()
|
||||||
|
|
||||||
|
if (!repoMetadata) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageHeader
|
||||||
|
className={css.pageHeader}
|
||||||
|
title={title}
|
||||||
|
breadcrumbs={
|
||||||
|
<Layout.Horizontal
|
||||||
|
spacing="small"
|
||||||
|
className={css.breadcrumb}
|
||||||
|
padding={{ bottom: 0 }}
|
||||||
|
margin={{ bottom: 'small' }}>
|
||||||
|
<Link to={routes.toCODERepositories({ space })}>{getString('repositories')}</Link>
|
||||||
|
<Icon name="main-chevron-right" size={8} color={Color.GREY_500} />
|
||||||
|
<Link to={routes.toCODERepository({ repoPath: repoMetadata.path as string, gitRef })}>
|
||||||
|
{repoMetadata.uid}
|
||||||
|
</Link>
|
||||||
|
{extraBreadcrumbLinks.map(link => (
|
||||||
|
<Fragment key={link.url}>
|
||||||
|
<Icon name="main-chevron-right" size={8} color={Color.GREY_500} />
|
||||||
|
<Link to={link.url}>{link.label}</Link>
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</Layout.Horizontal>
|
||||||
|
}
|
||||||
|
content={
|
||||||
|
<Container className={css.tabs}>
|
||||||
|
{Object.values(TabOptions).map(tabOption => (
|
||||||
|
<div
|
||||||
|
key={tabOption}
|
||||||
|
className={`${css.tab} ${selectedTab === tabOption ? css.active : ''}`}
|
||||||
|
onClick={() => setSelectedTab(tabOption)}>
|
||||||
|
{tabOption}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</Container>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PipelineSettingsPageHeader
|
@ -327,12 +327,18 @@ export interface StringsMap {
|
|||||||
pending: string
|
pending: string
|
||||||
'pipelines.createNewPipeline': string
|
'pipelines.createNewPipeline': string
|
||||||
'pipelines.created': string
|
'pipelines.created': string
|
||||||
|
'pipelines.deletePipelineButton': string
|
||||||
|
'pipelines.deletePipelineConfirm': string
|
||||||
|
'pipelines.deletePipelineError': string
|
||||||
|
'pipelines.deletePipelineSuccess': string
|
||||||
|
'pipelines.deletePipelineWarning': string
|
||||||
'pipelines.editPipeline': string
|
'pipelines.editPipeline': string
|
||||||
'pipelines.enterPipelineName': string
|
'pipelines.enterPipelineName': string
|
||||||
'pipelines.enterYAMLPath': string
|
'pipelines.enterYAMLPath': string
|
||||||
'pipelines.executionCouldNotStart': string
|
'pipelines.executionCouldNotStart': string
|
||||||
'pipelines.executionStarted': string
|
'pipelines.executionStarted': string
|
||||||
'pipelines.failedToCreatePipeline': string
|
'pipelines.failedToCreatePipeline': string
|
||||||
|
'pipelines.failedToUpdatePipeline': string
|
||||||
'pipelines.lastExecution': string
|
'pipelines.lastExecution': string
|
||||||
'pipelines.name': string
|
'pipelines.name': string
|
||||||
'pipelines.newPipelineButton': string
|
'pipelines.newPipelineButton': string
|
||||||
@ -340,6 +346,7 @@ export interface StringsMap {
|
|||||||
'pipelines.run': string
|
'pipelines.run': string
|
||||||
'pipelines.saveAndRun': string
|
'pipelines.saveAndRun': string
|
||||||
'pipelines.time': string
|
'pipelines.time': string
|
||||||
|
'pipelines.updatePipelineSuccess': string
|
||||||
'pipelines.updated': string
|
'pipelines.updated': string
|
||||||
'pipelines.yamlPath': string
|
'pipelines.yamlPath': string
|
||||||
'plugins.addAPlugin': string
|
'plugins.addAPlugin': string
|
||||||
|
@ -644,6 +644,13 @@ pipelines:
|
|||||||
updated: Pipeline updated successfully
|
updated: Pipeline updated successfully
|
||||||
executionStarted: Pipeline execution started successfully
|
executionStarted: Pipeline execution started successfully
|
||||||
executionCouldNotStart: Failure while starting Pipeline execution
|
executionCouldNotStart: Failure while starting Pipeline execution
|
||||||
|
deletePipelineWarning: This will permanently delete the {{pipeline}} pipeline and all executions.
|
||||||
|
deletePipelineButton: Delete pipeline
|
||||||
|
deletePipelineConfirm: Are you sure you want to delete the pipeline <strong>{{pipeline}}</strong>? You can't undo this action.
|
||||||
|
deletePipelineSuccess: Pipeline {{pipeline}} deleted.
|
||||||
|
deletePipelineError: Failed to delete Pipeline. Please try again.
|
||||||
|
updatePipelineSuccess: Pipeline {{pipeline}} updated.
|
||||||
|
failedToUpdatePipeline: Failed to update Pipeline. Please try again.
|
||||||
executions:
|
executions:
|
||||||
noData: There are no executions
|
noData: There are no executions
|
||||||
newExecutionButton: Run Pipeline
|
newExecutionButton: Run Pipeline
|
||||||
|
@ -127,6 +127,15 @@ export const DefaultMenu: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<NavMenuItem
|
||||||
|
data-code-repo-section="settings"
|
||||||
|
isSubLink
|
||||||
|
label={getString('settings')}
|
||||||
|
to={routes.toCODESettings({
|
||||||
|
repoPath
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
|
||||||
{!standalone && (
|
{!standalone && (
|
||||||
<NavMenuItem
|
<NavMenuItem
|
||||||
data-code-repo-section="search"
|
data-code-repo-section="search"
|
||||||
|
@ -65,7 +65,7 @@ const Execution = () => {
|
|||||||
<Container className={css.main}>
|
<Container className={css.main}>
|
||||||
<ExecutionPageHeader
|
<ExecutionPageHeader
|
||||||
repoMetadata={repoMetadata}
|
repoMetadata={repoMetadata}
|
||||||
title={execution?.title as string}
|
title={pipeline as string}
|
||||||
dataTooltipId="repositoryExecution"
|
dataTooltipId="repositoryExecution"
|
||||||
extraBreadcrumbLinks={
|
extraBreadcrumbLinks={
|
||||||
repoMetadata && [
|
repoMetadata && [
|
||||||
|
@ -233,13 +233,23 @@ const PipelineList = () => {
|
|||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<MenuItem
|
||||||
|
icon="settings"
|
||||||
|
text={getString('settings')}
|
||||||
|
onClick={e => {
|
||||||
|
e.stopPropagation()
|
||||||
|
history.push(
|
||||||
|
routes.toCODEPipelineSettings({ repoPath: repoMetadata?.path || '', pipeline: uid as string })
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Menu>
|
</Menu>
|
||||||
</Popover>
|
</Popover>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[getString, repoMetadata?.path, routes, searchTerm]
|
[getString, history, repoMetadata?.path, routes, searchTerm]
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -251,7 +261,7 @@ const PipelineList = () => {
|
|||||||
/>
|
/>
|
||||||
<PageBody
|
<PageBody
|
||||||
className={cx({ [css.withError]: !!error })}
|
className={cx({ [css.withError]: !!error })}
|
||||||
error={error ? getErrorMessage(error || pipelinesError) : null}
|
error={error || pipelinesError ? getErrorMessage(error || pipelinesError) : null}
|
||||||
retryOnError={voidFn(refetch)}
|
retryOnError={voidFn(refetch)}
|
||||||
noData={{
|
noData={{
|
||||||
when: () => pipelines?.length === 0 && searchTerm === undefined,
|
when: () => pipelines?.length === 0 && searchTerm === undefined,
|
||||||
|
Loading…
Reference in New Issue
Block a user