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

118 lines
3.6 KiB
TypeScript
Raw Normal View History

import { Toaster } from "components/ads/Toast";
import {
ReduxAction,
ReduxActionErrorTypes,
ReduxActionTypes,
} from "constants/ReduxActionConstants";
import {
CanvasWidgetsReduxState,
FlattenedWidgetProps,
} from "reducers/entityReducers/canvasWidgetsReducer";
import { all, put, select, takeLatest } from "redux-saga/effects";
import { WidgetDraggingUpdateParams } from "utils/hooks/useBlocksToBeDraggedOnCanvas";
import { updateWidgetPosition } from "utils/WidgetPropsUtils";
import { getWidgets } from "./selectors";
import log from "loglevel";
import { cloneDeep } from "lodash";
import { updateAndSaveLayout } from "actions/pageActions";
export type WidgetMoveParams = {
widgetId: string;
leftColumn: number;
topRow: number;
parentId: string;
/*
If newParentId is different from what we have in redux store,
then we have to delete this,
as it has been dropped in another container somewhere.
*/
newParentId: string;
allWidgets: CanvasWidgetsReduxState;
};
function* moveWidgetsSaga(
actionPayload: ReduxAction<{
draggedBlocksToUpdate: WidgetDraggingUpdateParams[];
}>,
) {
const start = performance.now();
const { draggedBlocksToUpdate } = actionPayload.payload;
const allWidgets: CanvasWidgetsReduxState = yield select(getWidgets);
const widgets = cloneDeep(allWidgets);
try {
const updatedWidgets = draggedBlocksToUpdate.reduce((widgetsObj, each) => {
return moveWidget({
...each.updateWidgetParams.payload,
widgetId: each.widgetId,
allWidgets: widgetsObj,
});
}, widgets);
yield put(updateAndSaveLayout(updatedWidgets));
log.debug("move computations took", performance.now() - start, "ms");
} catch (error) {
yield put({
type: ReduxActionErrorTypes.WIDGET_OPERATION_ERROR,
payload: {
action: ReduxActionTypes.WIDGETS_MOVE,
error,
},
});
}
}
function moveWidget(widgetMoveParams: WidgetMoveParams) {
Toaster.clear();
const {
allWidgets,
leftColumn,
newParentId,
parentId,
topRow,
widgetId,
} = widgetMoveParams;
const stateWidget: FlattenedWidgetProps = allWidgets[widgetId];
let widget = Object.assign({}, stateWidget);
// Get all widgets from DSL/Redux Store
const widgets = Object.assign({}, allWidgets);
// Get parent from DSL/Redux Store
const stateParent: FlattenedWidgetProps = allWidgets[parentId];
const parent = {
...stateParent,
children: [...(stateParent.children || [])],
};
// Update position of widget
const updatedPosition = updateWidgetPosition(widget, leftColumn, topRow);
widget = { ...widget, ...updatedPosition };
// Replace widget with update widget props
widgets[widgetId] = widget;
// If the parent has changed i.e parentWidgetId is not parent.widgetId
if (parent.widgetId !== newParentId && widgetId !== newParentId) {
// Remove from the previous parent
if (parent.children && Array.isArray(parent.children)) {
const indexOfChild = parent.children.indexOf(widgetId);
if (indexOfChild > -1) delete parent.children[indexOfChild];
parent.children = parent.children.filter(Boolean);
}
// Add to new parent
widgets[parent.widgetId] = parent;
const newParent = {
...widgets[newParentId],
children: widgets[newParentId].children
? [...(widgets[newParentId].children || []), widgetId]
: [widgetId],
};
widgets[widgetId].parentId = newParentId;
widgets[newParentId] = newParent;
}
return widgets;
}
export default function* draggingCanvasSagas() {
yield all([takeLatest(ReduxActionTypes.WIDGETS_MOVE, moveWidgetsSaga)]);
}