feat: dsl migration with server (#28518)
## Description 1. Shifts DSL migration logic to @shared/dsl 2. Exposes /migrate/dsl endpoint on rts 3. Integrates RTS endpoint to backend for serving migrated pages 4. Introduces feature flag to switch between client-based and server-based on-demand migration #### PR fixes following issue(s) Fixes #26783, #26784, #26980 #### Type of change - New feature (non-breaking change which adds functionality) ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [x] Manual - [ ] JUnit - [x] Jest - [x] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed --------- Co-authored-by: Nayan <nayan@appsmith.com>
This commit is contained in:
parent
e018db8ec7
commit
71d67185c4
|
|
@ -116,8 +116,10 @@ app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitCloudSer
|
||||||
app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitDeployKeyGenerator.java @AnaghHegde @nayan-rafiq
|
app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitDeployKeyGenerator.java @AnaghHegde @nayan-rafiq
|
||||||
app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitFileUtils.java @AnaghHegde @nayan-rafiq
|
app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitFileUtils.java @AnaghHegde @nayan-rafiq
|
||||||
app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitUtils.java @AnaghHegde @nayan-rafiq
|
app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/GitUtils.java @AnaghHegde @nayan-rafiq
|
||||||
|
app/client/src/pages/Editor/gitSync/* @brayn003
|
||||||
|
|
||||||
|
# DSL Package
|
||||||
|
app/client/packages/dsl/* @brayn003
|
||||||
|
|
||||||
# Data Platform
|
# Data Platform
|
||||||
|
|
||||||
|
|
@ -215,7 +217,7 @@ app/client/cypress/e2e/Regression/ClientSide/Github/**/* @ankitakinger
|
||||||
app/client/cypress/e2e/Regression/ClientSide/FormLogin/**/* @ankitakinger
|
app/client/cypress/e2e/Regression/ClientSide/FormLogin/**/* @ankitakinger
|
||||||
app/client/cypress/e2e/Regression/ClientSide/Auditlogs/**/* @ankitakinger
|
app/client/cypress/e2e/Regression/ClientSide/Auditlogs/**/* @ankitakinger
|
||||||
|
|
||||||
#FE pod
|
# FE pod
|
||||||
app/client/src/actions/evaluationActions.ts @ApekshaBhosale
|
app/client/src/actions/evaluationActions.ts @ApekshaBhosale
|
||||||
app/client/src/ce/entities/DataTree/**/* @ApekshaBhosale
|
app/client/src/ce/entities/DataTree/**/* @ApekshaBhosale
|
||||||
app/client/src/ce/entities/DependencyMap/**/* @ApekshaBhosale
|
app/client/src/ce/entities/DependencyMap/**/* @ApekshaBhosale
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ describe("Check debugger logs state when there are onPageLoad actions", function
|
||||||
|
|
||||||
it("1. Check debugger logs state when there are onPageLoad actions", function () {
|
it("1. Check debugger logs state when there are onPageLoad actions", function () {
|
||||||
EditorNavigation.SelectEntityByName("Table1", EntityType.Widget);
|
EditorNavigation.SelectEntityByName("Table1", EntityType.Widget);
|
||||||
propPane.UpdatePropertyFieldValue("Table data", "{{TestApi.data.users}}");
|
|
||||||
apiPage.CreateAndFillApi(testdata.baseUrl + testdata.methods, "TestApi");
|
apiPage.CreateAndFillApi(testdata.baseUrl + testdata.methods, "TestApi");
|
||||||
apiPage.RunAPI();
|
apiPage.RunAPI();
|
||||||
agHelper.GetNClick(explorer.addWidget);
|
agHelper.GetNClick(explorer.addWidget);
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,6 @@ describe("Input widget test with default value from chart datapoint", () => {
|
||||||
|
|
||||||
it("2. onDataPointClick should work and respond with x, y, seriesTitle, and rawEventData (in case of custom fusion chart).", () => {
|
it("2. onDataPointClick should work and respond with x, y, seriesTitle, and rawEventData (in case of custom fusion chart).", () => {
|
||||||
agHelper.AddDsl("chartCustomSankeyDataDsl");
|
agHelper.AddDsl("chartCustomSankeyDataDsl");
|
||||||
assertHelper.AssertNetworkStatus("@updateLayout");
|
|
||||||
EditorNavigation.SelectEntityByName("Chart1", EntityType.Widget);
|
EditorNavigation.SelectEntityByName("Chart1", EntityType.Widget);
|
||||||
agHelper.Sleep(1500); //waiting for chart to load!
|
agHelper.Sleep(1500); //waiting for chart to load!
|
||||||
propPane.SelectPlatformFunction("onDataPointClick", "Show alert");
|
propPane.SelectPlatformFunction("onDataPointClick", "Show alert");
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,6 @@ describe("DatePicker Widget Property pane tests with js bindings", function () {
|
||||||
EditorNavigation.SelectEntityByName("DatePicker1", EntityType.Widget);
|
EditorNavigation.SelectEntityByName("DatePicker1", EntityType.Widget);
|
||||||
_.propPane.EnterJSContext("Min Date", "2021-01-01");
|
_.propPane.EnterJSContext("Min Date", "2021-01-01");
|
||||||
_.propPane.EnterJSContext("Max Date", "2021-10-10");
|
_.propPane.EnterJSContext("Max Date", "2021-10-10");
|
||||||
_.propPane.EnterJSContext("Default Date", "");
|
|
||||||
cy.selectDateFormat("DD/MM/YYYY HH:mm");
|
cy.selectDateFormat("DD/MM/YYYY HH:mm");
|
||||||
_.propPane.EnterJSContext(
|
_.propPane.EnterJSContext(
|
||||||
"Default Date",
|
"Default Date",
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,6 @@ describe("Form data", function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("CheckboxGroupWidget, MultiSelectTreeWidget, MultiSelectWidgetV2, SelectWidget, SingleSelectTreeWidget, SwitchGroupWidget, PhoneInputWidget, InputWidgetV2 and CurrencyInputWidget should have value props of which values are not null or undefined to be included as a form data", function () {
|
it("CheckboxGroupWidget, MultiSelectTreeWidget, MultiSelectWidgetV2, SelectWidget, SingleSelectTreeWidget, SwitchGroupWidget, PhoneInputWidget, InputWidgetV2 and CurrencyInputWidget should have value props of which values are not null or undefined to be included as a form data", function () {
|
||||||
cy.wait("@updateLayout").should(
|
|
||||||
"have.nested.property",
|
|
||||||
"response.body.responseMeta.status",
|
|
||||||
200,
|
|
||||||
);
|
|
||||||
// Check form data
|
// Check form data
|
||||||
cy.get("[data-testid='container-wrapper-vannrar7rd'] span")
|
cy.get("[data-testid='container-wrapper-vannrar7rd'] span")
|
||||||
.should("exist")
|
.should("exist")
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ describe("Table Widget Filtered Table data in autocomplete", function () {
|
||||||
|
|
||||||
it("Table Widget Functionality To Filter and search data", function () {
|
it("Table Widget Functionality To Filter and search data", function () {
|
||||||
cy.openPropertyPane("tablewidget");
|
cy.openPropertyPane("tablewidget");
|
||||||
cy.wait("@updateLayout");
|
|
||||||
cy.get(publish.searchInput).first().type("query");
|
cy.get(publish.searchInput).first().type("query");
|
||||||
cy.get(publish.filterBtn).click();
|
cy.get(publish.filterBtn).click();
|
||||||
cy.get(publish.attributeDropdown).click();
|
cy.get(publish.attributeDropdown).click();
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ describe("Basic flow ", () => {
|
||||||
cy.get(".t--property-control-allowaddingarow").should("exist");
|
cy.get(".t--property-control-allowaddingarow").should("exist");
|
||||||
cy.get(".t--property-control-allowaddingarow input").should("exist");
|
cy.get(".t--property-control-allowaddingarow input").should("exist");
|
||||||
cy.get(".t--add-new-row").should("not.exist");
|
cy.get(".t--add-new-row").should("not.exist");
|
||||||
_.propPane.TogglePropertyState("Allow adding a row", "Off");
|
_.propPane.TogglePropertyState("Allow adding a row", "Off", null);
|
||||||
cy.get(".t--add-new-row").should("not.exist");
|
cy.get(".t--add-new-row").should("not.exist");
|
||||||
cy.get(".t--property-control-onsave").should("not.exist");
|
cy.get(".t--property-control-onsave").should("not.exist");
|
||||||
cy.get(".t--property-control-ondiscard").should("not.exist");
|
cy.get(".t--property-control-ondiscard").should("not.exist");
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ describe("Table Widget V2 Filtered Table data in autocomplete", function () {
|
||||||
before("Table Widget V2 Functionality", () => {
|
before("Table Widget V2 Functionality", () => {
|
||||||
_.agHelper.AddDsl("tableV2AndTextDsl");
|
_.agHelper.AddDsl("tableV2AndTextDsl");
|
||||||
cy.openPropertyPane("tablewidgetv2");
|
cy.openPropertyPane("tablewidgetv2");
|
||||||
cy.wait("@updateLayout");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("1. Table Widget V2 Functionality To Filter and search data", function () {
|
it("1. Table Widget V2 Functionality To Filter and search data", function () {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
{
|
{
|
||||||
"extends": ["../../.eslintrc.base.json"],
|
"extends": ["../../.eslintrc.base.json"],
|
||||||
"ignorePatterns": ["build"]
|
"ignorePatterns": ["build"],
|
||||||
|
"rules": {
|
||||||
|
"@typescript-eslint/strict-boolean-expressions": "off",
|
||||||
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
"@typescript-eslint/prefer-nullish-coalescing": "off"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
"typescript": "4.5.5"
|
"typescript": "4.5.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@rollup/plugin-json": "^6.0.0",
|
||||||
"jest": "^29.5.0",
|
"jest": "^29.5.0",
|
||||||
"ts-jest": "^29.1.0"
|
"ts-jest": "^29.1.0"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import commonjs from "@rollup/plugin-commonjs";
|
||||||
import typescript from "rollup-plugin-typescript2";
|
import typescript from "rollup-plugin-typescript2";
|
||||||
import generatePackageJson from "rollup-plugin-generate-package-json";
|
import generatePackageJson from "rollup-plugin-generate-package-json";
|
||||||
import packageJson from "./package.json";
|
import packageJson from "./package.json";
|
||||||
|
import json from "@rollup/plugin-json";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// TODO: Figure out regex where each directory can be a separate module without having to manually add them
|
// TODO: Figure out regex where each directory can be a separate module without having to manually add them
|
||||||
|
|
@ -25,6 +26,7 @@ export default {
|
||||||
typescript({
|
typescript({
|
||||||
useTsconfigDeclarationDir: true,
|
useTsconfigDeclarationDir: true,
|
||||||
}),
|
}),
|
||||||
|
json(),
|
||||||
generatePackageJson({
|
generatePackageJson({
|
||||||
baseContents: (pkg) => ({
|
baseContents: (pkg) => ({
|
||||||
...pkg,
|
...pkg,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
export { nestDSL, flattenDSL } from "./DSL";
|
export { nestDSL, flattenDSL, ROOT_CONTAINER_WIDGET_ID } from "./transform";
|
||||||
export { ROOT_CONTAINER_WIDGET_ID } from "./constants";
|
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
NestedDSLWidget,
|
NestedDSLWidget,
|
||||||
|
|
@ -7,4 +6,8 @@ export type {
|
||||||
FlattenedDSLWidget,
|
FlattenedDSLWidget,
|
||||||
FlattenedDSL,
|
FlattenedDSL,
|
||||||
FlattenedDSLEntities,
|
FlattenedDSLEntities,
|
||||||
} from "./DSL";
|
} from "./transform";
|
||||||
|
|
||||||
|
export { migrateDSL, LATEST_DSL_VERSION } from "./migrate";
|
||||||
|
|
||||||
|
export type { DSLWidget } from "./migrate/types";
|
||||||
|
|
|
||||||
61315
app/client/packages/dsl/src/migrate/helpers/widget-configs.json
Normal file
61315
app/client/packages/dsl/src/migrate/helpers/widget-configs.json
Normal file
File diff suppressed because one or more lines are too long
599
app/client/packages/dsl/src/migrate/index.ts
Normal file
599
app/client/packages/dsl/src/migrate/index.ts
Normal file
|
|
@ -0,0 +1,599 @@
|
||||||
|
import { flattenDSL } from "../transform";
|
||||||
|
import { updateContainers } from "./migrations/001-update-containers";
|
||||||
|
import { chartDataMigration } from "./migrations/002-chart-data-migration";
|
||||||
|
import { mapDataMigration } from "./migrations/003-map-data-migration";
|
||||||
|
import { singleChartDataMigration } from "./migrations/004-single-chart-data-migration";
|
||||||
|
import { tabsWidgetTabsPropertyMigration } from "./migrations/005-tabs-widget-property-migration";
|
||||||
|
import { dynamicPathListMigration } from "./migrations/006-dynamic-path-list-migration";
|
||||||
|
import { canvasNameConflictMigration } from "./migrations/007-canvas-name-conflict-migration";
|
||||||
|
import { renamedCanvasNameConflictMigration } from "./migrations/008-renamed-canvas-name-conflict-migration";
|
||||||
|
import { tableWidgetPropertyPaneMigrations } from "./migrations/009-table-widget-property-pane-migration";
|
||||||
|
import { addVersionNumberMigration } from "./migrations/010-add-version-number-migration";
|
||||||
|
import { migrateTablePrimaryColumnsBindings } from "./migrations/011-migrate-table-primary-columns-binding";
|
||||||
|
import { migrateIncorrectDynamicBindingPathLists } from "./migrations/012-migrate-incorrect-dynamic-binding-path-lists";
|
||||||
|
import { migrateOldChartData } from "./migrations/013-migrate-old-chart-data";
|
||||||
|
import { rteDefaultValueMigration } from "./migrations/014-rte-default-value-migration";
|
||||||
|
import { migrateTextStyleFromTextWidget } from "./migrations/015-migrate-text-style-from-text-widget";
|
||||||
|
import { migrateChartDataFromArrayToObject } from "./migrations/016-migrate-chart-data-from-array-to-object";
|
||||||
|
import { migrateTabsData } from "./migrations/017-migrate-tabs-data";
|
||||||
|
import { migrateInitialValues } from "./migrations/018-migrate-initial-values";
|
||||||
|
import {
|
||||||
|
getCanvasSnapRows,
|
||||||
|
migrateToNewLayout,
|
||||||
|
} from "./migrations/019-migrate-to-new-layout";
|
||||||
|
import { migrateNewlyAddedTabsWidgetsMissingData } from "./migrations/020-migrate-newly-added-tabs-widgets-missing-data";
|
||||||
|
import {
|
||||||
|
migrateOverFlowingTabsWidgets,
|
||||||
|
migrateWidgetsWithoutLeftRightColumns,
|
||||||
|
} from "./migrations/021-migrate-overflowing-tabs-widgets";
|
||||||
|
import { migrateTableWidgetParentRowSpaceProperty } from "./migrations/022-migrate-table-widget-parent-row-space-property";
|
||||||
|
import { addLogBlackListToAllListWidgetChildren } from "./migrations/023-add-log-blacklist-to-all-widget-children";
|
||||||
|
import { migrateTableWidgetHeaderVisibilityProperties } from "./migrations/024-migrate-table-widget-header-visibility-properties";
|
||||||
|
import { migrateItemsToListDataInListWidget } from "./migrations/025-migrate-items-to-list-data-in-list-widget";
|
||||||
|
import { migrateDatePickerMinMaxDate } from "./migrations/026-migrate-datepicker-min-max-date";
|
||||||
|
import { migrateFilterValueForDropDownWidget } from "./migrations/027-migrate-filter-value-for-dropdown-widget";
|
||||||
|
import { migrateTablePrimaryColumnsComputedValue } from "./migrations/028-migrate-table-primary-columns-computed-value";
|
||||||
|
import { migrateToNewMultiSelect } from "./migrations/029-migrate-to-new-multiselect";
|
||||||
|
import { migrateTableWidgetDelimiterProperties } from "./migrations/030-migrate-table-widget-delimiter-properties";
|
||||||
|
import { migrateIsDisabledToButtonColumn } from "./migrations/031-migrate-is-disabled-to-button-column";
|
||||||
|
import { migrateTableDefaultSelectedRow } from "./migrations/032-migrate-table-default-selected-row";
|
||||||
|
import { migrateMenuButtonWidgetButtonProperties } from "./migrations/033-migrate-menu-button-widget-button-properties";
|
||||||
|
import { migrateButtonWidgetValidation } from "./migrations/034-migrate-button-widget-validation";
|
||||||
|
import { migrateInputValidation } from "./migrations/035-migrate-input-validation";
|
||||||
|
import { revertTableDefaultSelectedRow } from "./migrations/036-revert-table-default-selected-row";
|
||||||
|
import { migrateTableSanitizeColumnKeys } from "./migrations/037-migrate-table-sanitize-column-keys";
|
||||||
|
import { migrateResizableModalWidgetProperties } from "./migrations/038-migrate-resizable-modal-widget-properties";
|
||||||
|
import { migrateTableWidgetSelectedRowBindings } from "./migrations/039-migrate-table-widget-selected-row-bindings";
|
||||||
|
import { revertButtonStyleToButtonColor } from "./migrations/040-revert-button-style-to-button-color";
|
||||||
|
import { migrateButtonVariant } from "./migrations/041-migrate-button-variant";
|
||||||
|
import { migrateMapWidgetIsClickedMarkerCentered } from "./migrations/042-migrate-map-widget-is-clicked-marker-centered";
|
||||||
|
import { mapAllowHorizontalScrollMigration } from "./migrations/043-map-allow-horizontal-scroll-mirgation";
|
||||||
|
import { isSortableMigration } from "./migrations/044-is-sortable-migration";
|
||||||
|
import { migrateTableWidgetIconButtonVariant } from "./migrations/045-migrate-table-widget-icon-button-variant";
|
||||||
|
import { migrateCheckboxGroupWidgetInlineProperty } from "./migrations/046-migrate-checkbox-group-widget-inline-property";
|
||||||
|
import { migrateRecaptchaType } from "./migrations/048-migrate-recaptcha-type";
|
||||||
|
import { addPrivateWidgetsToAllListWidgets } from "./migrations/049-add-private-widgets-to-all-list-widgets";
|
||||||
|
import { migratePhoneInputWidgetAllowFormatting } from "./migrations/051-migrate-phone-input-widget-allow-formatting";
|
||||||
|
import { migrateModalIconButtonWidget } from "./migrations/052-migrate-modal-icon-button-widget";
|
||||||
|
import { migrateScrollTruncateProperties } from "./migrations/053-migrate-scroll-truncate-property";
|
||||||
|
import { migratePhoneInputWidgetDefaultDialCode } from "./migrations/054-migrate-phone-input-widget-default-dial-code";
|
||||||
|
import { migrateCurrencyInputWidgetDefaultCurrencyCode } from "./migrations/055-migrate-currency-input-widget-default-currency-code";
|
||||||
|
import { migrateRadioGroupAlignmentProperty } from "./migrations/056-migrate-radio-group-alignment-property";
|
||||||
|
import { migrateStylingPropertiesForTheming } from "./migrations/057-migrate-styling-properties-for-theming";
|
||||||
|
import { migrateCheckboxSwitchProperty } from "./migrations/058-migrate-checkbox-switch-property";
|
||||||
|
import { migrateChartWidgetReskinningData } from "./migrations/059-migrate-chart-widget-reskinning-data";
|
||||||
|
import { migrateTableWidgetV2Validation } from "./migrations/060-migrate-table-widget-v2-validation";
|
||||||
|
import { MigrateSelectTypeWidgetDefaultValue } from "./migrations/062-migrate-select-type-widget-default-value";
|
||||||
|
import { migrateMapChartWidgetReskinningData } from "./migrations/063-migrate-map-chart-widget-reskinning-data";
|
||||||
|
import { migrateRateWidgetDisabledState } from "./migrations/064-migrate-rate-widget-disabed-state";
|
||||||
|
import { migrateCodeScannerLayout } from "./migrations/065-migrate-code-scanner-layout";
|
||||||
|
import { migrateTableWidgetV2ValidationBinding } from "./migrations/066-migrate-table-widget-v2-validation-binding";
|
||||||
|
import { migrateLabelPosition } from "./migrations/067-migrate-label-position";
|
||||||
|
import { migratePropertiesForDynamicHeight } from "./migrations/068-migrate-properties-for-dynamic-height";
|
||||||
|
import { migrateMenuButtonDynamicItems } from "./migrations/069-migrate-menu-button-dynamic-items";
|
||||||
|
import { migrateChildStylesheetFromDynamicBindingPathList } from "./migrations/070-migrate-child-stylesheet-from-dynamic-binding-path-list";
|
||||||
|
import { migrateTableWidgetV2SelectOption } from "./migrations/071-migrate-table-widget-v2-select-option";
|
||||||
|
import { migrateListWidgetChildrenForAutoHeight } from "./migrations/072-migrate-list-widget-children-for-auto-height";
|
||||||
|
import { migrateInputWidgetShowStepArrows } from "./migrations/073-mirgate-input-widget-show-step-arrows";
|
||||||
|
import { migrateMenuButtonDynamicItemsInsideTableWidget } from "./migrations/074-migrate-mwnu-button-dynamic-items-inside-table-widget";
|
||||||
|
import { migrateInputWidgetsMultiLineInputType } from "./migrations/075-migrate-input-widgets-multiline-input-type";
|
||||||
|
import { migrateColumnFreezeAttributes } from "./migrations/076-migrate-column-freeze-attributes";
|
||||||
|
import { migrateTableSelectOptionAttributesForNewRow } from "./migrations/077-migrate-table-select-option-attributes-for-new-row";
|
||||||
|
import { migrateBindingPrefixSuffixForInlineEditValidationControl } from "./migrations/078-migrate-binding-prefix-suffix-for-inline-edit-validation-control";
|
||||||
|
import { migrateTableWidgetTableDataJsMode } from "./migrations/079-migrate-table-widget-table-data-js-mode";
|
||||||
|
import { migrateSelectWidgetOptionToSourceData } from "./migrations/080-migrate-select-widget-option-to-source-data";
|
||||||
|
import { migrateSelectWidgetSourceDataBindingPathList } from "./migrations/081-migrate-select-widget-source-data-binding-path-list";
|
||||||
|
import { migrateChartWidgetLabelOrientationStaggerOption } from "./migrations/082-migrate-chart-widget-label-orientation-stagger-option";
|
||||||
|
import { migrateAddShowHideDataPointLabels } from "./migrations/083-migrate-add-show-hide-data-point-labels";
|
||||||
|
import { migrateSelectWidgetAddSourceDataPropertyPathList } from "./migrations/084-migrate-select-widget-add-source-data-property-path-list";
|
||||||
|
import { migrateDefaultValuesForCustomEChart } from "./migrations/085-migrate-default-values-for-custom-echart";
|
||||||
|
import { migrateTableServerSideFiltering } from "./migrations/086-migrate-table-server-side-filtering";
|
||||||
|
import type { DSLWidget } from "./types";
|
||||||
|
|
||||||
|
export const LATEST_DSL_VERSION = 87;
|
||||||
|
|
||||||
|
export const calculateDynamicHeight = () => {
|
||||||
|
const DEFAULT_GRID_ROW_HEIGHT = 10;
|
||||||
|
const screenHeight = typeof window !== "undefined" ? window.innerHeight : 600;
|
||||||
|
const gridRowHeight = DEFAULT_GRID_ROW_HEIGHT;
|
||||||
|
// DGRH - DEFAULT_GRID_ROW_HEIGHT
|
||||||
|
// View Mode: Header height + Page Selection Tab = 8 * DGRH (approx)
|
||||||
|
// Edit Mode: Header height + Canvas control = 8 * DGRH (approx)
|
||||||
|
// buffer: ~8 grid row height
|
||||||
|
const buffer =
|
||||||
|
gridRowHeight +
|
||||||
|
2 * 48 /*pixelToNumber(theme.smallHeaderHeight) */ +
|
||||||
|
37; /*pixelToNumber(theme.bottomBarHeight);*/
|
||||||
|
const calculatedMinHeight =
|
||||||
|
Math.floor((screenHeight - buffer) / gridRowHeight) * gridRowHeight;
|
||||||
|
return calculatedMinHeight;
|
||||||
|
};
|
||||||
|
|
||||||
|
const migrateUnversionedDSL = (currentDSL: DSLWidget) => {
|
||||||
|
const DEFAULT_GRID_ROW_HEIGHT = 10;
|
||||||
|
if (currentDSL.version === undefined) {
|
||||||
|
// Since this top level widget is a CANVAS_WIDGET,
|
||||||
|
// DropTargetComponent needs to know the minimum height the canvas can take
|
||||||
|
// See DropTargetUtils.ts
|
||||||
|
currentDSL.minHeight = calculateDynamicHeight();
|
||||||
|
currentDSL.bottomRow = currentDSL.minHeight - DEFAULT_GRID_ROW_HEIGHT;
|
||||||
|
// For the first time the DSL is created, remove one row from the total possible rows
|
||||||
|
// to adjust for padding and margins.
|
||||||
|
currentDSL.snapRows =
|
||||||
|
Math.floor(currentDSL.bottomRow / DEFAULT_GRID_ROW_HEIGHT) - 1;
|
||||||
|
|
||||||
|
// Force the width of the canvas to 1224 px
|
||||||
|
currentDSL.rightColumn = 1224;
|
||||||
|
// The canvas is a CANVAS_WIDGET which doesn't have a background or borders by default
|
||||||
|
currentDSL.backgroundColor = "none";
|
||||||
|
currentDSL.containerStyle = "none";
|
||||||
|
currentDSL.type = "CANVAS_WIDGET";
|
||||||
|
currentDSL.detachFromLayout = true;
|
||||||
|
currentDSL.canExtend = true;
|
||||||
|
|
||||||
|
// Update version to make sure this doesn't run every time.
|
||||||
|
currentDSL.version = 1;
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A rudimentary transform function which updates the DSL based on its version.
|
||||||
|
// A more modular approach needs to be designed.
|
||||||
|
// This needs the widget config to be already built to migrate correctly
|
||||||
|
const migrateVersionedDSL = (currentDSL: DSLWidget, newPage = false) => {
|
||||||
|
if (currentDSL.version === 1) {
|
||||||
|
if (currentDSL.children && currentDSL.children.length > 0)
|
||||||
|
currentDSL.children = currentDSL.children.map(updateContainers);
|
||||||
|
currentDSL.version = 2;
|
||||||
|
}
|
||||||
|
if (currentDSL.version === 2) {
|
||||||
|
currentDSL = chartDataMigration(currentDSL);
|
||||||
|
currentDSL.version = 3;
|
||||||
|
}
|
||||||
|
if (currentDSL.version === 3) {
|
||||||
|
currentDSL = mapDataMigration(currentDSL);
|
||||||
|
currentDSL.version = 4;
|
||||||
|
}
|
||||||
|
if (currentDSL.version === 4) {
|
||||||
|
currentDSL = singleChartDataMigration(currentDSL);
|
||||||
|
currentDSL.version = 5;
|
||||||
|
}
|
||||||
|
if (currentDSL.version === 5) {
|
||||||
|
currentDSL = tabsWidgetTabsPropertyMigration(currentDSL);
|
||||||
|
currentDSL.version = 6;
|
||||||
|
}
|
||||||
|
if (currentDSL.version === 6) {
|
||||||
|
currentDSL = dynamicPathListMigration(currentDSL);
|
||||||
|
currentDSL.version = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 7) {
|
||||||
|
currentDSL = canvasNameConflictMigration(currentDSL);
|
||||||
|
currentDSL.version = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 8) {
|
||||||
|
currentDSL = renamedCanvasNameConflictMigration(currentDSL);
|
||||||
|
currentDSL.version = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 9) {
|
||||||
|
currentDSL = tableWidgetPropertyPaneMigrations(currentDSL);
|
||||||
|
currentDSL.version = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 10) {
|
||||||
|
currentDSL = addVersionNumberMigration(currentDSL);
|
||||||
|
currentDSL.version = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 11) {
|
||||||
|
currentDSL = migrateTablePrimaryColumnsBindings(currentDSL);
|
||||||
|
currentDSL.version = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 12) {
|
||||||
|
currentDSL = migrateIncorrectDynamicBindingPathLists(currentDSL);
|
||||||
|
currentDSL.version = 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 13) {
|
||||||
|
currentDSL = migrateOldChartData(currentDSL);
|
||||||
|
currentDSL.version = 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 14) {
|
||||||
|
currentDSL = rteDefaultValueMigration(currentDSL);
|
||||||
|
currentDSL.version = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 15) {
|
||||||
|
currentDSL = migrateTextStyleFromTextWidget(currentDSL);
|
||||||
|
currentDSL.version = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 16) {
|
||||||
|
currentDSL = migrateChartDataFromArrayToObject(currentDSL);
|
||||||
|
currentDSL.version = 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 17) {
|
||||||
|
currentDSL = migrateTabsData(currentDSL);
|
||||||
|
currentDSL.version = 18;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 18) {
|
||||||
|
currentDSL = migrateInitialValues(currentDSL);
|
||||||
|
currentDSL.version = 19;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 19) {
|
||||||
|
currentDSL.snapColumns = 64; // GridDefaults.DEFAULT_GRID_COLUMNS;
|
||||||
|
currentDSL.snapRows = getCanvasSnapRows(currentDSL.bottomRow);
|
||||||
|
if (!newPage) {
|
||||||
|
currentDSL = migrateToNewLayout(currentDSL);
|
||||||
|
}
|
||||||
|
currentDSL.version = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 20) {
|
||||||
|
currentDSL = migrateNewlyAddedTabsWidgetsMissingData(currentDSL);
|
||||||
|
currentDSL.version = 21;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 21) {
|
||||||
|
const canvasWidgets = flattenDSL(currentDSL);
|
||||||
|
currentDSL = migrateWidgetsWithoutLeftRightColumns(
|
||||||
|
currentDSL,
|
||||||
|
canvasWidgets,
|
||||||
|
);
|
||||||
|
currentDSL = migrateOverFlowingTabsWidgets(currentDSL, canvasWidgets);
|
||||||
|
currentDSL.version = 22;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 22) {
|
||||||
|
currentDSL = migrateTableWidgetParentRowSpaceProperty(currentDSL);
|
||||||
|
currentDSL.version = 23;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 23) {
|
||||||
|
currentDSL = addLogBlackListToAllListWidgetChildren(currentDSL);
|
||||||
|
currentDSL.version = 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 24) {
|
||||||
|
currentDSL = migrateTableWidgetHeaderVisibilityProperties(currentDSL);
|
||||||
|
currentDSL.version = 25;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 25) {
|
||||||
|
currentDSL = migrateItemsToListDataInListWidget(currentDSL);
|
||||||
|
currentDSL.version = 26;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 26) {
|
||||||
|
currentDSL = migrateDatePickerMinMaxDate(currentDSL);
|
||||||
|
currentDSL.version = 27;
|
||||||
|
}
|
||||||
|
if (currentDSL.version === 27) {
|
||||||
|
currentDSL = migrateFilterValueForDropDownWidget(currentDSL);
|
||||||
|
currentDSL.version = 28;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 28) {
|
||||||
|
currentDSL = migrateTablePrimaryColumnsComputedValue(currentDSL);
|
||||||
|
currentDSL.version = 29;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 29) {
|
||||||
|
currentDSL = migrateToNewMultiSelect(currentDSL);
|
||||||
|
currentDSL.version = 30;
|
||||||
|
}
|
||||||
|
if (currentDSL.version === 30) {
|
||||||
|
currentDSL = migrateTableWidgetDelimiterProperties(currentDSL);
|
||||||
|
currentDSL.version = 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 31) {
|
||||||
|
currentDSL = migrateIsDisabledToButtonColumn(currentDSL);
|
||||||
|
currentDSL.version = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 32) {
|
||||||
|
currentDSL = migrateTableDefaultSelectedRow(currentDSL);
|
||||||
|
currentDSL.version = 33;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 33) {
|
||||||
|
currentDSL = migrateMenuButtonWidgetButtonProperties(currentDSL);
|
||||||
|
currentDSL.version = 34;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 34) {
|
||||||
|
currentDSL = migrateButtonWidgetValidation(currentDSL);
|
||||||
|
currentDSL.version = 35;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 35) {
|
||||||
|
currentDSL = migrateInputValidation(currentDSL);
|
||||||
|
currentDSL.version = 36;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 36) {
|
||||||
|
currentDSL = revertTableDefaultSelectedRow(currentDSL);
|
||||||
|
currentDSL.version = 37;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 37) {
|
||||||
|
currentDSL = migrateTableSanitizeColumnKeys(currentDSL);
|
||||||
|
currentDSL.version = 38;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 38) {
|
||||||
|
currentDSL = migrateResizableModalWidgetProperties(currentDSL);
|
||||||
|
currentDSL.version = 39;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 39) {
|
||||||
|
currentDSL = migrateTableWidgetSelectedRowBindings(currentDSL);
|
||||||
|
currentDSL.version = 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 40) {
|
||||||
|
currentDSL = revertButtonStyleToButtonColor(currentDSL);
|
||||||
|
currentDSL.version = 41;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 41) {
|
||||||
|
currentDSL = migrateButtonVariant(currentDSL);
|
||||||
|
currentDSL.version = 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 42) {
|
||||||
|
currentDSL = migrateMapWidgetIsClickedMarkerCentered(currentDSL);
|
||||||
|
currentDSL.version = 43;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 43) {
|
||||||
|
currentDSL = mapAllowHorizontalScrollMigration(currentDSL);
|
||||||
|
currentDSL.version = 44;
|
||||||
|
}
|
||||||
|
if (currentDSL.version === 44) {
|
||||||
|
currentDSL = isSortableMigration(currentDSL);
|
||||||
|
currentDSL.version = 45;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 45) {
|
||||||
|
currentDSL = migrateTableWidgetIconButtonVariant(currentDSL);
|
||||||
|
currentDSL.version = 46;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 46) {
|
||||||
|
currentDSL = migrateCheckboxGroupWidgetInlineProperty(currentDSL);
|
||||||
|
currentDSL.version = 47;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 47) {
|
||||||
|
// We're skipping this to fix a bad table migration.
|
||||||
|
// skipped migration is added as version 51
|
||||||
|
currentDSL.version = 48;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 48) {
|
||||||
|
currentDSL = migrateRecaptchaType(currentDSL);
|
||||||
|
currentDSL.version = 49;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 49) {
|
||||||
|
currentDSL = addPrivateWidgetsToAllListWidgets(currentDSL);
|
||||||
|
currentDSL.version = 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 50) {
|
||||||
|
/*
|
||||||
|
* We're skipping this to fix a bad table migration - migrateTableWidgetNumericColumnName
|
||||||
|
* it overwrites the computedValue of the table columns
|
||||||
|
*/
|
||||||
|
|
||||||
|
currentDSL.version = 51;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 51) {
|
||||||
|
currentDSL = migratePhoneInputWidgetAllowFormatting(currentDSL);
|
||||||
|
currentDSL.version = 52;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 52) {
|
||||||
|
currentDSL = migrateModalIconButtonWidget(currentDSL);
|
||||||
|
currentDSL.version = 53;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 53) {
|
||||||
|
currentDSL = migrateScrollTruncateProperties(currentDSL);
|
||||||
|
currentDSL.version = 54;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 54) {
|
||||||
|
currentDSL = migratePhoneInputWidgetDefaultDialCode(currentDSL);
|
||||||
|
currentDSL.version = 55;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 55) {
|
||||||
|
currentDSL = migrateCurrencyInputWidgetDefaultCurrencyCode(currentDSL);
|
||||||
|
currentDSL.version = 56;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 56) {
|
||||||
|
currentDSL = migrateRadioGroupAlignmentProperty(currentDSL);
|
||||||
|
currentDSL.version = 57;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 57) {
|
||||||
|
currentDSL = migrateStylingPropertiesForTheming(currentDSL);
|
||||||
|
currentDSL.version = 58;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 58) {
|
||||||
|
currentDSL = migrateCheckboxSwitchProperty(currentDSL);
|
||||||
|
currentDSL.version = 59;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 59) {
|
||||||
|
/**
|
||||||
|
* migrateChartWidgetReskinningData function will be executed again in version 61,
|
||||||
|
* since for older apps the accentColor and fontFamily didn't get migrated.
|
||||||
|
*/
|
||||||
|
currentDSL = migrateChartWidgetReskinningData(currentDSL);
|
||||||
|
currentDSL.version = 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 60) {
|
||||||
|
currentDSL = migrateTableWidgetV2Validation(currentDSL);
|
||||||
|
currentDSL.version = 61;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 61) {
|
||||||
|
currentDSL = migrateChartWidgetReskinningData(currentDSL);
|
||||||
|
currentDSL.version = 62;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 62) {
|
||||||
|
currentDSL = MigrateSelectTypeWidgetDefaultValue(currentDSL);
|
||||||
|
currentDSL.version = 63;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 63) {
|
||||||
|
currentDSL = migrateMapChartWidgetReskinningData(currentDSL);
|
||||||
|
currentDSL.version = 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 64) {
|
||||||
|
currentDSL = migrateRateWidgetDisabledState(currentDSL);
|
||||||
|
currentDSL.version = 65;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 65) {
|
||||||
|
currentDSL = migrateCodeScannerLayout(currentDSL);
|
||||||
|
currentDSL.version = 66;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 66) {
|
||||||
|
currentDSL = migrateTableWidgetV2ValidationBinding(currentDSL);
|
||||||
|
currentDSL.version = 67;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 67) {
|
||||||
|
currentDSL = migrateLabelPosition(currentDSL);
|
||||||
|
currentDSL.version = 68;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 68) {
|
||||||
|
currentDSL = migratePropertiesForDynamicHeight(currentDSL);
|
||||||
|
currentDSL.version = 69;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 69) {
|
||||||
|
currentDSL = migrateMenuButtonDynamicItems(currentDSL);
|
||||||
|
currentDSL.version = 70;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 70) {
|
||||||
|
currentDSL = migrateChildStylesheetFromDynamicBindingPathList(currentDSL);
|
||||||
|
currentDSL.version = 71;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 71) {
|
||||||
|
currentDSL = migrateTableWidgetV2SelectOption(currentDSL);
|
||||||
|
currentDSL.version = 72;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 72) {
|
||||||
|
currentDSL = migrateListWidgetChildrenForAutoHeight(currentDSL);
|
||||||
|
currentDSL.version = 73;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 73) {
|
||||||
|
currentDSL = migrateInputWidgetShowStepArrows(currentDSL);
|
||||||
|
currentDSL.version = 74;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 74) {
|
||||||
|
currentDSL = migrateMenuButtonDynamicItemsInsideTableWidget(currentDSL);
|
||||||
|
currentDSL.version = 75;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 75) {
|
||||||
|
currentDSL = migrateInputWidgetsMultiLineInputType(currentDSL);
|
||||||
|
currentDSL.version = 76;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 76) {
|
||||||
|
currentDSL = migrateColumnFreezeAttributes(currentDSL);
|
||||||
|
currentDSL.version = 77;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 77) {
|
||||||
|
currentDSL = migrateTableSelectOptionAttributesForNewRow(currentDSL);
|
||||||
|
currentDSL.version = 78;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version == 78) {
|
||||||
|
currentDSL =
|
||||||
|
migrateBindingPrefixSuffixForInlineEditValidationControl(currentDSL);
|
||||||
|
currentDSL.version = 79;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version == 79) {
|
||||||
|
currentDSL = migrateTableWidgetTableDataJsMode(currentDSL);
|
||||||
|
currentDSL.version = 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 80) {
|
||||||
|
currentDSL = migrateSelectWidgetOptionToSourceData(currentDSL);
|
||||||
|
currentDSL.version = 81;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 81) {
|
||||||
|
currentDSL = migrateSelectWidgetSourceDataBindingPathList(currentDSL);
|
||||||
|
currentDSL.version = 82;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version == 82) {
|
||||||
|
currentDSL = migrateChartWidgetLabelOrientationStaggerOption(currentDSL);
|
||||||
|
currentDSL.version = 83;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version == 83) {
|
||||||
|
currentDSL = migrateAddShowHideDataPointLabels(currentDSL);
|
||||||
|
currentDSL.version = 84;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 84) {
|
||||||
|
currentDSL = migrateSelectWidgetAddSourceDataPropertyPathList(currentDSL);
|
||||||
|
currentDSL.version = 85;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 85) {
|
||||||
|
currentDSL = migrateDefaultValuesForCustomEChart(currentDSL);
|
||||||
|
currentDSL.version = 86;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.version === 86) {
|
||||||
|
currentDSL = migrateTableServerSideFiltering(currentDSL);
|
||||||
|
currentDSL.version = LATEST_DSL_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const migrateDSL = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
newPage = false,
|
||||||
|
): DSLWidget => {
|
||||||
|
if (currentDSL.version === undefined) {
|
||||||
|
const initialDSL = migrateUnversionedDSL(currentDSL);
|
||||||
|
return migrateVersionedDSL(initialDSL, newPage) as DSLWidget;
|
||||||
|
} else {
|
||||||
|
return migrateVersionedDSL(currentDSL, newPage) as DSLWidget;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
import { generateReactKey } from "../utils";
|
||||||
|
|
||||||
|
export const updateContainers = (dsl: DSLWidget) => {
|
||||||
|
if (dsl.type === "CONTAINER_WIDGET" || dsl.type === "FORM_WIDGET") {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
dsl.children &&
|
||||||
|
dsl.children.length > 0 &&
|
||||||
|
(dsl.children[0].type === "CANVAS_WIDGET" ||
|
||||||
|
dsl.children[0].type === "FORM_WIDGET")
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
const canvas: any = {
|
||||||
|
...dsl,
|
||||||
|
backgroundColor: "transparent",
|
||||||
|
type: "CANVAS_WIDGET",
|
||||||
|
detachFromLayout: true,
|
||||||
|
topRow: 0,
|
||||||
|
leftColumn: 0,
|
||||||
|
rightColumn: dsl.parentColumnSpace * (dsl.rightColumn - dsl.leftColumn),
|
||||||
|
bottomRow: dsl.parentRowSpace * (dsl.bottomRow - dsl.topRow),
|
||||||
|
widgetName: generateReactKey(),
|
||||||
|
widgetId: generateReactKey(),
|
||||||
|
parentRowSpace: 1,
|
||||||
|
parentColumnSpace: 1,
|
||||||
|
containerStyle: "none",
|
||||||
|
canExtend: false,
|
||||||
|
isVisible: true,
|
||||||
|
};
|
||||||
|
delete canvas.dynamicBindings;
|
||||||
|
delete canvas.dynamicProperties;
|
||||||
|
if (canvas.children && canvas.children.length > 0)
|
||||||
|
canvas.children = canvas.children.map(updateContainers);
|
||||||
|
dsl.children = [{ ...canvas }];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dsl;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const chartDataMigration = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((children: DSLWidget) => {
|
||||||
|
if (
|
||||||
|
children.type === "CHART_WIDGET" &&
|
||||||
|
children.chartData &&
|
||||||
|
children.chartData.length &&
|
||||||
|
!Array.isArray(children.chartData[0])
|
||||||
|
) {
|
||||||
|
children.chartData = [{ data: children.chartData }];
|
||||||
|
} else if (
|
||||||
|
children.type === "CONTAINER_WIDGET" ||
|
||||||
|
children.type === "FORM_WIDGET" ||
|
||||||
|
children.type === "CANVAS_WIDGET" ||
|
||||||
|
children.type === "TABS_WIDGET"
|
||||||
|
) {
|
||||||
|
children = chartDataMigration(children);
|
||||||
|
}
|
||||||
|
return children;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const mapDataMigration = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((children: DSLWidget) => {
|
||||||
|
if (children.type === "MAP_WIDGET") {
|
||||||
|
if (children.markers) {
|
||||||
|
children.markers = children.markers.map(
|
||||||
|
(marker: { lat: any; lng: any; long: any; title: any }) => {
|
||||||
|
return {
|
||||||
|
lat: marker.lat,
|
||||||
|
long: marker.lng || marker.long,
|
||||||
|
title: marker.title,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (children.defaultMarkers) {
|
||||||
|
const defaultMarkers = JSON.parse(children.defaultMarkers);
|
||||||
|
children.defaultMarkers = defaultMarkers.map(
|
||||||
|
(marker: {
|
||||||
|
lat: number;
|
||||||
|
lng: number;
|
||||||
|
long: number;
|
||||||
|
title: string;
|
||||||
|
}) => {
|
||||||
|
return {
|
||||||
|
lat: marker.lat,
|
||||||
|
long: marker.lng || marker.long,
|
||||||
|
title: marker.title,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (children.selectedMarker) {
|
||||||
|
children.selectedMarker = {
|
||||||
|
lat: children.selectedMarker.lat,
|
||||||
|
long: children.selectedMarker.lng || children.selectedMarker.long,
|
||||||
|
title: children.selectedMarker.title,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (children.mapCenter) {
|
||||||
|
children.mapCenter = {
|
||||||
|
lat: children.mapCenter.lat,
|
||||||
|
long: children.mapCenter.lng || children.mapCenter.long,
|
||||||
|
title: children.mapCenter.title,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (children.center) {
|
||||||
|
children.center = {
|
||||||
|
lat: children.center.lat,
|
||||||
|
long: children.center.lng || children.center.long,
|
||||||
|
title: children.center.title,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else if (children.children && children.children.length > 0) {
|
||||||
|
children = mapDataMigration(children);
|
||||||
|
}
|
||||||
|
return children;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const singleChartDataMigration = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "CHART_WIDGET") {
|
||||||
|
// Check if chart widget has the deprecated singleChartData property
|
||||||
|
if (child.hasOwnProperty("singleChartData")) {
|
||||||
|
// This is to make sure that the format of the chartData is accurate
|
||||||
|
if (
|
||||||
|
Array.isArray(child.singleChartData) &&
|
||||||
|
!child.singleChartData[0].hasOwnProperty("seriesName")
|
||||||
|
) {
|
||||||
|
child.singleChartData = {
|
||||||
|
seriesName: "Series 1",
|
||||||
|
data: child.singleChartData || [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//TODO: other possibilities?
|
||||||
|
child.chartData = JSON.stringify([...child.singleChartData]);
|
||||||
|
delete child.singleChartData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (child.children && child.children.length > 0) {
|
||||||
|
child = singleChartDataMigration(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import isString from "lodash/isString";
|
||||||
|
import log from "loglevel";
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const tabsWidgetTabsPropertyMigration = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children
|
||||||
|
?.filter(Boolean)
|
||||||
|
.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "TABS_WIDGET") {
|
||||||
|
try {
|
||||||
|
const tabs = isString(child.tabs)
|
||||||
|
? JSON.parse(child.tabs)
|
||||||
|
: child.tabs;
|
||||||
|
const newTabs = tabs.map((tab: any) => {
|
||||||
|
const childForTab = child.children
|
||||||
|
?.filter(Boolean)
|
||||||
|
.find((tabChild: DSLWidget) => tabChild.tabId === tab.id);
|
||||||
|
if (childForTab) {
|
||||||
|
tab.widgetId = childForTab.widgetId;
|
||||||
|
}
|
||||||
|
return tab;
|
||||||
|
});
|
||||||
|
child.tabs = JSON.stringify(newTabs);
|
||||||
|
} catch (migrationError) {
|
||||||
|
log.debug({ migrationError });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (child.children && child.children.length) {
|
||||||
|
child = tabsWidgetTabsPropertyMigration(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const dynamicPathListMigration = (currentDSL: DSLWidget) => {
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map(dynamicPathListMigration);
|
||||||
|
}
|
||||||
|
if (currentDSL.dynamicBindings) {
|
||||||
|
currentDSL.dynamicBindingPathList = Object.keys(
|
||||||
|
currentDSL.dynamicBindings,
|
||||||
|
).map((path) => ({ key: path }));
|
||||||
|
delete currentDSL.dynamicBindings;
|
||||||
|
}
|
||||||
|
if (currentDSL.dynamicTriggers) {
|
||||||
|
currentDSL.dynamicTriggerPathList = Object.keys(
|
||||||
|
currentDSL.dynamicTriggers,
|
||||||
|
).map((path) => ({ key: path }));
|
||||||
|
delete currentDSL.dynamicTriggers;
|
||||||
|
}
|
||||||
|
if (currentDSL.dynamicProperties) {
|
||||||
|
currentDSL.dynamicPropertyPathList = Object.keys(
|
||||||
|
currentDSL.dynamicProperties,
|
||||||
|
).map((path) => ({ key: path }));
|
||||||
|
delete currentDSL.dynamicProperties;
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const canvasNameConflictMigration = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
props = { counter: 1 },
|
||||||
|
): DSLWidget => {
|
||||||
|
if (
|
||||||
|
currentDSL.type === "CANVAS_WIDGET" &&
|
||||||
|
currentDSL.widgetName.startsWith("Canvas")
|
||||||
|
) {
|
||||||
|
currentDSL.widgetName = `Canvas${props.counter}`;
|
||||||
|
// Canvases inside tabs have `name` property as well
|
||||||
|
if (currentDSL.name) {
|
||||||
|
currentDSL.name = currentDSL.widgetName;
|
||||||
|
}
|
||||||
|
props.counter++;
|
||||||
|
}
|
||||||
|
currentDSL.children?.forEach((c: DSLWidget) =>
|
||||||
|
canvasNameConflictMigration(c, props),
|
||||||
|
);
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { canvasNameConflictMigration } from "./007-canvas-name-conflict-migration";
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const renamedCanvasNameConflictMigration = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
props = { counter: 1 },
|
||||||
|
): DSLWidget => {
|
||||||
|
// Rename all canvas widgets except for MainContainer
|
||||||
|
if (
|
||||||
|
currentDSL.type === "CANVAS_WIDGET" &&
|
||||||
|
currentDSL.widgetName !== "MainContainer"
|
||||||
|
) {
|
||||||
|
currentDSL.widgetName = `Canvas${props.counter}`;
|
||||||
|
// Canvases inside tabs have `name` property as well
|
||||||
|
if (currentDSL.name) {
|
||||||
|
currentDSL.name = currentDSL.widgetName;
|
||||||
|
}
|
||||||
|
props.counter++;
|
||||||
|
}
|
||||||
|
currentDSL.children?.forEach((c: DSLWidget) =>
|
||||||
|
canvasNameConflictMigration(c, props),
|
||||||
|
);
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,175 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import cloneDeep from "lodash/cloneDeep";
|
||||||
|
import isString from "lodash/isString";
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
import { removeSpecialChars } from "../utils";
|
||||||
|
|
||||||
|
export const getAllTableColumnKeys = (
|
||||||
|
tableData?: Array<Record<string, unknown>>,
|
||||||
|
) => {
|
||||||
|
const columnKeys: string[] = [];
|
||||||
|
if (tableData) {
|
||||||
|
for (let i = 0, tableRowCount = tableData.length; i < tableRowCount; i++) {
|
||||||
|
const row = tableData[i];
|
||||||
|
for (const key in row) {
|
||||||
|
// Replace all special characters to _, limit key length to 200 characters.
|
||||||
|
const sanitizedKey = removeSpecialChars(key, 200);
|
||||||
|
if (!columnKeys.includes(sanitizedKey)) {
|
||||||
|
columnKeys.push(sanitizedKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return columnKeys;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const tableWidgetPropertyPaneMigrations = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((_child: DSLWidget) => {
|
||||||
|
let child = cloneDeep(_child);
|
||||||
|
// If the current child is a TABLE_WIDGET
|
||||||
|
if (child.type === "TABLE_WIDGET") {
|
||||||
|
const hiddenColumns = child.hiddenColumns || [];
|
||||||
|
const columnNameMap = child.columnNameMap;
|
||||||
|
const columnSizeMap = child.columnSizeMap;
|
||||||
|
const columnTypeMap = child.columnTypeMap;
|
||||||
|
let tableColumns: string[] = [];
|
||||||
|
const dynamicBindingPathList = child.dynamicBindingPathList;
|
||||||
|
if (child.tableData.length) {
|
||||||
|
let tableData = [];
|
||||||
|
// Try parsing the table data, if it parses great
|
||||||
|
// If it does not parse, assign tableData the value as is.
|
||||||
|
try {
|
||||||
|
tableData = JSON.parse(child.tableData);
|
||||||
|
} catch (e) {
|
||||||
|
tableData = child.tableData;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!isString(tableData) &&
|
||||||
|
dynamicBindingPathList?.findIndex(
|
||||||
|
(item: { key: string }) => item.key !== "tableData",
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
// Get the list of column ids
|
||||||
|
tableColumns = getAllTableColumnKeys(tableData);
|
||||||
|
} else {
|
||||||
|
child.migrated = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get primaryColumns to be the list of column keys
|
||||||
|
// Use the old order if it exists, else use the new order
|
||||||
|
const primaryColumns = child.columnOrder?.length
|
||||||
|
? child.columnOrder
|
||||||
|
: tableColumns;
|
||||||
|
child.primaryColumns = {};
|
||||||
|
|
||||||
|
// const hasActions = child.columnActions && child.columnActions.length > 0;
|
||||||
|
// Generate new primarycolumns
|
||||||
|
primaryColumns.forEach((accessor: string, index: number) => {
|
||||||
|
// Get the column type from the columnTypeMap
|
||||||
|
let columnType =
|
||||||
|
columnTypeMap && columnTypeMap[accessor]
|
||||||
|
? columnTypeMap[accessor].type
|
||||||
|
: "text";
|
||||||
|
// If the columnType is currency make it a text type
|
||||||
|
// We're deprecating currency types
|
||||||
|
if (columnType === "currency") {
|
||||||
|
columnType = "text";
|
||||||
|
}
|
||||||
|
// Get a full set of column properties
|
||||||
|
const column: any = {
|
||||||
|
index, // Use to maintain order of columns
|
||||||
|
// The widget of the column
|
||||||
|
width:
|
||||||
|
columnSizeMap && columnSizeMap[accessor]
|
||||||
|
? columnSizeMap[accessor]
|
||||||
|
: 150,
|
||||||
|
// id of the column
|
||||||
|
id: accessor,
|
||||||
|
// default horizontal alignment
|
||||||
|
horizontalAlignment: "LEFT",
|
||||||
|
// default vertical alignment
|
||||||
|
verticalAlignment: "CENTER",
|
||||||
|
// columnType
|
||||||
|
columnType,
|
||||||
|
// default text color
|
||||||
|
textColor: "#231F20",
|
||||||
|
// default text size
|
||||||
|
textSize: "PARAGRAPH",
|
||||||
|
// default font size
|
||||||
|
fontStyle: "REGULAR",
|
||||||
|
enableFilter: true,
|
||||||
|
enableSort: true,
|
||||||
|
// hide the column if it was hidden earlier using hiddenColumns
|
||||||
|
isVisible: hiddenColumns.includes(accessor) ? false : true,
|
||||||
|
// We did not have a concept of derived columns so far
|
||||||
|
isDerived: false,
|
||||||
|
// Use renamed names from the map
|
||||||
|
// or use the newly generated name
|
||||||
|
label:
|
||||||
|
columnNameMap && columnNameMap[accessor]
|
||||||
|
? columnNameMap[accessor]
|
||||||
|
: accessor,
|
||||||
|
// Generate computed value
|
||||||
|
computedValue: `{{${child.widgetName}.sanitizedTableData.map((currentRow) => ( currentRow.${accessor})}}`,
|
||||||
|
};
|
||||||
|
// copy inputForma nd outputFormat for date column types
|
||||||
|
if (columnTypeMap && columnTypeMap[accessor]) {
|
||||||
|
column.outputFormat = columnTypeMap[accessor].format || "";
|
||||||
|
column.inputFormat = columnTypeMap[accessor].inputFormat || "";
|
||||||
|
}
|
||||||
|
child.primaryColumns[column.id] = column;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get all column actions
|
||||||
|
const columnActions = child.columnActions || [];
|
||||||
|
// Get dynamicTriggerPathList
|
||||||
|
let dynamicTriggerPathList: Array<{ key: string }> =
|
||||||
|
child.dynamicTriggerPathList || [];
|
||||||
|
|
||||||
|
const columnPrefix = "customColumn";
|
||||||
|
const updatedDerivedColumns: Record<string, object> = {};
|
||||||
|
// Add derived column for each column action
|
||||||
|
columnActions.forEach((action: any, index: number) => {
|
||||||
|
const column = {
|
||||||
|
index: child.primaryColumns.length + index, // Add to the end of the columns list
|
||||||
|
width: 150, // Default width
|
||||||
|
id: `${columnPrefix}${index + 1}`, // A random string which was generated previously
|
||||||
|
label: action.label, // Revert back to "Actions"
|
||||||
|
columnType: "button", // All actions are buttons
|
||||||
|
isVisible: true,
|
||||||
|
isDisabled: false,
|
||||||
|
isDerived: true,
|
||||||
|
buttonLabel: action.label,
|
||||||
|
buttonStyle: "rgb(3, 179, 101)",
|
||||||
|
buttonLabelColor: "#FFFFFF",
|
||||||
|
onClick: action.dynamicTrigger,
|
||||||
|
computedValue: "",
|
||||||
|
};
|
||||||
|
dynamicTriggerPathList.push({
|
||||||
|
key: `primaryColumns.${columnPrefix}${index + 1}.onClick`,
|
||||||
|
});
|
||||||
|
updatedDerivedColumns[column.id] = column;
|
||||||
|
child.primaryColumns[column.id] = column;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (Object.keys(updatedDerivedColumns).length) {
|
||||||
|
dynamicTriggerPathList = dynamicTriggerPathList.filter(
|
||||||
|
(triggerPath: Record<string, string>) => {
|
||||||
|
triggerPath.key !== "columnActions";
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
child.dynamicTriggerPathList = dynamicTriggerPathList;
|
||||||
|
child.textSize = "PARAGRAPH";
|
||||||
|
child.horizontalAlignment = "LEFT";
|
||||||
|
child.verticalAlignment = "CENTER";
|
||||||
|
child.fontStyle = "REGULAR";
|
||||||
|
|
||||||
|
child.derivedColumns = updatedDerivedColumns;
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = tableWidgetPropertyPaneMigrations(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const addVersionNumberMigration = (currentDSL: DSLWidget) => {
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map(addVersionNumberMigration);
|
||||||
|
}
|
||||||
|
if (currentDSL.version === undefined) {
|
||||||
|
currentDSL.version = 1;
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
import { removeSpecialChars } from "../utils";
|
||||||
|
|
||||||
|
export const migrateTablePrimaryColumnsBindings = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "TABLE_WIDGET") {
|
||||||
|
if (
|
||||||
|
child.primaryColumns &&
|
||||||
|
Object.keys(child.primaryColumns).length > 0
|
||||||
|
) {
|
||||||
|
const newPrimaryColumns: Record<string, any> = {};
|
||||||
|
for (const [key, value] of Object.entries(
|
||||||
|
child.primaryColumns as Record<string, any>,
|
||||||
|
)) {
|
||||||
|
const sanitizedKey = removeSpecialChars(key, 200);
|
||||||
|
const newComputedValue = value.computedValue
|
||||||
|
? value.computedValue.replace(
|
||||||
|
`${child.widgetName}.tableData.map`,
|
||||||
|
`${child.widgetName}.sanitizedTableData.map`,
|
||||||
|
)
|
||||||
|
: "";
|
||||||
|
newPrimaryColumns[sanitizedKey] = {
|
||||||
|
...value,
|
||||||
|
computedValue: newComputedValue,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
child.primaryColumns = newPrimaryColumns;
|
||||||
|
child.dynamicBindingPathList = child.dynamicBindingPathList?.map(
|
||||||
|
(path: { key: string }) => {
|
||||||
|
path.key = path.key.split(" ").join("_");
|
||||||
|
return path;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateTablePrimaryColumnsBindings(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,934 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import flow from "lodash/flow";
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
import log from "loglevel";
|
||||||
|
import get from "lodash/get";
|
||||||
|
import isString from "lodash/isString";
|
||||||
|
import memoize from "micro-memoize";
|
||||||
|
import { isObject, isUndefined } from "lodash";
|
||||||
|
import { generateReactKey, isDynamicValue } from "../utils";
|
||||||
|
import widgetConfigs from "../helpers/widget-configs.json";
|
||||||
|
|
||||||
|
export const WidgetHeightLimits = {
|
||||||
|
MAX_HEIGHT_IN_ROWS: 9000,
|
||||||
|
MIN_HEIGHT_IN_ROWS: 4,
|
||||||
|
MIN_CANVAS_HEIGHT_IN_ROWS: 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
function updateMinMaxDynamicHeight(
|
||||||
|
props: any,
|
||||||
|
propertyName: string,
|
||||||
|
propertyValue: unknown,
|
||||||
|
) {
|
||||||
|
const updates = [
|
||||||
|
{
|
||||||
|
propertyPath: propertyName,
|
||||||
|
propertyValue: propertyValue,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
if (propertyValue === "AUTO_HEIGHT_WITH_LIMITS") {
|
||||||
|
const minDynamicHeight = parseInt(props.minDynamicHeight, 10);
|
||||||
|
|
||||||
|
if (
|
||||||
|
isNaN(minDynamicHeight) ||
|
||||||
|
minDynamicHeight < WidgetHeightLimits.MIN_HEIGHT_IN_ROWS
|
||||||
|
) {
|
||||||
|
updates.push({
|
||||||
|
propertyPath: "minDynamicHeight",
|
||||||
|
propertyValue: WidgetHeightLimits.MIN_HEIGHT_IN_ROWS,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const maxDynamicHeight = parseInt(props.maxDynamicHeight, 10);
|
||||||
|
if (
|
||||||
|
isNaN(maxDynamicHeight) ||
|
||||||
|
maxDynamicHeight === WidgetHeightLimits.MAX_HEIGHT_IN_ROWS ||
|
||||||
|
maxDynamicHeight <= WidgetHeightLimits.MIN_HEIGHT_IN_ROWS
|
||||||
|
) {
|
||||||
|
updates.push({
|
||||||
|
propertyPath: "maxDynamicHeight",
|
||||||
|
propertyValue: props.bottomRow - props.topRow + 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case where maxDynamicHeight is zero
|
||||||
|
if (isNaN(maxDynamicHeight) || maxDynamicHeight === 0) {
|
||||||
|
updates.push({
|
||||||
|
propertyPath: "maxDynamicHeight",
|
||||||
|
propertyValue: props.bottomRow - props.topRow,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (propertyValue === "AUTO_HEIGHT") {
|
||||||
|
const minHeightInRows = props.isCanvas
|
||||||
|
? WidgetHeightLimits.MIN_CANVAS_HEIGHT_IN_ROWS
|
||||||
|
: WidgetHeightLimits.MIN_HEIGHT_IN_ROWS;
|
||||||
|
updates.push(
|
||||||
|
{
|
||||||
|
propertyPath: "minDynamicHeight",
|
||||||
|
propertyValue: minHeightInRows,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyPath: "maxDynamicHeight",
|
||||||
|
propertyValue: WidgetHeightLimits.MAX_HEIGHT_IN_ROWS,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propertyValue === "FIXED") {
|
||||||
|
updates.push({
|
||||||
|
propertyPath: "originalBottomRow",
|
||||||
|
propertyValue: undefined,
|
||||||
|
});
|
||||||
|
updates.push({
|
||||||
|
propertyPath: "originalTopRow",
|
||||||
|
propertyValue: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following are updates which apply to specific widgets.
|
||||||
|
if (
|
||||||
|
propertyValue === "AUTO_HEIGHT" ||
|
||||||
|
propertyValue === "AUTO_HEIGHT_WITH_LIMITS"
|
||||||
|
) {
|
||||||
|
if (props.dynamicHeight === "FIXED") {
|
||||||
|
updates.push({
|
||||||
|
propertyPath: "originalBottomRow",
|
||||||
|
propertyValue: props.bottomRow,
|
||||||
|
});
|
||||||
|
updates.push({
|
||||||
|
propertyPath: "originalTopRow",
|
||||||
|
propertyValue: props.topRow,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!props.shouldScrollContents) {
|
||||||
|
updates.push({
|
||||||
|
propertyPath: "shouldScrollContents",
|
||||||
|
propertyValue: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (props.overflow !== undefined) {
|
||||||
|
updates.push({
|
||||||
|
propertyPath: "overflow",
|
||||||
|
propertyValue: "NONE",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (props.scrollContents === true) {
|
||||||
|
updates.push({
|
||||||
|
propertyPath: "scrollContents",
|
||||||
|
propertyValue: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (props.fixedFooter === true) {
|
||||||
|
updates.push({
|
||||||
|
propertyPath: "fixedFooter",
|
||||||
|
propertyValue: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return updates;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PropertyPaneConfigTemplates: Record<string, any[]> = {
|
||||||
|
dynamicHeight: [
|
||||||
|
{
|
||||||
|
helpText:
|
||||||
|
"Auto Height: Configure the way the widget height reacts to content changes.",
|
||||||
|
propertyName: "dynamicHeight",
|
||||||
|
label: "Height",
|
||||||
|
controlType: "DROP_DOWN",
|
||||||
|
isBindProperty: false,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
dependencies: [
|
||||||
|
"shouldScrollContents",
|
||||||
|
"maxDynamicHeight",
|
||||||
|
"minDynamicHeight",
|
||||||
|
"bottomRow",
|
||||||
|
"topRow",
|
||||||
|
"overflow",
|
||||||
|
"dynamicHeight",
|
||||||
|
"isCanvas",
|
||||||
|
],
|
||||||
|
updateHook: updateMinMaxDynamicHeight,
|
||||||
|
helperText: (props: any) => {
|
||||||
|
return props.isCanvas && props.dynamicHeight === "AUTO_HEIGHT"
|
||||||
|
? "This widget shows an internal scroll when you add widgets in edit mode. It'll resize after you've added widgets. The scroll won't exist in view mode."
|
||||||
|
: "";
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: "Auto Height",
|
||||||
|
value: "AUTO_HEIGHT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Auto Height with limits",
|
||||||
|
value: "AUTO_HEIGHT_WITH_LIMITS",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Fixed",
|
||||||
|
value: "FIXED",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
postUpdateAction: "CHECK_CONTAINERS_FOR_AUTO_HEIGHT",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
function findAndUpdatePropertyPaneControlConfig(
|
||||||
|
config: any[],
|
||||||
|
propertyPaneUpdates: Record<string, Record<string, unknown>>,
|
||||||
|
): any[] {
|
||||||
|
return config.map((sectionConfig: any) => {
|
||||||
|
if (
|
||||||
|
Array.isArray(sectionConfig.children) &&
|
||||||
|
sectionConfig.children.length > 0
|
||||||
|
) {
|
||||||
|
Object.keys(propertyPaneUpdates).forEach((propertyName: string) => {
|
||||||
|
const controlConfigIndex: number | undefined =
|
||||||
|
sectionConfig.children?.findIndex(
|
||||||
|
(controlConfig: any) => controlConfig.propertyName === propertyName,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
controlConfigIndex !== undefined &&
|
||||||
|
controlConfigIndex > -1 &&
|
||||||
|
sectionConfig.children
|
||||||
|
) {
|
||||||
|
sectionConfig.children[controlConfigIndex] = {
|
||||||
|
...sectionConfig.children[controlConfigIndex],
|
||||||
|
...propertyPaneUpdates[propertyName],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return sectionConfig;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const WidgetFeaturePropertyPaneEnhancements: Record<
|
||||||
|
string,
|
||||||
|
(config: any[], widgetType?: string) => any[]
|
||||||
|
> = {
|
||||||
|
dynamicHeight: (config: any[], widgetType?: string) => {
|
||||||
|
function hideWhenDynamicHeightIsEnabled(props: any) {
|
||||||
|
return (
|
||||||
|
props.dynamicHeight === "AUTO_HEIGHT_WITH_LIMITS" ||
|
||||||
|
props.dynamicHeight === "AUTO_HEIGHT"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let update = findAndUpdatePropertyPaneControlConfig(config, {
|
||||||
|
shouldScrollContents: {
|
||||||
|
hidden: hideWhenDynamicHeightIsEnabled,
|
||||||
|
dependencies: ["dynamicHeight"],
|
||||||
|
},
|
||||||
|
scrollContents: {
|
||||||
|
hidden: hideWhenDynamicHeightIsEnabled,
|
||||||
|
dependencies: ["dynamicHeight"],
|
||||||
|
},
|
||||||
|
fixedFooter: {
|
||||||
|
hidden: hideWhenDynamicHeightIsEnabled,
|
||||||
|
dependencies: ["dynamicHeight"],
|
||||||
|
},
|
||||||
|
overflow: {
|
||||||
|
hidden: hideWhenDynamicHeightIsEnabled,
|
||||||
|
dependencies: ["dynamicHeight"],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (widgetType === "MODAL_WIDGET") {
|
||||||
|
update = findAndUpdatePropertyPaneControlConfig(update, {
|
||||||
|
dynamicHeight: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: "Auto Height",
|
||||||
|
value: "AUTO_HEIGHT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Fixed",
|
||||||
|
value: "FIXED",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return update;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function enhancePropertyPaneConfig(
|
||||||
|
config: any[],
|
||||||
|
features?: any,
|
||||||
|
configType?: string,
|
||||||
|
widgetType?: string,
|
||||||
|
) {
|
||||||
|
// Enhance property pane with widget features
|
||||||
|
// TODO(abhinav): The following "configType" check should come
|
||||||
|
// from the features themselves.
|
||||||
|
|
||||||
|
if (features && (configType === undefined || configType === "CONTENT")) {
|
||||||
|
Object.keys(features).forEach((registeredFeature: string) => {
|
||||||
|
const { sectionIndex } = features[registeredFeature];
|
||||||
|
const sectionName = config[sectionIndex]?.sectionName;
|
||||||
|
// This has been designed to check if the sectionIndex provided in the
|
||||||
|
// features configuration of the widget to point to the section named "General"
|
||||||
|
// If not, it logs an error
|
||||||
|
// This is a sanity check, and doesn't effect the functionality of the feature
|
||||||
|
// For consistency, we expect that all "Auto Height" property pane controls
|
||||||
|
// be present in the "General" section of the property pane
|
||||||
|
if (!sectionName || sectionName !== "General") {
|
||||||
|
log.error(
|
||||||
|
`Invalid section index for feature: ${registeredFeature} in widget: ${widgetType}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
Array.isArray(config[sectionIndex].children) &&
|
||||||
|
PropertyPaneConfigTemplates[registeredFeature]
|
||||||
|
) {
|
||||||
|
config[sectionIndex].children?.push(
|
||||||
|
...PropertyPaneConfigTemplates[registeredFeature],
|
||||||
|
);
|
||||||
|
config = WidgetFeaturePropertyPaneEnhancements[registeredFeature](
|
||||||
|
config,
|
||||||
|
widgetType,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function convertFunctionsToString(config: any[]) {
|
||||||
|
return config.map((sectionOrControlConfig: any) => {
|
||||||
|
const controlConfig = sectionOrControlConfig;
|
||||||
|
if (
|
||||||
|
controlConfig.validation &&
|
||||||
|
controlConfig.validation?.type === "FUNCTION" &&
|
||||||
|
controlConfig.validation?.params &&
|
||||||
|
controlConfig.validation?.params.fn
|
||||||
|
) {
|
||||||
|
controlConfig.validation.params.fnString =
|
||||||
|
controlConfig.validation.params.fn.toString();
|
||||||
|
delete controlConfig.validation.params.fn;
|
||||||
|
return sectionOrControlConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sectionOrControlConfig.children) {
|
||||||
|
sectionOrControlConfig.children = convertFunctionsToString(
|
||||||
|
sectionOrControlConfig.children,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = sectionOrControlConfig;
|
||||||
|
|
||||||
|
if (
|
||||||
|
config.panelConfig &&
|
||||||
|
config.panelConfig.children &&
|
||||||
|
Array.isArray(config.panelConfig.children)
|
||||||
|
) {
|
||||||
|
config.panelConfig.children = convertFunctionsToString(
|
||||||
|
config.panelConfig.children,
|
||||||
|
);
|
||||||
|
|
||||||
|
sectionOrControlConfig = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
config.panelConfig &&
|
||||||
|
config.panelConfig.contentChildren &&
|
||||||
|
Array.isArray(config.panelConfig.contentChildren)
|
||||||
|
) {
|
||||||
|
config.panelConfig.contentChildren = convertFunctionsToString(
|
||||||
|
config.panelConfig.contentChildren,
|
||||||
|
);
|
||||||
|
|
||||||
|
sectionOrControlConfig = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
config.panelConfig &&
|
||||||
|
config.panelConfig.styleChildren &&
|
||||||
|
Array.isArray(config.panelConfig.styleChildren)
|
||||||
|
) {
|
||||||
|
config.panelConfig.styleChildren = convertFunctionsToString(
|
||||||
|
config.panelConfig.styleChildren,
|
||||||
|
);
|
||||||
|
|
||||||
|
sectionOrControlConfig = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sectionOrControlConfig;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export const addPropertyConfigIds = (config: any[]) => {
|
||||||
|
return config.map((sectionOrControlConfig: any) => {
|
||||||
|
sectionOrControlConfig.id = generateReactKey();
|
||||||
|
if (sectionOrControlConfig.children) {
|
||||||
|
sectionOrControlConfig.children = addPropertyConfigIds(
|
||||||
|
sectionOrControlConfig.children,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const config = sectionOrControlConfig;
|
||||||
|
if (config.panelConfig) {
|
||||||
|
if (
|
||||||
|
config.panelConfig.children &&
|
||||||
|
Array.isArray(config.panelConfig.children)
|
||||||
|
) {
|
||||||
|
config.panelConfig.children = addPropertyConfigIds(
|
||||||
|
config.panelConfig.children,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
config.panelConfig.contentChildren &&
|
||||||
|
Array.isArray(config.panelConfig.contentChildren)
|
||||||
|
) {
|
||||||
|
config.panelConfig.contentChildren = addPropertyConfigIds(
|
||||||
|
config.panelConfig.contentChildren,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
config.panelConfig.styleChildren &&
|
||||||
|
Array.isArray(config.panelConfig.styleChildren)
|
||||||
|
) {
|
||||||
|
config.panelConfig.styleChildren = addPropertyConfigIds(
|
||||||
|
config.panelConfig.styleChildren,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
sectionOrControlConfig = config;
|
||||||
|
}
|
||||||
|
return sectionOrControlConfig;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function addSearchSpecificPropertiesToConfig(
|
||||||
|
config: readonly any[],
|
||||||
|
tag: string,
|
||||||
|
): any[] {
|
||||||
|
return config.map((configItem) => {
|
||||||
|
if (configItem.sectionName) {
|
||||||
|
const sectionConfig = {
|
||||||
|
...configItem,
|
||||||
|
collapsible: false,
|
||||||
|
tag,
|
||||||
|
};
|
||||||
|
if (configItem.children) {
|
||||||
|
sectionConfig.children = addSearchSpecificPropertiesToConfig(
|
||||||
|
configItem.children,
|
||||||
|
tag,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return sectionConfig;
|
||||||
|
} else if (configItem.controlType) {
|
||||||
|
const controlConfig = configItem;
|
||||||
|
if (controlConfig.panelConfig) {
|
||||||
|
return {
|
||||||
|
...controlConfig,
|
||||||
|
panelConfig: {
|
||||||
|
...controlConfig.panelConfig,
|
||||||
|
searchConfig: generatePropertyPaneSearchConfig(
|
||||||
|
controlConfig.panelConfig?.contentChildren ?? [],
|
||||||
|
controlConfig.panelConfig?.styleChildren ?? [],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return controlConfig;
|
||||||
|
}
|
||||||
|
return configItem;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generatePropertyPaneSearchConfig(
|
||||||
|
contentConfig: readonly any[],
|
||||||
|
styleConfig: readonly any[],
|
||||||
|
) {
|
||||||
|
return [
|
||||||
|
...addSearchSpecificPropertiesToConfig(contentConfig, "CONTENT"),
|
||||||
|
...addSearchSpecificPropertiesToConfig(styleConfig, "STYLE"),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addSearchConfigToPanelConfig(config: readonly any[]) {
|
||||||
|
return config.map((configItem) => {
|
||||||
|
if (configItem.sectionName) {
|
||||||
|
const sectionConfig = {
|
||||||
|
...configItem,
|
||||||
|
};
|
||||||
|
if (configItem.children) {
|
||||||
|
sectionConfig.children = addSearchConfigToPanelConfig(
|
||||||
|
configItem.children,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return sectionConfig;
|
||||||
|
} else if (configItem.controlType) {
|
||||||
|
const controlConfig = configItem;
|
||||||
|
if (controlConfig.panelConfig) {
|
||||||
|
return {
|
||||||
|
...controlConfig,
|
||||||
|
panelConfig: {
|
||||||
|
...controlConfig.panelConfig,
|
||||||
|
searchConfig: generatePropertyPaneSearchConfig(
|
||||||
|
controlConfig.panelConfig?.contentChildren ?? [],
|
||||||
|
controlConfig.panelConfig?.styleChildren ?? [],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return controlConfig;
|
||||||
|
}
|
||||||
|
return configItem;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const getWidgetPropertyPaneContentConfig = (type: string): readonly any[] => {
|
||||||
|
const propertyPaneContentConfig = (widgetConfigs as any)[type]
|
||||||
|
.propertyPaneContentConfig;
|
||||||
|
|
||||||
|
const features = (widgetConfigs as any)[type].features;
|
||||||
|
|
||||||
|
if (propertyPaneContentConfig) {
|
||||||
|
const enhance = flow([
|
||||||
|
enhancePropertyPaneConfig,
|
||||||
|
convertFunctionsToString,
|
||||||
|
addPropertyConfigIds,
|
||||||
|
addSearchConfigToPanelConfig,
|
||||||
|
Object.freeze,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const enhancedPropertyPaneContentConfig = enhance(
|
||||||
|
propertyPaneContentConfig,
|
||||||
|
features,
|
||||||
|
"CONTENT",
|
||||||
|
type,
|
||||||
|
);
|
||||||
|
|
||||||
|
return enhancedPropertyPaneContentConfig;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getWidgetPropertyPaneStyleConfig = (type: string): readonly any[] => {
|
||||||
|
const propertyPaneStyleConfig = (widgetConfigs as any)[type]
|
||||||
|
.propertyPaneStyleConfig;
|
||||||
|
|
||||||
|
const features = (widgetConfigs as any)[type].features;
|
||||||
|
|
||||||
|
if (propertyPaneStyleConfig) {
|
||||||
|
const enhance = flow([
|
||||||
|
enhancePropertyPaneConfig,
|
||||||
|
convertFunctionsToString,
|
||||||
|
addPropertyConfigIds,
|
||||||
|
addSearchConfigToPanelConfig,
|
||||||
|
Object.freeze,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const enhancedPropertyPaneConfig = enhance(
|
||||||
|
propertyPaneStyleConfig,
|
||||||
|
features,
|
||||||
|
"STYLE",
|
||||||
|
);
|
||||||
|
|
||||||
|
return enhancedPropertyPaneConfig;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getWidgetPropertyPaneCombinedConfig = (type: string): readonly any[] => {
|
||||||
|
const contentConfig = getWidgetPropertyPaneContentConfig(type);
|
||||||
|
const styleConfig = getWidgetPropertyPaneStyleConfig(type);
|
||||||
|
return [...contentConfig, ...styleConfig];
|
||||||
|
};
|
||||||
|
|
||||||
|
const getWidgetPropertyPaneConfig = (type: string): readonly any[] => {
|
||||||
|
const propertyPaneConfig = (widgetConfigs as any)[type].propertyPaneConfig;
|
||||||
|
|
||||||
|
const features = (widgetConfigs as any)[type].features;
|
||||||
|
|
||||||
|
if (Array.isArray(propertyPaneConfig) && propertyPaneConfig.length > 0) {
|
||||||
|
const enhance = flow([
|
||||||
|
enhancePropertyPaneConfig,
|
||||||
|
convertFunctionsToString,
|
||||||
|
addPropertyConfigIds,
|
||||||
|
Object.freeze,
|
||||||
|
]);
|
||||||
|
const enhancedPropertyPaneConfig = enhance(propertyPaneConfig, features);
|
||||||
|
|
||||||
|
return enhancedPropertyPaneConfig;
|
||||||
|
} else {
|
||||||
|
const config = getWidgetPropertyPaneCombinedConfig(type);
|
||||||
|
|
||||||
|
if (config === undefined) {
|
||||||
|
log.error("Widget property pane config not defined", type);
|
||||||
|
return [];
|
||||||
|
} else {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkPathsInConfig = (
|
||||||
|
config: any,
|
||||||
|
path: string,
|
||||||
|
): {
|
||||||
|
configBindingPaths: any;
|
||||||
|
configReactivePaths: any;
|
||||||
|
configTriggerPaths: Record<string, true>;
|
||||||
|
configValidationPaths: Record<string, any>;
|
||||||
|
} => {
|
||||||
|
const configBindingPaths: any = {};
|
||||||
|
const configTriggerPaths: Record<string, true> = {};
|
||||||
|
const configValidationPaths: Record<any, any> = {};
|
||||||
|
// Purely a Binding Path
|
||||||
|
if (config.isBindProperty && !config.isTriggerProperty) {
|
||||||
|
configBindingPaths[path] = config.evaluationSubstitutionType || "TEMPLATE";
|
||||||
|
if (config.validation) {
|
||||||
|
configValidationPaths[path] = config.validation;
|
||||||
|
}
|
||||||
|
} else if (config.isBindProperty && config.isTriggerProperty) {
|
||||||
|
configTriggerPaths[path] = true;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
configBindingPaths,
|
||||||
|
configReactivePaths: configBindingPaths, // All bindingPaths are reactivePaths.
|
||||||
|
configTriggerPaths,
|
||||||
|
configValidationPaths,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const childHasPanelConfig = (
|
||||||
|
config: any,
|
||||||
|
widget: any,
|
||||||
|
basePath: string,
|
||||||
|
originalWidget: any,
|
||||||
|
) => {
|
||||||
|
const panelPropertyPath = config.propertyName;
|
||||||
|
const widgetPanelPropertyValues = get(widget, panelPropertyPath);
|
||||||
|
|
||||||
|
let bindingPaths: any = {};
|
||||||
|
let reactivePaths: any = {};
|
||||||
|
let triggerPaths: Record<string, true> = {};
|
||||||
|
let validationPaths: Record<any, any> = {};
|
||||||
|
if (widgetPanelPropertyValues) {
|
||||||
|
Object.values(widgetPanelPropertyValues).forEach(
|
||||||
|
(widgetPanelPropertyValue: any) => {
|
||||||
|
const { panelIdPropertyName } = config.panelConfig;
|
||||||
|
const propertyPath = `${basePath}.${widgetPanelPropertyValue[panelIdPropertyName]}`;
|
||||||
|
|
||||||
|
let panelConfigChildren = [
|
||||||
|
...(config.panelConfig.contentChildren || []),
|
||||||
|
...(config.panelConfig.styleChildren || []),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (panelConfigChildren.length === 0)
|
||||||
|
panelConfigChildren = config.panelConfig.children;
|
||||||
|
|
||||||
|
panelConfigChildren.forEach((panelColumnConfig: any) => {
|
||||||
|
let isSectionHidden = false;
|
||||||
|
if ("hidden" in panelColumnConfig) {
|
||||||
|
isSectionHidden = panelColumnConfig.hidden(
|
||||||
|
originalWidget,
|
||||||
|
propertyPath,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!isSectionHidden) {
|
||||||
|
panelColumnConfig.children.forEach(
|
||||||
|
(panelColumnControlOrSectionConfig: any) => {
|
||||||
|
if (
|
||||||
|
panelColumnControlOrSectionConfig.sectionName !== undefined
|
||||||
|
) {
|
||||||
|
panelColumnControlOrSectionConfig.children.forEach(
|
||||||
|
(panelColumnControlConfig: any) => {
|
||||||
|
const panelPropertyConfigPath = `${propertyPath}.${panelColumnControlConfig.propertyName}`;
|
||||||
|
let isControlHidden = false;
|
||||||
|
if ("hidden" in panelColumnControlConfig) {
|
||||||
|
isControlHidden = panelColumnControlConfig.hidden(
|
||||||
|
originalWidget,
|
||||||
|
panelPropertyConfigPath,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!isControlHidden) {
|
||||||
|
const {
|
||||||
|
configBindingPaths,
|
||||||
|
configReactivePaths,
|
||||||
|
configTriggerPaths,
|
||||||
|
configValidationPaths,
|
||||||
|
} = checkPathsInConfig(
|
||||||
|
panelColumnControlConfig,
|
||||||
|
panelPropertyConfigPath,
|
||||||
|
);
|
||||||
|
bindingPaths = {
|
||||||
|
...configBindingPaths,
|
||||||
|
...bindingPaths,
|
||||||
|
};
|
||||||
|
reactivePaths = {
|
||||||
|
...configReactivePaths,
|
||||||
|
...reactivePaths,
|
||||||
|
};
|
||||||
|
triggerPaths = {
|
||||||
|
...configTriggerPaths,
|
||||||
|
...triggerPaths,
|
||||||
|
};
|
||||||
|
validationPaths = {
|
||||||
|
...configValidationPaths,
|
||||||
|
...validationPaths,
|
||||||
|
};
|
||||||
|
// Has child Panel Config
|
||||||
|
if (panelColumnControlConfig.panelConfig) {
|
||||||
|
const {
|
||||||
|
bindingPaths: panelBindingPaths,
|
||||||
|
reactivePaths: panelReactivePaths,
|
||||||
|
triggerPaths: panelTriggerPaths,
|
||||||
|
validationPaths: panelValidationPaths,
|
||||||
|
} = childHasPanelConfig(
|
||||||
|
panelColumnControlConfig,
|
||||||
|
widgetPanelPropertyValue,
|
||||||
|
panelPropertyConfigPath,
|
||||||
|
originalWidget,
|
||||||
|
);
|
||||||
|
bindingPaths = {
|
||||||
|
...panelBindingPaths,
|
||||||
|
...bindingPaths,
|
||||||
|
};
|
||||||
|
reactivePaths = {
|
||||||
|
...panelReactivePaths,
|
||||||
|
...reactivePaths,
|
||||||
|
};
|
||||||
|
triggerPaths = {
|
||||||
|
...panelTriggerPaths,
|
||||||
|
...triggerPaths,
|
||||||
|
};
|
||||||
|
validationPaths = {
|
||||||
|
...panelValidationPaths,
|
||||||
|
...validationPaths,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const panelPropertyConfigPath = `${propertyPath}.${panelColumnControlOrSectionConfig.propertyName}`;
|
||||||
|
let isControlHidden = false;
|
||||||
|
if ("hidden" in panelColumnControlOrSectionConfig) {
|
||||||
|
isControlHidden = panelColumnControlOrSectionConfig.hidden(
|
||||||
|
originalWidget,
|
||||||
|
panelPropertyConfigPath,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!isControlHidden) {
|
||||||
|
const {
|
||||||
|
configBindingPaths,
|
||||||
|
configReactivePaths,
|
||||||
|
configTriggerPaths,
|
||||||
|
configValidationPaths,
|
||||||
|
} = checkPathsInConfig(
|
||||||
|
panelColumnControlOrSectionConfig,
|
||||||
|
panelPropertyConfigPath,
|
||||||
|
);
|
||||||
|
bindingPaths = {
|
||||||
|
...configBindingPaths,
|
||||||
|
...bindingPaths,
|
||||||
|
};
|
||||||
|
reactivePaths = {
|
||||||
|
...configReactivePaths,
|
||||||
|
...reactivePaths,
|
||||||
|
};
|
||||||
|
triggerPaths = { ...configTriggerPaths, ...triggerPaths };
|
||||||
|
validationPaths = {
|
||||||
|
...configValidationPaths,
|
||||||
|
...validationPaths,
|
||||||
|
};
|
||||||
|
// Has child Panel Config
|
||||||
|
if (panelColumnControlOrSectionConfig.panelConfig) {
|
||||||
|
const {
|
||||||
|
bindingPaths: panelBindingPaths,
|
||||||
|
reactivePaths: panelReactivePaths,
|
||||||
|
triggerPaths: panelTriggerPaths,
|
||||||
|
validationPaths: panelValidationPaths,
|
||||||
|
} = childHasPanelConfig(
|
||||||
|
panelColumnControlOrSectionConfig,
|
||||||
|
widgetPanelPropertyValue,
|
||||||
|
panelPropertyConfigPath,
|
||||||
|
originalWidget,
|
||||||
|
);
|
||||||
|
bindingPaths = {
|
||||||
|
...panelBindingPaths,
|
||||||
|
...bindingPaths,
|
||||||
|
};
|
||||||
|
reactivePaths = {
|
||||||
|
...panelReactivePaths,
|
||||||
|
...reactivePaths,
|
||||||
|
};
|
||||||
|
triggerPaths = { ...panelTriggerPaths, ...triggerPaths };
|
||||||
|
validationPaths = {
|
||||||
|
...panelValidationPaths,
|
||||||
|
...validationPaths,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { reactivePaths, triggerPaths, validationPaths, bindingPaths };
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAllPathsFromPropertyConfigWithoutMemo = (
|
||||||
|
widget: any,
|
||||||
|
widgetConfig: readonly any[],
|
||||||
|
defaultProperties: Record<string, any>,
|
||||||
|
): {
|
||||||
|
bindingPaths: any;
|
||||||
|
reactivePaths: any;
|
||||||
|
triggerPaths: Record<string, true>;
|
||||||
|
validationPaths: Record<string, any>;
|
||||||
|
} => {
|
||||||
|
let bindingPaths: any = {};
|
||||||
|
let reactivePaths: any = {};
|
||||||
|
Object.keys(defaultProperties).forEach((property) => {
|
||||||
|
reactivePaths[property] = "TEMPLATE";
|
||||||
|
});
|
||||||
|
let triggerPaths: Record<string, true> = {};
|
||||||
|
let validationPaths: Record<any, any> = {};
|
||||||
|
|
||||||
|
widgetConfig.forEach((config) => {
|
||||||
|
if (config.children) {
|
||||||
|
config.children.forEach((controlConfig: any) => {
|
||||||
|
const basePath = controlConfig.propertyName;
|
||||||
|
let isHidden = false;
|
||||||
|
if ("hidden" in controlConfig) {
|
||||||
|
isHidden = controlConfig.hidden(widget, basePath);
|
||||||
|
}
|
||||||
|
if (!isHidden) {
|
||||||
|
const path = controlConfig.propertyName;
|
||||||
|
const {
|
||||||
|
configBindingPaths,
|
||||||
|
configReactivePaths,
|
||||||
|
configTriggerPaths,
|
||||||
|
configValidationPaths,
|
||||||
|
} = checkPathsInConfig(controlConfig, path);
|
||||||
|
bindingPaths = {
|
||||||
|
...bindingPaths,
|
||||||
|
...configBindingPaths,
|
||||||
|
};
|
||||||
|
// Update default path configs with the ones in the property config
|
||||||
|
reactivePaths = {
|
||||||
|
...reactivePaths,
|
||||||
|
...configReactivePaths,
|
||||||
|
};
|
||||||
|
triggerPaths = { ...triggerPaths, ...configTriggerPaths };
|
||||||
|
validationPaths = { ...validationPaths, ...configValidationPaths };
|
||||||
|
}
|
||||||
|
// Has child Panel Config
|
||||||
|
if (controlConfig.panelConfig) {
|
||||||
|
const resultingPaths = childHasPanelConfig(
|
||||||
|
controlConfig,
|
||||||
|
widget,
|
||||||
|
basePath,
|
||||||
|
widget,
|
||||||
|
);
|
||||||
|
bindingPaths = {
|
||||||
|
...bindingPaths,
|
||||||
|
...resultingPaths.bindingPaths,
|
||||||
|
};
|
||||||
|
reactivePaths = {
|
||||||
|
...reactivePaths,
|
||||||
|
...resultingPaths.reactivePaths,
|
||||||
|
};
|
||||||
|
triggerPaths = { ...triggerPaths, ...resultingPaths.triggerPaths };
|
||||||
|
validationPaths = {
|
||||||
|
...validationPaths,
|
||||||
|
...resultingPaths.validationPaths,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (controlConfig.children) {
|
||||||
|
const basePropertyPath = controlConfig.propertyName;
|
||||||
|
const widgetPropertyValue = get(widget, basePropertyPath, []);
|
||||||
|
// Property in object structure
|
||||||
|
if (
|
||||||
|
!isUndefined(widgetPropertyValue) &&
|
||||||
|
isObject(widgetPropertyValue)
|
||||||
|
) {
|
||||||
|
Object.keys(widgetPropertyValue).forEach((key: string) => {
|
||||||
|
const objectIndexPropertyPath = `${basePropertyPath}.${key}`;
|
||||||
|
controlConfig.children.forEach((childPropertyConfig: any) => {
|
||||||
|
const childArrayPropertyPath = `${objectIndexPropertyPath}.${childPropertyConfig.propertyName}`;
|
||||||
|
const {
|
||||||
|
configBindingPaths,
|
||||||
|
configReactivePaths,
|
||||||
|
configTriggerPaths,
|
||||||
|
configValidationPaths,
|
||||||
|
} = checkPathsInConfig(
|
||||||
|
childPropertyConfig,
|
||||||
|
childArrayPropertyPath,
|
||||||
|
);
|
||||||
|
bindingPaths = {
|
||||||
|
...bindingPaths,
|
||||||
|
...configBindingPaths,
|
||||||
|
};
|
||||||
|
reactivePaths = {
|
||||||
|
...reactivePaths,
|
||||||
|
...configReactivePaths,
|
||||||
|
};
|
||||||
|
triggerPaths = { ...triggerPaths, ...configTriggerPaths };
|
||||||
|
validationPaths = {
|
||||||
|
...validationPaths,
|
||||||
|
...configValidationPaths,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { reactivePaths, triggerPaths, validationPaths, bindingPaths };
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAllPathsFromPropertyConfig = memoize(
|
||||||
|
getAllPathsFromPropertyConfigWithoutMemo,
|
||||||
|
{ maxSize: 1000 },
|
||||||
|
);
|
||||||
|
|
||||||
|
export const migrateIncorrectDynamicBindingPathLists = (
|
||||||
|
currentDSL: Readonly<DSLWidget>,
|
||||||
|
): DSLWidget => {
|
||||||
|
const migratedDsl = {
|
||||||
|
...currentDSL,
|
||||||
|
};
|
||||||
|
const dynamicBindingPathList: any[] = [];
|
||||||
|
const propertyPaneConfig = getWidgetPropertyPaneConfig(currentDSL.type);
|
||||||
|
const { bindingPaths } = getAllPathsFromPropertyConfig(
|
||||||
|
currentDSL,
|
||||||
|
propertyPaneConfig,
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
Object.keys(bindingPaths).forEach((bindingPath) => {
|
||||||
|
const pathValue = get(migratedDsl, bindingPath);
|
||||||
|
if (pathValue && isString(pathValue)) {
|
||||||
|
if (isDynamicValue(pathValue)) {
|
||||||
|
dynamicBindingPathList.push({ key: bindingPath });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
migratedDsl.dynamicBindingPathList = dynamicBindingPathList;
|
||||||
|
|
||||||
|
if (currentDSL.children) {
|
||||||
|
migratedDsl.children = currentDSL.children.map(
|
||||||
|
migrateIncorrectDynamicBindingPathLists,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return migratedDsl;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import isString from "lodash/isString";
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateOldChartData = (currentDSL: DSLWidget) => {
|
||||||
|
if (currentDSL.type === "CHART_WIDGET") {
|
||||||
|
if (isString(currentDSL.chartData)) {
|
||||||
|
try {
|
||||||
|
currentDSL.chartData = JSON.parse(currentDSL.chartData);
|
||||||
|
} catch (error) {
|
||||||
|
// Sentry.captureException({
|
||||||
|
// message: "Chart Migration F`ailed",
|
||||||
|
// oldData: currentDSL.chartData,
|
||||||
|
// });
|
||||||
|
currentDSL.chartData = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map(migrateOldChartData);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const rteDefaultValueMigration = (currentDSL: DSLWidget): DSLWidget => {
|
||||||
|
if (currentDSL.type === "RICH_TEXT_EDITOR_WIDGET") {
|
||||||
|
currentDSL.inputType = "html";
|
||||||
|
}
|
||||||
|
currentDSL.children?.forEach((children: DSLWidget) =>
|
||||||
|
rteDefaultValueMigration(children),
|
||||||
|
);
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateTextStyleFromTextWidget = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
): DSLWidget => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "TEXT_WIDGET") {
|
||||||
|
const textStyle = child.textStyle;
|
||||||
|
switch (textStyle) {
|
||||||
|
case "HEADING":
|
||||||
|
child.fontSize = "HEADING1";
|
||||||
|
child.fontStyle = "BOLD";
|
||||||
|
break;
|
||||||
|
case "BODY":
|
||||||
|
child.fontSize = "PARAGRAPH";
|
||||||
|
child.fontStyle = "";
|
||||||
|
break;
|
||||||
|
case "LABEL":
|
||||||
|
child.fontSize = "PARAGRAPH";
|
||||||
|
child.fontStyle = "BOLD";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
child.textColor = "#231F20";
|
||||||
|
delete child.textStyle;
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateTextStyleFromTextWidget(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { set } from "lodash";
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
import { generateReactKey } from "../utils";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* changes chartData which we were using as array. now it will be a object
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param currentDSL
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const migrateChartDataFromArrayToObject = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((children: DSLWidget) => {
|
||||||
|
if (children.type === "CHART_WIDGET") {
|
||||||
|
if (Array.isArray(children.chartData)) {
|
||||||
|
const newChartData = {};
|
||||||
|
const dynamicBindingPathList = children?.dynamicBindingPathList
|
||||||
|
? children?.dynamicBindingPathList.slice()
|
||||||
|
: [];
|
||||||
|
|
||||||
|
children.chartData.map((datum: any, index: number) => {
|
||||||
|
const generatedKey = generateReactKey();
|
||||||
|
set(newChartData, `${generatedKey}`, datum);
|
||||||
|
|
||||||
|
if (
|
||||||
|
Array.isArray(children.dynamicBindingPathList) &&
|
||||||
|
children.dynamicBindingPathList?.findIndex(
|
||||||
|
(path: { key: string }) =>
|
||||||
|
(path.key = `chartData[${index}].data`),
|
||||||
|
) > -1
|
||||||
|
) {
|
||||||
|
const foundIndex = children.dynamicBindingPathList.findIndex(
|
||||||
|
(path: { key: string }) =>
|
||||||
|
(path.key = `chartData[${index}].data`),
|
||||||
|
);
|
||||||
|
|
||||||
|
dynamicBindingPathList[foundIndex] = {
|
||||||
|
key: `chartData.${generatedKey}.data`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
children.dynamicBindingPathList = dynamicBindingPathList;
|
||||||
|
children.chartData = newChartData;
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
children.type === "CONTAINER_WIDGET" ||
|
||||||
|
children.type === "FORM_WIDGET" ||
|
||||||
|
children.type === "CANVAS_WIDGET" ||
|
||||||
|
children.type === "TABS_WIDGET"
|
||||||
|
) {
|
||||||
|
children = migrateChartDataFromArrayToObject(children);
|
||||||
|
}
|
||||||
|
|
||||||
|
return children;
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { isString } from "lodash";
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
import { DATA_BIND_REGEX_GLOBAL } from "../utils";
|
||||||
|
|
||||||
|
function migrateTabsDataUsingMigrator(currentDSL: DSLWidget) {
|
||||||
|
if (currentDSL.type === "TABS_WIDGET" && currentDSL.version === 1) {
|
||||||
|
try {
|
||||||
|
currentDSL.type = "TABS_MIGRATOR_WIDGET";
|
||||||
|
currentDSL.version = 1;
|
||||||
|
} catch (error) {
|
||||||
|
// Sentry.captureException({
|
||||||
|
// message: "Tabs Migration Failed",
|
||||||
|
// oldData: currentDSL.tabs,
|
||||||
|
// });
|
||||||
|
currentDSL.tabsObj = {};
|
||||||
|
delete currentDSL.tabs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map(migrateTabsDataUsingMigrator);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const migrateTabsData = (currentDSL: DSLWidget) => {
|
||||||
|
if (
|
||||||
|
["TABS_WIDGET", "TABS_MIGRATOR_WIDGET"].includes(currentDSL.type) &&
|
||||||
|
currentDSL.version === 1
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
currentDSL.type = "TABS_WIDGET";
|
||||||
|
const isTabsDataBinded = isString(currentDSL.tabs);
|
||||||
|
currentDSL.dynamicPropertyPathList =
|
||||||
|
currentDSL.dynamicPropertyPathList || [];
|
||||||
|
currentDSL.dynamicBindingPathList =
|
||||||
|
currentDSL.dynamicBindingPathList || [];
|
||||||
|
|
||||||
|
if (isTabsDataBinded) {
|
||||||
|
const tabsString = currentDSL.tabs.replace(
|
||||||
|
DATA_BIND_REGEX_GLOBAL,
|
||||||
|
(word: any) => `"${word}"`,
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
currentDSL.tabs = JSON.parse(tabsString);
|
||||||
|
} catch (error) {
|
||||||
|
return migrateTabsDataUsingMigrator(currentDSL);
|
||||||
|
}
|
||||||
|
const dynamicPropsList = currentDSL.tabs
|
||||||
|
.filter((each: any) => DATA_BIND_REGEX_GLOBAL.test(each.isVisible))
|
||||||
|
.map((each: any) => {
|
||||||
|
return { key: `tabsObj.${each.id}.isVisible` };
|
||||||
|
});
|
||||||
|
const dynamicBindablePropsList = currentDSL.tabs.map((each: any) => {
|
||||||
|
return { key: `tabsObj.${each.id}.isVisible` };
|
||||||
|
});
|
||||||
|
currentDSL.dynamicPropertyPathList = [
|
||||||
|
...currentDSL.dynamicPropertyPathList,
|
||||||
|
...dynamicPropsList,
|
||||||
|
];
|
||||||
|
currentDSL.dynamicBindingPathList = [
|
||||||
|
...currentDSL.dynamicBindingPathList,
|
||||||
|
...dynamicBindablePropsList,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
currentDSL.dynamicPropertyPathList =
|
||||||
|
currentDSL.dynamicPropertyPathList.filter((each: { key: string }) => {
|
||||||
|
return each.key !== "tabs";
|
||||||
|
});
|
||||||
|
currentDSL.dynamicBindingPathList =
|
||||||
|
currentDSL.dynamicBindingPathList.filter((each: { key: string }) => {
|
||||||
|
return each.key !== "tabs";
|
||||||
|
});
|
||||||
|
currentDSL.tabsObj = currentDSL.tabs.reduce(
|
||||||
|
(obj: any, tab: any, index: number) => {
|
||||||
|
obj = {
|
||||||
|
...obj,
|
||||||
|
[tab.id]: {
|
||||||
|
...tab,
|
||||||
|
isVisible: tab.isVisible === undefined ? true : tab.isVisible,
|
||||||
|
index,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
currentDSL.version = 2;
|
||||||
|
delete currentDSL.tabs;
|
||||||
|
} catch (error) {
|
||||||
|
// Sentry.captureException({
|
||||||
|
// message: "Tabs Migration Failed",
|
||||||
|
// oldData: currentDSL.tabs,
|
||||||
|
// });
|
||||||
|
currentDSL.tabsObj = {};
|
||||||
|
delete currentDSL.tabs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map(migrateTabsData);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateInitialValues = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "INPUT_WIDGET") {
|
||||||
|
child = {
|
||||||
|
isRequired: false,
|
||||||
|
isDisabled: false,
|
||||||
|
resetOnSubmit: false,
|
||||||
|
...child,
|
||||||
|
};
|
||||||
|
} else if (child.type === "DROP_DOWN_WIDGET") {
|
||||||
|
child = {
|
||||||
|
isRequired: false,
|
||||||
|
isDisabled: false,
|
||||||
|
...child,
|
||||||
|
};
|
||||||
|
} else if (child.type === "DATE_PICKER_WIDGET2") {
|
||||||
|
child = {
|
||||||
|
minDate: "2001-01-01 00:00",
|
||||||
|
maxDate: "2041-12-31 23:59",
|
||||||
|
isRequired: false,
|
||||||
|
...child,
|
||||||
|
};
|
||||||
|
} else if (child.type === "SWITCH_WIDGET") {
|
||||||
|
child = {
|
||||||
|
isDisabled: false,
|
||||||
|
...child,
|
||||||
|
};
|
||||||
|
} else if (child.type === "ICON_WIDGET") {
|
||||||
|
child = {
|
||||||
|
isRequired: false,
|
||||||
|
...child,
|
||||||
|
};
|
||||||
|
} else if (child.type === "VIDEO_WIDGET") {
|
||||||
|
child = {
|
||||||
|
isRequired: false,
|
||||||
|
isDisabled: false,
|
||||||
|
...child,
|
||||||
|
};
|
||||||
|
} else if (child.type === "CHECKBOX_WIDGET") {
|
||||||
|
child = {
|
||||||
|
isDisabled: false,
|
||||||
|
isRequired: false,
|
||||||
|
...child,
|
||||||
|
};
|
||||||
|
} else if (child.type === "RADIO_GROUP_WIDGET") {
|
||||||
|
child = {
|
||||||
|
isDisabled: false,
|
||||||
|
isRequired: false,
|
||||||
|
...child,
|
||||||
|
};
|
||||||
|
} else if (child.type === "FILE_PICKER_WIDGET") {
|
||||||
|
child = {
|
||||||
|
isDisabled: false,
|
||||||
|
isRequired: false,
|
||||||
|
allowedFileTypes: [],
|
||||||
|
...child,
|
||||||
|
};
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateInitialValues(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
const DEFAULT_GRID_ROW_HEIGHT = 10;
|
||||||
|
const GRID_DENSITY_MIGRATION_V1 = 4;
|
||||||
|
|
||||||
|
export const getCanvasSnapRows = (
|
||||||
|
bottomRow: number,
|
||||||
|
mobileBottomRow?: number,
|
||||||
|
isMobile?: boolean,
|
||||||
|
isAutoLayoutActive?: boolean,
|
||||||
|
): number => {
|
||||||
|
const bottom =
|
||||||
|
isMobile && mobileBottomRow !== undefined && isAutoLayoutActive
|
||||||
|
? mobileBottomRow
|
||||||
|
: bottomRow;
|
||||||
|
const totalRows = Math.floor(bottom / DEFAULT_GRID_ROW_HEIGHT);
|
||||||
|
|
||||||
|
return isAutoLayoutActive ? totalRows : totalRows - 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const migrateToNewLayout = (dsl: DSLWidget) => {
|
||||||
|
const scaleWidget = (widgetProps: DSLWidget) => {
|
||||||
|
widgetProps.bottomRow *= GRID_DENSITY_MIGRATION_V1;
|
||||||
|
widgetProps.topRow *= GRID_DENSITY_MIGRATION_V1;
|
||||||
|
widgetProps.leftColumn *= GRID_DENSITY_MIGRATION_V1;
|
||||||
|
widgetProps.rightColumn *= GRID_DENSITY_MIGRATION_V1;
|
||||||
|
if (widgetProps.children && widgetProps.children.length) {
|
||||||
|
widgetProps.children.forEach((eachWidgetProp: DSLWidget) => {
|
||||||
|
scaleWidget(eachWidgetProp);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
scaleWidget(dsl);
|
||||||
|
return dsl;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import has from "lodash/has";
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateNewlyAddedTabsWidgetsMissingData = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
if (currentDSL.type === "TABS_WIDGET" && currentDSL.version === 2) {
|
||||||
|
try {
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map((each: any) => {
|
||||||
|
if (has(currentDSL, ["leftColumn", "rightColumn", "bottomRow"])) {
|
||||||
|
return each;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...each,
|
||||||
|
leftColumn: 0,
|
||||||
|
rightColumn:
|
||||||
|
(currentDSL.rightColumn - currentDSL.leftColumn) *
|
||||||
|
currentDSL.parentColumnSpace,
|
||||||
|
bottomRow:
|
||||||
|
(currentDSL.bottomRow - currentDSL.topRow) *
|
||||||
|
currentDSL.parentRowSpace,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
currentDSL.version = 3;
|
||||||
|
} catch (error) {
|
||||||
|
// Sentry.captureException({
|
||||||
|
// message: "Tabs Migration to add missing fields Failed",
|
||||||
|
// oldData: currentDSL.children,
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map(
|
||||||
|
migrateNewlyAddedTabsWidgetsMissingData,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { omit, omitBy } from "lodash";
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
const MAIN_CONTAINER_WIDGET_ID = "0";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function gets the next available row for pasting widgets
|
||||||
|
* NOTE: this function excludes modal widget when calculating next available row
|
||||||
|
*
|
||||||
|
* @param parentContainerId
|
||||||
|
* @param canvasWidgets
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const nextAvailableRowInContainer = (
|
||||||
|
parentContainerId: string,
|
||||||
|
canvasWidgets: any,
|
||||||
|
) => {
|
||||||
|
const filteredCanvasWidgets = omitBy(canvasWidgets, (widget) => {
|
||||||
|
return widget.type === "MODAL_WIDGET";
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
Object.values(filteredCanvasWidgets).reduce(
|
||||||
|
(prev: number, next: any) =>
|
||||||
|
next?.parentId === parentContainerId && next.bottomRow > prev
|
||||||
|
? next.bottomRow
|
||||||
|
: prev,
|
||||||
|
0,
|
||||||
|
) + 1
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const migrateWidgetsWithoutLeftRightColumns = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
canvasWidgets: any,
|
||||||
|
) => {
|
||||||
|
if (
|
||||||
|
currentDSL.widgetId !== MAIN_CONTAINER_WIDGET_ID &&
|
||||||
|
!(
|
||||||
|
currentDSL.hasOwnProperty("leftColumn") &&
|
||||||
|
currentDSL.hasOwnProperty("rightColumn")
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const nextRow = nextAvailableRowInContainer(
|
||||||
|
currentDSL.parentId || MAIN_CONTAINER_WIDGET_ID,
|
||||||
|
omit(canvasWidgets, [currentDSL.widgetId]),
|
||||||
|
);
|
||||||
|
canvasWidgets[currentDSL.widgetId].repositioned = true;
|
||||||
|
const leftColumn = 0;
|
||||||
|
// TODO(abhinav): Figure out a way to get the correct values from the widgets
|
||||||
|
const rightColumn = 4;
|
||||||
|
const bottomRow = nextRow + (currentDSL.bottomRow - currentDSL.topRow);
|
||||||
|
const topRow = nextRow;
|
||||||
|
currentDSL = {
|
||||||
|
...currentDSL,
|
||||||
|
topRow,
|
||||||
|
bottomRow,
|
||||||
|
rightColumn,
|
||||||
|
leftColumn,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
// Sentry.captureException({
|
||||||
|
// message: "Migrating position of widget on data loss failed",
|
||||||
|
// oldData: currentDSL,
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map((dsl: DSLWidget) =>
|
||||||
|
migrateWidgetsWithoutLeftRightColumns(dsl, canvasWidgets),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const migrateOverFlowingTabsWidgets = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
canvasWidgets: any,
|
||||||
|
) => {
|
||||||
|
if (
|
||||||
|
currentDSL.type === "TABS_WIDGET" &&
|
||||||
|
currentDSL.version === 3 &&
|
||||||
|
currentDSL.children &&
|
||||||
|
currentDSL.children.length
|
||||||
|
) {
|
||||||
|
const tabsWidgetHeight =
|
||||||
|
(currentDSL.bottomRow - currentDSL.topRow) * currentDSL.parentRowSpace;
|
||||||
|
const widgetHasOverflowingChildren = currentDSL.children.some(
|
||||||
|
(eachTab: DSLWidget) => {
|
||||||
|
if (eachTab.children && eachTab.children.length) {
|
||||||
|
return eachTab.children.some((child: DSLWidget) => {
|
||||||
|
if (canvasWidgets[child.widgetId].repositioned) {
|
||||||
|
const tabHeight = child.bottomRow * child.parentRowSpace;
|
||||||
|
return tabsWidgetHeight < tabHeight;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (widgetHasOverflowingChildren) {
|
||||||
|
currentDSL.shouldScrollContents = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map((eachChild: DSLWidget) =>
|
||||||
|
migrateOverFlowingTabsWidgets(eachChild, canvasWidgets),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateTableWidgetParentRowSpaceProperty = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "TABLE_WIDGET") {
|
||||||
|
if (child.parentRowSpace === 40) {
|
||||||
|
child.parentRowSpace = 10; //GridDefaults.DEFAULT_GRID_ROW_HEIGHT;
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateTableWidgetParentRowSpaceProperty(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { get, set } from "lodash";
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const addLogBlackListToAllListWidgetChildren = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((children: DSLWidget) => {
|
||||||
|
if (children.type === "LIST_WIDGET") {
|
||||||
|
const widgets = get(
|
||||||
|
children,
|
||||||
|
"children.0.children.0.children.0.children",
|
||||||
|
);
|
||||||
|
|
||||||
|
widgets.map((widget: any, index: number) => {
|
||||||
|
const logBlackList: { [key: string]: boolean } = {};
|
||||||
|
|
||||||
|
Object.keys(widget).map((key) => {
|
||||||
|
logBlackList[key] = true;
|
||||||
|
});
|
||||||
|
if (!widget.logBlackList) {
|
||||||
|
set(
|
||||||
|
children,
|
||||||
|
`children.0.children.0.children.0.children.${index}.logBlackList`,
|
||||||
|
logBlackList,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return children;
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateTableWidgetHeaderVisibilityProperties = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "TABLE_WIDGET") {
|
||||||
|
if (!("isVisibleSearch" in child)) {
|
||||||
|
child.isVisibleSearch = true;
|
||||||
|
child.isVisibleFilters = true;
|
||||||
|
child.isVisibleDownload = true;
|
||||||
|
child.isVisiblePagination = true;
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateTableWidgetHeaderVisibilityProperties(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
import get from "lodash/get";
|
||||||
|
import isString from "lodash/isString";
|
||||||
|
import set from "lodash/set";
|
||||||
|
|
||||||
|
const renameKeyInObject = (object: any, key: string, newKey: string) => {
|
||||||
|
if (object[key]) {
|
||||||
|
set(object, newKey, object[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return object;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* changes items -> listData
|
||||||
|
*
|
||||||
|
* @param currentDSL
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const migrateItemsToListDataInListWidget = (currentDSL: DSLWidget) => {
|
||||||
|
if (currentDSL.type === "LIST_WIDGET") {
|
||||||
|
currentDSL = renameKeyInObject(currentDSL, "items", "listData");
|
||||||
|
|
||||||
|
currentDSL.dynamicBindingPathList = currentDSL.dynamicBindingPathList?.map(
|
||||||
|
(path: { key: string }) => {
|
||||||
|
if (path.key === "items") {
|
||||||
|
return { key: "listData" };
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
currentDSL.dynamicBindingPathList?.map((path: { key: string }) => {
|
||||||
|
if (
|
||||||
|
get(currentDSL, path.key) &&
|
||||||
|
path.key !== "items" &&
|
||||||
|
path.key !== "listData" &&
|
||||||
|
isString(get(currentDSL, path.key))
|
||||||
|
) {
|
||||||
|
set(
|
||||||
|
currentDSL,
|
||||||
|
path.key,
|
||||||
|
get(currentDSL, path.key, "").replace("items", "listData"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(currentDSL.template).map((widgetName) => {
|
||||||
|
const currentWidget = currentDSL.template[widgetName];
|
||||||
|
|
||||||
|
currentWidget.dynamicBindingPathList?.map((path: { key: string }) => {
|
||||||
|
set(
|
||||||
|
currentWidget,
|
||||||
|
path.key,
|
||||||
|
get(currentWidget, path.key).replace("items", "listData"),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDSL.children && currentDSL.children.length > 0) {
|
||||||
|
currentDSL.children = currentDSL.children.map(
|
||||||
|
migrateItemsToListDataInListWidget,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateDatePickerMinMaxDate = (currentDSL: DSLWidget) => {
|
||||||
|
if (currentDSL.type === "DATE_PICKER_WIDGET2" && currentDSL.version === 2) {
|
||||||
|
if (currentDSL.minDate === "2001-01-01 00:00") {
|
||||||
|
currentDSL.minDate = "1920-12-31T18:30:00.000Z";
|
||||||
|
}
|
||||||
|
if (currentDSL.maxDate === "2041-12-31 23:59") {
|
||||||
|
currentDSL.maxDate = "2121-12-31T18:29:00.000Z";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children.map((eachWidgetDSL: DSLWidget) => {
|
||||||
|
migrateDatePickerMinMaxDate(eachWidgetDSL);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
const addFilterDefaultValue = (currentDSL: DSLWidget) => {
|
||||||
|
if (currentDSL.type === "DROP_DOWN_WIDGET") {
|
||||||
|
if (!currentDSL.hasOwnProperty("isFilterable")) {
|
||||||
|
currentDSL.isFilterable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const migrateFilterValueForDropDownWidget = (currentDSL: DSLWidget) => {
|
||||||
|
const newDSL = addFilterDefaultValue(currentDSL);
|
||||||
|
|
||||||
|
newDSL.children = newDSL.children?.map((children: DSLWidget) => {
|
||||||
|
return migrateFilterValueForDropDownWidget(children);
|
||||||
|
});
|
||||||
|
|
||||||
|
return newDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
import { removeSpecialChars } from "../utils";
|
||||||
|
|
||||||
|
export const migrateTablePrimaryColumnsComputedValue = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "TABLE_WIDGET") {
|
||||||
|
if (
|
||||||
|
child.primaryColumns &&
|
||||||
|
Object.keys(child.primaryColumns).length > 0
|
||||||
|
) {
|
||||||
|
const newPrimaryColumns: Record<string, any> = {};
|
||||||
|
for (const [key, value] of Object.entries(
|
||||||
|
child.primaryColumns as Record<string, any>,
|
||||||
|
)) {
|
||||||
|
const sanitizedKey = removeSpecialChars(key, 200);
|
||||||
|
let newComputedValue = "";
|
||||||
|
if (value.computedValue) {
|
||||||
|
newComputedValue = value.computedValue.replace(
|
||||||
|
`${child.widgetName}.sanitizedTableData.map((currentRow) => { return`,
|
||||||
|
`${child.widgetName}.sanitizedTableData.map((currentRow) => (`,
|
||||||
|
);
|
||||||
|
// change matching "}" bracket with ")"
|
||||||
|
const lastParanthesesInd = newComputedValue.length - 4;
|
||||||
|
newComputedValue =
|
||||||
|
newComputedValue.substring(0, lastParanthesesInd) +
|
||||||
|
")" +
|
||||||
|
newComputedValue.substring(lastParanthesesInd + 1);
|
||||||
|
}
|
||||||
|
newPrimaryColumns[sanitizedKey] = {
|
||||||
|
...value,
|
||||||
|
computedValue: newComputedValue,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
child.primaryColumns = newPrimaryColumns;
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateTablePrimaryColumnsComputedValue(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateToNewMultiSelect = (currentDSL: DSLWidget) => {
|
||||||
|
if (currentDSL.type === "DROP_DOWN_WIDGET") {
|
||||||
|
if (currentDSL.selectionType === "MULTI_SELECT") {
|
||||||
|
currentDSL.type = "MULTI_SELECT_WIDGET";
|
||||||
|
delete currentDSL.isFilterable;
|
||||||
|
}
|
||||||
|
delete currentDSL.selectionType;
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map((child: DSLWidget) =>
|
||||||
|
migrateToNewMultiSelect(child),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateTableWidgetDelimiterProperties = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "TABLE_WIDGET") {
|
||||||
|
if (!child.delimiter) {
|
||||||
|
child.delimiter = ",";
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateTableWidgetDelimiterProperties(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import type { ColumnProperties, DSLWidget } from "../types";
|
||||||
|
import isEmpty from "lodash/isEmpty";
|
||||||
|
|
||||||
|
const addIsDisabledToButtonColumn = (currentDSL: DSLWidget) => {
|
||||||
|
if (currentDSL.type === "TABLE_WIDGET") {
|
||||||
|
if (!isEmpty(currentDSL.primaryColumns)) {
|
||||||
|
for (const key of Object.keys(
|
||||||
|
currentDSL.primaryColumns as Record<string, ColumnProperties>,
|
||||||
|
)) {
|
||||||
|
if (currentDSL.primaryColumns[key].columnType === "button") {
|
||||||
|
if (!currentDSL.primaryColumns[key].hasOwnProperty("isDisabled")) {
|
||||||
|
currentDSL.primaryColumns[key]["isDisabled"] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!currentDSL.primaryColumns[key].hasOwnProperty("isCellVisible")) {
|
||||||
|
currentDSL.primaryColumns[key]["isCellVisible"] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const migrateIsDisabledToButtonColumn = (currentDSL: DSLWidget) => {
|
||||||
|
const newDSL = addIsDisabledToButtonColumn(currentDSL);
|
||||||
|
|
||||||
|
newDSL.children = newDSL.children?.map((children: DSLWidget) => {
|
||||||
|
return migrateIsDisabledToButtonColumn(children);
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateTableDefaultSelectedRow = (currentDSL: DSLWidget) => {
|
||||||
|
if (currentDSL.type === "TABLE_WIDGET") {
|
||||||
|
if (!currentDSL.defaultSelectedRow) currentDSL.defaultSelectedRow = "0";
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map((child: DSLWidget) =>
|
||||||
|
migrateTableDefaultSelectedRow(child),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateMenuButtonWidgetButtonProperties = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "MENU_BUTTON_WIDGET") {
|
||||||
|
if (!("menuStyle" in child)) {
|
||||||
|
child.menuStyle = "PRIMARY";
|
||||||
|
child.menuVariant = "SOLID";
|
||||||
|
child.isVisible = true;
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateMenuButtonWidgetButtonProperties(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
import has from "lodash/has";
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateButtonWidgetValidation = (currentDSL: DSLWidget) => {
|
||||||
|
if (currentDSL.type === "INPUT_WIDGET") {
|
||||||
|
if (!has(currentDSL, "validation")) {
|
||||||
|
currentDSL.validation = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children.map((eachWidgetDSL: DSLWidget) => {
|
||||||
|
migrateButtonWidgetValidation(eachWidgetDSL);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
import has from "lodash/has";
|
||||||
|
|
||||||
|
export const migrateInputValidation = (currentDSL: DSLWidget) => {
|
||||||
|
if (currentDSL.type === "INPUT_WIDGET") {
|
||||||
|
if (has(currentDSL, "validation")) {
|
||||||
|
// convert boolean to string expression
|
||||||
|
if (typeof currentDSL.validation === "boolean") {
|
||||||
|
currentDSL.validation = String(currentDSL.validation);
|
||||||
|
} else if (typeof currentDSL.validation !== "string") {
|
||||||
|
// for any other type of value set to default undefined
|
||||||
|
currentDSL.validation = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map((child: DSLWidget) =>
|
||||||
|
migrateInputValidation(child),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const revertTableDefaultSelectedRow = (currentDSL: DSLWidget) => {
|
||||||
|
if (currentDSL.type === "TABLE_WIDGET") {
|
||||||
|
if (currentDSL.version === 1 && currentDSL.defaultSelectedRow === "0")
|
||||||
|
currentDSL.defaultSelectedRow = undefined;
|
||||||
|
// update version to 3 for all table dsl
|
||||||
|
currentDSL.version = 3;
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map((child: DSLWidget) =>
|
||||||
|
revertTableDefaultSelectedRow(child),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
import type { ColumnProperties, DSLWidget } from "../types";
|
||||||
|
import { removeSpecialChars } from "../utils";
|
||||||
|
|
||||||
|
const getSubstringBetweenTwoWords = (
|
||||||
|
str: string,
|
||||||
|
startWord: string,
|
||||||
|
endWord: string,
|
||||||
|
) => {
|
||||||
|
const endIndexOfStartWord = str.indexOf(startWord) + startWord.length;
|
||||||
|
const startIndexOfEndWord = str.lastIndexOf(endWord);
|
||||||
|
|
||||||
|
if (startIndexOfEndWord < endIndexOfStartWord) return "";
|
||||||
|
|
||||||
|
return str.substring(startIndexOfEndWord, endIndexOfStartWord);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This migration sanitizes the following properties -
|
||||||
|
* primaryColumns object key, for the value of each key - id, computedValue are sanitized
|
||||||
|
* columnOrder
|
||||||
|
* dynamicBindingPathList
|
||||||
|
*
|
||||||
|
* This migration solves the following issue -
|
||||||
|
* https://github.com/appsmithorg/appsmith/issues/6897
|
||||||
|
*/
|
||||||
|
export const migrateTableSanitizeColumnKeys = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "TABLE_WIDGET") {
|
||||||
|
const primaryColumnEntries: [string, ColumnProperties][] = Object.entries(
|
||||||
|
child.primaryColumns || {},
|
||||||
|
);
|
||||||
|
|
||||||
|
const newPrimaryColumns: Record<string, ColumnProperties> = {};
|
||||||
|
if (primaryColumnEntries.length) {
|
||||||
|
for (const [, primaryColumnEntry] of primaryColumnEntries.entries()) {
|
||||||
|
// Value is reassigned when its invalid(Faulty DSL https://github.com/appsmithorg/appsmith/issues/8979)
|
||||||
|
const [key] = primaryColumnEntry;
|
||||||
|
let [, value] = primaryColumnEntry;
|
||||||
|
const sanitizedKey = removeSpecialChars(key, 200);
|
||||||
|
let id = "";
|
||||||
|
if (value.id) {
|
||||||
|
id = removeSpecialChars(value.id, 200);
|
||||||
|
}
|
||||||
|
// When id is undefined it's likely value isn't correct and needs fixing
|
||||||
|
else if (Object.keys(value)) {
|
||||||
|
const onlyKey = Object.keys(value)[0] as keyof ColumnProperties;
|
||||||
|
const obj: ColumnProperties = value[onlyKey];
|
||||||
|
if (!obj.id && !obj.columnType) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
value = obj;
|
||||||
|
id = removeSpecialChars(value.id, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanitizes "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.$$$random_header))}}"
|
||||||
|
// to "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow._random_header))}}"
|
||||||
|
const computedValue = (value?.computedValue || "").replace(
|
||||||
|
key,
|
||||||
|
sanitizedKey,
|
||||||
|
);
|
||||||
|
|
||||||
|
newPrimaryColumns[sanitizedKey] = {
|
||||||
|
...value,
|
||||||
|
computedValue,
|
||||||
|
id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
child.primaryColumns = newPrimaryColumns;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanitizes [ "id", "name", $$$random_header ]
|
||||||
|
// to [ "id", "name", _random_header ]
|
||||||
|
child.columnOrder = (child.columnOrder || []).map((co: string) =>
|
||||||
|
removeSpecialChars(co, 200),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Sanitizes [ {key: primaryColumns.$random.header.computedValue }]
|
||||||
|
// to [ {key: primaryColumns._random_header.computedValue }]
|
||||||
|
child.dynamicBindingPathList = (child.dynamicBindingPathList || []).map(
|
||||||
|
(path: { key: string }) => {
|
||||||
|
const pathChunks = path.key.split("."); // primaryColumns.$random.header.computedValue -> [ "primaryColumns", "$random", "header", "computedValue"]
|
||||||
|
|
||||||
|
// tableData is a valid dynamicBindingPath and pathChunks would have just one entry
|
||||||
|
if (pathChunks.length < 2) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstPart = pathChunks[0] + "."; // "primaryColumns."
|
||||||
|
const lastPart = "." + pathChunks[pathChunks.length - 1]; // ".computedValue"
|
||||||
|
|
||||||
|
const key = getSubstringBetweenTwoWords(
|
||||||
|
path.key,
|
||||||
|
firstPart,
|
||||||
|
lastPart,
|
||||||
|
); // primaryColumns.$random.header.computedValue -> $random.header
|
||||||
|
|
||||||
|
const sanitizedPrimaryColumnKey = removeSpecialChars(key, 200);
|
||||||
|
|
||||||
|
return {
|
||||||
|
key: firstPart + sanitizedPrimaryColumnKey + lastPart,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateTableSanitizeColumnKeys(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
const DEFAULT_GRID_ROW_HEIGHT = 10;
|
||||||
|
|
||||||
|
export const migrateResizableModalWidgetProperties = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "MODAL_WIDGET" && child.version === 1) {
|
||||||
|
const size = child.size;
|
||||||
|
switch (size) {
|
||||||
|
case "MODAL_SMALL":
|
||||||
|
child.width = 456;
|
||||||
|
child.height = DEFAULT_GRID_ROW_HEIGHT * 24;
|
||||||
|
break;
|
||||||
|
case "MODAL_LARGE":
|
||||||
|
child.width = 532;
|
||||||
|
child.height = DEFAULT_GRID_ROW_HEIGHT * 60;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
child.width = 456;
|
||||||
|
child.height = DEFAULT_GRID_ROW_HEIGHT * 24;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
child.version = 2;
|
||||||
|
delete child.size;
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateResizableModalWidgetProperties(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
import type { ColumnProperties, DSLWidget } from "../types";
|
||||||
|
import { removeSpecialChars } from "../utils";
|
||||||
|
|
||||||
|
const getUpdatedColumns = (
|
||||||
|
widgetName: string,
|
||||||
|
columns: Record<string, ColumnProperties>,
|
||||||
|
) => {
|
||||||
|
const updatedColumns: Record<string, ColumnProperties> = {};
|
||||||
|
if (columns && Object.keys(columns).length > 0) {
|
||||||
|
for (const [columnId, columnProps] of Object.entries(columns)) {
|
||||||
|
const sanitizedColumnId = removeSpecialChars(columnId, 200);
|
||||||
|
const selectedRowBindingValue = `${widgetName}.selectedRow`;
|
||||||
|
let newOnClickBindingValue = undefined;
|
||||||
|
if (
|
||||||
|
columnProps.onClick &&
|
||||||
|
columnProps.onClick.includes(selectedRowBindingValue)
|
||||||
|
) {
|
||||||
|
newOnClickBindingValue = columnProps.onClick.replace(
|
||||||
|
selectedRowBindingValue,
|
||||||
|
"currentRow",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
updatedColumns[sanitizedColumnId] = columnProps;
|
||||||
|
if (newOnClickBindingValue)
|
||||||
|
updatedColumns[sanitizedColumnId].onClick = newOnClickBindingValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return updatedColumns;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const migrateTableWidgetSelectedRowBindings = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "TABLE_WIDGET") {
|
||||||
|
child.derivedColumns = getUpdatedColumns(
|
||||||
|
child.widgetName,
|
||||||
|
child.derivedColumns as Record<string, ColumnProperties>,
|
||||||
|
);
|
||||||
|
child.primaryColumns = getUpdatedColumns(
|
||||||
|
child.widgetName,
|
||||||
|
child.primaryColumns as Record<string, ColumnProperties>,
|
||||||
|
);
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateTableWidgetSelectedRowBindings(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export enum ButtonStyleTypes {
|
||||||
|
PRIMARY = "PRIMARY",
|
||||||
|
WARNING = "WARNING",
|
||||||
|
DANGER = "DANGER",
|
||||||
|
INFO = "INFO",
|
||||||
|
SECONDARY = "SECONDARY",
|
||||||
|
CUSTOM = "CUSTOM",
|
||||||
|
}
|
||||||
|
|
||||||
|
const Colors = {
|
||||||
|
DANGER_SOLID: "#F22B2B",
|
||||||
|
GREEN: "#03B365",
|
||||||
|
WARNING_SOLID: "#FEB811",
|
||||||
|
INFO_SOLID: "#6698FF",
|
||||||
|
GRAY: "#858282",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const revertButtonStyleToButtonColor = (currentDSL: DSLWidget) => {
|
||||||
|
if (
|
||||||
|
currentDSL.type === "BUTTON_WIDGET" ||
|
||||||
|
currentDSL.type === "FORM_BUTTON_WIDGET" ||
|
||||||
|
currentDSL.type === "ICON_BUTTON_WIDGET"
|
||||||
|
) {
|
||||||
|
if (currentDSL.hasOwnProperty("buttonStyle")) {
|
||||||
|
switch (currentDSL.buttonStyle) {
|
||||||
|
case ButtonStyleTypes.DANGER:
|
||||||
|
currentDSL.buttonColor = Colors.DANGER_SOLID;
|
||||||
|
break;
|
||||||
|
case ButtonStyleTypes.PRIMARY:
|
||||||
|
currentDSL.buttonColor = Colors.GREEN;
|
||||||
|
break;
|
||||||
|
case ButtonStyleTypes.WARNING:
|
||||||
|
currentDSL.buttonColor = Colors.WARNING_SOLID;
|
||||||
|
break;
|
||||||
|
case ButtonStyleTypes.INFO:
|
||||||
|
currentDSL.buttonColor = Colors.INFO_SOLID;
|
||||||
|
break;
|
||||||
|
case ButtonStyleTypes.SECONDARY:
|
||||||
|
currentDSL.buttonColor = Colors.GRAY;
|
||||||
|
break;
|
||||||
|
case "PRIMARY_BUTTON":
|
||||||
|
currentDSL.buttonColor = Colors.GREEN;
|
||||||
|
break;
|
||||||
|
case "SECONDARY_BUTTON":
|
||||||
|
currentDSL.buttonColor = Colors.GREEN;
|
||||||
|
currentDSL.buttonVariant = "SECONDARY";
|
||||||
|
break;
|
||||||
|
case "DANGER_BUTTON":
|
||||||
|
currentDSL.buttonColor = Colors.DANGER_SOLID;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!currentDSL.buttonColor) currentDSL.buttonColor = Colors.GREEN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
delete currentDSL.buttonStyle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.type === "MENU_BUTTON_WIDGET") {
|
||||||
|
if (currentDSL.hasOwnProperty("menuStyle")) {
|
||||||
|
switch (currentDSL.menuStyle) {
|
||||||
|
case ButtonStyleTypes.DANGER:
|
||||||
|
currentDSL.menuColor = Colors.DANGER_SOLID;
|
||||||
|
break;
|
||||||
|
case ButtonStyleTypes.PRIMARY:
|
||||||
|
currentDSL.menuColor = Colors.GREEN;
|
||||||
|
break;
|
||||||
|
case ButtonStyleTypes.WARNING:
|
||||||
|
currentDSL.menuColor = Colors.WARNING_SOLID;
|
||||||
|
break;
|
||||||
|
case ButtonStyleTypes.INFO:
|
||||||
|
currentDSL.menuColor = Colors.INFO_SOLID;
|
||||||
|
break;
|
||||||
|
case ButtonStyleTypes.SECONDARY:
|
||||||
|
currentDSL.menuColor = Colors.GRAY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!currentDSL.menuColor) currentDSL.menuColor = Colors.GREEN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
delete currentDSL.menuStyle;
|
||||||
|
delete currentDSL.prevMenuStyle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.type === "TABLE_WIDGET") {
|
||||||
|
if (currentDSL.hasOwnProperty("primaryColumns")) {
|
||||||
|
Object.keys(currentDSL.primaryColumns).forEach((column) => {
|
||||||
|
if (currentDSL.primaryColumns[column].columnType === "button") {
|
||||||
|
currentDSL.primaryColumns[column].buttonColor =
|
||||||
|
currentDSL.primaryColumns[column].buttonStyle;
|
||||||
|
delete currentDSL.primaryColumns[column].buttonStyle;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map((child: DSLWidget) =>
|
||||||
|
revertButtonStyleToButtonColor(child),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
enum ButtonVariantTypes {
|
||||||
|
PRIMARY = "PRIMARY",
|
||||||
|
SECONDARY = "SECONDARY",
|
||||||
|
TERTIARY = "TERTIARY",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const migrateButtonVariant = (currentDSL: DSLWidget) => {
|
||||||
|
if (
|
||||||
|
currentDSL.type === "BUTTON_WIDGET" ||
|
||||||
|
currentDSL.type === "FORM_BUTTON_WIDGET" ||
|
||||||
|
currentDSL.type === "ICON_BUTTON_WIDGET"
|
||||||
|
) {
|
||||||
|
switch (currentDSL.buttonVariant) {
|
||||||
|
case "OUTLINE":
|
||||||
|
currentDSL.buttonVariant = ButtonVariantTypes.SECONDARY;
|
||||||
|
break;
|
||||||
|
case "GHOST":
|
||||||
|
currentDSL.buttonVariant = ButtonVariantTypes.TERTIARY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
currentDSL.buttonVariant = ButtonVariantTypes.PRIMARY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.type === "MENU_BUTTON_WIDGET") {
|
||||||
|
switch (currentDSL.menuVariant) {
|
||||||
|
case "OUTLINE":
|
||||||
|
currentDSL.menuVariant = ButtonVariantTypes.SECONDARY;
|
||||||
|
break;
|
||||||
|
case "GHOST":
|
||||||
|
currentDSL.menuVariant = ButtonVariantTypes.TERTIARY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
currentDSL.menuVariant = ButtonVariantTypes.PRIMARY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.type === "TABLE_WIDGET") {
|
||||||
|
if (currentDSL.hasOwnProperty("primaryColumns")) {
|
||||||
|
Object.keys(currentDSL.primaryColumns).forEach((column) => {
|
||||||
|
if (currentDSL.primaryColumns[column].columnType === "iconButton") {
|
||||||
|
let newVariant = ButtonVariantTypes.PRIMARY;
|
||||||
|
switch (currentDSL.primaryColumns[column].buttonVariant) {
|
||||||
|
case "OUTLINE":
|
||||||
|
newVariant = ButtonVariantTypes.SECONDARY;
|
||||||
|
break;
|
||||||
|
case "GHOST":
|
||||||
|
newVariant = ButtonVariantTypes.TERTIARY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentDSL.primaryColumns[column].buttonVariant = newVariant;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentDSL.children && currentDSL.children.length) {
|
||||||
|
currentDSL.children = currentDSL.children.map((child: DSLWidget) =>
|
||||||
|
migrateButtonVariant(child),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateMapWidgetIsClickedMarkerCentered = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "MAP_WIDGET") {
|
||||||
|
if (!("isClickedMarkerCentered" in child)) {
|
||||||
|
child.isClickedMarkerCentered = true;
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateMapWidgetIsClickedMarkerCentered(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const mapAllowHorizontalScrollMigration = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "CHART_WIDGET") {
|
||||||
|
child.allowScroll = child.allowHorizontalScroll;
|
||||||
|
delete child.allowHorizontalScroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(child.children) && child.children.length > 0)
|
||||||
|
child = mapAllowHorizontalScrollMigration(child);
|
||||||
|
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const isSortableMigration = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "TABLE_WIDGET" && !child.hasOwnProperty("isSortable")) {
|
||||||
|
child["isSortable"] = true;
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = isSortableMigration(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import type { ColumnProperties, DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateTableWidgetIconButtonVariant = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "TABLE_WIDGET") {
|
||||||
|
const primaryColumns = child.primaryColumns as Record<
|
||||||
|
string,
|
||||||
|
ColumnProperties
|
||||||
|
>;
|
||||||
|
Object.keys(primaryColumns).forEach((accessor: string) => {
|
||||||
|
const primaryColumn = primaryColumns[accessor];
|
||||||
|
|
||||||
|
if (primaryColumn.columnType === "iconButton") {
|
||||||
|
if (!("buttonVariant" in primaryColumn)) {
|
||||||
|
primaryColumn.buttonVariant = "TERTIARY";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateTableWidgetIconButtonVariant(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateCheckboxGroupWidgetInlineProperty = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "CHECKBOX_GROUP_WIDGET") {
|
||||||
|
if (child.version === 1) {
|
||||||
|
child.isInline = true;
|
||||||
|
child.version = 2;
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateCheckboxGroupWidgetInlineProperty(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
// We're skipping this to fix a bad table migration.
|
||||||
|
// skipped migration is added as version 51
|
||||||
|
export {};
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateRecaptchaType = (currentDSL: DSLWidget): DSLWidget => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "BUTTON_WIDGET" || child.type === "FORM_BUTTON_WIDGET") {
|
||||||
|
const recaptchaV2 = child.recaptchaV2;
|
||||||
|
if (recaptchaV2) {
|
||||||
|
child.recaptchaType = "V2";
|
||||||
|
} else {
|
||||||
|
child.recaptchaType = "V3";
|
||||||
|
}
|
||||||
|
delete child.recaptchaV2;
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateRecaptchaType(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import set from "lodash/set";
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds 'privateWidgets' key for all list widgets
|
||||||
|
*
|
||||||
|
* @param currentDSL
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const addPrivateWidgetsToAllListWidgets = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "LIST_WIDGET") {
|
||||||
|
const privateWidgets: any = {};
|
||||||
|
Object.keys(child.template).forEach((entityName) => {
|
||||||
|
privateWidgets[entityName] = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!child.privateWidgets) {
|
||||||
|
set(child, `privateWidgets`, privateWidgets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
/*
|
||||||
|
* We're skipping this to fix a bad table migration - migrateTableWidgetNumericColumnName
|
||||||
|
* it overwrites the computedValue of the table columns
|
||||||
|
*/
|
||||||
|
export {};
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migratePhoneInputWidgetAllowFormatting = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
): DSLWidget => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "PHONE_INPUT_WIDGET") {
|
||||||
|
child.allowFormatting = true;
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migratePhoneInputWidgetAllowFormatting(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateModalIconButtonWidget = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "ICON_WIDGET") {
|
||||||
|
child.type = "ICON_BUTTON_WIDGET";
|
||||||
|
child.buttonColor = "#2E3D49"; // Colors.OXFORD_BLUE;
|
||||||
|
child.buttonVariant = "TERTIARY";
|
||||||
|
child.borderRadius = "SHARP";
|
||||||
|
child.color = undefined;
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateModalIconButtonWidget(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export enum OverflowTypes {
|
||||||
|
SCROLL = "SCROLL",
|
||||||
|
TRUNCATE = "TRUNCATE",
|
||||||
|
NONE = "NONE",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const migrateScrollTruncateProperties = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
): DSLWidget => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "TEXT_WIDGET") {
|
||||||
|
if (child.shouldTruncate) {
|
||||||
|
child.overflow = OverflowTypes.TRUNCATE;
|
||||||
|
} else if (child.shouldScroll) {
|
||||||
|
child.overflow = OverflowTypes.SCROLL;
|
||||||
|
} else {
|
||||||
|
child.overflow = OverflowTypes.NONE;
|
||||||
|
}
|
||||||
|
delete child.shouldScroll;
|
||||||
|
delete child.shouldTruncate;
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateScrollTruncateProperties(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migratePhoneInputWidgetDefaultDialCode = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
): DSLWidget => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "PHONE_INPUT_WIDGET") {
|
||||||
|
child.defaultDialCode = child.dialCode;
|
||||||
|
delete child.dialCode;
|
||||||
|
|
||||||
|
if (child.dynamicPropertyPathList) {
|
||||||
|
child.dynamicPropertyPathList.forEach((property: { key: string }) => {
|
||||||
|
if (property.key === "dialCode") {
|
||||||
|
property.key = "defaultDialCode";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child.dynamicBindingPathList) {
|
||||||
|
child.dynamicBindingPathList.forEach((property: { key: string }) => {
|
||||||
|
if (property.key === "dialCode") {
|
||||||
|
property.key = "defaultDialCode";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migratePhoneInputWidgetDefaultDialCode(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateCurrencyInputWidgetDefaultCurrencyCode = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
): DSLWidget => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "CURRENCY_INPUT_WIDGET") {
|
||||||
|
child.defaultCurrencyCode = child.currencyCode;
|
||||||
|
delete child.currencyCode;
|
||||||
|
|
||||||
|
if (child.dynamicPropertyPathList) {
|
||||||
|
child.dynamicPropertyPathList.forEach((property: { key: string }) => {
|
||||||
|
if (property.key === "currencyCode") {
|
||||||
|
property.key = "defaultCurrencyCode";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child.dynamicBindingPathList) {
|
||||||
|
child.dynamicBindingPathList.forEach((property: { key: string }) => {
|
||||||
|
if (property.key === "currencyCode") {
|
||||||
|
property.key = "defaultCurrencyCode";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateCurrencyInputWidgetDefaultCurrencyCode(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateRadioGroupAlignmentProperty = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "RADIO_GROUP_WIDGET") {
|
||||||
|
if (!child.hasOwnProperty("alignment")) {
|
||||||
|
child.alignment = "left";
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateRadioGroupAlignmentProperty(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,773 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { clone, get, has, isEmpty, set } from "lodash";
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
import { isDynamicValue } from "../utils";
|
||||||
|
|
||||||
|
enum ButtonBorderRadiusTypes {
|
||||||
|
SHARP = "SHARP",
|
||||||
|
ROUNDED = "ROUNDED",
|
||||||
|
CIRCLE = "CIRCLE",
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BoxShadowTypes {
|
||||||
|
NONE = "NONE",
|
||||||
|
VARIANT1 = "VARIANT1",
|
||||||
|
VARIANT2 = "VARIANT2",
|
||||||
|
VARIANT3 = "VARIANT3",
|
||||||
|
VARIANT4 = "VARIANT4",
|
||||||
|
VARIANT5 = "VARIANT5",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum TextSizes {
|
||||||
|
HEADING1 = "HEADING1",
|
||||||
|
HEADING2 = "HEADING2",
|
||||||
|
HEADING3 = "HEADING3",
|
||||||
|
PARAGRAPH = "PARAGRAPH",
|
||||||
|
PARAGRAPH2 = "PARAGRAPH2",
|
||||||
|
}
|
||||||
|
|
||||||
|
const THEMING_BORDER_RADIUS = {
|
||||||
|
none: "0px",
|
||||||
|
rounded: "0.375rem",
|
||||||
|
circle: "9999px",
|
||||||
|
};
|
||||||
|
|
||||||
|
const THEMEING_TEXT_SIZES = {
|
||||||
|
xs: "0.75rem",
|
||||||
|
sm: "0.875rem",
|
||||||
|
base: "1rem",
|
||||||
|
md: "1.125rem",
|
||||||
|
lg: "1.5rem",
|
||||||
|
xl: "1.875rem",
|
||||||
|
"2xl": "3rem",
|
||||||
|
"3xl": "3.75rem",
|
||||||
|
};
|
||||||
|
|
||||||
|
const rgbaMigrationConstantV56 = "rgba(0, 0, 0, 0.25)";
|
||||||
|
|
||||||
|
const DEFAULT_BOXSHADOW = "none";
|
||||||
|
|
||||||
|
const ROOT_SCHEMA_KEY = "__root_schema__";
|
||||||
|
|
||||||
|
const Colors = {
|
||||||
|
GREEN: "#03B365",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const BUTTON_GROUP_CHILD_STYLESHEET = {
|
||||||
|
button: {
|
||||||
|
buttonColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TABLE_WIDGET_CHILD_STYLESHEET = {
|
||||||
|
button: {
|
||||||
|
buttonColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
menuButton: {
|
||||||
|
menuColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
iconButton: {
|
||||||
|
menuColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const JSON_FORM_WIDGET_CHILD_STYLESHEET = {
|
||||||
|
ARRAY: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
cellBorderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
cellBoxShadow: "none",
|
||||||
|
},
|
||||||
|
OBJECT: {
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
cellBorderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
cellBoxShadow: "none",
|
||||||
|
},
|
||||||
|
CHECKBOX: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
},
|
||||||
|
CURRENCY_INPUT: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
DATEPICKER: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
EMAIL_INPUT: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
MULTISELECT: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
MULTILINE_TEXT_INPUT: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
NUMBER_INPUT: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
PASSWORD_INPUT: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
PHONE_NUMBER_INPUT: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
RADIO_GROUP: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
SELECT: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
SWITCH: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
TEXT_INPUT: {
|
||||||
|
accentColor: "{{appsmith.theme.colors.primaryColor}}",
|
||||||
|
borderRadius: "{{appsmith.theme.borderRadius.appBorderRadius}}",
|
||||||
|
boxShadow: "none",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive function to traverse through all the children of the JSON form in theming migration.
|
||||||
|
* @param schemaItem
|
||||||
|
* @param propertyPath
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
export const parseSchemaItem = (
|
||||||
|
schemaItem: any,
|
||||||
|
propertyPath: string,
|
||||||
|
callback: (schemaItem: any, propertyPath: string) => void,
|
||||||
|
) => {
|
||||||
|
// Update the theme stuff for this schema
|
||||||
|
callback(schemaItem, propertyPath);
|
||||||
|
if (schemaItem && !isEmpty(schemaItem.children)) {
|
||||||
|
Object.values(schemaItem.children).forEach((schemaItem: any) => {
|
||||||
|
const childPropertyPath = `${propertyPath}.children.${schemaItem.identifier}`;
|
||||||
|
parseSchemaItem(schemaItem, childPropertyPath, callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will add the given propertyName into the dynamicPropertyPathList.
|
||||||
|
* @param propertyName
|
||||||
|
* @param child
|
||||||
|
*/
|
||||||
|
export const addPropertyToDynamicPropertyPathList = (
|
||||||
|
propertyName: string,
|
||||||
|
child: DSLWidget,
|
||||||
|
) => {
|
||||||
|
const isPropertyPathPresent = (child.dynamicPropertyPathList || []).find(
|
||||||
|
(property: { key: string }) => property.key === propertyName,
|
||||||
|
);
|
||||||
|
if (!isPropertyPathPresent) {
|
||||||
|
child.dynamicPropertyPathList = [
|
||||||
|
...(child.dynamicPropertyPathList || []),
|
||||||
|
{ key: propertyName },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const migrateStylingPropertiesForTheming = (currentDSL: DSLWidget) => {
|
||||||
|
const widgetsWithPrimaryColorProp = [
|
||||||
|
"DATE_PICKER_WIDGET2",
|
||||||
|
"INPUT_WIDGET",
|
||||||
|
"INPUT_WIDGET_V2",
|
||||||
|
"LIST_WIDGET",
|
||||||
|
"MULTI_SELECT_TREE_WIDGET",
|
||||||
|
"DROP_DOWN_WIDGET",
|
||||||
|
"TABS_WIDGET",
|
||||||
|
"SINGLE_SELECT_TREE_WIDGET",
|
||||||
|
"TABLE_WIDGET",
|
||||||
|
"BUTTON_GROUP_WIDGET",
|
||||||
|
"PHONE_INPUT_WIDGET",
|
||||||
|
"CURRENCY_INPUT_WIDGET",
|
||||||
|
"SELECT_WIDGET",
|
||||||
|
"MULTI_SELECT_WIDGET_V2",
|
||||||
|
"MULTI_SELECT_WIDGET",
|
||||||
|
];
|
||||||
|
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
switch (child.borderRadius) {
|
||||||
|
case ButtonBorderRadiusTypes.SHARP:
|
||||||
|
child.borderRadius = THEMING_BORDER_RADIUS.none;
|
||||||
|
break;
|
||||||
|
case ButtonBorderRadiusTypes.ROUNDED:
|
||||||
|
child.borderRadius = THEMING_BORDER_RADIUS.rounded;
|
||||||
|
break;
|
||||||
|
case ButtonBorderRadiusTypes.CIRCLE:
|
||||||
|
child.borderRadius = THEMING_BORDER_RADIUS.circle;
|
||||||
|
addPropertyToDynamicPropertyPathList("borderRadius", child);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (
|
||||||
|
(child.type === "CONTAINER_WIDGET" ||
|
||||||
|
child.type === "FORM_WIDGET" ||
|
||||||
|
child.type === "JSON_FORM_WIDGET") &&
|
||||||
|
child.borderRadius
|
||||||
|
) {
|
||||||
|
child.borderRadius = `${child.borderRadius}px`;
|
||||||
|
addPropertyToDynamicPropertyPathList("borderRadius", child);
|
||||||
|
} else {
|
||||||
|
child.borderRadius = THEMING_BORDER_RADIUS.none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (child.boxShadow) {
|
||||||
|
case BoxShadowTypes.VARIANT1:
|
||||||
|
child.boxShadow = `0px 0px 4px 3px ${
|
||||||
|
child.boxShadowColor || "rgba(0, 0, 0, 0.25)"
|
||||||
|
}`;
|
||||||
|
addPropertyToDynamicPropertyPathList("boxShadow", child);
|
||||||
|
break;
|
||||||
|
case BoxShadowTypes.VARIANT2:
|
||||||
|
child.boxShadow = `3px 3px 4px ${
|
||||||
|
child.boxShadowColor || "rgba(0, 0, 0, 0.25)"
|
||||||
|
}`;
|
||||||
|
addPropertyToDynamicPropertyPathList("boxShadow", child);
|
||||||
|
break;
|
||||||
|
case BoxShadowTypes.VARIANT3:
|
||||||
|
child.boxShadow = `0px 1px 3px ${
|
||||||
|
child.boxShadowColor || "rgba(0, 0, 0, 0.25)"
|
||||||
|
}`;
|
||||||
|
addPropertyToDynamicPropertyPathList("boxShadow", child);
|
||||||
|
break;
|
||||||
|
case BoxShadowTypes.VARIANT4:
|
||||||
|
child.boxShadow = `2px 2px 0px ${
|
||||||
|
child.boxShadowColor || "rgba(0, 0, 0, 0.25)"
|
||||||
|
}`;
|
||||||
|
addPropertyToDynamicPropertyPathList("boxShadow", child);
|
||||||
|
break;
|
||||||
|
case BoxShadowTypes.VARIANT5:
|
||||||
|
child.boxShadow = `-2px -2px 0px ${
|
||||||
|
child.boxShadowColor || "rgba(0, 0, 0, 0.25)"
|
||||||
|
}`;
|
||||||
|
addPropertyToDynamicPropertyPathList("boxShadow", child);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
child.boxShadow = DEFAULT_BOXSHADOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrates the textSize property present at the table level.
|
||||||
|
*/
|
||||||
|
if (child.type === "TABLE_WIDGET") {
|
||||||
|
switch (child.textSize) {
|
||||||
|
case TextSizes.PARAGRAPH2:
|
||||||
|
child.textSize = THEMEING_TEXT_SIZES.xs;
|
||||||
|
addPropertyToDynamicPropertyPathList("textSize", child);
|
||||||
|
break;
|
||||||
|
case TextSizes.PARAGRAPH:
|
||||||
|
child.textSize = THEMEING_TEXT_SIZES.sm;
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING3:
|
||||||
|
child.textSize = THEMEING_TEXT_SIZES.base;
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING2:
|
||||||
|
child.textSize = THEMEING_TEXT_SIZES.md;
|
||||||
|
addPropertyToDynamicPropertyPathList("textSize", child);
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING1:
|
||||||
|
child.textSize = THEMEING_TEXT_SIZES.lg;
|
||||||
|
addPropertyToDynamicPropertyPathList("textSize", child);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
child.textSize = THEMEING_TEXT_SIZES.sm;
|
||||||
|
}
|
||||||
|
if (child.hasOwnProperty("primaryColumns")) {
|
||||||
|
Object.keys(child.primaryColumns).forEach((key: string) => {
|
||||||
|
/**
|
||||||
|
* Migrates the textSize property present at the primaryColumn and derivedColumn level.
|
||||||
|
*/
|
||||||
|
const column = child.primaryColumns[key];
|
||||||
|
const isDerivedColumn =
|
||||||
|
child.hasOwnProperty("derivedColumns") &&
|
||||||
|
key in child.derivedColumns;
|
||||||
|
const derivedColumn = child.derivedColumns[key];
|
||||||
|
switch (column.textSize) {
|
||||||
|
case TextSizes.PARAGRAPH2:
|
||||||
|
column.textSize = THEMEING_TEXT_SIZES.xs;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.textSize = THEMEING_TEXT_SIZES.xs;
|
||||||
|
}
|
||||||
|
addPropertyToDynamicPropertyPathList(
|
||||||
|
`primaryColumns.${key}.textSize`,
|
||||||
|
child,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case TextSizes.PARAGRAPH:
|
||||||
|
column.textSize = THEMEING_TEXT_SIZES.sm;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.textSize = THEMEING_TEXT_SIZES.sm;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING3:
|
||||||
|
column.textSize = THEMEING_TEXT_SIZES.base;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.textSize = THEMEING_TEXT_SIZES.base;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING2:
|
||||||
|
column.textSize = THEMEING_TEXT_SIZES.md;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.textSize = THEMEING_TEXT_SIZES.md;
|
||||||
|
}
|
||||||
|
addPropertyToDynamicPropertyPathList(
|
||||||
|
`primaryColumns.${key}.textSize`,
|
||||||
|
child,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING1:
|
||||||
|
column.textSize = THEMEING_TEXT_SIZES.lg;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.textSize = THEMEING_TEXT_SIZES.lg;
|
||||||
|
}
|
||||||
|
addPropertyToDynamicPropertyPathList(
|
||||||
|
`primaryColumns.${key}.textSize`,
|
||||||
|
child,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate the borderRadius if exists for the primary columns and derived columns
|
||||||
|
*/
|
||||||
|
if (!column.borderRadius) {
|
||||||
|
column.borderRadius = THEMING_BORDER_RADIUS.none;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.borderRadius = THEMING_BORDER_RADIUS.none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (column.borderRadius) {
|
||||||
|
case ButtonBorderRadiusTypes.SHARP:
|
||||||
|
column.borderRadius = THEMING_BORDER_RADIUS.none;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.borderRadius = THEMING_BORDER_RADIUS.none;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ButtonBorderRadiusTypes.ROUNDED:
|
||||||
|
column.borderRadius = THEMING_BORDER_RADIUS.rounded;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.borderRadius = THEMING_BORDER_RADIUS.rounded;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ButtonBorderRadiusTypes.CIRCLE:
|
||||||
|
column.borderRadius = THEMING_BORDER_RADIUS.circle;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.borderRadius = THEMING_BORDER_RADIUS.circle;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate the boxShadow if exists for the primary columns and derived columns:
|
||||||
|
*/
|
||||||
|
const isBoxShadowColorDynamic = isDynamicValue(column.boxShadowColor);
|
||||||
|
const newBoxShadowColor =
|
||||||
|
column.boxShadowColor || rgbaMigrationConstantV56;
|
||||||
|
|
||||||
|
if (column.boxShadow) {
|
||||||
|
addPropertyToDynamicPropertyPathList(
|
||||||
|
`primaryColumns.${key}.boxShadow`,
|
||||||
|
child,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
column.boxShadow = "none";
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.boxShadow = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (column.boxShadow) {
|
||||||
|
case BoxShadowTypes.VARIANT1:
|
||||||
|
if (!isBoxShadowColorDynamic) {
|
||||||
|
// Checks is boxShadowColor is not dynamic
|
||||||
|
column.boxShadow = `0px 0px 4px 3px ${newBoxShadowColor}`;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.boxShadow = `0px 0px 4px 3px ${newBoxShadowColor}`;
|
||||||
|
}
|
||||||
|
delete column.boxShadowColor;
|
||||||
|
} else {
|
||||||
|
// Dynamic
|
||||||
|
column.boxShadow = `0px 0px 4px 3px ${rgbaMigrationConstantV56}`;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.boxShadow = `0px 0px 4px 3px ${rgbaMigrationConstantV56}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BoxShadowTypes.VARIANT2:
|
||||||
|
if (!isBoxShadowColorDynamic) {
|
||||||
|
// Checks is boxShadowColor is not dynamic
|
||||||
|
column.boxShadow = `3px 3px 4px ${newBoxShadowColor}`;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.boxShadow = `3px 3px 4px ${newBoxShadowColor}`;
|
||||||
|
}
|
||||||
|
delete column.boxShadowColor;
|
||||||
|
} else {
|
||||||
|
// Dynamic
|
||||||
|
column.boxShadow = `3px 3px 4px ${rgbaMigrationConstantV56}`;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.boxShadow = `3px 3px 4px ${rgbaMigrationConstantV56}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BoxShadowTypes.VARIANT3:
|
||||||
|
if (!isBoxShadowColorDynamic) {
|
||||||
|
// Checks is boxShadowColor is not dynamic
|
||||||
|
column.boxShadow = `0px 1px 3px ${newBoxShadowColor}`;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.boxShadow = `0px 1px 3px ${newBoxShadowColor}`;
|
||||||
|
}
|
||||||
|
delete column.boxShadowColor;
|
||||||
|
} else {
|
||||||
|
// Dynamic
|
||||||
|
column.boxShadow = `0px 1px 3px ${rgbaMigrationConstantV56}`;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.boxShadow = `0px 1px 3px ${rgbaMigrationConstantV56}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BoxShadowTypes.VARIANT4:
|
||||||
|
if (!isBoxShadowColorDynamic) {
|
||||||
|
// Checks is boxShadowColor is not dynamic
|
||||||
|
column.boxShadow = `2px 2px 0px ${newBoxShadowColor}`;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.boxShadow = `2px 2px 0px ${newBoxShadowColor}`;
|
||||||
|
}
|
||||||
|
delete column.boxShadowColor;
|
||||||
|
} else {
|
||||||
|
column.boxShadow = `2px 2px 0px ${rgbaMigrationConstantV56}`;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.boxShadow = `2px 2px 0px ${rgbaMigrationConstantV56}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BoxShadowTypes.VARIANT5:
|
||||||
|
if (!isBoxShadowColorDynamic) {
|
||||||
|
// Checks is boxShadowColor is not dynamic
|
||||||
|
column.boxShadow = `-2px -2px 0px ${newBoxShadowColor}`;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.boxShadow = `-2px -2px 0px ${newBoxShadowColor}`;
|
||||||
|
}
|
||||||
|
delete column.boxShadowColor;
|
||||||
|
} else {
|
||||||
|
// Dynamic
|
||||||
|
column.boxShadow = `-2px -2px 0px ${rgbaMigrationConstantV56}`;
|
||||||
|
if (isDerivedColumn) {
|
||||||
|
derivedColumn.boxShadow = `-2px -2px 0px ${rgbaMigrationConstantV56}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate the parent level properties for JSON Form
|
||||||
|
*/
|
||||||
|
if (child.type === "JSON_FORM_WIDGET") {
|
||||||
|
const parentLevelProperties = ["submitButtonStyles", "resetButtonStyles"];
|
||||||
|
parentLevelProperties.forEach((propertyName: string) => {
|
||||||
|
const propertyPathBorderRadius = `${propertyName}.borderRadius`;
|
||||||
|
const propertyPathBoxShadow = `${propertyName}.boxShadow`;
|
||||||
|
const propertyPathBoxShadowColor = `${propertyName}.boxShadowColor`;
|
||||||
|
|
||||||
|
if (has(child, propertyPathBorderRadius)) {
|
||||||
|
const jsonFormBorderRadius = get(child, propertyPathBorderRadius);
|
||||||
|
switch (jsonFormBorderRadius) {
|
||||||
|
case ButtonBorderRadiusTypes.SHARP:
|
||||||
|
set(child, propertyPathBorderRadius, THEMING_BORDER_RADIUS.none);
|
||||||
|
break;
|
||||||
|
case ButtonBorderRadiusTypes.ROUNDED:
|
||||||
|
set(
|
||||||
|
child,
|
||||||
|
propertyPathBorderRadius,
|
||||||
|
THEMING_BORDER_RADIUS.rounded,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case ButtonBorderRadiusTypes.CIRCLE:
|
||||||
|
set(
|
||||||
|
child,
|
||||||
|
propertyPathBorderRadius,
|
||||||
|
THEMING_BORDER_RADIUS.circle,
|
||||||
|
);
|
||||||
|
addPropertyToDynamicPropertyPathList(
|
||||||
|
propertyPathBorderRadius,
|
||||||
|
child,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
set(child, propertyPathBorderRadius, THEMING_BORDER_RADIUS.none);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
set(child, propertyPathBorderRadius, THEMING_BORDER_RADIUS.none);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has(child, propertyPathBoxShadow)) {
|
||||||
|
const jsonFormBoxShadow = get(child, propertyPathBoxShadow);
|
||||||
|
const boxShadowColor =
|
||||||
|
(has(child, propertyPathBoxShadowColor) &&
|
||||||
|
get(child, propertyPathBoxShadowColor)) ||
|
||||||
|
"rgba(0, 0, 0, 0.25)";
|
||||||
|
switch (jsonFormBoxShadow) {
|
||||||
|
case BoxShadowTypes.VARIANT1:
|
||||||
|
set(
|
||||||
|
child,
|
||||||
|
propertyPathBoxShadow,
|
||||||
|
`0px 0px 4px 3px ${boxShadowColor}`,
|
||||||
|
);
|
||||||
|
addPropertyToDynamicPropertyPathList(
|
||||||
|
propertyPathBoxShadow,
|
||||||
|
child,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case BoxShadowTypes.VARIANT2:
|
||||||
|
set(
|
||||||
|
child,
|
||||||
|
propertyPathBoxShadow,
|
||||||
|
`3px 3px 4px ${boxShadowColor}`,
|
||||||
|
);
|
||||||
|
addPropertyToDynamicPropertyPathList(
|
||||||
|
propertyPathBoxShadow,
|
||||||
|
child,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case BoxShadowTypes.VARIANT3:
|
||||||
|
set(
|
||||||
|
child,
|
||||||
|
propertyPathBoxShadow,
|
||||||
|
`0px 1px 3px ${boxShadowColor}`,
|
||||||
|
);
|
||||||
|
addPropertyToDynamicPropertyPathList(
|
||||||
|
propertyPathBoxShadow,
|
||||||
|
child,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case BoxShadowTypes.VARIANT4:
|
||||||
|
set(
|
||||||
|
child,
|
||||||
|
propertyPathBoxShadow,
|
||||||
|
`2px 2px 0px ${boxShadowColor}`,
|
||||||
|
);
|
||||||
|
addPropertyToDynamicPropertyPathList(
|
||||||
|
propertyPathBoxShadow,
|
||||||
|
child,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case BoxShadowTypes.VARIANT5:
|
||||||
|
set(
|
||||||
|
child,
|
||||||
|
propertyPathBoxShadow,
|
||||||
|
`-2px -2px 0px ${boxShadowColor}`,
|
||||||
|
);
|
||||||
|
addPropertyToDynamicPropertyPathList(
|
||||||
|
propertyPathBoxShadow,
|
||||||
|
child,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
set(child, propertyPathBoxShadow, DEFAULT_BOXSHADOW);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
set(child, propertyPathBoxShadow, DEFAULT_BOXSHADOW);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate the children level properties for JSON form
|
||||||
|
*/
|
||||||
|
if (has(child, "schema")) {
|
||||||
|
const clonedSchema = clone(child.schema);
|
||||||
|
parseSchemaItem(
|
||||||
|
clonedSchema[ROOT_SCHEMA_KEY],
|
||||||
|
`schema.${ROOT_SCHEMA_KEY}`,
|
||||||
|
(schemaItem, propertyPath) => {
|
||||||
|
if (schemaItem) {
|
||||||
|
switch (schemaItem.labelTextSize) {
|
||||||
|
case TextSizes.PARAGRAPH2:
|
||||||
|
schemaItem.labelTextSize = THEMEING_TEXT_SIZES.xs;
|
||||||
|
addPropertyToDynamicPropertyPathList(
|
||||||
|
`${propertyPath}.labelTextSize`,
|
||||||
|
child,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case TextSizes.PARAGRAPH:
|
||||||
|
schemaItem.labelTextSize = THEMEING_TEXT_SIZES.sm;
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING3:
|
||||||
|
schemaItem.labelTextSize = THEMEING_TEXT_SIZES.base;
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING2:
|
||||||
|
schemaItem.labelTextSize = THEMEING_TEXT_SIZES.md;
|
||||||
|
addPropertyToDynamicPropertyPathList(
|
||||||
|
`${propertyPath}.labelTextSize`,
|
||||||
|
child,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING1:
|
||||||
|
schemaItem.labelTextSize = THEMEING_TEXT_SIZES.lg;
|
||||||
|
addPropertyToDynamicPropertyPathList(
|
||||||
|
`${propertyPath}.labelTextSize`,
|
||||||
|
child,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
schemaItem.labelTextSize = THEMEING_TEXT_SIZES.sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the default borderRadius
|
||||||
|
!has(schemaItem, "borderRadius") &&
|
||||||
|
set(schemaItem, "borderRadius", THEMING_BORDER_RADIUS.none);
|
||||||
|
// Set the default borderRadius for the Item styles in an array type:
|
||||||
|
!has(schemaItem, "cellBorderRadius") &&
|
||||||
|
set(schemaItem, "cellBorderRadius", THEMING_BORDER_RADIUS.none);
|
||||||
|
|
||||||
|
// Sets the default value for the boxShadow
|
||||||
|
!has(schemaItem, "boxShadow") &&
|
||||||
|
set(schemaItem, "boxShadow", DEFAULT_BOXSHADOW);
|
||||||
|
|
||||||
|
// Sets the default value for the boxShadow property of Item styles inside an array:
|
||||||
|
!has(schemaItem, "cellBoxShadow") &&
|
||||||
|
set(schemaItem, "cellBoxShadow", DEFAULT_BOXSHADOW);
|
||||||
|
|
||||||
|
// Sets default value as green for the accentColor(Most of the widgets require the below property):
|
||||||
|
!has(schemaItem, "accentColor") &&
|
||||||
|
set(schemaItem, "accentColor", Colors.GREEN);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
child.schema = clonedSchema;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (child.fontSize) {
|
||||||
|
case TextSizes.PARAGRAPH2:
|
||||||
|
child.fontSize = THEMEING_TEXT_SIZES.xs;
|
||||||
|
addPropertyToDynamicPropertyPathList("fontSize", child);
|
||||||
|
break;
|
||||||
|
case TextSizes.PARAGRAPH:
|
||||||
|
child.fontSize = THEMEING_TEXT_SIZES.sm;
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING3:
|
||||||
|
child.fontSize = THEMEING_TEXT_SIZES.base;
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING2:
|
||||||
|
child.fontSize = THEMEING_TEXT_SIZES.md;
|
||||||
|
addPropertyToDynamicPropertyPathList("fontSize", child);
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING1:
|
||||||
|
child.fontSize = THEMEING_TEXT_SIZES.lg;
|
||||||
|
addPropertyToDynamicPropertyPathList("fontSize", child);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (child.labelTextSize) {
|
||||||
|
case TextSizes.PARAGRAPH2:
|
||||||
|
child.labelTextSize = THEMEING_TEXT_SIZES.xs;
|
||||||
|
addPropertyToDynamicPropertyPathList("labelTextSize", child);
|
||||||
|
break;
|
||||||
|
case TextSizes.PARAGRAPH:
|
||||||
|
child.labelTextSize = THEMEING_TEXT_SIZES.sm;
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING3:
|
||||||
|
child.labelTextSize = THEMEING_TEXT_SIZES.base;
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING2:
|
||||||
|
child.labelTextSize = THEMEING_TEXT_SIZES.md;
|
||||||
|
addPropertyToDynamicPropertyPathList("labelTextSize", child);
|
||||||
|
break;
|
||||||
|
case TextSizes.HEADING1:
|
||||||
|
child.labelTextSize = THEMEING_TEXT_SIZES.lg;
|
||||||
|
addPropertyToDynamicPropertyPathList("labelTextSize", child);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
child.labelTextSize = THEMEING_TEXT_SIZES.sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add primaryColor color to missing widgets
|
||||||
|
*/
|
||||||
|
if (widgetsWithPrimaryColorProp.includes(child.type)) {
|
||||||
|
child.accentColor = "{{appsmith.theme.colors.primaryColor}}";
|
||||||
|
|
||||||
|
child.dynamicBindingPathList = [
|
||||||
|
...(child.dynamicBindingPathList || []),
|
||||||
|
{
|
||||||
|
key: "accentColor",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// specific fixes
|
||||||
|
if (child.type === "AUDIO_RECORDER_WIDGET") {
|
||||||
|
child.borderRadius = THEMING_BORDER_RADIUS.circle;
|
||||||
|
child.accentColor = child.backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child.type === "FILE_PICKER_WIDGET_V2") {
|
||||||
|
child.buttonColor = Colors.GREEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
child.type === "CHECKBOX_WIDGET" ||
|
||||||
|
child.type === "CHECKBOX_GROUP_WIDGET" ||
|
||||||
|
child.type === "SWITCH_WIDGET" ||
|
||||||
|
child.type === "SWITCH_GROUP_WIDGET"
|
||||||
|
) {
|
||||||
|
child.accentColor = Colors.GREEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child.type === "TEXT_WIDGET") {
|
||||||
|
child.fontFamily = "System Default";
|
||||||
|
}
|
||||||
|
// Adds childStyleSheets
|
||||||
|
switch (child.type) {
|
||||||
|
case "BUTTON_GROUP_WIDGET":
|
||||||
|
child.childStylesheet = BUTTON_GROUP_CHILD_STYLESHEET;
|
||||||
|
break;
|
||||||
|
case "JSON_FORM_WIDGET":
|
||||||
|
child.childStylesheet = JSON_FORM_WIDGET_CHILD_STYLESHEET;
|
||||||
|
break;
|
||||||
|
case "TABLE_WIDGET":
|
||||||
|
child.childStylesheet = TABLE_WIDGET_CHILD_STYLESHEET;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateStylingPropertiesForTheming(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export enum AlignWidgetTypes {
|
||||||
|
LEFT = "LEFT",
|
||||||
|
RIGHT = "RIGHT",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum LabelPosition {
|
||||||
|
Left = "Left",
|
||||||
|
Right = "Right",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const migrateCheckboxSwitchProperty = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "SWITCH_WIDGET" || child.type === "CHECKBOX_WIDGET") {
|
||||||
|
if (child.alignWidget === "RIGHT") {
|
||||||
|
child.alignWidget = AlignWidgetTypes.RIGHT;
|
||||||
|
child.labelPosition = LabelPosition.Left;
|
||||||
|
} else {
|
||||||
|
child.alignWidget = AlignWidgetTypes.LEFT;
|
||||||
|
child.labelPosition = LabelPosition.Right;
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateCheckboxSwitchProperty(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateChartWidgetReskinningData = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "CHART_WIDGET") {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
child.hasOwnProperty("accentColor") &&
|
||||||
|
child.hasOwnProperty("fontFamily")
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
child.accentColor = "{{appsmith.theme.colors.primaryColor}}";
|
||||||
|
child.fontFamily = "{{appsmith.theme.fontFamily.appFont}}";
|
||||||
|
|
||||||
|
child.dynamicBindingPathList = [
|
||||||
|
...(child.dynamicBindingPathList || []),
|
||||||
|
{
|
||||||
|
key: "accentColor",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "fontFamily",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateChartWidgetReskinningData(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds validation object to each column in the primaryColumns
|
||||||
|
*/
|
||||||
|
export const migrateTableWidgetV2Validation = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "TABLE_WIDGET_V2") {
|
||||||
|
const primaryColumns = child.primaryColumns;
|
||||||
|
|
||||||
|
for (const key in primaryColumns) {
|
||||||
|
if (primaryColumns.hasOwnProperty(key)) {
|
||||||
|
primaryColumns[key].validation = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateTableWidgetV2Validation(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
// this is a repeat of the migration 059-migrate-chart-widget-reskinning-data
|
||||||
|
|
||||||
|
export {};
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
import { isDynamicValue, stringToJS } from "../utils";
|
||||||
|
|
||||||
|
const getBindingTemplate = (widgetName: string) => {
|
||||||
|
const prefixTemplate = `{{ ((options, serverSideFiltering) => ( `;
|
||||||
|
const suffixTemplate = `))(${widgetName}.options, ${widgetName}.serverSideFiltering) }}`;
|
||||||
|
|
||||||
|
return { prefixTemplate, suffixTemplate };
|
||||||
|
};
|
||||||
|
|
||||||
|
const SelectTypeWidgets = ["SELECT_WIDGET", "MULTI_SELECT_WIDGET_V2"];
|
||||||
|
|
||||||
|
export function MigrateSelectTypeWidgetDefaultValue(currentDSL: DSLWidget) {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (SelectTypeWidgets.includes(child.type)) {
|
||||||
|
const defaultOptionValue = child.defaultOptionValue;
|
||||||
|
const { prefixTemplate, suffixTemplate } = getBindingTemplate(
|
||||||
|
child.widgetName,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof defaultOptionValue === "string" &&
|
||||||
|
isDynamicValue(defaultOptionValue) &&
|
||||||
|
!defaultOptionValue.endsWith(suffixTemplate) &&
|
||||||
|
!defaultOptionValue.startsWith(prefixTemplate)
|
||||||
|
) {
|
||||||
|
child.defaultOptionValue = `${prefixTemplate}${stringToJS(
|
||||||
|
defaultOptionValue,
|
||||||
|
)}${suffixTemplate}`;
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = MigrateSelectTypeWidgetDefaultValue(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateMapChartWidgetReskinningData = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "MAP_CHART_WIDGET") {
|
||||||
|
if (!child.hasOwnProperty("fontFamily")) {
|
||||||
|
child.fontFamily = "{{appsmith.theme.fontFamily.appFont}}";
|
||||||
|
|
||||||
|
child.dynamicBindingPathList = [
|
||||||
|
...(child.dynamicBindingPathList || []),
|
||||||
|
{
|
||||||
|
key: "fontFamily",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateMapChartWidgetReskinningData(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
import { isDynamicValue } from "../utils";
|
||||||
|
|
||||||
|
// migrate all rate widgets with isDisabled = true to isReadOnly = true
|
||||||
|
export function migrateRateWidgetDisabledState(currentDSL: DSLWidget) {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "RATE_WIDGET") {
|
||||||
|
// if isDisabled is true, set isReadOnly to true
|
||||||
|
if (child.isDisabled === true) {
|
||||||
|
child.isDisabled = false;
|
||||||
|
child.isReadOnly = true;
|
||||||
|
} else if (
|
||||||
|
// if isDisabled is a dynamic value, set isReadOnly to the same dynamic value
|
||||||
|
typeof child.isDisabled === "string" &&
|
||||||
|
isDynamicValue(child.isDisabled)
|
||||||
|
) {
|
||||||
|
child.isReadOnly = child.isDisabled;
|
||||||
|
child.isDisabled = false;
|
||||||
|
|
||||||
|
// add readonly to dynamic binding
|
||||||
|
child.dynamicBindingPathList = [
|
||||||
|
...(child.dynamicBindingPathList || []),
|
||||||
|
{
|
||||||
|
key: "isReadOnly",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
child.dynamicPropertyPathList = [
|
||||||
|
...(child.dynamicPropertyPathList || []),
|
||||||
|
{
|
||||||
|
key: "isReadOnly",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// remove readonly from dynamic binding
|
||||||
|
child.dynamicBindingPathList = child.dynamicBindingPathList.filter(
|
||||||
|
(item: { key: string }) => item.key !== "isDisabled",
|
||||||
|
);
|
||||||
|
|
||||||
|
child.dynamicPropertyPathList = child.dynamicPropertyPathList.filter(
|
||||||
|
(item: { key: string }) => item.key !== "isDisabled",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateRateWidgetDisabledState(child);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const migrateCodeScannerLayout = (currentDSL: DSLWidget) => {
|
||||||
|
currentDSL.children = currentDSL.children?.map((child: DSLWidget) => {
|
||||||
|
if (child.type === "CODE_SCANNER_WIDGET") {
|
||||||
|
if (!child.scannerLayout) {
|
||||||
|
child.scannerLayout = "CLICK_TO_SCAN";
|
||||||
|
}
|
||||||
|
} else if (child.children && child.children.length > 0) {
|
||||||
|
child = migrateCodeScannerLayout(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { isDynamicValue, traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const migrateTableWidgetV2ValidationBinding = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (widget.type === "TABLE_WIDGET_V2") {
|
||||||
|
const primaryColumns = widget.primaryColumns;
|
||||||
|
|
||||||
|
for (const column in primaryColumns) {
|
||||||
|
if (
|
||||||
|
primaryColumns.hasOwnProperty(column) &&
|
||||||
|
primaryColumns[column].validation &&
|
||||||
|
primaryColumns[column].validation.isColumnEditableCellValid &&
|
||||||
|
isDynamicValue(
|
||||||
|
primaryColumns[column].validation.isColumnEditableCellValid,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
const propertyValue =
|
||||||
|
primaryColumns[column].validation.isColumnEditableCellValid;
|
||||||
|
|
||||||
|
const binding = propertyValue
|
||||||
|
.replace(oldBindingPrefix, "")
|
||||||
|
.replace(oldBindingSuffix(widget.widgetName, column), "");
|
||||||
|
|
||||||
|
primaryColumns[column].validation.isColumnEditableCellValid =
|
||||||
|
newBindingPrefix +
|
||||||
|
binding +
|
||||||
|
newBindingSuffix(widget.widgetName, column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export function migrateLabelPosition(currentDSL: DSLWidget) {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (
|
||||||
|
(widget.type === "PHONE_INPUT_WIDGET" ||
|
||||||
|
widget.type === "CURRENCY_INPUT_WIDGET") &&
|
||||||
|
widget.labelPosition === undefined
|
||||||
|
) {
|
||||||
|
widget.labelPosition = "Left";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export const WidgetHeightLimits = {
|
||||||
|
MAX_HEIGHT_IN_ROWS: 9000,
|
||||||
|
MIN_HEIGHT_IN_ROWS: 4,
|
||||||
|
MIN_CANVAS_HEIGHT_IN_ROWS: 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WidgetFeatureProps: Record<string, Record<string, unknown>> = {
|
||||||
|
dynamicHeight: {
|
||||||
|
minDynamicHeight: WidgetHeightLimits.MIN_HEIGHT_IN_ROWS,
|
||||||
|
maxDynamicHeight: WidgetHeightLimits.MAX_HEIGHT_IN_ROWS,
|
||||||
|
dynamicHeight: "FIXED",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const migratePropertiesForDynamicHeight = (currentDSL: DSLWidget) => {
|
||||||
|
/* const widgetsWithDynamicHeight = compact(
|
||||||
|
ALL_WIDGETS_AND_CONFIG.map(([, config]) => {
|
||||||
|
if (config.features?.dynamicHeight) return config.type;
|
||||||
|
}),
|
||||||
|
); */
|
||||||
|
// Ideally the above should be the code, however,
|
||||||
|
// there seems to be some cyclic imports which
|
||||||
|
// cause the test to fail in CI.
|
||||||
|
const widgetsWithDynamicHeight = [
|
||||||
|
"CONTAINER_WIDGET",
|
||||||
|
"TEXT_WIDGET",
|
||||||
|
"CHECKBOX_WIDGET",
|
||||||
|
"RADIO_GROUP_WIDGET",
|
||||||
|
"TABS_WIDGET",
|
||||||
|
"MODAL_WIDGET",
|
||||||
|
"RICH_TEXT_EDITOR_WIDGET",
|
||||||
|
"DATE_PICKER_WIDGET2",
|
||||||
|
"SWITCH_WIDGET",
|
||||||
|
"FORM_WIDGET",
|
||||||
|
"RATE_WIDGET",
|
||||||
|
"CHECKBOX_GROUP_WIDGET",
|
||||||
|
"STATBOX_WIDGET",
|
||||||
|
"MULTI_SELECT_TREE_WIDGET",
|
||||||
|
"SINGLE_SELECT_TREE_WIDGET",
|
||||||
|
"SWITCH_GROUP_WIDGET",
|
||||||
|
"SELECT_WIDGET",
|
||||||
|
"MULTI_SELECT_WIDGET_V2",
|
||||||
|
"INPUT_WIDGET_V2",
|
||||||
|
"PHONE_INPUT_WIDGET",
|
||||||
|
"CURRENCY_INPUT_WIDGET",
|
||||||
|
"JSON_FORM_WIDGET",
|
||||||
|
];
|
||||||
|
if (widgetsWithDynamicHeight.includes(currentDSL.type)) {
|
||||||
|
currentDSL = {
|
||||||
|
...currentDSL,
|
||||||
|
...WidgetFeatureProps["dynamicHeight"],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (Array.isArray(currentDSL.children)) {
|
||||||
|
currentDSL.children = currentDSL.children.map(
|
||||||
|
migratePropertiesForDynamicHeight,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return currentDSL;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export const migrateMenuButtonDynamicItems = (currentDSL: DSLWidget) => {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (widget.type === "MENU_BUTTON_WIDGET" && !widget.menuItemsSource) {
|
||||||
|
widget.menuItemsSource = "STATIC";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export const migrateChildStylesheetFromDynamicBindingPathList = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
const widgetsWithChildStylesheet = [
|
||||||
|
"TABLE_WIDGET_V2",
|
||||||
|
"BUTTON_GROUP_WIDGET",
|
||||||
|
"JSON_FORM_WIDGET",
|
||||||
|
];
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (
|
||||||
|
widgetsWithChildStylesheet.includes(widget.type) &&
|
||||||
|
widget.childStylesheet
|
||||||
|
) {
|
||||||
|
const newPaths = widget.dynamicBindingPathList?.filter(
|
||||||
|
({ key }: { key: string }) => !key.startsWith("childStylesheet."),
|
||||||
|
);
|
||||||
|
widget.dynamicBindingPathList = newPaths;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { isDynamicValue, stringToJS, traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export const migrateTableWidgetV2SelectOption = (currentDSL: DSLWidget) => {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (widget.type === "TABLE_WIDGET_V2") {
|
||||||
|
Object.values(
|
||||||
|
widget.primaryColumns as Record<
|
||||||
|
string,
|
||||||
|
{ columnType: string; selectOptions: string }
|
||||||
|
>,
|
||||||
|
)
|
||||||
|
.filter((column) => column.columnType === "select")
|
||||||
|
.forEach((column) => {
|
||||||
|
const selectOptions = column.selectOptions;
|
||||||
|
|
||||||
|
if (selectOptions && isDynamicValue(selectOptions)) {
|
||||||
|
column.selectOptions = `{{${
|
||||||
|
widget.widgetName
|
||||||
|
}.processedTableData.map((currentRow, currentIndex) => ( ${stringToJS(
|
||||||
|
selectOptions,
|
||||||
|
)}))}}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
import type { DSLWidget } from "../types";
|
||||||
|
|
||||||
|
export function migrateListWidgetChildrenForAutoHeight(
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
isChildOfListWidget = false,
|
||||||
|
): DSLWidget {
|
||||||
|
if (!currentDSL) return currentDSL;
|
||||||
|
|
||||||
|
let isCurrentListWidget = false;
|
||||||
|
if (currentDSL.type === "LIST_WIDGET") isCurrentListWidget = true;
|
||||||
|
|
||||||
|
//Iterate and recursively call each children
|
||||||
|
const children = currentDSL.children?.map((childDSL: DSLWidget) =>
|
||||||
|
migrateListWidgetChildrenForAutoHeight(
|
||||||
|
childDSL,
|
||||||
|
isCurrentListWidget || isChildOfListWidget,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let newDSL;
|
||||||
|
// Add dynamicHeight to FIXED for each of it's children
|
||||||
|
if (isChildOfListWidget && !currentDSL.detachFromLayout) {
|
||||||
|
newDSL = {
|
||||||
|
...currentDSL,
|
||||||
|
dynamicHeight: "FIXED",
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
newDSL = {
|
||||||
|
...currentDSL,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (children) {
|
||||||
|
newDSL.children = children;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newDSL;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export const migrateInputWidgetShowStepArrows = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
): DSLWidget => {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (
|
||||||
|
(widget.type === "CURRENCY_INPUT_WIDGET" ||
|
||||||
|
(widget.type === "INPUT_WIDGET_V2" && widget.inputType === "NUMBER")) &&
|
||||||
|
widget.showStepArrows === undefined
|
||||||
|
) {
|
||||||
|
widget.showStepArrows = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export const migrateMenuButtonDynamicItemsInsideTableWidget = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (widget.type === "TABLE_WIDGET_V2") {
|
||||||
|
const primaryColumns = widget.primaryColumns;
|
||||||
|
|
||||||
|
if (primaryColumns) {
|
||||||
|
for (const column in primaryColumns) {
|
||||||
|
if (
|
||||||
|
primaryColumns.hasOwnProperty(column) &&
|
||||||
|
primaryColumns[column].columnType === "menuButton" &&
|
||||||
|
!primaryColumns[column].menuItemsSource
|
||||||
|
) {
|
||||||
|
primaryColumns[column].menuItemsSource = "STATIC";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
const GRID_DENSITY_MIGRATION_V1 = 4;
|
||||||
|
|
||||||
|
export function migrateInputWidgetsMultiLineInputType(
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
): DSLWidget {
|
||||||
|
if (!currentDSL) return currentDSL;
|
||||||
|
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (widget.type === "INPUT_WIDGET_V2") {
|
||||||
|
const minInputSingleLineHeight =
|
||||||
|
widget.label || widget.tooltip
|
||||||
|
? // adjust height for label | tooltip extra div
|
||||||
|
GRID_DENSITY_MIGRATION_V1 + 4
|
||||||
|
: // GRID_DENSITY_MIGRATION_V1 used to adjust code as per new scaled canvas.
|
||||||
|
GRID_DENSITY_MIGRATION_V1;
|
||||||
|
const isMultiLine =
|
||||||
|
(widget.bottomRow - widget.topRow) / minInputSingleLineHeight > 1 &&
|
||||||
|
widget.inputType === "TEXT";
|
||||||
|
|
||||||
|
if (isMultiLine) {
|
||||||
|
widget.inputType = "MULTI_LINE_TEXT";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export const migrateColumnFreezeAttributes = (currentDSL: DSLWidget) => {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (widget.type === "TABLE_WIDGET_V2") {
|
||||||
|
const primaryColumns = widget?.primaryColumns;
|
||||||
|
|
||||||
|
// Assign default sticky value to each column
|
||||||
|
if (primaryColumns) {
|
||||||
|
for (const column in primaryColumns) {
|
||||||
|
if (!primaryColumns[column].hasOwnProperty("sticky")) {
|
||||||
|
primaryColumns[column].sticky = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
widget.canFreezeColumn = false;
|
||||||
|
widget.columnUpdatedAt = Date.now();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import type { ColumnPropertiesV2, DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export const migrateTableSelectOptionAttributesForNewRow = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (widget.type === "TABLE_WIDGET_V2") {
|
||||||
|
const primaryColumns = widget?.primaryColumns as ColumnPropertiesV2;
|
||||||
|
|
||||||
|
// Set default value for allowSameOptionsInNewRow
|
||||||
|
if (primaryColumns) {
|
||||||
|
Object.values(primaryColumns).forEach((column: any) => {
|
||||||
|
if (
|
||||||
|
column.hasOwnProperty("columnType") &&
|
||||||
|
column.columnType === "select"
|
||||||
|
) {
|
||||||
|
column.allowSameOptionsInNewRow = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import type { ColumnPropertiesV2, DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export const migrateBindingPrefixSuffixForInlineEditValidationControl = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (widget.type === "TABLE_WIDGET_V2") {
|
||||||
|
const tableId = widget.widgetName;
|
||||||
|
|
||||||
|
const oldBindingPrefix = `{{((isNewRow)=>(`;
|
||||||
|
const newBindingPrefix = `{{
|
||||||
|
(
|
||||||
|
(isNewRow, currentIndex, currentRow) => (
|
||||||
|
`;
|
||||||
|
|
||||||
|
const oldBindingSuffix = `))(${tableId}.isAddRowInProgress)}}`;
|
||||||
|
const newBindingSuffix = `
|
||||||
|
))
|
||||||
|
(
|
||||||
|
${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 applicableValidationNames = [
|
||||||
|
"min",
|
||||||
|
"max",
|
||||||
|
"regex",
|
||||||
|
"errorMessage",
|
||||||
|
"isColumnEditableCellRequired",
|
||||||
|
];
|
||||||
|
const primaryColumns = widget?.primaryColumns as ColumnPropertiesV2;
|
||||||
|
|
||||||
|
Object.values(primaryColumns).forEach((column: any) => {
|
||||||
|
if (column.hasOwnProperty("validation")) {
|
||||||
|
const validations = column.validation;
|
||||||
|
for (const validationName in validations) {
|
||||||
|
if (applicableValidationNames.indexOf(validationName) == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const validationValue = validations[validationName];
|
||||||
|
if (typeof validationValue !== "string") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let compressedValidationValue = validationValue.replace(/\s/g, "");
|
||||||
|
compressedValidationValue = compressedValidationValue.replace(
|
||||||
|
oldBindingPrefix,
|
||||||
|
newBindingPrefix,
|
||||||
|
);
|
||||||
|
compressedValidationValue = compressedValidationValue.replace(
|
||||||
|
oldBindingSuffix,
|
||||||
|
newBindingSuffix,
|
||||||
|
);
|
||||||
|
validations[validationName] = compressedValidationValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export const migrateTableWidgetTableDataJsMode = (currentDSL: DSLWidget) => {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (widget.type === "TABLE_WIDGET_V2") {
|
||||||
|
const dynamicPropertyPathList = (
|
||||||
|
widget.dynamicPropertyPathList || []
|
||||||
|
).concat([
|
||||||
|
{
|
||||||
|
key: "tableData",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
widget.dynamicPropertyPathList = dynamicPropertyPathList;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export function migrateSelectWidgetOptionToSourceData(currentDSL: DSLWidget) {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (
|
||||||
|
["SELECT_WIDGET", "MULTI_SELECT_WIDGET_V2"].includes(widget.type) &&
|
||||||
|
widget.options
|
||||||
|
) {
|
||||||
|
widget.sourceData = widget.options;
|
||||||
|
widget.optionLabel = "label";
|
||||||
|
widget.optionValue = "value";
|
||||||
|
|
||||||
|
delete widget.options;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Migration to remove the options from dynamicBindingPathList and replace it with
|
||||||
|
* sourceData
|
||||||
|
*/
|
||||||
|
export function migrateSelectWidgetSourceDataBindingPathList(
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (["SELECT_WIDGET", "MULTI_SELECT_WIDGET_V2"].includes(widget.type)) {
|
||||||
|
const dynamicBindingPathList = widget.dynamicBindingPathList;
|
||||||
|
|
||||||
|
const optionsIndex = dynamicBindingPathList
|
||||||
|
?.map((d: { key: string }) => d.key)
|
||||||
|
.indexOf("options");
|
||||||
|
|
||||||
|
if (optionsIndex && optionsIndex > -1) {
|
||||||
|
dynamicBindingPathList?.splice(optionsIndex, 1, {
|
||||||
|
key: "sourceData",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export const migrateChartWidgetLabelOrientationStaggerOption = (
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) => {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (widget.type == "CHART_WIDGET") {
|
||||||
|
const chartWidgetProps = widget;
|
||||||
|
if (chartWidgetProps.labelOrientation == "stagger") {
|
||||||
|
chartWidgetProps.labelOrientation = "auto";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export const migrateAddShowHideDataPointLabels = (currentDSL: DSLWidget) => {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (widget.type == "CHART_WIDGET") {
|
||||||
|
const chartWidgetProps = widget;
|
||||||
|
chartWidgetProps.showDataPointLabel = chartWidgetProps.allowScroll;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Migration to add sourceData to the dynamicPropertyPathList
|
||||||
|
*/
|
||||||
|
export function migrateSelectWidgetAddSourceDataPropertyPathList(
|
||||||
|
currentDSL: DSLWidget,
|
||||||
|
) {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (["SELECT_WIDGET", "MULTI_SELECT_WIDGET_V2"].includes(widget.type)) {
|
||||||
|
const dynamicPropertyPathList = widget.dynamicPropertyPathList;
|
||||||
|
|
||||||
|
const sourceDataIndex = dynamicPropertyPathList
|
||||||
|
?.map((d: { key: string }) => d.key)
|
||||||
|
.indexOf("sourceData");
|
||||||
|
|
||||||
|
if (sourceDataIndex && sourceDataIndex === -1) {
|
||||||
|
dynamicPropertyPathList?.push({
|
||||||
|
key: "sourceData",
|
||||||
|
});
|
||||||
|
} else if (!Array.isArray(dynamicPropertyPathList)) {
|
||||||
|
widget.dynamicPropertyPathList = [
|
||||||
|
{
|
||||||
|
key: "sourceData",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
const DefaultEChartConfig = {
|
||||||
|
dataset: {
|
||||||
|
source: [
|
||||||
|
["Day", "Baidu", "Google", "Bing"],
|
||||||
|
["Mon", 620, 120, 60],
|
||||||
|
["Tue", 732, 132, 72],
|
||||||
|
["Wed", 701, 101, 71],
|
||||||
|
["Thu", 734, 134, 74],
|
||||||
|
["Fri", 1090, 290, 190],
|
||||||
|
["Sat", 1130, 230, 130],
|
||||||
|
["Sun", 1120, 220, 110],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: "axis",
|
||||||
|
axisPointer: {
|
||||||
|
type: "shadow",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
text: "Search Engine Usage",
|
||||||
|
left: "center",
|
||||||
|
textStyle: {
|
||||||
|
width: 200,
|
||||||
|
overflow: "truncate",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
top: 40,
|
||||||
|
type: "scroll",
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: 15,
|
||||||
|
right: 15,
|
||||||
|
bottom: 30,
|
||||||
|
top: 100,
|
||||||
|
containLabel: true,
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: "category",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: "value",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: "bar",
|
||||||
|
stack: "Search Engine",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "bar",
|
||||||
|
stack: "Search Engine",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "bar",
|
||||||
|
stack: "Search Engine",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const migrateDefaultValuesForCustomEChart = (currentDSL: DSLWidget) => {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (widget.type == "CHART_WIDGET") {
|
||||||
|
const chartWidgetProps = widget;
|
||||||
|
chartWidgetProps.customEChartConfig = DefaultEChartConfig;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import type { DSLWidget, WidgetProps } from "../types";
|
||||||
|
import { traverseDSLAndMigrate } from "../utils";
|
||||||
|
|
||||||
|
export const migrateTableServerSideFiltering = (currentDSL: DSLWidget) => {
|
||||||
|
return traverseDSLAndMigrate(currentDSL, (widget: WidgetProps) => {
|
||||||
|
if (widget.type === "TABLE_WIDGET_V2") {
|
||||||
|
widget.enableServerSideFiltering = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user