Fix validate action not triggered when used with different components in custom validation

This commit is contained in:
Nakul Nagargade 2024-11-14 11:29:37 +05:30
parent d512ec232a
commit fe3d2f0331
6 changed files with 48 additions and 44 deletions

View file

@ -80,7 +80,7 @@ const RenderWidget = ({
...{ validationObject: unResolvedValidation }, ...{ validationObject: unResolvedValidation },
customResolveObjects: customResolvables, customResolveObjects: customResolvables,
}), }),
[validateWidget, customResolvables, unResolvedValidation] [validateWidget, customResolvables, unResolvedValidation, resolvedValidation]
); );
const resetComponent = useCallback(() => { const resetComponent = useCallback(() => {

View file

@ -253,7 +253,7 @@ export const Checkbox = ({
</> </>
)} )}
</div> </div>
{validationError && visibility && !checked && userInteracted && ( {!isValid && visibility && userInteracted && (
<div <div
data-cy={`${String(componentName).toLowerCase()}-invalid-feedback`} data-cy={`${String(componentName).toLowerCase()}-invalid-feedback`}
style={{ style={{

View file

@ -101,6 +101,8 @@ export const DropdownV2 = ({
const [isDropdownDisabled, setIsDropdownDisabled] = useState(disabledState); const [isDropdownDisabled, setIsDropdownDisabled] = useState(disabledState);
const [searchInputValue, setSearchInputValue] = useState(''); const [searchInputValue, setSearchInputValue] = useState('');
const [isDropdownOpen, setIsDropdownOpen] = useState(false); const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const [userInteracted, setUserInteracted] = useState(false);
const _height = padding === 'default' ? `${height}px` : `${height + 4}px`; const _height = padding === 'default' ? `${height}px` : `${height + 4}px`;
const labelRef = useRef(); const labelRef = useRef();
function findDefaultItem(schema) { function findDefaultItem(schema) {
@ -317,6 +319,7 @@ export const DropdownV2 = ({
accentColor, accentColor,
isLoading: isDropdownLoading, isLoading: isDropdownLoading,
isDisabled: isDropdownDisabled, isDisabled: isDropdownDisabled,
userInteracted,
}), }),
backgroundColor: getInputBackgroundColor({ backgroundColor: getInputBackgroundColor({
fieldBackgroundColor, fieldBackgroundColor,
@ -479,6 +482,7 @@ export const DropdownV2 = ({
fireEvent('onSelect'); fireEvent('onSelect');
} }
setIsDropdownOpen(false); setIsDropdownOpen(false);
setUserInteracted(true);
}} }}
options={selectOptions} options={selectOptions}
styles={customStyles} styles={customStyles}
@ -507,19 +511,20 @@ export const DropdownV2 = ({
/> />
</div> </div>
</div> </div>
<div {userInteracted && visibility && !isValid && (
className={`${isValid ? '' : visibility ? 'd-flex' : 'none'}`} <div
style={{ className={'d-flex'}
color: errTextColor, style={{
justifyContent: direction === 'right' ? 'flex-start' : 'flex-end', color: errTextColor,
fontSize: '11px', justifyContent: direction === 'right' ? 'flex-start' : 'flex-end',
fontWeight: '400', fontSize: '11px',
lineHeight: '16px', fontWeight: '400',
display: visibility ? 'block' : 'none', lineHeight: '16px',
}} }}
> >
{!isValid && validationError} {validationError}
</div> </div>
)}
</> </>
); );
}; };

View file

@ -7,8 +7,16 @@ export const getInputFocusedColor = ({ accentColor }) => {
return 'var(--primary-accent-strong)'; return 'var(--primary-accent-strong)';
}; };
export const getInputBorderColor = ({ isValid, isFocused, fieldBorderColor, accentColor, isLoading, isDisabled }) => { export const getInputBorderColor = ({
if (!isValid) { isValid,
isFocused,
fieldBorderColor,
accentColor,
isLoading,
isDisabled,
userInteracted,
}) => {
if (userInteracted && !isValid) {
return 'var(--status-error-strong)'; return 'var(--status-error-strong)';
} }

View file

@ -12,8 +12,6 @@ import Label from '@/_ui/Label';
const tinycolor = require('tinycolor2'); const tinycolor = require('tinycolor2');
import { CustomDropdownIndicator, CustomClearIndicator } from '../DropdownV2/DropdownV2'; import { CustomDropdownIndicator, CustomClearIndicator } from '../DropdownV2/DropdownV2';
import { getInputBackgroundColor, getInputBorderColor, getInputFocusedColor } from '../DropdownV2/utils'; import { getInputBackgroundColor, getInputBorderColor, getInputFocusedColor } from '../DropdownV2/utils';
import useStore from '@/AppBuilder/_stores/store';
import { shallow } from 'zustand/shallow';
export const MultiselectV2 = ({ export const MultiselectV2 = ({
id, id,
@ -28,7 +26,6 @@ export const MultiselectV2 = ({
validate, validate,
validation, validation,
componentName, componentName,
width,
}) => { }) => {
let { let {
label, label,
@ -76,6 +73,7 @@ export const MultiselectV2 = ({
const [isSelectAllSelected, setIsSelectAllSelected] = useState(false); const [isSelectAllSelected, setIsSelectAllSelected] = useState(false);
const [searchInputValue, setSearchInputValue] = useState(''); const [searchInputValue, setSearchInputValue] = useState('');
const _height = padding === 'default' ? `${height}px` : `${height + 4}px`; const _height = padding === 'default' ? `${height}px` : `${height + 4}px`;
const [userInteracted, setUserInteracted] = useState(false);
const [isMultiselectOpen, setIsMultiselectOpen] = useState(false); const [isMultiselectOpen, setIsMultiselectOpen] = useState(false);
useEffect(() => { useEffect(() => {
@ -129,9 +127,7 @@ export const MultiselectV2 = ({
const onChangeHandler = (items, action) => { const onChangeHandler = (items, action) => {
setInputValue(items); setInputValue(items);
fireEvent('onSelect'); fireEvent('onSelect');
// if (action.action === 'select-option') { setUserInteracted(true);
// fireEvent('onSelect');
// }
}; };
useEffect(() => { useEffect(() => {
@ -332,6 +328,7 @@ export const MultiselectV2 = ({
accentColor, accentColor,
isLoading: isMultiSelectLoading, isLoading: isMultiSelectLoading,
isDisabled: isMultiSelectDisabled, isDisabled: isMultiSelectDisabled,
userInteracted,
}), }),
backgroundColor: getInputBackgroundColor({ backgroundColor: getInputBackgroundColor({
fieldBackgroundColor, fieldBackgroundColor,
@ -420,7 +417,6 @@ export const MultiselectV2 = ({
}), }),
}; };
const _width = (labelWidth / 100) * 70; // Max width which label can go is 70% for better UX calculate width based on this value const _width = (labelWidth / 100) * 70; // Max width which label can go is 70% for better UX calculate width based on this value
return ( return (
<> <>
<div <div
@ -520,19 +516,20 @@ export const MultiselectV2 = ({
/> />
</div> </div>
</div> </div>
<div {userInteracted && visibility && !isValid && (
className={`${isValid ? '' : visibility ? 'd-flex' : 'none'}`} <div
style={{ className={'d-flex'}
color: errTextColor, style={{
justifyContent: direction === 'right' ? 'flex-start' : 'flex-end', color: errTextColor,
fontSize: '11px', justifyContent: direction === 'right' ? 'flex-start' : 'flex-end',
fontWeight: '400', fontSize: '11px',
lineHeight: '16px', fontWeight: '400',
display: visibility ? 'block' : 'none', lineHeight: '16px',
}} }}
> >
{!isValid && validationError} {validationError}
</div> </div>
)}
</> </>
); );
}; };

View file

@ -12,7 +12,6 @@ const Switch = ({
borderColor, borderColor,
setOn, setOn,
styles, styles,
setExposedVariable,
fireEvent, fireEvent,
setUserInteracted, setUserInteracted,
}) => { }) => {
@ -106,7 +105,6 @@ export const ToggleSwitchV2 = ({
const isMandatory = validation?.mandatory ?? false; const isMandatory = validation?.mandatory ?? false;
const [validationStatus, setValidationStatus] = useState(validate(on)); const [validationStatus, setValidationStatus] = useState(validate(on));
const { isValid, validationError } = validationStatus; const { isValid, validationError } = validationStatus;
const [showValidationError, setShowValidationError] = useState(true);
const [loading, setLoading] = useState(properties?.loadingState); const [loading, setLoading] = useState(properties?.loadingState);
const [disable, setDisable] = useState(properties.disabledState || properties.loadingState); const [disable, setDisable] = useState(properties.disabledState || properties.loadingState);
const [visibility, setVisibility] = useState(properties.visibility); const [visibility, setVisibility] = useState(properties.visibility);
@ -276,15 +274,11 @@ export const ToggleSwitchV2 = ({
onChange={toggleValue} onChange={toggleValue}
color={toggleSwitchColor} color={toggleSwitchColor}
alignment={alignment} alignment={alignment}
validationError={validationError}
isValid={isValid} isValid={isValid}
showValidationError={showValidationError}
properties={properties} properties={properties}
setShowValidationError={setShowValidationError}
borderColor={borderColor} borderColor={borderColor}
setOn={setInputValue} setOn={setInputValue}
styles={styles} styles={styles}
setExposedVariable={setExposedVariable}
fireEvent={fireEvent} fireEvent={fireEvent}
setUserInteracted={setUserInteracted} setUserInteracted={setUserInteracted}
/> />
@ -300,7 +294,7 @@ export const ToggleSwitchV2 = ({
}} }}
> >
{renderInput()} {renderInput()}
{showValidationError && isMandatory && userInteracted && !on && visibility && ( {userInteracted && visibility && !isValid && (
<div <div
data-cy={`${String(componentName).toLowerCase()}-invalid-feedback`} data-cy={`${String(componentName).toLowerCase()}-invalid-feedback`}
style={{ style={{