3 * Copyright (C) 2009-2024 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 import { InputSize, Select } from '@sonarsource/echoes-react';
21 import { FormField, InputField, TextError } from 'design-system/lib';
22 import { isEmpty, isUndefined } from 'lodash';
23 import React from 'react';
24 import isEmail from 'validator/lib/isEmail';
25 import { translate, translateWithParameters } from '../../../../helpers/l10n';
27 type InputType = 'email' | 'number' | 'password' | 'select' | 'text';
30 children?: (props: { onChange: (value: string) => void }) => React.ReactNode;
34 onChange: (value: string) => void;
38 value: string | undefined;
41 export function EmailNotificationFormField(props: Readonly<Props>) {
42 const { description, id, name, options, required, type = 'text', value } = props;
44 const [validationMessage, setValidationMessage] = React.useState<string>();
46 const handleCheck = (changedValue?: string) => {
47 if (isEmpty(changedValue) && required) {
48 setValidationMessage(translate('settings.state.value_cant_be_empty_no_default'));
52 if (type === 'email' && !isEmail(changedValue ?? '')) {
53 setValidationMessage(translate('email_notification.state.value_should_be_valid_email'));
57 setValidationMessage(undefined);
61 const onChange = (newValue: string) => {
62 handleCheck(newValue);
63 props.onChange(newValue);
66 const hasValidationMessage = !isUndefined(validationMessage);
70 className="sw-grid sw-grid-cols-2 sw-gap-x-4 sw-py-6 sw-px-4"
72 label={translate(name)}
74 requiredAriaLabel={translate('field_required')}
76 <div className="sw-row-span-2 sw-grid">
77 {type === 'select' ? (
81 options={options ?? []}
97 {hasValidationMessage && (
100 text={translateWithParameters('settings.state.validation_failed', validationMessage)}
105 <div className="sw-w-abs-300">
106 {!isUndefined(description) && <div className="markdown sw-mt-1">{description}</div>}
116 onChange: (value: string) => void;
119 value: string | undefined;
122 const { id, onChange, name, required, type, value } = props;
127 min={type === 'number' ? 0 : undefined}
129 onChange={(event) => onChange(event.target.value)}
132 step={type === 'number' ? 1 : undefined}
139 function SelectInput(
143 onChange: (value: string) => void;
146 value: string | undefined;
149 const { id, name, onChange, options, required, value } = props;
153 data={options?.map((option) => ({ label: option, value: option })) ?? []}
156 isRequired={required}
159 size={InputSize.Large}