Merge branch 'feat/reactive-actions-run-behaviour' of https://github.com/appsmithorg/appsmith into feat/reactive-actions-run-behaviour

This commit is contained in:
Ankita Kinger 2025-05-08 17:12:38 +05:30
commit ee2aeca9e7
15 changed files with 156 additions and 43 deletions

View File

@ -30,6 +30,6 @@ export const deleteMetaWidgets = (
export const updateMetaWidgetProperty = (
payload: UpdateMetaWidgetPropertyPayload,
) => ({
type: ReduxActionTypes.UPDATE_META_WIDGET_PROPERTY,
type: ReduxActionTypes.UPDATE_META_WIDGET_PROPERTY_INIT,
payload,
});

View File

@ -523,6 +523,7 @@ const WidgetCanvasActionTypes = {
MODIFY_META_WIDGETS: "MODIFY_META_WIDGETS",
MODIFY_META_WIDGETS_WITHOUT_EVAL: "MODIFY_META_WIDGETS_WITHOUT_EVAL",
DELETE_META_WIDGETS: "DELETE_META_WIDGETS",
UPDATE_META_WIDGET_PROPERTY_INIT: "UPDATE_META_WIDGET_PROPERTY_INIT",
UPDATE_META_WIDGET_PROPERTY: "UPDATE_META_WIDGET_PROPERTY",
SHOW_MODAL: "SHOW_MODAL",
SHOW_MODAL_BY_NAME: "SHOW_MODAL_BY_NAME",

View File

@ -31,6 +31,7 @@ export const initialState: EditorReduxState = {
cloningPageError: false,
updatingWidgetName: false,
updateWidgetNameError: false,
isSettingUpPage: false,
},
isSnipingMode: false,
snipModeBindTo: undefined,
@ -269,6 +270,31 @@ export const handlers = {
...state,
widgetConfigBuilt: true,
}),
[ReduxActionTypes.SETUP_PAGE_INIT]: (state: EditorReduxState) => {
return {
...state,
loadingStates: {
...state.loadingStates,
isSettingUpPage: true,
},
};
},
[ReduxActionTypes.SETUP_PAGE_SUCCESS]: (state: EditorReduxState) => {
return {
...state,
loadingStates: {
...state.loadingStates,
isSettingUpPage: false,
},
};
},
[ReduxActionErrorTypes.SETUP_PAGE_ERROR]: (state: EditorReduxState) => {
return {
...state,
loadingStates: { ...state.loadingStates, isSettingUpPage: false },
};
},
};
const editorReducer = createReducer(initialState, handlers);
@ -305,6 +331,7 @@ export interface EditorReduxState {
cloningPageError: boolean;
updatingWidgetName: boolean;
updateWidgetNameError: boolean;
isSettingUpPage: boolean;
};
}

View File

