[CODE-1159] UI to disable public repo creation with a flag - GITNESS_PUBLIC_RESOURCE_CREATION_ENABLED (#895)

This commit is contained in:
Ritik Kapoor 2023-12-18 08:42:38 +00:00 committed by Harness
parent b24729d608
commit cb817bf2ad
4 changed files with 171 additions and 198 deletions

View File

@ -18,20 +18,11 @@ import React, { useState } from 'react'
import { Intent } from '@blueprintjs/core'
import * as yup from 'yup'
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 { FontVariation } from '@harnessio/design-system'
import { useStrings } from 'framework/strings'
import { REGEX_VALID_REPO_NAME } from 'utils/Utils'
import {
ImportFormData,
RepoVisibility,
GitProviders,
getProviders,
getOrgLabel,
getOrgPlaceholder
} from 'utils/GitUtils'
import Private from '../../../icons/private.svg'
import { ImportFormData, GitProviders, getProviders, getOrgLabel, getOrgPlaceholder } from 'utils/GitUtils'
import css from '../NewRepoModalButton.module.scss'
interface ImportFormProps {
@ -56,8 +47,7 @@ const ImportForm = (props: ImportFormProps) => {
username: '',
password: '',
name: '',
description: '',
isPublic: RepoVisibility.PRIVATE
description: ''
}
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
spacing="small"
padding={{ right: 'xxlarge', top: 'xlarge', bottom: 'large' }}

View File

@ -46,6 +46,7 @@ import {
import { Icon } from '@harnessio/icons'
import { Color, FontVariation } from '@harnessio/design-system'
import { useGet, useMutate } from 'restful-react'
import { Render } from 'react-jsx-match'
import { get } from 'lodash-es'
import { useModalHook } from 'hooks/useModalHook'
import { useStrings } from 'framework/strings'
@ -107,6 +108,7 @@ export const NewRepoModalButton: React.FC<NewRepoModalButtonProps> = ({
const ModalComponent: React.FC = () => {
const { getString } = useStrings()
const [branchName, setBranchName] = useState(DEFAULT_BRANCH_NAME)
const [enablePublicRepo, setEnablePublicRepo] = useState(false)
const { showError } = useToaster()
const { mutate: createRepo, loading: submitLoading } = useMutate<TypesRepository>({
@ -141,13 +143,31 @@ export const NewRepoModalButton: React.FC<NewRepoModalButtonProps> = ({
loading: licenseLoading,
error: licenseError
} = 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(() => {
if (gitIgnoreError || licenseError) {
showError(getErrorMessage(gitIgnoreError || licenseError), 0)
if (gitIgnoreError || licenseError || systemConfigError) {
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) => {
try {
const payload: OpenapiCreateRepositoryRequest = {
@ -309,54 +329,56 @@ export const NewRepoModalButton: React.FC<NewRepoModalButtonProps> = ({
{getString('createRepoModal.branch')}
</Text>
</Container>
<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>
<Render when={enablePublicRepo}>
<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>
</Render>
<hr className={css.dividerContainer} />
<FormInput.Select

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import React, { useState } from 'react'
import React, { useState, useEffect } from 'react'
import {
Container,
Layout,
@ -33,7 +33,8 @@ import cx from 'classnames'
import { Color, FontVariation, Intent } from '@harnessio/design-system'
import { Icon } from '@harnessio/icons'
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 { useStrings } from 'framework/strings'
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 [repoVis, setRepoVis] = useState<RepoVisibility>(currRepoVisibility)
const [enablePublicRepo, setEnablePublicRepo] = useState(false)
const { mutate } = useMutate({
verb: 'PATCH',
path: `/api/v1/repos/${repoMetadata?.path}/+/`
@ -87,6 +89,14 @@ const GeneralSettingsContent = (props: GeneralSettingsProps) => {
},
[space]
)
const { data: systemConfig } = useGet({ path: 'api/v1/system/config' })
useEffect(() => {
if (systemConfig) {
setEnablePublicRepo(systemConfig.public_resource_creation_enabled)
}
}, [systemConfig])
const ModalComponent: React.FC = () => {
return (
<Dialog
@ -231,87 +241,89 @@ const GeneralSettingsContent = (props: GeneralSettingsProps) => {
</Container>
</Layout.Horizontal>
</Container>
<Container padding="large" margin={{ bottom: 'medium' }} className={css.generalContainer}>
<Layout.Horizontal padding={{ bottom: 'medium' }}>
<Container className={css.label}>
<Text color={Color.GREY_600} font={{ size: 'small' }}>
{getString('repoVisibility')}
</Text>
</Container>
<Container className={css.content}>
<FormInput.RadioGroup
name="isPublic"
label=""
onChange={evt => {
setRepoVis((evt.target as HTMLInputElement).value as RepoVisibility)
}}
className={css.radioContainer}
items={[
{
label: (
<Container>
<Layout.Horizontal>
<Icon
className={css.iconContainer}
name="git-clone-step"
size={20}
margin={{ left: 'small', right: 'medium' }}
/>
<Container>
<Layout.Vertical spacing="xsmall">
<Text font={{ size: 'small' }}>{getString('public')}</Text>
<Text font={{ variation: FontVariation.TINY }}>
{getString('createRepoModal.publicLabel')}
</Text>
</Layout.Vertical>
</Container>
</Layout.Horizontal>
</Container>
),
<Render when={enablePublicRepo}>
<Container padding="large" margin={{ bottom: 'medium' }} className={css.generalContainer}>
<Layout.Horizontal padding={{ bottom: 'medium' }}>
<Container className={css.label}>
<Text color={Color.GREY_600} font={{ size: 'small' }}>
{getString('repoVisibility')}
</Text>
</Container>
<Container className={css.content}>
<FormInput.RadioGroup
name="isPublic"
label=""
onChange={evt => {
setRepoVis((evt.target as HTMLInputElement).value as RepoVisibility)
}}
className={css.radioContainer}
items={[
{
label: (
<Container>
<Layout.Horizontal>
<Icon
className={css.iconContainer}
name="git-clone-step"
size={20}
margin={{ left: 'small', right: 'medium' }}
/>
<Container>
<Layout.Vertical spacing="xsmall">
<Text font={{ size: 'small' }}>{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 className={css.iconContainer} margin={{ left: 'small', right: 'medium' }}>
<img width={20} height={20} src={Private} />
</Container>
<Container margin={{ left: 'small' }}>
<Layout.Vertical spacing="xsmall">
<Text font={{ size: 'small' }}>{getString('private')}</Text>
<Text font={{ variation: FontVariation.TINY }}>
{getString('createRepoModal.privateLabel')}
</Text>
</Layout.Vertical>
</Container>
</Layout.Horizontal>
</Container>
),
value: RepoVisibility.PRIVATE
}
]}
/>
<hr className={css.dividerContainer} />
<Layout.Horizontal className={css.buttonContainer}>
{repoVis !== currRepoVisibility ? (
<Button
margin={{ right: 'medium' }}
type="submit"
text={getString('save')}
variation={ButtonVariation.PRIMARY}
size={ButtonSize.SMALL}
onClick={() => {
setRepoVis(formik.values.isPublic)
openModal()
}}
/>
) : null}
</Layout.Horizontal>
</Container>
</Layout.Horizontal>
</Container>
value: RepoVisibility.PUBLIC
},
{
label: (
<Container>
<Layout.Horizontal>
<Container className={css.iconContainer} margin={{ left: 'small', right: 'medium' }}>
<img width={20} height={20} src={Private} />
</Container>
<Container margin={{ left: 'small' }}>
<Layout.Vertical spacing="xsmall">
<Text font={{ size: 'small' }}>{getString('private')}</Text>
<Text font={{ variation: FontVariation.TINY }}>
{getString('createRepoModal.privateLabel')}
</Text>
</Layout.Vertical>
</Container>
</Layout.Horizontal>
</Container>
),
value: RepoVisibility.PRIVATE
}
]}
/>
<hr className={css.dividerContainer} />
<Layout.Horizontal className={css.buttonContainer}>
{repoVis !== currRepoVisibility ? (
<Button
margin={{ right: 'medium' }}
type="submit"
text={getString('save')}
variation={ButtonVariation.PRIMARY}
size={ButtonSize.SMALL}
onClick={() => {
setRepoVis(formik.values.isPublic)
openModal()
}}
/>
) : null}
</Layout.Horizontal>
</Container>
</Layout.Horizontal>
</Container>
</Render>
<Container padding="medium" className={css.generalContainer}>
<Container className={css.deleteContainer}>
<Text icon="main-trash" color={Color.GREY_600} font={{ size: 'small' }}>

View File

@ -58,7 +58,6 @@ export interface ImportFormData {
password: string
name: string
description: string
isPublic: RepoVisibility
}
export interface ExportFormData {