From a6894572a4167d2beb167192173da5b235235390 Mon Sep 17 00:00:00 2001 From: Deepesh Kumar Date: Wed, 5 Jun 2024 17:35:31 +0000 Subject: [PATCH] feat: [CDE-42]: Gitspace UI changes (#2078) --- .../CreateGitspace/CreateGitspace.tsx | 77 +- .../components/SelectIDE/SelectIDE.tsx | 4 +- .../SelectInfraProvider.tsx | 7 +- .../SelectMachine/SelectMachine.module.scss | 4 + .../SelectMachine.module.scss.d.ts | 19 + .../SelectMachine/SelectMachine.tsx | 68 +- .../components/SelectRegion/SelectRegion.tsx | 45 +- .../components/SelectRegion/assests/Empty.png | Bin 0 -> 52082 bytes .../SelectRepository/SelectRepository.tsx | 53 +- .../GitspaceDetails/GitspaceDetails.tsx | 186 ++++- .../GitspaceLogs/GitspaceLogs.module.scss | 7 +- .../GitspaceLogs.module.scss.d.ts | 1 + .../components/GitspaceLogs/GitspaceLogs.tsx | 85 +- .../GitspaceLogs/GitspaceLogs.utils.ts | 38 + .../ListGitspaces/ListGitspaces.module.scss | 8 +- .../ListGitspaces.module.scss.d.ts | 1 + .../ListGitspaces/ListGitspaces.tsx | 92 ++- web/src/cde/constants/index.ts | 4 +- .../GitspaceDetail/GitspaceDetail.module.scss | 4 +- .../pages/GitspaceDetail/GitspaceDetail.tsx | 85 +- .../GitspacesListing/GitspacesListing.tsx | 37 +- web/src/cde/pages/GitspacesListing/mock.ts | 12 +- web/src/framework/strings/stringTypes.ts | 3 + web/src/i18n/strings.en.yaml | 5 +- web/src/services/cde/index.tsx | 59 +- web/src/services/cde/swagger.yaml | 777 +++++++++--------- 26 files changed, 1058 insertions(+), 623 deletions(-) create mode 100644 web/src/cde/components/CreateGitspace/components/SelectMachine/SelectMachine.module.scss create mode 100644 web/src/cde/components/CreateGitspace/components/SelectMachine/SelectMachine.module.scss.d.ts create mode 100644 web/src/cde/components/CreateGitspace/components/SelectRegion/assests/Empty.png create mode 100644 web/src/cde/components/GitspaceLogs/GitspaceLogs.utils.ts diff --git a/web/src/cde/components/CreateGitspace/CreateGitspace.tsx b/web/src/cde/components/CreateGitspace/CreateGitspace.tsx index 742d39dbd..f3e59af6e 100644 --- a/web/src/cde/components/CreateGitspace/CreateGitspace.tsx +++ b/web/src/cde/components/CreateGitspace/CreateGitspace.tsx @@ -16,12 +16,15 @@ import React from 'react' import * as yup from 'yup' -import { Button, ButtonVariation, Card, Formik, FormikForm, Layout, Text } from '@harnessio/uicore' +import { Button, ButtonVariation, Card, Formik, FormikForm, Layout, Text, useToaster } from '@harnessio/uicore' import { FontVariation } from '@harnessio/design-system' -import { useCreateGitspace, type EnumCodeRepoType, type EnumIDEType } from 'services/cde' +import { useHistory } from 'react-router-dom' +import { useCreateGitspace, OpenapiCreateGitspaceRequest } from 'services/cde' import { useGetSpaceParam } from 'hooks/useGetSpaceParam' import { useStrings } from 'framework/strings' import { IDEType } from 'cde/constants' +import { useAppContext } from 'AppContext' +import { getErrorMessage } from 'utils/Utils' import { SelectIDE } from './components/SelectIDE/SelectIDE' import { SelectRepository } from './components/SelectRepository/SelectRepository' import { BranchInput } from './components/BranchInput/BranchInput' @@ -32,33 +35,53 @@ const initData = { ide: IDEType.VSCODE } -export interface GitspaceFormInterface { - ide?: EnumIDEType - branch?: string - codeRepoId?: string - codeRepoUrl?: string - codeRepoType?: EnumCodeRepoType - region?: string - infra_provider_resource_id?: string -} - -interface GitspaceFormProps { - onSubmit: (data: GitspaceFormInterface) => void -} - -const GitspaceForm = ({ onSubmit }: GitspaceFormProps) => { +const GitspaceForm = () => { const { getString } = useStrings() + const { routes } = useAppContext() + const space = useGetSpaceParam() + const { showError } = useToaster() + const history = useHistory() + + const { mutate, loading, error } = useCreateGitspace({ + accountIdentifier: space?.split('/')[0], + orgIdentifier: space?.split('/')[1], + projectIdentifier: space?.split('/')[2] + }) + + if (error) { + showError(getErrorMessage(error)) + } + return ( - - onSubmit={async data => await onSubmit(data)} + + onSubmit={async data => { + try { + const createdGitspace = await mutate(data) + history.push( + `${routes.toCDEGitspaceDetail({ + space, + gitspaceId: createdGitspace?.id || '' + })}?redirectFrom=login` + ) + } catch (err) { + showError(getErrorMessage(err)) + } + }} formName={'createGitSpace'} initialValues={initData} + validateOnMount={false} validationSchema={yup.object().shape({ - codeRepoId: yup.string().trim().required(), branch: yup.string().trim().required(), + code_repo_id: yup.string().trim().required(), + code_repo_type: yup.string().trim().required(), + code_repo_url: yup.string().trim().required(), + id: yup.string().trim().required(), ide: yup.string().trim().required(), - region: yup.string().trim().required(), - infra_provider_resource_id: yup.string().trim().required() + infra_provider_resource_id: yup.string().trim().required(), + name: yup.string().trim().required(), + metadata: yup.object().shape({ + region: yup.string().trim().required() + }) })}> {_ => { return ( @@ -70,7 +93,7 @@ const GitspaceForm = ({ onSubmit }: GitspaceFormProps) => { - @@ -82,20 +105,14 @@ const GitspaceForm = ({ onSubmit }: GitspaceFormProps) => { } export const CreateGitspace = () => { - const space = useGetSpaceParam() const { getString } = useStrings() - const { mutate } = useCreateGitspace({ - accountIdentifier: space?.split('/')[0], - orgIdentifier: space?.split('/')[1], - projectIdentifier: space?.split('/')[2] - }) return ( {getString('cde.createGitspace')} - + ) } diff --git a/web/src/cde/components/CreateGitspace/components/SelectIDE/SelectIDE.tsx b/web/src/cde/components/CreateGitspace/components/SelectIDE/SelectIDE.tsx index a45cd65bd..9b19bef9e 100644 --- a/web/src/cde/components/CreateGitspace/components/SelectIDE/SelectIDE.tsx +++ b/web/src/cde/components/CreateGitspace/components/SelectIDE/SelectIDE.tsx @@ -21,8 +21,8 @@ import { useFormikContext } from 'formik' import { GitspaceSelect } from 'cde/components/GitspaceSelect/GitspaceSelect' import { useStrings, type UseStringsReturn } from 'framework/strings' import { IDEType } from 'cde/constants' +import type { OpenapiCreateGitspaceRequest } from 'services/cde' import VSCode from '../../../../icons/VSCode.svg?url' -import type { GitspaceFormInterface } from '../../CreateGitspace' export const getIDESelectItems = (getString: UseStringsReturn['getString']) => [ { label: getString('cde.ide.desktop'), value: IDEType.VSCODE }, @@ -30,7 +30,7 @@ export const getIDESelectItems = (getString: UseStringsReturn['getString']) => [ ] export const SelectIDE = () => { - const { values, errors, setFieldValue: onChange } = useFormikContext() + const { values, errors, setFieldValue: onChange } = useFormikContext() const { ide } = values const { getString } = useStrings() const IDESelectItems = getIDESelectItems(getString) diff --git a/web/src/cde/components/CreateGitspace/components/SelectInfraProvider/SelectInfraProvider.tsx b/web/src/cde/components/CreateGitspace/components/SelectInfraProvider/SelectInfraProvider.tsx index b8901222d..54ae770ba 100644 --- a/web/src/cde/components/CreateGitspace/components/SelectInfraProvider/SelectInfraProvider.tsx +++ b/web/src/cde/components/CreateGitspace/components/SelectInfraProvider/SelectInfraProvider.tsx @@ -19,13 +19,12 @@ import { defaultTo, isObject } from 'lodash-es' import { Layout } from '@harnessio/uicore' import { useFormikContext } from 'formik' import { CDEPathParams, useGetCDEAPIParams } from 'cde/hooks/useGetCDEAPIParams' -import { useListInfraProviderResources } from 'services/cde' -import type { GitspaceFormInterface } from 'cde/components/CreateGitspace/CreateGitspace' +import { OpenapiCreateGitspaceRequest, useListInfraProviderResources } from 'services/cde' import { SelectRegion } from '../SelectRegion/SelectRegion' import { SelectMachine } from '../SelectMachine/SelectMachine' export const SelectInfraProvider = () => { - const { values } = useFormikContext() + const { values } = useFormikContext() const { accountIdentifier, orgIdentifier, projectIdentifier } = useGetCDEAPIParams() as CDEPathParams const { data } = useListInfraProviderResources({ accountIdentifier, @@ -44,7 +43,7 @@ export const SelectInfraProvider = () => { const machineOptions = optionsList - ?.filter(item => item?.region === values?.region) + ?.filter(item => item?.region === values?.metadata?.region) ?.map(item => { return { ...item } }) || [] diff --git a/web/src/cde/components/CreateGitspace/components/SelectMachine/SelectMachine.module.scss b/web/src/cde/components/CreateGitspace/components/SelectMachine/SelectMachine.module.scss new file mode 100644 index 000000000..fe2e99b71 --- /dev/null +++ b/web/src/cde/components/CreateGitspace/components/SelectMachine/SelectMachine.module.scss @@ -0,0 +1,4 @@ +.tags { + background: var(--grey-100) !important; + border-radius: 10px; +} diff --git a/web/src/cde/components/CreateGitspace/components/SelectMachine/SelectMachine.module.scss.d.ts b/web/src/cde/components/CreateGitspace/components/SelectMachine/SelectMachine.module.scss.d.ts new file mode 100644 index 000000000..7e5cf0d8d --- /dev/null +++ b/web/src/cde/components/CreateGitspace/components/SelectMachine/SelectMachine.module.scss.d.ts @@ -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 tags: string diff --git a/web/src/cde/components/CreateGitspace/components/SelectMachine/SelectMachine.tsx b/web/src/cde/components/CreateGitspace/components/SelectMachine/SelectMachine.tsx index 705269c94..9fbd072b5 100644 --- a/web/src/cde/components/CreateGitspace/components/SelectMachine/SelectMachine.tsx +++ b/web/src/cde/components/CreateGitspace/components/SelectMachine/SelectMachine.tsx @@ -19,16 +19,11 @@ import { Layout, Text } from '@harnessio/uicore' import { Menu, MenuItem } from '@blueprintjs/core' import { Cpu } from 'iconoir-react' import { useFormikContext } from 'formik' +import { FontVariation } from '@harnessio/design-system' import { GitspaceSelect } from 'cde/components/GitspaceSelect/GitspaceSelect' -import type { TypesInfraProviderResourceResponse } from 'services/cde' +import type { OpenapiCreateGitspaceRequest, TypesInfraProviderResourceResponse } from 'services/cde' import { useStrings } from 'framework/strings' -import RAM8 from './assests/RAM8.svg?url' -import RAM16 from './assests/RAM16.svg?url' -import Storage32 from './assests/Storage32.svg?url' -import Storage64 from './assests/Storage64.svg?url' -import CPU4Cores from './assests/CPU4Cores.svg?url' -import CPU8Cores from './assests/CPU8Cores.svg?url' -import type { GitspaceFormInterface } from '../../CreateGitspace' +import css from './SelectMachine.module.scss' export const machineIdToLabel = { '4core_8gb_32gb': 'Standard', @@ -46,26 +41,30 @@ interface SelectMachineInterface { export const SelectMachine = ({ options }: SelectMachineInterface) => { const { getString } = useStrings() - const { values, errors, setFieldValue: onChange } = useFormikContext() + const { values, errors, setFieldValue: onChange } = useFormikContext() const { infra_provider_resource_id: machine } = values const [machineState, setMachineState] = useState(machine || '') const machineTypes = options.map(item => { - const { cpu, disk, memory, infra_provider_config_id } = item + const { cpu, disk, memory, id, name } = item return { - infra_provider_config_id, - id: `${cpu}_${disk}_${memory}`, - label: machineIdToLabel[`${cpu}_${disk}_${memory}` as keyof typeof machineIdToLabel] + id, + label: name, + cpu, + disk, + memory } }) + const data = (machineTypes?.find(item => item.id === machine) || {}) as (typeof machineTypes)[0] + return ( - {machine || getString('cde.machine')} + {data.label || getString('cde.machine')} } errorMessage={errors.infra_provider_resource_id} @@ -76,15 +75,26 @@ export const SelectMachine = ({ options }: SelectMachineInterface) => { {machineTypes.map(item => { return ( - {machineIdToLabel[item.id as keyof typeof machineIdToLabel]} - + + {item.label?.toUpperCase()} + + + Cpu: {item.cpu} + + + Disk: {item.disk} + + + Memory: {item.memory} + + + } onClick={() => { - onChange('infra_provider_resource_id', item.infra_provider_config_id || '') + onChange('infra_provider_resource_id', item.id || '') }} onMouseOver={(e: React.MouseEvent) => { const dd = e.currentTarget.innerText as keyof typeof labelToMachineId @@ -94,26 +104,6 @@ export const SelectMachine = ({ options }: SelectMachineInterface) => { ) })} - - {machineState === labelToMachineId.Standard && ( - - - - - - - - )} - {machineState === labelToMachineId.Large && ( - - - - - - - - )} - } /> diff --git a/web/src/cde/components/CreateGitspace/components/SelectRegion/SelectRegion.tsx b/web/src/cde/components/CreateGitspace/components/SelectRegion/SelectRegion.tsx index 385b7ba09..697716177 100644 --- a/web/src/cde/components/CreateGitspace/components/SelectRegion/SelectRegion.tsx +++ b/web/src/cde/components/CreateGitspace/components/SelectRegion/SelectRegion.tsx @@ -22,21 +22,37 @@ import { useFormikContext } from 'formik' import { GitspaceSelect } from 'cde/components/GitspaceSelect/GitspaceSelect' import { useStrings } from 'framework/strings' import { GitspaceRegion } from 'cde/constants' +import type { OpenapiCreateGitspaceRequest } from 'services/cde' import USWest from './assests/USWest.png' import USEast from './assests/USEast.png' import Australia from './assests/Aus.png' import Europe from './assests/Europe.png' -import type { GitspaceFormInterface } from '../../CreateGitspace' +import Empty from './assests/Empty.png' interface SelectRegionInterface { options: SelectOption[] } +export const getMapFromRegion = (region: string) => { + switch (region) { + case GitspaceRegion.USEast: + return USEast + case GitspaceRegion.USWest: + return USWest + case GitspaceRegion.Europe: + return Europe + case GitspaceRegion.Australia: + return Australia + default: + return Empty + } +} + export const SelectRegion = ({ options }: SelectRegionInterface) => { const { getString } = useStrings() - const { values, errors, setFieldValue: onChange } = useFormikContext() - const { region = '' } = values - const [regionState, setRegionState] = useState(region) + const { values, errors, setFieldValue: onChange } = useFormikContext() + const { metadata } = values + const [regionState, setRegionState] = useState(metadata?.region) return ( { text={ - {region || getString('cde.region')} + {metadata?.region || getString('cde.region')} } - formikName="region" - errorMessage={errors.region} + formikName="metadata.region" + errorMessage={ + ( + errors['metadata'] as unknown as { + [key: string]: string + } + )?.region as unknown as string + } renderMenu={ @@ -57,9 +79,9 @@ export const SelectRegion = ({ options }: SelectRegionInterface) => { {label}} + text={{label.toUpperCase()}} onClick={() => { - onChange('region', label) + onChange('metadata.region', label.toLowerCase()) }} onMouseOver={(e: React.MouseEvent) => { setRegionState(e.currentTarget.innerText) @@ -69,10 +91,7 @@ export const SelectRegion = ({ options }: SelectRegionInterface) => { })} - {regionState === GitspaceRegion.USEast && } - {regionState === GitspaceRegion.USWest && } - {regionState === GitspaceRegion.Europe && } - {regionState === GitspaceRegion.Australia && } + } diff --git a/web/src/cde/components/CreateGitspace/components/SelectRegion/assests/Empty.png b/web/src/cde/components/CreateGitspace/components/SelectRegion/assests/Empty.png new file mode 100644 index 0000000000000000000000000000000000000000..e783ce98548daebf742c4111a782d05c0b95c199 GIT binary patch literal 52082 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 { const repoURLSplit = repoURL?.split('/') return repoURLSplit?.[repoURLSplit?.length - 1] + ?.replace(/-/g, '') + ?.replace(/_/g, '') + .replace(/\./g, '') + ?.toLowerCase() +} + +export function generateAlphaNumericHash(length: number) { + let result = '' + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + const charactersLength = characters.length + + for (let i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)) + } + + return result } const RepositoryText = ({ repoURL }: { repoURL?: string }) => { @@ -53,9 +68,9 @@ const RepositoryText = ({ repoURL }: { repoURL?: string }) => { export const SelectRepository = () => { const { getString } = useStrings() - const { values, errors, setFieldValue: onChange } = useFormikContext() + const { values, errors, setFormikState } = useFormikContext() - const { codeRepoUrl } = values + const { code_repo_url } = values const space = useGetSpaceParam() const [validatedOnce, setValidatedOnce] = useState(false) @@ -69,10 +84,10 @@ export const SelectRepository = () => { return ( } + text={} icon={'code'} - errorMessage={errors.codeRepoId} - formikName="codeRepoId" + errorMessage={errors.code_repo_url} + formikName="code_repo_url" renderMenu={ { formLoading={loading} onSubmit={() => noop()} formName={'publicURL'} - initialValues={{ url: codeRepoUrl }} + initialValues={{ url: code_repo_url }} validate={async ({ url }) => { - if (!url) { + if (!url || loading) { return {} } let errorMessages = undefined @@ -109,6 +124,7 @@ export const SelectRepository = () => { {formikProps => { if (!formikProps.touched.url && validatedOnce) { formikProps.setFieldTouched('url', true) + setRepoMetadata(undefined) } return ( @@ -135,9 +151,22 @@ export const SelectRepository = () => { { - onChange('codeRepoUrl', repoMetadata?.url || '') - onChange('codeRepoType', repoMetadata?.repo_type || '') - onChange('codeRepoId', repoMetadata?.url || '') + setFormikState((prv: any) => { + const repoId = getRepoNameFromURL(repoMetadata?.url) + const hash = generateAlphaNumericHash(5)?.toLowerCase() + return { + ...prv, + values: { + ...prv.values, + id: `${repoId}${hash}`, + name: `${repoId} ${hash}`?.toLowerCase(), + code_repo_url: repoMetadata?.url || '', + code_repo_type: repoMetadata?.repo_type || '', + code_repo_id: repoId, + branch: repoMetadata?.branch + } + } + }) }} text={ { +export const getGitspaceDetailTitle = ({ + getString, + status, + loading, + redirectFrom, + actionError +}: { + getString: UseStringsReturn['getString'] + status?: EnumGitspaceStateType + loading?: boolean + redirectFrom?: string + actionError?: GetDataError | null +}) => { + if (loading) { + return getString('cde.details.fetchingGitspace') + } else if ( + status === GitspaceStatus.UNKNOWN || + (status === GitspaceStatus.STOPPED && !!redirectFrom && !actionError) + ) { + return getString('cde.details.provisioningGitspace') + } else if (status === GitspaceStatus.STOPPED) { + return getString('cde.details.gitspaceStopped') + } else if (status === GitspaceStatus.RUNNING) { + return getString('cde.details.gitspaceRunning') + } else if (!loading && isUndefined(status)) { + getString('cde.details.noData') + } +} + +export const GitspaceDetails = ({ + data, + error, + loading, + refetch, + mutate, + refetchLogs, + mutateLoading, + isfetchingInProgress, + actionError +}: { + data?: OpenapiGetGitspaceResponse | null + error?: GetDataError | null + loading?: boolean + mutateLoading?: boolean + isfetchingInProgress?: boolean + refetch: ( + options?: Partial, 'lazy'>> | undefined + ) => Promise + refetchLogs?: ( + options?: Partial, 'lazy'>> | undefined + ) => Promise + mutate: MutateMethod + actionError?: GetDataError | null +}) => { const { getString } = useStrings() - const { accountIdentifier, orgIdentifier, projectIdentifier } = useGetCDEAPIParams() as CDEPathParams const { gitspaceId } = useParams() + const { routes } = useAppContext() + const space = useGetSpaceParam() + const { showError } = useToaster() + const history = useHistory() + const { projectIdentifier } = useGetCDEAPIParams() as CDEPathParams + const { redirectFrom = '' } = useQueryParams<{ redirectFrom?: string }>() - const { data, loading, error, refetch } = useGetGitspace({ - accountIdentifier, - orgIdentifier, - projectIdentifier, - gitspaceIdentifier: gitspaceId || '' - }) - - const { config, status } = data || {} - - const { mutate } = useGitspaceAction({ - accountIdentifier, - orgIdentifier, - projectIdentifier, - gitspaceIdentifier: gitspaceId || '' - }) + const { config, status, url } = data || {} const openEditorLabel = config?.ide === IDEType.VSCODE ? getString('cde.details.openEditor') : getString('cde.details.openBrowser') + const color = getStatusColor(status as EnumGitspaceStateType) + return ( @@ -65,12 +122,11 @@ export const GitspaceDetails = () => { {error ? ( refetch()} message={getErrorMessage(error)} /> ) : ( - - {status === GitspaceStatus.UNKNOWN && getString('cde.details.provisioningGitspace')} - {status === GitspaceStatus.STOPPED && getString('cde.details.gitspaceStopped')} - {status === GitspaceStatus.RUNNING && getString('cde.details.gitspaceRunning')} - {loading && getString('cde.details.fetchingGitspace')} - {!loading && isUndefined(status) && getString('cde.details.noData')} + + {getGitspaceDetailTitle({ getString, status, loading, redirectFrom, actionError })} )} @@ -85,7 +141,7 @@ export const GitspaceDetails = () => { - + {config?.code_repo_id?.toUpperCase()} @@ -110,10 +166,27 @@ export const GitspaceDetails = () => { {status === GitspaceStatus.UNKNOWN && ( <> - - @@ -121,17 +194,46 @@ export const GitspaceDetails = () => { {status === GitspaceStatus.STOPPED && ( <> - - + )} {status === GitspaceStatus.RUNNING && ( <> - + - {getErrorMessage(error)} -