2019-10-21 15:12:45 +00:00
|
|
|
import {
|
|
|
|
|
ReduxAction,
|
|
|
|
|
ReduxActionErrorTypes,
|
|
|
|
|
ReduxActionTypes,
|
|
|
|
|
} from "../constants/ReduxActionConstants";
|
|
|
|
|
import { Intent } from "@blueprintjs/core";
|
2019-10-25 05:35:20 +00:00
|
|
|
import {
|
|
|
|
|
all,
|
|
|
|
|
call,
|
|
|
|
|
select,
|
|
|
|
|
put,
|
|
|
|
|
takeEvery,
|
|
|
|
|
takeLatest,
|
|
|
|
|
} from "redux-saga/effects";
|
2019-10-21 15:12:45 +00:00
|
|
|
import { initialize } from "redux-form";
|
|
|
|
|
import { ActionPayload, PageAction } from "../constants/ActionConstants";
|
|
|
|
|
import ActionAPI, {
|
2019-10-29 12:02:58 +00:00
|
|
|
ActionApiResponse,
|
2019-10-21 15:12:45 +00:00
|
|
|
ActionCreateUpdateResponse,
|
|
|
|
|
ExecuteActionRequest,
|
|
|
|
|
RestAction,
|
|
|
|
|
} from "../api/ActionAPI";
|
|
|
|
|
import { AppState } from "../reducers";
|
|
|
|
|
import { JSONPath } from "jsonpath-plus";
|
|
|
|
|
import _ from "lodash";
|
|
|
|
|
import { mapToPropList } from "../utils/AppsmithUtils";
|
2019-11-04 10:57:19 +00:00
|
|
|
import AppToaster from "../components/editorComponents/ToastComponent";
|
2019-10-21 15:12:45 +00:00
|
|
|
import { GenericApiResponse } from "../api/ApiResponses";
|
2019-10-22 14:54:23 +00:00
|
|
|
import { API_EDITOR_FORM_NAME } from "../constants/forms";
|
2019-10-25 05:35:20 +00:00
|
|
|
import {
|
|
|
|
|
createActionSuccess,
|
|
|
|
|
deleteActionSuccess,
|
|
|
|
|
updateActionSuccess,
|
|
|
|
|
} from "../actions/actionActions";
|
|
|
|
|
import { API_EDITOR_ID_URL, API_EDITOR_URL } from "../constants/routes";
|
|
|
|
|
import history from "../utils/history";
|
2019-10-21 15:12:45 +00:00
|
|
|
|
|
|
|
|
const getDataTree = (state: AppState) => {
|
|
|
|
|
return state.entities;
|
|
|
|
|
};
|
|
|
|
|
|
2019-11-01 07:11:32 +00:00
|
|
|
const getAction = (
|
|
|
|
|
state: AppState,
|
|
|
|
|
actionId: string,
|
|
|
|
|
): RestAction | undefined => {
|
|
|
|
|
return _.find(state.entities.actions.data, { id: actionId });
|
2019-10-21 15:12:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function* evaluateJSONPathSaga(jsonPath: string): any {
|
|
|
|
|
const dataTree = yield select(getDataTree);
|
2019-11-01 07:11:32 +00:00
|
|
|
const splitPath = jsonPath.split(".");
|
|
|
|
|
const bindingPath = dataTree.nameBindings[splitPath[0]];
|
|
|
|
|
const fullPath = `${bindingPath}.${splitPath.slice(1).join(".")}`;
|
|
|
|
|
return JSONPath({ path: fullPath, json: dataTree });
|
2019-10-21 15:12:45 +00:00
|
|
|
}
|
|
|
|
|
|
2019-11-01 07:11:32 +00:00
|
|
|
export function* executeAPIQueryActionSaga(apiAction: { actionId: string }) {
|
2019-10-21 15:12:45 +00:00
|
|
|
const api: PageAction = yield select(getAction, apiAction.actionId);
|
|
|
|
|
|
|
|
|
|
const executeActionRequest: ExecuteActionRequest = {
|
|
|
|
|
actionId: apiAction.actionId,
|
|
|
|
|
};
|
|
|
|
|
if (!_.isNil(api.jsonPathKeys)) {
|
2019-11-01 07:11:32 +00:00
|
|
|
const values: any = _.flatten(
|
|
|
|
|
yield all(
|
|
|
|
|
api.jsonPathKeys.map((jsonPath: string) => {
|
|
|
|
|
return call(evaluateJSONPathSaga, jsonPath);
|
|
|
|
|
}),
|
|
|
|
|
),
|
2019-10-21 15:12:45 +00:00
|
|
|
);
|
2019-11-01 07:11:32 +00:00
|
|
|
const dynamicBindings: Record<string, string> = {};
|
|
|
|
|
api.jsonPathKeys.forEach((key, i) => {
|
|
|
|
|
dynamicBindings[key] = values[i];
|
|
|
|
|
});
|
|
|
|
|
executeActionRequest.params = mapToPropList(dynamicBindings);
|
2019-10-21 15:12:45 +00:00
|
|
|
}
|
2019-11-01 07:11:32 +00:00
|
|
|
return yield ActionAPI.executeAction(executeActionRequest);
|
2019-10-21 15:12:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function* executeActionSaga(action: ReduxAction<ActionPayload[]>) {
|
|
|
|
|
if (!_.isNil(action.payload)) {
|
|
|
|
|
yield all(
|
|
|
|
|
_.map(action.payload, (actionPayload: ActionPayload) => {
|
|
|
|
|
switch (actionPayload.actionType) {
|
|
|
|
|
case "API":
|
|
|
|
|
return call(executeAPIQueryActionSaga, actionPayload);
|
|
|
|
|
case "QUERY":
|
|
|
|
|
return call(executeAPIQueryActionSaga, actionPayload);
|
|
|
|
|
}
|
|
|
|
|
return undefined;
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function* createActionSaga(actionPayload: ReduxAction<RestAction>) {
|
|
|
|
|
const response: ActionCreateUpdateResponse = yield ActionAPI.createAPI(
|
|
|
|
|
actionPayload.payload,
|
|
|
|
|
);
|
|
|
|
|
if (response.responseMeta.success) {
|
|
|
|
|
AppToaster.show({
|
|
|
|
|
message: `${actionPayload.payload.name} Action created`,
|
|
|
|
|
intent: Intent.SUCCESS,
|
|
|
|
|
});
|
2019-10-25 05:35:20 +00:00
|
|
|
yield put(createActionSuccess(response.data));
|
|
|
|
|
history.push(API_EDITOR_ID_URL(response.data.id));
|
2019-10-21 15:12:45 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function* fetchActionsSaga() {
|
|
|
|
|
const response: GenericApiResponse<
|
|
|
|
|
RestAction[]
|
|
|
|
|
> = yield ActionAPI.fetchActions();
|
|
|
|
|
if (response.responseMeta.success) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.FETCH_ACTIONS_SUCCESS,
|
|
|
|
|
payload: response.data,
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.FETCH_ACTIONS_ERROR,
|
|
|
|
|
payload: response.responseMeta.status,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function* fetchActionSaga(actionPayload: ReduxAction<{ id: string }>) {
|
|
|
|
|
const response: GenericApiResponse<RestAction> = yield ActionAPI.fetchAPI(
|
|
|
|
|
actionPayload.payload.id,
|
|
|
|
|
);
|
|
|
|
|
const data = response.data;
|
2019-10-22 14:54:23 +00:00
|
|
|
yield put(initialize(API_EDITOR_FORM_NAME, data));
|
2019-10-21 15:12:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function* runActionSaga(actionPayload: ReduxAction<{ id: string }>) {
|
|
|
|
|
const id = actionPayload.payload.id;
|
2019-11-01 07:11:32 +00:00
|
|
|
const response: ActionApiResponse = yield call(executeAPIQueryActionSaga, {
|
2019-10-29 12:02:58 +00:00
|
|
|
actionId: id,
|
|
|
|
|
});
|
|
|
|
|
let payload = response;
|
|
|
|
|
if (response.responseMeta && response.responseMeta.error) {
|
|
|
|
|
payload = {
|
|
|
|
|
body: response.responseMeta.error,
|
|
|
|
|
statusCode: response.responseMeta.error.code,
|
|
|
|
|
...response,
|
|
|
|
|
};
|
|
|
|
|
}
|
2019-10-21 15:12:45 +00:00
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.RUN_ACTION_SUCCESS,
|
2019-10-29 12:02:58 +00:00
|
|
|
payload: { [id]: payload },
|
2019-10-21 15:12:45 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function* updateActionSaga(
|
|
|
|
|
actionPayload: ReduxAction<{ data: RestAction }>,
|
|
|
|
|
) {
|
|
|
|
|
const finalFields: Partial<RestAction> = _.omit(
|
|
|
|
|
actionPayload.payload.data,
|
|
|
|
|
"new",
|
|
|
|
|
);
|
|
|
|
|
const response: GenericApiResponse<RestAction> = yield ActionAPI.updateAPI(
|
|
|
|
|
finalFields,
|
|
|
|
|
);
|
|
|
|
|
if (response.responseMeta.success) {
|
|
|
|
|
AppToaster.show({
|
|
|
|
|
message: `${actionPayload.payload.data.name} Action updated`,
|
|
|
|
|
intent: Intent.SUCCESS,
|
|
|
|
|
});
|
2019-10-25 05:35:20 +00:00
|
|
|
yield put(updateActionSuccess({ data: response.data }));
|
2019-10-21 15:12:45 +00:00
|
|
|
} else {
|
|
|
|
|
AppToaster.show({
|
|
|
|
|
message: "Error occurred when updating action",
|
|
|
|
|
intent: Intent.DANGER,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function* deleteActionSaga(actionPayload: ReduxAction<{ id: string }>) {
|
|
|
|
|
const id = actionPayload.payload.id;
|
|
|
|
|
const response: GenericApiResponse<RestAction> = yield ActionAPI.deleteAction(
|
|
|
|
|
id,
|
|
|
|
|
);
|
|
|
|
|
if (response.responseMeta.success) {
|
|
|
|
|
AppToaster.show({
|
|
|
|
|
message: `${response.data.name} Action deleted`,
|
|
|
|
|
intent: Intent.SUCCESS,
|
|
|
|
|
});
|
2019-10-25 05:35:20 +00:00
|
|
|
yield put(deleteActionSuccess({ id }));
|
|
|
|
|
history.push(API_EDITOR_URL);
|
2019-10-21 15:12:45 +00:00
|
|
|
} else {
|
|
|
|
|
AppToaster.show({
|
|
|
|
|
message: "Error occurred when deleting action",
|
|
|
|
|
intent: Intent.DANGER,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function* watchActionSagas() {
|
|
|
|
|
yield all([
|
|
|
|
|
takeEvery(ReduxActionTypes.FETCH_ACTIONS_INIT, fetchActionsSaga),
|
2019-10-25 05:35:20 +00:00
|
|
|
takeLatest(ReduxActionTypes.EXECUTE_ACTION, executeActionSaga),
|
|
|
|
|
takeLatest(ReduxActionTypes.CREATE_ACTION_INIT, createActionSaga),
|
2019-10-21 15:12:45 +00:00
|
|
|
takeEvery(ReduxActionTypes.FETCH_ACTION, fetchActionSaga),
|
2019-10-25 05:35:20 +00:00
|
|
|
takeLatest(ReduxActionTypes.RUN_ACTION_INIT, runActionSaga),
|
|
|
|
|
takeLatest(ReduxActionTypes.UPDATE_ACTION_INIT, updateActionSaga),
|
|
|
|
|
takeLatest(ReduxActionTypes.DELETE_ACTION_INIT, deleteActionSaga),
|
2019-10-21 15:12:45 +00:00
|
|
|
]);
|
|
|
|
|
}
|