From b8bb77e20c74dc4d2682d06de3a62fe022e9715b Mon Sep 17 00:00:00 2001 From: Kavin Venkatachalam Date: Tue, 11 Mar 2025 16:53:07 +0530 Subject: [PATCH] fix: Fixed the multiselect issue on add new row and edit on validation onClick --- .../_components/DataTypes/CustomSelect.jsx | 97 ++++++++++++++----- .../NewTable/_components/DataTypes/String.jsx | 13 ++- .../NewTable/_components/DataTypes/Text.jsx | 29 ++++-- .../TableData/_components/TableRow.jsx | 1 - .../NewTable/_utils/generateColumnsData.js | 2 + 5 files changed, 106 insertions(+), 36 deletions(-) diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/CustomSelect.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/CustomSelect.jsx index 0a5dacac08..f9a89fee17 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/CustomSelect.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/CustomSelect.jsx @@ -1,11 +1,13 @@ -import React, { useState, useCallback, useMemo, useRef } from 'react'; +import React, { useState, useCallback, useMemo, useRef, useEffect } from 'react'; import Select from '@/_ui/Select'; import { components } from 'react-select'; import defaultStyles from '@/_ui/Select/styles'; import SolidIcon from '@/_ui/Icon/SolidIcons'; import { Checkbox } from '@/_ui/CheckBox/CheckBox'; import OverlayTrigger from 'react-bootstrap/OverlayTrigger'; -import { isArray, isString } from 'lodash'; +import { isArray } from 'lodash'; +import useStore from '@/AppBuilder/_stores/store'; +import { shallow } from 'zustand/shallow'; const { MenuList } = components; @@ -132,11 +134,32 @@ export const CustomSelectColumn = ({ optionsLoadingState = false, horizontalAlignment = 'left', isEditable, + column, + isNewRow, }) => { + const validateWidget = useStore((state) => state.validateWidget, shallow); + const [isFocused, setIsFocused] = useState(false); const containerRef = useRef(null); const inputRef = useRef(null); + const validationData = validateWidget({ + validationObject: { + customRule: { value: column.customRule }, + }, + widgetValue: value, + customResolveObjects: { value }, + }); + const { isValid, validationError } = validationData; + + useEffect(() => { + const handleDocumentClick = (event) => { + if ((isMulti || isNewRow) && !containerRef.current?.contains(event.target)) setIsFocused(false); + }; + document.addEventListener('mousedown', handleDocumentClick); + return () => document.removeEventListener('mousedown', handleDocumentClick); + }, [isMulti, isNewRow]); + const customComponents = { MenuList: (props) => , Option: CustomOption, @@ -250,30 +273,52 @@ export const CustomSelectColumn = ({ trigger={isMulti && !isFocused && isOverflowing() && ['hover', 'focus']} rootClose={true} > -
- { + setIsFocused(true); + }} + onChange={handleChange} + useCustomStyles={true} + styles={customStyles} + defaultValue={defaultValue} + placeholder={placeholder} + isMulti={isMulti} + hideSelectedOptions={false} + isClearable={false} + clearIndicator={false} + darkMode={darkMode} + menuIsOpen={isFocused || undefined} + isFocused={isFocused || undefined} + /> +
+
{ + if (!isValid) { + setIsFocused(true); // Open the dropdown + } + }} + className={` ${isValid ? 'd-none' : 'invalid-feedback d-block'}`} + > + {validationError} +
+ ); }; diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/String.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/String.jsx index d70341b41e..89eb561c4d 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/String.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/String.jsx @@ -70,6 +70,12 @@ export const StringColumn = ({ (ref?.current?.clientWidth < ref?.current?.children[0]?.offsetWidth || ref?.current?.clientHeight < ref?.current?.children[0]?.offsetHeight); + const focusInput = () => { + if (ref.current) { + ref.current.focus(); + } + }; + const renderEditableContent = () => (
- {!isValid &&
{validationError}
} + {!isValid && ( +
+ {validationError} +
+ )} ); diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Text.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Text.jsx index 6e8639e5b1..6b1f631d63 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Text.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Text.jsx @@ -72,6 +72,12 @@ export const TextColumn = ({ [cellTextColor, isMaxRowHeightAuto, maxRowHeightValue, cellHeight] ); + const focusInput = () => { + if (cellRef.current) { + cellRef.current.focus(); + } + }; + const renderContent = useCallback(() => { if (!isEditable) { return ( @@ -95,7 +101,7 @@ export const TextColumn = ({ darkMode ? 'textarea-dark-theme' : '' }`} style={{ - ...cellStyle, + color: cellTextColor || 'inherit', maxWidth: containerWidth, outline: 'none', border: 'none', @@ -112,22 +118,25 @@ export const TextColumn = ({ handleContentChange(e.target.innerHTML); } }} - dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(cellValue) }} onKeyDown={handleKeyDown} onFocus={() => setIsEditing(true)} - /> + suppressContentEditableWarning={true} + > + + ); }, [ isEditable, isValid, darkMode, - cellStyle, + cellTextColor, containerWidth, - cellValue, handleKeyDown, - handleContentChange, - horizontalAlignment, + cellValue, searchText, + horizontalAlignment, + cellStyle, + handleContentChange, ]); return ( @@ -166,7 +175,11 @@ export const TextColumn = ({ > {renderContent()} - {isEditable && !isValid &&
{validationError}
} + {isEditable && !isValid && ( +
+ {validationError} +
+ )} ); diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/TableData/_components/TableRow.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/TableData/_components/TableRow.jsx index 9f61bd0ae3..d1c2030154 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/TableData/_components/TableRow.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/TableData/_components/TableRow.jsx @@ -116,7 +116,6 @@ export const TableRow = ({ className={`td-container ${ cell.column.columnDef?.meta?.columnType === 'image' && 'jet-table-image-column h-100' } ${cell.column.columnDef?.meta?.columnType !== 'image' && `w-100 h-100`}`} - style={{ display: 'flex', alignItems: 'center' }} > {flexRender(cell.column?.columnDef?.cell, cell.getContext())} diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_utils/generateColumnsData.js b/frontend/src/AppBuilder/Widgets/NewTable/_utils/generateColumnsData.js index 868ab5a0c1..1cbbbd1904 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_utils/generateColumnsData.js +++ b/frontend/src/AppBuilder/Widgets/NewTable/_utils/generateColumnsData.js @@ -219,6 +219,8 @@ export default function generateColumnsData({ isEditable={isEditable} isMulti={columnType === 'newMultiSelect'} className="select-search table-select-search" + column={column} + isNewRow={columnForAddNewRow} /> );