mirror of
https://github.com/harness/drone.git
synced 2025-05-21 11:29:52 +08:00
feat: create repo from gitspace (#2157)
This commit is contained in:
parent
ceb86704be
commit
37cce5c8a4
@ -52,8 +52,8 @@ import AddUpdatePipeline from 'pages/AddUpdatePipeline/AddUpdatePipeline'
|
||||
import { useAppContext } from 'AppContext'
|
||||
import PipelineSettings from 'components/PipelineSettings/PipelineSettings'
|
||||
import GitspaceDetail from 'cde/pages/GitspaceDetail/GitspaceDetail'
|
||||
import Gitspaces from 'cde/pages/Gitspaces/Gitspaces'
|
||||
import GitspacesListing from 'cde/pages/GitspacesListing/GitspacesListing'
|
||||
import { GitspaceListing } from 'cde-gitness/pages/GitspaceListing/GitspaceListing'
|
||||
import { GitspaceCreate } from 'cde-gitness/pages/GitspaceCreate/GitspaceCreate'
|
||||
|
||||
export const RouteDestinations: React.FC = React.memo(function RouteDestinations() {
|
||||
const { getString } = useStrings()
|
||||
@ -267,7 +267,15 @@ export const RouteDestinations: React.FC = React.memo(function RouteDestinations
|
||||
{standalone && (
|
||||
<Route exact path={routes.toCDEGitspacesEdit({ space: pathProps.space, gitspaceId: pathProps.gitspaceId })}>
|
||||
<LayoutWithSideNav title={getString('cde.gitspaces')}>
|
||||
<Gitspaces />
|
||||
<GitspaceCreate />
|
||||
</LayoutWithSideNav>
|
||||
</Route>
|
||||
)}
|
||||
|
||||
{standalone && (
|
||||
<Route path={routes.toCDEGitspacesCreate({ space: pathProps.space })}>
|
||||
<LayoutWithSideNav title={getString('cde.gitspaces')}>
|
||||
<GitspaceCreate />
|
||||
</LayoutWithSideNav>
|
||||
</Route>
|
||||
)}
|
||||
@ -283,15 +291,7 @@ export const RouteDestinations: React.FC = React.memo(function RouteDestinations
|
||||
{standalone && (
|
||||
<Route path={routes.toCDEGitspaces({ space: pathProps.space })}>
|
||||
<LayoutWithSideNav title={getString('cde.gitspaces')}>
|
||||
<Gitspaces />
|
||||
</LayoutWithSideNav>
|
||||
</Route>
|
||||
)}
|
||||
|
||||
{standalone && (
|
||||
<Route path={routes.toCDEGitspacesCreate({ space: pathProps.space })}>
|
||||
<LayoutWithSideNav title={getString('cde.gitspaces')}>
|
||||
<GitspacesListing />
|
||||
<GitspaceListing />
|
||||
</LayoutWithSideNav>
|
||||
</Route>
|
||||
)}
|
||||
|
@ -0,0 +1,3 @@
|
||||
.repoAndBranch {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
19
web/src/cde-gitness/components/GitnessRepoImportForm/GitnessRepoImportForm.module.scss.d.ts
vendored
Normal file
19
web/src/cde-gitness/components/GitnessRepoImportForm/GitnessRepoImportForm.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 repoAndBranch: string
|
@ -0,0 +1,226 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useGet } from 'restful-react'
|
||||
import { Container, ExpandingSearchInput, Layout, Text } from '@harnessio/uicore'
|
||||
import { Menu, MenuItem } from '@blueprintjs/core'
|
||||
import { Color } from '@harnessio/design-system'
|
||||
import { Icon } from '@harnessio/icons'
|
||||
import { useFormikContext } from 'formik'
|
||||
import type { TypesRepository } from 'services/code'
|
||||
import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
|
||||
import { String, useStrings } from 'framework/strings'
|
||||
import { LIST_FETCHING_LIMIT } from 'utils/Utils'
|
||||
import NewRepoModalButton from 'components/NewRepoModalButton/NewRepoModalButton'
|
||||
import { GitspaceSelect } from '../../../cde/components/GitspaceSelect/GitspaceSelect'
|
||||
import gitnessRepoLogo from './gitness.svg?url'
|
||||
import css from './GitnessRepoImportForm.module.scss'
|
||||
|
||||
const RepositoryText = ({ repoList, value }: { repoList: TypesRepository[] | null; value?: string }) => {
|
||||
const { getString } = useStrings()
|
||||
const repoMetadata = repoList?.find(repo => repo.git_url === value)
|
||||
const repoName = repoMetadata?.path
|
||||
|
||||
return (
|
||||
<Layout.Horizontal spacing={'medium'} flex={{ justifyContent: 'flex-start', alignItems: 'center' }}>
|
||||
<img src={gitnessRepoLogo} height={24} width={24} />
|
||||
{repoName ? (
|
||||
<Container margin={{ left: 'medium' }}>
|
||||
<Layout.Vertical spacing="xsmall">
|
||||
<Text font={'normal'}>{getString('cde.repository.repo')}</Text>
|
||||
<Text color={Color.BLACK} font={'small'} lineClamp={1}>
|
||||
{repoName || getString('cde.repository.repositoryURL')}
|
||||
</Text>
|
||||
</Layout.Vertical>
|
||||
</Container>
|
||||
) : (
|
||||
<Text font={'normal'}>{getString('cde.repository.selectRepository')}</Text>
|
||||
)}
|
||||
</Layout.Horizontal>
|
||||
)
|
||||
}
|
||||
|
||||
const BranchText = ({ value }: { value?: string }) => {
|
||||
const { getString } = useStrings()
|
||||
return (
|
||||
<Layout.Horizontal spacing={'medium'} flex={{ justifyContent: 'flex-start', alignItems: 'center' }}>
|
||||
<Icon name={'git-branch'} size={24} />
|
||||
{value ? (
|
||||
<Container margin={{ left: 'medium' }}>
|
||||
<Layout.Vertical spacing="xsmall">
|
||||
<Text font={'normal'}>{getString('branch')}</Text>
|
||||
<Text color={Color.BLACK} font={'small'} lineClamp={1}>
|
||||
{value}
|
||||
</Text>
|
||||
</Layout.Vertical>
|
||||
</Container>
|
||||
) : (
|
||||
<Text font={'normal'}>{getString('cde.create.selectBranchPlaceholder')}</Text>
|
||||
)}
|
||||
</Layout.Horizontal>
|
||||
)
|
||||
}
|
||||
|
||||
export const GitnessRepoImportForm = () => {
|
||||
const { getString } = useStrings()
|
||||
const space = useGetSpaceParam()
|
||||
const [branchSearch, setBranchSearch] = useState('')
|
||||
const [repoSearch, setRepoSearch] = useState('')
|
||||
const [repoRef, setReporef] = useState('')
|
||||
|
||||
const {
|
||||
data: repositories,
|
||||
loading,
|
||||
refetch: refetchRepos
|
||||
} = useGet<TypesRepository[]>({
|
||||
path: `/api/v1/spaces/${space}/+/repos`,
|
||||
queryParams: { query: repoSearch },
|
||||
debounce: 500
|
||||
})
|
||||
|
||||
const {
|
||||
data: branches,
|
||||
refetch,
|
||||
loading: loadingBranches
|
||||
} = useGet<{ name: string }[]>({
|
||||
path: `/api/v1/repos/${repoRef}/+/branches`,
|
||||
queryParams: {
|
||||
limit: LIST_FETCHING_LIMIT,
|
||||
page: 1,
|
||||
sort: 'date',
|
||||
order: 'desc',
|
||||
include_commit: false,
|
||||
query: branchSearch
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (repoRef || branchSearch) {
|
||||
refetch()
|
||||
}
|
||||
}, [repoRef, branchSearch])
|
||||
|
||||
const repoListOptions = repositories || []
|
||||
|
||||
const formik = useFormikContext<any>()
|
||||
|
||||
const { values } = formik
|
||||
const repoMetadata = repoListOptions.find(repo => repo.git_url === values.code_repo_url)
|
||||
if (repoRef !== repoMetadata?.path) {
|
||||
setReporef(repoMetadata?.path as string)
|
||||
}
|
||||
|
||||
return (
|
||||
<Container flex={{ justifyContent: 'space-between', alignItems: 'baseline' }}>
|
||||
<Container width={'63%'}>
|
||||
<GitspaceSelect
|
||||
loading={loading}
|
||||
formikName="code_repo_url"
|
||||
formInputClassName={css.repoAndBranch}
|
||||
text={<RepositoryText value={values.code_repo_url} repoList={repositories} />}
|
||||
tooltipProps={{
|
||||
onClose: () => {
|
||||
setRepoSearch('')
|
||||
}
|
||||
}}
|
||||
renderMenu={
|
||||
<Menu>
|
||||
<Container margin={'small'}>
|
||||
<ExpandingSearchInput
|
||||
placeholder={getString('cde.create.searchRepositoryPlaceholder')}
|
||||
alwaysExpanded
|
||||
autoFocus={false}
|
||||
defaultValue={repoSearch}
|
||||
onChange={setRepoSearch}
|
||||
/>
|
||||
</Container>
|
||||
{loading ? (
|
||||
<MenuItem disabled text={getString('loading')} />
|
||||
) : repoListOptions?.length ? (
|
||||
repoListOptions.map(repo => (
|
||||
<MenuItem
|
||||
key={repo.path}
|
||||
text={
|
||||
<Layout.Horizontal spacing="medium">
|
||||
<img src={gitnessRepoLogo} height={16} width={16} />
|
||||
<Text>{repo.path}</Text>
|
||||
</Layout.Horizontal>
|
||||
}
|
||||
active={repo.git_url === values.code_repo_url}
|
||||
onClick={() => {
|
||||
formik.setValues((prvValues: any) => {
|
||||
return {
|
||||
...prvValues,
|
||||
code_repo_url: repo.git_url,
|
||||
id: repo.path,
|
||||
name: repo.path
|
||||
}
|
||||
})
|
||||
formik.setFieldValue('code_repo_url', repo.git_url)
|
||||
}}
|
||||
/>
|
||||
))
|
||||
) : (
|
||||
<Container>
|
||||
<NewRepoModalButton
|
||||
space={space}
|
||||
newRepoModalOnly
|
||||
notFoundRepoName={repoSearch}
|
||||
modalTitle={getString('createRepo')}
|
||||
onSubmit={() => {
|
||||
refetchRepos()
|
||||
}}
|
||||
/>
|
||||
</Container>
|
||||
)}
|
||||
</Menu>
|
||||
}
|
||||
/>
|
||||
</Container>
|
||||
<Container width={'35%'}>
|
||||
<GitspaceSelect
|
||||
formikName="branch"
|
||||
loading={loadingBranches}
|
||||
disabled={!values.code_repo_url}
|
||||
formInputClassName={css.repoAndBranch}
|
||||
text={<BranchText value={values.branch} />}
|
||||
tooltipProps={{
|
||||
onClose: () => {
|
||||
setBranchSearch('')
|
||||
}
|
||||
}}
|
||||
renderMenu={
|
||||
<Menu>
|
||||
<Container margin={'small'}>
|
||||
<ExpandingSearchInput
|
||||
placeholder={getString('cde.create.searchBranchPlaceholder')}
|
||||
alwaysExpanded
|
||||
autoFocus={false}
|
||||
defaultValue={branchSearch}
|
||||
onChange={setBranchSearch}
|
||||
/>
|
||||
</Container>
|
||||
{loadingBranches ? (
|
||||
<MenuItem disabled text={getString('loading')} />
|
||||
) : branches?.length ? (
|
||||
branches?.map(branch => (
|
||||
<MenuItem
|
||||
key={branch.name}
|
||||
icon="git-branch"
|
||||
text={branch.name}
|
||||
active={branch.name === values.branch}
|
||||
onClick={() => formik.setFieldValue('branch', branch.name)}
|
||||
/>
|
||||
))
|
||||
) : (
|
||||
<MenuItem
|
||||
icon="warning-sign"
|
||||
text={<String stringID="branchNotFound" vars={{ branch: branchSearch }} useRichText />}
|
||||
/>
|
||||
)}
|
||||
</Menu>
|
||||
}
|
||||
/>
|
||||
</Container>
|
||||
</Container>
|
||||
)
|
||||
}
|
@ -0,0 +1 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 25"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 .482c-6.627 0-12 5.373-12 12s5.373 12 12 12h2.4a1.6 1.6 0 0 0 1.6-1.6v-2.4a4 4 0 0 1 4-4h-4 6.4a1.6 1.6 0 0 0 1.6-1.6v-4.8a1.6 1.6 0 0 0-1.6-1.6h-4.8a1.6 1.6 0 0 0-1.6 1.6v2.4a4 4 0 1 1-4-4h2.4a1.6 1.6 0 0 0 1.6-1.6v-4.8a1.6 1.6 0 0 0-1.6-1.6H12Z" fill="#1B2E49"/></svg>
|
After Width: | Height: | Size: 395 B |
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.table {
|
||||
margin-top: var(--spacing-large);
|
||||
|
||||
div[class*='TableV2--cell'] {
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
div[class*='TableV2--cells'],
|
||||
div[class*='TableV2--header'] {
|
||||
display: grid !important;
|
||||
grid-template-columns: 1fr 1fr 1fr 0.7fr 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.popover {
|
||||
> div[class*='popover-arrow'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.listContainer {
|
||||
:global {
|
||||
a.bp3-menu-item:hover,
|
||||
.bp3-active {
|
||||
background: var(--primary-1) !important;
|
||||
color: var(--grey-1000) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gitspaceURL {
|
||||
white-space: nowrap !important;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.repositoryCell {
|
||||
width: fit-content !important;
|
||||
}
|
23
web/src/cde-gitness/components/GitspaceListing/ListGitspaces.module.scss.d.ts
vendored
Normal file
23
web/src/cde-gitness/components/GitspaceListing/ListGitspaces.module.scss.d.ts
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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 gitspaceUrl: string
|
||||
export declare const listContainer: string
|
||||
export declare const popover: string
|
||||
export declare const repositoryCell: string
|
||||
export declare const table: string
|
505
web/src/cde-gitness/components/GitspaceListing/ListGitspaces.tsx
Normal file
505
web/src/cde-gitness/components/GitspaceListing/ListGitspaces.tsx
Normal file
@ -0,0 +1,505 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import { Container, Layout, TableV2, Text, useToaster } from '@harnessio/uicore'
|
||||
import React from 'react'
|
||||
import { Color } from '@harnessio/design-system'
|
||||
import type { Renderer, CellProps } from 'react-table'
|
||||
import ReactTimeago from 'react-timeago'
|
||||
import {
|
||||
Circle,
|
||||
GitBranch,
|
||||
Cpu,
|
||||
Clock,
|
||||
Play,
|
||||
Square,
|
||||
Db,
|
||||
ModernTv,
|
||||
OpenInBrowser,
|
||||
DeleteCircle,
|
||||
EditPencil,
|
||||
ViewColumns2,
|
||||
GithubCircle,
|
||||
GitLabFull,
|
||||
Code,
|
||||
Bitbucket as BitbucketIcon
|
||||
} from 'iconoir-react'
|
||||
import { Menu, MenuItem, PopoverInteractionKind, Position } from '@blueprintjs/core'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import { isNil } from 'lodash-es'
|
||||
import { UseStringsReturn, useStrings } from 'framework/strings'
|
||||
import { useAppContext } from 'AppContext'
|
||||
import { getErrorMessage } from 'utils/Utils'
|
||||
import { useConfirmAct } from 'hooks/useConfirmAction'
|
||||
import VSCode from 'cde/icons/VSCode.svg?url'
|
||||
import { GitspaceStatus } from 'cde/constants'
|
||||
import {
|
||||
EnumGitspaceStateType,
|
||||
EnumIDEType,
|
||||
useDeleteGitspace,
|
||||
type TypesGitspaceConfig,
|
||||
type EnumCodeRepoType
|
||||
} from 'cde-gitness/services'
|
||||
import css from './ListGitspaces.module.scss'
|
||||
|
||||
enum CodeRepoType {
|
||||
Github = 'github',
|
||||
Gitlab = 'gitlab',
|
||||
HarnessCode = 'harness_code',
|
||||
Bitbucket = 'bitbucket',
|
||||
Unknown = 'unknown'
|
||||
}
|
||||
|
||||
const getIconByRepoType = ({ repoType }: { repoType?: EnumCodeRepoType }): React.ReactNode => {
|
||||
switch (repoType) {
|
||||
case CodeRepoType.Github:
|
||||
return <GithubCircle height={40} />
|
||||
case CodeRepoType.Gitlab:
|
||||
return <GitLabFull height={40} />
|
||||
case CodeRepoType.Bitbucket:
|
||||
return <BitbucketIcon height={40} />
|
||||
default:
|
||||
case CodeRepoType.Unknown:
|
||||
case CodeRepoType.HarnessCode:
|
||||
return <Code height={40} />
|
||||
}
|
||||
}
|
||||
|
||||
export const getStatusColor = (status?: EnumGitspaceStateType) => {
|
||||
switch (status) {
|
||||
case GitspaceStatus.RUNNING:
|
||||
return '#42AB45'
|
||||
case GitspaceStatus.STOPPED:
|
||||
return '#F3F3FA'
|
||||
case GitspaceStatus.ERROR:
|
||||
return '#FF0000'
|
||||
default:
|
||||
return '#000000'
|
||||
}
|
||||
}
|
||||
|
||||
export const getStatusText = (getString: UseStringsReturn['getString'], status?: EnumGitspaceStateType) => {
|
||||
switch (status) {
|
||||
case GitspaceStatus.RUNNING:
|
||||
return getString('cde.listing.online')
|
||||
case GitspaceStatus.STOPPED:
|
||||
return getString('cde.listing.offline')
|
||||
case GitspaceStatus.ERROR:
|
||||
return getString('cde.listing.error')
|
||||
default:
|
||||
return getString('cde.listing.offline')
|
||||
}
|
||||
}
|
||||
|
||||
enum IDEType {
|
||||
VSCODE = 'vs_code',
|
||||
VSCODEWEB = 'vs_code_web'
|
||||
}
|
||||
|
||||
const getUsageTemplate = (
|
||||
getString: UseStringsReturn['getString'],
|
||||
icon: React.ReactNode,
|
||||
resource_usage?: string,
|
||||
total_time_used?: number
|
||||
): React.ReactElement | null => {
|
||||
return (
|
||||
<Layout.Horizontal spacing={'small'} flex={{ alignItems: 'center', justifyContent: 'start' }}>
|
||||
{icon}
|
||||
<Text color={Color.GREY_500} font={{ align: 'left', size: 'normal' }}>
|
||||
{getString('cde.used')} {resource_usage || 0}
|
||||
</Text>
|
||||
<Text>/</Text>
|
||||
<Text color={Color.GREY_500} font={{ align: 'left', size: 'normal' }}>
|
||||
{total_time_used || 0} {getString('cde.hours')}
|
||||
</Text>
|
||||
</Layout.Horizontal>
|
||||
)
|
||||
}
|
||||
|
||||
export const RenderGitspaceName: Renderer<CellProps<TypesGitspaceConfig>> = ({ row }) => {
|
||||
const details = row.original
|
||||
const { name } = details
|
||||
return (
|
||||
<Layout.Horizontal spacing={'small'} flex={{ alignItems: 'center', justifyContent: 'start' }}>
|
||||
<img src={VSCode} height={20} width={20} />
|
||||
<Text color={Color.BLACK} title={name} font={{ align: 'left', size: 'normal', weight: 'semi-bold' }}>
|
||||
{name}
|
||||
</Text>
|
||||
</Layout.Horizontal>
|
||||
)
|
||||
}
|
||||
|
||||
export const RenderRepository: Renderer<CellProps<TypesGitspaceConfig>> = ({ row }) => {
|
||||
const { getString } = useStrings()
|
||||
const details = row.original
|
||||
const { name, branch, code_repo_url, code_repo_type, instance } = details || {}
|
||||
|
||||
return (
|
||||
<Layout.Vertical>
|
||||
<Layout.Horizontal
|
||||
spacing={'small'}
|
||||
className={css.repositoryCell}
|
||||
flex={{ alignItems: 'center', justifyContent: 'start' }}
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
window.open(code_repo_url, '_blank')
|
||||
}}>
|
||||
{getIconByRepoType({ repoType: code_repo_type })}
|
||||
<Text className={css.gitspaceUrl} color={Color.PRIMARY_7} title={name} font={{ align: 'left', size: 'normal' }}>
|
||||
{name}
|
||||
</Text>
|
||||
<Text color={Color.PRIMARY_7}>:</Text>
|
||||
<GitBranch />
|
||||
<Text color={Color.PRIMARY_7} title={name} font={{ align: 'left', size: 'normal' }}>
|
||||
{branch}
|
||||
</Text>
|
||||
</Layout.Horizontal>
|
||||
{(isNil(instance?.tracked_changes) || instance?.tracked_changes === '') && (
|
||||
<Text color={Color.GREY_300} font={{ align: 'left', size: 'small', weight: 'semi-bold' }}>
|
||||
{getString('cde.noChange')}
|
||||
</Text>
|
||||
)}
|
||||
</Layout.Vertical>
|
||||
)
|
||||
}
|
||||
|
||||
export const RenderCPUUsage: Renderer<CellProps<TypesGitspaceConfig>> = ({ row }) => {
|
||||
const { getString } = useStrings()
|
||||
const instance = row.original.instance
|
||||
const { resource_usage, total_time_used } = instance || {}
|
||||
|
||||
return getUsageTemplate(getString, <Cpu />, resource_usage, total_time_used)
|
||||
}
|
||||
|
||||
export const RenderStorageUsage: Renderer<CellProps<TypesGitspaceConfig>> = ({ row }) => {
|
||||
const { getString } = useStrings()
|
||||
const instance = row.original.instance
|
||||
const { resource_usage, total_time_used } = instance || {}
|
||||
|
||||
return getUsageTemplate(getString, <Db />, resource_usage, total_time_used)
|
||||
}
|
||||
|
||||
export const RenderLastActivity: Renderer<CellProps<TypesGitspaceConfig>> = ({ row }) => {
|
||||
const { getString } = useStrings()
|
||||
const instance = row.original.instance
|
||||
const { last_used } = instance || {}
|
||||
return (
|
||||
<Layout.Horizontal spacing={'small'} flex={{ alignItems: 'center', justifyContent: 'start' }}>
|
||||
<Clock />
|
||||
{last_used ? (
|
||||
<ReactTimeago date={last_used} />
|
||||
) : (
|
||||
<Text color={Color.GREY_500} font={{ align: 'left', size: 'normal' }}>
|
||||
{getString('cde.na')}
|
||||
</Text>
|
||||
)}
|
||||
</Layout.Horizontal>
|
||||
)
|
||||
}
|
||||
|
||||
export const RenderGitspaceStatus: Renderer<CellProps<TypesGitspaceConfig>> = ({ row }) => {
|
||||
const { getString } = useStrings()
|
||||
const details = row.original
|
||||
const { instance, name } = details
|
||||
const { state } = instance || {}
|
||||
const color = getStatusColor(state)
|
||||
return (
|
||||
<Layout.Horizontal spacing={'small'} flex={{ alignItems: 'center', justifyContent: 'start' }}>
|
||||
<Circle height={10} width={10} color={color} fill={color} />
|
||||
<Text color={Color.BLACK} title={name} font={{ align: 'left', size: 'normal', weight: 'semi-bold' }}>
|
||||
{getStatusText(getString, state)}
|
||||
</Text>
|
||||
</Layout.Horizontal>
|
||||
)
|
||||
}
|
||||
|
||||
export const StartStopButton = ({ state, loading }: { state?: EnumGitspaceStateType; loading?: boolean }) => {
|
||||
const { getString } = useStrings()
|
||||
return (
|
||||
<Layout.Horizontal spacing="small" flex={{ alignItems: 'center', justifyContent: 'flex-start' }}>
|
||||
{loading ? <></> : state === GitspaceStatus.RUNNING ? <Square /> : <Play />}
|
||||
<Text icon={loading ? 'loading' : undefined}>
|
||||
{state === GitspaceStatus.RUNNING
|
||||
? getString('cde.details.stopGitspace')
|
||||
: getString('cde.details.startGitspace')}
|
||||
</Text>
|
||||
</Layout.Horizontal>
|
||||
)
|
||||
}
|
||||
|
||||
export const OpenGitspaceButton = ({ ide }: { ide?: EnumIDEType }) => {
|
||||
const { getString } = useStrings()
|
||||
|
||||
return (
|
||||
<Layout.Horizontal spacing="small" flex={{ alignItems: 'center', justifyContent: 'flex-start' }}>
|
||||
{ide === IDEType.VSCODE ? <ModernTv /> : <OpenInBrowser />}
|
||||
<Text>{ide === IDEType.VSCODE ? getString('cde.ide.openVSCode') : getString('cde.ide.openBrowser')}</Text>
|
||||
</Layout.Horizontal>
|
||||
)
|
||||
}
|
||||
|
||||
interface ActionMenuProps {
|
||||
data: TypesGitspaceConfig
|
||||
refreshList: () => void
|
||||
handleStartStop?: () => Promise<void>
|
||||
loading?: boolean
|
||||
actionLoading?: boolean
|
||||
deleteLoading?: boolean
|
||||
deleteGitspace: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => Promise<void>
|
||||
}
|
||||
|
||||
const ActionMenu = ({
|
||||
data,
|
||||
deleteGitspace,
|
||||
refreshList,
|
||||
handleStartStop,
|
||||
actionLoading,
|
||||
deleteLoading
|
||||
}: ActionMenuProps) => {
|
||||
const { getString } = useStrings()
|
||||
const { showError } = useToaster()
|
||||
const { instance, ide } = data
|
||||
const { id, state, url = ' ' } = instance || {}
|
||||
const history = useHistory()
|
||||
const { routes } = useAppContext()
|
||||
const pathparamsList = instance?.space_path?.split('/') || []
|
||||
const projectIdentifier = pathparamsList[pathparamsList.length - 1] || ''
|
||||
|
||||
return (
|
||||
<Container
|
||||
className={css.listContainer}
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}}>
|
||||
<Menu>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
history.push(
|
||||
routes.toCDEGitspaceDetail({
|
||||
space: instance?.space_path || '',
|
||||
gitspaceId: instance?.id || ''
|
||||
})
|
||||
)
|
||||
}}
|
||||
text={
|
||||
<Layout.Horizontal spacing="small" flex={{ alignItems: 'center', justifyContent: 'flex-start' }}>
|
||||
<ViewColumns2 />
|
||||
<Text>{getString('cde.viewGitspace')}</Text>
|
||||
</Layout.Horizontal>
|
||||
}
|
||||
/>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
history.push(
|
||||
routes.toCDEGitspacesEdit({
|
||||
space: instance?.space_path || '',
|
||||
gitspaceId: instance?.id || ''
|
||||
})
|
||||
)
|
||||
}}
|
||||
text={
|
||||
<Layout.Horizontal spacing="small" flex={{ alignItems: 'center', justifyContent: 'flex-start' }}>
|
||||
<EditPencil />
|
||||
<Text>{getString('cde.editGitspace')}</Text>
|
||||
</Layout.Horizontal>
|
||||
}
|
||||
/>
|
||||
<MenuItem
|
||||
onClick={async e => {
|
||||
try {
|
||||
if (!actionLoading) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
await handleStartStop?.()
|
||||
await refreshList()
|
||||
}
|
||||
} catch (error) {
|
||||
showError(getErrorMessage(error))
|
||||
}
|
||||
}}
|
||||
text={
|
||||
<Layout.Horizontal spacing="small">
|
||||
<StartStopButton state={state} loading={actionLoading} />
|
||||
</Layout.Horizontal>
|
||||
}
|
||||
/>
|
||||
{ide && state == GitspaceStatus.RUNNING && (
|
||||
<MenuItem
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
if (ide === IDEType.VSCODE) {
|
||||
window.open(`vscode://harness-inc.gitspaces/${projectIdentifier}/${id}`, '_blank')
|
||||
} else {
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
}}
|
||||
text={
|
||||
<Layout.Horizontal spacing="small">
|
||||
<OpenGitspaceButton ide={ide} />
|
||||
</Layout.Horizontal>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<MenuItem
|
||||
onClick={deleteGitspace as Unknown as () => void}
|
||||
text={
|
||||
<Layout.Horizontal spacing="small" flex={{ alignItems: 'center', justifyContent: 'flex-start' }}>
|
||||
{deleteLoading ? <></> : <DeleteCircle />}
|
||||
<Text icon={deleteLoading ? 'loading' : undefined}>{getString('cde.deleteGitspace')}</Text>
|
||||
</Layout.Horizontal>
|
||||
}
|
||||
/>
|
||||
</Menu>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
interface RenderActionsProps extends CellProps<TypesGitspaceConfig> {
|
||||
refreshList: () => void
|
||||
}
|
||||
|
||||
export const RenderActions = ({ row, refreshList }: RenderActionsProps) => {
|
||||
const { getString } = useStrings()
|
||||
const { showError, showSuccess } = useToaster()
|
||||
const details = row.original
|
||||
const { instance, name } = details
|
||||
const { mutate: deleteGitspace, loading: deleteLoading } = useDeleteGitspace({})
|
||||
|
||||
// To be added in BE later.
|
||||
// const { mutate: actionGitspace, loading: actionLoading } = useGitspaceAction({
|
||||
// accountIdentifier,
|
||||
// projectIdentifier,
|
||||
// orgIdentifier,
|
||||
// gitspaceIdentifier: instance?.id || ''
|
||||
// })
|
||||
|
||||
// const handleStartStop = async () => {
|
||||
// return await actionGitspace({
|
||||
// action: instance?.state === GitspaceStatus.RUNNING ? GitspaceActionType.STOP : GitspaceActionType.START
|
||||
// })
|
||||
// }
|
||||
|
||||
const confirmDelete = useConfirmAct()
|
||||
|
||||
const handleDelete = async (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
confirmDelete({
|
||||
title: getString('cde.deleteGitspaceTitle'),
|
||||
message: getString('cde.deleteGitspaceText', { name: name }),
|
||||
action: async () => {
|
||||
try {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
await deleteGitspace(instance?.id || '')
|
||||
showSuccess(getString('cde.deleteSuccess'))
|
||||
await refreshList()
|
||||
} catch (exception) {
|
||||
showError(getErrorMessage(exception))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Text
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}}
|
||||
style={{ cursor: 'pointer' }}
|
||||
icon={deleteLoading || false ? 'steps-spinner' : 'Options'}
|
||||
tooltip={
|
||||
<ActionMenu
|
||||
data={details}
|
||||
actionLoading={false}
|
||||
deleteLoading={deleteLoading}
|
||||
deleteGitspace={handleDelete}
|
||||
refreshList={refreshList}
|
||||
/>
|
||||
}
|
||||
tooltipProps={{
|
||||
interactionKind: PopoverInteractionKind.HOVER,
|
||||
position: Position.BOTTOM_RIGHT,
|
||||
usePortal: true,
|
||||
popoverClassName: css.popover
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export const ListGitspaces = ({ data, refreshList }: { data: TypesGitspaceConfig[]; refreshList: () => void }) => {
|
||||
const history = useHistory()
|
||||
const { getString } = useStrings()
|
||||
const { routes } = useAppContext()
|
||||
|
||||
return (
|
||||
<Container>
|
||||
{data && (
|
||||
<TableV2<TypesGitspaceConfig>
|
||||
className={css.table}
|
||||
onRowClick={row => {
|
||||
const pathparamsList = row?.instance?.space_path?.split('/') || []
|
||||
const projectIdentifier = pathparamsList[pathparamsList.length - 1] || ''
|
||||
|
||||
if (row?.instance?.state === GitspaceStatus.RUNNING) {
|
||||
if (row?.ide === IDEType.VSCODE) {
|
||||
window.open(`vscode://harness-inc.gitspaces/${projectIdentifier}/${row?.instance?.id}`, '_blank')
|
||||
} else {
|
||||
window.open(row?.instance.url, '_blank')
|
||||
}
|
||||
} else {
|
||||
history.push(
|
||||
routes.toCDEGitspaceDetail({
|
||||
space: row?.instance?.space_path as string,
|
||||
gitspaceId: row?.instance?.id as string
|
||||
})
|
||||
)
|
||||
}
|
||||
}}
|
||||
columns={[
|
||||
{
|
||||
id: 'gitspaces',
|
||||
Header: getString('cde.gitspaces'),
|
||||
Cell: RenderGitspaceName
|
||||
},
|
||||
{
|
||||
id: 'repository',
|
||||
Header: getString('cde.repositoryAndBranch'),
|
||||
Cell: RenderRepository
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
Header: getString('cde.status'),
|
||||
Cell: RenderGitspaceStatus
|
||||
},
|
||||
{
|
||||
id: 'lastactivity',
|
||||
Header: getString('cde.sessionDuration'),
|
||||
Cell: RenderLastActivity
|
||||
},
|
||||
{
|
||||
id: 'action',
|
||||
Cell: (props: RenderActionsProps) => <RenderActions {...props} refreshList={refreshList} />
|
||||
}
|
||||
]}
|
||||
data={data}
|
||||
/>
|
||||
)}
|
||||
</Container>
|
||||
)
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
.split-button {
|
||||
display: flex;
|
||||
border: 1px solid var(--grey-200);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.split-button p {
|
||||
flex-wrap: wrap;
|
||||
padding: 4px 8px !important;
|
||||
border: none;
|
||||
align-self: center;
|
||||
color: #1f2937 !important;
|
||||
cursor: pointer;
|
||||
font-size: 12px !important;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:first-child {
|
||||
border-right: 1px solid var(--grey-200);
|
||||
}
|
||||
}
|
||||
|
||||
.split-button p.active {
|
||||
background-color: var(--primary-1) !important;
|
||||
color: var(--primary-8) !important;
|
||||
}
|
||||
|
||||
.split-button p:hover {
|
||||
background-color: var(--white);
|
||||
}
|
20
web/src/cde-gitness/components/RepositoryTypeButton/RepositoryTypeButton.module.scss.d.ts
vendored
Normal file
20
web/src/cde-gitness/components/RepositoryTypeButton/RepositoryTypeButton.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 active: string
|
||||
export declare const splitButton: string
|
@ -0,0 +1,61 @@
|
||||
import React, { useState } from 'react'
|
||||
import { Container, Text } from '@harnessio/uicore'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import { useConfirmAct } from 'hooks/useConfirmAction'
|
||||
import css from './RepositoryTypeButton.module.scss'
|
||||
|
||||
export enum RepositoryType {
|
||||
GITNESS = 'gitness',
|
||||
THIRDPARTY = 'thirdParty'
|
||||
}
|
||||
|
||||
const RepositoryTypeButton = ({
|
||||
hasChange,
|
||||
onChange
|
||||
}: {
|
||||
hasChange?: boolean
|
||||
onChange: (type: RepositoryType) => void
|
||||
}) => {
|
||||
const { getString } = useStrings()
|
||||
const confirmSwitch = useConfirmAct()
|
||||
const [activeButton, setActiveButton] = useState(RepositoryType.GITNESS)
|
||||
|
||||
const handleSwitch = (type: RepositoryType) => {
|
||||
const onConfirm = () => {
|
||||
setActiveButton(type)
|
||||
onChange(type)
|
||||
}
|
||||
if (hasChange) {
|
||||
confirmSwitch({
|
||||
title: getString('cde.create.unsaved.title'),
|
||||
message: getString('cde.create.unsaved.message'),
|
||||
action: async () => {
|
||||
onConfirm()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
onConfirm()
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Container className={css.splitButton}>
|
||||
<Text
|
||||
className={activeButton === RepositoryType.GITNESS ? css.active : ''}
|
||||
onClick={() => {
|
||||
handleSwitch(RepositoryType.GITNESS)
|
||||
}}>
|
||||
{getString('cde.create.gitnessRepositories')}
|
||||
</Text>
|
||||
<Text
|
||||
className={activeButton === RepositoryType.THIRDPARTY ? css.active : ''}
|
||||
onClick={() => {
|
||||
handleSwitch(RepositoryType.THIRDPARTY)
|
||||
}}>
|
||||
{getString('cde.create.thirdPartyGitRepositories')}
|
||||
</Text>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
export default RepositoryTypeButton
|
@ -0,0 +1,12 @@
|
||||
.hideContainer {
|
||||
:global {
|
||||
--bp3-intent-color: unset !important;
|
||||
.bp3-form-helper-text {
|
||||
margin-top: unset !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.repoAndBranch {
|
||||
width: 47% !important;
|
||||
}
|
@ -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 hideContainer: string
|
||||
export declare const repoAndBranch: string
|
@ -0,0 +1,125 @@
|
||||
import { FormInput, FormikForm, Layout } from '@harnessio/uicore'
|
||||
import React, { useState } from 'react'
|
||||
import { useFormikContext } from 'formik'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import { GitProviders, ImportFormData, getOrgLabel, getOrgPlaceholder, getProviders } from 'utils/GitUtils'
|
||||
import css from './ThirdPartyRepoImportForm.module.scss'
|
||||
|
||||
export interface ThirdPartyRepoImportFormProps extends ImportFormData {
|
||||
branch: string
|
||||
ide: string
|
||||
id: string
|
||||
}
|
||||
|
||||
export const ThirdPartyRepoImportForm = () => {
|
||||
const [auth, setAuth] = useState(false)
|
||||
const { getString } = useStrings()
|
||||
const { values, setFieldValue, validateField } = useFormikContext<ThirdPartyRepoImportFormProps>()
|
||||
return (
|
||||
<FormikForm>
|
||||
<FormInput.Select name={'gitProvider'} label={getString('importSpace.gitProvider')} items={getProviders()} />
|
||||
{![GitProviders.GITHUB, GitProviders.GITLAB, GitProviders.BITBUCKET, GitProviders.AZURE].includes(
|
||||
values.gitProvider
|
||||
) && (
|
||||
<FormInput.Text
|
||||
className={css.hideContainer}
|
||||
name="hostUrl"
|
||||
label={getString('importRepo.url')}
|
||||
placeholder={getString('importRepo.urlPlaceholder')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'repositoryURLTextField'
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<FormInput.Text
|
||||
className={css.hideContainer}
|
||||
name="org"
|
||||
label={getString(getOrgLabel(values.gitProvider))}
|
||||
placeholder={getString(getOrgPlaceholder(values.gitProvider))}
|
||||
/>
|
||||
{values.gitProvider === GitProviders.AZURE && (
|
||||
<FormInput.Text
|
||||
className={css.hideContainer}
|
||||
name="project"
|
||||
label={getString('importRepo.project')}
|
||||
placeholder={getString('importRepo.projectPlaceholder')}
|
||||
/>
|
||||
)}
|
||||
<Layout.Horizontal spacing="medium" flex={{ justifyContent: 'space-between', alignItems: 'baseline' }}>
|
||||
<Layout.Vertical className={css.repoAndBranch} spacing="small">
|
||||
<FormInput.Text
|
||||
className={css.hideContainer}
|
||||
name="repo"
|
||||
label={getString('importRepo.repo')}
|
||||
placeholder={getString('importRepo.repoPlaceholder')}
|
||||
onChange={event => {
|
||||
const target = event.target as HTMLInputElement
|
||||
setFieldValue('repo', target.value)
|
||||
if (target.value) {
|
||||
setFieldValue('name', target.value)
|
||||
validateField('repo')
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Layout.Vertical>
|
||||
<Layout.Vertical className={css.repoAndBranch} spacing="small">
|
||||
<FormInput.Text
|
||||
className={css.hideContainer}
|
||||
name="branch"
|
||||
label={getString('branch')}
|
||||
placeholder={getString('cde.create.branchPlaceholder')}
|
||||
onChange={event => {
|
||||
const target = event.target as HTMLInputElement
|
||||
setFieldValue('branch', target.value)
|
||||
}}
|
||||
/>
|
||||
</Layout.Vertical>
|
||||
</Layout.Horizontal>
|
||||
<Layout.Horizontal spacing="medium">
|
||||
<FormInput.CheckBox
|
||||
name="authorization"
|
||||
label={getString('importRepo.reqAuth')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'authorization'
|
||||
}}
|
||||
onClick={() => {
|
||||
setAuth(!auth)
|
||||
}}
|
||||
style={auth ? {} : { margin: 0 }}
|
||||
/>
|
||||
</Layout.Horizontal>
|
||||
|
||||
{auth ? (
|
||||
<>
|
||||
{[GitProviders.BITBUCKET, GitProviders.AZURE].includes(values.gitProvider) && (
|
||||
<FormInput.Text
|
||||
name="username"
|
||||
label={getString('userName')}
|
||||
placeholder={getString('importRepo.userPlaceholder')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'repositoryUserTextField'
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<FormInput.Text
|
||||
inputGroup={{ type: 'password' }}
|
||||
name="password"
|
||||
label={
|
||||
[GitProviders.BITBUCKET, GitProviders.AZURE].includes(values.gitProvider)
|
||||
? getString('importRepo.appPassword')
|
||||
: getString('importRepo.passToken')
|
||||
}
|
||||
placeholder={
|
||||
[GitProviders.BITBUCKET, GitProviders.AZURE].includes(values.gitProvider)
|
||||
? getString('importRepo.appPasswordPlaceholder')
|
||||
: getString('importRepo.passTokenPlaceholder')
|
||||
}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'repositoryPasswordTextField'
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
</FormikForm>
|
||||
)
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
import type { ThirdPartyRepoImportFormProps } from 'cde-gitness/components/ThirdPartyRepoImportForm/ThirdPartyRepoImportForm'
|
||||
import type { EnumIDEType, OpenapiCreateGitspaceRequest } from 'cde-gitness/services'
|
||||
import { GitProviders } from 'utils/GitUtils'
|
||||
|
||||
export const gitnessFormInitialValues: OpenapiCreateGitspaceRequest = {
|
||||
branch: '',
|
||||
code_repo_url: '',
|
||||
devcontainer_path: '',
|
||||
id: '',
|
||||
ide: 'vsCode' as EnumIDEType,
|
||||
infra_provider_resource_id: 'default',
|
||||
name: ''
|
||||
}
|
||||
export const thirdPartyformInitialValues: ThirdPartyRepoImportFormProps = {
|
||||
gitProvider: GitProviders.GITHUB,
|
||||
hostUrl: '',
|
||||
org: '',
|
||||
project: '',
|
||||
repo: '',
|
||||
username: '',
|
||||
password: '',
|
||||
name: '',
|
||||
description: '',
|
||||
branch: '',
|
||||
ide: 'vsCode' as EnumIDEType,
|
||||
id: '',
|
||||
importPipelineLabel: false
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
.main {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.cardMain {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.subContainers {
|
||||
margin: var(--spacing-xlarge) 0 !important;
|
||||
margin-bottom: 0px !important;
|
||||
}
|
||||
|
||||
.formDivider {
|
||||
height: 2px !important;
|
||||
border-top: 1px solid var(--grey-200) !important;
|
||||
}
|
||||
|
||||
.formTitleContainer {
|
||||
padding: var(--spacing-medium) var(--spacing-large) !important;
|
||||
border: 1px solid var(--grey-200);
|
||||
border-radius: 5px;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.formContainer {
|
||||
border: 1px solid var(--grey-200);
|
||||
border-radius: 5px;
|
||||
padding: var(--spacing-medium) var(--spacing-large) !important;
|
||||
border-top-right-radius: 0px;
|
||||
border-top-left-radius: 0px;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.formOuterContainer {
|
||||
padding: var(--spacing-medium) 0 !important;
|
||||
padding-bottom: 0px !important;
|
||||
|
||||
button {
|
||||
margin-bottom: none;
|
||||
}
|
||||
}
|
26
web/src/cde-gitness/pages/GitspaceCreate/GitspaceCreate.module.scss.d.ts
vendored
Normal file
26
web/src/cde-gitness/pages/GitspaceCreate/GitspaceCreate.module.scss.d.ts
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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 cardMain: string
|
||||
export declare const cardTitle: string
|
||||
export declare const formContainer: string
|
||||
export declare const formDivider: string
|
||||
export declare const formOuterContainer: string
|
||||
export declare const formTitleContainer: string
|
||||
export declare const main: string
|
||||
export declare const subContainers: string
|
123
web/src/cde-gitness/pages/GitspaceCreate/GitspaceCreate.tsx
Normal file
123
web/src/cde-gitness/pages/GitspaceCreate/GitspaceCreate.tsx
Normal file
@ -0,0 +1,123 @@
|
||||
import React, { useState } from 'react'
|
||||
import {
|
||||
Button,
|
||||
ButtonVariation,
|
||||
Card,
|
||||
Container,
|
||||
Formik,
|
||||
FormikForm,
|
||||
Layout,
|
||||
Page,
|
||||
Text,
|
||||
useToaster
|
||||
} from '@harnessio/uicore'
|
||||
import { FontVariation } from '@harnessio/design-system'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import {
|
||||
ThirdPartyRepoImportForm,
|
||||
ThirdPartyRepoImportFormProps
|
||||
} from 'cde-gitness/components/ThirdPartyRepoImportForm/ThirdPartyRepoImportForm'
|
||||
import { GitnessRepoImportForm } from 'cde-gitness/components/GitnessRepoImportForm/GitnessRepoImportForm'
|
||||
import { SelectIDE } from 'cde/components/CreateGitspace/components/SelectIDE/SelectIDE'
|
||||
import { useCreateGitspace, type OpenapiCreateGitspaceRequest } from 'cde-gitness/services'
|
||||
import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
|
||||
import { getErrorMessage } from 'utils/Utils'
|
||||
import { useAppContext } from 'AppContext'
|
||||
import RepositoryTypeButton, { RepositoryType } from '../../components/RepositoryTypeButton/RepositoryTypeButton'
|
||||
import { gitnessFormInitialValues, thirdPartyformInitialValues } from './GitspaceCreate.constants'
|
||||
import { handleImportSubmit, validateGitnessForm, validationSchemaStepOne } from './GitspaceCreate.utils'
|
||||
import css from './GitspaceCreate.module.scss'
|
||||
|
||||
export const GitspaceCreate = () => {
|
||||
const { getString } = useStrings()
|
||||
const space = useGetSpaceParam()
|
||||
const { routes } = useAppContext()
|
||||
const history = useHistory()
|
||||
const [activeButton, setActiveButton] = useState(RepositoryType.GITNESS)
|
||||
const { showSuccess, showError } = useToaster()
|
||||
const { mutate } = useCreateGitspace({})
|
||||
|
||||
return (
|
||||
<>
|
||||
<Page.Header title={getString('cde.gitspaces')} />
|
||||
<Page.Body className={css.main}>
|
||||
<Card className={css.cardMain}>
|
||||
<Text className={css.cardTitle} font={{ variation: FontVariation.CARD_TITLE }}>
|
||||
{getString('cde.createGitspace')}
|
||||
</Text>
|
||||
<Container className={css.subContainers}>
|
||||
<Formik
|
||||
onSubmit={async data => {
|
||||
try {
|
||||
const payload =
|
||||
activeButton === RepositoryType.GITNESS
|
||||
? data
|
||||
: handleImportSubmit(data as ThirdPartyRepoImportFormProps)
|
||||
await mutate({ ...payload, space_ref: space } as OpenapiCreateGitspaceRequest & {
|
||||
space_ref?: string
|
||||
})
|
||||
showSuccess(getString('cde.create.gitspaceCreateSuccess'))
|
||||
history.push(routes.toCDEGitspaces({ space }))
|
||||
} catch (error) {
|
||||
showError(getString('cde.create.gitspaceCreateFailed'))
|
||||
showError(getErrorMessage(error))
|
||||
}
|
||||
}}
|
||||
initialValues={
|
||||
activeButton === RepositoryType.GITNESS ? gitnessFormInitialValues : thirdPartyformInitialValues
|
||||
}
|
||||
validationSchema={
|
||||
activeButton === RepositoryType.GITNESS
|
||||
? validateGitnessForm(getString)
|
||||
: validationSchemaStepOne(getString)
|
||||
}
|
||||
formName="importRepoForm"
|
||||
enableReinitialize>
|
||||
{formik => {
|
||||
return (
|
||||
<>
|
||||
<Layout.Horizontal
|
||||
className={css.formTitleContainer}
|
||||
flex={{ justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Text font={{ variation: FontVariation.CARD_TITLE }}>
|
||||
{getString('cde.create.repositoryDetails')}
|
||||
</Text>
|
||||
<RepositoryTypeButton
|
||||
hasChange={formik.dirty}
|
||||
onChange={type => {
|
||||
setActiveButton(type)
|
||||
formik?.resetForm()
|
||||
}}
|
||||
/>
|
||||
</Layout.Horizontal>
|
||||
<FormikForm>
|
||||
<Container className={css.formContainer}>
|
||||
{activeButton === RepositoryType.GITNESS && (
|
||||
<Container>
|
||||
<GitnessRepoImportForm />
|
||||
</Container>
|
||||
)}
|
||||
{activeButton === RepositoryType.THIRDPARTY && (
|
||||
<Container>
|
||||
<ThirdPartyRepoImportForm />
|
||||
</Container>
|
||||
)}
|
||||
</Container>
|
||||
<Container className={css.formOuterContainer}>
|
||||
<SelectIDE />
|
||||
<Button width={'100%'} variation={ButtonVariation.PRIMARY} height={50} type="submit">
|
||||
{getString('cde.createGitspace')}
|
||||
</Button>
|
||||
</Container>
|
||||
</FormikForm>
|
||||
</>
|
||||
)
|
||||
}}
|
||||
</Formik>
|
||||
</Container>
|
||||
</Card>
|
||||
</Page.Body>
|
||||
</>
|
||||
)
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
import * as yup from 'yup'
|
||||
import { compact } from 'lodash-es'
|
||||
import type { UseStringsReturn } from 'framework/strings'
|
||||
import { GitProviders, getProviderTypeMapping } from 'utils/GitUtils'
|
||||
import type { ThirdPartyRepoImportFormProps } from 'cde-gitness/components/ThirdPartyRepoImportForm/ThirdPartyRepoImportForm'
|
||||
|
||||
export const validateGitnessForm = (getString: UseStringsReturn['getString']) =>
|
||||
yup.object().shape({
|
||||
branch: yup.string().trim().required(getString('cde.branchValidationMessage')),
|
||||
code_repo_url: yup.string().trim().required(getString('cde.repoValidationMessage')),
|
||||
id: yup.string().trim().required(),
|
||||
ide: yup.string().trim().required(),
|
||||
infra_provider_resource_id: yup.string().trim().required(getString('cde.machineValidationMessage')),
|
||||
name: yup.string().trim().required()
|
||||
})
|
||||
|
||||
export const validationSchemaStepOne = (getString: UseStringsReturn['getString']) =>
|
||||
yup.object().shape({
|
||||
gitProvider: yup.string().required(),
|
||||
repo: yup
|
||||
.string()
|
||||
.trim()
|
||||
.when('gitProvider', {
|
||||
is: gitProvider => [GitProviders.GITHUB, GitProviders.GITLAB, GitProviders.BITBUCKET].includes(gitProvider),
|
||||
then: yup.string().required(getString('importSpace.orgRequired'))
|
||||
}),
|
||||
branch: yup.string().trim().required(getString('cde.branchValidationMessage')),
|
||||
hostUrl: yup
|
||||
.string()
|
||||
// .matches(MATCH_REPOURL_REGEX, getString('importSpace.invalidUrl'))
|
||||
.when('gitProvider', {
|
||||
is: gitProvider =>
|
||||
![GitProviders.GITHUB, GitProviders.GITLAB, GitProviders.BITBUCKET, GitProviders.AZURE].includes(gitProvider),
|
||||
then: yup.string().required(getString('importRepo.required')),
|
||||
otherwise: yup.string().notRequired() // Optional based on your needs
|
||||
}),
|
||||
org: yup
|
||||
.string()
|
||||
.trim()
|
||||
.when('gitProvider', {
|
||||
is: GitProviders.AZURE,
|
||||
then: yup.string().required(getString('importSpace.orgRequired'))
|
||||
}),
|
||||
project: yup
|
||||
.string()
|
||||
.trim()
|
||||
.when('gitProvider', {
|
||||
is: GitProviders.AZURE,
|
||||
then: yup.string().required(getString('importSpace.spaceNameRequired'))
|
||||
}),
|
||||
name: yup.string().trim().required(getString('validation.nameIsRequired'))
|
||||
})
|
||||
|
||||
export const handleImportSubmit = (formData: ThirdPartyRepoImportFormProps) => {
|
||||
const type = getProviderTypeMapping(formData.gitProvider)
|
||||
|
||||
const provider = {
|
||||
type,
|
||||
username: formData.username,
|
||||
password: formData.password,
|
||||
host: ''
|
||||
}
|
||||
|
||||
if (
|
||||
![GitProviders.GITHUB, GitProviders.GITLAB, GitProviders.BITBUCKET, GitProviders.AZURE].includes(
|
||||
formData.gitProvider
|
||||
)
|
||||
) {
|
||||
provider.host = formData.hostUrl
|
||||
}
|
||||
|
||||
const importPayload = {
|
||||
name: formData.repo || formData.name,
|
||||
description: formData.description || '',
|
||||
id: formData.repo,
|
||||
provider,
|
||||
ide: formData.ide,
|
||||
branch: formData.branch,
|
||||
infra_provider_resource_id: 'default',
|
||||
provider_repo: compact([
|
||||
formData.org,
|
||||
formData.gitProvider === GitProviders.AZURE ? formData.project : '',
|
||||
formData.repo
|
||||
])
|
||||
.join('/')
|
||||
.replace(/\.git$/, '')
|
||||
}
|
||||
|
||||
return importPayload
|
||||
}
|
102
web/src/cde-gitness/pages/GitspaceListing/GitspaceListing.tsx
Normal file
102
web/src/cde-gitness/pages/GitspaceListing/GitspaceListing.tsx
Normal file
@ -0,0 +1,102 @@
|
||||
import React from 'react'
|
||||
import {
|
||||
Button,
|
||||
Page,
|
||||
ButtonVariation,
|
||||
Breadcrumbs,
|
||||
HarnessDocTooltip,
|
||||
Container,
|
||||
Layout,
|
||||
Text
|
||||
} from '@harnessio/uicore'
|
||||
import { FontVariation } from '@harnessio/design-system'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import { useGet } from 'restful-react'
|
||||
import { useAppContext } from 'AppContext'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
|
||||
import { LIST_FETCHING_LIMIT, PageBrowserProps, getErrorMessage } from 'utils/Utils'
|
||||
import noSpace from 'cde/images/no-gitspace.svg?url'
|
||||
import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination'
|
||||
import { useQueryParams } from 'hooks/useQueryParams'
|
||||
import { usePageIndex } from 'hooks/usePageIndex'
|
||||
import { ListGitspaces } from 'cde-gitness/components/GitspaceListing/ListGitspaces'
|
||||
import type { TypesGitspaceConfig } from 'cde-gitness/services'
|
||||
import css from './GitspacesListing.module.scss'
|
||||
|
||||
export const GitspaceListing = () => {
|
||||
const space = useGetSpaceParam()
|
||||
const history = useHistory()
|
||||
const { getString } = useStrings()
|
||||
const { routes } = useAppContext()
|
||||
const pageBrowser = useQueryParams<PageBrowserProps>()
|
||||
const pageInit = pageBrowser.page ? parseInt(pageBrowser.page) : 1
|
||||
const [page, setPage] = usePageIndex(pageInit)
|
||||
|
||||
const {
|
||||
data = '',
|
||||
loading = false,
|
||||
error = undefined,
|
||||
refetch,
|
||||
response
|
||||
} = useGet<TypesGitspaceConfig[]>({
|
||||
path: `/api/v1/spaces/${space}/+/gitspaces`,
|
||||
queryParams: { page, limit: LIST_FETCHING_LIMIT },
|
||||
debounce: 500
|
||||
})
|
||||
|
||||
// useEffect(() => {
|
||||
// if (!data && !loading) {
|
||||
// history.push(routes.toCDEGitspacesCreate({ space }))
|
||||
// }
|
||||
// }, [data, loading])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Page.Header
|
||||
title={
|
||||
<div className="ng-tooltip-native">
|
||||
<h2 data-tooltip-id="artifactListPageHeading"> {getString('cde.gitspaces')}</h2>
|
||||
<HarnessDocTooltip tooltipId="GitSpaceListPageHeading" useStandAlone={true} />
|
||||
</div>
|
||||
}
|
||||
breadcrumbs={
|
||||
<Breadcrumbs links={[{ url: routes.toCDEGitspaces({ space }), label: getString('cde.gitspaces') }]} />
|
||||
}
|
||||
toolbar={
|
||||
<Button
|
||||
onClick={() => history.push(routes.toCDEGitspacesCreate({ space }))}
|
||||
variation={ButtonVariation.PRIMARY}>
|
||||
{getString('cde.newGitspace')}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<Container className={css.main}>
|
||||
<Layout.Vertical spacing={'large'}>
|
||||
<Page.Body
|
||||
loading={loading}
|
||||
error={
|
||||
error ? (
|
||||
<Layout.Vertical spacing={'large'}>
|
||||
<Text font={{ variation: FontVariation.FORM_MESSAGE_DANGER }}>{getErrorMessage(error)}</Text>
|
||||
<Button
|
||||
onClick={() => refetch?.()}
|
||||
variation={ButtonVariation.PRIMARY}
|
||||
text={getString('cde.retry')}
|
||||
/>
|
||||
</Layout.Vertical>
|
||||
) : null
|
||||
}
|
||||
noData={{
|
||||
when: () => data?.length === 0,
|
||||
image: noSpace,
|
||||
message: getString('cde.noGitspaces')
|
||||
}}>
|
||||
<ListGitspaces data={data || []} refreshList={refetch} />
|
||||
<ResourceListingPagination response={response} page={page} setPage={setPage} />
|
||||
</Page.Body>
|
||||
</Layout.Vertical>
|
||||
</Container>
|
||||
</>
|
||||
)
|
||||
}
|
@ -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.
|
||||
*/
|
||||
|
||||
.main {
|
||||
margin: var(--spacing-xxlarge) !important;
|
||||
}
|
19
web/src/cde-gitness/pages/GitspaceListing/GitspacesListing.module.scss.d.ts
vendored
Normal file
19
web/src/cde-gitness/pages/GitspaceListing/GitspacesListing.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 main: string
|
1559
web/src/cde-gitness/services/index.tsx
Normal file
1559
web/src/cde-gitness/services/index.tsx
Normal file
File diff suppressed because it is too large
Load Diff
@ -17,9 +17,8 @@
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import cx from 'classnames'
|
||||
import { Menu, PopoverInteractionKind, PopoverPosition } from '@blueprintjs/core'
|
||||
import { Text, Button, Container, ButtonVariation, FormError } from '@harnessio/uicore'
|
||||
import { Text, Button, Container, ButtonVariation, FormInput } from '@harnessio/uicore'
|
||||
import type { IconName } from '@harnessio/icons'
|
||||
import { useFormikContext } from 'formik'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import css from './GitspaceSelect.module.scss'
|
||||
|
||||
@ -32,24 +31,25 @@ interface GitspaceSelectProps {
|
||||
errorMessage?: string
|
||||
formikName?: string
|
||||
tooltipProps?: { [key: string]: any }
|
||||
formInputClassName?: string
|
||||
loading?: boolean
|
||||
}
|
||||
|
||||
export const GitspaceSelect = ({
|
||||
text,
|
||||
icon,
|
||||
loading,
|
||||
renderMenu,
|
||||
disabled,
|
||||
overridePopOverWidth,
|
||||
errorMessage,
|
||||
formikName,
|
||||
tooltipProps
|
||||
tooltipProps,
|
||||
formInputClassName
|
||||
}: GitspaceSelectProps) => {
|
||||
const { getString } = useStrings()
|
||||
const buttonRef = useRef<HTMLDivElement | null>(null)
|
||||
const [popoverWidth, setPopoverWidth] = useState(0)
|
||||
|
||||
const { touched } = useFormikContext<{ validated?: boolean }>()
|
||||
|
||||
const defaultTooltipProps = {
|
||||
tooltip: (
|
||||
<Container className={css.listContainer} width={overridePopOverWidth ? '100%' : popoverWidth}>
|
||||
@ -85,18 +85,25 @@ export const GitspaceSelect = ({
|
||||
const addTooltipProps = disabled ? {} : { ...defaultTooltipProps }
|
||||
|
||||
return (
|
||||
<div className={css.buttonDiv} ref={buttonRef}>
|
||||
<Button
|
||||
className={cx(css.button, { [css.buttonWithoutIcon]: !icon })}
|
||||
text={text}
|
||||
rightIcon="chevron-down"
|
||||
variation={ButtonVariation.TERTIARY}
|
||||
iconProps={{ size: 14 }}
|
||||
{...iconProp}
|
||||
{...addTooltipProps}
|
||||
disabled={disabled}
|
||||
/>
|
||||
{touched.validated && <FormError errorMessage={errorMessage} name={formikName || ''} />}
|
||||
</div>
|
||||
<FormInput.CustomRender
|
||||
name={formikName || ''}
|
||||
className={cx(formInputClassName)}
|
||||
render={() => {
|
||||
return (
|
||||
<div className={css.buttonDiv} ref={buttonRef}>
|
||||
<Button
|
||||
className={cx(css.button, { [css.buttonWithoutIcon]: !icon })}
|
||||
text={text}
|
||||
rightIcon={loading ? 'loading' : 'chevron-down'}
|
||||
variation={ButtonVariation.TERTIARY}
|
||||
iconProps={{ size: 14 }}
|
||||
{...iconProp}
|
||||
{...addTooltipProps}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import { useStrings } from 'framework/strings'
|
||||
import Gitspace from '../../icons/Gitspace.svg?url'
|
||||
import css from './Gitspaces.module.scss'
|
||||
|
||||
const CreateGitspaceTitle = () => {
|
||||
export const CreateGitspaceTitle = () => {
|
||||
const { getString } = useStrings()
|
||||
return (
|
||||
<Container className={css.gitspaceTitle}>
|
||||
|
@ -49,7 +49,7 @@ import { useGet, useMutate } from 'restful-react'
|
||||
import { Render } from 'react-jsx-match'
|
||||
import { compact, get } from 'lodash-es'
|
||||
import { useModalHook } from 'hooks/useModalHook'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import { String, useStrings } from 'framework/strings'
|
||||
import {
|
||||
DEFAULT_BRANCH_NAME,
|
||||
getErrorMessage,
|
||||
@ -96,6 +96,8 @@ export interface NewRepoModalButtonProps extends Omit<ButtonProps, 'onClick' | '
|
||||
submitButtonTitle?: string
|
||||
cancelButtonTitle?: string
|
||||
onSubmit: (data: TypesRepository & SpaceImportRepositoriesOutput) => void
|
||||
newRepoModalOnly?: boolean
|
||||
notFoundRepoName?: string
|
||||
}
|
||||
|
||||
export const NewRepoModalButton: React.FC<NewRepoModalButtonProps> = ({
|
||||
@ -478,7 +480,19 @@ export const NewRepoModalButton: React.FC<NewRepoModalButtonProps> = ({
|
||||
},
|
||||
[space]
|
||||
)
|
||||
return (
|
||||
|
||||
return props?.newRepoModalOnly ? (
|
||||
<MenuItem
|
||||
icon="plus"
|
||||
text={<String stringID="cde.create.repoNotFound" vars={{ repo: props?.notFoundRepoName }} useRichText />}
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
setRepoOption(repoCreateOptions[0])
|
||||
setTimeout(() => openModal(), 0)
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<SplitButton
|
||||
{...props}
|
||||
loading={false}
|
||||
|
@ -143,6 +143,18 @@ export interface StringsMap {
|
||||
'cde.branchValidationMessage': string
|
||||
'cde.cloudDeveloperExperience': string
|
||||
'cde.cpu': string
|
||||
'cde.create.branchPlaceholder': string
|
||||
'cde.create.gitnessRepositories': string
|
||||
'cde.create.gitspaceCreateFailed': string
|
||||
'cde.create.gitspaceCreateSuccess': string
|
||||
'cde.create.repoNotFound': string
|
||||
'cde.create.repositoryDetails': string
|
||||
'cde.create.searchBranchPlaceholder': string
|
||||
'cde.create.searchRepositoryPlaceholder': string
|
||||
'cde.create.selectBranchPlaceholder': string
|
||||
'cde.create.thirdPartyGitRepositories': string
|
||||
'cde.create.unsaved.message': string
|
||||
'cde.create.unsaved.title': string
|
||||
'cde.createGitspace': string
|
||||
'cde.createRepo': string
|
||||
'cde.deleteGitspace': string
|
||||
@ -183,6 +195,9 @@ export interface StringsMap {
|
||||
'cde.introText1': string
|
||||
'cde.introText2': string
|
||||
'cde.introText3': string
|
||||
'cde.listing.error': string
|
||||
'cde.listing.offline': string
|
||||
'cde.listing.online': string
|
||||
'cde.logs': string
|
||||
'cde.machine': string
|
||||
'cde.machineValidationMessage': string
|
||||
@ -211,6 +226,7 @@ export interface StringsMap {
|
||||
'cde.retry': string
|
||||
'cde.sessionDuration': string
|
||||
'cde.startingGitspace': string
|
||||
'cde.status': string
|
||||
'cde.stopingGitspace': string
|
||||
'cde.updateGitspace': string
|
||||
'cde.used': string
|
||||
|
@ -1162,6 +1162,25 @@ cde:
|
||||
deleteGitspaceText: "Are you sure to delete the gitspace, '{{name}}'?"
|
||||
deleteSuccess: Gitspace deleted succesfully
|
||||
repositoryAndBranch: Repository & Branch
|
||||
status: Status
|
||||
listing:
|
||||
online: Online
|
||||
offline: Offline
|
||||
error: Error
|
||||
create:
|
||||
repositoryDetails: Repository Details
|
||||
gitnessRepositories: Gitness Repositories
|
||||
thirdPartyGitRepositories: Third Party Git Repositories
|
||||
branchPlaceholder: Enter the Branch name
|
||||
selectBranchPlaceholder: Select branch
|
||||
searchRepositoryPlaceholder: Search for a repository
|
||||
searchBranchPlaceholder: Search for a branch
|
||||
repoNotFound: 'Create a repo <strong>{{repo}}</strong> in Gitness'
|
||||
gitspaceCreateSuccess: Gitspace created successfully
|
||||
gitspaceCreateFailed: Gitspace creation failed
|
||||
unsaved:
|
||||
title: Unsaved Changes
|
||||
message: 'You have unsaved changes, On switching all unsaved changes will be lost'
|
||||
details:
|
||||
actions: More Actions
|
||||
openEditor: Open VS Code Editor
|
||||
|
Loading…
Reference in New Issue
Block a user