* update meta properties + default properties map * update widget registery * update get meta property * update metahoc + widgetfactory + data tree evaluator * try sending function as string to worker * revert data tree evaluator update * pass default props map from dataTreeWidget file * wip * save child meta properties * remove console.log * save meta and default map in list * update listwidget * remove console.log + unused variables * revert getMetaPropertiesMap function * fix data tree test * fix list widget test * fix entity definition test * fix overriting of item in updatedItems * remove todo comments * fix meta prop issue * revert making meta properties from undefiend to "" & fix filepicker bug * fix test case * change items to listData and updatedItems to items * remove console.log * fix test * extract derived properties to dervied.js * disabled top, left, right resize handler list widget container * add test for dervied js * add test for selectedItem * fix background color bug on hover * remove console.log * fix chart widget inside list widget * fix checkbox issue + points raised by yogesh * revert the createImmerReducer usage * fix parse derived properties * remove internal props object that fails the test * fix import typo * allow bottom resize handler * fix template height check * fix template height check * update template size check * fix the is visible invalid prop issue * fix migration of list widget phase 2 * fix migration * remove unused import * fix migration * fix migration * remove console.log * hide delete option for container in entity explorer * fix testcases * remove unused import * fix switch widget meta prop Co-authored-by: root <root@DESKTOP-9GENCK0.localdomain> Co-authored-by: Pawan Kumar <pawankumar@Pawans-MacBook-Pro.local>
227 lines
6.5 KiB
TypeScript
227 lines
6.5 KiB
TypeScript
import {
|
|
MAIN_CONTAINER_WIDGET_ID,
|
|
WidgetTypes,
|
|
} from "constants/WidgetConstants";
|
|
import { cloneDeep, get, isString, filter, set } from "lodash";
|
|
import { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReducer";
|
|
import { call, select } from "redux-saga/effects";
|
|
import { getDynamicBindings } from "utils/DynamicBindingUtils";
|
|
import { getWidget } from "./selectors";
|
|
|
|
/**
|
|
* checks if triggerpaths contains property path passed
|
|
*
|
|
* @param isTriggerProperty
|
|
* @param propertyPath
|
|
* @param triggerPaths
|
|
* @returns
|
|
*/
|
|
export const doesTriggerPathsContainPropertyPath = (
|
|
isTriggerProperty: boolean,
|
|
propertyPath: string,
|
|
triggerPaths?: string[],
|
|
) => {
|
|
if (!isTriggerProperty) {
|
|
if (
|
|
triggerPaths &&
|
|
triggerPaths.length &&
|
|
triggerPaths.includes(propertyPath)
|
|
) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return isTriggerProperty;
|
|
};
|
|
|
|
/**
|
|
*
|
|
* check if copied widget is being pasted in list widget,
|
|
* if yes, change all keys in template of list widget and
|
|
* update dynamicBindingPathList of ListWidget
|
|
*
|
|
* updates in list widget :
|
|
* 1. `dynamicBindingPathList`
|
|
* 2. `template`
|
|
*
|
|
* @param widget
|
|
* @param widgets
|
|
*/
|
|
export const handleIfParentIsListWidgetWhilePasting = (
|
|
widget: FlattenedWidgetProps,
|
|
widgets: { [widgetId: string]: FlattenedWidgetProps },
|
|
): { [widgetId: string]: FlattenedWidgetProps } => {
|
|
let root = get(widgets, `${widget.parentId}`);
|
|
|
|
while (root && root.parentId && root.widgetId !== MAIN_CONTAINER_WIDGET_ID) {
|
|
if (root.type === WidgetTypes.LIST_WIDGET) {
|
|
const listWidget = root;
|
|
const currentWidget = cloneDeep(widget);
|
|
let template = get(listWidget, "template", {});
|
|
const dynamicBindingPathList: any[] = get(
|
|
listWidget,
|
|
"dynamicBindingPathList",
|
|
[],
|
|
).slice();
|
|
|
|
// iterating over each keys of the new createdWidget checking if value contains currentItem
|
|
const keys = Object.keys(currentWidget);
|
|
|
|
for (let i = 0; i < keys.length; i++) {
|
|
const key = keys[i];
|
|
let value = currentWidget[key];
|
|
|
|
if (isString(value) && value.indexOf("currentItem") > -1) {
|
|
const { jsSnippets } = getDynamicBindings(value);
|
|
|
|
const modifiedAction = jsSnippets.reduce(
|
|
(prev: string, next: string) => {
|
|
return prev + `${next}`;
|
|
},
|
|
"",
|
|
);
|
|
|
|
value = `{{${listWidget.widgetName}.listData.map((currentItem) => ${modifiedAction})}}`;
|
|
|
|
currentWidget[key] = value;
|
|
|
|
dynamicBindingPathList.push({
|
|
key: `template.${currentWidget.widgetName}.${key}`,
|
|
});
|
|
}
|
|
}
|
|
|
|
template = {
|
|
...template,
|
|
[currentWidget.widgetName]: currentWidget,
|
|
};
|
|
|
|
// now we have updated `dynamicBindingPathList` and updatedTemplate
|
|
// we need to update it the list widget
|
|
widgets[listWidget.widgetId] = {
|
|
...listWidget,
|
|
template,
|
|
dynamicBindingPathList,
|
|
};
|
|
}
|
|
|
|
root = widgets[root.parentId];
|
|
}
|
|
|
|
return widgets;
|
|
};
|
|
|
|
/**
|
|
* this saga handles special cases when pasting the widget
|
|
*
|
|
* for e.g - when the list widget is being copied, we want to update template of list widget
|
|
* with new widgets name
|
|
*
|
|
* @param widget
|
|
* @param widgets
|
|
* @param widgetNameMap
|
|
* @param newWidgetList
|
|
* @returns
|
|
*/
|
|
export const handleSpecificCasesWhilePasting = (
|
|
widget: FlattenedWidgetProps,
|
|
widgets: { [widgetId: string]: FlattenedWidgetProps },
|
|
widgetNameMap: Record<string, string>,
|
|
newWidgetList: FlattenedWidgetProps[],
|
|
) => {
|
|
// this is the case when whole list widget is copied and pasted
|
|
if (widget.type === WidgetTypes.LIST_WIDGET) {
|
|
Object.keys(widget.template).map((widgetName) => {
|
|
const oldWidgetName = widgetName;
|
|
const newWidgetName = widgetNameMap[oldWidgetName];
|
|
|
|
const newWidget = newWidgetList.find(
|
|
(w: any) => w.widgetName === newWidgetName,
|
|
);
|
|
|
|
if (newWidget) {
|
|
newWidget.widgetName = newWidgetName;
|
|
|
|
if (widgetName === oldWidgetName) {
|
|
widget.template[newWidgetName] = {
|
|
...widget.template[oldWidgetName],
|
|
widgetId: newWidget.widgetId,
|
|
widgetName: newWidget.widgetName,
|
|
};
|
|
|
|
delete widget.template[oldWidgetName];
|
|
}
|
|
}
|
|
|
|
// updating dynamicBindingPath in copied widget if the copied widge thas reference to oldWidgetNames
|
|
widget.dynamicBindingPathList = (widget.dynamicBindingPathList || []).map(
|
|
(path: any) => {
|
|
if (path.key.startsWith(`template.${oldWidgetName}`)) {
|
|
return {
|
|
key: path.key.replace(
|
|
`template.${oldWidgetName}`,
|
|
`template.${newWidgetName}`,
|
|
),
|
|
};
|
|
}
|
|
|
|
return path;
|
|
},
|
|
);
|
|
});
|
|
|
|
widgets[widget.widgetId] = widget;
|
|
} else if (widget.type === WidgetTypes.MODAL_WIDGET) {
|
|
// if Modal is being coppied handle all onClose action rename
|
|
const oldWidgetName = Object.keys(widgetNameMap).find(
|
|
(key) => widgetNameMap[key] === widget.widgetName,
|
|
);
|
|
// get all the button, icon widgets
|
|
const copiedBtnIcnWidgets = filter(
|
|
newWidgetList,
|
|
(copyWidget) =>
|
|
copyWidget.type === "BUTTON_WIDGET" ||
|
|
copyWidget.type === "ICON_WIDGET",
|
|
);
|
|
// replace oldName with new one if any of this widget have onClick action for old modal
|
|
copiedBtnIcnWidgets.map((copyWidget) => {
|
|
if (copyWidget.onClick) {
|
|
const newOnClick = widgets[copyWidget.widgetId].onClick.replace(
|
|
oldWidgetName,
|
|
widget.widgetName,
|
|
);
|
|
set(widgets[copyWidget.widgetId], "onClick", newOnClick);
|
|
}
|
|
});
|
|
}
|
|
|
|
widgets = handleIfParentIsListWidgetWhilePasting(widget, widgets);
|
|
|
|
return widgets;
|
|
};
|
|
|
|
export function* getWidgetChildren(widgetId: string): any {
|
|
const childrenIds: string[] = [];
|
|
const widget = yield select(getWidget, widgetId);
|
|
// When a form widget tries to resetChildrenMetaProperties
|
|
// But one or more of its container like children
|
|
// have just been deleted, widget can be undefined
|
|
if (widget === undefined) {
|
|
return [];
|
|
}
|
|
const { children = [] } = widget;
|
|
if (children && children.length) {
|
|
for (const childIndex in children) {
|
|
if (children.hasOwnProperty(childIndex)) {
|
|
const child = children[childIndex];
|
|
childrenIds.push(child);
|
|
const grandChildren = yield call(getWidgetChildren, child);
|
|
if (grandChildren.length) {
|
|
childrenIds.push(...grandChildren);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return childrenIds;
|
|
}
|