fix: updates the logic to not interfere with DSL when infinitescroll is enabled (#41217)

## Description

TLDR:
Refines TableWidgetV2 cell editability logic to disable editing when
infinite scroll is enabled.

<ins>Problem</ins>

When people toggled infinite scroll of ON and then moved it back to ON,
we were forcibly enabling editing for all columns which was wrong
product behavior.

<ins>Root cause</ins>

The utilities were putting the additables to true in DSL.
And editability logic missed a check for the infinite scroll setting,
causing cells to remain editable even when infinite scroll was active.

<ins>Solution</ins>

This PR handles the integration of infinite scroll support into
TableWidgetV2 by updating header and cell components to respect the
infiniteScrollEnabled prop. Editability is now disabled when infinite
scroll is active, ensuring consistent and predictable user experience.

Fixes #`Issue Number`  
_or_  
Fixes https://github.com/appsmithorg/appsmith-ee/issues/8144
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.Table"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/17998257804>
> Commit: 4d0ff9c41d97c55a94a3d261b962faef492f453a
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=17998257804&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Table`
> Spec:
> <hr>Thu, 25 Sep 2025 06:15:12 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Laveena Enid <laveena@appsmith.com>
Co-authored-by: Aparna Ramachandran <101863839+btsgh@users.noreply.github.com>
Co-authored-by: Abhijeet <41686026+abhvsn@users.noreply.github.com>
Co-authored-by: yatinappsmith <84702014+yatinappsmith@users.noreply.github.com>
Co-authored-by: Nidhi <nidhi@appsmith.com>
Co-authored-by: Shrikant Sharat Kandula <shrikant@appsmith.com>
Co-authored-by: “sneha122” <“sneha@appsmith.com”>
Co-authored-by: Nidhi <nidhi.nair93@gmail.com>
Co-authored-by: Ankita Kinger <ankita@appsmith.com>
Co-authored-by: Rudraprasad Das <rudra@appsmith.com>
Co-authored-by: Trisha Anand <trisha@appsmith.com>
Co-authored-by: Trisha Anand <trisha1990@gmail.com>
Co-authored-by: Arpit Mohan <mohanarpit@users.noreply.github.com>
Co-authored-by: Hetu Nandu <hetu@appsmith.com>
Co-authored-by: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com>
Co-authored-by: Albin <albin@appsmith.com>
Co-authored-by: Manish Kumar <107841575+sondermanish@users.noreply.github.com>
Co-authored-by: Pawan Kumar <pawan@appsmith.com>
Co-authored-by: Apeksha Bhosale <7846888+ApekshaBhosale@users.noreply.github.com>
Co-authored-by: Diljit <diljit@appsmith.com>
Co-authored-by: jacquesikot <jacquesikot@gmail.com>
Co-authored-by: Goutham Pratapa <goutham@appsmith.com>
Co-authored-by: Wyatt Walter <wyattwalter@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Laveena Enid <109572422+laveena-en@users.noreply.github.com>
Co-authored-by: Abhinav Jha <abhinav@appsmith.com>
This commit is contained in:
Rahul Barwal 2025-09-25 16:01:59 +05:30 committed by GitHub
parent 49dfbd2339
commit b79b160d2f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 28 additions and 143 deletions

View File

@ -200,7 +200,10 @@ const HeaderCellComponent = (props: HeaderProps) => {
const isColumnEditable = const isColumnEditable =
props.column.columnProperties.isCellEditable && props.column.columnProperties.isCellEditable &&
props.column.columnProperties.isEditable && props.column.columnProperties.isEditable &&
isColumnTypeEditable(props.column.columnProperties.columnType); isColumnTypeEditable(
props.column.columnProperties.columnType,
isInfiniteScrollEnabled,
);
const toggleColumnFreeze = (value: StickyType) => { const toggleColumnFreeze = (value: StickyType) => {
handleColumnFreeze && handleColumnFreeze &&

View File

@ -10,7 +10,6 @@ import {
updateCustomColumnAliasOnLabelChange, updateCustomColumnAliasOnLabelChange,
selectColumnOptionsValidation, selectColumnOptionsValidation,
allowedFirstDayOfWeekRange, allowedFirstDayOfWeekRange,
updateCellEditabilityOnInfiniteScrollChange,
updateSearchSortFilterOnInfiniteScrollChange, updateSearchSortFilterOnInfiniteScrollChange,
} from "../propertyUtils"; } from "../propertyUtils";
import _ from "lodash"; import _ from "lodash";
@ -1151,96 +1150,4 @@ describe("Infinite Scroll Update Hooks - ", () => {
), ),
).toBeUndefined(); ).toBeUndefined();
}); });
it("updateCellEditabilityOnInfiniteScrollChange - should disable cell editability when infinite scroll is enabled", () => {
// Setup mock primary columns
const props = {
primaryColumns: {
column1: {
id: "column1",
alias: "column1",
isEditable: true,
isCellEditable: true,
},
column2: {
id: "column2",
alias: "column2",
isEditable: true,
isCellEditable: true,
},
},
} as unknown as TableWidgetProps;
// When infinite scroll is enabled
expect(
updateCellEditabilityOnInfiniteScrollChange(
props,
"infiniteScrollEnabled",
true,
),
).toEqual([
{
propertyPath: "primaryColumns.column1.isCellEditable",
propertyValue: false,
},
{
propertyPath: "primaryColumns.column1.isEditable",
propertyValue: false,
},
{
propertyPath: "primaryColumns.column2.isCellEditable",
propertyValue: false,
},
{
propertyPath: "primaryColumns.column2.isEditable",
propertyValue: false,
},
]);
// When infinite scroll is disabled
expect(
updateCellEditabilityOnInfiniteScrollChange(
props,
"infiniteScrollEnabled",
false,
),
).toEqual([
{
propertyPath: "primaryColumns.column1.isCellEditable",
propertyValue: true,
},
{
propertyPath: "primaryColumns.column1.isEditable",
propertyValue: true,
},
{
propertyPath: "primaryColumns.column2.isCellEditable",
propertyValue: true,
},
{
propertyPath: "primaryColumns.column2.isEditable",
propertyValue: true,
},
]);
// Test with no primary columns
const propsWithoutColumns = {} as TableWidgetProps;
expect(
updateCellEditabilityOnInfiniteScrollChange(
propsWithoutColumns,
"infiniteScrollEnabled",
true,
),
).toBeUndefined();
// When some other value is passed
expect(
updateCellEditabilityOnInfiniteScrollChange(
props,
"infiniteScrollEnabled",
"some-other-value",
),
).toBeUndefined();
});
}); });

View File

@ -580,6 +580,7 @@ class TableWidgetV2 extends BaseWidget<TableWidgetProps, WidgetState> {
getTableColumns = () => { getTableColumns = () => {
const { const {
columnWidthMap, columnWidthMap,
infiniteScrollEnabled,
isPreviewMode, isPreviewMode,
orderedTableColumns, orderedTableColumns,
renderMode, renderMode,
@ -597,6 +598,7 @@ class TableWidgetV2 extends BaseWidget<TableWidgetProps, WidgetState> {
componentWidth, componentWidth,
renderMode, renderMode,
isPreviewMode, isPreviewMode,
infiniteScrollEnabled,
); );
}; };
@ -2067,7 +2069,8 @@ class TableWidgetV2 extends BaseWidget<TableWidgetProps, WidgetState> {
} }
const isColumnEditable = const isColumnEditable =
column.isEditable && isColumnTypeEditable(column.columnType); column.isEditable &&
isColumnTypeEditable(column.columnType, this.props.infiniteScrollEnabled);
const alias = props.cell.column.columnProperties.alias; const alias = props.cell.column.columnProperties.alias;
const isCellEditable = isColumnEditable && cellProperties.isCellEditable; const isCellEditable = isColumnEditable && cellProperties.isCellEditable;

View File

@ -137,7 +137,10 @@ export default {
const columnType = get(props, `${baseProperty}.columnType`, ""); const columnType = get(props, `${baseProperty}.columnType`, "");
const isDerived = get(props, `${baseProperty}.isDerived`, false); const isDerived = get(props, `${baseProperty}.isDerived`, false);
return !isColumnTypeEditable(columnType) || isDerived; return (
!isColumnTypeEditable(columnType, props.infiniteScrollEnabled) ||
isDerived
);
}, },
}, },
{ {

View File

@ -22,7 +22,6 @@ import {
totalRecordsCountValidation, totalRecordsCountValidation,
uniqueColumnNameValidation, uniqueColumnNameValidation,
updateAllowAddNewRowOnInfiniteScrollChange, updateAllowAddNewRowOnInfiniteScrollChange,
updateCellEditabilityOnInfiniteScrollChange,
updateColumnOrderHook, updateColumnOrderHook,
updateCustomColumnAliasOnLabelChange, updateCustomColumnAliasOnLabelChange,
updateInlineEditingOptionDropdownVisibilityHook, updateInlineEditingOptionDropdownVisibilityHook,
@ -197,7 +196,6 @@ export default [
isTriggerProperty: false, isTriggerProperty: false,
updateHook: composePropertyUpdateHook([ updateHook: composePropertyUpdateHook([
updateAllowAddNewRowOnInfiniteScrollChange, updateAllowAddNewRowOnInfiniteScrollChange,
updateCellEditabilityOnInfiniteScrollChange,
updateSearchSortFilterOnInfiniteScrollChange, updateSearchSortFilterOnInfiniteScrollChange,
]), ]),
dependencies: ["primaryColumns", "serverSidePaginationEnabled"], dependencies: ["primaryColumns", "serverSidePaginationEnabled"],

View File

@ -1513,46 +1513,3 @@ export const updateSearchSortFilterOnInfiniteScrollChange = (
return; return;
}; };
// Disable cell editability when infinite scroll is enabled
export const updateCellEditabilityOnInfiniteScrollChange = (
props: TableWidgetProps,
propertyPath: string,
propertyValue: unknown,
): Array<{ propertyPath: string; propertyValue: unknown }> | undefined => {
if (!props.primaryColumns) return;
const updates: Array<{ propertyPath: string; propertyValue: unknown }> = [];
if (propertyValue === true) {
Object.entries(props.primaryColumns).forEach(([, column]) => {
const columnName = column.alias;
updates.push({
propertyPath: `primaryColumns.${columnName}.isCellEditable`,
propertyValue: false,
});
updates.push({
propertyPath: `primaryColumns.${columnName}.isEditable`,
propertyValue: false,
});
});
} else if (propertyValue === false) {
Object.entries(props.primaryColumns).forEach(([, column]) => {
const columnName = column.alias;
updates.push({
propertyPath: `primaryColumns.${columnName}.isCellEditable`,
propertyValue: true,
});
updates.push({
propertyPath: `primaryColumns.${columnName}.isEditable`,
propertyValue: true,
});
});
}
return updates.length > 0 ? updates : undefined;
};

View File

@ -4,6 +4,7 @@ import { RenderModes } from "constants/WidgetConstants";
import { StickyType } from "../../component/Constants"; import { StickyType } from "../../component/Constants";
import { import {
COLUMN_MIN_WIDTH, COLUMN_MIN_WIDTH,
ColumnTypes,
DEFAULT_COLUMN_WIDTH, DEFAULT_COLUMN_WIDTH,
DEFAULT_COLUMN_NAME, DEFAULT_COLUMN_NAME,
} from "../../constants"; } from "../../constants";
@ -21,6 +22,7 @@ export type getColumns = (
componentWidth: number, componentWidth: number,
renderMode: RenderMode, renderMode: RenderMode,
isPreviewMode: boolean, isPreviewMode: boolean,
infiniteScrollEnabled?: boolean,
) => ReactTableColumnProps[]; ) => ReactTableColumnProps[];
//TODO: (Vamsi) need to unit test this function //TODO: (Vamsi) need to unit test this function
@ -32,6 +34,7 @@ export const getColumnsPureFn: getColumns = (
componentWidth, componentWidth,
renderMode, renderMode,
isPreviewMode, isPreviewMode,
infiniteScrollEnabled = false,
) => { ) => {
let columns: ReactTableColumnProps[] = []; let columns: ReactTableColumnProps[] = [];
const hiddenColumns: ReactTableColumnProps[] = []; const hiddenColumns: ReactTableColumnProps[] = [];
@ -42,6 +45,14 @@ export const getColumnsPureFn: getColumns = (
// TODO: Fix this the next time the file is edited // TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
orderedTableColumns.forEach((column: any) => { orderedTableColumns.forEach((column: any) => {
// Skip EDIT_ACTIONS columns when infinite scroll is enabled
if (
infiniteScrollEnabled &&
column.columnType === ColumnTypes.EDIT_ACTIONS
) {
return;
}
const isHidden = !column.isVisible; const isHidden = !column.isVisible;
const columnData = { const columnData = {

View File

@ -540,8 +540,11 @@ const EdtiableColumnTypes: string[] = [
ColumnTypes.CURRENCY, ColumnTypes.CURRENCY,
]; ];
export function isColumnTypeEditable(columnType: string) { export function isColumnTypeEditable(
return EdtiableColumnTypes.includes(columnType); columnType: string,
isInfiniteScrollEnabled = false,
) {
return EdtiableColumnTypes.includes(columnType) && !isInfiniteScrollEnabled;
} }
/* /*