feat: [AH-370]: export create registry button from gitness to use in harness ng ui (#2737)

* feat: [AH-370]: export create registry button from gitness to use in harness ng ui
This commit is contained in:
Shivanand Sonnad 2024-09-25 09:24:00 +00:00 committed by Harness
parent 2b3b8b3503
commit 8f2744668c
7 changed files with 102 additions and 21 deletions

View File

@ -55,7 +55,8 @@ module.exports = {
'./Labels': './src/pages/ManageSpace/ManageLabels/ManageLabels.tsx', './Labels': './src/pages/ManageSpace/ManageLabels/ManageLabels.tsx',
'./WebhookDetails': './src/pages/WebhookDetails/WebhookDetails.tsx', './WebhookDetails': './src/pages/WebhookDetails/WebhookDetails.tsx',
'./NewRepoModalButton': './src/components/NewRepoModalButton/NewRepoModalButton.tsx', './NewRepoModalButton': './src/components/NewRepoModalButton/NewRepoModalButton.tsx',
'./HAREnterpriseApp': './src/ar/app/EnterpriseApp.tsx' './HAREnterpriseApp': './src/ar/app/EnterpriseApp.tsx',
'./HARCreateRegistryButton': './src/ar/views/CreateRegistryButton/CreateRegistryButton.tsx'
}, },
shared: { shared: {
formik: packageJSON.dependencies['formik'], formik: packageJSON.dependencies['formik'],

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
import React, { Suspense, useEffect, useRef } from 'react' import React, { PropsWithChildren, Suspense, useEffect, useRef } from 'react'
import { Page } from '@harnessio/uicore' import { Page } from '@harnessio/uicore'
import { HARServiceAPIClient } from '@harnessio/react-har-service-client' import { HARServiceAPIClient } from '@harnessio/react-har-service-client'
import { QueryClientProvider } from '@tanstack/react-query' import { QueryClientProvider } from '@tanstack/react-query'
@ -35,7 +35,7 @@ import css from '@ar/app/app.module.scss'
const RouteDestinations = React.lazy(() => import('@ar/routes/RouteDestinations')) const RouteDestinations = React.lazy(() => import('@ar/routes/RouteDestinations'))
export default function ChildApp(props: MFEAppProps): React.ReactElement { export default function ChildApp(props: PropsWithChildren<MFEAppProps>): React.ReactElement {
const { const {
renderUrl, renderUrl,
parentContextObj, parentContextObj,
@ -105,6 +105,7 @@ export default function ChildApp(props: MFEAppProps): React.ReactElement {
components={{ ...components, ...customComponents } as ParentProviderProps['components']} components={{ ...components, ...customComponents } as ParentProviderProps['components']}
utils={{ ...customUtils }}> utils={{ ...customUtils }}>
<ModalProvider> <ModalProvider>
{props.children ?? (
<NavComponent> <NavComponent>
<Suspense <Suspense
fallback={ fallback={
@ -115,6 +116,7 @@ export default function ChildApp(props: MFEAppProps): React.ReactElement {
<RouteDestinations /> <RouteDestinations />
</Suspense> </Suspense>
</NavComponent> </NavComponent>
)}
</ModalProvider> </ModalProvider>
</ParentProvider> </ParentProvider>
</StringsContextProvider> </StringsContextProvider>

View File

@ -49,6 +49,7 @@ import css from './RepositoryDetailsForm.module.scss'
interface FormContentProps { interface FormContentProps {
formikProps: FormikProps<VirtualRegistryRequest> formikProps: FormikProps<VirtualRegistryRequest>
allowedPackageTypes?: RepositoryPackageType[]
getDefaultValuesByRepositoryType: ( getDefaultValuesByRepositoryType: (
type: RepositoryPackageType, type: RepositoryPackageType,
defaultValue: VirtualRegistryRequest defaultValue: VirtualRegistryRequest
@ -56,7 +57,7 @@ interface FormContentProps {
} }
function FormContent(props: FormContentProps): JSX.Element { function FormContent(props: FormContentProps): JSX.Element {
const { formikProps, getDefaultValuesByRepositoryType } = props const { formikProps, getDefaultValuesByRepositoryType, allowedPackageTypes } = props
const { getString } = useStrings() const { getString } = useStrings()
const { values } = formikProps const { values } = formikProps
const { packageType, config } = values const { packageType, config } = values
@ -78,7 +79,8 @@ function FormContent(props: FormContentProps): JSX.Element {
name="packageType" name="packageType"
items={RepositoryTypes.map(each => ({ items={RepositoryTypes.map(each => ({
...each, ...each,
label: getString(each.label) label: getString(each.label),
disabled: allowedPackageTypes?.length ? !allowedPackageTypes.includes(each.value) : each.disabled
}))} }))}
staticItems staticItems
/> />
@ -97,12 +99,13 @@ function FormContent(props: FormContentProps): JSX.Element {
interface RepositoryCreateFormProps { interface RepositoryCreateFormProps {
factory?: RepositoryAbstractFactory factory?: RepositoryAbstractFactory
defaultType?: RepositoryPackageType defaultType?: RepositoryPackageType
allowedPackageTypes?: RepositoryPackageType[]
setShowOverlay: (show: boolean) => void setShowOverlay: (show: boolean) => void
onSuccess: (data: Repository) => void onSuccess: (data: Repository) => void
} }
function RepositoryCreateForm(props: RepositoryCreateFormProps, formikRef: FormikFowardRef): JSX.Element { function RepositoryCreateForm(props: RepositoryCreateFormProps, formikRef: FormikFowardRef): JSX.Element {
const { defaultType = RepositoryPackageType.DOCKER, factory = repositoryFactory, onSuccess, setShowOverlay } = props const { defaultType, factory = repositoryFactory, onSuccess, setShowOverlay, allowedPackageTypes } = props
const { getString } = useStrings() const { getString } = useStrings()
const parentRef = useGetSpaceRef() const parentRef = useGetSpaceRef()
const { showSuccess, showError, clear } = useToaster() const { showSuccess, showError, clear } = useToaster()
@ -125,7 +128,10 @@ function RepositoryCreateForm(props: RepositoryCreateFormProps, formikRef: Formi
) )
const getInitialValues = (): VirtualRegistryRequest => { const getInitialValues = (): VirtualRegistryRequest => {
return getDefaultValuesByRepositoryType(defaultType) const defaultSelectedPackageType = allowedPackageTypes?.length
? allowedPackageTypes[0]
: RepositoryPackageType.DOCKER
return getDefaultValuesByRepositoryType(defaultType ?? defaultSelectedPackageType)
} }
const handleSubmit = async (values: VirtualRegistryRequest): Promise<void> => { const handleSubmit = async (values: VirtualRegistryRequest): Promise<void> => {
@ -170,7 +176,11 @@ function RepositoryCreateForm(props: RepositoryCreateFormProps, formikRef: Formi
setFormikRef(formikRef, formik) setFormikRef(formikRef, formik)
return ( return (
<Container className={css.formContainer}> <Container className={css.formContainer}>
<FormContent formikProps={formik} getDefaultValuesByRepositoryType={getDefaultValuesByRepositoryType} /> <FormContent
allowedPackageTypes={allowedPackageTypes}
formikProps={formik}
getDefaultValuesByRepositoryType={getDefaultValuesByRepositoryType}
/>
</Container> </Container>
) )
}} }}

View File

@ -21,15 +21,17 @@ import { Button, ButtonVariation, Layout, ModalDialog, Text } from '@harnessio/u
import { useParentHooks } from '@ar/hooks' import { useParentHooks } from '@ar/hooks'
import { useStrings } from '@ar/frameworks/strings' import { useStrings } from '@ar/frameworks/strings'
import type { RepositoryPackageType } from '@ar/common/types'
import RepositoryCreateForm from '@ar/pages/repository-details/components/Forms/RepositoryCreateForm' import RepositoryCreateForm from '@ar/pages/repository-details/components/Forms/RepositoryCreateForm'
import type { Repository } from '@ar/pages/repository-details/types' import type { Repository } from '@ar/pages/repository-details/types'
interface useCreateRepositoryModalProps { interface useCreateRepositoryModalProps {
onSuccess: (data: Repository) => void onSuccess: (data: Repository) => void
allowedPackageTypes?: RepositoryPackageType[]
} }
export function useCreateRepositoryModal(props: useCreateRepositoryModalProps) { export function useCreateRepositoryModal(props: useCreateRepositoryModalProps) {
const { onSuccess } = props const { onSuccess, allowedPackageTypes } = props
const { getString } = useStrings() const { getString } = useStrings()
const { useModalHook } = useParentHooks() const { useModalHook } = useParentHooks()
const [showOverlay, setShowOverlay] = useState(false) const [showOverlay, setShowOverlay] = useState(false)
@ -62,7 +64,6 @@ export function useCreateRepositoryModal(props: useCreateRepositoryModalProps) {
} }
isCloseButtonShown isCloseButtonShown
width={800} width={800}
showOverlay={showOverlay}
footer={ footer={
<Layout.Horizontal spacing="small"> <Layout.Horizontal spacing="small">
<Button <Button
@ -76,7 +77,12 @@ export function useCreateRepositoryModal(props: useCreateRepositoryModalProps) {
<Button variation={ButtonVariation.TERTIARY} text={getString('cancel')} onClick={hideModal} /> <Button variation={ButtonVariation.TERTIARY} text={getString('cancel')} onClick={hideModal} />
</Layout.Horizontal> </Layout.Horizontal>
}> }>
<RepositoryCreateForm onSuccess={onSuccess} setShowOverlay={setShowOverlay} ref={stepRef} /> <RepositoryCreateForm
allowedPackageTypes={allowedPackageTypes}
onSuccess={onSuccess}
setShowOverlay={setShowOverlay}
ref={stepRef}
/>
</ModalDialog> </ModalDialog>
), ),
[showOverlay] [showOverlay]

View File

@ -1,5 +1,6 @@
pageHeading: Artifact Registries pageHeading: Artifact Registries
newRepository: New Artifact Registry newRepository: New Artifact Registry
newRegistry: New Registry
artifactRegistry: artifactRegistry:
label: Artifact Registry label: Artifact Registry
subLabel: Manage internal packages and external dependencies through a unified registry. subLabel: Manage internal packages and external dependencies through a unified registry.

View File

@ -94,6 +94,7 @@ export interface StringsMap {
'repositoryList.artifactRegistry.subLabel': string 'repositoryList.artifactRegistry.subLabel': string
'repositoryList.deleteModal.contentText': string 'repositoryList.deleteModal.contentText': string
'repositoryList.deleteModal.title': string 'repositoryList.deleteModal.title': string
'repositoryList.newRegistry': string
'repositoryList.newRepository': string 'repositoryList.newRepository': string
'repositoryList.pageHeading': string 'repositoryList.pageHeading': string
'repositoryList.selectEnvironments': string 'repositoryList.selectEnvironments': string

View File

@ -0,0 +1,60 @@
/*
* Copyright 2024 Harness, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react'
import { ButtonVariation } from '@harnessio/uicore'
import { useParentComponents } from '@ar/hooks'
import { useStrings } from '@ar/frameworks/strings'
import type { RepositoryPackageType } from '@ar/common/types'
import type { Repository } from '@ar/pages/repository-details/types'
import type { RbacButtonProps } from '@ar/__mocks__/components/RbacButton'
import { useCreateRepositoryModal } from '@ar/pages/repository-details/hooks/useCreateRepositoryModal/useCreateRepositoryModal'
import '@ar/pages/version-details/VersionFactory'
import '@ar/pages/repository-details/RepositoryFactory'
interface CreateRegistryButtonProps extends RbacButtonProps {
onSuccess: (data: Repository) => void
allowedPackageTypes?: RepositoryPackageType[]
}
export default function CreateRegistryButton(props: CreateRegistryButtonProps) {
const { onSuccess, allowedPackageTypes, ...rest } = props
const { RbacButton } = useParentComponents()
const { getString } = useStrings()
const [show, hide] = useCreateRepositoryModal({
onSuccess: data => {
hide()
onSuccess(data)
},
allowedPackageTypes
})
return (
<RbacButton
variation={ButtonVariation.SECONDARY}
icon={'plus'}
iconProps={{ size: 10 }}
text={getString('repositoryList.newRegistry')}
{...rest}
onClick={() => {
show()
}}
/>
)
}