fix: bugfixes on column data types and table

This commit is contained in:
Kavin Venkatachalam 2025-03-28 20:26:14 +05:30
parent b79b073b38
commit a835f9091f
16 changed files with 371 additions and 198 deletions

View file

@ -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}
/>
<span className="cell-icon-display">
<SolidIcon
width="16"
fill="var(--borders-strong)"
name="calender"
className="table-column-datepicker-input-icon"
/>
</span>
{!readOnly && (
<span className="cell-icon-display">
<SolidIcon
width="16"
fill="var(--borders-strong)"
name="calender"
className="table-column-datepicker-input-icon"
/>
</span>
)}
</>
)}
</div>
@ -253,6 +256,7 @@ export const DatepickerColumn = ({
dropdownMode="select"
excludeDates={excludedDates}
showPopperArrow={false}
renderCustomHeader={(headerProps) => <CustomDatePickerHeader {...headerProps} />}
shouldCloseOnSelect
readOnly={readOnly}
popperProps={{ strategy: 'fixed' }}

View file

@ -8,20 +8,22 @@ export const LinkColumn = ({ cellValue, linkTarget, underline, underlineColor, l
return (
<div className="h-100 d-flex align-items-center">
<a
className={underline === 'hover' ? 'table-link-hover' : 'table-link'}
href={cellValue}
target={linkTarget === '_self' || linkTarget == false ? '_self' : '_blank'}
onClick={(e) => e.stopPropagation()}
style={{
color: linkTextColor,
textDecoration: underline === 'always' && 'underline',
textDecorationColor: underlineColor,
}}
rel="noopener noreferrer"
>
{displayText || String(cellValue)}
</a>
<div className="w-100">
<a
className={underline === 'hover' ? 'table-link-hover' : 'table-link'}
href={cellValue}
target={linkTarget === '_self' || linkTarget == false ? '_self' : '_blank'}
onClick={(e) => e.stopPropagation()}
style={{
color: linkTextColor,
textDecoration: underline === 'always' && 'underline',
textDecorationColor: underlineColor,
}}
rel="noopener noreferrer"
>
{displayText || String(cellValue)}
</a>
</div>
</div>
);
};

View file

@ -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()}

View file

@ -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 (
<>
<div
style={{
marginBottom: 10,
marginTop: 10,
display: 'flex',
justifyContent: 'center',
}}
>
<button
className="tj-datepicker-widget-arrows tj-datepicker-widget-left"
onClick={(e) => {
e.stopPropagation();
decreaseMonth();
}}
disabled={prevMonthButtonDisabled}
>
<SolidIcon name="cheveronleft" width="12" />
</button>
<div style={{ marginRight: '8px' }}>
<select
value={months[moment(date).month()]}
onChange={({ target: { value } }) => changeMonth(months.indexOf(value))}
className="tj-datepicker-widget-month-selector"
>
{months.map((option) => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
<select
value={moment(date).year()}
onChange={({ target: { value } }) => changeYear(value)}
className="tj-datepicker-widget-year-selector"
style={{ padding: '4px 6px' }}
>
{years.map((option) => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
</div>
<button
className="tj-datepicker-widget-arrows tj-datepicker-widget-right "
onClick={(e) => {
e.stopPropagation();
increaseMonth();
}}
disabled={nextMonthButtonDisabled}
>
<SolidIcon name="cheveronright" width="12" />
</button>
</div>
</>
);
};
export default CustomDatePickerHeader;

View file

@ -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
/>
</div>

View file

@ -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 (
<div className={`table-add-new-row card ${darkMode && 'dark-theme'}`}>
<div className="card-header row">
@ -90,7 +102,7 @@ export function AddNewRow({ id, hideAddNewRowPopup, darkMode, allColumns, fireEv
</h4>
</div>
<div className="col-auto">
<button data-cy={`button-close-filters`} onClick={hideAddNewRowPopup} className="btn btn-light btn-sm">
<button data-cy={`button-close-filters`} onClick={closeAddNewRowPopup} className="btn btn-light btn-sm">
x
</button>
</div>
@ -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' }}

View file

@ -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 (
<>
<Tooltip id={tooltipId} className="tooltip" />
<OverlayTriggerComponent trigger="click" overlay={callBack()} rootClose={true} placement={'top-end'}>
const renderButton = (icon, onClick, tooltipId, tooltipContent) => {
return (
<>
<Tooltip id={tooltipId} className="tooltip" />
<ButtonSolid
variant="ghostBlack"
className={`tj-text-xsm `}
@ -33,125 +34,149 @@ export const ControlButtons = memo(({ id, table, darkMode, height, componentName
size="md"
data-tooltip-id={tooltipId}
data-tooltip-content={tooltipContent}
onClick={(e) => {
if (document.activeElement === e.currentTarget) {
e.currentTarget.blur();
}
}}
></ButtonSolid>
</OverlayTriggerComponent>
</>
);
};
// Haven't seperated this into a separate component because of UI issues
const hideColumnsPopover = () => (
<Popover className={`${darkMode && 'dark-theme'}`} style={{ maxHeight: `${height - 79}px`, overflowY: 'auto' }}>
<div
data-cy={`dropdown-hide-column`}
className={`dropdown-table-column-hide-common ${
darkMode ? 'dropdown-table-column-hide-dark-themed dark-theme' : 'dropdown-table-column-hide'
} `}
placement="top-end"
>
<div className="dropdown-item cursor-pointer">
<IndeterminateCheckbox
checked={table.getIsAllColumnsVisible()}
onChange={table.getToggleAllColumnsVisibilityHandler()}
/>
<span className="hide-column-name tj-text-xsm" data-cy={`options-select-all-coloumn`}>
Selects All
</span>
</div>
{table.getAllLeafColumns().map((column) => {
const header = column?.columnDef?.header;
return (
typeof header === 'string' && (
<div key={column.id}>
<div>
<label className="dropdown-item d-flex cursor-pointer">
<input
type="checkbox"
data-cy={`checkbox-coloumn-${String(header).toLowerCase().replace(/\s+/g, '-')}`}
checked={column.getIsVisible()}
onChange={column.getToggleVisibilityHandler()}
/>
<span
className="hide-column-name tj-text-xsm"
data-cy={`options-coloumn-${String(header).toLowerCase().replace(/\s+/g, '-')}`}
>
{` ${header}`}
</span>
</label>
</div>
</div>
)
);
})}
</div>
</Popover>
);
// Haven't seperated this into a separate component because of UI issues
const downlaodPopover = () => (
<Popover
id="popover-basic"
data-cy="popover-card"
className={`${darkMode && 'dark-theme'} shadow table-widget-download-popup`}
placement="top-end"
>
<Popover.Body className="p-0">
<div className="table-download-option cursor-pointer">
<span
data-cy={`option-download-CSV`}
className="cursor-pointer"
onClick={() => exportToCSV(table, componentName)}
>
Download as CSV
</span>
<span
data-cy={`option-download-execel`}
className="pt-2 cursor-pointer"
onClick={() => exportToExcel(table, componentName)}
>
Download as Excel
</span>
<span
data-cy={`option-download-pdf`}
className="pt-2 cursor-pointer"
onClick={() => exportToPDF(table, componentName)}
>
Download as PDF
</span>
</div>
</Popover.Body>
</Popover>
);
return (
<div className="col d-flex justify-content-end ">
{showAddNewRowButton && (
<>
<Tooltip id="tooltip-for-add-new-row" className="tooltip" />
<ButtonSolid
variant="ghostBlack"
fill={`var(--icons-default)`}
className={'tj-text-xsm'}
customStyles={{ minWidth: '32px' }}
leftIcon="plus"
iconWidth="16"
onClick={() => {
setShowAddNewRowPopup(true);
}}
size="md"
data-tooltip-id="tooltip-for-add-new-row"
data-tooltip-content="Add new row"
onClick={onClick}
></ButtonSolid>
</>
)}
{showDownloadButton && renderOverlay(id, 'filedownload', downlaodPopover, 'tooltip-for-download', 'Download')}
{!hideColumnSelectorButton &&
renderOverlay(id, 'eye1', hideColumnsPopover, 'tooltip-for-manage-columns', 'Manage columns')}
</div>
);
});
);
};
const renderOverlay = (id, icon, callBack, tooltipId, tooltipContent) => {
const onClick = (e) => {
if (document.activeElement === e.currentTarget) {
e.currentTarget.blur();
}
};
return (
<>
<Tooltip id={tooltipId} className="tooltip" />
<OverlayTriggerComponent trigger="click" overlay={callBack()} rootClose={true} placement={'top-end'}>
{renderButton(icon, onClick, tooltipId, tooltipContent)}
</OverlayTriggerComponent>
</>
);
};
// Haven't seperated this into a separate component because of UI issues
const hideColumnsPopover = () => (
<Popover className={`${darkMode && 'dark-theme'}`} style={{ maxHeight: `${height - 79}px`, overflowY: 'auto' }}>
<div
data-cy={`dropdown-hide-column`}
className={`dropdown-table-column-hide-common ${
darkMode ? 'dropdown-table-column-hide-dark-themed dark-theme' : 'dropdown-table-column-hide'
} `}
placement="top-end"
>
<div className="dropdown-item cursor-pointer">
<IndeterminateCheckbox
checked={table.getIsAllColumnsVisible()}
onChange={table.getToggleAllColumnsVisibilityHandler()}
/>
<span className="hide-column-name tj-text-xsm" data-cy={`options-select-all-coloumn`}>
Selects All
</span>
</div>
{table.getAllLeafColumns().map((column) => {
const header = column?.columnDef?.header;
return (
typeof header === 'string' && (
<div key={column.id}>
<div>
<label className="dropdown-item d-flex cursor-pointer">
<input
type="checkbox"
data-cy={`checkbox-coloumn-${String(header).toLowerCase().replace(/\s+/g, '-')}`}
checked={column.getIsVisible()}
onChange={column.getToggleVisibilityHandler()}
/>
<span
className="hide-column-name tj-text-xsm"
data-cy={`options-coloumn-${String(header).toLowerCase().replace(/\s+/g, '-')}`}
>
{` ${header}`}
</span>
</label>
</div>
</div>
)
);
})}
</div>
</Popover>
);
// Haven't seperated this into a separate component because of UI issues
const downlaodPopover = () => (
<Popover
id="popover-basic"
data-cy="popover-card"
className={`${darkMode && 'dark-theme'} shadow table-widget-download-popup`}
placement="top-end"
>
<Popover.Body className="p-0">
<div className="table-download-option cursor-pointer">
<span
data-cy={`option-download-CSV`}
className="cursor-pointer"
onClick={() => exportToCSV(table, componentName)}
>
Download as CSV
</span>
<span
data-cy={`option-download-execel`}
className="pt-2 cursor-pointer"
onClick={() => exportToExcel(table, componentName)}
>
Download as Excel
</span>
<span
data-cy={`option-download-pdf`}
className="pt-2 cursor-pointer"
onClick={() => exportToPDF(table, componentName)}
>
Download as PDF
</span>
</div>
</Popover.Body>
</Popover>
);
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 (
<div className="col d-flex justify-content-end ">
{showAddNewRowButton && (
<>
<Tooltip id="tooltip-for-add-new-row" className="tooltip" />
<ButtonSolid
variant="ghostBlack"
fill={`var(--icons-default)`}
className={'tj-text-xsm'}
customStyles={{ minWidth: '32px' }}
leftIcon="plus"
iconWidth="16"
onClick={() => {
setShowAddNewRowPopup(true);
}}
size="md"
data-tooltip-id="tooltip-for-add-new-row"
data-tooltip-content="Add new row"
></ButtonSolid>
</>
)}
{renderDownloadButton()}
{!hideColumnSelectorButton &&
renderOverlay(id, 'eye1', hideColumnsPopover, 'tooltip-for-manage-columns', 'Manage columns')}
</div>
);
}
);

View file

@ -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 <span>{text}</span>;
const parts = String(text).split(new RegExp(`(${searchTerm})`, 'gi'));
return (
<span>
{parts.map((part, index) =>
part.toLowerCase() === searchTerm.toLowerCase() ? (
part?.toLowerCase() === searchTerm?.toLowerCase() ? (
<span key={index}>
<mark>{part}</mark>
</span>

View file

@ -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);

View file

@ -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())}
</div>

View file

@ -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 = ({
<td
key={cell.id}
style={cellStyles}
className={cx('table-cell table-text-align-left td', {
className={cx('table-cell td', {
'table-text-align-center': cell.column.columnDef?.meta?.horizontalAlignment === 'center',
'table-text-align-right': cell.column.columnDef?.meta?.horizontalAlignment === 'right',
'table-text-align-left': cell.column.columnDef?.meta?.horizontalAlignment === 'left',
'wrap-wrapper': contentWrap,
'has-text': cell.column.columnDef?.meta?.columnType === 'text' || isEditable,
'has-datepicker': cell.column.columnDef?.meta?.columnType === 'datepicker',
'has-number': cell.column.columnDef?.meta?.columnType === 'number',
'has-badge': ['badge', 'badges'].includes(cell.column.columnDef?.meta?.columnType),
[cellHeight]: true,

View file

@ -16,7 +16,7 @@ export const TableExposedVariables = ({
fireEvent,
table,
componentName,
pageIndex,
pageIndex = 1,
lastClickedRow,
}) => {
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]);

View file

@ -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 || [];
},

View file

@ -63,7 +63,7 @@ export const buildTableColumn = (
fireEvent,
tableRef: tableBodyRef,
handleCellValueChange,
searchText: serverSideSearch ? '' : globalFilter,
searchText: globalFilter,
}).filter(Boolean),
...generateActionColumns({

View file

@ -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 }) => (

View file

@ -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 })}
/>
);