PromucFlow_constructor/app/client/src/sagas/ModalSagas.ts
NandanAnantharamu 05f190c102
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 14:22:45 +05:30

180 lines
4.8 KiB
TypeScript

import {
all,
select,
call,
put,
takeLatest,
takeEvery,
delay,
} from "redux-saga/effects";
import { generateReactKey } from "utils/generators";
import { WidgetAddChild } from "actions/pageActions";
import {
MAIN_CONTAINER_WIDGET_ID,
WidgetTypes,
} from "constants/WidgetConstants";
import {
ReduxActionErrorTypes,
ReduxActionTypes,
ReduxAction,
} from "constants/ReduxActionConstants";
import {
getWidgets,
getWidgetByName,
getWidgetsMeta,
getWidgetIdsByType,
getWidgetMetaProps,
} from "sagas/selectors";
import { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReducer";
import { updateWidgetMetaProperty } from "actions/metaActions";
import { focusWidget } from "actions/widgetActions";
export function* createModalSaga(action: ReduxAction<{ modalName: string }>) {
try {
const modalWidgetId = generateReactKey();
const props: WidgetAddChild = {
widgetId: MAIN_CONTAINER_WIDGET_ID,
widgetName: action.payload.modalName,
type: WidgetTypes.MODAL_WIDGET,
newWidgetId: modalWidgetId,
parentRowSpace: 1,
parentColumnSpace: 1,
leftColumn: 0,
topRow: 0,
columns: 0,
rows: 0,
tabId: "",
};
yield put({
type: ReduxActionTypes.WIDGET_ADD_CHILD,
payload: props,
});
yield put({
type: ReduxActionTypes.SHOW_MODAL,
payload: { modalId: modalWidgetId },
});
} catch (error) {
console.log(error);
yield put({
type: ReduxActionErrorTypes.CREATE_MODAL_ERROR,
payload: { error },
});
}
}
export function* showModalByNameSaga(
action: ReduxAction<{ modalName: string }>,
) {
const widgets: { [widgetId: string]: FlattenedWidgetProps } = yield select(
getWidgets,
);
const modal: FlattenedWidgetProps | undefined = Object.values(widgets).find(
(widget: FlattenedWidgetProps) =>
widget.widgetName === action.payload.modalName,
);
if (modal) {
yield put({
type: ReduxActionTypes.SHOW_MODAL,
payload: {
modalId: modal.widgetId,
},
});
}
}
export function* showModalSaga(action: ReduxAction<{ modalId: string }>) {
// First we close the currently open modals (if any)
// Notice the empty payload.
yield call(closeModalSaga, {
type: ReduxActionTypes.CLOSE_MODAL,
payload: {
exclude: action.payload.modalId,
},
});
yield put({
type: ReduxActionTypes.SELECT_WIDGET,
payload: { widgetId: action.payload.modalId },
});
yield put(focusWidget(action.payload.modalId));
const metaProps = yield select(getWidgetMetaProps, action.payload.modalId);
if (!metaProps || !metaProps.isVisible) {
// Then show the modal we would like to show.
yield put(
updateWidgetMetaProperty(action.payload.modalId, "isVisible", true),
);
yield delay(1000);
}
yield put({
type: ReduxActionTypes.SHOW_PROPERTY_PANE,
payload: {
widgetId: action.payload.modalId,
callForDragOrResize: undefined,
force: true,
},
});
}
export function* closeModalSaga(
action: ReduxAction<{ modalName?: string; exclude?: string }>,
) {
try {
const { modalName } = action.payload;
let widgetIds: string[] = [];
// If modalName is provided, we just want to close this modal
if (modalName) {
const widget = yield select(getWidgetByName, modalName);
widgetIds = [widget.widgetId];
yield put({
type: ReduxActionTypes.SHOW_PROPERTY_PANE,
payload: {},
});
} else {
// If modalName is not provided, find all open modals
// Get all meta prop records
const metaProps: Record<string, any> = yield select(getWidgetsMeta);
// Get widgetIds of all widgets of type MODAL_WIDGET
const modalWidgetIds: string[] = yield select(
getWidgetIdsByType,
WidgetTypes.MODAL_WIDGET,
);
// Loop through all modal widgetIds
modalWidgetIds.forEach((widgetId: string) => {
// Check if modal is open
if (metaProps[widgetId] && metaProps[widgetId].isVisible) {
// Add to our list of widgetIds
widgetIds.push(widgetId);
}
});
}
widgetIds = action.payload.exclude
? widgetIds.filter((id: string) => id !== action.payload.exclude)
: widgetIds;
// If we have modals to close, set its isVisible to false to close.
if (widgetIds) {
yield all(
widgetIds.map((widgetId: string) =>
put(updateWidgetMetaProperty(widgetId, "isVisible", false)),
),
);
}
} catch (error) {
console.log(error);
}
}
export default function* modalSagas() {
yield all([
takeEvery(ReduxActionTypes.CLOSE_MODAL, closeModalSaga),
takeLatest(ReduxActionTypes.CREATE_MODAL_INIT, createModalSaga),
takeLatest(ReduxActionTypes.SHOW_MODAL, showModalSaga),
takeLatest(ReduxActionTypes.SHOW_MODAL_BY_NAME, showModalByNameSaga),
]);
}