Skip to content

Commit 8e5ffa3

Browse files
fix project import validation
1 parent 09a99d8 commit 8e5ffa3

File tree

13 files changed

+235
-178
lines changed

13 files changed

+235
-178
lines changed

apps/gitness/src/pages-v2/project/project-import-container.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ImporterProviderType, ImportSpaceRequestBody, useImportSpaceMutation }
44
import { ImportProjectFormFields, ImportProjectPage, ProviderOptionsEnum } from '@harnessio/ui/views'
55

66
import { useRoutes } from '../../framework/context/NavigationContext'
7+
import { useTranslationStore } from '../../i18n/stores/i18n-store'
78

89
export const ImportProjectContainer = () => {
910
const routes = useRoutes()
@@ -53,6 +54,7 @@ export const ImportProjectContainer = () => {
5354
onFormCancel={onCancel}
5455
isLoading={isLoading}
5556
apiErrorsValue={error?.message?.toString()}
57+
useTranslationStore={useTranslationStore}
5658
/>
5759
)
5860
}

packages/ui/locales/en/views.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,18 @@
458458
"generalTab": "General",
459459
"keysTab": "Keys and Tokens"
460460
},
461+
"project": {
462+
"importProjectValidation": {
463+
"nameMax": "Name must be no longer than 100 characters",
464+
"nameRegex": "Organization name must contain only letters, numbers, and the characters: - _ .",
465+
"nameNoSpaces": "Name cannot contain spaces",
466+
"descriptionMax": "Description must be no longer than 1024 characters",
467+
"organizationNameMax": "Organization name must be no longer than 100 characters",
468+
"noSpaces": "Organization name cannot contain spaces",
469+
"hostUrlRequired": "Repository URL is required",
470+
"hostUrlInvalid": "Invalid URL"
471+
}
472+
},
461473
"forms": {
462474
"selectMember": "Select member",
463475
"selectRole": "Select role",
@@ -520,4 +532,4 @@
520532
"secrets": {
521533
"secretsTitle": "Secrets"
522534
}
523-
}
535+
}

packages/ui/locales/es/views.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,18 @@
449449
"generalTab": "General",
450450
"keysTab": "Claves y Tokens"
451451
},
452+
"project": {
453+
"importProjectValidation": {
454+
"nameMax": "El nombre no debe superar los 100 caracteres",
455+
"nameRegex": "El nombre de la organización debe contener solo letras, números y los caracteres: - _ .",
456+
"nameNoSpaces": "El nombre no puede contener espacios",
457+
"descriptionMax": "La descripción no debe superar los 1024 caracteres",
458+
"organizationNameMax": "El nombre de la organización no debe superar los 100 caracteres",
459+
"noSpaces": "El nombre de la organización no puede contener espacios",
460+
"hostUrlRequired": "La URL del repositorio es obligatoria",
461+
"hostUrlInvalid": "URL inválida"
462+
}
463+
},
452464
"forms": {
453465
"selectMember": "",
454466
"selectRole": "",
@@ -509,4 +521,4 @@
509521
"secrets": {
510522
"secretsTitle": "Secrets"
511523
}
512-
}
524+
}

packages/ui/locales/fr/views.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,18 @@
454454
"generalTab": "Général",
455455
"keysTab": "Clés et Jetons"
456456
},
457+
"project": {
458+
"importProjectValidation": {
459+
"nameMax": "Le nom ne doit pas dépasser 100 caractères",
460+
"nameRegex": "Le nom de l'organisation doit contenir uniquement des lettres, des chiffres et les caractères : - _ .",
461+
"nameNoSpaces": "Le nom ne peut pas contenir d'espaces",
462+
"descriptionMax": "La description ne doit pas dépasser 1024 caractères",
463+
"organizationNameMax": "Le nom de l'organisation ne doit pas dépasser 100 caractères",
464+
"noSpaces": "Le nom de l'organisation ne peut pas contenir d'espaces",
465+
"hostUrlRequired": "L'URL du référentiel est requis",
466+
"hostUrlInvalid": "URL invalide"
467+
}
468+
},
457469
"forms": {
458470
"selectMember": "",
459471
"selectRole": "",
@@ -514,4 +526,4 @@
514526
"secrets": {
515527
"secretsTitle": "Secrets"
516528
}
517-
}
529+
}

