diff --git a/app/client/src/actions/metaWidgetActions.ts b/app/client/src/actions/metaWidgetActions.ts index d469117114..5bb0c626a5 100644 --- a/app/client/src/actions/metaWidgetActions.ts +++ b/app/client/src/actions/metaWidgetActions.ts @@ -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, }); diff --git a/app/client/src/ce/constants/ReduxActionConstants.tsx b/app/client/src/ce/constants/ReduxActionConstants.tsx index 0a5c7a7ab3..d589f39f10 100644 --- a/app/client/src/ce/constants/ReduxActionConstants.tsx +++ b/app/client/src/ce/constants/ReduxActionConstants.tsx @@ -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", diff --git a/app/client/src/ce/reducers/uiReducers/editorReducer.tsx b/app/client/src/ce/reducers/uiReducers/editorReducer.tsx index 9fc850c6db..573b00b1ac 100644 --- a/app/client/src/ce/reducers/uiReducers/editorReducer.tsx +++ b/app/client/src/ce/reducers/uiReducers/editorReducer.tsx @@ -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; }; } diff --git a/app/client/src/ce/sagas/PageSagas.tsx b/app/client/src/ce/sagas/PageSagas.tsx index ac46d79660..145635ac0a 100644 --- a/app/client/src/ce/sagas/PageSagas.tsx +++ b/app/client/src/ce/sagas/PageSagas.tsx @@ -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); diff --git a/app/client/src/ce/sagas/helpers.ts b/app/client/src/ce/sagas/helpers.ts index ecc2cf2097..555fa1d837 100644 --- a/app/client/src/ce/sagas/helpers.ts +++ b/app/client/src/ce/sagas/helpers.ts @@ -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, + editorConfigs: Record, +) { + const nestedDSL = nestDSL(widgets, Object.keys(widgets)[0]); + + return { + ...editorConfigs, + dsl: nestedDSL, + }; +} diff --git a/app/client/src/ce/selectors/entitiesSelector.ts b/app/client/src/ce/selectors/entitiesSelector.ts index ee67114afb..e1dfde4815 100644 --- a/app/client/src/ce/selectors/entitiesSelector.ts +++ b/app/client/src/ce/selectors/entitiesSelector.ts @@ -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; +}; diff --git a/app/client/src/components/propertyControls/index.ts b/app/client/src/components/propertyControls/index.ts index 3915385606..ef44f1f97c 100644 --- a/app/client/src/components/propertyControls/index.ts +++ b/app/client/src/components/propertyControls/index.ts @@ -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 = diff --git a/app/client/src/ee/components/propertyControls/index.ts b/app/client/src/ee/components/propertyControls/index.ts new file mode 100644 index 0000000000..ff8b4c5632 --- /dev/null +++ b/app/client/src/ee/components/propertyControls/index.ts @@ -0,0 +1 @@ +export default {}; diff --git a/app/client/src/reducers/entityReducers/metaWidgetsReducer.ts b/app/client/src/reducers/entityReducers/metaWidgetsReducer.ts index f30155a93b..3d803bd5da 100644 --- a/app/client/src/reducers/entityReducers/metaWidgetsReducer.ts +++ b/app/client/src/reducers/entityReducers/metaWidgetsReducer.ts @@ -38,6 +38,7 @@ export interface UpdateMetaWidgetPropertyPayload { updates: BatchPropertyUpdatePayload; widgetId: string; creatorId?: string; + computeDynamicPaths?: boolean; } export interface DeleteMetaWidgetsPayload { diff --git a/app/client/src/sagas/WidgetOperationSagas.tsx b/app/client/src/sagas/WidgetOperationSagas.tsx index 7f6b1301ec..def61a0b66 100644 --- a/app/client/src/sagas/WidgetOperationSagas.tsx +++ b/app/client/src/sagas/WidgetOperationSagas.tsx @@ -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) { 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) { } } +function* updateMetaWidgetPropertySaga( + action: ReduxAction, +) { + try { + if (action.payload.computeDynamicPaths) { + const metaWidgets: Record = + 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, + ), ]); } diff --git a/app/client/src/utils/ReducerUtils.ts b/app/client/src/utils/ReducerUtils.ts index 9a492352b8..fe17b26de7 100644 --- a/app/client/src/utils/ReducerUtils.ts +++ b/app/client/src/utils/ReducerUtils.ts @@ -1,4 +1,5 @@ import type { ReduxAction } from "actions/ReduxActionTypes"; +import log from "loglevel"; import { create } from "mutative"; export const createReducer = ( @@ -35,10 +36,14 @@ export const createImmerReducer = ( if (action?.payload?.updates) { const updates = action?.payload?.updates; - for (const update of updates) { - if (update.kind === "newTree") { - return update.rhs; + try { + for (const update of updates) { + if (update.kind === "newTree") { + return update.rhs; + } } + } catch (e) { + log.error(e); } } diff --git a/app/client/src/widgets/TableWidgetV2/widget/index.tsx b/app/client/src/widgets/TableWidgetV2/widget/index.tsx index 6b3c490122..1f6b595061 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/index.tsx +++ b/app/client/src/widgets/TableWidgetV2/widget/index.tsx @@ -3066,6 +3066,7 @@ class TableWidgetV2 extends BaseWidget { resetTableForInfiniteScroll = () => { resetWidget(this.props.widgetId, false); + this.updatePageNumber(0, EventType.ON_NEXT_PAGE); }; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java index d7bfc5961f..561a35b6f1 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java @@ -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), diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/fs/GitFSServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/fs/GitFSServiceCEImpl.java index d87615a1c0..6a5c40bab9 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/fs/GitFSServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/fs/GitFSServiceCEImpl.java @@ -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 - .createAndCheckoutReference(repoSuffix, gitRefDTO) - .flatMap(newRef -> fsGitHandler.pushArtifact( - repoSuffix, remoteUrl, publicKey, privateKey, gitRefDTO.getRefName(), incomingRefType))); + 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))); } @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 diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java index 181068f83a..1ebdd50953 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCEImpl.java @@ -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,13 +409,15 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { } applicationJson.getActionList().forEach(action -> { - action.getPublishedAction().setPageId(pageName); action.getUnpublishedAction().setPageId(pageName); - if (action.getPublishedAction().getCollectionId() != null) { - String collectionName = - action.getPublishedAction().getCollectionId().split("_")[1]; - action.getPublishedAction().setCollectionId(pageName + "_" + collectionName); - action.getUnpublishedAction().setCollectionId(pageName + "_" + collectionName); + 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];