PromucFlow_constructor/app/client/src/utils/DSLMigrations.ts
Dhruvik Neharia eb567c0af5
chore: Remove server side filtering flag (#27663)
## Description
Remove the feature flag of server-side filtering for the table widget
and add migration.

#### PR fixes following issue(s)
Fixes #27164

#### Type of change
- Chore (housekeeping or task changes that don't impact user perception)

## 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
- [ ] Manual
- [ ] JUnit
- [ ] Jest
- [ ] 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
2023-10-04 13:48:41 +05:30

1679 lines
51 KiB
TypeScript

import { generateReactKey } from "./generators";
import {
GridDefaults,
LATEST_PAGE_VERSION,
MAIN_CONTAINER_WIDGET_ID,
} from "constants/WidgetConstants";
import { nextAvailableRowInContainer } from "entities/Widget/utils";
import { get, has, isEmpty, isString, omit, set } from "lodash";
import * as Sentry from "@sentry/react";
import type { ChartDataPoint } from "widgets/ChartWidget/constants";
import log from "loglevel";
import { migrateIncorrectDynamicBindingPathLists } from "./migrations/IncorrectDynamicBindingPathLists";
import {
migrateTablePrimaryColumnsBindings,
migrateTableWidgetHeaderVisibilityProperties,
migrateTableWidgetParentRowSpaceProperty,
tableWidgetPropertyPaneMigrations,
migrateTablePrimaryColumnsComputedValue,
migrateTableWidgetDelimiterProperties,
migrateTableWidgetSelectedRowBindings,
migrateTableSanitizeColumnKeys,
isSortableMigration,
migrateTableWidgetIconButtonVariant,
migrateTableWidgetV2Validation,
migrateTableWidgetV2ValidationBinding,
migrateMenuButtonDynamicItemsInsideTableWidget,
migrateTableWidgetV2SelectOption,
migrateColumnFreezeAttributes,
migrateTableSelectOptionAttributesForNewRow,
migrateBindingPrefixSuffixForInlineEditValidationControl,
migrateTableWidgetTableDataJsMode,
migrateTableServerSideFiltering,
} from "./migrations/TableWidget";
import {
migrateTextStyleFromTextWidget,
migrateScrollTruncateProperties,
} from "./migrations/TextWidget";
import { DATA_BIND_REGEX_GLOBAL } from "constants/BindingsConstants";
import { theme } from "constants/DefaultTheme";
import { getCanvasSnapRows } from "./WidgetPropsUtils";
import type { FetchPageResponse } from "api/PageApi";
import { GRID_DENSITY_MIGRATION_V1 } from "WidgetProvider/constants";
// import defaultTemplate from "templates/default";
import { renameKeyInObject } from "./helpers";
import type { ColumnProperties } from "widgets/TableWidget/component/Constants";
import {
migrateMenuButtonDynamicItems,
migrateMenuButtonWidgetButtonProperties,
} from "./migrations/MenuButtonWidget";
import { ButtonStyleTypes, ButtonVariantTypes } from "components/constants";
import { Colors } from "constants/Colors";
import {
migrateModalIconButtonWidget,
migrateResizableModalWidgetProperties,
} from "./migrations/ModalWidget";
import { migrateCheckboxGroupWidgetInlineProperty } from "./migrations/CheckboxGroupWidget";
import { migrateMapWidgetIsClickedMarkerCentered } from "./migrations/MapWidget";
import type { DSLWidget } from "WidgetProvider/constants";
import { migrateRecaptchaType } from "./migrations/ButtonWidgetMigrations";
import type { PrivateWidgets } from "@appsmith/entities/DataTree/types";
import {
migrateChildStylesheetFromDynamicBindingPathList,
migrateStylingPropertiesForTheming,
} from "./migrations/ThemingMigrations";
import {
migratePhoneInputWidgetAllowFormatting,
migratePhoneInputWidgetDefaultDialCode,
} from "./migrations/PhoneInputWidgetMigrations";
import {
migrateCurrencyInputWidgetDefaultCurrencyCode,
migrateInputWidgetShowStepArrows,
} from "./migrations/CurrencyInputWidgetMigrations";
import { migrateRadioGroupAlignmentProperty } from "./migrations/RadioGroupWidget";
import { migrateCheckboxSwitchProperty } from "./migrations/PropertyPaneMigrations";
import { migrateChartWidgetReskinningData } from "./migrations/ChartWidgetReskinningMigrations";
import {
MigrateSelectTypeWidgetDefaultValue,
migrateSelectWidgetAddSourceDataPropertyPathList,
migrateSelectWidgetOptionToSourceData,
migrateSelectWidgetSourceDataBindingPathList,
} from "./migrations/SelectWidget";
import { migrateMapChartWidgetReskinningData } from "./migrations/MapChartReskinningMigrations";
import { migrateRateWidgetDisabledState } from "./migrations/RateWidgetMigrations";
import { migrateCodeScannerLayout } from "./migrations/CodeScannerWidgetMigrations";
import { migrateLabelPosition } from "./migrations/MigrateLabelPosition";
import {
migrateInputWidgetsMultiLineInputType,
migrateListWidgetChildrenForAutoHeight,
migratePropertiesForDynamicHeight,
} from "./migrations/autoHeightMigrations";
import {
migrateChartWidgetLabelOrientationStaggerOption,
migrateAddShowHideDataPointLabels,
migrateDefaultValuesForCustomEChart,
} from "./migrations/ChartWidget";
import { flattenDSL } from "@shared/dsl";
/**
* adds logBlackList key for all list widget children
*
* @param currentDSL
* @returns
*/
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;
};
/**
* 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: PrivateWidgets = {};
Object.keys(child.template).forEach((entityName) => {
privateWidgets[entityName] = true;
});
if (!child.privateWidgets) {
set(child, `privateWidgets`, privateWidgets);
}
}
return child;
});
return currentDSL;
};
/**
* 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;
};
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 = {
...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,
};
// @ts-expect-error: Types are not available
delete canvas.dynamicBindings;
// @ts-expect-error: Types are not available
delete canvas.dynamicProperties;
if (canvas.children && canvas.children.length > 0)
canvas.children = canvas.children.map(updateContainers);
dsl.children = [{ ...canvas }];
}
}
return dsl;
};
//transform chart data, from old chart widget to new chart widget
//updated chart widget has support for multiple series
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 as ChartDataPoint[] }];
} 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;
};
export const singleChartDataMigration = (currentDSL: DSLWidget) => {
currentDSL.children = currentDSL.children?.map((child) => {
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;
};
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;
};
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;
};
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;
};
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;
};
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;
};
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) => canvasNameConflictMigration(c, props));
return currentDSL;
};
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) => canvasNameConflictMigration(c, props));
return currentDSL;
};
export const rteDefaultValueMigration = (currentDSL: DSLWidget): DSLWidget => {
if (currentDSL.type === "RICH_TEXT_EDITOR_WIDGET") {
currentDSL.inputType = "html";
}
currentDSL.children?.forEach((children) =>
rteDefaultValueMigration(children),
);
return currentDSL;
};
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 as any) &&
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) => {
return each.key !== "tabs";
});
currentDSL.dynamicBindingPathList =
currentDSL.dynamicBindingPathList.filter((each) => {
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;
};
// A rudimentary transform function which updates the DSL based on its version.
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 Failed",
oldData: currentDSL.chartData,
});
currentDSL.chartData = [];
}
}
}
if (currentDSL.children && currentDSL.children.length) {
currentDSL.children = currentDSL.children.map(migrateOldChartData);
}
return currentDSL;
};
/**
* 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) => (path.key = `chartData[${index}].data`),
) > -1
) {
const foundIndex = children.dynamicBindingPathList.findIndex(
(path) => (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;
};
const pixelToNumber = (pixel: string) => {
if (pixel.includes("px")) {
return parseInt(pixel.split("px").join(""));
}
return 0;
};
export const calculateDynamicHeight = () => {
const screenHeight = window.innerHeight;
const gridRowHeight = GridDefaults.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 * pixelToNumber(theme.smallHeaderHeight) +
pixelToNumber(theme.bottomBarHeight);
const calculatedMinHeight =
Math.floor((screenHeight - buffer) / gridRowHeight) * gridRowHeight;
return calculatedMinHeight;
};
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;
};
// 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
export const transformDSL = (currentDSL: DSLWidget, newPage = false) => {
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 - GridDefaults.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 / GridDefaults.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;
}
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 = 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_PAGE_VERSION;
}
return currentDSL;
};
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) =>
migrateButtonVariant(child),
);
}
return currentDSL;
};
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) =>
revertTableDefaultSelectedRow(child),
);
}
return currentDSL;
};
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 = ButtonVariantTypes.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) =>
revertButtonStyleToButtonColor(child),
);
}
return currentDSL;
};
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) =>
migrateInputValidation(child),
);
}
return currentDSL;
};
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;
};
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) =>
migrateTableDefaultSelectedRow(child),
);
}
return currentDSL;
};
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;
};
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) =>
migrateToNewMultiSelect(child),
);
}
return currentDSL;
};
export const migrateObjectFitToImageWidget = (dsl: DSLWidget) => {
const addObjectFitProperty = (widgetProps: DSLWidget) => {
widgetProps.objectFit = "cover";
if (widgetProps.children && widgetProps.children.length) {
widgetProps.children.forEach((eachWidgetProp: DSLWidget) => {
if (widgetProps.type === "IMAGE_WIDGET") {
addObjectFitProperty(eachWidgetProp);
}
});
}
};
addObjectFitProperty(dsl);
return dsl;
};
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) => {
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) =>
migrateOverFlowingTabsWidgets(eachChild, canvasWidgets),
);
}
return currentDSL;
};
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) =>
migrateWidgetsWithoutLeftRightColumns(dsl, canvasWidgets),
);
}
return currentDSL;
};
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) => {
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;
};
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;
};
export const checkIfMigrationIsNeeded = (
fetchPageResponse?: FetchPageResponse,
) => {
const currentDSL = fetchPageResponse?.data.layouts[0].dsl;
if (!currentDSL) return false;
return currentDSL.version !== LATEST_PAGE_VERSION;
};
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;
};
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;
};