214 lines
6.6 KiB
TypeScript
214 lines
6.6 KiB
TypeScript
import {
|
|
ReduxAction,
|
|
ReduxActionTypes,
|
|
} from "@appsmith/constants/ReduxActionConstants";
|
|
import {
|
|
EventType,
|
|
ExecuteTriggerPayload,
|
|
TriggerSource,
|
|
} from "constants/AppsmithActionConstants/ActionConstants";
|
|
import * as log from "loglevel";
|
|
import { all, call, put, takeEvery, takeLatest } from "redux-saga/effects";
|
|
import {
|
|
evaluateArgumentSaga,
|
|
evaluateAndExecuteDynamicTrigger,
|
|
evaluateSnippetSaga,
|
|
setAppVersionOnWorkerSaga,
|
|
} from "sagas/EvaluationsSaga";
|
|
import navigateActionSaga from "sagas/ActionExecution/NavigateActionSaga";
|
|
import storeValueLocally from "sagas/ActionExecution/StoreActionSaga";
|
|
import downloadSaga from "sagas/ActionExecution/DownloadActionSaga";
|
|
import copySaga from "sagas/ActionExecution/CopyActionSaga";
|
|
import resetWidgetActionSaga from "sagas/ActionExecution/ResetWidgetActionSaga";
|
|
import showAlertSaga from "sagas/ActionExecution/ShowAlertActionSaga";
|
|
import executePluginActionTriggerSaga from "sagas/ActionExecution/PluginActionSaga";
|
|
import {
|
|
ActionDescription,
|
|
ActionTriggerType,
|
|
} from "entities/DataTree/actionTriggers";
|
|
import { clearActionResponse } from "actions/pluginActionActions";
|
|
import {
|
|
closeModalSaga,
|
|
openModalSaga,
|
|
} from "sagas/ActionExecution/ModalSagas";
|
|
import AppsmithConsole from "utils/AppsmithConsole";
|
|
import {
|
|
logActionExecutionError,
|
|
TriggerFailureError,
|
|
UncaughtPromiseError,
|
|
} from "sagas/ActionExecution/errorUtils";
|
|
import {
|
|
clearIntervalSaga,
|
|
setIntervalSaga,
|
|
} from "sagas/ActionExecution/SetIntervalSaga";
|
|
import { UserCancelledActionExecutionError } from "sagas/ActionExecution/errorUtils";
|
|
import {
|
|
getCurrentLocationSaga,
|
|
stopWatchCurrentLocation,
|
|
watchCurrentLocation,
|
|
} from "sagas/ActionExecution/GetCurrentLocationSaga";
|
|
import { requestModalConfirmationSaga } from "sagas/UtilSagas";
|
|
import { ModalType } from "reducers/uiReducers/modalActionReducer";
|
|
|
|
export type TriggerMeta = {
|
|
source?: TriggerSource;
|
|
triggerPropertyName?: string;
|
|
};
|
|
|
|
/**
|
|
* The controller saga that routes different trigger effects to its executor sagas
|
|
* @param trigger The trigger information with trigger type
|
|
* @param eventType Widget/Platform event which triggered this action
|
|
* @param triggerMeta Where the trigger originated from
|
|
*/
|
|
export function* executeActionTriggers(
|
|
trigger: ActionDescription,
|
|
eventType: EventType,
|
|
triggerMeta: TriggerMeta,
|
|
): any {
|
|
// when called via a promise, a trigger can return some value to be used in .then
|
|
let response: unknown[] = [];
|
|
switch (trigger.type) {
|
|
case ActionTriggerType.RUN_PLUGIN_ACTION:
|
|
response = yield call(
|
|
executePluginActionTriggerSaga,
|
|
trigger.payload,
|
|
eventType,
|
|
triggerMeta,
|
|
);
|
|
break;
|
|
case ActionTriggerType.CLEAR_PLUGIN_ACTION:
|
|
yield put(clearActionResponse(trigger.payload.actionId));
|
|
break;
|
|
case ActionTriggerType.NAVIGATE_TO:
|
|
yield call(navigateActionSaga, trigger.payload);
|
|
break;
|
|
case ActionTriggerType.SHOW_ALERT:
|
|
yield call(showAlertSaga, trigger.payload);
|
|
break;
|
|
case ActionTriggerType.SHOW_MODAL_BY_NAME:
|
|
yield call(openModalSaga, trigger);
|
|
break;
|
|
case ActionTriggerType.CLOSE_MODAL:
|
|
yield call(closeModalSaga, trigger);
|
|
break;
|
|
case ActionTriggerType.STORE_VALUE:
|
|
yield call(storeValueLocally, trigger.payload);
|
|
break;
|
|
case ActionTriggerType.DOWNLOAD:
|
|
yield call(downloadSaga, trigger.payload);
|
|
break;
|
|
case ActionTriggerType.COPY_TO_CLIPBOARD:
|
|
yield call(copySaga, trigger.payload);
|
|
break;
|
|
case ActionTriggerType.RESET_WIDGET_META_RECURSIVE_BY_NAME:
|
|
yield call(resetWidgetActionSaga, trigger.payload);
|
|
break;
|
|
case ActionTriggerType.SET_INTERVAL:
|
|
yield call(setIntervalSaga, trigger.payload, eventType, triggerMeta);
|
|
break;
|
|
case ActionTriggerType.CLEAR_INTERVAL:
|
|
yield call(clearIntervalSaga, trigger.payload);
|
|
break;
|
|
case ActionTriggerType.GET_CURRENT_LOCATION:
|
|
response = yield call(
|
|
getCurrentLocationSaga,
|
|
trigger.payload,
|
|
eventType,
|
|
triggerMeta,
|
|
);
|
|
break;
|
|
|
|
case ActionTriggerType.WATCH_CURRENT_LOCATION:
|
|
response = yield call(
|
|
watchCurrentLocation,
|
|
trigger.payload,
|
|
eventType,
|
|
triggerMeta,
|
|
);
|
|
break;
|
|
|
|
case ActionTriggerType.STOP_WATCHING_CURRENT_LOCATION:
|
|
response = yield call(stopWatchCurrentLocation, eventType, triggerMeta);
|
|
break;
|
|
case ActionTriggerType.CONFIRMATION_MODAL:
|
|
const payloadInfo = {
|
|
name: trigger?.payload?.funName,
|
|
modalOpen: true,
|
|
modalType: ModalType.RUN_ACTION,
|
|
};
|
|
const flag = yield call(requestModalConfirmationSaga, payloadInfo);
|
|
if (!flag) {
|
|
throw new UserCancelledActionExecutionError();
|
|
}
|
|
break;
|
|
default:
|
|
log.error("Trigger type unknown", trigger);
|
|
throw Error("Trigger type unknown");
|
|
}
|
|
return response;
|
|
}
|
|
|
|
export function* executeAppAction(payload: ExecuteTriggerPayload) {
|
|
const {
|
|
callbackData,
|
|
dynamicString,
|
|
event: { type },
|
|
globalContext,
|
|
source,
|
|
triggerPropertyName,
|
|
} = payload;
|
|
log.debug({ dynamicString, callbackData, globalContext });
|
|
if (dynamicString === undefined) {
|
|
throw new Error("Executing undefined action");
|
|
}
|
|
|
|
yield call(
|
|
evaluateAndExecuteDynamicTrigger,
|
|
dynamicString,
|
|
type,
|
|
{ source, triggerPropertyName },
|
|
callbackData,
|
|
globalContext,
|
|
);
|
|
}
|
|
|
|
function* initiateActionTriggerExecution(
|
|
action: ReduxAction<ExecuteTriggerPayload>,
|
|
) {
|
|
const { event, source, triggerPropertyName } = action.payload;
|
|
// Clear all error for this action trigger. In case the error still exists,
|
|
// it will be created again while execution
|
|
AppsmithConsole.deleteError(`${source?.id}-${triggerPropertyName}`);
|
|
try {
|
|
yield call(executeAppAction, action.payload);
|
|
if (event.callback) {
|
|
event.callback({ success: true });
|
|
}
|
|
} catch (e) {
|
|
if (e instanceof UncaughtPromiseError || e instanceof TriggerFailureError) {
|
|
logActionExecutionError(e.message, source, triggerPropertyName);
|
|
}
|
|
// handle errors here
|
|
if (event.callback) {
|
|
event.callback({ success: false });
|
|
}
|
|
log.error(e);
|
|
}
|
|
}
|
|
|
|
export function* watchActionExecutionSagas() {
|
|
yield all([
|
|
takeEvery(
|
|
ReduxActionTypes.EXECUTE_TRIGGER_REQUEST,
|
|
initiateActionTriggerExecution,
|
|
),
|
|
takeLatest(
|
|
ReduxActionTypes.SET_APP_VERSION_ON_WORKER,
|
|
setAppVersionOnWorkerSaga,
|
|
),
|
|
takeLatest(ReduxActionTypes.EVALUATE_SNIPPET, evaluateSnippetSaga),
|
|
takeLatest(ReduxActionTypes.EVALUATE_ARGUMENT, evaluateArgumentSaga),
|
|
]);
|
|
}
|