@ -57,10 +57,7 @@ import type {
UpdateWidgetNameResponse,
} from "api/PageApi";
import PageApi from "api/PageApi";
import type {
CanvasWidgetsReduxState,
FlattenedWidgetProps,
} from "ee/reducers/entityReducers/canvasWidgetsReducer";
import type { CanvasWidgetsReduxState } from "ee/reducers/entityReducers/canvasWidgetsReducer";
import { all, call, put, select, take } from "redux-saga/effects";
import history from "utils/history";
import { isNameValid } from "utils/helpers";
@ -152,6 +149,7 @@ import {
selectGitApplicationCurrentBranch,
} from "selectors/gitModSelectors";
import { appsmithTelemetry } from "instrumentation";
import { getLayoutSavePayload } from "ee/sagas/helpers";
export interface HandleWidgetNameUpdatePayload {
newName: string;
@ -479,7 +477,8 @@ export function* savePageSaga(action: ReduxAction<{ isRetry?: boolean }>) {
if (!editorConfigs) return;
const savePageRequest: SavePageRequest = getLayoutSavePayload(
const savePageRequest: SavePageRequest = yield call(
getLayoutSavePayload,
widgets,
editorConfigs,
);
@ -633,22 +632,6 @@ export function* saveAllPagesSaga(pageLayouts: PageLayoutsRequest[]) {
}
}
export function getLayoutSavePayload(
widgets: {
[widgetId: string]: FlattenedWidgetProps;
},
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
editorConfigs: any,
) {
const nestedDSL = nestDSL(widgets, Object.keys(widgets)[0]);
return {
...editorConfigs,
dsl: nestedDSL,
};
}
export function* saveLayoutSaga(action: ReduxAction<{ isRetry?: boolean }>) {
try {
const currentPageId: string = yield select(getCurrentPageId);

View File

@ -10,6 +10,7 @@ import { TEMP_DATASOURCE_ID } from "constants/Datasource";
import type { getConfigInitialValues } from "components/formControls/utils";
import type { CreateDatasourceConfig } from "ee/api/DatasourcesApi";
import type { Datasource } from "entities/Datasource";
import { nestDSL, type FlattenedDSL } from "@shared/dsl/src/transform";
export interface ResolveParentEntityMetadataReturnType {
parentEntityId?: string;
@ -96,3 +97,16 @@ export const createDatasourceAPIPayloadFromAction = (
return payload;
};
// This function is extended in EE for UI modules
export function* getLayoutSavePayload(
widgets: FlattenedDSL<unknown>,
editorConfigs: Record<string, unknown>,
) {
const nestedDSL = nestDSL(widgets, Object.keys(widgets)[0]);
return {
...editorConfigs,
dsl: nestedDSL,
};
}

View File

@ -1844,3 +1844,7 @@ export const getUpcomingPlugins = createSelector(
export const getCurrentPageDSLVersion = (state: DefaultRootState) => {
return state.entities.canvasWidgets[0]?.version || null;
};
export const getIsSettingUpPage = (state: DefaultRootState) => {
return state.ui.editor.loadingStates.isSettingUpPage;
};

View File

@ -80,6 +80,7 @@ import ArrayControl from "./ArrayControl";
import TableCustomSortControl, {
type TableCustomSortControlProps,
} from "./TableCustomSortControl";
import EEPropertyControls from "ee/components/propertyControls";
export const PropertyControls = {
InputTextControl,
@ -134,6 +135,7 @@ export const PropertyControls = {
PrimaryColumnsControlWDS,
ToolbarButtonListControl,
TableCustomSortControl,
...EEPropertyControls,
};
export type PropertyControlPropsType =

View File

@ -0,0 +1 @@
export default {};

View File

@ -38,6 +38,7 @@ export interface UpdateMetaWidgetPropertyPayload {
updates: BatchPropertyUpdatePayload;
widgetId: string;
creatorId?: string;
computeDynamicPaths?: boolean;
}
export interface DeleteMetaWidgetsPayload {

View File

@ -52,6 +52,7 @@ import {
getCurrentBasePageId,
getIsAutoLayout,
getIsAutoLayoutMobileBreakPoint,
getMetaWidgets,
} from "selectors/editorSelectors";
import { convertToString } from "utils/AppsmithUtils";
import type { DynamicPath } from "utils/DynamicBindingUtils";
@ -166,6 +167,8 @@ import { LayoutSystemTypes } from "layoutSystems/types";
import { getLayoutSystemType } from "selectors/layoutSystemSelectors";
import localStorage from "utils/localStorage";
import { getNewPositions } from "./PasteWidgetUtils";
import type { UpdateMetaWidgetPropertyPayload } from "reducers/entityReducers/metaWidgetsReducer";
import { modifyMetaWidgets } from "actions/metaWidgetActions";
export function* resizeSaga(resizeAction: ReduxAction<WidgetResize>) {
try {
@ -728,16 +731,29 @@ export function* getIsContainerLikeWidget(widget: FlattenedWidgetProps) {
export function* getPropertiesUpdatedWidget(
updatesObj: UpdateWidgetPropertyPayload,
) {
const { dynamicUpdates, updates, widgetId } = updatesObj;
const { modify = {}, postUpdateAction, remove = [], triggerPaths } = updates;
const { widgetId } = updatesObj;
const stateWidget: WidgetProps = yield select(getWidget, widgetId);
// if there is no widget in the state, don't do anything
if (!stateWidget) return;
let widget = cloneDeep(stateWidget);
const widget = cloneDeep(stateWidget);
const result: {
updatedWidget: WidgetProps;
actionToDispatch?: ReduxActionType;
} = yield call(computeWidgetProperties, widget, updatesObj);
return result;
}
function* computeWidgetProperties(
widget: WidgetProps,
updatesObj: UpdateWidgetPropertyPayload,
) {
const { dynamicUpdates, updates } = updatesObj;
const { modify = {}, postUpdateAction, remove = [], triggerPaths } = updates;
try {
if (Object.keys(modify).length > 0) {
@ -1997,6 +2013,49 @@ function* shouldCallSaga(saga: any, action: ReduxAction<unknown>) {
}
}
function* updateMetaWidgetPropertySaga(
action: ReduxAction<UpdateMetaWidgetPropertyPayload>,
) {
try {
if (action.payload.computeDynamicPaths) {
const metaWidgets: Record<string, WidgetProps> =
yield select(getMetaWidgets);
const updatedWidgetAndActionsToDispatch: {
updatedWidget: WidgetProps;
} = yield call(
computeWidgetProperties,
metaWidgets[action.payload.widgetId],
{
widgetId: action.payload.widgetId,
updates: action.payload.updates,
},
);
yield put(
modifyMetaWidgets({
addOrUpdate: {
[action.payload.widgetId]:
updatedWidgetAndActionsToDispatch.updatedWidget,
},
deleteIds: [],
creatorId: action.payload.creatorId,
}),
);
} else {
yield put({
type: ReduxActionTypes.UPDATE_META_WIDGET_PROPERTY,
payload: action.payload,
});
}
} catch (error) {
log.error(error);
yield put({
type: ReduxActionTypes.UPDATE_META_WIDGET_PROPERTY,
payload: action.payload,
});
}
}
export default function* widgetOperationSagas() {
yield fork(widgetAdditionSagas);
yield fork(widgetDeletionSagas);
@ -2051,5 +2110,9 @@ export default function* widgetOperationSagas() {
takeEvery(ReduxActionTypes.GROUP_WIDGETS_INIT, groupWidgetsSaga),
takeEvery(ReduxActionTypes.PARTIAL_IMPORT_INIT, partialImportSaga),
takeEvery(ReduxActionTypes.PARTIAL_EXPORT_INIT, partialExportSaga),
takeEvery(
ReduxActionTypes.UPDATE_META_WIDGET_PROPERTY_INIT,
updateMetaWidgetPropertySaga,
),
]);
}

View File

@ -1,4 +1,5 @@
import type { ReduxAction } from "actions/ReduxActionTypes";
import log from "loglevel";
import { create } from "mutative";
export const createReducer = (
@ -35,11 +36,15 @@ export const createImmerReducer = (
if (action?.payload?.updates) {
const updates = action?.payload?.updates;
try {
for (const update of updates) {
if (update.kind === "newTree") {
return update.rhs;
}
}
} catch (e) {
log.error(e);
}
}
const fn = handlers[action.type];

View File

@ -3066,6 +3066,7 @@ class TableWidgetV2 extends BaseWidget<TableWidgetProps, WidgetState> {
resetTableForInfiniteScroll = () => {
resetWidget(this.props.widgetId, false);
this.updatePageNumber(0, EventType.ON_NEXT_PAGE);
};
}

View File

@ -2781,8 +2781,7 @@ public class CentralGitServiceCEImpl implements CentralGitServiceCE {
final String baseArtifactId = baseGitMetadata.getDefaultArtifactId();
final String repoName = baseGitMetadata.getRepoName();
// 1. Hydrate from db to git system for both ref Artifacts
// Update function call
// 1. Hydrate from db to a git system for both branch artifacts
return Mono.usingWhen(
gitRedisUtils.acquireGitLock(
artifactType, baseArtifactId, GitConstants.GitCommandConstants.MERGE_BRANCH, TRUE),

View File

@ -770,11 +770,18 @@ public class GitFSServiceCEImpl implements GitHandlingServiceCE {
jsonTransformationDTO.getBaseArtifactId(),
jsonTransformationDTO.getRepoName());
// TODO: add the checkout to the current branch as well.
return fsGitHandler.checkoutToBranch(repoSuffix, baseRefName).flatMap(isCheckedOut -> fsGitHandler
return fsGitHandler
.resetToLastCommit(repoSuffix)
.then(fsGitHandler.checkoutToBranch(repoSuffix, baseRefName))
.flatMap(isCheckedOut -> fsGitHandler
.createAndCheckoutReference(repoSuffix, gitRefDTO)
.flatMap(newRef -> fsGitHandler.pushArtifact(
repoSuffix, remoteUrl, publicKey, privateKey, gitRefDTO.getRefName(), incomingRefType)));
repoSuffix,
remoteUrl,
publicKey,
privateKey,
gitRefDTO.getRefName(),
incomingRefType)));
}
@Override
@ -787,7 +794,9 @@ public class GitFSServiceCEImpl implements GitHandlingServiceCE {
jsonTransformationDTO.getBaseArtifactId(),
jsonTransformationDTO.getRepoName());
return fsGitHandler.checkoutRemoteBranch(repoSuffix, jsonTransformationDTO.getRefName());
return fsGitHandler
.resetToLastCommit(repoSuffix)
.then(fsGitHandler.checkoutRemoteBranch(repoSuffix, jsonTransformationDTO.getRefName()));
}
@Override

View File

@ -64,6 +64,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@ -408,14 +409,16 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE {
}
applicationJson.getActionList().forEach(action -> {
action.getPublishedAction().setPageId(pageName);
action.getUnpublishedAction().setPageId(pageName);
if (Objects.nonNull(action.getPublishedAction())) {
action.getPublishedAction().setPageId(pageName);
if (action.getPublishedAction().getCollectionId() != null) {
String collectionName =
action.getPublishedAction().getCollectionId().split("_")[1];
action.getPublishedAction().setCollectionId(pageName + "_" + collectionName);
action.getUnpublishedAction().setCollectionId(pageName + "_" + collectionName);
}
}
String actionName = action.getId().split("_")[1];
action.setId(pageName + "_" + actionName);