Skip to content

Commit

Permalink
Add account name type selection and radio group component for ISV con…
Browse files Browse the repository at this point in the history
…figuration
  • Loading branch information
ziyang-lin-404 committed Jan 29, 2025
1 parent ce580c2 commit 36b2bd0
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 13 deletions.
84 changes: 71 additions & 13 deletions src/react/ISV/components/ISVConfiguration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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,
}) => (
<FormGroup
id={FORM_FIELDS.ACCOUNT_NAME}
Expand All @@ -66,22 +81,59 @@ const AccountNameField = ({
}
helpErrorPosition="bottom"
error={
isAccountExist
isAccountExist && accountNameType === 'create'
? 'Account name already exists'
: errors.accountName?.message ?? ''
}
content={
<Input
id={FORM_FIELDS.ACCOUNT_NAME}
type="text"
autoComplete="off"
placeholder={
status === 'success' && accounts.length !== 0
? `${platform.id}-backup`
: undefined
}
{...register(FORM_FIELDS.ACCOUNT_NAME)}
/>
<>
<Controller
name={FORM_FIELDS.ACCOUNT_NAME_TYPE}
control={control}
defaultValue={accountNameType}
render={({ field: { onChange, value } }) => (
<RadioGroup
options={accountTypeOptions}
value={value}
onChange={onChange}
direction="vertical"
/>
)}
/>

{accountNameType === 'create' ? (
<Input
id={FORM_FIELDS.ACCOUNT_NAME}
type="text"
autoComplete="off"
placeholder={
status === 'success' && accounts.length !== 0
? `${platform.id}-backup`
: undefined
}
{...register(FORM_FIELDS.ACCOUNT_NAME)}
/>
) : (
<Controller
name={FORM_FIELDS.ACCOUNT_NAME}
control={control}
render={({ field: { onChange, value } }) => (
<Select
id={FORM_FIELDS.ACCOUNT_NAME}
onChange={onChange}
value={value}
placeholder="Select existing account"
>
{accounts.map((account) => (
<Select.Option key={account.name} value={account.name}>
{account.name}
</Select.Option>
))}
</Select>
)}
/>
)}
</>
}
/>
);
Expand All @@ -96,7 +148,10 @@ export const ISVConfiguration = () => {

const methods = useForm<ISVConfig>({
mode: 'all',
defaultValues: config,
defaultValues: {
...config,
accountNameType: 'create',
},
resolver: joiResolver(platform.validator),
});

Expand All @@ -122,6 +177,7 @@ export const ISVConfiguration = () => {
) ?? [];

const accountName = watch('accountName');
const accountNameType = watch('accountNameType');
const application = watch('application');
const isAccountExist = useMemo(() => {
const exists =
Expand Down Expand Up @@ -261,11 +317,13 @@ export const ISVConfiguration = () => {

<AccountNameField
register={register}
control={control}
errors={errors}
isAccountExist={isAccountExist}
status={status}
accounts={accounts}
platform={platform}
accountNameType={accountNameType}
/>

{platform.id === 'veeam' && renderVeeamApplication()}
Expand Down
98 changes: 98 additions & 0 deletions src/react/ISV/components/RadioGroup.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<RadioContainer direction={direction}>
{options.map((option) => (
<RadioWrapper key={option.value} data-disabled={disabled}>
<RadioInput
type="radio"
name={groupName}
value={option.value}
checked={value === option.value}
onChange={(e) => onChange(e.target.value)}
disabled={disabled}
/>
<RadioContent>
<RadioLabel>{option.label}</RadioLabel>
{option.description && (
<RadioDescription>{option.description}</RadioDescription>
)}
</RadioContent>
</RadioWrapper>
))}
</RadioContainer>
);
};
1 change: 1 addition & 0 deletions src/react/ISV/modules/commvault/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
1 change: 1 addition & 0 deletions src/react/ISV/modules/veeam/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
1 change: 1 addition & 0 deletions src/react/ISV/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Joi from '@hapi/joi';

export type ISVConfig = {
accountName: string;
accountNameType?: 'create' | 'existing';
application?: string;
enableImmutableBackup?: boolean;
buckets?: {
Expand Down

0 comments on commit 36b2bd0

Please sign in to comment.