From 36b2bd03076b6550f3d235ad333548de5f60cedc Mon Sep 17 00:00:00 2001 From: Ziyang Lin Date: Wed, 29 Jan 2025 12:10:23 +0100 Subject: [PATCH] Add account name type selection and radio group component for ISV configuration --- src/react/ISV/components/ISVConfiguration.tsx | 84 +++++++++++++--- src/react/ISV/components/RadioGroup.tsx | 98 +++++++++++++++++++ src/react/ISV/modules/commvault/index.tsx | 1 + src/react/ISV/modules/veeam/index.tsx | 1 + src/react/ISV/types/index.ts | 1 + 5 files changed, 172 insertions(+), 13 deletions(-) create mode 100644 src/react/ISV/components/RadioGroup.tsx diff --git a/src/react/ISV/components/ISVConfiguration.tsx b/src/react/ISV/components/ISVConfiguration.tsx index 9d5eb49b8..804ed743c 100644 --- a/src/react/ISV/components/ISVConfiguration.tsx +++ b/src/react/ISV/components/ISVConfiguration.tsx @@ -34,9 +34,11 @@ import { } from '../../next-architecture/ui/XCoreLibraryProvider'; import { getCapacityBytes } from '../../ui-elements/Veeam/useCapacityUnit'; import { ISVSkipModal } from './ISVSkipModal'; +import { RadioGroup } from './RadioGroup'; const FORM_FIELDS = { ACCOUNT_NAME: 'accountName', + ACCOUNT_NAME_TYPE: 'accountNameType', APPLICATION: 'application', BUCKET_NAME: 'bucketName', ENABLE_IMMUTABLE_BACKUP: 'enableImmutableBackup', @@ -47,13 +49,26 @@ const isImmutableBackupEnabled = (application: string) => application === VEEAM_OFFICE_365_V8 || application === 'COMMVAULT'; +const accountTypeOptions = [ + { + value: 'create', + label: 'Create a new account', + }, + { + value: 'existing', + label: 'Use an existing Account', + }, +]; + const AccountNameField = ({ register, + control, errors, isAccountExist, status, accounts, platform, + accountNameType, }) => ( + <> + ( + + )} + /> + + {accountNameType === 'create' ? ( + + ) : ( + ( + + )} + /> + )} + } /> ); @@ -96,7 +148,10 @@ export const ISVConfiguration = () => { const methods = useForm({ mode: 'all', - defaultValues: config, + defaultValues: { + ...config, + accountNameType: 'create', + }, resolver: joiResolver(platform.validator), }); @@ -122,6 +177,7 @@ export const ISVConfiguration = () => { ) ?? []; const accountName = watch('accountName'); + const accountNameType = watch('accountNameType'); const application = watch('application'); const isAccountExist = useMemo(() => { const exists = @@ -261,11 +317,13 @@ export const ISVConfiguration = () => { {platform.id === 'veeam' && renderVeeamApplication()} diff --git a/src/react/ISV/components/RadioGroup.tsx b/src/react/ISV/components/RadioGroup.tsx new file mode 100644 index 000000000..cc9792540 --- /dev/null +++ b/src/react/ISV/components/RadioGroup.tsx @@ -0,0 +1,98 @@ +import { useId } from 'react'; +import styled from 'styled-components'; +import { spacing } from '@scality/core-ui/dist/spacing'; + +type RadioOption = { + value: string; + label: string; + description?: string; +}; + +type RadioGroupProps = { + options: RadioOption[]; + value: string; + onChange: (value: string) => void; + name?: string; + direction?: 'horizontal' | 'vertical'; + disabled?: boolean; +}; + +const RadioContainer = styled.div<{ direction: 'horizontal' | 'vertical' }>` + display: flex; + flex-direction: ${(props) => + props.direction === 'horizontal' ? 'row' : 'column'}; + gap: ${spacing.r8}; +`; + +const RadioWrapper = styled.label` + display: flex; + align-items: flex-start; + gap: ${spacing.r8}; + cursor: pointer; + padding: ${spacing.r4}; + padding-left: 0; + padding-bottom: ${spacing.r8}; + border-radius: 4px; + + &[data-disabled='true'] { + cursor: not-allowed; + opacity: 0.5; + } +`; + +const RadioInput = styled.input` + margin-top: 4px; + margin-left: 0; + cursor: inherit; +`; + +const RadioContent = styled.div` + display: flex; + flex-direction: column; + gap: ${spacing.r4}; +`; + +const RadioLabel = styled.span` + color: ${(props) => props.theme.textPrimary}; + font-weight: 500; +`; + +const RadioDescription = styled.span` + color: ${(props) => props.theme.textSecondary}; + font-size: 0.875rem; +`; + +export const RadioGroup = ({ + options, + value, + onChange, + name, + direction = 'vertical', + disabled = false, +}: RadioGroupProps) => { + const groupId = useId(); + const groupName = name || groupId; + + return ( + + {options.map((option) => ( + + onChange(e.target.value)} + disabled={disabled} + /> + + {option.label} + {option.description && ( + {option.description} + )} + + + ))} + + ); +}; diff --git a/src/react/ISV/modules/commvault/index.tsx b/src/react/ISV/modules/commvault/index.tsx index 0620fdcb1..ca42bc365 100644 --- a/src/react/ISV/modules/commvault/index.tsx +++ b/src/react/ISV/modules/commvault/index.tsx @@ -113,6 +113,7 @@ export const Commvault: ISVPlatformConfig = { ], validator: Joi.object({ accountName: accountNameValidationSchema, + accountNameType: Joi.string().required(), enableImmutableBackup: Joi.boolean().default(true), buckets: Joi.array().items( Joi.object({ diff --git a/src/react/ISV/modules/veeam/index.tsx b/src/react/ISV/modules/veeam/index.tsx index 86959db55..512c9c6a0 100644 --- a/src/react/ISV/modules/veeam/index.tsx +++ b/src/react/ISV/modules/veeam/index.tsx @@ -131,6 +131,7 @@ export const Veeam: ISVPlatformConfig = { ], validator: Joi.object({ accountName: accountNameValidationSchema, + accountNameType: Joi.string().required(), application: Joi.string().required(), enableImmutableBackup: Joi.boolean().required(), buckets: Joi.array().items( diff --git a/src/react/ISV/types/index.ts b/src/react/ISV/types/index.ts index 37308e6e9..e8424043b 100644 --- a/src/react/ISV/types/index.ts +++ b/src/react/ISV/types/index.ts @@ -2,6 +2,7 @@ import Joi from '@hapi/joi'; export type ISVConfig = { accountName: string; + accountNameType?: 'create' | 'existing'; application?: string; enableImmutableBackup?: boolean; buckets?: {