We missed a race condition in: #25104 which caused some test cases to fail. This would rarely happen to any new apps in production but to ensure backwards compatibility we are updating the code itself
1632 lines
49 KiB
TypeScript
1632 lines
49 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,
|
|
} 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 "widgets/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 "widgets/constants";
|
|
import { migrateRecaptchaType } from "./migrations/ButtonWidgetMigrations";
|
|
import type { PrivateWidgets } from "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 } 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 { 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 = 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;
|
|
};
|