diff --git a/app/client/cypress/fixtures/tableV2ColumnOrderDsl.json b/app/client/cypress/fixtures/tableV2ColumnOrderDsl.json new file mode 100644 index 0000000000..af5bb11922 --- /dev/null +++ b/app/client/cypress/fixtures/tableV2ColumnOrderDsl.json @@ -0,0 +1,350 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1224, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 880, + "containerStyle": "none", + "snapRows": 50, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 60, + "minHeight": 510, + "parentColumnSpace": 1, + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "isVisibleDownload": true, + "iconSVG": "/static/media/icon.db8a9cbd2acd22a31ea91cc37ea2a46c.svg", + "topRow": 9, + "isSortable": true, + "type": "TABLE_WIDGET_V2", + "inlineEditingSaveOption": "ROW_LEVEL", + "animateLoading": true, + "dynamicBindingPathList": [ + { + "key": "primaryColumns.task.computedValue" + }, + { + "key": "primaryColumns.status.computedValue" + }, + { + "key": "primaryColumns.action.computedValue" + }, + { + "key": "primaryColumns.action.buttonColor" + }, + { + "key": "primaryColumns.action.borderRadius" + }, + { + "key": "primaryColumns.action.boxShadow" + }, + { + "key": "accentColor" + }, + { + "key": "borderRadius" + }, + { + "key": "boxShadow" + }, + { + "key": "childStylesheet.button.buttonColor" + }, + { + "key": "childStylesheet.button.borderRadius" + }, + { + "key": "childStylesheet.menuButton.menuColor" + }, + { + "key": "childStylesheet.menuButton.borderRadius" + }, + { + "key": "childStylesheet.iconButton.buttonColor" + }, + { + "key": "childStylesheet.iconButton.borderRadius" + }, + { + "key": "childStylesheet.editActions.saveButtonColor" + }, + { + "key": "childStylesheet.editActions.saveBorderRadius" + }, + { + "key": "childStylesheet.editActions.discardButtonColor" + }, + { + "key": "childStylesheet.editActions.discardBorderRadius" + }, + { + "key": "tableData" + }, + { + "key": "primaryColumns.step.computedValue" + } + ], + "leftColumn": 2, + "delimiter": ",", + "defaultSelectedRowIndex": 0, + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "isVisibleFilters": true, + "isVisible": true, + "enableClientSideSearch": true, + "version": 1, + "totalRecordsCount": 0, + "isLoading": false, + "childStylesheet": { + "button": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "menuButton": { + "menuColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "iconButton": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "editActions": { + "saveButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "saveBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "discardButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "discardBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + } + }, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "defaultSelectedRowIndices": [ + 0 + ], + "widgetName": "Table1", + "defaultPageSize": 0, + "columnOrder": [ + "step", + "task", + "status", + "action" + ], + "dynamicPropertyPathList": [], + "displayName": "Table", + "bottomRow": 36, + "columnWidthMap": { + "task": 245, + "step": 62, + "status": 75 + }, + "parentRowSpace": 10, + "hideCard": false, + "parentColumnSpace": 20.0625, + "dynamicTriggerPathList": [], + "primaryColumns": { + "task": { + "index": 1, + "width": 150, + "id": "task", + "originalId": "task", + "alias": "task", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isCellVisible": true, + "isCellEditable": false, + "isDerived": false, + "label": "task", + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"task\"]))}}", + "labelColor": "#FFFFFF" + }, + "status": { + "index": 2, + "width": 150, + "id": "status", + "originalId": "status", + "alias": "status", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isCellVisible": true, + "isCellEditable": false, + "isDerived": false, + "label": "status", + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"status\"]))}}", + "labelColor": "#FFFFFF" + }, + "action": { + "index": 3, + "width": 150, + "id": "action", + "originalId": "action", + "alias": "action", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "button", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isCellVisible": true, + "isCellEditable": false, + "isDisabled": false, + "isDerived": false, + "label": "action", + "onClick": "{{currentRow.step === '#1' ? showAlert('Done', 'success') : currentRow.step === '#2' ? navigateTo('https://docs.appsmith.com/core-concepts/connecting-to-data-sources/querying-a-database',undefined,'NEW_WINDOW') : navigateTo('https://docs.appsmith.com/core-concepts/displaying-data-read/display-data-tables',undefined,'NEW_WINDOW')}}", + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"action\"]))}}", + "labelColor": "#FFFFFF", + "buttonColor": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( appsmith.theme.colors.primaryColor))}}", + "borderRadius": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( appsmith.theme.borderRadius.appBorderRadius))}}", + "boxShadow": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( 'none'))}}" + }, + "step": { + "allowCellWrapping": false, + "index": 3, + "width": 150, + "originalId": "step", + "id": "step", + "alias": "step", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textColor": "", + "textSize": "0.875rem", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "step", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"step\"]))}}", + "cellBackground": "" + } + }, + "key": "j70d0qu7x0", + "isDeprecated": false, + "rightColumn": 35, + "textSize": "0.875rem", + "widgetId": "4tgdbe3685", + "tableData": "{{Switch1.isSwitchedOn ? [\n {\n \"step\": \"#1\",\n \"task\": \"Drop a table\",\n \"status\": \"✅\",\n \"action\": \"\"\n },\n {\n \"step\": \"#2\",\n \"task\": \"Create a query fetch_users with the Mock DB\",\n \"status\": \"--\",\n \"action\": \"\"\n },\n {\n \"step\": \"#3\",\n \"task\": \"Bind the query using => fetch_users.data\",\n \"status\": \"--\",\n \"action\": \"\"\n }\n] : [\n {\n \"step1\": \"#1\",\n \"task\": \"Drop a table\",\n \"status\": \"✅\",\n \"action\": \"\"\n },\n {\n \"step1\": \"#2\",\n \"task\": \"Create a query fetch_users with the Mock DB\",\n \"status\": \"--\",\n \"action\": \"\"\n },\n {\n \"step1\": \"#3\",\n \"task\": \"Bind the query using => fetch_users.data\",\n \"status\": \"--\",\n \"action\": \"\"\n }\n]}}", + "label": "Data", + "searchKey": "", + "parentId": "0", + "renderMode": "CANVAS", + "horizontalAlignment": "LEFT", + "isVisibleSearch": true, + "isVisiblePagination": true, + "verticalAlignment": "CENTER" + }, + { + "widgetName": "Text1", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b523e6f70ba6f40a10fc2c7c5b5.svg", + "searchTags": [ + "typography", + "paragraph", + "label" + ], + "topRow": 38, + "bottomRow": 44, + "parentRowSpace": 10, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "overflow": "NONE", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "parentColumnSpace": 20.0625, + "dynamicTriggerPathList": [], + "leftColumn": 2, + "dynamicBindingPathList": [ + { + "key": "fontFamily" + }, + { + "key": "borderRadius" + }, + { + "key": "text" + } + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "Column Order: {{Table1.columnOrder}}", + "key": "hclfcyn1f0", + "isDeprecated": false, + "rightColumn": 19, + "textAlign": "LEFT", + "widgetId": "squfkrflux", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "fontSize": "1rem" + }, + { + "boxShadow": "none", + "widgetName": "Switch1", + "displayName": "Switch", + "iconSVG": "/static/media/icon.a3115bc1c224776de2846985c8819f99.svg", + "searchTags": [ + "boolean" + ], + "topRow": 2, + "bottomRow": 6, + "parentRowSpace": 10, + "type": "SWITCH_WIDGET", + "alignWidget": "LEFT", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 20.0625, + "dynamicTriggerPathList": [], + "leftColumn": 2, + "dynamicBindingPathList": [ + { + "key": "accentColor" + } + ], + "labelPosition": "Left", + "isDisabled": false, + "key": "27mlin8jhk", + "isDeprecated": false, + "rightColumn": 20, + "widgetId": "drf5gxiufp", + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "isVisible": true, + "label": "Change one table column name", + "defaultSwitchState": true, + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/TableV2_Column_Order_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/TableV2_Column_Order_spec.js new file mode 100644 index 0000000000..d82c4ff4ef --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/TableV2_Column_Order_spec.js @@ -0,0 +1,34 @@ +const commonlocators = require("../../../../../locators/commonlocators.json"); +const dsl = require("../../../../../fixtures/tableV2ColumnOrderDsl.json"); +const widgetsPage = require("../../../../../locators/Widgets.json"); + +describe("Table Widget V2 column order maintained on column change validation", function() { + before(() => { + cy.addDsl(dsl); + }); + + it("Table widget V2 column order should be maintained after reorder and new column should be at the end", function() { + const thirdColumnSelector = `${commonlocators.TableV2Head} .tr div:nth-child(3)`; + const secondColumnSelector = `${commonlocators.TableV2Head} .tr div:nth-child(2) .draggable-header`; + + cy.get(thirdColumnSelector).trigger("dragstart"); + cy.get(secondColumnSelector).trigger("drop"); + cy.get(commonlocators.switchWidgetActive).click({ force: true }); + cy.get(commonlocators.textWidgetContainer).each((item, index, list) => { + cy.wrap(item).should( + "contain.text", + `Column Order: [\\"status\\",\\"task\\",\\"action\\",\\"step1\\"]`, + ); + }); + cy.wait(2000); + cy.get(thirdColumnSelector).trigger("dragstart"); + cy.get(secondColumnSelector).trigger("drop"); + cy.get(commonlocators.switchWidgetInActive).click({ force: true }); + cy.get(commonlocators.textWidgetContainer).each((item, index, list) => { + cy.wrap(item).should( + "contain.text", + `Column Order: [\\"status\\",\\"action\\",\\"task\\",\\"step\\"]`, + ); + }); + }); +}); diff --git a/app/client/cypress/locators/commonlocators.json b/app/client/cypress/locators/commonlocators.json index f477258e47..966125224d 100644 --- a/app/client/cypress/locators/commonlocators.json +++ b/app/client/cypress/locators/commonlocators.json @@ -42,6 +42,7 @@ "onDateSelectedField": ".t--property-control-ondateselected", "TableRow": ".t--draggable-tablewidget .tbody", "TableV2Row": ".t--draggable-tablewidgetv2 .tbody", + "TableV2Head": ".t--draggable-tablewidgetv2 .thead", "Disablejs": ".t--property-control-disabled", "spellCheck": ".t--property-control-spellcheck", "requiredjs": ".t--property-control-required", diff --git a/app/client/src/widgets/TableWidgetV2/widget/index.tsx b/app/client/src/widgets/TableWidgetV2/widget/index.tsx index 69aa541560..784d5dc100 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/index.tsx +++ b/app/client/src/widgets/TableWidgetV2/widget/index.tsx @@ -450,7 +450,10 @@ class TableWidgetV2 extends BaseWidget { !!_.xor(newColumnIds, columnOrder).length && !_.isEqual(_.sortBy(newColumnIds), _.sortBy(existingDerivedColumnIds)) ) { - propertiesToAdd["columnOrder"] = Object.keys(tableColumns); + // Maintain original columnOrder and keep new columns at the end + let newColumnOrder = _.intersection(columnOrder, newColumnIds); + newColumnOrder = _.union(newColumnOrder, newColumnIds); + propertiesToAdd["columnOrder"] = newColumnOrder; } const propertiesToUpdate: BatchPropertyUpdatePayload = {