2019-10-21 15:12:45 +00:00
|
|
|
import {
|
|
|
|
|
ReduxAction,
|
|
|
|
|
ReduxActionErrorTypes,
|
|
|
|
|
ReduxActionTypes,
|
2019-11-25 05:07:27 +00:00
|
|
|
} from "constants/ReduxActionConstants";
|
2019-10-25 05:35:20 +00:00
|
|
|
import {
|
|
|
|
|
all,
|
|
|
|
|
call,
|
|
|
|
|
put,
|
2020-02-18 10:41:52 +00:00
|
|
|
select,
|
2019-10-25 05:35:20 +00:00
|
|
|
takeEvery,
|
|
|
|
|
takeLatest,
|
|
|
|
|
} from "redux-saga/effects";
|
2021-01-12 04:17:28 +00:00
|
|
|
import { Datasource } from "entities/Datasource";
|
2021-03-01 14:57:15 +00:00
|
|
|
import ActionAPI, { ActionCreateUpdateResponse } from "api/ActionAPI";
|
2019-11-25 05:07:27 +00:00
|
|
|
import { GenericApiResponse } from "api/ApiResponses";
|
2020-06-16 10:23:19 +00:00
|
|
|
import PageApi from "api/PageApi";
|
|
|
|
|
import { updateCanvasWithDSL } from "sagas/PageSagas";
|
2019-10-25 05:35:20 +00:00
|
|
|
import {
|
2020-01-24 09:54:40 +00:00
|
|
|
copyActionError,
|
|
|
|
|
copyActionSuccess,
|
2019-10-25 05:35:20 +00:00
|
|
|
createActionSuccess,
|
|
|
|
|
deleteActionSuccess,
|
2020-07-03 08:58:58 +00:00
|
|
|
fetchActionsForPage,
|
2020-03-12 20:27:39 +00:00
|
|
|
fetchActionsForPageSuccess,
|
2019-12-11 15:24:27 +00:00
|
|
|
FetchActionsPayload,
|
2020-01-24 09:54:40 +00:00
|
|
|
moveActionError,
|
|
|
|
|
moveActionSuccess,
|
2020-07-03 08:58:58 +00:00
|
|
|
SetActionPropertyPayload,
|
2020-07-06 13:35:31 +00:00
|
|
|
updateAction,
|
2020-07-03 08:58:58 +00:00
|
|
|
updateActionProperty,
|
2019-10-25 05:35:20 +00:00
|
|
|
updateActionSuccess,
|
2019-11-25 05:07:27 +00:00
|
|
|
} from "actions/actionActions";
|
2019-11-20 10:57:05 +00:00
|
|
|
import {
|
2021-03-01 14:57:15 +00:00
|
|
|
DynamicPath,
|
|
|
|
|
isChildPropertyPath,
|
2019-11-20 10:57:05 +00:00
|
|
|
isDynamicValue,
|
2020-07-03 08:58:58 +00:00
|
|
|
removeBindingsFromActionObject,
|
2019-11-25 05:07:27 +00:00
|
|
|
} from "utils/DynamicBindingUtils";
|
2019-11-13 07:34:59 +00:00
|
|
|
import { validateResponse } from "./ErrorSagas";
|
2019-12-23 12:12:58 +00:00
|
|
|
import { transformRestAction } from "transformers/RestActionTransformer";
|
2020-07-06 13:35:31 +00:00
|
|
|
import {
|
|
|
|
|
getCurrentApplicationId,
|
|
|
|
|
getCurrentPageId,
|
2021-03-01 14:57:15 +00:00
|
|
|
getDataSources,
|
2020-07-06 13:35:31 +00:00
|
|
|
} from "selectors/editorSelectors";
|
2020-03-06 04:59:24 +00:00
|
|
|
import AnalyticsUtil from "utils/AnalyticsUtil";
|
2020-05-05 07:50:30 +00:00
|
|
|
import { QUERY_CONSTANT } from "constants/QueryEditorConstants";
|
2021-01-26 03:12:52 +00:00
|
|
|
import { Action, ActionViewMode } from "entities/Action";
|
2020-06-16 10:23:19 +00:00
|
|
|
import { ActionData } from "reducers/entityReducers/actionsReducer";
|
2020-07-03 08:58:58 +00:00
|
|
|
import {
|
|
|
|
|
getAction,
|
|
|
|
|
getCurrentPageNameByActionId,
|
2021-03-01 14:57:15 +00:00
|
|
|
getEditorConfig,
|
2020-07-03 08:58:58 +00:00
|
|
|
getPageNameByPageId,
|
2021-02-23 08:27:37 +00:00
|
|
|
getSettingConfig,
|
2020-07-03 08:58:58 +00:00
|
|
|
} from "selectors/entitiesSelector";
|
2020-07-06 13:35:31 +00:00
|
|
|
import { PLUGIN_TYPE_API } from "constants/ApiEditorConstants";
|
|
|
|
|
import history from "utils/history";
|
2020-08-14 07:18:30 +00:00
|
|
|
import {
|
2021-03-01 14:57:15 +00:00
|
|
|
API_EDITOR_ID_URL,
|
2020-08-14 07:18:30 +00:00
|
|
|
API_EDITOR_URL,
|
2020-08-19 05:47:54 +00:00
|
|
|
QUERIES_EDITOR_ID_URL,
|
2021-03-01 14:57:15 +00:00
|
|
|
QUERIES_EDITOR_URL,
|
2020-08-14 07:18:30 +00:00
|
|
|
} from "constants/routes";
|
2020-11-24 07:01:37 +00:00
|
|
|
import { Toaster } from "components/ads/Toast";
|
|
|
|
|
import { Variant } from "components/ads/common";
|
2020-09-28 05:12:23 +00:00
|
|
|
import PerformanceTracker, {
|
|
|
|
|
PerformanceTransactionName,
|
|
|
|
|
} from "utils/PerformanceTracker";
|
2021-02-11 11:47:21 +00:00
|
|
|
import PluginsApi from "api/PluginApi";
|
|
|
|
|
import _, { merge } from "lodash";
|
|
|
|
|
import { getConfigInitialValues } from "components/formControls/utils";
|
2019-10-21 15:12:45 +00:00
|
|
|
|
2020-12-30 07:31:20 +00:00
|
|
|
export function* createActionSaga(
|
2021-02-11 11:47:21 +00:00
|
|
|
actionPayload: ReduxAction<
|
|
|
|
|
Partial<Action> & { eventData: any; pluginId: string }
|
|
|
|
|
>,
|
2020-12-30 07:31:20 +00:00
|
|
|
) {
|
2019-11-13 07:34:59 +00:00
|
|
|
try {
|
2021-02-11 11:47:21 +00:00
|
|
|
let payload = actionPayload.payload;
|
|
|
|
|
if (actionPayload.payload.pluginId) {
|
2021-02-23 08:27:37 +00:00
|
|
|
let editorConfig;
|
|
|
|
|
editorConfig = yield select(
|
2021-02-11 11:47:21 +00:00
|
|
|
getEditorConfig,
|
|
|
|
|
actionPayload.payload.pluginId,
|
|
|
|
|
);
|
|
|
|
|
|
2021-02-23 08:27:37 +00:00
|
|
|
if (!editorConfig) {
|
2021-02-11 11:47:21 +00:00
|
|
|
const formConfigResponse: GenericApiResponse<any> = yield PluginsApi.fetchFormConfig(
|
|
|
|
|
actionPayload.payload.pluginId,
|
|
|
|
|
);
|
|
|
|
|
yield validateResponse(formConfigResponse);
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.FETCH_PLUGIN_FORM_SUCCESS,
|
|
|
|
|
payload: {
|
|
|
|
|
id: actionPayload.payload.pluginId,
|
|
|
|
|
...formConfigResponse.data,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
2021-02-23 08:27:37 +00:00
|
|
|
editorConfig = yield select(
|
2021-02-11 11:47:21 +00:00
|
|
|
getEditorConfig,
|
|
|
|
|
actionPayload.payload.pluginId,
|
|
|
|
|
);
|
|
|
|
|
}
|
2021-02-23 08:27:37 +00:00
|
|
|
const settingConfig = yield select(
|
|
|
|
|
getSettingConfig,
|
|
|
|
|
actionPayload.payload.pluginId,
|
|
|
|
|
);
|
2021-02-15 16:13:20 +00:00
|
|
|
|
2021-02-23 08:27:37 +00:00
|
|
|
let initialValues = yield call(getConfigInitialValues, editorConfig);
|
|
|
|
|
if (settingConfig) {
|
|
|
|
|
const settingInitialValues = yield call(
|
|
|
|
|
getConfigInitialValues,
|
|
|
|
|
settingConfig,
|
|
|
|
|
);
|
|
|
|
|
initialValues = merge(initialValues, settingInitialValues);
|
|
|
|
|
}
|
2021-02-11 11:47:21 +00:00
|
|
|
payload = merge(initialValues, actionPayload.payload);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-13 07:34:59 +00:00
|
|
|
const response: ActionCreateUpdateResponse = yield ActionAPI.createAPI(
|
2021-02-11 11:47:21 +00:00
|
|
|
payload,
|
2019-11-13 07:34:59 +00:00
|
|
|
);
|
|
|
|
|
const isValidResponse = yield validateResponse(response);
|
|
|
|
|
if (isValidResponse) {
|
2020-11-24 07:01:37 +00:00
|
|
|
Toaster.show({
|
|
|
|
|
text: `${actionPayload.payload.name} Action created`,
|
|
|
|
|
variant: Variant.success,
|
2019-11-13 07:34:59 +00:00
|
|
|
});
|
2020-03-06 04:59:24 +00:00
|
|
|
|
|
|
|
|
const pageName = yield select(
|
|
|
|
|
getCurrentPageNameByActionId,
|
|
|
|
|
response.data.id,
|
|
|
|
|
);
|
|
|
|
|
|
2020-10-06 15:10:21 +00:00
|
|
|
AnalyticsUtil.logEvent("CREATE_ACTION", {
|
2020-10-07 14:10:08 +00:00
|
|
|
id: response.data.id,
|
|
|
|
|
actionName: response.data.name,
|
2020-03-06 04:59:24 +00:00
|
|
|
pageName: pageName,
|
2020-10-06 15:10:21 +00:00
|
|
|
...actionPayload.payload.eventData,
|
2020-03-06 04:59:24 +00:00
|
|
|
});
|
2020-10-30 06:24:15 +00:00
|
|
|
|
2021-01-12 04:17:28 +00:00
|
|
|
const newAction = response.data;
|
2020-10-30 06:24:15 +00:00
|
|
|
|
|
|
|
|
yield put(createActionSuccess(newAction));
|
2019-11-13 07:34:59 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.CREATE_ACTION_ERROR,
|
2020-01-24 09:54:40 +00:00
|
|
|
payload: actionPayload.payload,
|
2019-10-21 15:12:45 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-11 15:24:27 +00:00
|
|
|
export function* fetchActionsSaga(action: ReduxAction<FetchActionsPayload>) {
|
2020-09-28 05:12:23 +00:00
|
|
|
const { applicationId } = action.payload;
|
|
|
|
|
PerformanceTracker.startAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_ACTIONS_API,
|
|
|
|
|
{ mode: "EDITOR", appId: applicationId },
|
|
|
|
|
);
|
2019-11-13 07:34:59 +00:00
|
|
|
try {
|
2021-01-12 04:17:28 +00:00
|
|
|
const response: GenericApiResponse<Action[]> = yield ActionAPI.fetchActions(
|
2020-01-24 09:54:40 +00:00
|
|
|
applicationId,
|
2019-12-11 15:24:27 +00:00
|
|
|
);
|
2019-11-13 07:34:59 +00:00
|
|
|
const isValidResponse = yield validateResponse(response);
|
|
|
|
|
if (isValidResponse) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.FETCH_ACTIONS_SUCCESS,
|
|
|
|
|
payload: response.data,
|
|
|
|
|
});
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_ACTIONS_API,
|
|
|
|
|
);
|
2019-11-13 07:34:59 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2019-10-21 15:12:45 +00:00
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.FETCH_ACTIONS_ERROR,
|
2019-11-13 07:34:59 +00:00
|
|
|
payload: { error },
|
2019-10-21 15:12:45 +00:00
|
|
|
});
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_ACTIONS_API,
|
|
|
|
|
{ failed: true },
|
|
|
|
|
);
|
2019-10-21 15:12:45 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-15 13:01:35 +00:00
|
|
|
export function* fetchActionsForViewModeSaga(
|
|
|
|
|
action: ReduxAction<FetchActionsPayload>,
|
|
|
|
|
) {
|
2020-09-28 05:12:23 +00:00
|
|
|
const { applicationId } = action.payload;
|
|
|
|
|
PerformanceTracker.startAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_ACTIONS_API,
|
|
|
|
|
{ mode: "VIEWER", appId: applicationId },
|
|
|
|
|
);
|
2020-07-15 13:01:35 +00:00
|
|
|
try {
|
2021-01-26 03:12:52 +00:00
|
|
|
const response: GenericApiResponse<ActionViewMode[]> = yield ActionAPI.fetchActionsForViewMode(
|
2020-07-15 13:01:35 +00:00
|
|
|
applicationId,
|
|
|
|
|
);
|
2021-01-26 03:12:52 +00:00
|
|
|
const correctFormatResponse = response.data.map((action) => {
|
|
|
|
|
return {
|
|
|
|
|
...action,
|
|
|
|
|
actionConfiguration: {
|
|
|
|
|
timeoutInMillisecond: action.timeoutInMillisecond,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
});
|
2020-07-15 13:01:35 +00:00
|
|
|
const isValidResponse = yield validateResponse(response);
|
|
|
|
|
if (isValidResponse) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.FETCH_ACTIONS_VIEW_MODE_SUCCESS,
|
2021-01-26 03:12:52 +00:00
|
|
|
payload: correctFormatResponse,
|
2020-07-15 13:01:35 +00:00
|
|
|
});
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_ACTIONS_API,
|
|
|
|
|
);
|
2020-07-15 13:01:35 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.FETCH_ACTIONS_VIEW_MODE_ERROR,
|
|
|
|
|
payload: { error },
|
|
|
|
|
});
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_ACTIONS_API,
|
|
|
|
|
{ failed: true },
|
|
|
|
|
);
|
2020-07-15 13:01:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-21 12:16:49 +00:00
|
|
|
export function* fetchActionsForPageSaga(
|
|
|
|
|
action: ReduxAction<{ pageId: string }>,
|
|
|
|
|
) {
|
2020-09-28 05:12:23 +00:00
|
|
|
const { pageId } = action.payload;
|
|
|
|
|
PerformanceTracker.startAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_PAGE_ACTIONS_API,
|
|
|
|
|
{ pageId: pageId },
|
|
|
|
|
);
|
2020-02-21 12:16:49 +00:00
|
|
|
try {
|
2021-01-12 04:17:28 +00:00
|
|
|
const response: GenericApiResponse<Action[]> = yield call(
|
2020-02-21 12:16:49 +00:00
|
|
|
ActionAPI.fetchActionsByPageId,
|
|
|
|
|
pageId,
|
|
|
|
|
);
|
|
|
|
|
const isValidResponse = yield validateResponse(response);
|
|
|
|
|
if (isValidResponse) {
|
|
|
|
|
yield put(fetchActionsForPageSuccess(response.data));
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_PAGE_ACTIONS_API,
|
|
|
|
|
);
|
2020-02-21 12:16:49 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_PAGE_ACTIONS_API,
|
|
|
|
|
{ failed: true },
|
|
|
|
|
);
|
2020-02-21 12:16:49 +00:00
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.FETCH_ACTIONS_FOR_PAGE_ERROR,
|
|
|
|
|
payload: { error },
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-06 13:35:31 +00:00
|
|
|
export function* updateActionSaga(actionPayload: ReduxAction<{ id: string }>) {
|
2019-11-13 07:34:59 +00:00
|
|
|
try {
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.startAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.UPDATE_ACTION_API,
|
|
|
|
|
{ actionid: actionPayload.payload.id },
|
|
|
|
|
);
|
2021-01-12 04:17:28 +00:00
|
|
|
let action = yield select(getAction, actionPayload.payload.id);
|
|
|
|
|
if (!action) throw new Error("Could not find action to update");
|
2020-07-06 13:35:31 +00:00
|
|
|
const isApi = action.pluginType === "API";
|
2020-06-23 11:10:26 +00:00
|
|
|
|
2020-05-05 07:50:30 +00:00
|
|
|
if (isApi) {
|
2020-07-06 13:35:31 +00:00
|
|
|
action = transformRestAction(action);
|
2020-06-29 08:23:10 +00:00
|
|
|
}
|
2020-06-16 10:23:19 +00:00
|
|
|
|
2021-01-12 04:17:28 +00:00
|
|
|
const response: GenericApiResponse<Action> = yield ActionAPI.updateAPI(
|
2019-12-23 12:12:58 +00:00
|
|
|
action,
|
2019-11-13 07:34:59 +00:00
|
|
|
);
|
|
|
|
|
const isValidResponse = yield validateResponse(response);
|
|
|
|
|
if (isValidResponse) {
|
2020-03-06 04:59:24 +00:00
|
|
|
const pageName = yield select(
|
|
|
|
|
getCurrentPageNameByActionId,
|
|
|
|
|
response.data.id,
|
|
|
|
|
);
|
|
|
|
|
|
2020-05-05 07:50:30 +00:00
|
|
|
if (action.pluginType === QUERY_CONSTANT) {
|
|
|
|
|
AnalyticsUtil.logEvent("SAVE_QUERY", {
|
|
|
|
|
queryName: action.name,
|
|
|
|
|
pageName,
|
|
|
|
|
});
|
2020-07-06 13:35:31 +00:00
|
|
|
} else if (action.pluginType === PLUGIN_TYPE_API) {
|
|
|
|
|
AnalyticsUtil.logEvent("SAVE_API", {
|
|
|
|
|
apiId: response.data.id,
|
|
|
|
|
apiName: response.data.name,
|
|
|
|
|
pageName: pageName,
|
|
|
|
|
});
|
2020-05-05 07:50:30 +00:00
|
|
|
}
|
2020-10-30 06:24:15 +00:00
|
|
|
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.UPDATE_ACTION_API,
|
|
|
|
|
);
|
2020-10-30 06:24:15 +00:00
|
|
|
|
2021-01-12 04:17:28 +00:00
|
|
|
yield put(updateActionSuccess({ data: response.data }));
|
2019-11-13 07:34:59 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.UPDATE_ACTION_API,
|
|
|
|
|
{ failed: true },
|
|
|
|
|
);
|
2019-11-13 07:34:59 +00:00
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.UPDATE_ACTION_ERROR,
|
2020-07-06 13:35:31 +00:00
|
|
|
payload: { error, id: actionPayload.payload.id },
|
2019-10-21 15:12:45 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-06 04:59:24 +00:00
|
|
|
export function* deleteActionSaga(
|
|
|
|
|
actionPayload: ReduxAction<{ id: string; name: string }>,
|
|
|
|
|
) {
|
2019-11-13 07:34:59 +00:00
|
|
|
try {
|
|
|
|
|
const id = actionPayload.payload.id;
|
2020-03-06 04:59:24 +00:00
|
|
|
const name = actionPayload.payload.name;
|
2020-07-06 13:35:31 +00:00
|
|
|
const action = yield select(getAction, id);
|
|
|
|
|
|
|
|
|
|
const isApi = action.pluginType === PLUGIN_TYPE_API;
|
|
|
|
|
const isQuery = action.pluginType === QUERY_CONSTANT;
|
|
|
|
|
|
2021-01-12 04:17:28 +00:00
|
|
|
const response: GenericApiResponse<Action> = yield ActionAPI.deleteAction(
|
2019-11-22 14:02:55 +00:00
|
|
|
id,
|
|
|
|
|
);
|
2019-11-13 07:34:59 +00:00
|
|
|
const isValidResponse = yield validateResponse(response);
|
|
|
|
|
if (isValidResponse) {
|
2020-11-24 07:01:37 +00:00
|
|
|
Toaster.show({
|
|
|
|
|
text: `${response.data.name} Action deleted`,
|
|
|
|
|
variant: Variant.success,
|
2019-11-13 07:34:59 +00:00
|
|
|
});
|
2020-07-06 13:35:31 +00:00
|
|
|
if (isApi) {
|
|
|
|
|
const pageName = yield select(getCurrentPageNameByActionId, id);
|
|
|
|
|
AnalyticsUtil.logEvent("DELETE_API", {
|
|
|
|
|
apiName: name,
|
|
|
|
|
pageName,
|
|
|
|
|
apiID: id,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (isQuery) {
|
|
|
|
|
AnalyticsUtil.logEvent("DELETE_QUERY", {
|
|
|
|
|
queryName: action.name,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-13 07:34:59 +00:00
|
|
|
yield put(deleteActionSuccess({ id }));
|
2020-07-06 13:35:31 +00:00
|
|
|
const applicationId = yield select(getCurrentApplicationId);
|
|
|
|
|
const pageId = yield select(getCurrentPageId);
|
|
|
|
|
if (isApi) {
|
|
|
|
|
history.push(API_EDITOR_URL(applicationId, pageId));
|
|
|
|
|
}
|
|
|
|
|
if (isQuery) {
|
|
|
|
|
history.push(QUERIES_EDITOR_URL(applicationId, pageId));
|
|
|
|
|
}
|
2019-11-13 07:34:59 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.DELETE_ACTION_ERROR,
|
2019-12-11 15:14:38 +00:00
|
|
|
payload: { error, id: actionPayload.payload.id },
|
2019-10-21 15:12:45 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-24 09:54:40 +00:00
|
|
|
function* moveActionSaga(
|
|
|
|
|
action: ReduxAction<{
|
|
|
|
|
id: string;
|
|
|
|
|
destinationPageId: string;
|
|
|
|
|
originalPageId: string;
|
|
|
|
|
name: string;
|
|
|
|
|
}>,
|
|
|
|
|
) {
|
2021-01-12 04:17:28 +00:00
|
|
|
const actionObject: Action = yield select(getAction, action.payload.id);
|
2020-07-03 08:58:58 +00:00
|
|
|
const withoutBindings = removeBindingsFromActionObject(actionObject);
|
2020-01-24 09:54:40 +00:00
|
|
|
try {
|
|
|
|
|
const response = yield ActionAPI.moveAction({
|
2020-01-27 13:53:33 +00:00
|
|
|
action: {
|
|
|
|
|
...withoutBindings,
|
2020-07-06 13:35:31 +00:00
|
|
|
pageId: action.payload.originalPageId,
|
2020-01-27 13:53:33 +00:00
|
|
|
name: action.payload.name,
|
|
|
|
|
},
|
2020-01-24 09:54:40 +00:00
|
|
|
destinationPageId: action.payload.destinationPageId,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const isValidResponse = yield validateResponse(response);
|
|
|
|
|
if (isValidResponse) {
|
2020-11-24 07:01:37 +00:00
|
|
|
Toaster.show({
|
|
|
|
|
text: `${response.data.name} Action moved`,
|
|
|
|
|
variant: Variant.success,
|
2020-01-24 09:54:40 +00:00
|
|
|
});
|
|
|
|
|
}
|
2020-03-06 04:59:24 +00:00
|
|
|
const pageName = yield select(getPageNameByPageId, response.data.pageId);
|
|
|
|
|
AnalyticsUtil.logEvent("MOVE_API", {
|
|
|
|
|
apiName: response.data.name,
|
|
|
|
|
pageName: pageName,
|
|
|
|
|
apiID: response.data.id,
|
|
|
|
|
});
|
2020-01-27 13:53:33 +00:00
|
|
|
yield put(moveActionSuccess(response.data));
|
2020-01-24 09:54:40 +00:00
|
|
|
} catch (e) {
|
2020-11-24 07:01:37 +00:00
|
|
|
Toaster.show({
|
|
|
|
|
text: `Error while moving action ${actionObject.name}`,
|
|
|
|
|
variant: Variant.danger,
|
2020-01-24 09:54:40 +00:00
|
|
|
});
|
|
|
|
|
yield put(
|
|
|
|
|
moveActionError({
|
|
|
|
|
id: action.payload.id,
|
|
|
|
|
originalPageId: action.payload.originalPageId,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function* copyActionSaga(
|
|
|
|
|
action: ReduxAction<{ id: string; destinationPageId: string; name: string }>,
|
|
|
|
|
) {
|
2021-01-12 04:17:28 +00:00
|
|
|
let actionObject: Action = yield select(getAction, action.payload.id);
|
2020-01-24 09:54:40 +00:00
|
|
|
try {
|
2021-01-12 04:17:28 +00:00
|
|
|
if (!actionObject) throw new Error("Could not find action to copy");
|
|
|
|
|
if (action.payload.destinationPageId !== actionObject.pageId) {
|
|
|
|
|
actionObject = removeBindingsFromActionObject(actionObject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const copyAction = Object.assign({}, actionObject, {
|
2020-01-24 09:54:40 +00:00
|
|
|
name: action.payload.name,
|
|
|
|
|
pageId: action.payload.destinationPageId,
|
2021-01-12 04:17:28 +00:00
|
|
|
}) as Partial<Action>;
|
|
|
|
|
delete copyAction.id;
|
2020-01-24 09:54:40 +00:00
|
|
|
const response = yield ActionAPI.createAPI(copyAction);
|
2020-12-10 08:22:40 +00:00
|
|
|
const datasources = yield select(getDataSources);
|
2020-01-24 09:54:40 +00:00
|
|
|
|
|
|
|
|
const isValidResponse = yield validateResponse(response);
|
|
|
|
|
if (isValidResponse) {
|
2020-11-24 07:01:37 +00:00
|
|
|
Toaster.show({
|
|
|
|
|
text: `${actionObject.name} Action copied`,
|
|
|
|
|
variant: Variant.success,
|
2020-01-24 09:54:40 +00:00
|
|
|
});
|
|
|
|
|
}
|
2020-03-06 04:59:24 +00:00
|
|
|
|
|
|
|
|
const pageName = yield select(getPageNameByPageId, response.data.pageId);
|
|
|
|
|
AnalyticsUtil.logEvent("DUPLICATE_API", {
|
|
|
|
|
apiName: response.data.name,
|
|
|
|
|
pageName: pageName,
|
|
|
|
|
apiID: response.data.id,
|
|
|
|
|
});
|
2020-12-10 08:22:40 +00:00
|
|
|
|
|
|
|
|
// checking if there is existing datasource to be added to the action payload
|
|
|
|
|
const existingDatasource = datasources.find(
|
|
|
|
|
(d: Datasource) => d.id === response.data.datasource.id,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let payload = response.data;
|
|
|
|
|
|
|
|
|
|
if (existingDatasource) {
|
|
|
|
|
payload = { ...payload, datasource: existingDatasource };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
yield put(copyActionSuccess(payload));
|
2020-01-24 09:54:40 +00:00
|
|
|
} catch (e) {
|
2020-11-24 07:01:37 +00:00
|
|
|
Toaster.show({
|
2021-01-12 04:17:28 +00:00
|
|
|
text: `Error while copying action ${
|
|
|
|
|
actionObject ? actionObject.name : ""
|
|
|
|
|
}`,
|
2020-11-24 07:01:37 +00:00
|
|
|
variant: Variant.danger,
|
2020-01-24 09:54:40 +00:00
|
|
|
});
|
|
|
|
|
yield put(copyActionError(action.payload));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-16 10:23:19 +00:00
|
|
|
export function* refactorActionName(
|
|
|
|
|
id: string,
|
|
|
|
|
pageId: string,
|
|
|
|
|
oldName: string,
|
|
|
|
|
newName: string,
|
|
|
|
|
) {
|
|
|
|
|
// fetch page of the action
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.startAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.REFACTOR_ACTION_NAME,
|
|
|
|
|
{ actionId: id },
|
|
|
|
|
);
|
2020-06-16 10:23:19 +00:00
|
|
|
const pageResponse = yield call(PageApi.fetchPage, {
|
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 08:52:45 +00:00
|
|
|
id: pageId,
|
2020-06-16 10:23:19 +00:00
|
|
|
});
|
|
|
|
|
// check if page request is successful
|
|
|
|
|
const isPageRequestSuccessful = yield validateResponse(pageResponse);
|
|
|
|
|
if (isPageRequestSuccessful) {
|
|
|
|
|
// get the layoutId from the page response
|
|
|
|
|
const layoutId = pageResponse.data.layouts[0].id;
|
|
|
|
|
// call to refactor action
|
|
|
|
|
const refactorResponse = yield ActionAPI.updateActionName({
|
|
|
|
|
layoutId,
|
|
|
|
|
pageId: pageId,
|
|
|
|
|
oldName: oldName,
|
|
|
|
|
newName: newName,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const isRefactorSuccessful = yield validateResponse(refactorResponse);
|
|
|
|
|
|
|
|
|
|
const currentPageId = yield select(getCurrentPageId);
|
2020-09-28 05:12:23 +00:00
|
|
|
|
|
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.REFACTOR_ACTION_NAME,
|
|
|
|
|
{ isSuccess: isRefactorSuccessful },
|
|
|
|
|
);
|
2020-06-16 10:23:19 +00:00
|
|
|
if (isRefactorSuccessful) {
|
2020-06-18 07:46:53 +00:00
|
|
|
yield put({
|
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 08:52:45 +00:00
|
|
|
type: ReduxActionTypes.SAVE_ACTION_NAME_SUCCESS,
|
2020-06-18 07:46:53 +00:00
|
|
|
payload: {
|
|
|
|
|
actionId: id,
|
|
|
|
|
},
|
|
|
|
|
});
|
2020-06-16 10:23:19 +00:00
|
|
|
if (currentPageId === pageId) {
|
|
|
|
|
yield updateCanvasWithDSL(refactorResponse.data, pageId, layoutId);
|
|
|
|
|
} else {
|
|
|
|
|
yield put(fetchActionsForPage(pageId));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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 08:52:45 +00:00
|
|
|
function* saveActionName(action: ReduxAction<{ id: string; name: string }>) {
|
2020-07-21 14:01:51 +00:00
|
|
|
// Takes from state, checks if the name isValid, saves
|
2020-06-18 14:16:49 +00:00
|
|
|
const apiId = action.payload.id;
|
2020-12-24 04:32:25 +00:00
|
|
|
const api = yield select((state) =>
|
2020-06-18 14:16:49 +00:00
|
|
|
state.entities.actions.find(
|
|
|
|
|
(action: ActionData) => action.config.id === apiId,
|
|
|
|
|
),
|
|
|
|
|
);
|
2020-06-17 13:16:14 +00:00
|
|
|
try {
|
2020-06-18 07:46:53 +00:00
|
|
|
yield refactorActionName(
|
|
|
|
|
api.config.id,
|
|
|
|
|
api.config.pageId,
|
|
|
|
|
api.config.name,
|
|
|
|
|
action.payload.name,
|
2020-06-17 13:16:14 +00:00
|
|
|
);
|
2020-06-18 07:46:53 +00:00
|
|
|
} catch (e) {
|
|
|
|
|
yield put({
|
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 08:52:45 +00:00
|
|
|
type: ReduxActionErrorTypes.SAVE_ACTION_NAME_ERROR,
|
2020-06-18 07:46:53 +00:00
|
|
|
payload: {
|
|
|
|
|
actionId: action.payload.id,
|
2020-06-18 14:16:49 +00:00
|
|
|
oldName: api.config.name,
|
2020-06-18 07:46:53 +00:00
|
|
|
},
|
|
|
|
|
});
|
2020-11-24 07:01:37 +00:00
|
|
|
Toaster.show({
|
|
|
|
|
text: `Unable to update Action name`,
|
|
|
|
|
variant: Variant.danger,
|
2020-06-17 13:16:14 +00:00
|
|
|
});
|
|
|
|
|
console.error(e);
|
2020-06-16 10:23:19 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-03 08:58:58 +00:00
|
|
|
function getDynamicBindingsChangesSaga(
|
|
|
|
|
action: Action,
|
2021-03-01 14:57:15 +00:00
|
|
|
value: unknown,
|
2020-07-03 08:58:58 +00:00
|
|
|
field: string,
|
|
|
|
|
) {
|
|
|
|
|
const bindingField = field.replace("actionConfiguration.", "");
|
2021-03-01 14:57:15 +00:00
|
|
|
let dynamicBindings: DynamicPath[] = action.dynamicBindingPathList || [];
|
2020-07-03 08:58:58 +00:00
|
|
|
|
2021-03-01 14:57:15 +00:00
|
|
|
if (typeof value === "object") {
|
|
|
|
|
dynamicBindings = dynamicBindings.filter((dynamicPath) => {
|
|
|
|
|
if (isChildPropertyPath(bindingField, dynamicPath.key)) {
|
|
|
|
|
const childPropertyValue = _.get(value, dynamicPath.key);
|
|
|
|
|
return isDynamicValue(childPropertyValue);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} else if (typeof value === "string") {
|
|
|
|
|
const fieldExists = _.some(dynamicBindings, { key: bindingField });
|
|
|
|
|
|
|
|
|
|
const isDynamic = isDynamicValue(value);
|
|
|
|
|
|
|
|
|
|
if (!isDynamic && fieldExists) {
|
|
|
|
|
dynamicBindings = dynamicBindings.filter((d) => d.key !== bindingField);
|
|
|
|
|
}
|
|
|
|
|
if (isDynamic && !fieldExists) {
|
|
|
|
|
dynamicBindings.push({ key: bindingField });
|
|
|
|
|
}
|
2020-07-03 08:58:58 +00:00
|
|
|
}
|
2021-03-01 14:57:15 +00:00
|
|
|
|
|
|
|
|
return dynamicBindings;
|
2020-07-03 08:58:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function* setActionPropertySaga(action: ReduxAction<SetActionPropertyPayload>) {
|
|
|
|
|
const { actionId, value, propertyName } = action.payload;
|
|
|
|
|
if (!actionId) return;
|
2020-07-06 04:19:49 +00:00
|
|
|
if (propertyName === "name") return;
|
2020-08-27 15:39:16 +00:00
|
|
|
|
2020-07-03 08:58:58 +00:00
|
|
|
const actionObj = yield select(getAction, actionId);
|
|
|
|
|
const effects: Record<string, any> = {};
|
|
|
|
|
// Value change effect
|
|
|
|
|
effects[propertyName] = value;
|
|
|
|
|
// Bindings change effect
|
|
|
|
|
effects.dynamicBindingPathList = getDynamicBindingsChangesSaga(
|
|
|
|
|
actionObj,
|
|
|
|
|
value,
|
|
|
|
|
propertyName,
|
|
|
|
|
);
|
|
|
|
|
yield all(
|
2020-12-24 04:32:25 +00:00
|
|
|
Object.keys(effects).map((field) =>
|
2020-07-03 08:58:58 +00:00
|
|
|
put(updateActionProperty({ id: actionId, field, value: effects[field] })),
|
|
|
|
|
),
|
|
|
|
|
);
|
2020-08-27 15:39:16 +00:00
|
|
|
if (propertyName === "executeOnLoad") {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.TOGGLE_ACTION_EXECUTE_ON_LOAD_INIT,
|
|
|
|
|
payload: {
|
|
|
|
|
actionId,
|
|
|
|
|
shouldExecute: value,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-07-06 13:35:31 +00:00
|
|
|
yield put(updateAction({ id: actionId }));
|
2020-07-03 08:58:58 +00:00
|
|
|
}
|
|
|
|
|
|
2020-08-27 15:39:16 +00:00
|
|
|
function* toggleActionExecuteOnLoadSaga(
|
|
|
|
|
action: ReduxAction<{ actionId: string; shouldExecute: boolean }>,
|
|
|
|
|
) {
|
|
|
|
|
try {
|
|
|
|
|
const response = yield call(
|
|
|
|
|
ActionAPI.toggleActionExecuteOnLoad,
|
|
|
|
|
action.payload.actionId,
|
|
|
|
|
action.payload.shouldExecute,
|
|
|
|
|
);
|
|
|
|
|
const isValidResponse = yield validateResponse(response);
|
|
|
|
|
if (isValidResponse) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.TOGGLE_ACTION_EXECUTE_ON_LOAD_SUCCESS,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.TOGGLE_ACTION_EXECUTE_ON_LOAD_ERROR,
|
|
|
|
|
payload: error,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-07 08:07:37 +00:00
|
|
|
function* handleMoveOrCopySaga(actionPayload: ReduxAction<{ id: string }>) {
|
|
|
|
|
const { id } = actionPayload.payload;
|
2020-08-21 06:03:04 +00:00
|
|
|
const action: Action = yield select(getAction, id);
|
2020-07-07 08:07:37 +00:00
|
|
|
const isApi = action.pluginType === PLUGIN_TYPE_API;
|
|
|
|
|
const isQuery = action.pluginType === QUERY_CONSTANT;
|
2020-08-21 06:03:04 +00:00
|
|
|
const applicationId = yield select(getCurrentApplicationId);
|
2020-07-07 08:07:37 +00:00
|
|
|
|
|
|
|
|
if (isApi) {
|
2020-08-21 06:03:04 +00:00
|
|
|
history.push(API_EDITOR_ID_URL(applicationId, action.pageId, action.id));
|
2020-07-07 08:07:37 +00:00
|
|
|
}
|
|
|
|
|
if (isQuery) {
|
2020-08-21 06:03:04 +00:00
|
|
|
history.push(
|
|
|
|
|
QUERIES_EDITOR_ID_URL(applicationId, action.pageId, action.id),
|
|
|
|
|
);
|
2020-07-07 08:07:37 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-21 15:12:45 +00:00
|
|
|
export function* watchActionSagas() {
|
|
|
|
|
yield all([
|
2020-07-03 08:58:58 +00:00
|
|
|
takeEvery(ReduxActionTypes.SET_ACTION_PROPERTY, setActionPropertySaga),
|
2019-10-21 15:12:45 +00:00
|
|
|
takeEvery(ReduxActionTypes.FETCH_ACTIONS_INIT, fetchActionsSaga),
|
2020-07-15 13:01:35 +00:00
|
|
|
takeEvery(
|
|
|
|
|
ReduxActionTypes.FETCH_ACTIONS_VIEW_MODE_INIT,
|
|
|
|
|
fetchActionsForViewModeSaga,
|
|
|
|
|
),
|
2020-04-22 09:15:24 +00:00
|
|
|
takeEvery(ReduxActionTypes.CREATE_ACTION_INIT, createActionSaga),
|
2020-07-28 10:41:51 +00:00
|
|
|
takeLatest(ReduxActionTypes.UPDATE_ACTION_INIT, updateActionSaga),
|
2019-10-25 05:35:20 +00:00
|
|
|
takeLatest(ReduxActionTypes.DELETE_ACTION_INIT, deleteActionSaga),
|
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 08:52:45 +00:00
|
|
|
takeLatest(ReduxActionTypes.SAVE_ACTION_NAME_INIT, saveActionName),
|
2020-01-24 09:54:40 +00:00
|
|
|
takeLatest(ReduxActionTypes.MOVE_ACTION_INIT, moveActionSaga),
|
|
|
|
|
takeLatest(ReduxActionTypes.COPY_ACTION_INIT, copyActionSaga),
|
2020-02-21 12:16:49 +00:00
|
|
|
takeLatest(
|
|
|
|
|
ReduxActionTypes.FETCH_ACTIONS_FOR_PAGE_INIT,
|
|
|
|
|
fetchActionsForPageSaga,
|
|
|
|
|
),
|
2020-07-07 08:07:37 +00:00
|
|
|
takeEvery(ReduxActionTypes.MOVE_ACTION_SUCCESS, handleMoveOrCopySaga),
|
|
|
|
|
takeEvery(ReduxActionTypes.COPY_ACTION_SUCCESS, handleMoveOrCopySaga),
|
|
|
|
|
takeEvery(ReduxActionErrorTypes.MOVE_ACTION_ERROR, handleMoveOrCopySaga),
|
|
|
|
|
takeEvery(ReduxActionErrorTypes.COPY_ACTION_ERROR, handleMoveOrCopySaga),
|
2020-08-27 15:39:16 +00:00
|
|
|
takeLatest(
|
|
|
|
|
ReduxActionTypes.TOGGLE_ACTION_EXECUTE_ON_LOAD_INIT,
|
|
|
|
|
toggleActionExecuteOnLoadSaga,
|
|
|
|
|
),
|
2019-10-21 15:12:45 +00:00
|
|
|
]);
|
|
|
|
|
}
|