2019-11-25 05:07:27 +00:00
|
|
|
import { FetchPageResponse } from "api/PageApi";
|
2020-03-27 09:02:11 +00:00
|
|
|
import { CANVAS_DEFAULT_HEIGHT_PX } from "constants/AppConstants";
|
2021-08-24 11:38:20 +00:00
|
|
|
import { XYCord } from "utils/hooks/useCanvasDragging";
|
2019-11-25 05:07:27 +00:00
|
|
|
import { ContainerWidgetProps } from "widgets/ContainerWidget";
|
|
|
|
|
import { WidgetConfigProps } from "reducers/entityReducers/widgetConfigReducer";
|
2019-11-13 07:00:25 +00:00
|
|
|
import {
|
|
|
|
|
WidgetOperation,
|
2020-03-06 09:45:21 +00:00
|
|
|
WidgetOperations,
|
|
|
|
|
WidgetProps,
|
2019-11-25 05:07:27 +00:00
|
|
|
} from "widgets/BaseWidget";
|
2020-01-16 11:46:21 +00:00
|
|
|
import {
|
|
|
|
|
GridDefaults,
|
2021-05-18 18:29:39 +00:00
|
|
|
LATEST_PAGE_VERSION,
|
2021-03-16 05:01:37 +00:00
|
|
|
MAIN_CONTAINER_WIDGET_ID,
|
2020-04-17 16:15:09 +00:00
|
|
|
RenderMode,
|
2020-03-06 09:45:21 +00:00
|
|
|
WidgetType,
|
2020-01-16 11:46:21 +00:00
|
|
|
WidgetTypes,
|
|
|
|
|
} from "constants/WidgetConstants";
|
2021-06-18 07:42:57 +00:00
|
|
|
import { renameKeyInObject, snapToGrid } from "./helpers";
|
2019-11-13 07:00:25 +00:00
|
|
|
import { OccupiedSpace } from "constants/editorConstants";
|
2020-02-13 09:32:24 +00:00
|
|
|
import defaultTemplate from "templates/default";
|
2020-03-27 09:02:11 +00:00
|
|
|
import { generateReactKey } from "./generators";
|
2020-04-15 15:26:36 +00:00
|
|
|
import { ChartDataPoint } from "widgets/ChartWidget";
|
2020-09-16 10:28:01 +00:00
|
|
|
import { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReducer";
|
2021-08-17 12:54:43 +00:00
|
|
|
import { has, isString, set, isEmpty, omit, get } from "lodash";
|
2020-09-18 05:22:54 +00:00
|
|
|
import log from "loglevel";
|
2021-02-25 11:51:54 +00:00
|
|
|
import {
|
|
|
|
|
migrateTablePrimaryColumnsBindings,
|
|
|
|
|
tableWidgetPropertyPaneMigrations,
|
2021-05-31 11:39:06 +00:00
|
|
|
migrateTableWidgetParentRowSpaceProperty,
|
2021-06-09 10:16:48 +00:00
|
|
|
migrateTableWidgetHeaderVisibilityProperties,
|
2021-07-22 08:43:58 +00:00
|
|
|
migrateTablePrimaryColumnsComputedValue,
|
2021-08-18 10:33:26 +00:00
|
|
|
migrateTableWidgetDelimiterProperties,
|
2021-02-25 11:51:54 +00:00
|
|
|
} from "utils/migrations/TableWidget";
|
2021-03-04 05:24:47 +00:00
|
|
|
import { migrateIncorrectDynamicBindingPathLists } from "utils/migrations/IncorrectDynamicBindingPathLists";
|
2021-03-09 14:35:42 +00:00
|
|
|
import * as Sentry from "@sentry/react";
|
2021-04-01 08:30:33 +00:00
|
|
|
import { migrateTextStyleFromTextWidget } from "./migrations/TextWidgetReplaceTextStyle";
|
2021-03-16 05:01:37 +00:00
|
|
|
import { nextAvailableRowInContainer } from "entities/Widget/utils";
|
2021-04-27 07:16:54 +00:00
|
|
|
import { DATA_BIND_REGEX_GLOBAL } from "constants/BindingsConstants";
|
2021-08-17 12:54:43 +00:00
|
|
|
import { ColumnProperties } from "components/designSystems/appsmith/TableComponent/Constants";
|
2021-05-28 16:55:10 +00:00
|
|
|
import WidgetConfigResponse, {
|
|
|
|
|
GRID_DENSITY_MIGRATION_V1,
|
|
|
|
|
} from "mockResponses/WidgetConfigResponse";
|
|
|
|
|
import CanvasWidgetsNormalizer from "normalizers/CanvasWidgetsNormalizer";
|
2021-06-17 13:26:54 +00:00
|
|
|
import { theme } from "../../src/constants/DefaultTheme";
|
2021-08-24 05:37:16 +00:00
|
|
|
import { migrateMenuButtonWidgetButtonProperties } from "./migrations/MenuButtonWidget";
|
2019-11-13 07:00:25 +00:00
|
|
|
|
|
|
|
|
export type WidgetOperationParams = {
|
|
|
|
|
operation: WidgetOperation;
|
|
|
|
|
widgetId: string;
|
|
|
|
|
payload: any;
|
|
|
|
|
};
|
2019-09-22 20:25:05 +00:00
|
|
|
|
2020-03-27 09:02:11 +00:00
|
|
|
const { DEFAULT_GRID_ROW_HEIGHT } = GridDefaults;
|
2019-09-25 21:21:04 +00:00
|
|
|
type Rect = {
|
|
|
|
|
top: number;
|
|
|
|
|
left: number;
|
|
|
|
|
right: number;
|
|
|
|
|
bottom: number;
|
|
|
|
|
};
|
2019-09-18 10:48:56 +00:00
|
|
|
|
2020-03-27 09:02:11 +00:00
|
|
|
const defaultDSL = defaultTemplate;
|
2020-01-16 11:46:21 +00:00
|
|
|
|
2020-03-27 09:02:11 +00:00
|
|
|
const updateContainers = (dsl: ContainerWidgetProps<WidgetProps>) => {
|
|
|
|
|
if (
|
|
|
|
|
dsl.type === WidgetTypes.CONTAINER_WIDGET ||
|
|
|
|
|
dsl.type === WidgetTypes.FORM_WIDGET
|
|
|
|
|
) {
|
|
|
|
|
if (
|
|
|
|
|
!(
|
|
|
|
|
dsl.children &&
|
|
|
|
|
dsl.children.length > 0 &&
|
|
|
|
|
(dsl.children[0].type === WidgetTypes.CANVAS_WIDGET ||
|
|
|
|
|
dsl.children[0].type === WidgetTypes.FORM_WIDGET)
|
|
|
|
|
)
|
|
|
|
|
) {
|
|
|
|
|
const canvas = {
|
|
|
|
|
...dsl,
|
2020-04-29 10:09:27 +00:00
|
|
|
backgroundColor: "transparent",
|
2020-03-27 09:02:11 +00:00
|
|
|
type: WidgetTypes.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,
|
|
|
|
|
};
|
2020-11-12 11:23:32 +00:00
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
|
|
// @ts-ignore
|
2020-03-27 09:02:11 +00:00
|
|
|
delete canvas.dynamicBindings;
|
2020-11-12 11:23:32 +00:00
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
|
|
// @ts-ignore
|
2020-03-27 09:02:11 +00:00
|
|
|
delete canvas.dynamicProperties;
|
|
|
|
|
if (canvas.children && canvas.children.length > 0)
|
|
|
|
|
canvas.children = canvas.children.map(updateContainers);
|
|
|
|
|
dsl.children = [{ ...canvas }];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return dsl;
|
|
|
|
|
};
|
2020-01-16 11:46:21 +00:00
|
|
|
|
2020-04-15 15:26:36 +00:00
|
|
|
//transform chart data, from old chart widget to new chart widget
|
|
|
|
|
//updatd chart widget has support for multiple series
|
|
|
|
|
const chartDataMigration = (currentDSL: ContainerWidgetProps<WidgetProps>) => {
|
|
|
|
|
currentDSL.children = currentDSL.children?.map((children: WidgetProps) => {
|
|
|
|
|
if (
|
|
|
|
|
children.type === WidgetTypes.CHART_WIDGET &&
|
|
|
|
|
children.chartData &&
|
|
|
|
|
children.chartData.length &&
|
|
|
|
|
!Array.isArray(children.chartData[0])
|
|
|
|
|
) {
|
|
|
|
|
children.chartData = [{ data: children.chartData as ChartDataPoint[] }];
|
|
|
|
|
} else if (
|
|
|
|
|
children.type === WidgetTypes.CONTAINER_WIDGET ||
|
|
|
|
|
children.type === WidgetTypes.FORM_WIDGET ||
|
|
|
|
|
children.type === WidgetTypes.CANVAS_WIDGET ||
|
|
|
|
|
children.type === WidgetTypes.TABS_WIDGET
|
|
|
|
|
) {
|
|
|
|
|
children = chartDataMigration(children);
|
|
|
|
|
}
|
|
|
|
|
return children;
|
|
|
|
|
});
|
|
|
|
|
return currentDSL;
|
|
|
|
|
};
|
|
|
|
|
|
2020-06-18 09:01:12 +00:00
|
|
|
const singleChartDataMigration = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
2020-12-24 04:32:25 +00:00
|
|
|
currentDSL.children = currentDSL.children?.map((child) => {
|
2020-06-18 09:01:12 +00:00
|
|
|
if (child.type === WidgetTypes.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;
|
|
|
|
|
};
|
|
|
|
|
|
2020-05-07 10:51:37 +00:00
|
|
|
const mapDataMigration = (currentDSL: ContainerWidgetProps<WidgetProps>) => {
|
|
|
|
|
currentDSL.children = currentDSL.children?.map((children: WidgetProps) => {
|
|
|
|
|
if (children.type === WidgetTypes.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;
|
|
|
|
|
};
|
|
|
|
|
|
2020-09-16 10:28:01 +00:00
|
|
|
const tabsWidgetTabsPropertyMigration = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
currentDSL.children = currentDSL.children
|
|
|
|
|
?.filter(Boolean)
|
|
|
|
|
.map((child: WidgetProps) => {
|
|
|
|
|
if (child.type === WidgetTypes.TABS_WIDGET) {
|
2020-09-18 05:22:54 +00:00
|
|
|
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: WidgetProps) => tabChild.tabId === tab.id);
|
|
|
|
|
if (childForTab) {
|
|
|
|
|
tab.widgetId = childForTab.widgetId;
|
|
|
|
|
}
|
|
|
|
|
return tab;
|
|
|
|
|
});
|
|
|
|
|
child.tabs = JSON.stringify(newTabs);
|
|
|
|
|
} catch (migrationError) {
|
|
|
|
|
log.debug({ migrationError });
|
|
|
|
|
}
|
2020-09-16 10:28:01 +00:00
|
|
|
}
|
|
|
|
|
if (child.children && child.children.length) {
|
|
|
|
|
child = tabsWidgetTabsPropertyMigration(child);
|
|
|
|
|
}
|
|
|
|
|
return child;
|
|
|
|
|
});
|
|
|
|
|
return currentDSL;
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-12 11:23:32 +00:00
|
|
|
const dynamicPathListMigration = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
if (currentDSL.children && currentDSL.children.length) {
|
|
|
|
|
currentDSL.children = currentDSL.children.map(dynamicPathListMigration);
|
|
|
|
|
}
|
|
|
|
|
if (currentDSL.dynamicBindings) {
|
|
|
|
|
currentDSL.dynamicBindingPathList = Object.keys(
|
|
|
|
|
currentDSL.dynamicBindings,
|
2020-12-24 04:32:25 +00:00
|
|
|
).map((path) => ({ key: path }));
|
2020-11-12 11:23:32 +00:00
|
|
|
delete currentDSL.dynamicBindings;
|
|
|
|
|
}
|
|
|
|
|
if (currentDSL.dynamicTriggers) {
|
|
|
|
|
currentDSL.dynamicTriggerPathList = Object.keys(
|
|
|
|
|
currentDSL.dynamicTriggers,
|
2020-12-24 04:32:25 +00:00
|
|
|
).map((path) => ({ key: path }));
|
2020-11-12 11:23:32 +00:00
|
|
|
delete currentDSL.dynamicTriggers;
|
|
|
|
|
}
|
|
|
|
|
if (currentDSL.dynamicProperties) {
|
|
|
|
|
currentDSL.dynamicPropertyPathList = Object.keys(
|
|
|
|
|
currentDSL.dynamicProperties,
|
2020-12-24 04:32:25 +00:00
|
|
|
).map((path) => ({ key: path }));
|
2020-11-12 11:23:32 +00:00
|
|
|
delete currentDSL.dynamicProperties;
|
|
|
|
|
}
|
|
|
|
|
return currentDSL;
|
|
|
|
|
};
|
|
|
|
|
|
2021-02-23 12:35:09 +00:00
|
|
|
const addVersionNumberMigration = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
if (currentDSL.children && currentDSL.children.length) {
|
|
|
|
|
currentDSL.children = currentDSL.children.map(addVersionNumberMigration);
|
|
|
|
|
}
|
|
|
|
|
if (currentDSL.version === undefined) {
|
|
|
|
|
currentDSL.version = 1;
|
|
|
|
|
}
|
|
|
|
|
return currentDSL;
|
|
|
|
|
};
|
|
|
|
|
|
2021-01-13 10:10:28 +00:00
|
|
|
const canvasNameConflictMigration = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
props = { counter: 1 },
|
|
|
|
|
): ContainerWidgetProps<WidgetProps> => {
|
|
|
|
|
if (
|
|
|
|
|
currentDSL.type === WidgetTypes.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;
|
|
|
|
|
};
|
|
|
|
|
|
2021-02-01 14:33:13 +00:00
|
|
|
const renamedCanvasNameConflictMigration = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
props = { counter: 1 },
|
|
|
|
|
): ContainerWidgetProps<WidgetProps> => {
|
|
|
|
|
// Rename all canvas widgets except for MainContainer
|
|
|
|
|
if (
|
|
|
|
|
currentDSL.type === WidgetTypes.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;
|
|
|
|
|
};
|
|
|
|
|
|
2021-02-15 11:49:33 +00:00
|
|
|
const rteDefaultValueMigration = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
): ContainerWidgetProps<WidgetProps> => {
|
|
|
|
|
if (currentDSL.type === WidgetTypes.RICH_TEXT_EDITOR_WIDGET) {
|
2021-02-18 10:12:45 +00:00
|
|
|
currentDSL.inputType = "html";
|
2021-02-15 11:49:33 +00:00
|
|
|
}
|
|
|
|
|
currentDSL.children?.forEach((children) =>
|
|
|
|
|
rteDefaultValueMigration(children),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return currentDSL;
|
|
|
|
|
};
|
|
|
|
|
|
2021-04-27 07:16:54 +00:00
|
|
|
function migrateTabsDataUsingMigrator(
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) {
|
|
|
|
|
if (currentDSL.type === WidgetTypes.TABS_WIDGET && currentDSL.version === 1) {
|
|
|
|
|
try {
|
|
|
|
|
currentDSL.type = WidgetTypes.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 function migrateTabsData(currentDSL: ContainerWidgetProps<WidgetProps>) {
|
|
|
|
|
if (
|
|
|
|
|
[WidgetTypes.TABS_WIDGET, WidgetTypes.TABS_MIGRATOR_WIDGET].includes(
|
|
|
|
|
currentDSL.type as any,
|
|
|
|
|
) &&
|
|
|
|
|
currentDSL.version === 1
|
|
|
|
|
) {
|
|
|
|
|
try {
|
|
|
|
|
currentDSL.type = WidgetTypes.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;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 09:02:11 +00:00
|
|
|
// A rudimentary transform function which updates the DSL based on its version.
|
2021-03-09 14:35:42 +00:00
|
|
|
function migrateOldChartData(currentDSL: ContainerWidgetProps<WidgetProps>) {
|
|
|
|
|
if (currentDSL.type === WidgetTypes.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;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-26 10:35:59 +00:00
|
|
|
/**
|
|
|
|
|
* changes chartData which we were using as array. now it will be a object
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @param currentDSL
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
export function migrateChartDataFromArrayToObject(
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) {
|
|
|
|
|
currentDSL.children = currentDSL.children?.map((children: WidgetProps) => {
|
|
|
|
|
if (children.type === WidgetTypes.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 === WidgetTypes.CONTAINER_WIDGET ||
|
|
|
|
|
children.type === WidgetTypes.FORM_WIDGET ||
|
|
|
|
|
children.type === WidgetTypes.CANVAS_WIDGET ||
|
|
|
|
|
children.type === WidgetTypes.TABS_WIDGET
|
|
|
|
|
) {
|
|
|
|
|
children = migrateChartDataFromArrayToObject(children);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return children;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return currentDSL;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-17 13:26:54 +00:00
|
|
|
const pixelToNumber = (pixel: string) => {
|
|
|
|
|
if (pixel.includes("px")) {
|
|
|
|
|
return parseInt(pixel.split("px").join(""));
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
};
|
|
|
|
|
|
2021-03-16 05:01:37 +00:00
|
|
|
export const calculateDynamicHeight = (
|
|
|
|
|
canvasWidgets: {
|
|
|
|
|
[widgetId: string]: FlattenedWidgetProps;
|
|
|
|
|
} = {},
|
|
|
|
|
presentMinimumHeight = CANVAS_DEFAULT_HEIGHT_PX,
|
|
|
|
|
) => {
|
2021-06-17 13:26:54 +00:00
|
|
|
let minimumHeight = presentMinimumHeight;
|
2021-03-16 05:01:37 +00:00
|
|
|
const nextAvailableRow = nextAvailableRowInContainer(
|
|
|
|
|
MAIN_CONTAINER_WIDGET_ID,
|
|
|
|
|
canvasWidgets,
|
|
|
|
|
);
|
|
|
|
|
const screenHeight = window.innerHeight;
|
|
|
|
|
const gridRowHeight = GridDefaults.DEFAULT_GRID_ROW_HEIGHT;
|
|
|
|
|
const calculatedCanvasHeight = nextAvailableRow * gridRowHeight;
|
|
|
|
|
// DGRH - DEFAULT_GRID_ROW_HEIGHT
|
2021-06-17 13:26:54 +00:00
|
|
|
// 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);
|
2021-03-16 05:01:37 +00:00
|
|
|
const calculatedMinHeight =
|
|
|
|
|
Math.floor((screenHeight - buffer) / gridRowHeight) * gridRowHeight;
|
|
|
|
|
if (
|
|
|
|
|
calculatedCanvasHeight < screenHeight &&
|
|
|
|
|
calculatedMinHeight !== presentMinimumHeight
|
|
|
|
|
) {
|
2021-06-17 13:26:54 +00:00
|
|
|
minimumHeight = calculatedMinHeight;
|
2021-03-16 05:01:37 +00:00
|
|
|
}
|
2021-06-17 13:26:54 +00:00
|
|
|
return minimumHeight;
|
2021-03-16 05:01:37 +00:00
|
|
|
};
|
|
|
|
|
|
2021-05-18 13:54:40 +00:00
|
|
|
export const migrateInitialValues = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
currentDSL.children = currentDSL.children?.map((child: WidgetProps) => {
|
|
|
|
|
if (child.type === WidgetTypes.INPUT_WIDGET) {
|
|
|
|
|
child = {
|
|
|
|
|
isRequired: false,
|
|
|
|
|
isDisabled: false,
|
|
|
|
|
resetOnSubmit: false,
|
|
|
|
|
...child,
|
|
|
|
|
};
|
|
|
|
|
} else if (child.type === WidgetTypes.DROP_DOWN_WIDGET) {
|
|
|
|
|
child = {
|
|
|
|
|
isRequired: false,
|
|
|
|
|
isDisabled: false,
|
|
|
|
|
...child,
|
|
|
|
|
};
|
|
|
|
|
} else if (child.type === WidgetTypes.DATE_PICKER_WIDGET2) {
|
|
|
|
|
child = {
|
|
|
|
|
minDate: "2001-01-01 00:00",
|
|
|
|
|
maxDate: "2041-12-31 23:59",
|
|
|
|
|
isRequired: false,
|
|
|
|
|
...child,
|
|
|
|
|
};
|
|
|
|
|
} else if (child.type === WidgetTypes.SWITCH_WIDGET) {
|
|
|
|
|
child = {
|
|
|
|
|
isDisabled: false,
|
|
|
|
|
...child,
|
|
|
|
|
};
|
|
|
|
|
} else if (child.type === WidgetTypes.ICON_WIDGET) {
|
|
|
|
|
child = {
|
|
|
|
|
isRequired: false,
|
|
|
|
|
...child,
|
|
|
|
|
};
|
|
|
|
|
} else if (child.type === WidgetTypes.VIDEO_WIDGET) {
|
|
|
|
|
child = {
|
|
|
|
|
isRequired: false,
|
|
|
|
|
isDisabled: false,
|
|
|
|
|
...child,
|
|
|
|
|
};
|
|
|
|
|
} else if (child.type === WidgetTypes.CHECKBOX_WIDGET) {
|
|
|
|
|
child = {
|
|
|
|
|
isDisabled: false,
|
|
|
|
|
isRequired: false,
|
|
|
|
|
...child,
|
|
|
|
|
};
|
|
|
|
|
} else if (child.type === WidgetTypes.RADIO_GROUP_WIDGET) {
|
|
|
|
|
child = {
|
|
|
|
|
isDisabled: false,
|
|
|
|
|
isRequired: false,
|
|
|
|
|
...child,
|
|
|
|
|
};
|
|
|
|
|
} else if (child.type === WidgetTypes.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;
|
|
|
|
|
};
|
|
|
|
|
|
2021-03-16 05:01:37 +00:00
|
|
|
// A rudimentary transform function which updates the DSL based on its version.
|
2020-03-27 09:02:11 +00:00
|
|
|
// A more modular approach needs to be designed.
|
|
|
|
|
const transformDSL = (currentDSL: ContainerWidgetProps<WidgetProps>) => {
|
|
|
|
|
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
|
2021-03-16 05:01:37 +00:00
|
|
|
currentDSL.minHeight = calculateDynamicHeight();
|
|
|
|
|
|
2020-03-27 09:02:11 +00:00
|
|
|
// For the first time the DSL is created, remove one row from the total possible rows
|
|
|
|
|
// to adjust for padding and margins.
|
|
|
|
|
currentDSL.snapRows =
|
|
|
|
|
Math.floor(currentDSL.bottomRow / DEFAULT_GRID_ROW_HEIGHT) - 1;
|
2020-01-16 11:46:21 +00:00
|
|
|
|
2020-03-27 09:02:11 +00:00
|
|
|
// Force the width of the canvas to 1224 px
|
|
|
|
|
currentDSL.rightColumn = 1224;
|
|
|
|
|
// The canvas is a CANVAS_WIDGET whichdoesn't have a background or borders by default
|
|
|
|
|
currentDSL.backgroundColor = "none";
|
|
|
|
|
currentDSL.containerStyle = "none";
|
|
|
|
|
currentDSL.type = WidgetTypes.CANVAS_WIDGET;
|
|
|
|
|
currentDSL.detachFromLayout = true;
|
|
|
|
|
currentDSL.canExtend = true;
|
2020-02-13 09:32:24 +00:00
|
|
|
|
2020-03-27 09:02:11 +00:00
|
|
|
// Update version to make sure this doesn't run everytime.
|
|
|
|
|
currentDSL.version = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (currentDSL.version === 1) {
|
|
|
|
|
if (currentDSL.children && currentDSL.children.length > 0)
|
|
|
|
|
currentDSL.children = currentDSL.children.map(updateContainers);
|
|
|
|
|
currentDSL.version = 2;
|
|
|
|
|
}
|
2020-04-15 15:26:36 +00:00
|
|
|
if (currentDSL.version === 2) {
|
|
|
|
|
currentDSL = chartDataMigration(currentDSL);
|
|
|
|
|
currentDSL.version = 3;
|
|
|
|
|
}
|
2020-05-07 10:51:37 +00:00
|
|
|
if (currentDSL.version === 3) {
|
|
|
|
|
currentDSL = mapDataMigration(currentDSL);
|
|
|
|
|
currentDSL.version = 4;
|
|
|
|
|
}
|
2020-06-18 09:01:12 +00:00
|
|
|
if (currentDSL.version === 4) {
|
|
|
|
|
currentDSL = singleChartDataMigration(currentDSL);
|
|
|
|
|
currentDSL.version = 5;
|
|
|
|
|
}
|
2020-09-16 10:28:01 +00:00
|
|
|
if (currentDSL.version === 5) {
|
|
|
|
|
currentDSL = tabsWidgetTabsPropertyMigration(currentDSL);
|
2020-09-18 05:22:54 +00:00
|
|
|
currentDSL.version = 6;
|
2020-09-16 10:28:01 +00:00
|
|
|
}
|
2020-11-12 11:23:32 +00:00
|
|
|
if (currentDSL.version === 6) {
|
|
|
|
|
currentDSL = dynamicPathListMigration(currentDSL);
|
|
|
|
|
currentDSL.version = 7;
|
|
|
|
|
}
|
2020-06-18 09:01:12 +00:00
|
|
|
|
2021-01-13 10:10:28 +00:00
|
|
|
if (currentDSL.version === 7) {
|
|
|
|
|
currentDSL = canvasNameConflictMigration(currentDSL);
|
|
|
|
|
currentDSL.version = 8;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-01 14:33:13 +00:00
|
|
|
if (currentDSL.version === 8) {
|
|
|
|
|
currentDSL = renamedCanvasNameConflictMigration(currentDSL);
|
|
|
|
|
currentDSL.version = 9;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-15 11:49:33 +00:00
|
|
|
if (currentDSL.version === 9) {
|
2021-02-16 10:29:08 +00:00
|
|
|
currentDSL = tableWidgetPropertyPaneMigrations(currentDSL);
|
2021-02-15 11:49:33 +00:00
|
|
|
currentDSL.version = 10;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-18 10:12:45 +00:00
|
|
|
if (currentDSL.version === 10) {
|
2021-02-23 12:35:09 +00:00
|
|
|
currentDSL = addVersionNumberMigration(currentDSL);
|
2021-02-18 10:12:45 +00:00
|
|
|
currentDSL.version = 11;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-23 12:41:14 +00:00
|
|
|
if (currentDSL.version === 11) {
|
2021-02-25 11:51:54 +00:00
|
|
|
currentDSL = migrateTablePrimaryColumnsBindings(currentDSL);
|
2021-02-23 12:41:14 +00:00
|
|
|
currentDSL.version = 12;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-26 11:05:12 +00:00
|
|
|
if (currentDSL.version === 12) {
|
2021-03-04 05:24:47 +00:00
|
|
|
currentDSL = migrateIncorrectDynamicBindingPathLists(currentDSL);
|
2021-02-26 11:05:12 +00:00
|
|
|
currentDSL.version = 13;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-09 14:35:42 +00:00
|
|
|
if (currentDSL.version === 13) {
|
|
|
|
|
currentDSL = migrateOldChartData(currentDSL);
|
|
|
|
|
currentDSL.version = 14;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-12 09:54:51 +00:00
|
|
|
if (currentDSL.version === 14) {
|
|
|
|
|
currentDSL = rteDefaultValueMigration(currentDSL);
|
|
|
|
|
currentDSL.version = 15;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-01 08:30:33 +00:00
|
|
|
if (currentDSL.version === 15) {
|
|
|
|
|
currentDSL = migrateTextStyleFromTextWidget(currentDSL);
|
|
|
|
|
currentDSL.version = 16;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-26 10:35:59 +00:00
|
|
|
if (currentDSL.version === 16) {
|
|
|
|
|
currentDSL = migrateChartDataFromArrayToObject(currentDSL);
|
|
|
|
|
currentDSL.version = 17;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-27 07:16:54 +00:00
|
|
|
if (currentDSL.version === 17) {
|
|
|
|
|
currentDSL = migrateTabsData(currentDSL);
|
|
|
|
|
currentDSL.version = 18;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-18 13:54:40 +00:00
|
|
|
if (currentDSL.version === 18) {
|
|
|
|
|
currentDSL = migrateInitialValues(currentDSL);
|
|
|
|
|
currentDSL.version = 19;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-18 18:29:39 +00:00
|
|
|
if (currentDSL.version === 19) {
|
|
|
|
|
currentDSL.snapColumns = GridDefaults.DEFAULT_GRID_COLUMNS;
|
|
|
|
|
currentDSL.snapRows = getCanvasSnapRows(
|
|
|
|
|
currentDSL.bottomRow,
|
|
|
|
|
currentDSL.detachFromLayout || false,
|
|
|
|
|
);
|
|
|
|
|
currentDSL = migrateToNewLayout(currentDSL);
|
2021-05-28 02:58:02 +00:00
|
|
|
currentDSL.version = 20;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (currentDSL.version === 20) {
|
|
|
|
|
currentDSL = migrateNewlyAddedTabsWidgetsMissingData(currentDSL);
|
2021-05-28 16:55:10 +00:00
|
|
|
currentDSL.version = 21;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (currentDSL.version === 21) {
|
|
|
|
|
const {
|
|
|
|
|
entities: { canvasWidgets },
|
|
|
|
|
} = CanvasWidgetsNormalizer.normalize(currentDSL);
|
|
|
|
|
currentDSL = migrateWidgetsWithoutLeftRightColumns(
|
|
|
|
|
currentDSL,
|
|
|
|
|
canvasWidgets,
|
|
|
|
|
);
|
|
|
|
|
currentDSL = migrateOverFlowingTabsWidgets(currentDSL, canvasWidgets);
|
2021-05-31 11:39:06 +00:00
|
|
|
currentDSL.version = 22;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (currentDSL.version === 22) {
|
|
|
|
|
currentDSL = migrateTableWidgetParentRowSpaceProperty(currentDSL);
|
2021-06-09 10:16:48 +00:00
|
|
|
currentDSL.version = 23;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (currentDSL.version === 23) {
|
2021-06-16 11:51:00 +00:00
|
|
|
currentDSL = addLogBlackListToAllListWidgetChildren(currentDSL);
|
|
|
|
|
currentDSL.version = 24;
|
2021-05-18 18:29:39 +00:00
|
|
|
}
|
|
|
|
|
|
2021-06-16 11:51:00 +00:00
|
|
|
if (currentDSL.version === 24) {
|
|
|
|
|
currentDSL = migrateTableWidgetHeaderVisibilityProperties(currentDSL);
|
2021-06-18 07:42:57 +00:00
|
|
|
currentDSL.version = 25;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (currentDSL.version === 25) {
|
|
|
|
|
currentDSL = migrateItemsToListDataInListWidget(currentDSL);
|
2021-07-08 10:23:12 +00:00
|
|
|
currentDSL.version = 26;
|
|
|
|
|
}
|
2021-07-16 07:04:11 +00:00
|
|
|
|
2021-07-08 10:23:12 +00:00
|
|
|
if (currentDSL.version === 26) {
|
2021-07-16 07:04:11 +00:00
|
|
|
currentDSL = migrateDatePickerMinMaxDate(currentDSL);
|
2021-08-03 06:38:01 +00:00
|
|
|
currentDSL.version = 27;
|
2021-07-16 07:04:11 +00:00
|
|
|
}
|
2021-08-03 06:38:01 +00:00
|
|
|
|
2021-07-16 07:04:11 +00:00
|
|
|
if (currentDSL.version === 27) {
|
2021-07-08 10:23:12 +00:00
|
|
|
currentDSL = migrateFilterValueForDropDownWidget(currentDSL);
|
2021-08-03 06:38:01 +00:00
|
|
|
currentDSL.version = 28;
|
2021-07-22 08:43:58 +00:00
|
|
|
}
|
2021-08-03 06:38:01 +00:00
|
|
|
|
|
|
|
|
if (currentDSL.version === 28) {
|
2021-07-22 08:43:58 +00:00
|
|
|
currentDSL = migrateTablePrimaryColumnsComputedValue(currentDSL);
|
2021-08-03 06:38:01 +00:00
|
|
|
currentDSL.version = 29;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (currentDSL.version === 29) {
|
|
|
|
|
currentDSL = migrateToNewMultiSelect(currentDSL);
|
2021-08-17 12:54:43 +00:00
|
|
|
currentDSL.version = 30;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (currentDSL.version === 30) {
|
2021-08-18 10:33:26 +00:00
|
|
|
currentDSL = migrateTableWidgetDelimiterProperties(currentDSL);
|
|
|
|
|
currentDSL.version = 31;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (currentDSL.version === 31) {
|
2021-08-17 12:54:43 +00:00
|
|
|
currentDSL = migrateIsDisabledToButtonColumn(currentDSL);
|
2021-08-31 08:59:26 +00:00
|
|
|
currentDSL.version = 32;
|
2021-08-30 06:58:45 +00:00
|
|
|
}
|
|
|
|
|
|
2021-08-31 08:59:26 +00:00
|
|
|
if (currentDSL.version === 32) {
|
2021-09-09 13:43:36 +00:00
|
|
|
currentDSL = migrateTableVersion(currentDSL);
|
2021-08-31 08:59:26 +00:00
|
|
|
currentDSL.version = 33;
|
2021-06-04 07:09:36 +00:00
|
|
|
}
|
2021-08-24 05:37:16 +00:00
|
|
|
|
2021-08-31 08:59:26 +00:00
|
|
|
if (currentDSL.version === 33) {
|
2021-08-24 05:37:16 +00:00
|
|
|
currentDSL = migrateMenuButtonWidgetButtonProperties(currentDSL);
|
2021-09-06 09:46:22 +00:00
|
|
|
currentDSL.version = 34;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (currentDSL.version === 34) {
|
|
|
|
|
currentDSL = migrateButtonWidgetValidation(currentDSL);
|
|
|
|
|
currentDSL.version = 35;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (currentDSL.version === 35) {
|
|
|
|
|
currentDSL = migrateInputValidation(currentDSL);
|
2021-09-09 13:43:36 +00:00
|
|
|
currentDSL.version = 36;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (currentDSL.version === 36) {
|
|
|
|
|
currentDSL = revertTableDefaultSelectedRow(currentDSL);
|
2021-08-24 05:37:16 +00:00
|
|
|
currentDSL.version = LATEST_PAGE_VERSION;
|
|
|
|
|
}
|
2021-08-31 08:59:26 +00:00
|
|
|
|
2021-08-17 12:54:43 +00:00
|
|
|
return currentDSL;
|
|
|
|
|
};
|
2021-06-04 07:09:36 +00:00
|
|
|
|
2021-09-09 13:43:36 +00:00
|
|
|
export const revertTableDefaultSelectedRow = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
if (currentDSL.type === WidgetTypes.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 migrateTableVersion = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
// this is done to stop reverse migrations for apps that did not use migrateTableDefaultSelectedRow to migrate
|
|
|
|
|
if (currentDSL.type === WidgetTypes.TABLE_WIDGET) {
|
|
|
|
|
currentDSL.version = 2;
|
|
|
|
|
}
|
|
|
|
|
if (currentDSL.children && currentDSL.children.length) {
|
|
|
|
|
currentDSL.children = currentDSL.children.map((child) =>
|
|
|
|
|
migrateTableVersion(child),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return currentDSL;
|
|
|
|
|
};
|
|
|
|
|
|
2021-08-17 12:54:43 +00:00
|
|
|
const addIsDisabledToButtonColumn = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-27 09:02:11 +00:00
|
|
|
return currentDSL;
|
|
|
|
|
};
|
2019-09-26 11:11:28 +00:00
|
|
|
|
2021-09-06 09:46:22 +00:00
|
|
|
export const migrateInputValidation = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
if (currentDSL.type === WidgetTypes.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;
|
|
|
|
|
};
|
|
|
|
|
|
2021-08-17 12:54:43 +00:00
|
|
|
const migrateIsDisabledToButtonColumn = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
const newDSL = addIsDisabledToButtonColumn(currentDSL);
|
|
|
|
|
|
|
|
|
|
newDSL.children = newDSL.children?.map((children: WidgetProps) => {
|
|
|
|
|
return migrateIsDisabledToButtonColumn(children);
|
|
|
|
|
});
|
|
|
|
|
return currentDSL;
|
|
|
|
|
};
|
2021-08-03 06:38:01 +00:00
|
|
|
export const migrateToNewMultiSelect = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
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;
|
|
|
|
|
};
|
2021-09-06 09:46:22 +00:00
|
|
|
|
|
|
|
|
const migrateButtonWidgetValidation = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
if (currentDSL.type === WidgetTypes.INPUT_WIDGET) {
|
|
|
|
|
if (!has(currentDSL, "validation")) {
|
|
|
|
|
currentDSL.validation = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (currentDSL.children && currentDSL.children.length) {
|
|
|
|
|
currentDSL.children.map(
|
|
|
|
|
(eachWidgetDSL: ContainerWidgetProps<WidgetProps>) => {
|
|
|
|
|
migrateButtonWidgetValidation(eachWidgetDSL);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return currentDSL;
|
|
|
|
|
};
|
|
|
|
|
|
2021-07-16 07:04:11 +00:00
|
|
|
const migrateDatePickerMinMaxDate = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
if (
|
|
|
|
|
currentDSL.type === WidgetTypes.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: ContainerWidgetProps<WidgetProps>) => {
|
|
|
|
|
migrateDatePickerMinMaxDate(eachWidgetDSL);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return currentDSL;
|
|
|
|
|
};
|
|
|
|
|
|
2021-07-08 10:23:12 +00:00
|
|
|
const addFilterDefaultValue = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
if (currentDSL.type === WidgetTypes.DROP_DOWN_WIDGET) {
|
|
|
|
|
if (!currentDSL.hasOwnProperty("isFilterable")) {
|
|
|
|
|
currentDSL.isFilterable = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return currentDSL;
|
|
|
|
|
};
|
|
|
|
|
export const migrateFilterValueForDropDownWidget = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
const newDSL = addFilterDefaultValue(currentDSL);
|
|
|
|
|
|
|
|
|
|
newDSL.children = newDSL.children?.map((children: WidgetProps) => {
|
|
|
|
|
return migrateFilterValueForDropDownWidget(children);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return newDSL;
|
|
|
|
|
};
|
2021-06-29 13:30:14 +00:00
|
|
|
export const migrateObjectFitToImageWidget = (
|
|
|
|
|
dsl: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
const addObjectFitProperty = (widgetProps: WidgetProps) => {
|
|
|
|
|
widgetProps.objectFit = "cover";
|
|
|
|
|
if (widgetProps.children && widgetProps.children.length) {
|
|
|
|
|
widgetProps.children.forEach((eachWidgetProp: WidgetProps) => {
|
|
|
|
|
if (widgetProps.type === "IMAGE_WIDGET") {
|
|
|
|
|
addObjectFitProperty(eachWidgetProp);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
addObjectFitProperty(dsl);
|
|
|
|
|
return dsl;
|
|
|
|
|
};
|
|
|
|
|
|
2021-05-28 16:55:10 +00:00
|
|
|
const migrateOverFlowingTabsWidgets = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
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: WidgetProps) => {
|
|
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const migrateWidgetsWithoutLeftRightColumns = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
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;
|
|
|
|
|
const rightColumn = WidgetConfigResponse.config[currentDSL.type].rows;
|
|
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
|
2021-05-28 02:58:02 +00:00
|
|
|
const migrateNewlyAddedTabsWidgetsMissingData = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
if (currentDSL.type === WidgetTypes.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;
|
|
|
|
|
};
|
|
|
|
|
|
2021-05-18 18:29:39 +00:00
|
|
|
export const migrateToNewLayout = (dsl: ContainerWidgetProps<WidgetProps>) => {
|
|
|
|
|
const scaleWidget = (widgetProps: WidgetProps) => {
|
|
|
|
|
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: WidgetProps) => {
|
|
|
|
|
scaleWidget(eachWidgetProp);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
scaleWidget(dsl);
|
|
|
|
|
return dsl;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const checkIfMigrationIsNeeded = (
|
|
|
|
|
fetchPageResponse?: FetchPageResponse,
|
|
|
|
|
) => {
|
|
|
|
|
const currentDSL = fetchPageResponse?.data.layouts[0].dsl || defaultDSL;
|
|
|
|
|
return currentDSL.version !== LATEST_PAGE_VERSION;
|
|
|
|
|
};
|
|
|
|
|
|
2019-09-18 10:48:56 +00:00
|
|
|
export const extractCurrentDSL = (
|
2021-03-16 05:01:37 +00:00
|
|
|
fetchPageResponse?: FetchPageResponse,
|
2019-09-18 10:48:56 +00:00
|
|
|
): ContainerWidgetProps<WidgetProps> => {
|
2021-03-16 05:01:37 +00:00
|
|
|
const currentDSL = fetchPageResponse?.data.layouts[0].dsl || defaultDSL;
|
2020-03-27 09:02:11 +00:00
|
|
|
return transformDSL(currentDSL);
|
2019-09-18 10:48:56 +00:00
|
|
|
};
|
|
|
|
|
|
2019-09-25 21:21:04 +00:00
|
|
|
export const getDropZoneOffsets = (
|
|
|
|
|
colWidth: number,
|
|
|
|
|
rowHeight: number,
|
2021-08-24 11:38:20 +00:00
|
|
|
dragOffset: XYCord,
|
|
|
|
|
parentOffset: XYCord,
|
2019-09-25 21:21:04 +00:00
|
|
|
) => {
|
|
|
|
|
// Calculate actual drop position by snapping based on x, y and grid cell size
|
|
|
|
|
return snapToGrid(
|
|
|
|
|
colWidth,
|
|
|
|
|
rowHeight,
|
2020-03-06 10:41:46 +00:00
|
|
|
dragOffset.x - parentOffset.x,
|
|
|
|
|
dragOffset.y - parentOffset.y,
|
2019-09-25 21:21:04 +00:00
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2021-06-17 13:26:54 +00:00
|
|
|
export const areIntersecting = (r1: Rect, r2: Rect) => {
|
2019-09-25 21:21:04 +00:00
|
|
|
return !(
|
2019-10-03 15:14:50 +00:00
|
|
|
r2.left >= r1.right ||
|
|
|
|
|
r2.right <= r1.left ||
|
|
|
|
|
r2.top >= r1.bottom ||
|
|
|
|
|
r2.bottom <= r1.top
|
2019-09-25 21:21:04 +00:00
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const isDropZoneOccupied = (
|
|
|
|
|
offset: Rect,
|
2019-10-08 06:19:10 +00:00
|
|
|
widgetId: string,
|
2019-11-13 07:00:25 +00:00
|
|
|
occupied?: OccupiedSpace[],
|
2019-09-25 21:21:04 +00:00
|
|
|
) => {
|
|
|
|
|
if (occupied) {
|
2020-12-24 04:32:25 +00:00
|
|
|
occupied = occupied.filter((widgetDetails) => {
|
2019-10-02 21:14:58 +00:00
|
|
|
return (
|
2019-10-08 06:19:10 +00:00
|
|
|
widgetDetails.id !== widgetId && widgetDetails.parentId !== widgetId
|
2019-10-02 21:14:58 +00:00
|
|
|
);
|
2019-09-25 21:21:04 +00:00
|
|
|
});
|
|
|
|
|
for (let i = 0; i < occupied.length; i++) {
|
|
|
|
|
if (areIntersecting(occupied[i], offset)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
|
2019-10-08 06:19:10 +00:00
|
|
|
export const isWidgetOverflowingParentBounds = (
|
|
|
|
|
parentRowCols: { rows?: number; cols?: number },
|
|
|
|
|
offset: Rect,
|
2020-01-16 11:46:21 +00:00
|
|
|
): boolean => {
|
2020-03-06 09:45:21 +00:00
|
|
|
return (
|
2020-01-16 11:46:21 +00:00
|
|
|
offset.right < 0 ||
|
|
|
|
|
offset.top < 0 ||
|
2019-10-08 06:19:10 +00:00
|
|
|
(parentRowCols.cols || GridDefaults.DEFAULT_GRID_COLUMNS) < offset.right ||
|
2020-03-06 09:45:21 +00:00
|
|
|
(parentRowCols.rows || 0) < offset.bottom
|
|
|
|
|
);
|
2019-10-08 06:19:10 +00:00
|
|
|
};
|
|
|
|
|
|
2019-09-25 21:21:04 +00:00
|
|
|
export const noCollision = (
|
2021-08-24 11:38:20 +00:00
|
|
|
clientOffset: XYCord,
|
2019-09-25 21:21:04 +00:00
|
|
|
colWidth: number,
|
|
|
|
|
rowHeight: number,
|
2021-08-24 11:38:20 +00:00
|
|
|
dropTargetOffset: XYCord,
|
2021-08-12 05:45:38 +00:00
|
|
|
widgetWidth: number,
|
|
|
|
|
widgetHeight: number,
|
|
|
|
|
widgetId: string,
|
2019-11-13 07:00:25 +00:00
|
|
|
occupiedSpaces?: OccupiedSpace[],
|
2019-10-08 06:19:10 +00:00
|
|
|
rows?: number,
|
|
|
|
|
cols?: number,
|
2021-08-12 05:45:38 +00:00
|
|
|
detachFromLayout = false,
|
2019-09-25 21:21:04 +00:00
|
|
|
): boolean => {
|
2021-08-12 05:45:38 +00:00
|
|
|
if (detachFromLayout) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (clientOffset && dropTargetOffset) {
|
2019-09-25 21:21:04 +00:00
|
|
|
const [left, top] = getDropZoneOffsets(
|
|
|
|
|
colWidth,
|
|
|
|
|
rowHeight,
|
2021-08-24 11:38:20 +00:00
|
|
|
clientOffset as XYCord,
|
2019-09-25 21:21:04 +00:00
|
|
|
dropTargetOffset,
|
|
|
|
|
);
|
2020-01-16 11:46:21 +00:00
|
|
|
if (left < 0 || top < 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2019-09-25 21:21:04 +00:00
|
|
|
const currentOffset = {
|
|
|
|
|
left,
|
|
|
|
|
right: left + widgetWidth,
|
|
|
|
|
top,
|
|
|
|
|
bottom: top + widgetHeight,
|
|
|
|
|
};
|
2019-10-08 06:19:10 +00:00
|
|
|
return (
|
2021-08-12 05:45:38 +00:00
|
|
|
!isDropZoneOccupied(currentOffset, widgetId, occupiedSpaces) &&
|
2019-10-08 06:19:10 +00:00
|
|
|
!isWidgetOverflowingParentBounds({ rows, cols }, currentOffset)
|
|
|
|
|
);
|
2019-09-25 21:21:04 +00:00
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
|
2020-01-16 11:46:21 +00:00
|
|
|
export const currentDropRow = (
|
|
|
|
|
dropTargetRowSpace: number,
|
|
|
|
|
dropTargetVerticalOffset: number,
|
|
|
|
|
draggableItemVerticalOffset: number,
|
|
|
|
|
widget: WidgetProps & Partial<WidgetConfigProps>,
|
|
|
|
|
) => {
|
|
|
|
|
const widgetHeight = widget.rows
|
|
|
|
|
? widget.rows
|
|
|
|
|
: widget.bottomRow - widget.topRow;
|
|
|
|
|
const top = Math.round(
|
|
|
|
|
(draggableItemVerticalOffset - dropTargetVerticalOffset) /
|
|
|
|
|
dropTargetRowSpace,
|
|
|
|
|
);
|
|
|
|
|
const currentBottomOffset = top + widgetHeight;
|
|
|
|
|
return currentBottomOffset;
|
|
|
|
|
};
|
|
|
|
|
|
2019-09-25 17:24:23 +00:00
|
|
|
export const widgetOperationParams = (
|
|
|
|
|
widget: WidgetProps & Partial<WidgetConfigProps>,
|
2021-08-24 11:38:20 +00:00
|
|
|
widgetOffset: XYCord,
|
|
|
|
|
parentOffset: XYCord,
|
2019-09-25 17:24:23 +00:00
|
|
|
parentColumnSpace: number,
|
|
|
|
|
parentRowSpace: number,
|
2019-11-13 07:00:25 +00:00
|
|
|
parentWidgetId: string, // parentWidget
|
|
|
|
|
): WidgetOperationParams => {
|
|
|
|
|
const [leftColumn, topRow] = getDropZoneOffsets(
|
|
|
|
|
parentColumnSpace,
|
|
|
|
|
parentRowSpace,
|
|
|
|
|
widgetOffset,
|
|
|
|
|
parentOffset,
|
|
|
|
|
);
|
|
|
|
|
// If this is an existing widget, we'll have the widgetId
|
|
|
|
|
// Therefore, this is a move operation on drop of the widget
|
2020-03-27 09:02:11 +00:00
|
|
|
if (widget.widgetName) {
|
2019-11-13 07:00:25 +00:00
|
|
|
return {
|
|
|
|
|
operation: WidgetOperations.MOVE,
|
|
|
|
|
widgetId: widget.widgetId,
|
|
|
|
|
payload: {
|
|
|
|
|
leftColumn,
|
|
|
|
|
topRow,
|
|
|
|
|
parentId: widget.parentId,
|
|
|
|
|
newParentId: parentWidgetId,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
// If this is not an existing widget, we'll not have the widgetId
|
|
|
|
|
// Therefore, this is an operation to add child to this container
|
2019-09-25 17:24:23 +00:00
|
|
|
}
|
2019-11-13 07:00:25 +00:00
|
|
|
const widgetDimensions = {
|
|
|
|
|
columns: widget.columns,
|
|
|
|
|
rows: widget.rows,
|
|
|
|
|
};
|
2021-04-23 05:43:13 +00:00
|
|
|
|
2019-11-13 07:00:25 +00:00
|
|
|
return {
|
|
|
|
|
operation: WidgetOperations.ADD_CHILD,
|
|
|
|
|
widgetId: parentWidgetId,
|
|
|
|
|
payload: {
|
|
|
|
|
type: widget.type,
|
|
|
|
|
leftColumn,
|
|
|
|
|
topRow,
|
|
|
|
|
...widgetDimensions,
|
|
|
|
|
parentRowSpace,
|
|
|
|
|
parentColumnSpace,
|
2020-03-27 09:02:11 +00:00
|
|
|
newWidgetId: widget.widgetId,
|
2019-11-13 07:00:25 +00:00
|
|
|
},
|
|
|
|
|
};
|
2019-09-25 17:24:23 +00:00
|
|
|
};
|
|
|
|
|
|
2019-09-22 20:25:05 +00:00
|
|
|
export const updateWidgetPosition = (
|
|
|
|
|
widget: WidgetProps,
|
2019-09-25 17:24:23 +00:00
|
|
|
leftColumn: number,
|
|
|
|
|
topRow: number,
|
2019-09-22 20:25:05 +00:00
|
|
|
) => {
|
|
|
|
|
const newPositions = {
|
2019-09-25 17:24:23 +00:00
|
|
|
leftColumn,
|
|
|
|
|
topRow,
|
|
|
|
|
rightColumn: leftColumn + (widget.rightColumn - widget.leftColumn),
|
|
|
|
|
bottomRow: topRow + (widget.bottomRow - widget.topRow),
|
2019-09-22 20:25:05 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return {
|
2020-01-16 11:46:21 +00:00
|
|
|
...newPositions,
|
2019-09-22 20:25:05 +00:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2020-03-27 09:02:11 +00:00
|
|
|
export const getCanvasSnapRows = (
|
|
|
|
|
bottomRow: number,
|
|
|
|
|
canExtend: boolean,
|
|
|
|
|
): number => {
|
|
|
|
|
const totalRows = Math.floor(
|
|
|
|
|
bottomRow / GridDefaults.DEFAULT_GRID_ROW_HEIGHT,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Canvas Widgets do not need to accomodate for widget and container padding.
|
|
|
|
|
// Only when they're extensible
|
|
|
|
|
if (canExtend) {
|
|
|
|
|
return totalRows;
|
|
|
|
|
}
|
|
|
|
|
// When Canvas widgets are not extensible
|
|
|
|
|
return totalRows - 1;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getSnapColumns = (): number => {
|
|
|
|
|
return GridDefaults.DEFAULT_GRID_COLUMNS;
|
|
|
|
|
};
|
|
|
|
|
|
2019-09-19 22:25:37 +00:00
|
|
|
export const generateWidgetProps = (
|
2020-09-16 10:28:01 +00:00
|
|
|
parent: FlattenedWidgetProps,
|
2019-09-19 22:25:37 +00:00
|
|
|
type: WidgetType,
|
2019-09-25 17:24:23 +00:00
|
|
|
leftColumn: number,
|
|
|
|
|
topRow: number,
|
|
|
|
|
parentRowSpace: number,
|
|
|
|
|
parentColumnSpace: number,
|
2019-10-02 18:13:04 +00:00
|
|
|
widgetName: string,
|
2021-02-01 14:33:13 +00:00
|
|
|
widgetConfig: {
|
|
|
|
|
widgetId: string;
|
|
|
|
|
renderMode: RenderMode;
|
|
|
|
|
} & Partial<WidgetProps>,
|
2021-02-23 12:35:09 +00:00
|
|
|
version: number,
|
2020-03-27 09:02:11 +00:00
|
|
|
): ContainerWidgetProps<WidgetProps> => {
|
|
|
|
|
if (parent) {
|
2019-09-22 20:25:05 +00:00
|
|
|
const sizes = {
|
2019-09-25 17:24:23 +00:00
|
|
|
leftColumn,
|
2020-03-27 09:02:11 +00:00
|
|
|
rightColumn: leftColumn + widgetConfig.columns,
|
2019-09-25 17:24:23 +00:00
|
|
|
topRow,
|
2020-03-27 09:02:11 +00:00
|
|
|
bottomRow: topRow + widgetConfig.rows,
|
2019-09-22 20:25:05 +00:00
|
|
|
};
|
2020-03-27 09:02:11 +00:00
|
|
|
|
|
|
|
|
const others = {};
|
2020-04-17 16:15:09 +00:00
|
|
|
const props: ContainerWidgetProps<WidgetProps> = {
|
Feature/entity browse (#220)
# New Feature: Entity Explorer
- Entities are actions (apis and queries), datasources, pages, and widgets
- With this new feature, all entities in the application will be available
to view in the new entity explorer sidebar
- All existing application features from the api sidebar, query sidebar, datasource sidebar and pages sidebar
now are avialable on the entity explorer sidebar
- Users are now able to quickly switch to any entity in the application from the entity explorer sidebar.
- Users can also search all entities in the application from the new sidebar. Use cmd + f or ctrl + f to focus on the search input
- Users can rename entities from the new sidebar
- Users can also perform contextual actions on these entities like set a page as home page, copy/move actions, delete entity, etc from the context menu available alongside the entities in the sidebar
- Users can view the properties of the entities in the sidebar, as well as copy bindings to use in the application.
2020-08-10 08:52:45 +00:00
|
|
|
isVisible: WidgetTypes.MODAL_WIDGET === type ? undefined : true,
|
2019-10-02 18:13:04 +00:00
|
|
|
...widgetConfig,
|
2019-09-22 20:25:05 +00:00
|
|
|
type,
|
2020-01-17 09:28:26 +00:00
|
|
|
widgetName,
|
2019-11-20 08:10:01 +00:00
|
|
|
isLoading: false,
|
2019-09-25 17:24:23 +00:00
|
|
|
parentColumnSpace,
|
|
|
|
|
parentRowSpace,
|
2019-09-22 20:25:05 +00:00
|
|
|
...sizes,
|
|
|
|
|
...others,
|
2020-04-14 05:35:16 +00:00
|
|
|
parentId: parent.widgetId,
|
2021-02-23 12:35:09 +00:00
|
|
|
version,
|
2019-09-19 22:25:37 +00:00
|
|
|
};
|
2020-03-27 09:02:11 +00:00
|
|
|
delete props.rows;
|
|
|
|
|
delete props.columns;
|
|
|
|
|
return props;
|
2019-09-19 22:25:37 +00:00
|
|
|
} else {
|
2020-01-16 11:46:21 +00:00
|
|
|
if (parent) {
|
2019-09-19 22:25:37 +00:00
|
|
|
throw Error("Failed to create widget: Parent's size cannot be calculate");
|
2020-01-16 11:46:21 +00:00
|
|
|
} else throw Error("Failed to create widget: Parent was not provided ");
|
2019-09-19 22:25:37 +00:00
|
|
|
}
|
|
|
|
|
};
|
2021-06-04 07:09:36 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* adds logBlackList key for all list widget children
|
|
|
|
|
*
|
|
|
|
|
* @param currentDSL
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
const addLogBlackListToAllListWidgetChildren = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
currentDSL.children = currentDSL.children?.map((children: WidgetProps) => {
|
|
|
|
|
if (children.type === WidgetTypes.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;
|
|
|
|
|
};
|
2021-06-18 07:42:57 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* changes items -> listData
|
|
|
|
|
*
|
|
|
|
|
* @param currentDSL
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
const migrateItemsToListDataInListWidget = (
|
|
|
|
|
currentDSL: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => {
|
|
|
|
|
if (currentDSL.type === WidgetTypes.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;
|
|
|
|
|
};
|