PromucFlow_constructor/app/client/src/sagas/WidgetBlueprintSagas.ts

95 lines
2.9 KiB
TypeScript

import { WidgetBlueprint } from "reducers/entityReducers/widgetConfigReducer";
import { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReducer";
import { WidgetProps } from "widgets/BaseWidget";
import { generateReactKey } from "utils/generators";
import { call } from "redux-saga/effects";
function buildView(view: WidgetBlueprint["view"], widgetId: string) {
const children = [];
for (const template of view) {
//TODO(abhinav): Can we keep rows and size mandatory?
try {
children.push({
widgetId,
type: template.type,
leftColumn: template.position.left || 0,
topRow: template.position.top || 0,
columns: template.size && template.size.cols,
rows: template.size && template.size.rows,
newWidgetId: generateReactKey(),
props: template.props,
});
} catch (e) {
console.error(e);
}
}
return children;
}
export function* buildWidgetBlueprint(
blueprint: WidgetBlueprint,
widgetId: string,
) {
const widgetProps = yield call(buildView, blueprint.view, widgetId);
return widgetProps;
}
export type UpdatePropertyArgs = {
widgetId: string;
propertyName: string;
propertyValue: any;
};
export type BlueprintOperationAddActionFn = () => void;
export type BlueprintOperationModifyPropsFn = (
widget: WidgetProps & { children?: WidgetProps[] },
parent?: WidgetProps,
) => UpdatePropertyArgs[] | undefined;
export type BlueprintOperationFunction =
| BlueprintOperationModifyPropsFn
| BlueprintOperationAddActionFn;
export enum BlueprintOperationTypes {
MODIFY_PROPS = "MODIFY_PROPS",
ADD_ACTION = "ADD_ACTION",
}
export type BlueprintOperationType = keyof typeof BlueprintOperationTypes;
export type BlueprintOperation = {
type: BlueprintOperationType;
fn: BlueprintOperationFunction;
};
export function* executeWidgetBlueprintOperations(
operations: BlueprintOperation[],
widgets: { [widgetId: string]: FlattenedWidgetProps },
widgetId: string,
) {
operations.forEach((operation: BlueprintOperation) => {
switch (operation.type) {
case BlueprintOperationTypes.MODIFY_PROPS:
const widget: WidgetProps & { children?: string[] | WidgetProps[] } = {
...widgets[widgetId],
};
if (widget.children && widget.children.length > 0) {
widget.children = (widget.children as string[]).map(
(childId: string) => widgets[childId],
) as WidgetProps[];
}
const updatePropertyPayloads:
| UpdatePropertyArgs[]
| undefined = (operation.fn as BlueprintOperationModifyPropsFn)(
widget as WidgetProps & { children?: WidgetProps[] },
widgets[widget.parentId],
);
updatePropertyPayloads &&
updatePropertyPayloads.forEach((params: UpdatePropertyArgs) => {
widgets[params.widgetId][params.propertyName] =
params.propertyValue;
});
}
});
return yield widgets;
}