mirror of
https://github.com/harness/drone.git
synced 2025-05-13 15:40:12 +08:00
[CODE-1159] UI to disable public repo creation with a flag - GITNESS_PUBLIC_RESOURCE_CREATION_ENABLED (#895)
This commit is contained in:
parent
b24729d608
commit
cb817bf2ad
@ -18,20 +18,11 @@ import React, { useState } from 'react'
|
|||||||
import { Intent } from '@blueprintjs/core'
|
import { Intent } from '@blueprintjs/core'
|
||||||
import * as yup from 'yup'
|
import * as yup from 'yup'
|
||||||
import { Color } from '@harnessio/design-system'
|
import { Color } from '@harnessio/design-system'
|
||||||
import { Button, Container, Layout, FlexExpander, Formik, FormikForm, FormInput, Text } from '@harnessio/uicore'
|
import { Button, Layout, FlexExpander, Formik, FormikForm, FormInput, Text } from '@harnessio/uicore'
|
||||||
import { Icon } from '@harnessio/icons'
|
import { Icon } from '@harnessio/icons'
|
||||||
import { FontVariation } from '@harnessio/design-system'
|
|
||||||
import { useStrings } from 'framework/strings'
|
import { useStrings } from 'framework/strings'
|
||||||
import { REGEX_VALID_REPO_NAME } from 'utils/Utils'
|
import { REGEX_VALID_REPO_NAME } from 'utils/Utils'
|
||||||
import {
|
import { ImportFormData, GitProviders, getProviders, getOrgLabel, getOrgPlaceholder } from 'utils/GitUtils'
|
||||||
ImportFormData,
|
|
||||||
RepoVisibility,
|
|
||||||
GitProviders,
|
|
||||||
getProviders,
|
|
||||||
getOrgLabel,
|
|
||||||
getOrgPlaceholder
|
|
||||||
} from 'utils/GitUtils'
|
|
||||||
import Private from '../../../icons/private.svg'
|
|
||||||
import css from '../NewRepoModalButton.module.scss'
|
import css from '../NewRepoModalButton.module.scss'
|
||||||
|
|
||||||
interface ImportFormProps {
|
interface ImportFormProps {
|
||||||
@ -56,8 +47,7 @@ const ImportForm = (props: ImportFormProps) => {
|
|||||||
username: '',
|
username: '',
|
||||||
password: '',
|
password: '',
|
||||||
name: '',
|
name: '',
|
||||||
description: '',
|
description: ''
|
||||||
isPublic: RepoVisibility.PRIVATE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const validationSchemaStepOne = yup.object().shape({
|
const validationSchemaStepOne = yup.object().shape({
|
||||||
@ -244,56 +234,6 @@ const ImportForm = (props: ImportFormProps) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<hr className={css.dividerContainer} />
|
|
||||||
|
|
||||||
<Container>
|
|
||||||
<FormInput.RadioGroup
|
|
||||||
name="isPublic"
|
|
||||||
label=""
|
|
||||||
items={[
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<Container>
|
|
||||||
<Layout.Horizontal>
|
|
||||||
<Icon name="git-clone-step" size={20} margin={{ right: 'medium' }} />
|
|
||||||
<Container>
|
|
||||||
<Layout.Vertical spacing="xsmall">
|
|
||||||
<Text>{getString('public')}</Text>
|
|
||||||
<Text font={{ variation: FontVariation.TINY }}>
|
|
||||||
{getString('createRepoModal.publicLabel')}
|
|
||||||
</Text>
|
|
||||||
</Layout.Vertical>
|
|
||||||
</Container>
|
|
||||||
</Layout.Horizontal>
|
|
||||||
</Container>
|
|
||||||
),
|
|
||||||
value: RepoVisibility.PUBLIC
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<Container>
|
|
||||||
<Layout.Horizontal>
|
|
||||||
<Container margin={{ right: 'medium' }}>
|
|
||||||
<img width={20} height={20} src={Private} />
|
|
||||||
</Container>
|
|
||||||
{/* <Icon name="git-clone-step" size={20} margin={{ right: 'medium' }} /> */}
|
|
||||||
<Container margin={{ left: 'small' }}>
|
|
||||||
<Layout.Vertical spacing="xsmall">
|
|
||||||
<Text>{getString('private')}</Text>
|
|
||||||
<Text font={{ variation: FontVariation.TINY }}>
|
|
||||||
{getString('createRepoModal.privateLabel')}
|
|
||||||
</Text>
|
|
||||||
</Layout.Vertical>
|
|
||||||
</Container>
|
|
||||||
</Layout.Horizontal>
|
|
||||||
</Container>
|
|
||||||
),
|
|
||||||
value: RepoVisibility.PRIVATE
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</Container>
|
|
||||||
|
|
||||||
<Layout.Horizontal
|
<Layout.Horizontal
|
||||||
spacing="small"
|
spacing="small"
|
||||||
padding={{ right: 'xxlarge', top: 'xlarge', bottom: 'large' }}
|
padding={{ right: 'xxlarge', top: 'xlarge', bottom: 'large' }}
|
||||||
|
@ -46,6 +46,7 @@ import {
|
|||||||
import { Icon } from '@harnessio/icons'
|
import { Icon } from '@harnessio/icons'
|
||||||
import { Color, FontVariation } from '@harnessio/design-system'
|
import { Color, FontVariation } from '@harnessio/design-system'
|
||||||
import { useGet, useMutate } from 'restful-react'
|
import { useGet, useMutate } from 'restful-react'
|
||||||
|
import { Render } from 'react-jsx-match'
|
||||||
import { get } from 'lodash-es'
|
import { get } from 'lodash-es'
|
||||||
import { useModalHook } from 'hooks/useModalHook'
|
import { useModalHook } from 'hooks/useModalHook'
|
||||||
import { useStrings } from 'framework/strings'
|
import { useStrings } from 'framework/strings'
|
||||||
@ -107,6 +108,7 @@ export const NewRepoModalButton: React.FC<NewRepoModalButtonProps> = ({
|
|||||||
const ModalComponent: React.FC = () => {
|
const ModalComponent: React.FC = () => {
|
||||||
const { getString } = useStrings()
|
const { getString } = useStrings()
|
||||||
const [branchName, setBranchName] = useState(DEFAULT_BRANCH_NAME)
|
const [branchName, setBranchName] = useState(DEFAULT_BRANCH_NAME)
|
||||||
|
const [enablePublicRepo, setEnablePublicRepo] = useState(false)
|
||||||
const { showError } = useToaster()
|
const { showError } = useToaster()
|
||||||
|
|
||||||
const { mutate: createRepo, loading: submitLoading } = useMutate<TypesRepository>({
|
const { mutate: createRepo, loading: submitLoading } = useMutate<TypesRepository>({
|
||||||
@ -141,13 +143,31 @@ export const NewRepoModalButton: React.FC<NewRepoModalButtonProps> = ({
|
|||||||
loading: licenseLoading,
|
loading: licenseLoading,
|
||||||
error: licenseError
|
error: licenseError
|
||||||
} = useGet({ path: '/api/v1/resources/license' })
|
} = useGet({ path: '/api/v1/resources/license' })
|
||||||
const loading = submitLoading || gitIgnoreLoading || licenseLoading || importRepoLoading || submitImportLoading
|
const {
|
||||||
|
data: systemConfig,
|
||||||
|
loading: systemConfigLoading,
|
||||||
|
error: systemConfigError
|
||||||
|
} = useGet({ path: 'api/v1/system/config' })
|
||||||
|
|
||||||
|
const loading =
|
||||||
|
submitLoading ||
|
||||||
|
gitIgnoreLoading ||
|
||||||
|
licenseLoading ||
|
||||||
|
importRepoLoading ||
|
||||||
|
submitImportLoading ||
|
||||||
|
systemConfigLoading
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (gitIgnoreError || licenseError) {
|
if (gitIgnoreError || licenseError || systemConfigError) {
|
||||||
showError(getErrorMessage(gitIgnoreError || licenseError), 0)
|
showError(getErrorMessage(gitIgnoreError || licenseError || systemConfigError), 0)
|
||||||
}
|
}
|
||||||
}, [gitIgnoreError, licenseError, showError])
|
}, [gitIgnoreError, licenseError, systemConfigError, showError])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (systemConfig) {
|
||||||
|
setEnablePublicRepo(systemConfig.public_resource_creation_enabled)
|
||||||
|
}
|
||||||
|
}, [systemConfig])
|
||||||
const handleSubmit = (formData: RepoFormData) => {
|
const handleSubmit = (formData: RepoFormData) => {
|
||||||
try {
|
try {
|
||||||
const payload: OpenapiCreateRepositoryRequest = {
|
const payload: OpenapiCreateRepositoryRequest = {
|
||||||
@ -309,54 +329,56 @@ export const NewRepoModalButton: React.FC<NewRepoModalButtonProps> = ({
|
|||||||
{getString('createRepoModal.branch')}
|
{getString('createRepoModal.branch')}
|
||||||
</Text>
|
</Text>
|
||||||
</Container>
|
</Container>
|
||||||
<hr className={css.dividerContainer} />
|
<Render when={enablePublicRepo}>
|
||||||
<Container>
|
<hr className={css.dividerContainer} />
|
||||||
<FormInput.RadioGroup
|
<Container>
|
||||||
name="isPublic"
|
<FormInput.RadioGroup
|
||||||
label=""
|
name="isPublic"
|
||||||
items={[
|
label=""
|
||||||
{
|
items={[
|
||||||
label: (
|
{
|
||||||
<Container>
|
label: (
|
||||||
<Layout.Horizontal>
|
<Container>
|
||||||
<Icon name="git-clone-step" size={20} margin={{ right: 'medium' }} />
|
<Layout.Horizontal>
|
||||||
<Container>
|
<Icon name="git-clone-step" size={20} margin={{ right: 'medium' }} />
|
||||||
<Layout.Vertical spacing="xsmall">
|
<Container>
|
||||||
<Text>{getString('public')}</Text>
|
<Layout.Vertical spacing="xsmall">
|
||||||
<Text font={{ variation: FontVariation.TINY }}>
|
<Text>{getString('public')}</Text>
|
||||||
{getString('createRepoModal.publicLabel')}
|
<Text font={{ variation: FontVariation.TINY }}>
|
||||||
</Text>
|
{getString('createRepoModal.publicLabel')}
|
||||||
</Layout.Vertical>
|
</Text>
|
||||||
</Container>
|
</Layout.Vertical>
|
||||||
</Layout.Horizontal>
|
</Container>
|
||||||
</Container>
|
</Layout.Horizontal>
|
||||||
),
|
</Container>
|
||||||
value: RepoVisibility.PUBLIC
|
),
|
||||||
},
|
value: RepoVisibility.PUBLIC
|
||||||
{
|
},
|
||||||
label: (
|
{
|
||||||
<Container>
|
label: (
|
||||||
<Layout.Horizontal>
|
<Container>
|
||||||
<Container margin={{ right: 'medium' }}>
|
<Layout.Horizontal>
|
||||||
<img width={20} height={20} src={Private} />
|
<Container margin={{ right: 'medium' }}>
|
||||||
</Container>
|
<img width={20} height={20} src={Private} />
|
||||||
{/* <Icon name="git-clone-step" size={20} margin={{ right: 'medium' }} /> */}
|
</Container>
|
||||||
<Container margin={{ left: 'small' }}>
|
{/* <Icon name="git-clone-step" size={20} margin={{ right: 'medium' }} /> */}
|
||||||
<Layout.Vertical spacing="xsmall">
|
<Container margin={{ left: 'small' }}>
|
||||||
<Text>{getString('private')}</Text>
|
<Layout.Vertical spacing="xsmall">
|
||||||
<Text font={{ variation: FontVariation.TINY }}>
|
<Text>{getString('private')}</Text>
|
||||||
{getString('createRepoModal.privateLabel')}
|
<Text font={{ variation: FontVariation.TINY }}>
|
||||||
</Text>
|
{getString('createRepoModal.privateLabel')}
|
||||||
</Layout.Vertical>
|
</Text>
|
||||||
</Container>
|
</Layout.Vertical>
|
||||||
</Layout.Horizontal>
|
</Container>
|
||||||
</Container>
|
</Layout.Horizontal>
|
||||||
),
|
</Container>
|
||||||
value: RepoVisibility.PRIVATE
|
),
|
||||||
}
|
value: RepoVisibility.PRIVATE
|
||||||
]}
|
}
|
||||||
/>
|
]}
|
||||||
</Container>
|
/>
|
||||||
|
</Container>
|
||||||
|
</Render>
|
||||||
<hr className={css.dividerContainer} />
|
<hr className={css.dividerContainer} />
|
||||||
|
|
||||||
<FormInput.Select
|
<FormInput.Select
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import {
|
import {
|
||||||
Container,
|
Container,
|
||||||
Layout,
|
Layout,
|
||||||
@ -33,7 +33,8 @@ import cx from 'classnames'
|
|||||||
import { Color, FontVariation, Intent } from '@harnessio/design-system'
|
import { Color, FontVariation, Intent } from '@harnessio/design-system'
|
||||||
import { Icon } from '@harnessio/icons'
|
import { Icon } from '@harnessio/icons'
|
||||||
import { noop } from 'lodash-es'
|
import { noop } from 'lodash-es'
|
||||||
import { useMutate } from 'restful-react'
|
import { useMutate, useGet } from 'restful-react'
|
||||||
|
import { Render } from 'react-jsx-match'
|
||||||
import { ACCESS_MODES, getErrorMessage, permissionProps, voidFn } from 'utils/Utils'
|
import { ACCESS_MODES, getErrorMessage, permissionProps, voidFn } from 'utils/Utils'
|
||||||
import { useStrings } from 'framework/strings'
|
import { useStrings } from 'framework/strings'
|
||||||
import type { TypesRepository } from 'services/code'
|
import type { TypesRepository } from 'services/code'
|
||||||
@ -64,6 +65,7 @@ const GeneralSettingsContent = (props: GeneralSettingsProps) => {
|
|||||||
const currRepoVisibility = repoMetadata?.is_public === true ? RepoVisibility.PUBLIC : RepoVisibility.PRIVATE
|
const currRepoVisibility = repoMetadata?.is_public === true ? RepoVisibility.PUBLIC : RepoVisibility.PRIVATE
|
||||||
|
|
||||||
const [repoVis, setRepoVis] = useState<RepoVisibility>(currRepoVisibility)
|
const [repoVis, setRepoVis] = useState<RepoVisibility>(currRepoVisibility)
|
||||||
|
const [enablePublicRepo, setEnablePublicRepo] = useState(false)
|
||||||
const { mutate } = useMutate({
|
const { mutate } = useMutate({
|
||||||
verb: 'PATCH',
|
verb: 'PATCH',
|
||||||
path: `/api/v1/repos/${repoMetadata?.path}/+/`
|
path: `/api/v1/repos/${repoMetadata?.path}/+/`
|
||||||
@ -87,6 +89,14 @@ const GeneralSettingsContent = (props: GeneralSettingsProps) => {
|
|||||||
},
|
},
|
||||||
[space]
|
[space]
|
||||||
)
|
)
|
||||||
|
const { data: systemConfig } = useGet({ path: 'api/v1/system/config' })
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (systemConfig) {
|
||||||
|
setEnablePublicRepo(systemConfig.public_resource_creation_enabled)
|
||||||
|
}
|
||||||
|
}, [systemConfig])
|
||||||
|
|
||||||
const ModalComponent: React.FC = () => {
|
const ModalComponent: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
@ -231,87 +241,89 @@ const GeneralSettingsContent = (props: GeneralSettingsProps) => {
|
|||||||
</Container>
|
</Container>
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
</Container>
|
</Container>
|
||||||
<Container padding="large" margin={{ bottom: 'medium' }} className={css.generalContainer}>
|
<Render when={enablePublicRepo}>
|
||||||
<Layout.Horizontal padding={{ bottom: 'medium' }}>
|
<Container padding="large" margin={{ bottom: 'medium' }} className={css.generalContainer}>
|
||||||
<Container className={css.label}>
|
<Layout.Horizontal padding={{ bottom: 'medium' }}>
|
||||||
<Text color={Color.GREY_600} font={{ size: 'small' }}>
|
<Container className={css.label}>
|
||||||
{getString('repoVisibility')}
|
<Text color={Color.GREY_600} font={{ size: 'small' }}>
|
||||||
</Text>
|
{getString('repoVisibility')}
|
||||||
</Container>
|
</Text>
|
||||||
<Container className={css.content}>
|
</Container>
|
||||||
<FormInput.RadioGroup
|
<Container className={css.content}>
|
||||||
name="isPublic"
|
<FormInput.RadioGroup
|
||||||
label=""
|
name="isPublic"
|
||||||
onChange={evt => {
|
label=""
|
||||||
setRepoVis((evt.target as HTMLInputElement).value as RepoVisibility)
|
onChange={evt => {
|
||||||
}}
|
setRepoVis((evt.target as HTMLInputElement).value as RepoVisibility)
|
||||||
className={css.radioContainer}
|
}}
|
||||||
items={[
|
className={css.radioContainer}
|
||||||
{
|
items={[
|
||||||
label: (
|
{
|
||||||
<Container>
|
label: (
|
||||||
<Layout.Horizontal>
|
<Container>
|
||||||
<Icon
|
<Layout.Horizontal>
|
||||||
className={css.iconContainer}
|
<Icon
|
||||||
name="git-clone-step"
|
className={css.iconContainer}
|
||||||
size={20}
|
name="git-clone-step"
|
||||||
margin={{ left: 'small', right: 'medium' }}
|
size={20}
|
||||||
/>
|
margin={{ left: 'small', right: 'medium' }}
|
||||||
<Container>
|
/>
|
||||||
<Layout.Vertical spacing="xsmall">
|
<Container>
|
||||||
<Text font={{ size: 'small' }}>{getString('public')}</Text>
|
<Layout.Vertical spacing="xsmall">
|
||||||
<Text font={{ variation: FontVariation.TINY }}>
|
<Text font={{ size: 'small' }}>{getString('public')}</Text>
|
||||||
{getString('createRepoModal.publicLabel')}
|
<Text font={{ variation: FontVariation.TINY }}>
|
||||||
</Text>
|
{getString('createRepoModal.publicLabel')}
|
||||||
</Layout.Vertical>
|
</Text>
|
||||||
</Container>
|
</Layout.Vertical>
|
||||||
</Layout.Horizontal>
|
</Container>
|
||||||
</Container>
|
</Layout.Horizontal>
|
||||||
),
|
</Container>
|
||||||
|
),
|
||||||
|
|
||||||
value: RepoVisibility.PUBLIC
|
value: RepoVisibility.PUBLIC
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: (
|
label: (
|
||||||
<Container>
|
<Container>
|
||||||
<Layout.Horizontal>
|
<Layout.Horizontal>
|
||||||
<Container className={css.iconContainer} margin={{ left: 'small', right: 'medium' }}>
|
<Container className={css.iconContainer} margin={{ left: 'small', right: 'medium' }}>
|
||||||
<img width={20} height={20} src={Private} />
|
<img width={20} height={20} src={Private} />
|
||||||
</Container>
|
</Container>
|
||||||
<Container margin={{ left: 'small' }}>
|
<Container margin={{ left: 'small' }}>
|
||||||
<Layout.Vertical spacing="xsmall">
|
<Layout.Vertical spacing="xsmall">
|
||||||
<Text font={{ size: 'small' }}>{getString('private')}</Text>
|
<Text font={{ size: 'small' }}>{getString('private')}</Text>
|
||||||
<Text font={{ variation: FontVariation.TINY }}>
|
<Text font={{ variation: FontVariation.TINY }}>
|
||||||
{getString('createRepoModal.privateLabel')}
|
{getString('createRepoModal.privateLabel')}
|
||||||
</Text>
|
</Text>
|
||||||
</Layout.Vertical>
|
</Layout.Vertical>
|
||||||
</Container>
|
</Container>
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
</Container>
|
</Container>
|
||||||
),
|
),
|
||||||
value: RepoVisibility.PRIVATE
|
value: RepoVisibility.PRIVATE
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<hr className={css.dividerContainer} />
|
<hr className={css.dividerContainer} />
|
||||||
<Layout.Horizontal className={css.buttonContainer}>
|
<Layout.Horizontal className={css.buttonContainer}>
|
||||||
{repoVis !== currRepoVisibility ? (
|
{repoVis !== currRepoVisibility ? (
|
||||||
<Button
|
<Button
|
||||||
margin={{ right: 'medium' }}
|
margin={{ right: 'medium' }}
|
||||||
type="submit"
|
type="submit"
|
||||||
text={getString('save')}
|
text={getString('save')}
|
||||||
variation={ButtonVariation.PRIMARY}
|
variation={ButtonVariation.PRIMARY}
|
||||||
size={ButtonSize.SMALL}
|
size={ButtonSize.SMALL}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setRepoVis(formik.values.isPublic)
|
setRepoVis(formik.values.isPublic)
|
||||||
openModal()
|
openModal()
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
</Container>
|
</Container>
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
</Container>
|
</Container>
|
||||||
|
</Render>
|
||||||
<Container padding="medium" className={css.generalContainer}>
|
<Container padding="medium" className={css.generalContainer}>
|
||||||
<Container className={css.deleteContainer}>
|
<Container className={css.deleteContainer}>
|
||||||
<Text icon="main-trash" color={Color.GREY_600} font={{ size: 'small' }}>
|
<Text icon="main-trash" color={Color.GREY_600} font={{ size: 'small' }}>
|
||||||
|
@ -58,7 +58,6 @@ export interface ImportFormData {
|
|||||||
password: string
|
password: string
|
||||||
name: string
|
name: string
|
||||||
description: string
|
description: string
|
||||||
isPublic: RepoVisibility
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExportFormData {
|
export interface ExportFormData {
|
||||||
|
Loading…
Reference in New Issue
Block a user