packages/ui/src/components/button-with-options.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ export const ButtonWithOptions = <T extends string>({
127127
control={<RadioButton className="mt-px" value={String(option.value)} id={String(option.value)} />}
128128
id={String(option.value)}
129129
label={option.label}
130-
ariaSelected={selectedValue === option.value}
130+
aria-selected={selectedValue === option.value}
131131
description={option?.description}
132132
/>
133133
</DropdownMenu.Item>
@@ -143,7 +143,7 @@ export const ButtonWithOptions = <T extends string>({
143143
onClick={() => handleOptionChange(option.value)}
144144
>
145145
<span className="flex flex-col gap-y-1.5">
146-
<span className="leading-none text-foreground-8">{option.label}</span>
146+
<span className="text-foreground-8 leading-none">{option.label}</span>
147147
{option?.description && <span className="text-foreground-4">{option.description}</span>}
148148
</span>
149149
</DropdownMenu.Item>

packages/ui/src/components/form-primitives/fieldset.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,31 @@ import { cn } from '@utils/cn'
55
interface FieldsetProps extends HTMLAttributes<HTMLFieldSetElement> {
66
box?: boolean
77
shaded?: boolean
8+
/**
9+
* For better accessibility, the fieldset should start from the legend element
10+
*/
11+
legend?: string
812
}
913

1014
/**
1115
* A form fieldset component that groups related form elements.
1216
* @example
13-
* <Fieldset box shaded>
17+
* <Fieldset box shaded legend="Some Information">
1418
* <div>Form elements</div>
1519
* </Fieldset>
1620
*/
17-
export function Fieldset({ children, box, shaded, className, ...props }: FieldsetProps) {
21+
export function Fieldset({ children, box, shaded, className, legend, ...props }: FieldsetProps) {
1822
return (
1923
<fieldset
2024
className={cn(
2125
'flex flex-col gap-y-7',
2226
{ 'rounded-md border px-5 py-3.5 pb-5': box, 'bg-primary/[0.02]': shaded },
2327
className
2428
)}
25-
role="group"
26-
aria-describedby="fieldset-description"
2729
{...props}
2830
>
31+
<legend className="sr-only">{legend}</legend>
32+
2933
{children}
3034
</fieldset>
3135
)

packages/ui/src/components/form-primitives/separator.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ interface FormSeparatorProps {
99
/**
1010
* A horizontal separator component for forms
1111
* @example
12-
* // Basic usage
12+
* Basic usage
1313
* <FormSeparator />
1414
*
15-
* // With dashed style
15+
* With dashed style
1616
* <FormSeparator dashed />
1717
*
18-
* // With custom className
18+
* With custom className
1919
* <FormSeparator className="my-4" />
2020
*/
2121
export function FormSeparator({ dashed, dotted, className }: FormSeparatorProps) {

packages/ui/src/components/git-commit-dialog/git-commit-dialog.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,17 +175,17 @@ export const GitCommitDialog: FC<GitCommitDialogProps> = ({
175175
Commit directly to the
176176
<span
177177
className="
178-
relative mx-1.5 inline-flex gap-1 px-2.5 text-foreground-8
179-
before:absolute before:-top-1 before:left-0 before:z-[-1] before:h-6 before:w-full before:rounded before:bg-background-8
178+
text-foreground-8 before:bg-background-8 relative mx-1.5 inline-flex gap-1
179+
px-2.5 before:absolute before:-top-1 before:left-0 before:z-[-1] before:h-6 before:w-full before:rounded
180180
"
181181
>
182-
<Icon className="translate-y-0.5 text-icons-9" name="branch" size={14} />
182+
<Icon className="text-icons-9 translate-y-0.5" name="branch" size={14} />
183183
{currentBranch}
184184
</span>
185185
branch
186186
</span>
187187
}
188-
ariaSelected={commitToGitRefValue === CommitToGitRefOption.DIRECTLY}
188+
aria-selected={commitToGitRefValue === CommitToGitRefOption.DIRECTLY}
189189
/>
190190
<Option
191191
control={
@@ -197,7 +197,7 @@ export const GitCommitDialog: FC<GitCommitDialogProps> = ({
197197
}
198198
id={CommitToGitRefOption.NEW_BRANCH}
199199
label="Create a new branch for this commit and start a pull request"
200-
ariaSelected={commitToGitRefValue === CommitToGitRefOption.NEW_BRANCH}
200+
aria-selected={commitToGitRefValue === CommitToGitRefOption.NEW_BRANCH}
201201
description={
202202
// TODO: Add correct path
203203
<StyledLink to="/">Learn more about pull requests</StyledLink>

packages/ui/src/components/input.tsx

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { forwardRef, Fragment, InputHTMLAttributes, ReactNode } from 'react'
1+
import { forwardRef, InputHTMLAttributes, ReactNode } from 'react'
22

33
import { Caption, ControlGroup, Icon, IconProps, Label, Message, MessageTheme } from '@/components'
44
import { cn } from '@utils/cn'
@@ -9,12 +9,12 @@ export interface BaseInputProps
99
VariantProps<typeof inputVariants> {}
1010

1111
const inputVariants = cva(
12-
'bg-input-background px-3 py-1 text-foreground-1 disabled:cursor-not-allowed disabled:bg-background-3 disabled:text-foreground-7',
12+
'bg-input-background text-foreground-1 disabled:bg-background-3 disabled:text-foreground-7 px-3 py-1 disabled:cursor-not-allowed',
1313
{
1414
variants: {
1515
variant: {
1616
default:
17-
'flex w-full rounded border text-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-foreground-4 focus-visible:rounded focus-visible:outline-none',
17+
'placeholder:text-foreground-4 flex w-full rounded border text-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:rounded focus-visible:outline-none',
1818
extended: 'grow border-none focus-visible:outline-none'
1919
},
2020
size: {
@@ -114,10 +114,6 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
114114
},
115115
ref
116116
) => {
117-
const isControlGroup = !!error || !!caption || !!label || !!wrapperClassName
118-
const InputWrapper = isControlGroup ? ControlGroup : Fragment
119-
const inputWrapperProps = isControlGroup ? { className: wrapperClassName } : {}
120-
121117
const InputComponent = customContent ? BaseInputWithWrapper : BaseInput
122118

123119
const baseInputComp = (
@@ -154,7 +150,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
154150

155151
return inputIconName ? (
156152
<span className="relative">
157-
<Icon className="absolute left-3 top-1/2 -translate-y-1/2 text-icons-9" name={inputIconName} size={14} />
153+
<Icon className="text-icons-9 absolute left-3 top-1/2 -translate-y-1/2" name={inputIconName} size={14} />
158154
{baseInputComp}
159155
</span>
160156
) : (
@@ -163,7 +159,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
163159
}
164160

165161
return (
166-
<InputWrapper {...inputWrapperProps}>
162+
<ControlGroup className={wrapperClassName}>
167163
{!!label && (
168164
<Label className="mb-2.5" color={disabled ? 'disabled-dark' : 'secondary'} optional={optional} htmlFor={id}>
169165
{label}
@@ -179,7 +175,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
179175
)}
180176

181177
{caption && <Caption className={cn({ 'text-foreground-9': disabled })}>{caption}</Caption>}
182-
</InputWrapper>
178+
</ControlGroup>
183179
)
184180
}
185181
)

packages/ui/src/components/option.tsx

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
import { FC, ReactElement, ReactNode } from 'react'
1+
import { FC, HTMLAttributes, ReactElement, ReactNode } from 'react'
22

3-
import { Checkbox, Label, RadioButton, Text } from '@/components'
3+
import { Checkbox, Label, RadioButton } from '@/components'
44
import { cn } from '@utils/cn'
55

66
type ControlType = ReactElement<typeof RadioButton> | ReactElement<typeof Checkbox>
77

8-
interface OptionProps {
8+
interface OptionProps extends HTMLAttributes<HTMLDivElement> {
99
control: ControlType
1010
id: string
1111
label?: string | ReactNode
1212
description?: string | ReactNode
13-
className?: string
14-
ariaSelected?: boolean
13+
disabled?: boolean
1514
}
1615

1716
/**
@@ -24,30 +23,32 @@ interface OptionProps {
2423
* description="Description for Option 1"
2524
* />
2625
*/
27-
export const Option: FC<OptionProps> = ({ control, id, label, description, ariaSelected, className }) => {
26+
export const Option: FC<OptionProps> = ({ control, id, label, description, className, disabled, ...props }) => {
2827
return (
2928
<div
3029
className={cn('flex items-start', className)}
3130
role="option"
3231
aria-labelledby={`${id}-label`}
33-
aria-selected={ariaSelected}
32+
aria-selected={false}
33+
{...props}
3434
>
3535
{control}
3636
<div className="flex flex-col gap-0">
37-
<Label htmlFor={id} className="cursor-pointer pl-2.5 leading-tight">
37+
<Label
38+
htmlFor={id}
39+
className={cn('cursor-pointer pl-2.5 leading-tight', { 'cursor-default': disabled })}
40+
color={disabled ? 'disabled' : 'primary'}
41+
>
3842
{label}
3943
</Label>
4044
{description && (
41-
<Text
42-
className="ml-2.5 mt-1.5 leading-snug tracking-tight"
43-
as="p"
44-
size={2}
45-
color="foreground-4"
45+
<p
46+
className="text-foreground-4 ml-2.5 mt-1.5 text-sm leading-snug tracking-tight"
4647
id={`${id}-description`}
4748
role="note"
4849
>
4950
{description}
50-
</Text>
51+
</p>
5152
)}
5253
</div>
5354
</div>

0 commit comments

Comments
 (0)