From 91643f3413beef16ac5a91f41ae59757dfcc225b Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Thu, 10 Oct 2024 10:53:51 +0200 Subject: [PATCH] Revert "SONAR-23137 Remove success status around legacy input" This reverts commit bba5ffa2fe6afe5c4eed1e4709db9f52710b0a7c. --- .../src/components/input/InputField.tsx | 12 +++++++++++- .../components/input/__tests__/InputField-test.tsx | 9 +++++---- .../create/project/components/ProjectValidation.tsx | 2 ++ .../create/project/manual/ManualProjectCreate.tsx | 1 + .../src/main/js/apps/projectKey/UpdateForm.tsx | 1 + .../BranchNewCodeDefinitionSettingModal.tsx | 1 + .../components/ProjectNewCodeDefinitionSelector.tsx | 1 + .../apps/settings/components/NewCodeDefinition.tsx | 1 + .../src/main/js/apps/users/components/UserForm.tsx | 2 ++ .../src/main/js/components/common/EmailInput.tsx | 1 + .../main/js/components/common/UserPasswordInput.tsx | 2 ++ .../js/components/controls/InputValidationField.tsx | 4 +++- .../NewCodeDefinitionDaysOption.tsx | 3 +++ .../NewCodeDefinitionSelector.tsx | 3 +++ 14 files changed, 37 insertions(+), 6 deletions(-) diff --git a/server/sonar-web/design-system/src/components/input/InputField.tsx b/server/sonar-web/design-system/src/components/input/InputField.tsx index a9501d15776..4649d739fb3 100644 --- a/server/sonar-web/design-system/src/components/input/InputField.tsx +++ b/server/sonar-web/design-system/src/components/input/InputField.tsx @@ -29,12 +29,14 @@ interface InputProps extends Omit, ' as?: React.ElementType; className?: string; isInvalid?: boolean; + isValid?: boolean; size?: InputSizeKeys; } interface InputTextAreaProps extends React.TextareaHTMLAttributes { className?: string; isInvalid?: boolean; + isValid?: boolean; size?: InputSizeKeys; } @@ -68,10 +70,18 @@ const dangerStyle = (props: ThemedProps) => css` --focusOutline: var(--echoes-focus-border-width-default) solid var(--echoes-color-focus-default); `; +const successStyle = (props: ThemedProps) => css` + --border: ${themeBorder('default', 'inputSuccess')(props)}; + --focusBorder: ${themeBorder('default', 'inputSuccessFocus')(props)}; + --focusOutline: ${themeBorder('focus', 'inputSuccessFocus')(props)}; +`; + const getInputVariant = (props: ThemedProps & { isInvalid?: boolean; isValid?: boolean }) => { - const { isInvalid } = props; + const { isValid, isInvalid } = props; if (isInvalid) { return dangerStyle; + } else if (isValid) { + return successStyle; } return defaultStyle; }; diff --git a/server/sonar-web/design-system/src/components/input/__tests__/InputField-test.tsx b/server/sonar-web/design-system/src/components/input/__tests__/InputField-test.tsx index 1682fca211a..ccac9ace735 100644 --- a/server/sonar-web/design-system/src/components/input/__tests__/InputField-test.tsx +++ b/server/sonar-web/design-system/src/components/input/__tests__/InputField-test.tsx @@ -22,10 +22,11 @@ import { InputField } from '../InputField'; describe('Input Field', () => { it.each([ - ['default', false, 'defaultStyle'], - ['invalid', true, 'dangerStyle'], - ])('should handle status %s', (_, isInvalid, expectedStyle) => { - render(); + ['default', false, false, 'defaultStyle'], + ['invalid', true, false, 'dangerStyle'], + ['valid', false, true, 'successStyle'], + ])('should handle status %s', (_, isInvalid, isValid, expectedStyle) => { + render(); // Emotion classes contain pseudo-random parts, we're interesting in the fixed part // so we can't just check a specific class diff --git a/server/sonar-web/src/main/js/apps/create/project/components/ProjectValidation.tsx b/server/sonar-web/src/main/js/apps/create/project/components/ProjectValidation.tsx index 6505f36e235..481711667b9 100644 --- a/server/sonar-web/src/main/js/apps/create/project/components/ProjectValidation.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/components/ProjectValidation.tsx @@ -248,6 +248,7 @@ export default function ProjectValidation(props: Readonly>) { value={name} autoFocus isInvalid={projectNameIsInvalid} + isValid={projectNameIsValid} required /> {projectNameIsInvalid && } @@ -277,6 +278,7 @@ export default function ProjectValidation(props: Readonly>) { type="text" value={key} isInvalid={projectKeyIsInvalid} + isValid={projectKeyIsValid} required /> {projectKeyIsInvalid && } diff --git a/server/sonar-web/src/main/js/apps/create/project/manual/ManualProjectCreate.tsx b/server/sonar-web/src/main/js/apps/create/project/manual/ManualProjectCreate.tsx index a174902cec5..bc7a765f741 100644 --- a/server/sonar-web/src/main/js/apps/create/project/manual/ManualProjectCreate.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/manual/ManualProjectCreate.tsx @@ -185,6 +185,7 @@ export default function ManualProjectCreate(props: Readonly) { type="text" value={mainBranchName} isInvalid={mainBranchNameIsInvalid} + isValid={mainBranchNameIsValid} required /> {mainBranchNameIsInvalid && } diff --git a/server/sonar-web/src/main/js/apps/projectKey/UpdateForm.tsx b/server/sonar-web/src/main/js/apps/projectKey/UpdateForm.tsx index 5c439b81d83..7d20cbb1b82 100644 --- a/server/sonar-web/src/main/js/apps/projectKey/UpdateForm.tsx +++ b/server/sonar-web/src/main/js/apps/projectKey/UpdateForm.tsx @@ -85,6 +85,7 @@ export default function UpdateForm(props: UpdateFormProps) { name="update_key.new_key" required isInvalid={hasChanged && error !== undefined} + isValid={hasChanged && error === undefined} autoFocus onChange={onInputChange} value={newKey} diff --git a/server/sonar-web/src/main/js/apps/projectNewCode/components/BranchNewCodeDefinitionSettingModal.tsx b/server/sonar-web/src/main/js/apps/projectNewCode/components/BranchNewCodeDefinitionSettingModal.tsx index 301ede63c7f..31360afa2ad 100644 --- a/server/sonar-web/src/main/js/apps/projectNewCode/components/BranchNewCodeDefinitionSettingModal.tsx +++ b/server/sonar-web/src/main/js/apps/projectNewCode/components/BranchNewCodeDefinitionSettingModal.tsx @@ -185,6 +185,7 @@ export default class BranchNewCodeDefinitionSettingModal extends React.PureCompo /> = MINIMUM_LOGIN_LENGTH} maxLength={MAXIMUM_LOGIN_LENGTH} minLength={MINIMUM_LOGIN_LENGTH} size="full" @@ -241,6 +242,7 @@ export default function UserForm(props: Props) { >
) { { const isValid = isMandotory diff --git a/server/sonar-web/src/main/js/components/common/UserPasswordInput.tsx b/server/sonar-web/src/main/js/components/common/UserPasswordInput.tsx index e4ecbe830b7..98ccd7077cb 100644 --- a/server/sonar-web/src/main/js/components/common/UserPasswordInput.tsx +++ b/server/sonar-web/src/main/js/components/common/UserPasswordInput.tsx @@ -57,6 +57,7 @@ export default function UserPasswordInput(props: Readonly) {
setIsFocused(true)} id="create-password" size={size} @@ -92,6 +93,7 @@ export default function UserPasswordInput(props: Readonly) {
setIsFocused(true)} id="confirm-password" size={size} diff --git a/server/sonar-web/src/main/js/components/controls/InputValidationField.tsx b/server/sonar-web/src/main/js/components/controls/InputValidationField.tsx index 9b9bd6ca412..de41934095f 100644 --- a/server/sonar-web/src/main/js/components/controls/InputValidationField.tsx +++ b/server/sonar-web/src/main/js/components/controls/InputValidationField.tsx @@ -45,7 +45,9 @@ export default function InputValidationField({ ...props }: Readonly) { const modalValidationProps = { description, dirty, error, label, touched, required }; return ( - {({ isInvalid }) => } + {({ isInvalid, isValid }) => ( + + )} ); } diff --git a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx index 4a4629cc763..f49479708df 100644 --- a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx +++ b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx @@ -46,6 +46,7 @@ export interface Props { currentDaysValue?: string; days: string; disabled?: boolean; + isChanged: boolean; isValid: boolean; onChangeDays: (value: string) => void; onSelect: (selection: NewCodeDefinitionType) => void; @@ -65,6 +66,7 @@ export default function NewCodeDefinitionDaysOption(props: Props) { projectKey, updatedAt, disabled, + isChanged, isValid, onChangeDays, onSelect, @@ -131,6 +133,7 @@ export default function NewCodeDefinitionDaysOption(props: Props) { onChangeDays(e.currentTarget.value)} diff --git a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionSelector.tsx b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionSelector.tsx index bf09cda52eb..535803665c5 100644 --- a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionSelector.tsx +++ b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionSelector.tsx @@ -54,6 +54,7 @@ export default function NewCodeDefinitionSelector(props: Props) { const [globalNcd, setGlobalNcd] = React.useState(null); const [selectedNcdType, setSelectedNcdType] = React.useState(null); const [days, setDays] = React.useState(''); + const [isChanged, setIsChanged] = React.useState(false); React.useEffect(() => { const numberOfDays = getNumberOfDaysDefaultValue(globalNcd); @@ -74,6 +75,7 @@ export default function NewCodeDefinitionSelector(props: Props) { (newNcdType: NewCodeDefinitionType) => { if (newNcdType && newNcdType !== selectedNcdType) { setSelectedNcdType(newNcdType); + setIsChanged(true); } }, [selectedNcdType], @@ -155,6 +157,7 @@ export default function NewCodeDefinitionSelector(props: Props) { disabled={Boolean( !selectedNcdType || selectedNcdType === NewCodeDefinitionType.Inherited, )} + isChanged={isChanged} isValid={isCompliant} onChangeDays={setDays} onSelect={handleNcdChanged} -- 2.39.5