From 6c8d4a9a663461c12b1c182464c14847c18109a6 Mon Sep 17 00:00:00 2001 From: Rahul Barwal Date: Tue, 20 Aug 2024 13:31:45 +0530 Subject: [PATCH 1/7] fix: Fixes currentRow calculation logic in table(property pane) (#35390) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Problem `currentRow` variable which is availabe in property pane of col settings - is not getting correct value during runtime if the table is sorted or filtered. Root cause * We are considering `processedTableData` to get the `currentRow`. * This property is not updated during filtering and sorting, another property `filteredTableData` is updated instead. * We CANNOT use `filteredTableData` as it depends on `primaryColumns` property which we intend to update as well - this is leading to cyclic dependency during evaluations. Solution Since the problem is related to edit cases and given the constraints around using `filteredTableData` directly, we fixed the problem by adding a new property to `editableCellValue` object called `__originalIndex__`. * This property stores the index of the row being edited in `processedTableData` * On top of this change, the PR adds a migration for updating the current row binding in TableWidgetV2, ensuring accurate current row calculation and improving the functionality of the widget. * We also added unit test for migration changes. * Additionally, This pull request refactors the DSLs for TableWidgetV2 migration test cases to update the DSLs to separate folder, drastically reducing the file size to its core logic, improving the readability of the code. * We also updated relevant test cases to account for this change. [Testing plan](https://www.notion.so/appsmith/Issue-34346-currentRow-doesn-t-work-correctly-when-the-table-is-filtered-449225ae822c485493036599c2b19487) [Counter part EE pr](https://github.com/appsmithorg/appsmith-ee/pull/4879) Fixes #34346 _or_ Fixes `Issue URL` > [!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.All" ### :mag: Cypress test results > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: d1d65c6898c223bf3f6dfbfe93b8e8de214fcc7d > Cypress dashboard. > Tags: `@tag.All` > Spec: >
Mon, 19 Aug 2024 11:15:04 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [x] Yes - [ ] No ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - Updated DSL migration process to support version 90, enhancing compatibility and robustness. - Introduced new migration logic for table widget data bindings, improving inline editing capabilities. - Enhanced validation logic for editable cells in table widgets, allowing for more dynamic data handling. - Added a method to discard edits in specific table cells, improving user interaction. - Introduced a new message constant for required fields, enhancing user feedback. - **Bug Fixes** - Improved validation checks for table cells based on updated indices and values. - **Tests** - Added comprehensive tests to validate migration functions related to Table Widget, ensuring all aspects function correctly post-update. - Enhanced test specifications for improved validation logic and coverage in table widget functionalities. --------- Co-authored-by: sneha122 --- .../TableV2/TableV2_PropertyPane_2_spec.js | 144 +- .../fixtures/tableV2NewDslWithPagination.json | 6 +- app/client/cypress/support/Pages/Table.ts | 12 + app/client/packages/dsl/src/migrate/index.ts | 8 +- ...rage-table-widget-v2-currentRow-binding.ts | 192 ++ .../src/migrate/tests/DSLMigration.test.ts | 10 + .../dsl/src/migrate/tests/TableWidget.test.ts | 2828 ----------------- .../DSLs/CurrenRowInValidationsBindingDSLs.ts | 140 + .../DSLs/IsColumnEditableCellValidDSLs.ts | 84 + .../DSLs/ParentRowSpaceUpdateDSLs.ts | 274 ++ .../DSLs/PropertyPaneUpgradeDSLs.ts | 625 ++++ .../DSLs/SelectedRowBindingsDSLs.ts | 341 ++ .../TableWidgetV2/DSLs/TableDataJSModeDSLs.ts | 96 + .../DSLs/TableSanitizeColumnKeysDSLs.ts | 453 +++ .../DSLs/TableV2SelectOptionDSLs.ts | 48 + .../DSLs/UpdateHeaderOptionsDSLs.ts | 279 ++ .../tests/TableWidgetV2/TableWidget.test.ts | 131 + app/client/src/ce/constants/messages.ts | 2 + .../TableInlineEditValidPropertyControl.tsx | 2 +- .../TableInlineEditValidationControl.tsx | 2 +- .../src/widgets/TableWidgetV2/constants.ts | 4 +- .../widgets/TableWidgetV2/widget/index.tsx | 1 + 22 files changed, 2801 insertions(+), 2881 deletions(-) create mode 100644 app/client/packages/dsl/src/migrate/migrations/089-migrage-table-widget-v2-currentRow-binding.ts delete mode 100644 app/client/packages/dsl/src/migrate/tests/TableWidget.test.ts create mode 100644 app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/CurrenRowInValidationsBindingDSLs.ts create mode 100644 app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/IsColumnEditableCellValidDSLs.ts create mode 100644 app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/ParentRowSpaceUpdateDSLs.ts create mode 100644 app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/PropertyPaneUpgradeDSLs.ts create mode 100644 app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/SelectedRowBindingsDSLs.ts create mode 100644 app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/TableDataJSModeDSLs.ts create mode 100644 app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/TableSanitizeColumnKeysDSLs.ts create mode 100644 app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/TableV2SelectOptionDSLs.ts create mode 100644 app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/UpdateHeaderOptionsDSLs.ts create mode 100644 app/client/packages/dsl/src/migrate/tests/TableWidgetV2/TableWidget.test.ts diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/TableV2_PropertyPane_2_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/TableV2_PropertyPane_2_spec.js index 45ad94e47ba6..0c73fae21be2 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/TableV2_PropertyPane_2_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/TableV2_PropertyPane_2_spec.js @@ -1,11 +1,10 @@ import { - entityExplorer, - table, - propPane, agHelper, deployMode, draggableWidgets, locators, + propPane, + table, } from "../../../../../support/Objects/ObjectsCore"; const widgetsPage = require("../../../../../locators/Widgets.json"); @@ -114,6 +113,11 @@ describe( it("4. It provides currentRow and currentIndex properties in min validation field", function () { agHelper.AddDsl("tableV2NewDslWithPagination"); cy.openPropertyPane("tablewidgetv2"); + // To make sorting more predictable making `id` column type Number. + table.toggleColumnEditableViaColSettingsPane("id", "v2", true, false); + cy.changeColumnType("Number"); + + propPane.NavigateBackToPropertyPane(); table.toggleColumnEditableViaColSettingsPane( "orderAmount", "v2", @@ -124,17 +128,18 @@ describe( propPane.UpdatePropertyFieldValue("Computed value", "{{currentIndex}}"); cy.changeColumnType("Number"); + // #region Min propPane.UpdatePropertyFieldValue("Min", "{{currentIndex}}"); cy.get(".t--evaluatedPopup-error").should("not.exist"); // Update cell with row : 1, column : orderAmount table.EditTableCell(1, 4, -1, false); - cy.get(".bp3-popover-content").contains("Invalid input"); + cy.get(locators._popoverToolTip).contains("Invalid input"); table.UpdateTableCell(1, 4, 0); - cy.get(".bp3-popover-content").contains("Invalid input"); + cy.get(locators._popoverToolTip).contains("Invalid input"); table.UpdateTableCell(1, 4, 3); - cy.get(".bp3-popover-content").should("not.exist"); + cy.get(locators._popoverToolTip).should("not.exist"); // Check if currentRow works propPane.NavigateBackToPropertyPane(); @@ -148,25 +153,39 @@ describe( // Update cell with row : 0, column : orderAmount. The min is set to 7 (i.e value of cell in id column) table.EditTableCell(1, 4, 8, false); - cy.get(".bp3-popover-content").should("not.exist"); + cy.get(locators._popoverToolTip).should("not.exist"); - table.UpdateTableCell(1, 4, 6); - cy.get(".bp3-popover-content").contains("Row at index 1 is not valid"); + table.UpdateTableCell(1, 4, -1); + cy.get(locators._popoverToolTip).contains("Row at index 1 is not valid"); table.UpdateTableCell(1, 4, 8); - cy.get(".bp3-popover-content").should("not.exist"); + cy.get(locators._popoverToolTip).should("not.exist"); propPane.UpdatePropertyFieldValue( "Error message", "Row with id {{currentRow.id}} is not valid", ); - table.EditTableCell(1, 4, 5, false); - cy.get(".bp3-popover-content").contains("Row with id 7 is not valid"); + table.EditTableCell(1, 4, 1, false); + cy.get(locators._popoverToolTip).contains("Row with id 2 is not valid"); + + cy.discardTableCellValue(4, 1); + table.DiscardEditRow(1, 5); + + // Sort the id column and ensure that `currentRow` is correctly evaluated + table.SortColumn("id", "descending"); + table.EditTableCell(1, 4, 1, false); + cy.get(locators._popoverToolTip).contains("Row with id 24 is not valid"); + + cy.discardTableCellValue(4, 1); + table.SortColumn("id", "ascending"); propPane.UpdatePropertyFieldValue("Min", ""); propPane.UpdatePropertyFieldValue("Error message", ""); + // #endregion Min + + // #region Regex // Check for currentIndex property on Regex field cy.changeColumnType("Plain text"); propPane.UpdatePropertyFieldValue("Regex", "{{currentIndex}}2"); @@ -174,68 +193,101 @@ describe( cy.get(".t--evaluatedPopup-error").should("not.exist"); table.EditTableCell(1, 4, 3, false); - cy.get(".bp3-popover-content").contains("Invalid input"); + cy.get(locators._popoverToolTip).contains("Invalid input"); table.UpdateTableCell(1, 4, 12); - cy.get(".bp3-popover-content").should("not.exist"); + cy.get(locators._popoverToolTip).should("not.exist"); // Check for currentRow property on Regex field propPane.UpdatePropertyFieldValue("Regex", "{{currentRow.id}}"); - table.EditTableCell(1, 4, 7, false); - cy.get(".bp3-popover-content").should("not.exist"); + table.EditTableCell(1, 4, 20, false); + cy.get(locators._popoverToolTip).should("not.exist"); table.UpdateTableCell(1, 4, 8); - cy.get(".bp3-popover-content").contains("Invalid input"); - table.UpdateTableCell(1, 4, 7); - cy.get(".bp3-popover-content").should("not.exist"); + cy.get(locators._popoverToolTip).contains("Invalid input"); + table.UpdateTableCell(1, 4, 20); + cy.get(locators._popoverToolTip).should("not.exist"); + + cy.discardTableCellValue(4, 1); + table.DiscardEditRow(1, 5); + + // Sort the id column and ensure that `currentRow` is correctly evaluated + table.SortColumn("id", "descending"); + + table.EditTableCell(1, 4, 10, false); + cy.get(locators._popoverToolTip).contains("Invalid input"); + + table.UpdateTableCell(1, 4, 24); + cy.get(locators._popoverToolTip).should("not.exist"); + propPane.UpdatePropertyFieldValue("Regex", ""); + table.DiscardEditRow(1, 5); + table.SortColumn("id", "ascending"); + + // #endregion Regex + + // #region Required propPane.EnterJSContext("Required", "{{currentIndex == 1}}"); table.EditTableCell(1, 4, "", false); - cy.get(".bp3-popover-content").contains("This field is required"); + cy.get(locators._popoverToolTip).contains( + Cypress.env("MESSAGES").FIELD_REQUIRED_MESSAGE(), + ); table.UpdateTableCell(1, 4, 1, true); - cy.get(".bp3-popover-content").should("not.exist"); - - cy.wait(1500); - cy.discardTableRow(5, 1); - cy.wait(1500); + cy.get(locators._popoverToolTip).should("not.exist"); // Value isn't required in Row Index 2 table.EditTableCell(2, 4, "", false); - cy.get(".bp3-popover-content").should("not.exist"); + cy.get(locators._popoverToolTip).should("not.exist"); table.UpdateTableCell(2, 4, "11"); - cy.get(".bp3-popover-content").should("not.exist"); + cy.get(locators._popoverToolTip).should("not.exist"); table.UpdateTableCell(2, 4, "", true); - cy.get(".bp3-popover-content").should("not.exist"); - - cy.wait(1500); - cy.discardTableRow(5, 2); + cy.get(locators._popoverToolTip).should("not.exist"); - // Check for Required property using currentRow, row with index 1 has id 7 - propPane.UpdatePropertyFieldValue("Required", "{{currentRow.id == 7}}"); + table.DiscardEditRow(2, 5); + // Check for Required property using currentRow, row with index 1 has id 2 + propPane.UpdatePropertyFieldValue("Required", "{{currentRow.id == 2}}"); table.EditTableCell(1, 4, "", false); - cy.get(".bp3-popover-content").contains("This field is required"); + cy.get(locators._popoverToolTip).contains( + Cypress.env("MESSAGES").FIELD_REQUIRED_MESSAGE(), + ); table.UpdateTableCell(1, 4, 1); - cy.get(".bp3-popover-content").should("not.exist"); + cy.get(locators._popoverToolTip).should("not.exist"); table.UpdateTableCell(1, 4, ""); - cy.get(".bp3-popover-content").contains("This field is required"); + cy.get(locators._popoverToolTip).contains( + Cypress.env("MESSAGES").FIELD_REQUIRED_MESSAGE(), + ); table.UpdateTableCell(1, 4, "1", true); - cy.get(".bp3-popover-content").should("not.exist"); - - cy.wait(1500); - cy.discardTableRow(5, 1); - cy.wait(1500); + cy.get(locators._popoverToolTip).should("not.exist"); // Value isn't required in Row Index 2 table.EditTableCell(2, 4, "", false); - cy.get(".bp3-popover-content").should("not.exist"); + cy.get(locators._popoverToolTip).should("not.exist"); table.UpdateTableCell(2, 4, 10); - cy.get(".bp3-popover-content").should("not.exist"); + cy.get(locators._popoverToolTip).should("not.exist"); table.UpdateTableCell(2, 4, "", true); - cy.get(".bp3-popover-content").should("not.exist"); + cy.get(locators._popoverToolTip).should("not.exist"); + + table.DiscardEditRow(2, 5); + + // Sort the id column and ensure that `currentRow` is correctly evaluated + table.SortColumn("id", "descending"); + table.EditTableCell(1, 4, "", false); + cy.get(locators._popoverToolTip).should("not.exist"); + table.UpdateTableCell(1, 4, 10); + cy.get(locators._popoverToolTip).should("not.exist"); + + propPane.UpdatePropertyFieldValue("Required", "{{currentRow.id == 24}}"); + table.EditTableCell(1, 4, ""); + cy.get(locators._popoverToolTip).contains( + Cypress.env("MESSAGES").FIELD_REQUIRED_MESSAGE(), + ); + + cy.discardTableCellValue(4, 1); + table.DiscardEditRow(1, 5); - cy.wait(1500); - cy.discardTableRow(5, 2); + table.SortColumn("id", "ascending"); + // #endregion Required // Cleanup propPane.UpdatePropertyFieldValue( diff --git a/app/client/cypress/fixtures/tableV2NewDslWithPagination.json b/app/client/cypress/fixtures/tableV2NewDslWithPagination.json index 03c33584df6d..b0c4432e2170 100644 --- a/app/client/cypress/fixtures/tableV2NewDslWithPagination.json +++ b/app/client/cypress/fixtures/tableV2NewDslWithPagination.json @@ -132,7 +132,7 @@ "productName", "orderAmount" ], - "dynamicPropertyPathList": [{"key": "tableData"}], + "dynamicPropertyPathList": [{ "key": "tableData" }], "displayName": "Table", "bottomRow": 132, "columnWidthMap": { @@ -271,7 +271,7 @@ "rightColumn": 50, "textSize": "0.875rem", "widgetId": "8o3mdylmxa", - "tableData": "{{[\n {\n \"id\": 6,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 7,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 2,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 3,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 4,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 2381224,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 2381224,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 2381224,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 2381224,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 2381224,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 2381224,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 2381224,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 2381224,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n },\n {\n \"id\": 2736212,\n \"email\": \"lindsay.ferguson@reqres.in\",\n \"userName\": \"Lindsay Ferguson\",\n \"productName\": \"Tuna Salad\",\n \"orderAmount\": 9.99\n },\n {\n \"id\": 6788734,\n \"email\": \"tobias.funke@reqres.in\",\n \"userName\": \"Tobias Funke\",\n \"productName\": \"Beef steak\",\n \"orderAmount\": 19.99\n },\n {\n \"id\": 7434532,\n \"email\": \"byron.fields@reqres.in\",\n \"userName\": \"Byron Fields\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n },\n {\n \"id\": 7434532,\n \"email\": \"ryan.holmes@reqres.in\",\n \"userName\": \"Ryan Holmes\",\n \"productName\": \"Avocado Panini\",\n \"orderAmount\": 7.99\n },\n\t {\n \"id\": 7434532,\n \"email\": \"byron.fields@reqres.in\",\n \"userName\": \"Byron Fields\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n },\n {\n \"id\": 7434532,\n \"email\": \"ryan.holmes@reqres.in\",\n \"userName\": \"Ryan Holmes\",\n \"productName\": \"Avocado Panini\",\n \"orderAmount\": 7.99\n },\n\t {\n \"id\": 7434532,\n \"email\": \"byron.fields@reqres.in\",\n \"userName\": \"Byron Fields\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n },\n {\n \"id\": 7434532,\n \"email\": \"ryan.holmes@reqres.in\",\n \"userName\": \"Ryan Holmes\",\n \"productName\": \"Avocado Panini\",\n \"orderAmount\": 7.99\n },\n\t {\n \"id\": 7434532,\n \"email\": \"byron.fields@reqres.in\",\n \"userName\": \"Byron Fields\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n },\n {\n \"id\": 7434532,\n \"email\": \"ryan.holmes@reqres.in\",\n \"userName\": \"Ryan Holmes\",\n \"productName\": \"Avocado Panini\",\n \"orderAmount\": 7.99\n },\n\t {\n \"id\": 7434532,\n \"email\": \"byron.fields@reqres.in\",\n \"userName\": \"Byron Fields\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n },\n {\n \"id\": 7434532,\n \"email\": \"ryan.holmes@reqres.in\",\n \"userName\": \"Ryan Holmes\",\n \"productName\": \"Avocado Panini\",\n \"orderAmount\": 7.99\n }\n]}}", + "tableData": "{{[\n {\n \"id\": 1,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 2,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 3,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 4,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 5,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 6,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 7,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 8,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 9,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 10,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 11,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 12,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n }, {\n \"id\": 13,\n \"email\": \"michael.lawson@reqres.in\",\n \"userName\": \"Michael Lawson\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n },\n {\n \"id\": 14,\n \"email\": \"lindsay.ferguson@reqres.in\",\n \"userName\": \"Lindsay Ferguson\",\n \"productName\": \"Tuna Salad\",\n \"orderAmount\": 9.99\n },\n {\n \"id\": 15,\n \"email\": \"tobias.funke@reqres.in\",\n \"userName\": \"Tobias Funke\",\n \"productName\": \"Beef steak\",\n \"orderAmount\": 19.99\n },\n {\n \"id\": 16,\n \"email\": \"byron.fields@reqres.in\",\n \"userName\": \"Byron Fields\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n },\n {\n \"id\": 17,\n \"email\": \"ryan.holmes@reqres.in\",\n \"userName\": \"Ryan Holmes\",\n \"productName\": \"Avocado Panini\",\n \"orderAmount\": 7.99\n },\n {\n \"id\": 18,\n \"email\": \"byron.fields@reqres.in\",\n \"userName\": \"Byron Fields\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n },\n {\n \"id\": 19,\n \"email\": \"ryan.holmes@reqres.in\",\n \"userName\": \"Ryan Holmes\",\n \"productName\": \"Avocado Panini\",\n \"orderAmount\": 7.99\n },\n {\n \"id\": 20,\n \"email\": \"byron.fields@reqres.in\",\n \"userName\": \"Byron Fields\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n },\n {\n \"id\": 21,\n \"email\": \"ryan.holmes@reqres.in\",\n \"userName\": \"Ryan Holmes\",\n \"productName\": \"Avocado Panini\",\n \"orderAmount\": 7.99\n },\n {\n \"id\": 22,\n \"email\": \"byron.fields@reqres.in\",\n \"userName\": \"Byron Fields\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n },\n {\n \"id\": 23,\n \"email\": \"ryan.holmes@reqres.in\",\n \"userName\": \"Ryan Holmes\",\n \"productName\": \"Avocado Panini\",\n \"orderAmount\": 7.99\n },\n {\n \"id\": 24,\n \"email\": \"byron.fields@reqres.in\",\n \"userName\": \"Byron Fields\",\n \"productName\": \"Chicken Sandwich\",\n \"orderAmount\": 4.99\n },\n {\n \"id\": 25,\n \"email\": \"ryan.holmes@reqres.in\",\n \"userName\": \"Ryan Holmes\",\n \"productName\": \"Avocado Panini\",\n \"orderAmount\": 7.99\n }\n]}}", "label": "Data", "searchKey": "", "parentId": "0", @@ -312,4 +312,4 @@ } ] } -} \ No newline at end of file +} diff --git a/app/client/cypress/support/Pages/Table.ts b/app/client/cypress/support/Pages/Table.ts index ad1d723b88f5..c82f7e9a0548 100644 --- a/app/client/cypress/support/Pages/Table.ts +++ b/app/client/cypress/support/Pages/Table.ts @@ -827,4 +827,16 @@ export class Table { .GetText(this._listActivePage(version), "text") .then(($newPageNo) => expect(Number($newPageNo)).to.eq(pageNumber)); } + + public DiscardEditRow(row: number, col: number, verify = true) { + /* + * Why not get it with text `Discard`? + * We've tried using selector: `[data-colindex="${col}"][data-rowindex="${row}"] button span:contains('Discard')` and this dosn't work, making this spec fail. + */ + const selector = `${this._tableRow(row, col, "v2")} button`; + + cy.get(selector).eq(1).should("be.enabled"); + this.agHelper.GetHoverNClick(selector, 1, true); + verify && cy.get(selector).eq(1).should("be.disabled"); + } } diff --git a/app/client/packages/dsl/src/migrate/index.ts b/app/client/packages/dsl/src/migrate/index.ts index cdb810ee7b28..fc4c31a07a9f 100644 --- a/app/client/packages/dsl/src/migrate/index.ts +++ b/app/client/packages/dsl/src/migrate/index.ts @@ -90,9 +90,10 @@ import { migrateDefaultValuesForCustomEChart } from "./migrations/085-migrate-de import { migrateTableServerSideFiltering } from "./migrations/086-migrate-table-server-side-filtering"; import { migrateChartwidgetCustomEchartConfig } from "./migrations/087-migrate-chart-widget-customechartdata"; import { migrateCustomWidgetDynamicHeight } from "./migrations/088-migrate-custom-widget-dynamic-height"; +import { migrateTableWidgetV2CurrentRowInValidationsBinding } from "./migrations/089-migrage-table-widget-v2-currentRow-binding"; import type { DSLWidget } from "./types"; -export const LATEST_DSL_VERSION = 89; +export const LATEST_DSL_VERSION = 90; export const calculateDynamicHeight = () => { const DEFAULT_GRID_ROW_HEIGHT = 10; @@ -592,6 +593,11 @@ const migrateVersionedDSL = (currentDSL: DSLWidget, newPage = false) => { if (currentDSL.version === 88) { currentDSL = migrateCustomWidgetDynamicHeight(currentDSL); + currentDSL.version = 89; + } + + if (currentDSL.version === 89) { + currentDSL = migrateTableWidgetV2CurrentRowInValidationsBinding(currentDSL); currentDSL.version = LATEST_DSL_VERSION; } diff --git a/app/client/packages/dsl/src/migrate/migrations/089-migrage-table-widget-v2-currentRow-binding.ts b/app/client/packages/dsl/src/migrate/migrations/089-migrage-table-widget-v2-currentRow-binding.ts new file mode 100644 index 000000000000..f876814c9930 --- /dev/null +++ b/app/client/packages/dsl/src/migrate/migrations/089-migrage-table-widget-v2-currentRow-binding.ts @@ -0,0 +1,192 @@ +import type { ColumnProperties, DSLWidget, WidgetProps } from "../types"; +import { isDynamicValue, traverseDSLAndMigrate } from "../utils"; + +const ORIGINAL_INDEX_KEY = "__originalIndex__"; +const PRIMARY_COLUMN_KEY_VALUE = "__primaryKey__"; + +const oldBindingSuffixForInlineEditValidationControl = (tableId: string) => { + return ` + )) + ( + ${tableId}.isAddRowInProgress, + ${tableId}.isAddRowInProgress ? -1 : ${tableId}.editableCell.index, + ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.index] || + Object.keys(${tableId}.processedTableData[0]) + .filter(key => ["${ORIGINAL_INDEX_KEY}", "${PRIMARY_COLUMN_KEY_VALUE}"].indexOf(key) === -1) + .reduce((prev, curr) => { + prev[curr] = ""; + return prev; + }, {})) + ) + }} + `; +}; + +const newBindingSuffixForInlineEditValidationControl = (tableId: string) => { + return ` + )) + ( + ${tableId}.isAddRowInProgress, + ${tableId}.isAddRowInProgress ? -1 : ${tableId}.editableCell.index, + ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.${ORIGINAL_INDEX_KEY}] || + Object.keys(${tableId}.processedTableData[0]) + .filter(key => ["${ORIGINAL_INDEX_KEY}", "${PRIMARY_COLUMN_KEY_VALUE}"].indexOf(key) === -1) + .reduce((prev, curr) => { + prev[curr] = ""; + return prev; + }, {})) + ) + }} + `; +}; + +const oldBindingSuffixForInlineEditValidProperty = ( + tableId: string, + columnName: string, +) => { + return ` + )) + ( + (${tableId}.isAddRowInProgress ? ${tableId}.newRow.${columnName} : ${tableId}.columnEditableCellValue.${columnName}) || "", + ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.index] || + Object.keys(${tableId}.processedTableData[0]) + .filter(key => ["${ORIGINAL_INDEX_KEY}", "${PRIMARY_COLUMN_KEY_VALUE}"].indexOf(key) === -1) + .reduce((prev, curr) => { + prev[curr] = ""; + return prev; + }, {})), + ${tableId}.isAddRowInProgress ? -1 : ${tableId}.editableCell.index, + ${tableId}.isAddRowInProgress + ) + }} + `; +}; +const newBindingSuffixForInlineEditValidProperty = ( + tableId: string, + columnName: string, +) => { + return ` + )) + ( + (${tableId}.isAddRowInProgress ? ${tableId}.newRow.${columnName} : ${tableId}.columnEditableCellValue.${columnName}) || "", + ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.${ORIGINAL_INDEX_KEY}] || + Object.keys(${tableId}.processedTableData[0]) + .filter(key => ["${ORIGINAL_INDEX_KEY}", "${PRIMARY_COLUMN_KEY_VALUE}"].indexOf(key) === -1) + .reduce((prev, curr) => { + prev[curr] = ""; + return prev; + }, {})), + ${tableId}.isAddRowInProgress ? -1 : ${tableId}.editableCell.index, + ${tableId}.isAddRowInProgress + ) + }} + `; +}; + +const TABLE_INLINE_EDIT_VALIDATION_CONTROL_PROPERTIES_TO_UPDATE = [ + "regex", + "errorMessage", + "isColumnEditableCellRequired", + "min", + "max", +]; +export const migrateTableWidgetV2CurrentRowInValidationsBinding = ( + currentDSL: DSLWidget, +) => { + return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => { + if (widget.type !== "TABLE_WIDGET_V2") return; + + const primaryColumns: Record = + widget.primaryColumns as Record; + Object.entries(primaryColumns).forEach(([colName, colProperties]) => { + if (!colProperties.validation) return; + + handleInlineEditValidationControl( + widget.widgetName, + colName, + colProperties, + ); + handleInlineEditValidValidationControl( + widget.widgetName, + colName, + colProperties, + ); + }); + }); +}; + +function handleInlineEditValidationControl( + tableName: string, + colName: string, + colProperties: ColumnProperties, +) { + TABLE_INLINE_EDIT_VALIDATION_CONTROL_PROPERTIES_TO_UPDATE.forEach( + (property) => { + updateColProperty(tableName, colName, colProperties, property); + }, + ); +} + +function handleInlineEditValidValidationControl( + tableName: string, + colName: string, + colProperties: ColumnProperties, +) { + updateColProperty( + tableName, + colName, + colProperties, + "isColumnEditableCellValid", + ); +} + +function getBindingPrefixSuffix( + tableName: string, + colName: string, + property: string, + getOldBinding: boolean, +) { + if (getOldBinding) { + if (property === "isColumnEditableCellValid") { + return oldBindingSuffixForInlineEditValidProperty(tableName, colName); + } + return oldBindingSuffixForInlineEditValidationControl(tableName); + } else { + if (property === "isColumnEditableCellValid") { + return newBindingSuffixForInlineEditValidProperty(tableName, colName); + } + return newBindingSuffixForInlineEditValidationControl(tableName); + } +} + +function updateColProperty( + tableName: string, + colName: string, + colProperties: ColumnProperties, + propertyToUpdate: string, +) { + const oldBindingSuffix = getBindingPrefixSuffix( + tableName, + colName, + propertyToUpdate, + true, + ); + const newBindingSuffix = getBindingPrefixSuffix( + tableName, + colName, + propertyToUpdate, + false, + ); + + const isValidationValueDynamic = + propertyToUpdate in colProperties.validation && + colProperties.validation[propertyToUpdate] && + isDynamicValue(colProperties.validation[propertyToUpdate]); + if (!isValidationValueDynamic) return; + + const propertyValue = colProperties.validation[propertyToUpdate]; + colProperties.validation[propertyToUpdate] = propertyValue.replace( + oldBindingSuffix, + newBindingSuffix, + ); +} diff --git a/app/client/packages/dsl/src/migrate/tests/DSLMigration.test.ts b/app/client/packages/dsl/src/migrate/tests/DSLMigration.test.ts index 9a925b68a74f..0a0c39188ff7 100644 --- a/app/client/packages/dsl/src/migrate/tests/DSLMigration.test.ts +++ b/app/client/packages/dsl/src/migrate/tests/DSLMigration.test.ts @@ -89,6 +89,7 @@ import * as m85 from "../migrations/085-migrate-default-values-for-custom-echart import * as m86 from "../migrations/086-migrate-table-server-side-filtering"; import * as m87 from "../migrations/087-migrate-chart-widget-customechartdata"; import * as m88 from "../migrations/088-migrate-custom-widget-dynamic-height"; +import * as m89 from "../migrations/089-migrage-table-widget-v2-currentRow-binding"; interface Migration { functionLookup: { @@ -920,6 +921,15 @@ const migrations: Migration[] = [ ], version: 88, }, + { + functionLookup: [ + { + moduleObj: m89, + functionName: "migrateTableWidgetV2CurrentRowInValidationsBinding", + }, + ], + version: 89, + }, ]; const mockFnObj: Record = {}; diff --git a/app/client/packages/dsl/src/migrate/tests/TableWidget.test.ts b/app/client/packages/dsl/src/migrate/tests/TableWidget.test.ts deleted file mode 100644 index 6a906bd441e5..000000000000 --- a/app/client/packages/dsl/src/migrate/tests/TableWidget.test.ts +++ /dev/null @@ -1,2828 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import type { DSLWidget } from "../types"; -import { tableWidgetPropertyPaneMigrations } from "../migrations/009-table-widget-property-pane-migration"; -import { migrateTableWidgetParentRowSpaceProperty } from "../migrations/022-migrate-table-widget-parent-row-space-property"; -import { migrateTableWidgetHeaderVisibilityProperties } from "../migrations/024-migrate-table-widget-header-visibility-properties"; -import { migrateTableSanitizeColumnKeys } from "../migrations/037-migrate-table-sanitize-column-keys"; -import { migrateTableWidgetSelectedRowBindings } from "../migrations/039-migrate-table-widget-selected-row-bindings"; -import { migrateTableWidgetV2SelectOption } from "../migrations/071-migrate-table-widget-v2-select-option"; -import { migrateTableWidgetV2ValidationBinding } from "../migrations/066-migrate-table-widget-v2-validation-binding"; -import { migrateTableWidgetTableDataJsMode } from "../migrations/079-migrate-table-widget-table-data-js-mode"; - -const input1: DSLWidget = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1224, - snapColumns: 16, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 1840, - containerStyle: "none", - snapRows: 33, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 7, - minHeight: 1292, - parentColumnSpace: 1, - dynamicBindingPathList: [], - leftColumn: 0, - isLoading: false, - parentId: "", - renderMode: "CANVAS", - children: [ - { - isVisible: true, - label: "Data", - widgetName: "Table1", - searchKey: "", - tableData: - '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', - type: "TABLE_WIDGET", - isLoading: false, - parentColumnSpace: 74, - parentRowSpace: 40, - leftColumn: 0, - rightColumn: 8, - topRow: 19, - bottomRow: 26, - parentId: "0", - widgetId: "fs785w9gcy", - dynamicBindingPathList: [], - renderMode: "CANVAS", - version: 1, - }, - ], -}; - -const input2: DSLWidget = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1224, - snapColumns: 16, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 1840, - containerStyle: "none", - snapRows: 33, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 7, - minHeight: 1292, - parentColumnSpace: 1, - dynamicBindingPathList: [], - leftColumn: 0, - isLoading: false, - parentId: "", - renderMode: "CANVAS", - children: [ - { - isVisible: true, - label: "Data", - widgetName: "Table2", - searchKey: "", - tableData: - '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', - type: "TABLE_WIDGET", - isLoading: false, - parentColumnSpace: 74, - parentRowSpace: 40, - leftColumn: 0, - rightColumn: 8, - topRow: 28, - bottomRow: 35, - parentId: "0", - widgetId: "l9i1e8ybkm", - dynamicBindingPathList: [], - dynamicTriggerPathList: [{ key: "columnActions" }], - columnActions: [ - { - label: "Test", - id: "ezooq966rd", - actionPayloads: [], - dynamicTrigger: "{{showAlert('test','success')}}", - }, - { - label: "Fail", - id: "1k8nkay5r6", - actionPayloads: [], - dynamicTrigger: "{{showAlert('Fail','error')}}", - }, - ], - renderMode: "CANVAS", - version: 1, - }, - ], -}; - -const input3: DSLWidget = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1224, - snapColumns: 16, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 1840, - containerStyle: "none", - snapRows: 33, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 7, - minHeight: 1292, - parentColumnSpace: 1, - dynamicBindingPathList: [], - leftColumn: 0, - isLoading: false, - parentId: "", - renderMode: "CANVAS", - children: [ - { - isVisible: true, - label: "Data", - widgetName: "Table3", - searchKey: "", - tableData: - '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', - type: "TABLE_WIDGET", - isLoading: false, - parentColumnSpace: 74, - parentRowSpace: 40, - leftColumn: 0, - rightColumn: 8, - topRow: 37, - bottomRow: 44, - parentId: "0", - widgetId: "8mkidz550s", - dynamicBindingPathList: [], - dynamicTriggerPathList: [ - { key: "onRowSelected" }, - { key: "onSearchTextChanged" }, - ], - onRowSelected: "{{showAlert('test','success')}}", - onSearchTextChanged: "{{showAlert('fail','error')}}", - renderMode: "CANVAS", - version: 1, - }, - ], -}; - -const output1 = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1224, - snapColumns: 16, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 1840, - containerStyle: "none", - snapRows: 33, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 7, - minHeight: 1292, - parentColumnSpace: 1, - dynamicBindingPathList: [], - leftColumn: 0, - isLoading: false, - parentId: "", - renderMode: "CANVAS", - children: [ - { - isVisible: true, - label: "Data", - widgetName: "Table1", - searchKey: "", - tableData: - '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', - type: "TABLE_WIDGET", - isLoading: false, - parentColumnSpace: 74, - parentRowSpace: 40, - leftColumn: 0, - rightColumn: 8, - topRow: 19, - bottomRow: 26, - parentId: "0", - widgetId: "fs785w9gcy", - dynamicBindingPathList: [], - primaryColumns: { - id: { - index: 0, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - computedValue: "", - }, - email: { - index: 1, - width: 150, - id: "email", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "email", - computedValue: "", - }, - userName: { - index: 2, - width: 150, - id: "userName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "userName", - computedValue: "", - }, - productName: { - index: 3, - width: 150, - id: "productName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "productName", - computedValue: "", - }, - orderAmount: { - index: 4, - width: 150, - id: "orderAmount", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "orderAmount", - computedValue: "", - }, - }, - textSize: "PARAGRAPH", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - renderMode: "CANVAS", - version: 1, - }, - ], -}; - -const output2 = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1224, - snapColumns: 16, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 1840, - containerStyle: "none", - snapRows: 33, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 7, - minHeight: 1292, - parentColumnSpace: 1, - dynamicBindingPathList: [], - leftColumn: 0, - isLoading: false, - parentId: "", - renderMode: "CANVAS", - children: [ - { - isVisible: true, - label: "Data", - widgetName: "Table2", - searchKey: "", - tableData: - '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', - type: "TABLE_WIDGET", - isLoading: false, - parentColumnSpace: 74, - parentRowSpace: 40, - leftColumn: 0, - rightColumn: 8, - topRow: 28, - bottomRow: 35, - parentId: "0", - widgetId: "l9i1e8ybkm", - dynamicBindingPathList: [], - dynamicTriggerPathList: [ - { key: "columnActions" }, - { key: "primaryColumns.customColumn1.onClick" }, - { key: "primaryColumns.customColumn2.onClick" }, - ], - columnActions: [ - { - label: "Test", - id: "ezooq966rd", - actionPayloads: [], - dynamicTrigger: "{{showAlert('test','success')}}", - }, - { - label: "Fail", - id: "1k8nkay5r6", - actionPayloads: [], - dynamicTrigger: "{{showAlert('Fail','error')}}", - }, - ], - primaryColumns: { - id: { - index: 0, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - computedValue: "", - }, - email: { - index: 1, - width: 150, - id: "email", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "email", - computedValue: "", - }, - userName: { - index: 2, - width: 150, - id: "userName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "userName", - computedValue: "", - }, - productName: { - index: 3, - width: 150, - id: "productName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "productName", - computedValue: "", - }, - orderAmount: { - index: 4, - width: 150, - id: "orderAmount", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "orderAmount", - computedValue: "", - }, - customColumn1: { - index: 5, - width: 150, - id: "ezooq966rd", - label: "Test", - columnType: "button", - isVisible: true, - isDerived: true, - buttonLabel: "Test", - buttonStyle: "rgb(3, 179, 101)", - buttonLabelColor: "#FFFFFF", - onClick: "{{showAlert('test','success')}}", - }, - customColumn2: { - index: 6, - width: 150, - id: "1k8nkay5r6", - label: "Fail", - columnType: "button", - isVisible: true, - isDerived: true, - buttonLabel: "Fail", - buttonStyle: "rgb(3, 179, 101)", - buttonLabelColor: "#FFFFFF", - onClick: "{{showAlert('Fail','error')}}", - }, - }, - textSize: "PARAGRAPH", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - renderMode: "CANVAS", - version: 1, - }, - ], -}; - -const output3 = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1224, - snapColumns: 16, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 1840, - containerStyle: "none", - snapRows: 33, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 7, - minHeight: 1292, - parentColumnSpace: 1, - dynamicBindingPathList: [], - leftColumn: 0, - isLoading: false, - parentId: "", - renderMode: "CANVAS", - children: [ - { - isVisible: true, - label: "Data", - widgetName: "Table3", - searchKey: "", - tableData: - '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', - type: "TABLE_WIDGET", - isLoading: false, - parentColumnSpace: 74, - parentRowSpace: 40, - leftColumn: 0, - rightColumn: 8, - topRow: 37, - bottomRow: 44, - parentId: "0", - widgetId: "8mkidz550s", - dynamicBindingPathList: [], - dynamicTriggerPathList: [ - { key: "onRowSelected" }, - { key: "onSearchTextChanged" }, - ], - onRowSelected: "{{showAlert('test','success')}}", - onSearchTextChanged: "{{showAlert('fail','error')}}", - primaryColumns: { - id: { - index: 0, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - computedValue: "", - }, - email: { - index: 1, - width: 150, - id: "email", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "email", - computedValue: "", - }, - userName: { - index: 2, - width: 150, - id: "userName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "userName", - computedValue: "", - }, - productName: { - index: 3, - width: 150, - id: "productName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "productName", - computedValue: "", - }, - orderAmount: { - index: 4, - width: 150, - id: "orderAmount", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "orderAmount", - computedValue: "", - }, - }, - textSize: "PARAGRAPH", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - renderMode: "CANVAS", - version: 1, - }, - ], -}; - -describe("Table Widget Property Pane Upgrade", () => { - it("To test primaryColumns are created for a simple table", () => { - const newDsl = tableWidgetPropertyPaneMigrations(input1); - expect(JSON.stringify(newDsl) === JSON.stringify(output1)); - }); - it("To test columnActions are migrated derived primaryColumns", () => { - const newDsl = tableWidgetPropertyPaneMigrations(input2); - expect(JSON.stringify(newDsl) === JSON.stringify(output2)); - }); - it("To test table action are migrated", () => { - const newDsl = tableWidgetPropertyPaneMigrations(input3); - expect(JSON.stringify(newDsl) === JSON.stringify(output3)); - }); - - it("To test table parentRowSpace is updated", () => { - const inputDsl: DSLWidget = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1224, - snapColumns: 16, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 1840, - containerStyle: "none", - snapRows: 33, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 7, - minHeight: 1292, - parentColumnSpace: 1, - dynamicBindingPathList: [], - leftColumn: 0, - isLoading: false, - parentId: "", - renderMode: "CANVAS", - children: [ - { - isVisible: true, - label: "Data", - widgetName: "Table1", - searchKey: "", - tableData: - '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', - type: "TABLE_WIDGET", - isLoading: false, - parentColumnSpace: 74, - parentRowSpace: 40, - leftColumn: 0, - rightColumn: 8, - topRow: 19, - bottomRow: 26, - parentId: "0", - widgetId: "fs785w9gcy", - dynamicBindingPathList: [], - primaryColumns: { - id: { - index: 0, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - computedValue: "", - }, - email: { - index: 1, - width: 150, - id: "email", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "email", - computedValue: "", - }, - userName: { - index: 2, - width: 150, - id: "userName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "userName", - computedValue: "", - }, - productName: { - index: 3, - width: 150, - id: "productName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "productName", - computedValue: "", - }, - orderAmount: { - index: 4, - width: 150, - id: "orderAmount", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "orderAmount", - computedValue: "", - }, - }, - textSize: "PARAGRAPH", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - renderMode: "CANVAS", - version: 1, - }, - ], - }; - const outputDsl: DSLWidget = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1224, - snapColumns: 16, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 1840, - containerStyle: "none", - snapRows: 33, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 7, - minHeight: 1292, - parentColumnSpace: 1, - dynamicBindingPathList: [], - leftColumn: 0, - isLoading: false, - parentId: "", - renderMode: "CANVAS", - children: [ - { - isVisible: true, - label: "Data", - widgetName: "Table1", - searchKey: "", - tableData: - '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', - type: "TABLE_WIDGET", - isLoading: false, - parentColumnSpace: 74, - parentRowSpace: 10, - leftColumn: 0, - rightColumn: 8, - topRow: 19, - bottomRow: 26, - parentId: "0", - widgetId: "fs785w9gcy", - dynamicBindingPathList: [], - primaryColumns: { - id: { - index: 0, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - computedValue: "", - }, - email: { - index: 1, - width: 150, - id: "email", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "email", - computedValue: "", - }, - userName: { - index: 2, - width: 150, - id: "userName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "userName", - computedValue: "", - }, - productName: { - index: 3, - width: 150, - id: "productName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "productName", - computedValue: "", - }, - orderAmount: { - index: 4, - width: 150, - id: "orderAmount", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "orderAmount", - computedValue: "", - }, - }, - textSize: "PARAGRAPH", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - renderMode: "CANVAS", - version: 1, - }, - ], - }; - const newDsl = migrateTableWidgetParentRowSpaceProperty(inputDsl); - expect(JSON.stringify(newDsl) === JSON.stringify(outputDsl)); - }); - - it("TableWidget : should update header options visibilities", () => { - const inputDsl: DSLWidget = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1224, - snapColumns: 16, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 1840, - containerStyle: "none", - snapRows: 33, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 7, - minHeight: 1292, - parentColumnSpace: 1, - dynamicBindingPathList: [], - leftColumn: 0, - isLoading: false, - parentId: "", - renderMode: "CANVAS", - children: [ - { - isVisible: true, - label: "Data", - widgetName: "Table1", - searchKey: "", - tableData: - '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', - type: "TABLE_WIDGET", - isLoading: false, - parentColumnSpace: 74, - parentRowSpace: 40, - leftColumn: 0, - rightColumn: 8, - topRow: 19, - bottomRow: 26, - parentId: "0", - widgetId: "fs785w9gcy", - dynamicBindingPathList: [], - primaryColumns: { - id: { - index: 0, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - computedValue: "", - }, - email: { - index: 1, - width: 150, - id: "email", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "email", - computedValue: "", - }, - userName: { - index: 2, - width: 150, - id: "userName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "userName", - computedValue: "", - }, - productName: { - index: 3, - width: 150, - id: "productName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "productName", - computedValue: "", - }, - orderAmount: { - index: 4, - width: 150, - id: "orderAmount", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "orderAmount", - computedValue: "", - }, - }, - textSize: "PARAGRAPH", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - renderMode: "CANVAS", - version: 1, - }, - ], - }; - const outputDsl: DSLWidget = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1224, - snapColumns: 16, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 1840, - containerStyle: "none", - snapRows: 33, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 7, - minHeight: 1292, - parentColumnSpace: 1, - dynamicBindingPathList: [], - leftColumn: 0, - isLoading: false, - parentId: "", - renderMode: "CANVAS", - children: [ - { - isVisible: true, - label: "Data", - widgetName: "Table1", - searchKey: "", - tableData: - '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', - type: "TABLE_WIDGET", - isLoading: false, - parentColumnSpace: 74, - parentRowSpace: 10, - leftColumn: 0, - rightColumn: 8, - topRow: 19, - bottomRow: 26, - parentId: "0", - widgetId: "fs785w9gcy", - dynamicBindingPathList: [], - primaryColumns: { - id: { - index: 0, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - computedValue: "", - }, - email: { - index: 1, - width: 150, - id: "email", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "email", - computedValue: "", - }, - userName: { - index: 2, - width: 150, - id: "userName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "userName", - computedValue: "", - }, - productName: { - index: 3, - width: 150, - id: "productName", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "productName", - computedValue: "", - }, - orderAmount: { - index: 4, - width: 150, - id: "orderAmount", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "orderAmount", - computedValue: "", - }, - }, - textSize: "PARAGRAPH", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - renderMode: "CANVAS", - isVisibleSearch: true, - isVisibleFilters: true, - isVisibleDownload: true, - isVisibleCompactMode: true, - isVisiblePagination: true, - version: 1, - }, - ], - }; - const newDsl = migrateTableWidgetHeaderVisibilityProperties(inputDsl); - expect(JSON.stringify(newDsl) === JSON.stringify(outputDsl)); - }); -}); - -describe("Table Widget Migration - #migrateTableSanitizeColumnKeys", () => { - it("sanitizes primaryColumns, dynamicBindingPathList, columnOrder", () => { - const inputDsl = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1080, - snapColumns: 64, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 980, - containerStyle: "none", - snapRows: 125, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 34, - minHeight: 860, - parentColumnSpace: 1, - dynamicTriggerPathList: [], - dynamicBindingPathList: [], - leftColumn: 0, - children: [ - { - widgetName: "Table1", - defaultPageSize: 0, - columnOrder: ["id", "name", "'random_header", "Employee.id"], - isVisibleDownload: true, - dynamicPropertyPathList: [], - topRow: 8, - bottomRow: 53, - parentRowSpace: 10, - type: "TABLE_WIDGET", - parentColumnSpace: 14.62421875, - dynamicTriggerPathList: [], - dynamicBindingPathList: [ - { key: "tableData" }, - { key: "primaryColumns.id.computedValue" }, - { key: "primaryColumns.name.computedValue" }, - { key: "primaryColumns.'random_header.computedValue" }, - { key: "primaryColumns.Employee.id.computedValue" }, - ], - leftColumn: 1, - primaryColumns: { - id: { - index: 0, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isDisabled: false, - isCellVisible: true, - isDerived: false, - label: "id", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.id))}}", - }, - name: { - index: 14, - width: 150, - id: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isDisabled: false, - isCellVisible: true, - isDerived: false, - label: "name", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.name))}}", - }, - "'random_header": { - index: 20, - width: 150, - id: "'random_header", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "'random_header", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.'random_header))}}", - }, - "Employee.id": { - index: 20, - width: 150, - id: "Employee.id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "Employee.id", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.Employee.id))}}", - }, - }, - delimiter: ",", - derivedColumns: {}, - rightColumn: 63, - textSize: "PARAGRAPH", - widgetId: "oclzovhzgx", - isVisibleFilters: true, - tableData: '{{users.data.concat({ "\'random header": 100})}}', - isVisible: true, - label: "Data", - searchKey: "", - version: 1, - parentId: "0", - totalRecordCount: 0, - isLoading: false, - isVisibleCompactMode: true, - horizontalAlignment: "LEFT", - isVisibleSearch: true, - isVisiblePagination: true, - verticalAlignment: "CENTER", - columnSizeMap: { - task: 245, - step: 62, - status: 75, - email: 261, - }, - }, - ], - } as unknown as DSLWidget; - - const outputDsl = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1080, - snapColumns: 64, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 980, - containerStyle: "none", - snapRows: 125, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 34, - minHeight: 860, - parentColumnSpace: 1, - dynamicTriggerPathList: [], - dynamicBindingPathList: [], - leftColumn: 0, - children: [ - { - widgetName: "Table1", - defaultPageSize: 0, - columnOrder: ["id", "name", "_random_header", "Employee_id"], - isVisibleDownload: true, - dynamicPropertyPathList: [], - topRow: 8, - bottomRow: 53, - parentRowSpace: 10, - type: "TABLE_WIDGET", - parentColumnSpace: 14.62421875, - dynamicTriggerPathList: [], - dynamicBindingPathList: [ - { key: "tableData" }, - { key: "primaryColumns.id.computedValue" }, - { key: "primaryColumns.name.computedValue" }, - { key: "primaryColumns._random_header.computedValue" }, - { key: "primaryColumns.Employee_id.computedValue" }, - ], - leftColumn: 1, - primaryColumns: { - id: { - index: 0, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isDisabled: false, - isCellVisible: true, - isDerived: false, - label: "id", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.id))}}", - }, - name: { - index: 14, - width: 150, - id: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isDisabled: false, - isCellVisible: true, - isDerived: false, - label: "name", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.name))}}", - }, - _random_header: { - index: 20, - width: 150, - id: "_random_header", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "'random_header", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow._random_header))}}", - }, - Employee_id: { - index: 20, - width: 150, - id: "Employee_id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "Employee.id", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.Employee_id))}}", - }, - }, - delimiter: ",", - derivedColumns: {}, - rightColumn: 63, - textSize: "PARAGRAPH", - widgetId: "oclzovhzgx", - isVisibleFilters: true, - tableData: '{{users.data.concat({ "\'random header": 100})}}', - isVisible: true, - label: "Data", - searchKey: "", - version: 1, - parentId: "0", - totalRecordCount: 0, - isLoading: false, - isVisibleCompactMode: true, - horizontalAlignment: "LEFT", - isVisibleSearch: true, - isVisiblePagination: true, - verticalAlignment: "CENTER", - columnSizeMap: { - task: 245, - step: 62, - status: 75, - email: 261, - }, - }, - ], - }; - - const badDsl = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1080, - snapColumns: 64, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 980, - containerStyle: "none", - snapRows: 125, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 34, - minHeight: 860, - parentColumnSpace: 1, - dynamicTriggerPathList: [], - dynamicBindingPathList: [], - leftColumn: 0, - children: [ - { - widgetName: "Table1", - defaultPageSize: 0, - columnOrder: ["Employee.id"], - isVisibleDownload: true, - dynamicPropertyPathList: [], - topRow: 8, - bottomRow: 53, - parentRowSpace: 10, - type: "TABLE_WIDGET", - parentColumnSpace: 14.62421875, - dynamicTriggerPathList: [], - dynamicBindingPathList: [ - { key: "tableData" }, - { key: "primaryColumns.Employee.id.computedValue" }, - ], - leftColumn: 1, - primaryColumns: { - "Employee.id": { - "": { - index: 20, - width: 150, - id: "Employee.id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "Employee.id", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.Employee.id))}}", - }, - }, - }, - delimiter: ",", - derivedColumns: {}, - rightColumn: 63, - textSize: "PARAGRAPH", - widgetId: "oclzovhzgx", - isVisibleFilters: true, - tableData: '{{users.data.concat({ "\'random header": 100})}}', - isVisible: true, - label: "Data", - searchKey: "", - version: 1, - parentId: "0", - totalRecordCount: 0, - isLoading: false, - isVisibleCompactMode: true, - horizontalAlignment: "LEFT", - isVisibleSearch: true, - isVisiblePagination: true, - verticalAlignment: "CENTER", - columnSizeMap: { - task: 245, - step: 62, - status: 75, - email: 261, - }, - }, - ], - } as unknown as DSLWidget; - - const fixedDsl = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1080, - snapColumns: 64, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 980, - containerStyle: "none", - snapRows: 125, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 34, - minHeight: 860, - parentColumnSpace: 1, - dynamicTriggerPathList: [], - dynamicBindingPathList: [], - leftColumn: 0, - children: [ - { - widgetName: "Table1", - defaultPageSize: 0, - columnOrder: ["Employee_id"], - isVisibleDownload: true, - dynamicPropertyPathList: [], - topRow: 8, - bottomRow: 53, - parentRowSpace: 10, - type: "TABLE_WIDGET", - parentColumnSpace: 14.62421875, - dynamicTriggerPathList: [], - dynamicBindingPathList: [ - { key: "tableData" }, - { key: "primaryColumns.Employee_id.computedValue" }, - ], - leftColumn: 1, - primaryColumns: { - Employee_id: { - index: 20, - width: 150, - id: "Employee_id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "Employee.id", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.Employee_id))}}", - }, - }, - delimiter: ",", - derivedColumns: {}, - rightColumn: 63, - textSize: "PARAGRAPH", - widgetId: "oclzovhzgx", - isVisibleFilters: true, - tableData: '{{users.data.concat({ "\'random header": 100})}}', - isVisible: true, - label: "Data", - searchKey: "", - version: 1, - parentId: "0", - totalRecordCount: 0, - isLoading: false, - isVisibleCompactMode: true, - horizontalAlignment: "LEFT", - isVisibleSearch: true, - isVisiblePagination: true, - verticalAlignment: "CENTER", - columnSizeMap: { - task: 245, - step: 62, - status: 75, - email: 261, - }, - }, - ], - }; - - const newDsl = migrateTableSanitizeColumnKeys(inputDsl); - const correctedDsl = migrateTableSanitizeColumnKeys(badDsl); - expect(newDsl).toStrictEqual(outputDsl); - expect(correctedDsl).toStrictEqual(fixedDsl); - }); -}); - -describe("Table Widget selectedRow bindings update", () => { - it("To test selectedRow bindings are updated for primaryColumns and derivedColumns", () => { - const inputDsl: DSLWidget = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1118, - snapColumns: 64, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 540, - containerStyle: "none", - snapRows: 129, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 36, - minHeight: 550, - parentColumnSpace: 1, - dynamicTriggerPathList: [], - dynamicBindingPathList: [], - leftColumn: 0, - renderMode: "CANVAS", - isLoading: false, - children: [ - { - widgetName: "Table1", - defaultPageSize: 0, - isVisibleDownload: true, - dynamicPropertyPathList: [], - topRow: 8, - bottomRow: 36, - parentRowSpace: 10, - type: "TABLE_WIDGET", - defaultSelectedRow: "0", - parentColumnSpace: 17.28125, - dynamicTriggerPathList: [{ key: "primaryColumns.action.onClick" }], - dynamicBindingPathList: [ - { key: "primaryColumns.step.computedValue" }, - { key: "primaryColumns.task.computedValue" }, - { key: "primaryColumns.status.computedValue" }, - { key: "primaryColumns.action.computedValue" }, - ], - leftColumn: 6, - primaryColumns: { - step: { - index: 0, - width: 150, - id: "step", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isDerived: false, - label: "step", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.step))}}", - }, - task: { - index: 1, - width: 150, - id: "task", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isDerived: false, - label: "task", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.task))}}", - }, - status: { - index: 2, - width: 150, - id: "status", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isDerived: false, - label: "status", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.status))}}", - }, - action: { - index: 3, - width: 150, - id: "action", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "button", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isDisabled: false, - isDerived: false, - label: "action", - onClick: "{{showAlert(Table1.selectedRow.task,'info')}}", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.action))}}", - }, - customColumn1: { - index: 4, - width: 150, - id: "customColumn1", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "button", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isDisabled: false, - isDerived: true, - label: "Delete", - onClick: "{{showAlert('Hello')}}", - computedValue: "", - }, - }, - delimiter: ",", - derivedColumns: {}, - rightColumn: 36, - textSize: "PARAGRAPH", - widgetId: "yd68qpgb0b", - isVisibleFilters: true, - tableData: [ - { step: "#1", task: "Drop a table", status: "✅", action: "" }, - { - step: "#2", - task: "Create a query fetch_users with the Mock DB", - status: "--", - action: "", - }, - { - step: "#3", - task: "Bind the query using => fetch_users.data", - status: "--", - action: "", - }, - ], - isVisible: true, - label: "Data", - searchKey: "", - version: 1, - totalRecordsCount: 0, - parentId: "0", - isLoading: false, - horizontalAlignment: "LEFT", - renderMode: "CANVAS", - isVisibleSearch: true, - isVisiblePagination: true, - verticalAlignment: "CENTER", - columnSizeMap: { task: 245, step: 62, status: 75 }, - }, - ], - }; - const newDsl = migrateTableWidgetSelectedRowBindings(inputDsl); - const outputDsl: DSLWidget = { - widgetName: "MainContainer", - backgroundColor: "none", - rightColumn: 1118, - snapColumns: 64, - detachFromLayout: true, - widgetId: "0", - topRow: 0, - bottomRow: 540, - containerStyle: "none", - snapRows: 129, - parentRowSpace: 1, - type: "CANVAS_WIDGET", - canExtend: true, - version: 36, - minHeight: 550, - parentColumnSpace: 1, - dynamicTriggerPathList: [], - dynamicBindingPathList: [], - leftColumn: 0, - renderMode: "CANVAS", - isLoading: false, - children: [ - { - widgetName: "Table1", - defaultPageSize: 0, - isVisibleDownload: true, - dynamicPropertyPathList: [], - topRow: 8, - bottomRow: 36, - parentRowSpace: 10, - type: "TABLE_WIDGET", - defaultSelectedRow: "0", - parentColumnSpace: 17.28125, - dynamicTriggerPathList: [{ key: "primaryColumns.action.onClick" }], - dynamicBindingPathList: [ - { key: "primaryColumns.step.computedValue" }, - { key: "primaryColumns.task.computedValue" }, - { key: "primaryColumns.status.computedValue" }, - { key: "primaryColumns.action.computedValue" }, - ], - leftColumn: 6, - primaryColumns: { - step: { - index: 0, - width: 150, - id: "step", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isDerived: false, - label: "step", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.step))}}", - }, - task: { - index: 1, - width: 150, - id: "task", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isDerived: false, - label: "task", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.task))}}", - }, - status: { - index: 2, - width: 150, - id: "status", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isDerived: false, - label: "status", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.status))}}", - }, - action: { - index: 3, - width: 150, - id: "action", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "button", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isDisabled: false, - isDerived: false, - label: "action", - onClick: "{{showAlert(currentRow.task,'info')}}", - computedValue: - "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.action))}}", - }, - customColumn1: { - index: 4, - width: 150, - id: "customColumn1", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "button", - textSize: "PARAGRAPH", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isDisabled: false, - isDerived: true, - label: "Delete", - onClick: "{{showAlert('Hello')}}", - computedValue: "", - }, - }, - delimiter: ",", - derivedColumns: {}, - rightColumn: 36, - textSize: "PARAGRAPH", - widgetId: "yd68qpgb0b", - isVisibleFilters: true, - tableData: [ - { step: "#1", task: "Drop a table", status: "✅", action: "" }, - { - step: "#2", - task: "Create a query fetch_users with the Mock DB", - status: "--", - action: "", - }, - { - step: "#3", - task: "Bind the query using => fetch_users.data", - status: "--", - action: "", - }, - ], - isVisible: true, - label: "Data", - searchKey: "", - version: 1, - totalRecordsCount: 0, - parentId: "0", - isLoading: false, - horizontalAlignment: "LEFT", - renderMode: "CANVAS", - isVisibleSearch: true, - isVisiblePagination: true, - verticalAlignment: "CENTER", - columnSizeMap: { task: 245, step: 62, status: 75 }, - }, - ], - }; - expect(newDsl).toStrictEqual(outputDsl); - }); -}); - -// describe("Table Widget numeric column name to string update", () => { -// it("to test numeric column name converted to string and rest column configuration remains same", () => { -// const inputDsl: DSLWidget = { -// widgetName: "MainContainer", -// backgroundColor: "none", -// rightColumn: 816, -// snapColumns: 64, -// detachFromLayout: true, -// widgetId: "0", -// topRow: 0, -// bottomRow: 5016, -// containerStyle: "none", -// snapRows: 125, -// parentRowSpace: 1, -// type: "CANVAS_WIDGET", -// canExtend: true, -// version: 50, -// minHeight: 1292, -// parentColumnSpace: 1, -// dynamicBindingPathList: [], -// leftColumn: 0, -// parentId: "", -// renderMode: "CANVAS", -// isLoading: false, -// children: [ -// { -// widgetName: "Table1", -// parentColumnSpace: 74, -// defaultPageSize: 0, -// columnOrder: [ -// "1", -// "2", -// "_user_", -// "_client_", -// "rowIndex", -// "customColumn1", -// "customColumn2", -// ], -// isVisibleDownload: true, -// dynamicPropertyPathList: [], -// displayName: "Table", -// iconSVG: "/static/media/icon.db8a9cbd.svg", -// topRow: 1, -// bottomRow: 29, -// isSortable: true, -// parentRowSpace: 10, -// type: "TABLE_WIDGET", -// defaultSelectedRow: "0", -// hideCard: false, -// animateLoading: true, -// isLoading: false, -// dynamicTriggerPathList: [], -// dynamicBindingPathList: [ -// { -// key: "tableData", -// }, -// { -// key: "primaryColumns.1.computedValue", -// }, -// { -// key: "primaryColumns.2.computedValue", -// }, -// { -// key: "primaryColumns._user_.computedValue", -// }, -// { -// key: "primaryColumns._client_.computedValue", -// }, -// { -// key: "primaryColumns.rowIndex.computedValue", -// }, -// { -// key: "derivedColumns.customColumn1.computedValue", -// }, -// { -// key: "primaryColumns.customColumn1.computedValue", -// }, -// { -// key: "derivedColumns.customColumn2.computedValue", -// }, -// { -// key: "primaryColumns.customColumn2.computedValue", -// }, -// ], -// leftColumn: 0, -// primaryColumns: { -// "1": { -// index: 0, -// width: 150, -// id: "1", -// horizontalAlignment: "LEFT", -// verticalAlignment: "CENTER", -// columnType: "text", -// textSize: "PARAGRAPH", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: false, -// label: "ONE", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.1))}}", -// }, -// "2": { -// index: 1, -// width: 150, -// id: "2", -// horizontalAlignment: "LEFT", -// verticalAlignment: "CENTER", -// columnType: "text", -// textSize: "PARAGRAPH", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: false, -// label: "TWO", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.2))}}", -// }, -// _user_: { -// index: 2, -// width: 150, -// id: "_user_", -// horizontalAlignment: "LEFT", -// verticalAlignment: "CENTER", -// columnType: "text", -// textSize: "PARAGRAPH", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: false, -// label: "USER", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow._user_))}}", -// }, -// _client_: { -// index: 3, -// width: 150, -// id: "_client_", -// horizontalAlignment: "LEFT", -// verticalAlignment: "CENTER", -// columnType: "text", -// textSize: "PARAGRAPH", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: false, -// label: "CLIENT", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow._client_))}}", -// }, -// rowIndex: { -// index: 4, -// width: 150, -// id: "rowIndex", -// horizontalAlignment: "LEFT", -// verticalAlignment: "CENTER", -// columnType: "text", -// textSize: "PARAGRAPH", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: false, -// label: "rowIndex", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.rowIndex))}}", -// }, -// customColumn1: { -// index: 5, -// width: 150, -// id: "customColumn1", -// columnType: "text", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: true, -// label: "Custom Column 1", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.customColumn1))}}", -// buttonStyle: "rgb(3, 179, 101)", -// buttonLabelColor: "#FFFFFF", -// buttonColor: "#03B365", -// menuColor: "#03B365", -// labelColor: "#FFFFFF", -// }, -// customColumn2: { -// index: 6, -// width: 150, -// id: "customColumn2", -// columnType: "text", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: true, -// label: "Custom Label", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.customColumn2))}}", -// buttonStyle: "rgb(3, 179, 101)", -// buttonLabelColor: "#FFFFFF", -// buttonColor: "#03B365", -// menuColor: "#03B365", -// labelColor: "#FFFFFF", -// }, -// }, -// delimiter: ",", -// key: "d0akgsw2t4", -// derivedColumns: { -// customColumn1: { -// index: 5, -// width: 150, -// id: "customColumn1", -// columnType: "text", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: true, -// label: "Custom Column 1", -// computedValue: -// '{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.rowIndex + " CC1"))}}', -// buttonStyle: "rgb(3, 179, 101)", -// buttonLabelColor: "#FFFFFF", -// buttonColor: "#03B365", -// menuColor: "#03B365", -// labelColor: "#FFFFFF", -// }, -// customColumn2: { -// index: 6, -// width: 150, -// id: "customColumn2", -// columnType: "text", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: true, -// label: "Custom Label", -// computedValue: -// '{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.rowIndex + " CC1"))}}', -// buttonStyle: "rgb(3, 179, 101)", -// buttonLabelColor: "#FFFFFF", -// buttonColor: "#03B365", -// menuColor: "#03B365", -// labelColor: "#FFFFFF", -// }, -// }, -// rightColumn: 34, -// textSize: "PARAGRAPH", -// widgetId: "v3kdn1uyjb", -// isVisibleFilters: true, -// tableData: "{{Api2.data}}", -// isVisible: true, -// label: "Data", -// searchKey: "", -// enableClientSideSearch: true, -// version: 3, -// totalRecordsCount: 0, -// parentId: "0", -// renderMode: "CANVAS", -// horizontalAlignment: "LEFT", -// isVisibleSearch: true, -// isVisiblePagination: true, -// verticalAlignment: "CENTER", -// columnSizeMap: { -// task: 245, -// step: 62, -// status: 75, -// }, -// }, -// ], -// }; -// // using cloneDeep, create new reference of inputDsl -// // otherwise migration function will modify inputDsl too -// const newDsl = migrateTableWidgetNumericColumnName(cloneDeep(inputDsl)); -// const outputDsl: DSLWidget = { -// widgetName: "MainContainer", -// backgroundColor: "none", -// rightColumn: 816, -// snapColumns: 64, -// detachFromLayout: true, -// widgetId: "0", -// topRow: 0, -// bottomRow: 5016, -// containerStyle: "none", -// snapRows: 125, -// parentRowSpace: 1, -// type: "CANVAS_WIDGET", -// canExtend: true, -// version: 50, -// minHeight: 1292, -// parentColumnSpace: 1, -// dynamicBindingPathList: [], -// leftColumn: 0, -// parentId: "", -// renderMode: "CANVAS", -// isLoading: false, -// children: [ -// { -// widgetName: "Table1", -// parentColumnSpace: 74, -// defaultPageSize: 0, -// columnOrder: [ -// "_1", -// "_2", -// "_user_", -// "_client_", -// "rowIndex", -// "customColumn1", -// "customColumn2", -// ], -// isVisibleDownload: true, -// dynamicPropertyPathList: [], -// displayName: "Table", -// iconSVG: "/static/media/icon.db8a9cbd.svg", -// topRow: 1, -// bottomRow: 29, -// isSortable: true, -// parentRowSpace: 10, -// type: "TABLE_WIDGET", -// defaultSelectedRow: "0", -// hideCard: false, -// animateLoading: true, -// isLoading: false, -// dynamicTriggerPathList: [], -// dynamicBindingPathList: [ -// { -// key: "tableData", -// }, -// { -// key: "primaryColumns._1.computedValue", -// }, -// { -// key: "primaryColumns._2.computedValue", -// }, -// { -// key: "primaryColumns._user_.computedValue", -// }, -// { -// key: "primaryColumns._client_.computedValue", -// }, -// { -// key: "primaryColumns.rowIndex.computedValue", -// }, -// { -// key: "derivedColumns.customColumn1.computedValue", -// }, -// { -// key: "primaryColumns.customColumn1.computedValue", -// }, -// { -// key: "derivedColumns.customColumn2.computedValue", -// }, -// { -// key: "primaryColumns.customColumn2.computedValue", -// }, -// ], -// leftColumn: 0, -// primaryColumns: { -// _1: { -// index: 0, -// width: 150, -// id: "_1", -// horizontalAlignment: "LEFT", -// verticalAlignment: "CENTER", -// columnType: "text", -// textSize: "PARAGRAPH", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: false, -// label: "ONE", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow._1))}}", -// }, -// _2: { -// index: 1, -// width: 150, -// id: "_2", -// horizontalAlignment: "LEFT", -// verticalAlignment: "CENTER", -// columnType: "text", -// textSize: "PARAGRAPH", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: false, -// label: "TWO", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow._2))}}", -// }, -// _user_: { -// index: 2, -// width: 150, -// id: "_user_", -// horizontalAlignment: "LEFT", -// verticalAlignment: "CENTER", -// columnType: "text", -// textSize: "PARAGRAPH", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: false, -// label: "USER", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow._user_))}}", -// }, -// _client_: { -// index: 3, -// width: 150, -// id: "_client_", -// horizontalAlignment: "LEFT", -// verticalAlignment: "CENTER", -// columnType: "text", -// textSize: "PARAGRAPH", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: false, -// label: "CLIENT", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow._client_))}}", -// }, -// rowIndex: { -// index: 4, -// width: 150, -// id: "rowIndex", -// horizontalAlignment: "LEFT", -// verticalAlignment: "CENTER", -// columnType: "text", -// textSize: "PARAGRAPH", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: false, -// label: "rowIndex", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.rowIndex))}}", -// }, -// customColumn1: { -// index: 5, -// width: 150, -// id: "customColumn1", -// columnType: "text", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: true, -// label: "Custom Column 1", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.customColumn1))}}", -// buttonStyle: "rgb(3, 179, 101)", -// buttonLabelColor: "#FFFFFF", -// buttonColor: "#03B365", -// menuColor: "#03B365", -// labelColor: "#FFFFFF", -// }, -// customColumn2: { -// index: 6, -// width: 150, -// id: "customColumn2", -// columnType: "text", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: true, -// label: "Custom Label", -// computedValue: -// "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.customColumn2))}}", -// buttonStyle: "rgb(3, 179, 101)", -// buttonLabelColor: "#FFFFFF", -// buttonColor: "#03B365", -// menuColor: "#03B365", -// labelColor: "#FFFFFF", -// }, -// }, -// delimiter: ",", -// key: "d0akgsw2t4", -// derivedColumns: { -// customColumn1: { -// index: 5, -// width: 150, -// id: "customColumn1", -// columnType: "text", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: true, -// label: "Custom Column 1", -// computedValue: -// '{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.rowIndex + " CC1"))}}', -// buttonStyle: "rgb(3, 179, 101)", -// buttonLabelColor: "#FFFFFF", -// buttonColor: "#03B365", -// menuColor: "#03B365", -// labelColor: "#FFFFFF", -// }, -// customColumn2: { -// index: 6, -// width: 150, -// id: "customColumn2", -// columnType: "text", -// enableFilter: true, -// enableSort: true, -// isVisible: true, -// isDisabled: false, -// isCellVisible: true, -// isDerived: true, -// label: "Custom Label", -// computedValue: -// '{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.rowIndex + " CC1"))}}', -// buttonStyle: "rgb(3, 179, 101)", -// buttonLabelColor: "#FFFFFF", -// buttonColor: "#03B365", -// menuColor: "#03B365", -// labelColor: "#FFFFFF", -// }, -// }, -// rightColumn: 34, -// textSize: "PARAGRAPH", -// widgetId: "v3kdn1uyjb", -// isVisibleFilters: true, -// tableData: "{{Api2.data}}", -// isVisible: true, -// label: "Data", -// searchKey: "", -// enableClientSideSearch: true, -// version: 3, -// totalRecordsCount: 0, -// parentId: "0", -// renderMode: "CANVAS", -// horizontalAlignment: "LEFT", -// isVisibleSearch: true, -// isVisiblePagination: true, -// verticalAlignment: "CENTER", -// columnSizeMap: { -// task: 245, -// step: 62, -// status: 75, -// }, -// }, -// ], -// }; - -// expect(newDsl).toStrictEqual(outputDsl); -// }); -// }); - -const oldBindingPrefix = `{{ - ( - (editedValue, currentRow, currentIndex) => ( -`; -const newBindingPrefix = `{{ - ( - (editedValue, currentRow, currentIndex, isNewRow) => ( -`; - -const oldBindingSuffix = (tableId: string, columnName: string) => ` - )) - ( - ${tableId}.columnEditableCellValue.${columnName} || "", - ${tableId}.processedTableData[${tableId}.editableCell.index] || - Object.keys(${tableId}.processedTableData[0]) - .filter(key => ["__originalIndex__", "__primaryKey__"].indexOf(key) === -1) - .reduce((prev, curr) => { - prev[curr] = ""; - return prev; - }, {}), - ${tableId}.editableCell.index) -}} -`; -const newBindingSuffix = (tableId: string, columnName: string) => { - return ` - )) - ( - (${tableId}.isAddRowInProgress ? ${tableId}.newRow.${columnName} : ${tableId}.columnEditableCellValue.${columnName}) || "", - ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.index] || - Object.keys(${tableId}.processedTableData[0]) - .filter(key => ["__originalIndex__", "__primaryKey__"].indexOf(key) === -1) - .reduce((prev, curr) => { - prev[curr] = ""; - return prev; - }, {})), - ${tableId}.isAddRowInProgress ? -1 : ${tableId}.editableCell.index, - ${tableId}.isAddRowInProgress - ) - }} - `; -}; - -describe("migrateTableWidgetV2ValidationBinding", () => { - const binding = "true"; - - it("should test that binding of isColumnEditableCellValid is getting updated", () => { - expect( - migrateTableWidgetV2ValidationBinding({ - children: [ - { - widgetName: "Table", - type: "TABLE_WIDGET_V2", - primaryColumns: { - step: { - validation: { - isColumnEditableCellValid: `${oldBindingPrefix}${binding}${oldBindingSuffix( - "Table", - "step", - )}`, - }, - }, - }, - }, - ], - } as any as DSLWidget), - ).toEqual({ - children: [ - { - widgetName: "Table", - type: "TABLE_WIDGET_V2", - primaryColumns: { - step: { - validation: { - isColumnEditableCellValid: `${newBindingPrefix}${binding}${newBindingSuffix( - "Table", - "step", - )}`, - }, - }, - }, - }, - ], - }); - }); -}); - -describe("migrateTableWidgetV2SelectOption", () => { - it("should test that binding of selectOption is getting updated", () => { - expect( - migrateTableWidgetV2SelectOption({ - children: [ - { - widgetName: "Table", - type: "TABLE_WIDGET_V2", - primaryColumns: { - step: { - columnType: "select", - selectOptions: "[{label: 1, value: 2}]", - }, - task: { - columnType: "select", - selectOptions: "{{[{label: 1, value: 2}]}}", - }, - status: { - columnType: "text", - selectOptions: "{{[{label: 1, value: 2}]}}", - }, - }, - }, - ], - } as any as DSLWidget), - ).toEqual({ - children: [ - { - widgetName: "Table", - type: "TABLE_WIDGET_V2", - primaryColumns: { - step: { - columnType: "select", - selectOptions: "[{label: 1, value: 2}]", - }, - task: { - columnType: "select", - selectOptions: - "{{Table.processedTableData.map((currentRow, currentIndex) => ( [{label: 1, value: 2}]))}}", - }, - status: { - columnType: "text", - selectOptions: "{{[{label: 1, value: 2}]}}", - }, - }, - }, - ], - }); - }); -}); - -describe("migrateTableWidgetTableDataJsMode", () => { - it("should test that tableData js mode is enabled", () => { - expect( - migrateTableWidgetTableDataJsMode({ - children: [ - { - widgetName: "Table", - type: "TABLE_WIDGET_V2", - primaryColumns: { - step: { - columnType: "select", - selectOptions: "[{label: 1, value: 2}]", - }, - task: { - columnType: "select", - selectOptions: "{{[{label: 1, value: 2}]}}", - }, - status: { - columnType: "text", - selectOptions: "{{[{label: 1, value: 2}]}}", - }, - }, - }, - { - widgetName: "Table1", - type: "TABLE_WIDGET_V2", - primaryColumns: { - step: { - columnType: "select", - selectOptions: "[{label: 1, value: 2}]", - }, - task: { - columnType: "select", - selectOptions: "{{[{label: 1, value: 2}]}}", - }, - status: { - columnType: "text", - selectOptions: "{{[{label: 1, value: 2}]}}", - }, - }, - dynamicPropertyPathList: [{ key: "test" }], - }, - { - widgetName: "Text", - type: "TEXT_WIDGET", - dynamicPropertyPathList: [{ key: "test" }], - }, - ], - } as any as DSLWidget), - ).toEqual({ - children: [ - { - widgetName: "Table", - type: "TABLE_WIDGET_V2", - primaryColumns: { - step: { - columnType: "select", - selectOptions: "[{label: 1, value: 2}]", - }, - task: { - columnType: "select", - selectOptions: "{{[{label: 1, value: 2}]}}", - }, - status: { - columnType: "text", - selectOptions: "{{[{label: 1, value: 2}]}}", - }, - }, - dynamicPropertyPathList: [{ key: "tableData" }], - }, - { - widgetName: "Table1", - type: "TABLE_WIDGET_V2", - primaryColumns: { - step: { - columnType: "select", - selectOptions: "[{label: 1, value: 2}]", - }, - task: { - columnType: "select", - selectOptions: "{{[{label: 1, value: 2}]}}", - }, - status: { - columnType: "text", - selectOptions: "{{[{label: 1, value: 2}]}}", - }, - }, - dynamicPropertyPathList: [{ key: "test" }, { key: "tableData" }], - }, - { - widgetName: "Text", - type: "TEXT_WIDGET", - dynamicPropertyPathList: [{ key: "test" }], - }, - ], - }); - }); -}); diff --git a/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/CurrenRowInValidationsBindingDSLs.ts b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/CurrenRowInValidationsBindingDSLs.ts new file mode 100644 index 000000000000..0ed24a1a151b --- /dev/null +++ b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/CurrenRowInValidationsBindingDSLs.ts @@ -0,0 +1,140 @@ +import type { DSLWidget } from "../../../types"; + +const bindingPrefixForInlineEditValidationControl = `{{ + ( + (isNewRow, currentIndex, currentRow) => ( +`; + +const oldBindingSuffixForInlineEditValidationControl = (tableId: string) => { + return ` + )) + ( + ${tableId}.isAddRowInProgress, + ${tableId}.isAddRowInProgress ? -1 : ${tableId}.editableCell.index, + ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.index] || + Object.keys(${tableId}.processedTableData[0]) + .filter(key => ["__originalIndex__", "__primaryKey__"].indexOf(key) === -1) + .reduce((prev, curr) => { + prev[curr] = ""; + return prev; + }, {})) + ) + }} + `; +}; + +const newBindingSuffixForInlineEditValidationControl = (tableId: string) => { + return ` + )) + ( + ${tableId}.isAddRowInProgress, + ${tableId}.isAddRowInProgress ? -1 : ${tableId}.editableCell.index, + ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.__originalIndex__] || + Object.keys(${tableId}.processedTableData[0]) + .filter(key => ["__originalIndex__", "__primaryKey__"].indexOf(key) === -1) + .reduce((prev, curr) => { + prev[curr] = ""; + return prev; + }, {})) + ) + }} + `; +}; + +const bindingPrefixForInlineEditValidProperty = `{{ + ( + (editedValue, currentRow, currentIndex, isNewRow) => ( +`; + +const oldBindingSuffixForInlineEditValidProperty = ( + tableId: string, + columnName: string, +) => { + return ` + )) + ( + (${tableId}.isAddRowInProgress ? ${tableId}.newRow.${columnName} : ${tableId}.columnEditableCellValue.${columnName}) || "", + ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.index] || + Object.keys(${tableId}.processedTableData[0]) + .filter(key => ["__originalIndex__", "__primaryKey__"].indexOf(key) === -1) + .reduce((prev, curr) => { + prev[curr] = ""; + return prev; + }, {})), + ${tableId}.isAddRowInProgress ? -1 : ${tableId}.editableCell.index, + ${tableId}.isAddRowInProgress + ) + }} + `; +}; + +const newBindingSuffixForInlineEditValidProperty = ( + tableId: string, + columnName: string, +) => { + return ` + )) + ( + (${tableId}.isAddRowInProgress ? ${tableId}.newRow.${columnName} : ${tableId}.columnEditableCellValue.${columnName}) || "", + ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.__originalIndex__] || + Object.keys(${tableId}.processedTableData[0]) + .filter(key => ["__originalIndex__", "__primaryKey__"].indexOf(key) === -1) + .reduce((prev, curr) => { + prev[curr] = ""; + return prev; + }, {})), + ${tableId}.isAddRowInProgress ? -1 : ${tableId}.editableCell.index, + ${tableId}.isAddRowInProgress + ) + }} + `; +}; + +const binding = "JSObject.myFun(currentRow)"; +export const currentRownInValidationsBindingInput = { + children: [ + { + widgetName: "Table", + type: "TABLE_WIDGET_V2", + primaryColumns: { + step: { + validation: { + isColumnEditableCellValid: `${bindingPrefixForInlineEditValidProperty}${binding}${oldBindingSuffixForInlineEditValidProperty( + "Table", + "step", + )}`, + errorMessage: `${bindingPrefixForInlineEditValidationControl}${binding}${oldBindingSuffixForInlineEditValidationControl("Table")}`, + isColumnEditableCellRequired: `${bindingPrefixForInlineEditValidationControl}${binding}${oldBindingSuffixForInlineEditValidationControl("Table")}`, + min: `${bindingPrefixForInlineEditValidationControl}${binding}${oldBindingSuffixForInlineEditValidationControl("Table")}`, + max: `${bindingPrefixForInlineEditValidationControl}${binding}${oldBindingSuffixForInlineEditValidationControl("Table")}`, + regex: `${bindingPrefixForInlineEditValidationControl}${binding}${oldBindingSuffixForInlineEditValidationControl("Table")}`, + }, + }, + }, + }, + ], +} as any as DSLWidget; + +export const currentRownInValidationsBindingOutput = { + children: [ + { + widgetName: "Table", + type: "TABLE_WIDGET_V2", + primaryColumns: { + step: { + validation: { + isColumnEditableCellValid: `${bindingPrefixForInlineEditValidProperty}${binding}${newBindingSuffixForInlineEditValidProperty( + "Table", + "step", + )}`, + errorMessage: `${bindingPrefixForInlineEditValidationControl}${binding}${newBindingSuffixForInlineEditValidationControl("Table")}`, + isColumnEditableCellRequired: `${bindingPrefixForInlineEditValidationControl}${binding}${newBindingSuffixForInlineEditValidationControl("Table")}`, + min: `${bindingPrefixForInlineEditValidationControl}${binding}${newBindingSuffixForInlineEditValidationControl("Table")}`, + max: `${bindingPrefixForInlineEditValidationControl}${binding}${newBindingSuffixForInlineEditValidationControl("Table")}`, + regex: `${bindingPrefixForInlineEditValidationControl}${binding}${newBindingSuffixForInlineEditValidationControl("Table")}`, + }, + }, + }, + }, + ], +} as any as DSLWidget; diff --git a/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/IsColumnEditableCellValidDSLs.ts b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/IsColumnEditableCellValidDSLs.ts new file mode 100644 index 000000000000..96ea0f29eeb2 --- /dev/null +++ b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/IsColumnEditableCellValidDSLs.ts @@ -0,0 +1,84 @@ +import type { DSLWidget } from "../../../types"; + +const oldBindingPrefix = `{{ + ( + (editedValue, currentRow, currentIndex) => ( +`; + +const newBindingPrefix = `{{ + ( + (editedValue, currentRow, currentIndex, isNewRow) => ( +`; + +const oldBindingSuffix = (tableId: string, columnName: string) => ` + )) + ( + ${tableId}.columnEditableCellValue.${columnName} || "", + ${tableId}.processedTableData[${tableId}.editableCell.index] || + Object.keys(${tableId}.processedTableData[0]) + .filter(key => ["__originalIndex__", "__primaryKey__"].indexOf(key) === -1) + .reduce((prev, curr) => { + prev[curr] = ""; + return prev; + }, {}), + ${tableId}.editableCell.index) +}} +`; + +const newBindingSuffix = (tableId: string, columnName: string) => { + return ` + )) + ( + (${tableId}.isAddRowInProgress ? ${tableId}.newRow.${columnName} : ${tableId}.columnEditableCellValue.${columnName}) || "", + ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.index] || + Object.keys(${tableId}.processedTableData[0]) + .filter(key => ["__originalIndex__", "__primaryKey__"].indexOf(key) === -1) + .reduce((prev, curr) => { + prev[curr] = ""; + return prev; + }, {})), + ${tableId}.isAddRowInProgress ? -1 : ${tableId}.editableCell.index, + ${tableId}.isAddRowInProgress + ) + }} + `; +}; + +const binding = "true"; +export const isEditableCellInput = { + children: [ + { + widgetName: "Table", + type: "TABLE_WIDGET_V2", + primaryColumns: { + step: { + validation: { + isColumnEditableCellValid: `${oldBindingPrefix}${binding}${oldBindingSuffix( + "Table", + "step", + )}`, + }, + }, + }, + }, + ], +} as any as DSLWidget; + +export const isEditableCellOutput = { + children: [ + { + widgetName: "Table", + type: "TABLE_WIDGET_V2", + primaryColumns: { + step: { + validation: { + isColumnEditableCellValid: `${newBindingPrefix}${binding}${newBindingSuffix( + "Table", + "step", + )}`, + }, + }, + }, + }, + ], +} as any as DSLWidget; diff --git a/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/ParentRowSpaceUpdateDSLs.ts b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/ParentRowSpaceUpdateDSLs.ts new file mode 100644 index 000000000000..22d58afc8d79 --- /dev/null +++ b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/ParentRowSpaceUpdateDSLs.ts @@ -0,0 +1,274 @@ +import type { DSLWidget } from "../../../types"; + +export const inputDsl: DSLWidget = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1224, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1840, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 7, + minHeight: 1292, + parentColumnSpace: 1, + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + label: "Data", + widgetName: "Table1", + searchKey: "", + tableData: + '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', + type: "TABLE_WIDGET", + isLoading: false, + parentColumnSpace: 74, + parentRowSpace: 40, + leftColumn: 0, + rightColumn: 8, + topRow: 19, + bottomRow: 26, + parentId: "0", + widgetId: "fs785w9gcy", + dynamicBindingPathList: [], + primaryColumns: { + id: { + index: 0, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + computedValue: "", + }, + email: { + index: 1, + width: 150, + id: "email", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "email", + computedValue: "", + }, + userName: { + index: 2, + width: 150, + id: "userName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "userName", + computedValue: "", + }, + productName: { + index: 3, + width: 150, + id: "productName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "productName", + computedValue: "", + }, + orderAmount: { + index: 4, + width: 150, + id: "orderAmount", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "orderAmount", + computedValue: "", + }, + }, + textSize: "PARAGRAPH", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + renderMode: "CANVAS", + version: 1, + }, + ], +}; +export const outputDsl: DSLWidget = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1224, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1840, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 7, + minHeight: 1292, + parentColumnSpace: 1, + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + label: "Data", + widgetName: "Table1", + searchKey: "", + tableData: + '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', + type: "TABLE_WIDGET", + isLoading: false, + parentColumnSpace: 74, + parentRowSpace: 10, + leftColumn: 0, + rightColumn: 8, + topRow: 19, + bottomRow: 26, + parentId: "0", + widgetId: "fs785w9gcy", + dynamicBindingPathList: [], + primaryColumns: { + id: { + index: 0, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + computedValue: "", + }, + email: { + index: 1, + width: 150, + id: "email", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "email", + computedValue: "", + }, + userName: { + index: 2, + width: 150, + id: "userName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "userName", + computedValue: "", + }, + productName: { + index: 3, + width: 150, + id: "productName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "productName", + computedValue: "", + }, + orderAmount: { + index: 4, + width: 150, + id: "orderAmount", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "orderAmount", + computedValue: "", + }, + }, + textSize: "PARAGRAPH", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + renderMode: "CANVAS", + version: 1, + }, + ], +}; diff --git a/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/PropertyPaneUpgradeDSLs.ts b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/PropertyPaneUpgradeDSLs.ts new file mode 100644 index 000000000000..237530e7220f --- /dev/null +++ b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/PropertyPaneUpgradeDSLs.ts @@ -0,0 +1,625 @@ +import type { DSLWidget } from "../../../types"; + +export const input1: DSLWidget = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1224, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1840, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 7, + minHeight: 1292, + parentColumnSpace: 1, + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + label: "Data", + widgetName: "Table1", + searchKey: "", + tableData: + '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', + type: "TABLE_WIDGET", + isLoading: false, + parentColumnSpace: 74, + parentRowSpace: 40, + leftColumn: 0, + rightColumn: 8, + topRow: 19, + bottomRow: 26, + parentId: "0", + widgetId: "fs785w9gcy", + dynamicBindingPathList: [], + renderMode: "CANVAS", + version: 1, + }, + ], +}; + +export const input2: DSLWidget = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1224, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1840, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 7, + minHeight: 1292, + parentColumnSpace: 1, + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + label: "Data", + widgetName: "Table2", + searchKey: "", + tableData: + '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', + type: "TABLE_WIDGET", + isLoading: false, + parentColumnSpace: 74, + parentRowSpace: 40, + leftColumn: 0, + rightColumn: 8, + topRow: 28, + bottomRow: 35, + parentId: "0", + widgetId: "l9i1e8ybkm", + dynamicBindingPathList: [], + dynamicTriggerPathList: [{ key: "columnActions" }], + columnActions: [ + { + label: "Test", + id: "ezooq966rd", + actionPayloads: [], + dynamicTrigger: "{{showAlert('test','success')}}", + }, + { + label: "Fail", + id: "1k8nkay5r6", + actionPayloads: [], + dynamicTrigger: "{{showAlert('Fail','error')}}", + }, + ], + renderMode: "CANVAS", + version: 1, + }, + ], +}; + +export const input3: DSLWidget = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1224, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1840, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 7, + minHeight: 1292, + parentColumnSpace: 1, + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + label: "Data", + widgetName: "Table3", + searchKey: "", + tableData: + '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', + type: "TABLE_WIDGET", + isLoading: false, + parentColumnSpace: 74, + parentRowSpace: 40, + leftColumn: 0, + rightColumn: 8, + topRow: 37, + bottomRow: 44, + parentId: "0", + widgetId: "8mkidz550s", + dynamicBindingPathList: [], + dynamicTriggerPathList: [ + { key: "onRowSelected" }, + { key: "onSearchTextChanged" }, + ], + onRowSelected: "{{showAlert('test','success')}}", + onSearchTextChanged: "{{showAlert('fail','error')}}", + renderMode: "CANVAS", + version: 1, + }, + ], +}; + +export const output1 = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1224, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1840, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 7, + minHeight: 1292, + parentColumnSpace: 1, + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + label: "Data", + widgetName: "Table1", + searchKey: "", + tableData: + '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', + type: "TABLE_WIDGET", + isLoading: false, + parentColumnSpace: 74, + parentRowSpace: 40, + leftColumn: 0, + rightColumn: 8, + topRow: 19, + bottomRow: 26, + parentId: "0", + widgetId: "fs785w9gcy", + dynamicBindingPathList: [], + primaryColumns: { + id: { + index: 0, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + computedValue: "", + }, + email: { + index: 1, + width: 150, + id: "email", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "email", + computedValue: "", + }, + userName: { + index: 2, + width: 150, + id: "userName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "userName", + computedValue: "", + }, + productName: { + index: 3, + width: 150, + id: "productName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "productName", + computedValue: "", + }, + orderAmount: { + index: 4, + width: 150, + id: "orderAmount", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "orderAmount", + computedValue: "", + }, + }, + textSize: "PARAGRAPH", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + renderMode: "CANVAS", + version: 1, + }, + ], +}; + +export const output2 = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1224, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1840, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 7, + minHeight: 1292, + parentColumnSpace: 1, + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + label: "Data", + widgetName: "Table2", + searchKey: "", + tableData: + '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', + type: "TABLE_WIDGET", + isLoading: false, + parentColumnSpace: 74, + parentRowSpace: 40, + leftColumn: 0, + rightColumn: 8, + topRow: 28, + bottomRow: 35, + parentId: "0", + widgetId: "l9i1e8ybkm", + dynamicBindingPathList: [], + dynamicTriggerPathList: [ + { key: "columnActions" }, + { key: "primaryColumns.customColumn1.onClick" }, + { key: "primaryColumns.customColumn2.onClick" }, + ], + columnActions: [ + { + label: "Test", + id: "ezooq966rd", + actionPayloads: [], + dynamicTrigger: "{{showAlert('test','success')}}", + }, + { + label: "Fail", + id: "1k8nkay5r6", + actionPayloads: [], + dynamicTrigger: "{{showAlert('Fail','error')}}", + }, + ], + primaryColumns: { + id: { + index: 0, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + computedValue: "", + }, + email: { + index: 1, + width: 150, + id: "email", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "email", + computedValue: "", + }, + userName: { + index: 2, + width: 150, + id: "userName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "userName", + computedValue: "", + }, + productName: { + index: 3, + width: 150, + id: "productName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "productName", + computedValue: "", + }, + orderAmount: { + index: 4, + width: 150, + id: "orderAmount", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "orderAmount", + computedValue: "", + }, + customColumn1: { + index: 5, + width: 150, + id: "ezooq966rd", + label: "Test", + columnType: "button", + isVisible: true, + isDerived: true, + buttonLabel: "Test", + buttonStyle: "rgb(3, 179, 101)", + buttonLabelColor: "#FFFFFF", + onClick: "{{showAlert('test','success')}}", + }, + customColumn2: { + index: 6, + width: 150, + id: "1k8nkay5r6", + label: "Fail", + columnType: "button", + isVisible: true, + isDerived: true, + buttonLabel: "Fail", + buttonStyle: "rgb(3, 179, 101)", + buttonLabelColor: "#FFFFFF", + onClick: "{{showAlert('Fail','error')}}", + }, + }, + textSize: "PARAGRAPH", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + renderMode: "CANVAS", + version: 1, + }, + ], +}; + +export const output3 = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1224, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1840, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 7, + minHeight: 1292, + parentColumnSpace: 1, + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + label: "Data", + widgetName: "Table3", + searchKey: "", + tableData: + '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', + type: "TABLE_WIDGET", + isLoading: false, + parentColumnSpace: 74, + parentRowSpace: 40, + leftColumn: 0, + rightColumn: 8, + topRow: 37, + bottomRow: 44, + parentId: "0", + widgetId: "8mkidz550s", + dynamicBindingPathList: [], + dynamicTriggerPathList: [ + { key: "onRowSelected" }, + { key: "onSearchTextChanged" }, + ], + onRowSelected: "{{showAlert('test','success')}}", + onSearchTextChanged: "{{showAlert('fail','error')}}", + primaryColumns: { + id: { + index: 0, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + computedValue: "", + }, + email: { + index: 1, + width: 150, + id: "email", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "email", + computedValue: "", + }, + userName: { + index: 2, + width: 150, + id: "userName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "userName", + computedValue: "", + }, + productName: { + index: 3, + width: 150, + id: "productName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "productName", + computedValue: "", + }, + orderAmount: { + index: 4, + width: 150, + id: "orderAmount", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "orderAmount", + computedValue: "", + }, + }, + textSize: "PARAGRAPH", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + renderMode: "CANVAS", + version: 1, + }, + ], +}; diff --git a/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/SelectedRowBindingsDSLs.ts b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/SelectedRowBindingsDSLs.ts new file mode 100644 index 000000000000..f9a95ed86738 --- /dev/null +++ b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/SelectedRowBindingsDSLs.ts @@ -0,0 +1,341 @@ +import type { DSLWidget } from "../../../types"; + +export const inputDsl: DSLWidget = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1118, + snapColumns: 64, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 540, + containerStyle: "none", + snapRows: 129, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 36, + minHeight: 550, + parentColumnSpace: 1, + dynamicTriggerPathList: [], + dynamicBindingPathList: [], + leftColumn: 0, + renderMode: "CANVAS", + isLoading: false, + children: [ + { + widgetName: "Table1", + defaultPageSize: 0, + isVisibleDownload: true, + dynamicPropertyPathList: [], + topRow: 8, + bottomRow: 36, + parentRowSpace: 10, + type: "TABLE_WIDGET", + defaultSelectedRow: "0", + parentColumnSpace: 17.28125, + dynamicTriggerPathList: [{ key: "primaryColumns.action.onClick" }], + dynamicBindingPathList: [ + { key: "primaryColumns.step.computedValue" }, + { key: "primaryColumns.task.computedValue" }, + { key: "primaryColumns.status.computedValue" }, + { key: "primaryColumns.action.computedValue" }, + ], + leftColumn: 6, + primaryColumns: { + step: { + index: 0, + width: 150, + id: "step", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isDerived: false, + label: "step", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.step))}}", + }, + task: { + index: 1, + width: 150, + id: "task", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isDerived: false, + label: "task", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.task))}}", + }, + status: { + index: 2, + width: 150, + id: "status", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isDerived: false, + label: "status", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.status))}}", + }, + action: { + index: 3, + width: 150, + id: "action", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "button", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isDisabled: false, + isDerived: false, + label: "action", + onClick: "{{showAlert(Table1.selectedRow.task,'info')}}", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.action))}}", + }, + customColumn1: { + index: 4, + width: 150, + id: "customColumn1", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "button", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isDisabled: false, + isDerived: true, + label: "Delete", + onClick: "{{showAlert('Hello')}}", + computedValue: "", + }, + }, + delimiter: ",", + derivedColumns: {}, + rightColumn: 36, + textSize: "PARAGRAPH", + widgetId: "yd68qpgb0b", + isVisibleFilters: true, + tableData: [ + { step: "#1", task: "Drop a table", status: "✅", action: "" }, + { + step: "#2", + task: "Create a query fetch_users with the Mock DB", + status: "--", + action: "", + }, + { + step: "#3", + task: "Bind the query using => fetch_users.data", + status: "--", + action: "", + }, + ], + isVisible: true, + label: "Data", + searchKey: "", + version: 1, + totalRecordsCount: 0, + parentId: "0", + isLoading: false, + horizontalAlignment: "LEFT", + renderMode: "CANVAS", + isVisibleSearch: true, + isVisiblePagination: true, + verticalAlignment: "CENTER", + columnSizeMap: { task: 245, step: 62, status: 75 }, + }, + ], +}; + +export const outputDsl: DSLWidget = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1118, + snapColumns: 64, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 540, + containerStyle: "none", + snapRows: 129, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 36, + minHeight: 550, + parentColumnSpace: 1, + dynamicTriggerPathList: [], + dynamicBindingPathList: [], + leftColumn: 0, + renderMode: "CANVAS", + isLoading: false, + children: [ + { + widgetName: "Table1", + defaultPageSize: 0, + isVisibleDownload: true, + dynamicPropertyPathList: [], + topRow: 8, + bottomRow: 36, + parentRowSpace: 10, + type: "TABLE_WIDGET", + defaultSelectedRow: "0", + parentColumnSpace: 17.28125, + dynamicTriggerPathList: [{ key: "primaryColumns.action.onClick" }], + dynamicBindingPathList: [ + { key: "primaryColumns.step.computedValue" }, + { key: "primaryColumns.task.computedValue" }, + { key: "primaryColumns.status.computedValue" }, + { key: "primaryColumns.action.computedValue" }, + ], + leftColumn: 6, + primaryColumns: { + step: { + index: 0, + width: 150, + id: "step", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isDerived: false, + label: "step", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.step))}}", + }, + task: { + index: 1, + width: 150, + id: "task", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isDerived: false, + label: "task", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.task))}}", + }, + status: { + index: 2, + width: 150, + id: "status", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isDerived: false, + label: "status", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.status))}}", + }, + action: { + index: 3, + width: 150, + id: "action", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "button", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isDisabled: false, + isDerived: false, + label: "action", + onClick: "{{showAlert(currentRow.task,'info')}}", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.action))}}", + }, + customColumn1: { + index: 4, + width: 150, + id: "customColumn1", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "button", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isDisabled: false, + isDerived: true, + label: "Delete", + onClick: "{{showAlert('Hello')}}", + computedValue: "", + }, + }, + delimiter: ",", + derivedColumns: {}, + rightColumn: 36, + textSize: "PARAGRAPH", + widgetId: "yd68qpgb0b", + isVisibleFilters: true, + tableData: [ + { step: "#1", task: "Drop a table", status: "✅", action: "" }, + { + step: "#2", + task: "Create a query fetch_users with the Mock DB", + status: "--", + action: "", + }, + { + step: "#3", + task: "Bind the query using => fetch_users.data", + status: "--", + action: "", + }, + ], + isVisible: true, + label: "Data", + searchKey: "", + version: 1, + totalRecordsCount: 0, + parentId: "0", + isLoading: false, + horizontalAlignment: "LEFT", + renderMode: "CANVAS", + isVisibleSearch: true, + isVisiblePagination: true, + verticalAlignment: "CENTER", + columnSizeMap: { task: 245, step: 62, status: 75 }, + }, + ], +}; diff --git a/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/TableDataJSModeDSLs.ts b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/TableDataJSModeDSLs.ts new file mode 100644 index 000000000000..6c914adb3046 --- /dev/null +++ b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/TableDataJSModeDSLs.ts @@ -0,0 +1,96 @@ +import type { DSLWidget } from "../../../types"; + +export const tableV2DataJSModeInput = { + children: [ + { + widgetName: "Table", + type: "TABLE_WIDGET_V2", + primaryColumns: { + step: { + columnType: "select", + selectOptions: "[{label: 1, value: 2}]", + }, + task: { + columnType: "select", + selectOptions: "{{[{label: 1, value: 2}]}}", + }, + status: { + columnType: "text", + selectOptions: "{{[{label: 1, value: 2}]}}", + }, + }, + }, + { + widgetName: "Table1", + type: "TABLE_WIDGET_V2", + primaryColumns: { + step: { + columnType: "select", + selectOptions: "[{label: 1, value: 2}]", + }, + task: { + columnType: "select", + selectOptions: "{{[{label: 1, value: 2}]}}", + }, + status: { + columnType: "text", + selectOptions: "{{[{label: 1, value: 2}]}}", + }, + }, + dynamicPropertyPathList: [{ key: "test" }], + }, + { + widgetName: "Text", + type: "TEXT_WIDGET", + dynamicPropertyPathList: [{ key: "test" }], + }, + ], +} as any as DSLWidget; + +export const tableV2DataJSModeOutput = { + children: [ + { + widgetName: "Table", + type: "TABLE_WIDGET_V2", + primaryColumns: { + step: { + columnType: "select", + selectOptions: "[{label: 1, value: 2}]", + }, + task: { + columnType: "select", + selectOptions: "{{[{label: 1, value: 2}]}}", + }, + status: { + columnType: "text", + selectOptions: "{{[{label: 1, value: 2}]}}", + }, + }, + dynamicPropertyPathList: [{ key: "tableData" }], + }, + { + widgetName: "Table1", + type: "TABLE_WIDGET_V2", + primaryColumns: { + step: { + columnType: "select", + selectOptions: "[{label: 1, value: 2}]", + }, + task: { + columnType: "select", + selectOptions: "{{[{label: 1, value: 2}]}}", + }, + status: { + columnType: "text", + selectOptions: "{{[{label: 1, value: 2}]}}", + }, + }, + dynamicPropertyPathList: [{ key: "test" }, { key: "tableData" }], + }, + { + widgetName: "Text", + type: "TEXT_WIDGET", + dynamicPropertyPathList: [{ key: "test" }], + }, + ], +} as any as DSLWidget; diff --git a/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/TableSanitizeColumnKeysDSLs.ts b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/TableSanitizeColumnKeysDSLs.ts new file mode 100644 index 000000000000..ce5990029993 --- /dev/null +++ b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/TableSanitizeColumnKeysDSLs.ts @@ -0,0 +1,453 @@ +import type { DSLWidget } from "../../../types"; + +export const inputDsl = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1080, + snapColumns: 64, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 980, + containerStyle: "none", + snapRows: 125, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 34, + minHeight: 860, + parentColumnSpace: 1, + dynamicTriggerPathList: [], + dynamicBindingPathList: [], + leftColumn: 0, + children: [ + { + widgetName: "Table1", + defaultPageSize: 0, + columnOrder: ["id", "name", "'random_header", "Employee.id"], + isVisibleDownload: true, + dynamicPropertyPathList: [], + topRow: 8, + bottomRow: 53, + parentRowSpace: 10, + type: "TABLE_WIDGET", + parentColumnSpace: 14.62421875, + dynamicTriggerPathList: [], + dynamicBindingPathList: [ + { key: "tableData" }, + { key: "primaryColumns.id.computedValue" }, + { key: "primaryColumns.name.computedValue" }, + { key: "primaryColumns.'random_header.computedValue" }, + { key: "primaryColumns.Employee.id.computedValue" }, + ], + leftColumn: 1, + primaryColumns: { + id: { + index: 0, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isDisabled: false, + isCellVisible: true, + isDerived: false, + label: "id", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.id))}}", + }, + name: { + index: 14, + width: 150, + id: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isDisabled: false, + isCellVisible: true, + isDerived: false, + label: "name", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.name))}}", + }, + "'random_header": { + index: 20, + width: 150, + id: "'random_header", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "'random_header", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.'random_header))}}", + }, + "Employee.id": { + index: 20, + width: 150, + id: "Employee.id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "Employee.id", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.Employee.id))}}", + }, + }, + delimiter: ",", + derivedColumns: {}, + rightColumn: 63, + textSize: "PARAGRAPH", + widgetId: "oclzovhzgx", + isVisibleFilters: true, + tableData: '{{users.data.concat({ "\'random header": 100})}}', + isVisible: true, + label: "Data", + searchKey: "", + version: 1, + parentId: "0", + totalRecordCount: 0, + isLoading: false, + isVisibleCompactMode: true, + horizontalAlignment: "LEFT", + isVisibleSearch: true, + isVisiblePagination: true, + verticalAlignment: "CENTER", + columnSizeMap: { + task: 245, + step: 62, + status: 75, + email: 261, + }, + }, + ], +} as unknown as DSLWidget; + +export const outputDsl = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1080, + snapColumns: 64, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 980, + containerStyle: "none", + snapRows: 125, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 34, + minHeight: 860, + parentColumnSpace: 1, + dynamicTriggerPathList: [], + dynamicBindingPathList: [], + leftColumn: 0, + children: [ + { + widgetName: "Table1", + defaultPageSize: 0, + columnOrder: ["id", "name", "_random_header", "Employee_id"], + isVisibleDownload: true, + dynamicPropertyPathList: [], + topRow: 8, + bottomRow: 53, + parentRowSpace: 10, + type: "TABLE_WIDGET", + parentColumnSpace: 14.62421875, + dynamicTriggerPathList: [], + dynamicBindingPathList: [ + { key: "tableData" }, + { key: "primaryColumns.id.computedValue" }, + { key: "primaryColumns.name.computedValue" }, + { key: "primaryColumns._random_header.computedValue" }, + { key: "primaryColumns.Employee_id.computedValue" }, + ], + leftColumn: 1, + primaryColumns: { + id: { + index: 0, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isDisabled: false, + isCellVisible: true, + isDerived: false, + label: "id", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.id))}}", + }, + name: { + index: 14, + width: 150, + id: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isDisabled: false, + isCellVisible: true, + isDerived: false, + label: "name", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.name))}}", + }, + _random_header: { + index: 20, + width: 150, + id: "_random_header", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "'random_header", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow._random_header))}}", + }, + Employee_id: { + index: 20, + width: 150, + id: "Employee_id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "Employee.id", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.Employee_id))}}", + }, + }, + delimiter: ",", + derivedColumns: {}, + rightColumn: 63, + textSize: "PARAGRAPH", + widgetId: "oclzovhzgx", + isVisibleFilters: true, + tableData: '{{users.data.concat({ "\'random header": 100})}}', + isVisible: true, + label: "Data", + searchKey: "", + version: 1, + parentId: "0", + totalRecordCount: 0, + isLoading: false, + isVisibleCompactMode: true, + horizontalAlignment: "LEFT", + isVisibleSearch: true, + isVisiblePagination: true, + verticalAlignment: "CENTER", + columnSizeMap: { + task: 245, + step: 62, + status: 75, + email: 261, + }, + }, + ], +}; + +export const badDsl = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1080, + snapColumns: 64, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 980, + containerStyle: "none", + snapRows: 125, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 34, + minHeight: 860, + parentColumnSpace: 1, + dynamicTriggerPathList: [], + dynamicBindingPathList: [], + leftColumn: 0, + children: [ + { + widgetName: "Table1", + defaultPageSize: 0, + columnOrder: ["Employee.id"], + isVisibleDownload: true, + dynamicPropertyPathList: [], + topRow: 8, + bottomRow: 53, + parentRowSpace: 10, + type: "TABLE_WIDGET", + parentColumnSpace: 14.62421875, + dynamicTriggerPathList: [], + dynamicBindingPathList: [ + { key: "tableData" }, + { key: "primaryColumns.Employee.id.computedValue" }, + ], + leftColumn: 1, + primaryColumns: { + "Employee.id": { + "": { + index: 20, + width: 150, + id: "Employee.id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "Employee.id", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.Employee.id))}}", + }, + }, + }, + delimiter: ",", + derivedColumns: {}, + rightColumn: 63, + textSize: "PARAGRAPH", + widgetId: "oclzovhzgx", + isVisibleFilters: true, + tableData: '{{users.data.concat({ "\'random header": 100})}}', + isVisible: true, + label: "Data", + searchKey: "", + version: 1, + parentId: "0", + totalRecordCount: 0, + isLoading: false, + isVisibleCompactMode: true, + horizontalAlignment: "LEFT", + isVisibleSearch: true, + isVisiblePagination: true, + verticalAlignment: "CENTER", + columnSizeMap: { + task: 245, + step: 62, + status: 75, + email: 261, + }, + }, + ], +} as unknown as DSLWidget; + +export const fixedDsl = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1080, + snapColumns: 64, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 980, + containerStyle: "none", + snapRows: 125, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 34, + minHeight: 860, + parentColumnSpace: 1, + dynamicTriggerPathList: [], + dynamicBindingPathList: [], + leftColumn: 0, + children: [ + { + widgetName: "Table1", + defaultPageSize: 0, + columnOrder: ["Employee_id"], + isVisibleDownload: true, + dynamicPropertyPathList: [], + topRow: 8, + bottomRow: 53, + parentRowSpace: 10, + type: "TABLE_WIDGET", + parentColumnSpace: 14.62421875, + dynamicTriggerPathList: [], + dynamicBindingPathList: [ + { key: "tableData" }, + { key: "primaryColumns.Employee_id.computedValue" }, + ], + leftColumn: 1, + primaryColumns: { + Employee_id: { + index: 20, + width: 150, + id: "Employee_id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "PARAGRAPH", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "Employee.id", + computedValue: + "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.Employee_id))}}", + }, + }, + delimiter: ",", + derivedColumns: {}, + rightColumn: 63, + textSize: "PARAGRAPH", + widgetId: "oclzovhzgx", + isVisibleFilters: true, + tableData: '{{users.data.concat({ "\'random header": 100})}}', + isVisible: true, + label: "Data", + searchKey: "", + version: 1, + parentId: "0", + totalRecordCount: 0, + isLoading: false, + isVisibleCompactMode: true, + horizontalAlignment: "LEFT", + isVisibleSearch: true, + isVisiblePagination: true, + verticalAlignment: "CENTER", + columnSizeMap: { + task: 245, + step: 62, + status: 75, + email: 261, + }, + }, + ], +}; diff --git a/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/TableV2SelectOptionDSLs.ts b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/TableV2SelectOptionDSLs.ts new file mode 100644 index 000000000000..24f8c794529f --- /dev/null +++ b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/TableV2SelectOptionDSLs.ts @@ -0,0 +1,48 @@ +import type { DSLWidget } from "../../../types"; + +export const tableV2SelectOptionInput = { + children: [ + { + widgetName: "Table", + type: "TABLE_WIDGET_V2", + primaryColumns: { + step: { + columnType: "select", + selectOptions: "[{label: 1, value: 2}]", + }, + task: { + columnType: "select", + selectOptions: "{{[{label: 1, value: 2}]}}", + }, + status: { + columnType: "text", + selectOptions: "{{[{label: 1, value: 2}]}}", + }, + }, + }, + ], +} as any as DSLWidget; + +export const tableV2SelectOptionOutput = { + children: [ + { + widgetName: "Table", + type: "TABLE_WIDGET_V2", + primaryColumns: { + step: { + columnType: "select", + selectOptions: "[{label: 1, value: 2}]", + }, + task: { + columnType: "select", + selectOptions: + "{{Table.processedTableData.map((currentRow, currentIndex) => ( [{label: 1, value: 2}]))}}", + }, + status: { + columnType: "text", + selectOptions: "{{[{label: 1, value: 2}]}}", + }, + }, + }, + ], +} as any as DSLWidget; diff --git a/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/UpdateHeaderOptionsDSLs.ts b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/UpdateHeaderOptionsDSLs.ts new file mode 100644 index 000000000000..09c547f2b986 --- /dev/null +++ b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/DSLs/UpdateHeaderOptionsDSLs.ts @@ -0,0 +1,279 @@ +import type { DSLWidget } from "../../../types"; + +export const inputDsl: DSLWidget = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1224, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1840, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 7, + minHeight: 1292, + parentColumnSpace: 1, + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + label: "Data", + widgetName: "Table1", + searchKey: "", + tableData: + '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', + type: "TABLE_WIDGET", + isLoading: false, + parentColumnSpace: 74, + parentRowSpace: 40, + leftColumn: 0, + rightColumn: 8, + topRow: 19, + bottomRow: 26, + parentId: "0", + widgetId: "fs785w9gcy", + dynamicBindingPathList: [], + primaryColumns: { + id: { + index: 0, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + computedValue: "", + }, + email: { + index: 1, + width: 150, + id: "email", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "email", + computedValue: "", + }, + userName: { + index: 2, + width: 150, + id: "userName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "userName", + computedValue: "", + }, + productName: { + index: 3, + width: 150, + id: "productName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "productName", + computedValue: "", + }, + orderAmount: { + index: 4, + width: 150, + id: "orderAmount", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "orderAmount", + computedValue: "", + }, + }, + textSize: "PARAGRAPH", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + renderMode: "CANVAS", + version: 1, + }, + ], +}; +export const outputDsl: DSLWidget = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1224, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1840, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 7, + minHeight: 1292, + parentColumnSpace: 1, + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + label: "Data", + widgetName: "Table1", + searchKey: "", + tableData: + '[\n {\n "id": 2381224,\n "email": "michael.lawson@reqres.in",\n "userName": "Michael Lawson",\n "productName": "Chicken Sandwich",\n "orderAmount": 4.99\n },\n {\n "id": 2736212,\n "email": "lindsay.ferguson@reqres.in",\n "userName": "Lindsay Ferguson",\n "productName": "Tuna Salad",\n "orderAmount": 9.99\n },\n {\n "id": 6788734,\n "email": "tobias.funke@reqres.in",\n "userName": "Tobias Funke",\n "productName": "Beef steak",\n "orderAmount": 19.99\n }\n]', + type: "TABLE_WIDGET", + isLoading: false, + parentColumnSpace: 74, + parentRowSpace: 10, + leftColumn: 0, + rightColumn: 8, + topRow: 19, + bottomRow: 26, + parentId: "0", + widgetId: "fs785w9gcy", + dynamicBindingPathList: [], + primaryColumns: { + id: { + index: 0, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + computedValue: "", + }, + email: { + index: 1, + width: 150, + id: "email", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "email", + computedValue: "", + }, + userName: { + index: 2, + width: 150, + id: "userName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "userName", + computedValue: "", + }, + productName: { + index: 3, + width: 150, + id: "productName", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "productName", + computedValue: "", + }, + orderAmount: { + index: 4, + width: 150, + id: "orderAmount", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "orderAmount", + computedValue: "", + }, + }, + textSize: "PARAGRAPH", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + renderMode: "CANVAS", + isVisibleSearch: true, + isVisibleFilters: true, + isVisibleDownload: true, + isVisibleCompactMode: true, + isVisiblePagination: true, + version: 1, + }, + ], +}; diff --git a/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/TableWidget.test.ts b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/TableWidget.test.ts new file mode 100644 index 000000000000..fa9eca4b580c --- /dev/null +++ b/app/client/packages/dsl/src/migrate/tests/TableWidgetV2/TableWidget.test.ts @@ -0,0 +1,131 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { tableWidgetPropertyPaneMigrations } from "../../migrations/009-table-widget-property-pane-migration"; +import { migrateTableWidgetParentRowSpaceProperty } from "../../migrations/022-migrate-table-widget-parent-row-space-property"; +import { migrateTableWidgetHeaderVisibilityProperties } from "../../migrations/024-migrate-table-widget-header-visibility-properties"; +import { migrateTableSanitizeColumnKeys } from "../../migrations/037-migrate-table-sanitize-column-keys"; +import { migrateTableWidgetSelectedRowBindings } from "../../migrations/039-migrate-table-widget-selected-row-bindings"; +import { migrateTableWidgetV2ValidationBinding } from "../../migrations/066-migrate-table-widget-v2-validation-binding"; +import { migrateTableWidgetV2SelectOption } from "../../migrations/071-migrate-table-widget-v2-select-option"; +import { migrateTableWidgetTableDataJsMode } from "../../migrations/079-migrate-table-widget-table-data-js-mode"; +import { migrateTableWidgetV2CurrentRowInValidationsBinding } from "../../migrations/089-migrage-table-widget-v2-currentRow-binding"; +import { + currentRownInValidationsBindingInput, + currentRownInValidationsBindingOutput, +} from "./DSLs/CurrenRowInValidationsBindingDSLs"; +import { + isEditableCellInput, + isEditableCellOutput, +} from "./DSLs/IsColumnEditableCellValidDSLs"; +import { + input1, + input2, + input3, + output1, + output2, + output3, +} from "./DSLs/PropertyPaneUpgradeDSLs"; +import { + inputDsl as parentRowSpaceInputDsl, + outputDsl as parentRowSpaceOutputDsl, + inputDsl as selectedRowInputDsl, + outputDsl as selectedRowOutputDsl, +} from "./DSLs/SelectedRowBindingsDSLs"; +import { + tableV2DataJSModeInput, + tableV2DataJSModeOutput, +} from "./DSLs/TableDataJSModeDSLs"; +import { + badDsl, + fixedDsl, + inputDsl, + outputDsl, +} from "./DSLs/TableSanitizeColumnKeysDSLs"; +import { + tableV2SelectOptionInput, + tableV2SelectOptionOutput, +} from "./DSLs/TableV2SelectOptionDSLs"; +import { + inputDsl as updateHeaderOptionsInputDsl, + outputDsl as updateHeaderOptionsOutputDsl, +} from "./DSLs/UpdateHeaderOptionsDSLs"; + +describe("Table Widget Property Pane Upgrade", () => { + it("To test primaryColumns are created for a simple table", () => { + const newDsl = tableWidgetPropertyPaneMigrations(input1); + expect(JSON.stringify(newDsl) === JSON.stringify(output1)); + }); + it("To test columnActions are migrated derived primaryColumns", () => { + const newDsl = tableWidgetPropertyPaneMigrations(input2); + expect(JSON.stringify(newDsl) === JSON.stringify(output2)); + }); + it("To test table action are migrated", () => { + const newDsl = tableWidgetPropertyPaneMigrations(input3); + expect(JSON.stringify(newDsl) === JSON.stringify(output3)); + }); + + it("To test table parentRowSpace is updated", () => { + const newDsl = migrateTableWidgetParentRowSpaceProperty( + parentRowSpaceInputDsl, + ); + expect(JSON.stringify(newDsl) === JSON.stringify(parentRowSpaceOutputDsl)); + }); + + it("TableWidget : should update header options visibilities", () => { + const newDsl = migrateTableWidgetHeaderVisibilityProperties( + updateHeaderOptionsInputDsl, + ); + expect( + JSON.stringify(newDsl) === JSON.stringify(updateHeaderOptionsOutputDsl), + ); + }); +}); + +describe("Table Widget Migration - #migrateTableSanitizeColumnKeys", () => { + it("sanitizes primaryColumns, dynamicBindingPathList, columnOrder", () => { + const newDsl = migrateTableSanitizeColumnKeys(inputDsl); + const correctedDsl = migrateTableSanitizeColumnKeys(badDsl); + expect(newDsl).toStrictEqual(outputDsl); + expect(correctedDsl).toStrictEqual(fixedDsl); + }); +}); + +describe("Table Widget selectedRow bindings update", () => { + it("To test selectedRow bindings are updated for primaryColumns and derivedColumns", () => { + const newDsl = migrateTableWidgetSelectedRowBindings(selectedRowInputDsl); + expect(newDsl).toStrictEqual(selectedRowOutputDsl); + }); +}); + +describe("migrateTableWidgetV2ValidationBinding", () => { + it("should test that binding of isColumnEditableCellValid is getting updated", () => { + expect(migrateTableWidgetV2ValidationBinding(isEditableCellInput)).toEqual( + isEditableCellOutput, + ); + }); +}); + +describe("migrateTableWidgetV2SelectOption", () => { + it("should test that binding of selectOption is getting updated", () => { + expect(migrateTableWidgetV2SelectOption(tableV2SelectOptionInput)).toEqual( + tableV2SelectOptionOutput, + ); + }); +}); + +describe("migrateTableWidgetTableDataJsMode", () => { + it("should test that tableData js mode is enabled", () => { + expect(migrateTableWidgetTableDataJsMode(tableV2DataJSModeInput)).toEqual( + tableV2DataJSModeOutput, + ); + }); +}); + +describe("migrateTableWidgetV2CurrentRowInValidationsBinding", () => { + it("should test that tableData js mode is enabled", () => { + expect( + migrateTableWidgetV2CurrentRowInValidationsBinding( + currentRownInValidationsBindingInput, + ), + ).toEqual(currentRownInValidationsBindingOutput); + }); +}); diff --git a/app/client/src/ce/constants/messages.ts b/app/client/src/ce/constants/messages.ts index 7fce411506fe..7de903836a11 100644 --- a/app/client/src/ce/constants/messages.ts +++ b/app/client/src/ce/constants/messages.ts @@ -2500,3 +2500,5 @@ export const PAGE_ENTITY_NAME = "Page"; export const EMPTY_DATASOURCE_TOOLTIP_SIDEBUTTON = () => "Create a datasource to power your app with data."; + +export const FIELD_REQUIRED_MESSAGE = () => `This field is required`; diff --git a/app/client/src/components/propertyControls/TableInlineEditValidPropertyControl.tsx b/app/client/src/components/propertyControls/TableInlineEditValidPropertyControl.tsx index ea38a3c6fddd..804783445a72 100644 --- a/app/client/src/components/propertyControls/TableInlineEditValidPropertyControl.tsx +++ b/app/client/src/components/propertyControls/TableInlineEditValidPropertyControl.tsx @@ -28,7 +28,7 @@ const getBindingSuffix = (tableId: string, columnName: string) => { )) ( (${tableId}.isAddRowInProgress ? ${tableId}.newRow.${columnName} : ${tableId}.columnEditableCellValue.${columnName}) || "", - ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.index] || + ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.${ORIGINAL_INDEX_KEY}] || Object.keys(${tableId}.processedTableData[0]) .filter(key => ["${ORIGINAL_INDEX_KEY}", "${PRIMARY_COLUMN_KEY_VALUE}"].indexOf(key) === -1) .reduce((prev, curr) => { diff --git a/app/client/src/components/propertyControls/TableInlineEditValidationControl.tsx b/app/client/src/components/propertyControls/TableInlineEditValidationControl.tsx index 0205b0070c85..002b2aa710eb 100644 --- a/app/client/src/components/propertyControls/TableInlineEditValidationControl.tsx +++ b/app/client/src/components/propertyControls/TableInlineEditValidationControl.tsx @@ -113,7 +113,7 @@ const getBindingSuffix = (tableId: string) => { ( ${tableId}.isAddRowInProgress, ${tableId}.isAddRowInProgress ? -1 : ${tableId}.editableCell.index, - ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.index] || + ${tableId}.isAddRowInProgress ? ${tableId}.newRow : (${tableId}.processedTableData[${tableId}.editableCell.${ORIGINAL_INDEX_KEY}] || Object.keys(${tableId}.processedTableData[0]) .filter(key => ["${ORIGINAL_INDEX_KEY}", "${PRIMARY_COLUMN_KEY_VALUE}"].indexOf(key) === -1) .reduce((prev, curr) => { diff --git a/app/client/src/widgets/TableWidgetV2/constants.ts b/app/client/src/widgets/TableWidgetV2/constants.ts index 2537bc10fe65..0e066c83f9a9 100644 --- a/app/client/src/widgets/TableWidgetV2/constants.ts +++ b/app/client/src/widgets/TableWidgetV2/constants.ts @@ -21,6 +21,7 @@ export interface EditableCell { value: string | number | null; initialValue: string; inputValue: string; + [ORIGINAL_INDEX_KEY]: number; } export enum PaginationDirection { @@ -218,12 +219,13 @@ export enum DateInputFormat { MILLISECONDS = "Milliseconds", } -export const defaultEditableCell = { +export const defaultEditableCell: EditableCell = { column: "", index: -1, inputValue: "", value: "", initialValue: "", + [ORIGINAL_INDEX_KEY]: -1, }; export const DEFAULT_COLUMN_NAME = "Table Column"; diff --git a/app/client/src/widgets/TableWidgetV2/widget/index.tsx b/app/client/src/widgets/TableWidgetV2/widget/index.tsx index 0e85883a653f..09f45d48be86 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/index.tsx +++ b/app/client/src/widgets/TableWidgetV2/widget/index.tsx @@ -2591,6 +2591,7 @@ class TableWidgetV2 extends BaseWidget { // To revert back to previous on discard initialValue: value, inputValue: value, + __originalIndex__: this.getRowOriginalIndex(rowIndex), }); pushBatchMetaUpdates("columnEditableCellValue", { ...this.props.columnEditableCellValue, From cd80904369bdb68e79fa75a6114d442bd5bfe7fd Mon Sep 17 00:00:00 2001 From: Sagar Khalasi Date: Tue, 20 Aug 2024 16:49:13 +0530 Subject: [PATCH 2/7] chore: Run a local server with docker compose while running from yarn setup (#35636) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description As a user, I want to run my backend server in local machine for running cypress test cases. Fixes #`35635` ## Automation /ok-to-test tags="@tag.Sanity" ### :mag: Cypress test results > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: 33c2dbbcf389a6840830e8914738a068d8ab41d9 > Cypress dashboard. > Tags: `@tag.Sanity` > Spec: >
Tue, 20 Aug 2024 10:54:22 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No Screenshot 2024-08-12 at 10 12 04 PM Screenshot 2024-08-12 at 10 12 10 PM Screenshot 2024-08-12 at 10 13 03 PM Screenshot 2024-08-12 at 10 13 10 PM Screenshot 2024-08-12 at 10 14 11 PM ## Summary by CodeRabbit - **New Features** - Introduced a new function to manage local server setup using Docker Compose, enhancing the setup process. - Added user prompts to guide decisions regarding local server setup. - **Improvements** - Implemented a retry mechanism to check Docker services, improving reliability during setup. - Enhanced error handling to provide clear feedback when setup conditions are not met. - **Refactor** - Integrated new functionalities into the existing setup process for a smoother user experience. --- .../cypress/scripts/cypress-local-setup.js | 99 ++++++++++++++++++- 1 file changed, 95 insertions(+), 4 deletions(-) diff --git a/app/client/cypress/scripts/cypress-local-setup.js b/app/client/cypress/scripts/cypress-local-setup.js index 72c6a4737077..e8424e083426 100644 --- a/app/client/cypress/scripts/cypress-local-setup.js +++ b/app/client/cypress/scripts/cypress-local-setup.js @@ -1,13 +1,12 @@ -const { execSync } = require("child_process"); +const { exec, execSync } = require("child_process"); const { existsSync, readFileSync, writeFileSync } = require("fs"); const path = require("path"); const prompt = require("prompt-sync")(); -// Function to check if a Docker container is running function isContainerRunning(containerName) { try { const output = execSync( - `docker ps --format '{{.Names}}' | grep -w "${containerName}"`, + `docker ps --filter "name=^/${containerName}$" --format '{{.Names}}'`, ); return output.length > 0; } catch (error) { @@ -15,6 +14,98 @@ function isContainerRunning(containerName) { } } +// Helper function to execute commands and return a Promise +async function execCommand(command, options) { + return new Promise((resolve, reject) => { + exec(command, options, (error, stdout, stderr) => { + if (error) { + reject(error); + } else { + resolve({ stdout, stderr }); + } + }); + }); +} + +function checkDockerCompose() { + try { + execSync("docker-compose --version", { stdio: "ignore" }); + return true; + } catch (error) { + console.error( + "ERROR: docker-compose is not installed. Please install Docker Compose.", + ); + process.exit(1); + } +} + +async function runLocalServer() { + try { + let user_input = prompt( + `Do you wish to continue without setting up the local server with docker? (yes/no): `, + ); + user_input = (user_input || "").trim().toLowerCase(); + + if (user_input === "yes" || user_input === "y") { + console.log( + "INFO", + "Continuing without setting up local backend docker based server.", + ); + } else { + // Adjust the path to point to the correct directory + const dockerDir = path.join(__dirname, "../../../../deploy/docker"); + + if (!existsSync(dockerDir)) { + console.error(`ERROR: Directory ${dockerDir} does not exist.`); + process.exit(1); // Exit if the directory is missing + } + + await checkDockerCompose(); // Ensure Docker Compose is available + + console.log("INFO: Starting local server using Docker Compose..."); + execSync(`cd ${dockerDir} && pwd && docker-compose up -d`, { + stdio: "inherit", + }); + + // Wait for the services to be fully up and running + let servicesRunning = false; + const maxRetries = 30; + const retryInterval = 7000; // 7 seconds + + for (let attempt = 1; attempt <= maxRetries; attempt++) { + try { + const { stdout } = await execCommand("docker-compose ps", { + cwd: dockerDir, + }); + if (stdout.includes("Up")) { + servicesRunning = true; + break; + } + } catch (error) { + console.error("ERROR: Error checking service status:", error.message); + process.exit(1); // Exit if checking service status fails + } + console.log( + `INFO: Waiting for services to be fully up and running... (attempt ${attempt}/${maxRetries})`, + ); + await new Promise((resolve) => setTimeout(resolve, retryInterval)); + } + if (servicesRunning) { + console.log("INFO: Local server is up and running."); + return true; + } else { + console.error( + "ERROR: Services did not become available within the expected time.", + ); + process.exit(1); // Exit if services are not up + } + } + } catch (error) { + console.error("ERROR: Error starting local server:", error.message); + process.exit(1); // Exit if starting local server fails + } +} + function ensureTEDIsRunning() { // Check if TED is running. If not, then ask user if they wish to pull and run the TED container const isTedRunning = isContainerRunning("ted"); @@ -147,7 +238,7 @@ async function setupCypress() { // Get the baseUrl from cypress.config.ts file let repoRoot = path.join(__dirname, "..", ".."); let baseUrl = getBaseUrl(repoRoot); - + await runLocalServer(); await checkIfAppsmithIsRunning(baseUrl); // Install Cypress using yarn install on the app/client repository From de8caad9991bb99c4110e2c3cd172f4e78c1ff18 Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:41:03 +0530 Subject: [PATCH 3/7] feat: Updates for accounting Section and Zone changes (#35753) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description This PR have following fixes and updates, 1. Changed renderEachConfigV2 to accommodate SECTION_V2, SINGLE_COLUMN_ZONE, and DOUBLE_COLUMN_ZONE. 2. Added classes to form render components to handle parallel use of old config and new config. 3. Updated Section and Zone component CSS to use nested structure. 4. Fixed the height difference between label with JS toggle and without JS toggle. Fixes #35544 ## Automation /ok-to-test tags="@tag.All" ### :mag: Cypress test results > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: 3dcc0df29aaffb0e2470e1561fb996fde3fc4837 > Cypress dashboard. > Tags: `@tag.All` > Spec: >
Mon, 19 Aug 2024 16:10:09 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No ## Summary by CodeRabbit - **New Features** - Improved styling for toggle buttons and dropdowns for a better user experience. - Enhanced layout adaptability through updated class names and properties across various components. - Introduced a new function for more efficient rendering of form sections and nested components. - **Bug Fixes** - Addressed potential layout shifts and visual inconsistencies by enforcing minimum heights on key components. - **Documentation** - Updated CSS selectors for better readability and maintainability without altering existing functionalities. --- .../form/ToggleComponentToJson.tsx | 2 +- .../formControls/DropDownControl.tsx | 2 +- .../formControls/FieldArrayControl.tsx | 2 +- .../formControls/InputTextControl.tsx | 1 + .../ActionForm/Section/styles.module.css | 13 +++-- .../pages/Editor/ActionForm/Zone/index.tsx | 4 +- .../Editor/ActionForm/Zone/styles.module.css | 51 ++++++++++++++++--- app/client/src/pages/Editor/FormConfig.tsx | 1 + .../pages/Editor/QueryEditor/FormRender.tsx | 49 ++++++++++++++---- 9 files changed, 95 insertions(+), 30 deletions(-) diff --git a/app/client/src/components/editorComponents/form/ToggleComponentToJson.tsx b/app/client/src/components/editorComponents/form/ToggleComponentToJson.tsx index def220df07af..9a0b3cea4b21 100644 --- a/app/client/src/components/editorComponents/form/ToggleComponentToJson.tsx +++ b/app/client/src/components/editorComponents/form/ToggleComponentToJson.tsx @@ -76,7 +76,7 @@ function ToggleComponentToJsonHandler(props: HandlerProps) { content={!!configPropertyPathJsonValue && JS_TOGGLE_DISABLED_MESSAGE} isDisabled={!configPropertyPathJsonValue} > - + { return ( 0 && props.fields.map((field: string, index: number) => { return ( - + {/* TODO: Fix this the next time the file is edited */} {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */} {props.schema.map((sch: any, idx: number) => { diff --git a/app/client/src/components/formControls/InputTextControl.tsx b/app/client/src/components/formControls/InputTextControl.tsx index 9443cd4a397d..cc352a1e5ffc 100644 --- a/app/client/src/components/formControls/InputTextControl.tsx +++ b/app/client/src/components/formControls/InputTextControl.tsx @@ -144,6 +144,7 @@ class InputTextControl extends BaseControl { return ( = ({ children, layout = "single-column" }) => { +const Zone: React.FC = ({ children, layout = "single_column" }) => { return (
{children} diff --git a/app/client/src/pages/Editor/ActionForm/Zone/styles.module.css b/app/client/src/pages/Editor/ActionForm/Zone/styles.module.css index 144ea7040372..6b04213740de 100644 --- a/app/client/src/pages/Editor/ActionForm/Zone/styles.module.css +++ b/app/client/src/pages/Editor/ActionForm/Zone/styles.module.css @@ -3,18 +3,55 @@ gap: var(--ads-v2-spaces-4); width: 100%; box-sizing: border-box; -} -.zone[data-layout="double-column"] { - grid-template-columns: repeat(2, minmax(260px, 1fr)); -} + &[data-layout="double_column"] { + grid-template-columns: repeat(2, minmax(260px, 1fr)); + } -.zone[data-layout="single-column"] { - grid-template-columns: 1fr; + &[data-layout="single_column"] { + grid-template-columns: 1fr; + } + + /* + This section can be removed once the condition abouve each is resolved + */ + /* 1. Margin is removed from FieldWrapper component in FormRender file */ + & :global(.uqi-form-wrapper) { + margin: 0; + } + /* DropdownControl default width is removed */ + & :global(.uqi-dropdown-select) { + width: unset !important; + } + /* InputTexctControl min,max and width removed */ + & :global(.uqi-input-text) { + width: unset !important; + min-width: unset !important; + max-width: unset !important; + } + /* FieldArrayControl hardcoded width is removed */ + & :global(.t--form-control-ARRAY_FIELD) { + & :global(.t--form-control-QUERY_DYNAMIC_INPUT_TEXT) > div { + width: unset !important; + } + + & > div { + width: 100% !important; + + & > :global(.array-control-secondary-box) { + width: 100% !important; + + & > div { + flex: 1; + } + } + } + } + /* Removable section ends here */ } @container uqi-section (max-width: 531px) { - .zone[data-layout="double-column"] { + .zone[data-layout="double_column"] { grid-template-columns: 1fr; } } diff --git a/app/client/src/pages/Editor/FormConfig.tsx b/app/client/src/pages/Editor/FormConfig.tsx index a4529dbaff1b..f6385ec64f5b 100644 --- a/app/client/src/pages/Editor/FormConfig.tsx +++ b/app/client/src/pages/Editor/FormConfig.tsx @@ -29,6 +29,7 @@ const FlexWrapper = styled.div` display: flex; width: fit-content; margin-right: 5px; + min-height: 21px; & .t--js-toggle { margin-bottom: 0px; diff --git a/app/client/src/pages/Editor/QueryEditor/FormRender.tsx b/app/client/src/pages/Editor/QueryEditor/FormRender.tsx index f45e305da3e7..daeb376e171e 100644 --- a/app/client/src/pages/Editor/QueryEditor/FormRender.tsx +++ b/app/client/src/pages/Editor/QueryEditor/FormRender.tsx @@ -24,6 +24,7 @@ import FormControl from "../FormControl"; import type { ControlProps } from "components/formControls/BaseControl"; import { Spinner } from "@appsmith/ads"; import type { QueryAction, SaaSAction } from "entities/Action"; +import { Section, Zone } from "../ActionForm"; interface Props { // TODO: Fix this the next time the file is edited @@ -154,21 +155,18 @@ const FormRender = (props: Props) => { } if (section.hasOwnProperty("controlType")) { // If component is type section, render it's children - if ( - section.controlType === "SECTION" && - section.hasOwnProperty("children") - ) { - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return section.children.map((section: any, idx: number) => { - return renderEachConfigV2(formName, section, idx); - }); + if (Object.hasOwn(section, "children")) { + return rederNodeWithChildren(section, formName); } try { const { configProperty } = section; const modifiedSection = modifySectionConfig(section, enabled); return ( - + // TODO: Remove classname once action redesign epic is done + ); @@ -185,6 +183,32 @@ const FormRender = (props: Props) => { return null; }; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const rederNodeWithChildren = (section: any, formName: string) => { + if (!Object.hasOwn(section, "children")) return; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const children = section.children.map((section: any, idx: number) => + renderEachConfigV2(formName, section, idx), + ); + + switch (section.controlType) { + case "SECTION_V2": + return
{children}
; + + case "SINGLE_COLUMN_ZONE": + case "DOUBLE_COLUMN_ZONE": { + const layout = + section.controlType === "SINGLE_COLUMN_ZONE" + ? "single_column" + : "double_column"; + return {children}; + } + default: + return children; + } + }; + // Recursive call to render forms pre UQI const renderEachConfig = (formName: string) => @@ -200,7 +224,10 @@ const FormRender = (props: Props) => { try { const { configProperty } = formControlOrSection; return ( - + Date: Tue, 20 Aug 2024 18:36:32 +0530 Subject: [PATCH 4/7] chore: Add cleanup and update stage for tenant at the server restart (#35786) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description PR to add the cleanup and update default tenant at the server restart. This was required because whenever we update tenant via migrations the result gets reverted because the cached tenant is not getting updated as we generally end up updating only the MongoDB state and not the cached entry. /test Sanity ### :mag: Cypress test results > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: e288cfe1084bdbf2104a656bf60eb9c24708fe77 > Cypress dashboard. > Tags: `@tag.Sanity` > Spec: >
Tue, 20 Aug 2024 13:01:42 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No ## Summary by CodeRabbit - **New Features** - Implemented a mechanism to refresh tenant policies and manage cache cleanup during server restarts, ensuring accurate policy enforcement for multi-tenant applications. --- .../server/configurations/TenantConfig.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/TenantConfig.java diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/TenantConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/TenantConfig.java new file mode 100644 index 000000000000..544430ca03ca --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/TenantConfig.java @@ -0,0 +1,45 @@ +package com.appsmith.server.configurations; + +import com.appsmith.server.constants.FieldName; +import com.appsmith.server.domains.Tenant; +import com.appsmith.server.helpers.CollectionUtils; +import com.appsmith.server.repositories.CacheableRepositoryHelper; +import com.appsmith.server.repositories.TenantRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.context.event.ApplicationStartedEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Configuration; +import reactor.core.publisher.Mono; + +import static com.appsmith.external.models.BaseDomain.policySetToMap; + +@Configuration +@RequiredArgsConstructor +@Slf4j +public class TenantConfig implements ApplicationListener { + + private final TenantRepository tenantRepository; + private final CacheableRepositoryHelper cachableRepositoryHelper; + + // Method to cleanup the cache and update the default tenant policies if the policyMap is empty. This will make sure + // cache will be updated if we update the tenant via startup DB migrations. + // As we have mocked the TenantService in the tests, we had to manually evict the cache and save the object to DB + private Mono cleanupAndUpdateRefreshDefaultTenantPolicies() { + log.debug("Cleaning up and updating default tenant policies on server startup"); + return tenantRepository.findBySlug(FieldName.DEFAULT).flatMap(tenant -> { + if (CollectionUtils.isNullOrEmpty(tenant.getPolicyMap())) { + tenant.setPolicyMap(policySetToMap(tenant.getPolicies())); + return cachableRepositoryHelper + .evictCachedTenant(tenant.getId()) + .then(tenantRepository.save(tenant)); + } + return Mono.just(tenant); + }); + } + + @Override + public void onApplicationEvent(ApplicationStartedEvent event) { + cleanupAndUpdateRefreshDefaultTenantPolicies().block(); + } +} From 94a732b37a11e84d966cefab8e66c92d7a8f8095 Mon Sep 17 00:00:00 2001 From: Abhijeet <41686026+abhvsn@users.noreply.github.com> Date: Tue, 20 Aug 2024 20:50:33 +0530 Subject: [PATCH 5/7] chore: Add adhoc image builder (#35791) --- .github/workflows/ad-hoc-docker-image.yml | 113 ++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 .github/workflows/ad-hoc-docker-image.yml diff --git a/.github/workflows/ad-hoc-docker-image.yml b/.github/workflows/ad-hoc-docker-image.yml new file mode 100644 index 000000000000..38afa93839ae --- /dev/null +++ b/.github/workflows/ad-hoc-docker-image.yml @@ -0,0 +1,113 @@ +name: Ad-hoc Docker Image + +on: + # This line enables manual triggering of this workflow. + workflow_dispatch: + inputs: + branch: + description: Branch to build image out of + required: false + type: string + default: master + tag: + description: Tag to use for image + required: false + type: string + default: ad-hoc + +jobs: + server-build: + name: server-build + uses: ./.github/workflows/server-build.yml + secrets: inherit + with: + branch: ${{ inputs.branch }} + skip-tests: true + + client-build: + name: client-build + uses: ./.github/workflows/client-build.yml + secrets: inherit + with: + branch: ${{ inputs.branch }} + + rts-build: + name: rts-build + uses: ./.github/workflows/rts-build.yml + secrets: inherit + with: + branch: ${{ inputs.branch }} + + package: + needs: [server-build, client-build, rts-build] + runs-on: ubuntu-latest + # Set permissions since we're using OIDC token authentication between Depot and GitHub + permissions: + contents: read + id-token: write + + steps: + # Check out the specified branch in case this workflow is called by another workflow + - name: Checkout the specified branch + uses: actions/checkout@v4 + with: + fetch-tags: true + ref: ${{ inputs.branch }} + + - name: Download the react build artifact + uses: actions/download-artifact@v4 + with: + name: client-build + path: app/client + + - name: Unpack the client build artifact + if: steps.run_result.outputs.run_result != 'success' + run: | + mkdir -p app/client/build + tar -xvf app/client/build.tar -C app/client/build + + - name: Download the server build artifact + uses: actions/download-artifact@v4 + with: + name: server-build + path: app/server/dist + + - name: Download the rts build artifact + uses: actions/download-artifact@v4 + with: + name: rts-dist + path: app/client/packages/rts/dist + + - name: Untar the rts folder + run: | + tar -xvf app/client/packages/rts/dist/rts-dist.tar -C app/client/packages/rts/ + echo "Cleaning up the tar files" + rm app/client/packages/rts/dist/rts-dist.tar + + - name: Generate info.json + run: | + if [[ -f scripts/generate_info_json.sh ]]; then + scripts/generate_info_json.sh + fi + + - name: Set up Depot CLI + uses: depot/setup-action@v1 + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + - name: Build and push environment specific image to Docker Hub + if: success() + uses: depot/build-push-action@v1 + with: + context: . + push: true + platforms: linux/arm64,linux/amd64 + build-args: | + APPSMITH_SEGMENT_CE_KEY=${{ secrets.APPSMITH_SEGMENT_CE_KEY }} + BASE=${{ vars.DOCKER_HUB_ORGANIZATION }}/base-${{ vars.EDITION }}:nightly + tags: | + ${{ vars.DOCKER_HUB_ORGANIZATION }}/appsmith-${{ vars.EDITION }}:${{ inputs.tag }} From 52681647760a7da48fab52bca58f66745ce2bacc Mon Sep 17 00:00:00 2001 From: Apeksha Bhosale <7846888+ApekshaBhosale@users.noreply.github.com> Date: Wed, 21 Aug 2024 11:43:40 +0530 Subject: [PATCH 6/7] chore: preStop scripts (#35785) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description > [!TIP] > _Add a TL;DR when the description is longer than 500 words or extremely technical (helps the content, marketing, and DevRel team)._ > > _Please also include relevant motivation and context. List any dependencies that are required for this change. Add links to Notion, Figma or any other documents that might be relevant to the PR._ Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!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.Sanity" ### :mag: Cypress test results > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: c23bd2ad01d0a8ce214762ddea7ed71e6d4a758e > Cypress dashboard. > Tags: `@tag.Sanity` > Spec: >
Wed, 21 Aug 2024 06:05:39 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit - **New Features** - Introduced scripts for capturing heap and thread dumps in Docker environments to enhance troubleshooting capabilities for Java applications. - **Improvements** - Updated thread dump scripts to allow users to specify dump locations, improving flexibility for diagnostic data management. - Enhanced file path organization for generated profile files, making retrieval easier. - **Chores** - Implemented error handling and directory creation for storing dumps to ensure robust operation. --- deploy/docker/fs/opt/appsmith/record-heap-dump.sh | 12 ++++++++++-- deploy/docker/fs/opt/appsmith/record-thread-dump.sh | 12 ++++++++++-- .../docker/fs/opt/appsmith/thread-profile-start.sh | 4 ++-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/deploy/docker/fs/opt/appsmith/record-heap-dump.sh b/deploy/docker/fs/opt/appsmith/record-heap-dump.sh index 4148a1c45ac4..853f20a683c9 100755 --- a/deploy/docker/fs/opt/appsmith/record-heap-dump.sh +++ b/deploy/docker/fs/opt/appsmith/record-heap-dump.sh @@ -5,6 +5,14 @@ set -o pipefail set -o nounset set -o noglob -location=/appsmith-stacks/heap_dumps/ad-hoc/$(date "+%Y_%m_%d_%H_%S")/heap-profile; +arg=${1:-} + +# Set the location based on the argument +if [ "$arg" == "preStop" ]; then + location=/appsmith-stacks/heap_dumps/processdumps/${HOSTNAME}/$(date "+%Y_%m_%d_%H_%S"); +else + location=/appsmith-stacks/heap_dumps/ad-hoc/${HOSTNAME}/heap-profile/$(date "+%Y_%m_%d_%H_%S"); +fi + mkdir -p $location; -jcmd $(pgrep -f -- "-jar\sserver.jar") GC.heap_dump filename=$location/${HOSTNAME}.log \ No newline at end of file +jcmd $(pgrep -f -- "-jar\sserver.jar") GC.heap_dump $location.log \ No newline at end of file diff --git a/deploy/docker/fs/opt/appsmith/record-thread-dump.sh b/deploy/docker/fs/opt/appsmith/record-thread-dump.sh index 0b44d56d9474..934b7dc84554 100755 --- a/deploy/docker/fs/opt/appsmith/record-thread-dump.sh +++ b/deploy/docker/fs/opt/appsmith/record-thread-dump.sh @@ -5,6 +5,14 @@ set -o pipefail set -o nounset set -o noglob -location=/appsmith-stacks/heap_dumps/ad-hoc/$(date "+%Y_%m_%d_%H_%S")/thread-profile; +arg=${1:-} + +# Set the location based on the argument +if [ "$arg" == "preStop" ]; then + location=/appsmith-stacks/heap_dumps/preStop/${HOSTNAME}/$(date "+%Y_%m_%d_%H_%S"); +else + location=/appsmith-stacks/heap_dumps/ad-hoc/${HOSTNAME}/thread-profile/$(date "+%Y_%m_%d_%H_%S"); +fi + mkdir -p $location; -jcmd $(pgrep -f -- "-jar\sserver.jar") Thread.print > $location/trace-${HOSTNAME}.log \ No newline at end of file +jstack $(pgrep -f -- "-jar\sserver.jar") > $location.log diff --git a/deploy/docker/fs/opt/appsmith/thread-profile-start.sh b/deploy/docker/fs/opt/appsmith/thread-profile-start.sh index f7aed6c2c4c6..cefeeba53e8c 100755 --- a/deploy/docker/fs/opt/appsmith/thread-profile-start.sh +++ b/deploy/docker/fs/opt/appsmith/thread-profile-start.sh @@ -5,6 +5,6 @@ set -o pipefail set -o nounset set -o noglob -location=/appsmith-stacks/heap_dumps/ad-hoc/$(date "+%Y_%m_%d_%H_%S")/thread-profile; +location=/appsmith-stacks/heap_dumps/ad-hoc/${HOSTNAME}/thread-profile/profile-$(date "+%Y_%m_%d_%H_%S"); mkdir -p $location; -jcmd $(pgrep -f -- "-jar\sserver.jar") JFR.start name=profile filename=$location/profile-${HOSTNAME}.jfr \ No newline at end of file +jcmd $(pgrep -f -- "-jar\sserver.jar") JFR.start name=profile filename=$location.jfr \ No newline at end of file From 3e38ae59d21ae39f8d040d4e6b785e7ed1b1e54c Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Wed, 21 Aug 2024 14:16:07 +0530 Subject: [PATCH 7/7] chore: Do not mark User testing PRs as stale (#35806) ## Description Adds a new exception on the stale check workflow. If the PR has the flag of "User Testing", it will not mark it as stale. > [!WARNING] > Tests have not run on the HEAD f27d4ceaf7b36227481c8a11a882c5d5c9fe07ea yet >
Wed, 21 Aug 2024 08:34:31 UTC ## Summary by CodeRabbit - **New Features** - Added the `User Testing` label to the list of exempt labels, preventing pull requests in user testing from being closed due to inactivity. This enhances workflow management for extended reviews or testing periods. --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 0ca30d865c40..fb759fd9a7f2 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -24,6 +24,6 @@ jobs: close-issue-message: 'This issue has been closed because of inactivity.' close-pr-message: 'This PR has been closed because of inactivity.' only-issue-labels: 'Critical' - exempt-pr-labels: 'Dont merge,WIP' + exempt-pr-labels: 'Dont merge,WIP,User Testing'