From a835f9091f6dd825d7e24802cc74809576f21ddf Mon Sep 17 00:00:00 2001 From: Kavin Venkatachalam Date: Fri, 28 Mar 2025 20:26:14 +0530 Subject: [PATCH] fix: bugfixes on column data types and table --- .../_components/DataTypes/Datepicker.jsx | 20 +- .../NewTable/_components/DataTypes/Link.jsx | 30 +- .../NewTable/_components/DataTypes/Number.jsx | 51 ++-- .../_components/CustomDatePickerHeader.jsx | 93 ++++++ .../NewTable/_components/Footer/Footer.jsx | 1 + .../Footer/_components/AddNewRow.jsx | 17 +- .../Footer/_components/ControlButtons.jsx | 289 ++++++++++-------- .../HighLightSearch/HighLightSearch.jsx | 7 +- .../TableContainer/TableContainer.jsx | 1 - .../TableData/_components/TableHeader.jsx | 2 + .../TableData/_components/TableRow.jsx | 10 +- .../TableExposedVariables.jsx | 7 +- .../NewTable/_stores/slices/initSlice.js | 22 +- .../NewTable/_utils/buildTableColumn.js | 2 +- .../NewTable/_utils/generateActionColumns.js | 2 +- .../NewTable/_utils/generateColumnsData.js | 15 +- 16 files changed, 371 insertions(+), 198 deletions(-) create mode 100644 frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/_components/CustomDatePickerHeader.jsx diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Datepicker.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Datepicker.jsx index 62e4b0cc0d..ca8ae506fe 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Datepicker.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Datepicker.jsx @@ -3,6 +3,7 @@ import DatePickerComponent from 'react-datepicker'; import moment from 'moment-timezone'; import cx from 'classnames'; import SolidIcon from '@/_ui/Icon/SolidIcons'; +import CustomDatePickerHeader from './_components/CustomDatePickerHeader'; import 'react-datepicker/dist/react-datepicker.css'; const DISABLED_DATE_FORMAT = 'MM/DD/YYYY'; @@ -24,14 +25,16 @@ const DatepickerInput = forwardRef(({ value, onClick, styles, readOnly, onInputC onChange={onInputChange} onFocus={onInputFocus} /> - - - + {!readOnly && ( + + + + )} )} @@ -253,6 +256,7 @@ export const DatepickerColumn = ({ dropdownMode="select" excludeDates={excludedDates} showPopperArrow={false} + renderCustomHeader={(headerProps) => } shouldCloseOnSelect readOnly={readOnly} popperProps={{ strategy: 'fixed' }} diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Link.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Link.jsx index f5a58b3adb..dd5e5632a8 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Link.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Link.jsx @@ -8,20 +8,22 @@ export const LinkColumn = ({ cellValue, linkTarget, underline, underlineColor, l return (
- e.stopPropagation()} - style={{ - color: linkTextColor, - textDecoration: underline === 'always' && 'underline', - textDecorationColor: underlineColor, - }} - rel="noopener noreferrer" - > - {displayText || String(cellValue)} - +
+ e.stopPropagation()} + style={{ + color: linkTextColor, + textDecoration: underline === 'always' && 'underline', + textDecorationColor: underlineColor, + }} + rel="noopener noreferrer" + > + {displayText || String(cellValue)} + +
); }; diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Number.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Number.jsx index b76a51463d..c740b3ddc1 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Number.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/Number.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import useStore from '@/AppBuilder/_stores/store'; import { shallow } from 'zustand/shallow'; import { determineJustifyContentValue } from '@/_helpers/utils'; @@ -16,7 +16,25 @@ export const NumberColumn = ({ row, searchText, }) => { + const [displayValue, setDisplayValue] = useState(cellValue); const validateWidget = useStore((state) => state.validateWidget, shallow); + const getResolvedValue = useStore((state) => state.getResolvedValue, shallow); + + useEffect(() => { + setDisplayValue(cellValue); + }, [cellValue]); + + const removingExcessDecimalPlaces = (value, allowedDecimalPlaces) => { + if (value?.toString()?.includes('.')) { + const [integerPart, decimalPart] = value.toString().split('.'); + const truncatedDecimalPart = decimalPart.slice(0, allowedDecimalPlaces); + return Number(`${integerPart}.${truncatedDecimalPart}`); + } + return value; + }; + + const allowedDecimalPlaces = getResolvedValue(column?.decimalPlaces) ?? null; + cellValue = allowedDecimalPlaces ? removingExcessDecimalPlaces(cellValue, allowedDecimalPlaces) : cellValue; const validationData = validateWidget({ validationObject: { @@ -55,26 +73,15 @@ export const NumberColumn = ({ } }; - const removingExcessDecimalPlaces = (value, allowedDecimalPlaces) => { - if (value?.toString()?.includes('.')) { - const [integerPart, decimalPart] = value.toString().split('.'); - const truncatedDecimalPart = decimalPart.slice(0, allowedDecimalPlaces); - return Number(`${integerPart}.${truncatedDecimalPart}`); - } - return value; - }; - const handleValueChange = (value) => { if (value === '') return; const numValue = Number(value); if (isNaN(numValue)) return; - const allowedDecimalPlaces = column?.decimalPlaces ?? null; - const processedValue = allowedDecimalPlaces - ? removingExcessDecimalPlaces(numValue, allowedDecimalPlaces) - : numValue; - + const processedValue = + allowedDecimalPlaces !== null ? removingExcessDecimalPlaces(numValue, allowedDecimalPlaces) : numValue; + setDisplayValue(processedValue); handleCellValueChange(row.index, column.key || column.name, processedValue, row.original); }; @@ -91,17 +98,19 @@ export const NumberColumn = ({ paddingRight: '20px', }} className={`table-column-type-input-element input-number h-100 ${!isValid ? 'is-invalid' : ''}`} - defaultValue={cellValue} + value={displayValue} + onChange={(e) => setDisplayValue(e.target.value)} + step={allowedDecimalPlaces !== null ? `0.${'0'.repeat(allowedDecimalPlaces - 1)}1` : 'any'} onKeyDown={(e) => { if (e.key === 'Enter') { - if (e.target.defaultValue !== e.target.value) { - handleValueChange(e.target.value); + if (displayValue !== cellValue) { + handleValueChange(displayValue); } } }} - onBlur={(e) => { - if (e.target.defaultValue !== e.target.value) { - handleValueChange(e.target.value); + onBlur={() => { + if (displayValue !== cellValue) { + handleValueChange(displayValue); } }} onFocus={(e) => e.stopPropagation()} diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/_components/CustomDatePickerHeader.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/_components/CustomDatePickerHeader.jsx new file mode 100644 index 0000000000..98cab64487 --- /dev/null +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/DataTypes/_components/CustomDatePickerHeader.jsx @@ -0,0 +1,93 @@ +import React from 'react'; +import SolidIcon from '@/_ui/Icon/SolidIcons'; +import moment from 'moment'; +import { range } from 'lodash'; + +const CustomDatePickerHeader = ({ + date, + changeYear, + changeMonth, + decreaseMonth, + increaseMonth, + prevMonthButtonDisabled, + nextMonthButtonDisabled, +}) => { + const months = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', + ]; + + const years = range(1900, 2101); + + return ( + <> +
+ +
+ + +
+ + +
+ + ); +}; + +export default CustomDatePickerHeader; diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/Footer/Footer.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/Footer/Footer.jsx index aa6e0953eb..ed41e56d98 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/Footer/Footer.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/Footer/Footer.jsx @@ -89,6 +89,7 @@ export const Footer = memo( height={height} componentName={componentName} setShowAddNewRowPopup={setShowAddNewRowPopup} + fireEvent={fireEvent} columnVisibility={columnVisibility} // Passed to trigger a re-render when columnVisibility changes /> diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/Footer/_components/AddNewRow.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/Footer/_components/AddNewRow.jsx index c9ea7b913a..8d50f9e513 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/Footer/_components/AddNewRow.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/Footer/_components/AddNewRow.jsx @@ -13,17 +13,24 @@ export function AddNewRow({ id, hideAddNewRowPopup, darkMode, allColumns, fireEv const addNewRowDetails = useTableStore((state) => state.getAllAddNewRowDetails(id), shallow); const updateAddNewRowDetails = useTableStore((state) => state.updateAddNewRowDetails, shallow); const clearAddNewRowDetails = useTableStore((state) => state.clearAddNewRowDetails, shallow); + const updateShouldPersistAddNewRow = useTableStore((state) => state.updateShouldPersistAddNewRow, shallow); const addNewRowDetailsLength = addNewRowDetails.size; const newEmptyRow = useMemo(() => { return allColumns.reduce((accumulator, column) => { + if (column.columnDef?.meta?.skipAddNewRow) return accumulator; const key = column.columnDef.accessorKey; - if (column.id !== 'selection') accumulator[key] = ''; + accumulator[key] = ''; return accumulator; }, {}); }, [allColumns]); + useEffect(() => { + clearAddNewRowDetails(id); + updateShouldPersistAddNewRow(id, false); + }, [updateShouldPersistAddNewRow, clearAddNewRowDetails, id]); + useEffect(() => { function discardNewlyAddedRows() { clearAddNewRowDetails(id); @@ -81,6 +88,11 @@ export function AddNewRow({ id, hideAddNewRowPopup, darkMode, allColumns, fireEv updateAddNewRowDetails(id, addNewRowDetailsLength, newEmptyRow); }; + const closeAddNewRowPopup = () => { + hideAddNewRowPopup(); + updateShouldPersistAddNewRow(id, true); + }; + return (
@@ -90,7 +102,7 @@ export function AddNewRow({ id, hideAddNewRowPopup, darkMode, allColumns, fireEv
-
@@ -178,7 +190,6 @@ export function AddNewRow({ id, hideAddNewRowPopup, darkMode, allColumns, fireEv onClick={async () => { await fireEvent('onNewRowsAdded'); hideAddNewRowPopup(); - clearAddNewRowDetails(id); }} size="sm" customStyles={{ padding: '10px 20px' }} diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/Footer/_components/ControlButtons.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/Footer/_components/ControlButtons.jsx index e62efde29e..500d3ee991 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/Footer/_components/ControlButtons.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/Footer/_components/ControlButtons.jsx @@ -8,19 +8,20 @@ import IndeterminateCheckbox from '../../IndeterminateCheckbox'; import Popover from 'react-bootstrap/Popover'; import { exportToCSV, exportToExcel, exportToPDF } from '@/AppBuilder/Widgets/NewTable/_utils/exportData'; -export const ControlButtons = memo(({ id, table, darkMode, height, componentName, setShowAddNewRowPopup }) => { - const showAddNewRowButton = useTableStore((state) => state.getTableProperties(id)?.showAddNewRowButton, shallow); - const showDownloadButton = useTableStore((state) => state.getTableProperties(id)?.showDownloadButton, shallow); - const hideColumnSelectorButton = useTableStore( - (state) => state.getTableProperties(id)?.hideColumnSelectorButton, - shallow - ); +export const ControlButtons = memo( + ({ id, table, darkMode, height, componentName, setShowAddNewRowPopup, fireEvent }) => { + const showAddNewRowButton = useTableStore((state) => state.getTableProperties(id)?.showAddNewRowButton, shallow); + const showDownloadButton = useTableStore((state) => state.getTableProperties(id)?.showDownloadButton, shallow); + const hideColumnSelectorButton = useTableStore( + (state) => state.getTableProperties(id)?.hideColumnSelectorButton, + shallow + ); + const clientSidePagination = useTableStore((state) => state.getTableProperties(id)?.clientSidePagination, shallow); - const renderOverlay = (id, icon, callBack, tooltipId, tooltipContent) => { - return ( - <> - - + const renderButton = (icon, onClick, tooltipId, tooltipContent) => { + return ( + <> + { - if (document.activeElement === e.currentTarget) { - e.currentTarget.blur(); - } - }} - > - - - ); - }; - - // Haven't seperated this into a separate component because of UI issues - const hideColumnsPopover = () => ( - -
-
- - - Selects All - -
- {table.getAllLeafColumns().map((column) => { - const header = column?.columnDef?.header; - return ( - typeof header === 'string' && ( -
-
- -
-
- ) - ); - })} -
-
- ); - - // Haven't seperated this into a separate component because of UI issues - const downlaodPopover = () => ( - - -
- exportToCSV(table, componentName)} - > - Download as CSV - - exportToExcel(table, componentName)} - > - Download as Excel - - exportToPDF(table, componentName)} - > - Download as PDF - -
-
-
- ); - - return ( -
- {showAddNewRowButton && ( - <> - - { - setShowAddNewRowPopup(true); - }} - size="md" - data-tooltip-id="tooltip-for-add-new-row" - data-tooltip-content="Add new row" + onClick={onClick} > - )} - {showDownloadButton && renderOverlay(id, 'filedownload', downlaodPopover, 'tooltip-for-download', 'Download')} - {!hideColumnSelectorButton && - renderOverlay(id, 'eye1', hideColumnsPopover, 'tooltip-for-manage-columns', 'Manage columns')} -
- ); -}); + ); + }; + + const renderOverlay = (id, icon, callBack, tooltipId, tooltipContent) => { + const onClick = (e) => { + if (document.activeElement === e.currentTarget) { + e.currentTarget.blur(); + } + }; + + return ( + <> + + + {renderButton(icon, onClick, tooltipId, tooltipContent)} + + + ); + }; + + // Haven't seperated this into a separate component because of UI issues + const hideColumnsPopover = () => ( + +
+
+ + + Selects All + +
+ {table.getAllLeafColumns().map((column) => { + const header = column?.columnDef?.header; + return ( + typeof header === 'string' && ( +
+
+ +
+
+ ) + ); + })} +
+
+ ); + + // Haven't seperated this into a separate component because of UI issues + const downlaodPopover = () => ( + + +
+ exportToCSV(table, componentName)} + > + Download as CSV + + exportToExcel(table, componentName)} + > + Download as Excel + + exportToPDF(table, componentName)} + > + Download as PDF + +
+
+
+ ); + + const renderDownloadButton = () => { + if (!clientSidePagination) { + const onClick = () => { + fireEvent('onTableDataDownload'); + }; + return renderButton('filedownload', onClick, 'tooltip-for-download-serverside-pagingation', 'Download'); + } + + return renderOverlay(id, 'filedownload', downlaodPopover, 'tooltip-for-download', 'Download'); + }; + + return ( +
+ {showAddNewRowButton && ( + <> + + { + setShowAddNewRowPopup(true); + }} + size="md" + data-tooltip-id="tooltip-for-add-new-row" + data-tooltip-content="Add new row" + > + + )} + {renderDownloadButton()} + {!hideColumnSelectorButton && + renderOverlay(id, 'eye1', hideColumnsPopover, 'tooltip-for-manage-columns', 'Manage columns')} +
+ ); + } +); diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/HighLightSearch/HighLightSearch.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/HighLightSearch/HighLightSearch.jsx index 4df716c9c2..af44ba429b 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/HighLightSearch/HighLightSearch.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/HighLightSearch/HighLightSearch.jsx @@ -1,14 +1,17 @@ import React from 'react'; export const HighLightSearch = React.memo(({ text, searchTerm }) => { - if (searchTerm === '' || !text.toString()?.toLowerCase().includes(searchTerm?.toLowerCase())) return text; + if (text === '') return null; + + if (searchTerm === '' || !text.toString()?.toLowerCase().includes(searchTerm?.toLowerCase())) + return {text}; const parts = String(text).split(new RegExp(`(${searchTerm})`, 'gi')); return ( {parts.map((part, index) => - part.toLowerCase() === searchTerm.toLowerCase() ? ( + part?.toLowerCase() === searchTerm?.toLowerCase() ? ( {part} diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/TableContainer/TableContainer.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/TableContainer/TableContainer.jsx index 0883f321e0..dcdaf1fadb 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/TableContainer/TableContainer.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/TableContainer/TableContainer.jsx @@ -22,7 +22,6 @@ export const TableContainer = ({ useTableStore(); const columnProperties = getColumnProperties(id); - // Table properties const showBulkSelector = useTableStore((state) => state.getTableProperties(id)?.showBulkSelector, shallow); const enableSorting = useTableStore((state) => state.getTableProperties(id)?.enabledSort, shallow); diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_components/TableData/_components/TableHeader.jsx b/frontend/src/AppBuilder/Widgets/NewTable/_components/TableData/_components/TableHeader.jsx index fc86639dfb..67240c5887 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/TableData/_components/TableHeader.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/TableData/_components/TableHeader.jsx @@ -17,6 +17,7 @@ const DraggableHeader = ({ header, darkMode, id }) => { }); const columnHeaderWrap = useTableStore((state) => state.getTableStyles(id)?.columnHeaderWrap, shallow); + const headerCasing = useTableStore((state) => state.getTableStyles(id)?.headerCasing, shallow); const getResolvedValue = useStore.getState().getResolvedValue; @@ -82,6 +83,7 @@ const DraggableHeader = ({ header, darkMode, id }) => { 'text-truncate': getResolvedValue(columnHeaderWrap) === 'fixed', 'wrap-wrapper': getResolvedValue(columnHeaderWrap) === 'wrap', })} + style={{ textTransform: headerCasing === 'uppercase' ? 'uppercase' : 'none' }} > {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
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 d1c2030154..77d759ad7d 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_components/TableData/_components/TableRow.jsx +++ b/frontend/src/AppBuilder/Widgets/NewTable/_components/TableData/_components/TableRow.jsx @@ -51,9 +51,6 @@ export const TableRow = ({ fireEvent('onRowHovered'); } }} - onMouseLeave={() => { - hasHoveredEvent && setExposedVariables({ hoveredRowId: '', hoveredRow: '' }); - }} > {row.getVisibleCells().map((cell) => { const cellStyles = { @@ -65,6 +62,7 @@ export const TableRow = ({ justifyContent: determineJustifyContentValue(cell.column.columnDef?.meta?.horizontalAlignment), display: 'flex', alignItems: 'center', + textAlign: cell.column.columnDef?.meta?.horizontalAlignment, }; const isEditable = getResolvedValue(cell.column.columnDef?.meta?.isEditable ?? false, { @@ -76,9 +74,13 @@ export const TableRow = ({ { const editedRows = useTableStore((state) => state.getAllEditedRows(id), shallow); @@ -63,6 +63,8 @@ export const TableExposedVariables = ({ columnSizing: table.getState().columnSizing, }; + const prevSortingLength = useRef(null); + const getColumnName = useCallback( (columnId) => { const column = table.getColumn(columnId); @@ -147,8 +149,11 @@ export const TableExposedVariables = ({ const sortApplied = [{ column: getColumnName(sorting[0].id), direction: sorting[0].desc ? 'desc' : 'asc' }]; setExposedVariables({ sortApplied }); fireEvent('onSort'); + prevSortingLength.current = sorting.length; } else { setExposedVariables({ sortApplied: undefined }); + prevSortingLength.current && fireEvent('onSort'); + prevSortingLength.current = null; } }, [sorting, getColumnName, setExposedVariables, fireEvent]); diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_stores/slices/initSlice.js b/frontend/src/AppBuilder/Widgets/NewTable/_stores/slices/initSlice.js index edd548e8fe..ded47684d7 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_stores/slices/initSlice.js +++ b/frontend/src/AppBuilder/Widgets/NewTable/_stores/slices/initSlice.js @@ -3,7 +3,7 @@ import { utilityForNestedNewRow } from '../helper'; import { deepClone } from '@/_helpers/utilities/utils.helpers'; export const createInitSlice = (set, get) => ({ - initializeComponent: (id) => + initializeComponent: (id) => { set( (state) => { if (!state.components[id]) { @@ -12,6 +12,7 @@ export const createInitSlice = (set, get) => ({ styles: {}, filters: {}, addNewRow: new Map(), + shouldPersistAddNewRow: false, editedRowDetails: { editedRows: new Map(), editedFields: new Map(), @@ -31,7 +32,8 @@ export const createInitSlice = (set, get) => ({ }, false, { type: 'initializeComponent', payload: { id } } - ), + ); + }, setTableProperties: (id, properties) => set( @@ -105,10 +107,9 @@ export const createInitSlice = (set, get) => ({ maxRowHeight = 'auto', maxRowHeightValue = 80, columnHeaderWrap = 'fixed', + headerCasing = 'uppercase', } = styles; - console.log('style--- cellSize--- ', cellSize); - state.components[id].styles.borderRadius = Number.parseFloat(borderRadius); state.components[id].styles.boxShadow = boxShadow; state.components[id].styles.borderColor = borderColor; @@ -120,6 +121,7 @@ export const createInitSlice = (set, get) => ({ state.components[id].styles.isMaxRowHeightAuto = maxRowHeight === 'auto'; state.components[id].styles.maxRowHeightValue = maxRowHeightValue; state.components[id].styles.columnHeaderWrap = columnHeaderWrap; + state.components[id].styles.headerCasing = headerCasing; }, false, { type: 'setStyles', payload: { id, styles } } @@ -239,11 +241,21 @@ export const createInitSlice = (set, get) => ({ clearAddNewRowDetails: (id) => set( (state) => { - state.components[id].addNewRow.clear(); + if (!state.components[id].shouldPersistAddNewRow) { + state.components[id].addNewRow.clear(); + } }, false, { type: 'clearNewRow', payload: { id } } ), + updateShouldPersistAddNewRow: (id, value) => + set( + (state) => { + state.components[id].shouldPersistAddNewRow = value; + }, + false, + { type: 'updateShouldPersistAddNewRow', payload: { id, value } } + ), getTableComponentEvents: (id) => { return get().components[id]?.events?.tableComponentEvents || []; }, diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_utils/buildTableColumn.js b/frontend/src/AppBuilder/Widgets/NewTable/_utils/buildTableColumn.js index f84745154a..c46dac58bf 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_utils/buildTableColumn.js +++ b/frontend/src/AppBuilder/Widgets/NewTable/_utils/buildTableColumn.js @@ -63,7 +63,7 @@ export const buildTableColumn = ( fireEvent, tableRef: tableBodyRef, handleCellValueChange, - searchText: serverSideSearch ? '' : globalFilter, + searchText: globalFilter, }).filter(Boolean), ...generateActionColumns({ diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_utils/generateActionColumns.js b/frontend/src/AppBuilder/Widgets/NewTable/_utils/generateActionColumns.js index 59d16a6a7d..91240c90e8 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_utils/generateActionColumns.js +++ b/frontend/src/AppBuilder/Widgets/NewTable/_utils/generateActionColumns.js @@ -9,7 +9,7 @@ export const generateActionColumns = ({ actions, fireEvent, setExposedVariables, id: `${position}Actions`, accessorKey: 'actions', enableResizing: false, - meta: { columnType: 'action', position, skipFilter: true }, + meta: { columnType: 'action', position, skipFilter: true, skipAddNewRow: true }, size: 90, header: 'Actions', cell: ({ row, cell }) => ( diff --git a/frontend/src/AppBuilder/Widgets/NewTable/_utils/generateColumnsData.js b/frontend/src/AppBuilder/Widgets/NewTable/_utils/generateColumnsData.js index 1cbbbd1904..fb5c73fad3 100644 --- a/frontend/src/AppBuilder/Widgets/NewTable/_utils/generateColumnsData.js +++ b/frontend/src/AppBuilder/Widgets/NewTable/_utils/generateColumnsData.js @@ -79,6 +79,9 @@ export default function generateColumnsData({ } const isEditable = getResolvedValue(column.isEditable); + const isVisible = getResolvedValue(column.columnVisibility) ?? true; + + if (!isVisible) return null; const columnDef = { id: column.id || uuidv4(), @@ -91,7 +94,7 @@ export default function generateColumnsData({ filterFn: 'applyFilters', size: columnSize || defaultColumn.width, minSize: 60, - show: column?.columnVisibility ?? true, + show: isVisible, meta: { columnType, isEditable: isEditable, @@ -100,7 +103,7 @@ export default function generateColumnsData({ horizontalAlignment: column?.horizontalAlignment ?? 'left', transformation: column.transformation, validation: column.validation, - columnVisibility: column.columnVisibility, + columnVisibility: isVisible, ...column, }, @@ -108,9 +111,9 @@ export default function generateColumnsData({ const changeSet = columnForAddNewRow ? getAddNewRowDetailFromIndex(id, row.index) : getEditedRowFromIndex(id, row.index); - const cellValue = changeSet - ? changeSet[cell.column.columnDef?.meta?.name] ?? cell.getValue() - : cell.getValue(); + + let cellValue = changeSet ? changeSet[cell.column.columnDef?.meta?.name] ?? cell.getValue() : cell.getValue(); + cellValue = cellValue === undefined || cellValue === null ? '' : cellValue; const rowData = tableData?.[row.index]; switch (columnType) { @@ -221,6 +224,8 @@ export default function generateColumnsData({ className="select-search table-select-search" column={column} isNewRow={columnForAddNewRow} + horizontalAlignment={column?.horizontalAlignment} + textColor={getResolvedValue(column.textColor, { cellValue, rowData })} /> );