PromucFlow_constructor/app/client/src/reducers/entityReducers/actionsReducer.tsx
Aman Agarwal acc3b19377
fix: action reducers were using old implementation of updating state (#22912)
## Description

In this PR `ActionReducer` code was refactored to use
`createImmerReducer` instead of `createReducer`, which helped in solving
the gsheet error of spreadsheet name mismatch and api url field update failing autosave by updating the redux
store values properly.
2023-05-05 14:45:10 +05:30

391 lines
11 KiB
TypeScript

import { createImmerReducer } from "utils/ReducerUtils";
import type { ReduxAction } from "@appsmith/constants/ReduxActionConstants";
import {
ReduxActionTypes,
ReduxActionErrorTypes,
} from "@appsmith/constants/ReduxActionConstants";
import type { ActionResponse } from "api/ActionAPI";
import type { ExecuteErrorPayload } from "constants/AppsmithActionConstants/ActionConstants";
import _ from "lodash";
import type { Action } from "entities/Action";
import type { UpdateActionPropertyActionPayload } from "actions/pluginActionActions";
export interface ActionData {
isLoading: boolean;
config: Action;
data?: ActionResponse;
}
export interface ActionDataWithMeta extends ActionData {
responseMeta: {
headers?: unknown;
isExecutionSuccess: boolean;
statusCode?: string;
};
}
export type ActionDataState = ActionData[];
export interface PartialActionData {
isLoading: boolean;
config: { id: string };
data?: ActionResponse;
}
const initialState: ActionDataState = [];
const actionsReducer = createImmerReducer(initialState, {
[ReduxActionTypes.FETCH_ACTIONS_SUCCESS]: (
draftMetaState: ActionDataState,
action: ReduxAction<Action[]>,
) => {
return action.payload.map((action) => {
const foundAction = draftMetaState.find((currentAction) => {
return currentAction.config.id === action.id;
});
return {
isLoading: false,
config: action,
data: foundAction?.data,
};
});
},
[ReduxActionTypes.FETCH_ACTIONS_VIEW_MODE_SUCCESS]: (
_: ActionDataState,
action: ReduxAction<Action[]>,
) => {
return action.payload.map((a) => ({
isLoading: false,
config: a,
}));
},
[ReduxActionTypes.FETCH_ACTIONS_FOR_PAGE_SUCCESS]: (
draftMetaState: ActionDataState,
action: ReduxAction<Action[]>,
) => {
if (action.payload.length > 0) {
const stateActionMap = _.keyBy(draftMetaState, "config.id");
const result: ActionDataState = [];
action.payload.forEach((actionPayload: Action) => {
const stateAction = stateActionMap[actionPayload.id];
if (stateAction) {
result.push({
data: stateAction.data,
isLoading: false,
config: actionPayload,
});
delete stateActionMap[actionPayload.id];
} else {
result.push({
isLoading: false,
config: actionPayload,
});
}
});
Object.keys(stateActionMap).forEach((stateActionKey) => {
result.push(stateActionMap[stateActionKey]);
});
return result;
}
},
[ReduxActionTypes.SUBMIT_CURL_FORM_SUCCESS]: (
draftMetaState: ActionDataState,
action: ReduxAction<Action>,
) => {
return draftMetaState.concat([
{ config: action.payload, isLoading: false },
]);
},
[ReduxActionErrorTypes.FETCH_ACTIONS_ERROR]: () => initialState,
[ReduxActionErrorTypes.FETCH_ACTIONS_VIEW_MODE_ERROR]: () => initialState,
[ReduxActionTypes.CREATE_ACTION_INIT]: (
draftMetaState: ActionDataState,
action: ReduxAction<Action>,
) => {
return draftMetaState.concat([
{
config: { ...action.payload, id: action.payload.name },
isLoading: false,
},
]);
},
[ReduxActionTypes.CREATE_ACTION_SUCCESS]: (
draftMetaState: ActionDataState,
action: ReduxAction<Action>,
) => {
draftMetaState.forEach((a) => {
if (
a.config.pageId === action.payload.pageId &&
a.config.id === action.payload.name
) {
a.config = action.payload;
}
});
},
[ReduxActionErrorTypes.CREATE_ACTION_ERROR]: (
draftMetaState: ActionDataState,
action: ReduxAction<Action>,
) => {
return draftMetaState.filter(
(a) =>
a.config.name !== action.payload.name &&
a.config.id !== action.payload.name,
);
},
[ReduxActionTypes.UPDATE_ACTION_SUCCESS]: (
draftMetaState: ActionDataState,
action: ReduxAction<{ data: Action }>,
) => {
draftMetaState.forEach((a) => {
if (a.config.id === action.payload.data.id) {
a.config = action.payload.data;
}
});
},
[ReduxActionTypes.UPDATE_ACTION_PROPERTY]: (
draftMetaState: ActionDataState,
action: ReduxAction<UpdateActionPropertyActionPayload>,
) => {
draftMetaState.forEach((a) => {
if (a.config.id === action.payload.id) {
return _.set(a, `config.${action.payload.field}`, action.payload.value);
}
});
},
[ReduxActionTypes.DELETE_ACTION_SUCCESS]: (
draftMetaState: ActionDataState,
action: ReduxAction<{ id: string }>,
) => {
return draftMetaState.filter((a) => a.config.id !== action.payload.id);
},
[ReduxActionTypes.EXECUTE_PLUGIN_ACTION_REQUEST]: (
draftMetaState: ActionDataState,
action: ReduxAction<{ id: string }>,
) => {
draftMetaState.forEach((a) => {
if (a.config.id === action.payload.id) {
a.isLoading = true;
}
});
},
[ReduxActionTypes.EXECUTE_PLUGIN_ACTION_SUCCESS]: (
draftMetaState: Array<ActionData | PartialActionData>,
action: ReduxAction<{ id: string; response: ActionResponse }>,
) => {
const foundAction = draftMetaState.find((stateAction) => {
return stateAction.config.id === action.payload.id;
});
if (foundAction) {
foundAction.isLoading = false;
if (foundAction.data) _.assign(foundAction.data, action.payload.response);
else foundAction.data = action.payload.response;
} else {
const partialAction: PartialActionData = {
isLoading: false,
config: { id: action.payload.id },
data: action.payload.response,
};
draftMetaState.push(partialAction);
}
},
[ReduxActionTypes.SET_ACTION_RESPONSE_DISPLAY_FORMAT]: (
draftMetaState: ActionDataState,
action: ReduxAction<UpdateActionPropertyActionPayload>,
) => {
draftMetaState.forEach((a) => {
if (a.config.id === action.payload.id) {
return _.set(a, `data.${action.payload.field}`, action.payload.value);
}
});
},
[ReduxActionTypes.CLEAR_ACTION_RESPONSE]: (
draftMetaState: ActionDataState,
action: ReduxAction<{ actionId: string }>,
) => {
draftMetaState.forEach((stateAction) => {
if (stateAction.config.id === action.payload.actionId) {
stateAction.data = undefined;
}
});
},
[ReduxActionErrorTypes.EXECUTE_PLUGIN_ACTION_ERROR]: (
draftMetaState: ActionDataState,
action: ReduxAction<ExecuteErrorPayload>,
) => {
draftMetaState.forEach((a) => {
if (a.config.id === action.payload.actionId) {
a.isLoading = false;
a.data = action.payload.data;
}
});
},
[ReduxActionTypes.RUN_ACTION_REQUEST]: (
draftMetaState: ActionDataState,
action: ReduxAction<{ id: string }>,
) => {
draftMetaState.forEach((a) => {
if (action.payload.id === a.config.id) {
a.isLoading = true;
}
});
},
[ReduxActionTypes.RUN_ACTION_SUCCESS]: (
draftMetaState: ActionDataState,
action: ReduxAction<{ [id: string]: ActionResponse }>,
) => {
const actionId = Object.keys(action.payload)[0];
draftMetaState.forEach((a) => {
if (a.config.id === actionId) {
a.isLoading = false;
if (a.data) _.assign(a.data, action.payload[actionId]);
else a.data = action.payload[actionId];
}
});
},
[ReduxActionErrorTypes.RUN_ACTION_ERROR]: (
draftMetaState: ActionDataState,
action: ReduxAction<{ id: string }>,
) => {
draftMetaState.forEach((a) => {
if (a.config.id === action.payload.id) {
a.isLoading = false;
}
});
},
[ReduxActionTypes.RUN_ACTION_CANCELLED]: (
draftMetaState: ActionDataState,
action: ReduxAction<{ id: string }>,
) => {
draftMetaState.forEach((a) => {
if (a.config.id === action.payload.id) {
a.isLoading = false;
}
});
},
[ReduxActionTypes.MOVE_ACTION_INIT]: (
draftMetaState: ActionDataState,
action: ReduxAction<{
id: string;
destinationPageId: string;
name: string;
}>,
) => {
draftMetaState.forEach((a) => {
if (a.config.id === action.payload.id) {
a.config.name = action.payload.name;
a.config.pageId = action.payload.destinationPageId;
}
});
},
[ReduxActionTypes.MOVE_ACTION_SUCCESS]: (
draftMetaState: ActionDataState,
action: ReduxAction<Action>,
) => {
draftMetaState.forEach((a) => {
if (a.config.id === action.payload.id) {
a.config = action.payload;
}
});
},
[ReduxActionErrorTypes.MOVE_ACTION_ERROR]: (
draftMetaState: ActionDataState,
action: ReduxAction<{ id: string; originalPageId: string }>,
) => {
draftMetaState.forEach((a) => {
if (a.config.id === action.payload.id) {
a.config.pageId = action.payload.originalPageId;
}
});
},
[ReduxActionTypes.COPY_ACTION_INIT]: (
draftMetaState: ActionDataState,
action: ReduxAction<{
id: string;
destinationPageId: string;
name: string;
}>,
) => {
return draftMetaState.concat(
draftMetaState
.filter((a) => a.config.id === action.payload.id)
.map((a) => ({
...a,
data: undefined,
config: {
...a.config,
id: "TEMP_COPY_ID",
name: action.payload.name,
pageId: action.payload.destinationPageId,
},
})),
);
},
[ReduxActionTypes.COPY_ACTION_SUCCESS]: (
draftMetaState: ActionDataState,
action: ReduxAction<Action>,
) => {
draftMetaState.forEach((a) => {
if (
a.config.pageId === action.payload.pageId &&
a.config.name === action.payload.name
) {
a.config = action.payload;
}
});
},
[ReduxActionErrorTypes.COPY_ACTION_ERROR]: (
draftMetaState: ActionDataState,
action: ReduxAction<{
id: string;
destinationPageId: string;
name: string;
}>,
) => {
return draftMetaState.filter((a) => {
if (a.config.pageId === action.payload.destinationPageId) {
if (
a.config.id === action.payload.id ||
a.config.id === "TEMP_COPY_ID"
) {
return a.config.name !== action.payload.name;
}
return true;
}
return true;
});
},
[ReduxActionTypes.SET_ACTION_TO_EXECUTE_ON_PAGELOAD]: (
draftMetaState: ActionDataState,
action: ReduxAction<
Array<{
executeOnLoad: boolean;
id: string;
name: string;
}>
>,
) => {
const actionUpdateSearch = _.keyBy(action.payload, "id");
draftMetaState.forEach((action) => {
if (action.config.id in actionUpdateSearch) {
action.config.executeOnLoad =
actionUpdateSearch[action.config.id].executeOnLoad;
}
});
},
[ReduxActionTypes.SWITCH_CURRENT_PAGE_ID]: (
draftMetaState: ActionDataState,
) => {
draftMetaState.forEach((a) => {
a.data = undefined;
});
},
});
export default actionsReducer;