diff --git a/app/client/cypress/e2e/Regression/ClientSide/Git/GitSync/MergeViaRemote_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Git/GitSync/MergeViaRemote_spec.ts index b93ce987a4..10cf74d2fd 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Git/GitSync/MergeViaRemote_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Git/GitSync/MergeViaRemote_spec.ts @@ -88,8 +88,8 @@ describe( cy.wait("@getConsolidatedData").then((intercept2) => { const { application, pages } = intercept2.response.body.data.pages.data; const defaultPage = pages.find((p) => p.isDefault); - legacyPathname = `/applications/${application.id}/pages/${defaultPage.id}`; - newPathname = `/app/${application.slug}/${defaultPage.slug}-${defaultPage.id}`; + legacyPathname = `/applications/${application.baseId}/pages/${defaultPage.baseId}`; + newPathname = `/app/${application.slug}/${defaultPage.slug}-${defaultPage.baseId}`; }); cy.location().should((location) => { diff --git a/app/client/cypress/e2e/Regression/ClientSide/ProductRamps/PrivateEmbedRamp_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/ProductRamps/PrivateEmbedRamp_spec.ts index 0f339abc88..d2888bd5f2 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/ProductRamps/PrivateEmbedRamp_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/ProductRamps/PrivateEmbedRamp_spec.ts @@ -62,11 +62,13 @@ describe("Private embed in-app ramp", { tags: ["@tag.Settings"] }, () => { featureFlagIntercept({ license_private_embeds_enabled: false, }); + _.agHelper.WaitUntilEleAppear("[data-testid=t--canvas-artboard]"); _.inviteModal.OpenShareModal(); checkRampTextInShareModal(); featureFlagIntercept({ license_private_embeds_enabled: true, }); + _.agHelper.WaitUntilEleAppear("[data-testid=t--canvas-artboard]"); _.inviteModal.OpenShareModal(); _.agHelper.AssertElementAbsence( _.inviteModal.locators._privateEmbedRampAppSettings, diff --git a/app/client/src/actions/apiPaneActions.ts b/app/client/src/actions/apiPaneActions.ts index 6d6a2dff92..bbecfbf484 100644 --- a/app/client/src/actions/apiPaneActions.ts +++ b/app/client/src/actions/apiPaneActions.ts @@ -47,17 +47,6 @@ export const updateBodyContentType = ( payload: { title, apiId }, }); -export const redirectToNewIntegrations = ( - pageId: string, - params?: any, -): ReduxAction<{ - pageId: string; - params: any; -}> => ({ - type: ReduxActionTypes.REDIRECT_TO_NEW_INTEGRATIONS, - payload: { pageId, params }, -}); - export const executeCommandAction = (payload: SlashCommandPayload) => ({ type: ReduxActionTypes.EXECUTE_COMMAND, payload: payload, diff --git a/app/client/src/actions/initActions.ts b/app/client/src/actions/initActions.ts index 4f83f7e067..b45f225c36 100644 --- a/app/client/src/actions/initActions.ts +++ b/app/client/src/actions/initActions.ts @@ -8,41 +8,41 @@ export const initCurrentPage = () => { }; }; -export interface InitializeEditorPayload { - applicationId?: string; - pageId?: string; +export interface InitEditorActionPayload { + baseApplicationId?: string; + basePageId?: string; branch?: string; mode: APP_MODE; shouldInitialiseUserDetails?: boolean; } -export const initEditor = ( - payload: InitializeEditorPayload, -): ReduxAction => ({ +export const initEditorAction = ( + payload: InitEditorActionPayload, +): ReduxAction => ({ type: ReduxActionTypes.INITIALIZE_EDITOR, payload, }); export interface InitAppViewerPayload { branch: string; - applicationId?: string; - pageId: string; + baseApplicationId?: string; + basePageId: string; mode: APP_MODE; shouldInitialiseUserDetails?: boolean; } -export const initAppViewer = ({ - applicationId, +export const initAppViewerAction = ({ + baseApplicationId, + basePageId, branch, mode, - pageId, shouldInitialiseUserDetails, }: InitAppViewerPayload) => ({ type: ReduxActionTypes.INITIALIZE_PAGE_VIEWER, payload: { branch: branch, - applicationId, - pageId, + baseApplicationId, + basePageId, mode, shouldInitialiseUserDetails, }, diff --git a/app/client/src/actions/onboardingActions.ts b/app/client/src/actions/onboardingActions.ts index 35c64f20f8..c0dfbf2f4b 100644 --- a/app/client/src/actions/onboardingActions.ts +++ b/app/client/src/actions/onboardingActions.ts @@ -32,14 +32,14 @@ export const disableStartSignpostingAction = () => { export const firstTimeUserOnboardingInit = ( applicationId: string | undefined, - pageId: string, + basePageId: string, suffix?: string, ) => { return { type: ReduxActionTypes.FIRST_TIME_USER_ONBOARDING_INIT, payload: { - applicationId: applicationId, - pageId: pageId, + applicationId, + basePageId, suffix, }, }; diff --git a/app/client/src/actions/pageActions.tsx b/app/client/src/actions/pageActions.tsx index 52a211679f..6a4a4c84a2 100644 --- a/app/client/src/actions/pageActions.tsx +++ b/app/client/src/actions/pageActions.tsx @@ -4,6 +4,7 @@ import type { ReduxAction, UpdateCanvasPayload, AnyReduxAction, + ClonePageSuccessPayload, } from "@appsmith/constants/ReduxActionConstants"; import { ReduxActionTypes, @@ -15,7 +16,6 @@ import type { DynamicPath } from "utils/DynamicBindingUtils"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import type { WidgetOperation } from "widgets/BaseWidget"; import type { - FetchPageRequest, FetchPageResponse, PageLayout, SavePageResponse, @@ -25,7 +25,6 @@ import type { import type { UrlDataState } from "reducers/entityReducers/appReducer"; import type { APP_MODE } from "entities/App"; import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer"; -import type { GenerateTemplatePageRequest } from "api/PageApi"; import type { ENTITY_TYPE } from "@appsmith/entities/AppsmithConsole/utils"; import type { Replayable } from "entities/Replay/ReplayEntity/ReplayEditor"; import * as Sentry from "@sentry/react"; @@ -35,28 +34,23 @@ export interface FetchPageListPayload { mode: APP_MODE; } -export interface ClonePageActionPayload { - id: string; - blockNavigation?: boolean; -} - -export interface CreatePageActionPayload { - applicationId: string; - name: string; - layouts: Partial[]; -} - export interface updateLayoutOptions { isRetry?: boolean; shouldReplay?: boolean; updatedWidgetIds?: string[]; } -export const fetchPage = ( +export interface FetchPageActionPayload { + id: string; + isFirstLoad?: boolean; + pageWithMigratedDsl?: FetchPageResponse; +} + +export const fetchPageAction = ( pageId: string, isFirstLoad = false, pageWithMigratedDsl?: FetchPageResponse, -): ReduxAction => { +): ReduxAction => { return { type: ReduxActionTypes.FETCH_PAGE_INIT, payload: { @@ -67,12 +61,20 @@ export const fetchPage = ( }; }; -export const fetchPublishedPage = ( +// fetch a published page +export interface FetchPublishedPageActionPayload { + pageId: string; + bustCache?: boolean; + firstLoad?: boolean; + pageWithMigratedDsl?: FetchPageResponse; +} + +export const fetchPublishedPageAction = ( pageId: string, bustCache = false, firstLoad = false, pageWithMigratedDsl?: FetchPageResponse, -) => ({ +): ReduxAction => ({ type: ReduxActionTypes.FETCH_PUBLISHED_PAGE_INIT, payload: { pageId, @@ -110,11 +112,17 @@ export const fetchAllPageEntityCompletion = ( payload: undefined, }); +export interface UpdateCurrentPagePayload { + id: string; + slug?: string; + permissions?: string[]; +} + export const updateCurrentPage = ( id: string, slug?: string, permissions?: string[], -) => ({ +): ReduxAction => ({ type: ReduxActionTypes.SWITCH_CURRENT_PAGE_ID, payload: { id, slug, permissions }, }); @@ -170,7 +178,13 @@ export const saveLayout = (isRetry?: boolean) => { }; }; -export const createPage = ( +export interface CreatePageActionPayload { + applicationId: string; + name: string; + layouts: Partial[]; +} + +export const createPageAction = ( applicationId: string, pageName: string, layouts: Partial[], @@ -212,14 +226,16 @@ export const createNewPageFromEntities = ( }; }; -/** - * action to clone page - * - * @param pageId - * @param blockNavigation - * @returns - */ -export const clonePageInit = (pageId: string, blockNavigation?: boolean) => { +// cloning a page +export interface ClonePageActionPayload { + id: string; + blockNavigation?: boolean; +} + +export const clonePageInit = ( + pageId: string, + blockNavigation?: boolean, +): ReduxAction => { return { type: ReduxActionTypes.CLONE_PAGE_INIT, payload: { @@ -229,24 +245,37 @@ export const clonePageInit = (pageId: string, blockNavigation?: boolean) => { }; }; -export const clonePageSuccess = ( - pageId: string, - pageName: string, - layoutId: string, - pageSlug: string, -) => { +export const clonePageSuccess = ({ + basePageId, + layoutId, + pageId, + pageName, + slug, +}: ClonePageSuccessPayload) => { return { type: ReduxActionTypes.CLONE_PAGE_SUCCESS, payload: { pageId, + basePageId, pageName, layoutId, - pageSlug, + slug, }, }; }; -export const updatePage = (payload: UpdatePageRequest) => { +// update a page + +export interface UpdatePageActionPayload { + id: string; + name?: string; + isHidden?: boolean; + customSlug?: string; +} + +export const updatePageAction = ( + payload: UpdatePageActionPayload, +): ReduxAction => { // Update page *needs* id to be there. We found certain scenarios // where this was not happening and capturing the error to know gather // more info: https://github.com/appsmithorg/appsmith/issues/16435 @@ -408,6 +437,7 @@ export interface GenerateCRUDSuccess { page: { layouts: Array; id: string; + baseId: string; name: string; isDefault?: boolean; slug: string; @@ -429,6 +459,17 @@ export const generateTemplateError = () => { }; }; +export interface GenerateTemplatePageActionPayload { + pageId: string; + tableName: string; + datasourceId: string; + applicationId: string; + columns?: string[]; + searchColumn?: string; + mode?: string; + pluginSpecificParams?: Record; +} + export const generateTemplateToUpdatePage = ({ applicationId, columns, @@ -438,7 +479,7 @@ export const generateTemplateToUpdatePage = ({ pluginSpecificParams, searchColumn, tableName, -}: GenerateTemplatePageRequest): ReduxActionWithExtraParams => { +}: GenerateTemplatePageActionPayload): ReduxActionWithExtraParams => { return { type: ReduxActionTypes.GENERATE_TEMPLATE_PAGE_INIT, payload: { @@ -485,14 +526,15 @@ export function redoAction() { }; } -/** - * action for delete page - * - * @param pageId - * @param pageName - * @returns - */ -export const deletePage = (pageId: string) => { +// delete a page + +export interface DeletePageActionPayload { + id: string; +} + +export const deletePageAction = ( + pageId: string, +): ReduxAction => { return { type: ReduxActionTypes.DELETE_PAGE_INIT, payload: { @@ -501,14 +543,15 @@ export const deletePage = (pageId: string) => { }; }; -/** - * action for set page as default - * - * @param pageId - * @param applicationId - * @returns - */ -export const setPageAsDefault = (pageId: string, applicationId?: string) => { +export interface SetDefaultPageActionPayload { + id: string; + applicationId: string; +} + +export const setPageAsDefault = ( + pageId: string, + applicationId: string, +): ReduxAction => { return { type: ReduxActionTypes.SET_DEFAULT_APPLICATION_PAGE_INIT, payload: { @@ -518,18 +561,17 @@ export const setPageAsDefault = (pageId: string, applicationId?: string) => { }; }; -/** - * action for updating order of a page - * - * @param pageId - * @param applicationId - * @returns - */ +export interface SetPageOrderActionPayload { + pageId: string; + order: number; + applicationId: string; +} + export const setPageOrder = ( applicationId: string, pageId: string, order: number, -) => { +): ReduxAction => { return { type: ReduxActionTypes.SET_PAGE_ORDER_INIT, payload: { @@ -552,12 +594,17 @@ export const fetchPageDSLs = (payload?: any) => ({ type: ReduxActionTypes.POPULATE_PAGEDSLS_INIT, payload, }); +export interface SetupPageActionPayload { + id: string; + isFirstLoad?: boolean; + pageWithMigratedDsl?: FetchPageResponse; +} -export const setupPage = ( +export const setupPageAction = ( pageId: string, isFirstLoad = false, pageWithMigratedDsl?: FetchPageResponse, -): ReduxAction => ({ +): ReduxAction => ({ type: ReduxActionTypes.SETUP_PAGE_INIT, payload: { id: pageId, @@ -566,12 +613,19 @@ export const setupPage = ( }, }); +export interface SetupPublishedPageActionPayload { + pageId: string; + bustCache: boolean; + firstLoad: boolean; + pageWithMigratedDsl?: FetchPageResponse; +} + export const setupPublishedPage = ( pageId: string, bustCache = false, firstLoad = false, pageWithMigratedDsl?: FetchPageResponse, -) => ({ +): ReduxAction => ({ type: ReduxActionTypes.SETUP_PUBLISHED_PAGE_INIT, payload: { pageId, diff --git a/app/client/src/actions/pluginActionActions.ts b/app/client/src/actions/pluginActionActions.ts index afc6224389..f91db8686a 100644 --- a/app/client/src/actions/pluginActionActions.ts +++ b/app/client/src/actions/pluginActionActions.ts @@ -250,6 +250,7 @@ export const executePluginActionRequest = (payload: { id: string }) => ({ export interface ExecutePluginActionSuccessPayload { id: string; + baseId: string; response: ActionResponse; isPageLoad?: boolean; isActionCreatedInApp: boolean; @@ -364,7 +365,7 @@ export const setJSActionsToExecuteOnPageLoad = ( export const bindDataOnCanvas = (payload: { queryId: string; applicationId: string; - pageId: string; + basePageId: string; }) => { return { type: ReduxActionTypes.BIND_DATA_ON_CANVAS, diff --git a/app/client/src/actions/queryPaneActions.ts b/app/client/src/actions/queryPaneActions.ts index 7bfe58cc56..274f5d3944 100644 --- a/app/client/src/actions/queryPaneActions.ts +++ b/app/client/src/actions/queryPaneActions.ts @@ -4,10 +4,10 @@ import type { Action } from "entities/Action"; import type { QueryPaneDebuggerState } from "@appsmith/reducers/uiReducers/queryPaneReducer"; export interface ChangeQueryPayload { - id: string; + baseQueryId: string; packageId?: string; applicationId?: string; - pageId?: string; + basePageId?: string; moduleId?: string; workflowId?: string; newQuery?: boolean; diff --git a/app/client/src/actions/widgetSelectionActions.ts b/app/client/src/actions/widgetSelectionActions.ts index 2f3f83a26b..f6863ecd36 100644 --- a/app/client/src/actions/widgetSelectionActions.ts +++ b/app/client/src/actions/widgetSelectionActions.ts @@ -7,14 +7,14 @@ export interface WidgetSelectionRequestPayload { selectionRequestType: SelectionRequestType; payload?: string[]; invokedBy?: NavigationMethod; - pageId?: string; + basePageId?: string; } export type WidgetSelectionRequest = ( selectionRequestType: SelectionRequestType, payload?: string[], invokedBy?: NavigationMethod, - pageId?: string, + basePageId?: string, ) => ReduxAction; // Use to select a widget programmatically via platform action @@ -22,10 +22,10 @@ export const selectWidgetInitAction: WidgetSelectionRequest = ( selectionRequestType, payload, invokedBy?: NavigationMethod, - pageId?: string, + basePageId?: string, ) => ({ type: ReduxActionTypes.SELECT_WIDGET_INIT, - payload: { selectionRequestType, payload, pageId, invokedBy }, + payload: { selectionRequestType, payload, basePageId, invokedBy }, }); export interface SetSelectedWidgetsPayload { diff --git a/app/client/src/api/ActionAPI.tsx b/app/client/src/api/ActionAPI.tsx index 5097ac4efa..debfa333ee 100644 --- a/app/client/src/api/ActionAPI.tsx +++ b/app/client/src/api/ActionAPI.tsx @@ -19,6 +19,7 @@ export interface Property { export type ActionCreateUpdateResponse = ApiResponse & { id: string; + baseId: string; jsonPathKeys: Record; datasource: { id?: string; diff --git a/app/client/src/api/GitSyncAPI.tsx b/app/client/src/api/GitSyncAPI.tsx index 22509b3041..d46b56374f 100644 --- a/app/client/src/api/GitSyncAPI.tsx +++ b/app/client/src/api/GitSyncAPI.tsx @@ -8,7 +8,6 @@ export interface CommitPayload { applicationId: string; commitMessage: string; doPush: boolean; - branch: string; } export interface MergeBranchPayload { @@ -34,15 +33,9 @@ export interface ConnectToGitPayload { interface GitStatusParam { applicationId: string; - branch: string; compareRemote: boolean; } -interface GitRemoteStatusParam { - applicationId: string; - branch: string; -} - export enum AutocommitResponseEnum { IN_PROGRESS = "IN_PROGRESS", LOCKED = "LOCKED", @@ -69,17 +62,13 @@ class GitSyncAPI extends Api { static async commit({ applicationId, - branch, commitMessage, doPush, }: CommitPayload): Promise> { - return Api.post( - `${GitSyncAPI.baseURL}/commit/app/${applicationId}?branchName=${branch}`, - { - commitMessage, - doPush, - }, - ); + return Api.post(`${GitSyncAPI.baseURL}/commit/app/${applicationId}`, { + commitMessage, + doPush, + }); } static async merge({ @@ -108,9 +97,12 @@ class GitSyncAPI extends Api { return Api.get(`${GitSyncAPI.baseURL}/pull/app/${applicationId}`); } - static async connect(payload: ConnectToGitPayload, applicationId: string) { + static async connect( + payload: ConnectToGitPayload, + baseApplicationId: string, + ) { return Api.post( - `${GitSyncAPI.baseURL}/connect/app/${applicationId}`, + `${GitSyncAPI.baseURL}/connect/app/${baseApplicationId}`, payload, ); } @@ -150,70 +142,60 @@ class GitSyncAPI extends Api { ); } - static async getLocalConfig(applicationId: string) { - return Api.get(`${GitSyncAPI.baseURL}/profile/app/${applicationId}`); + static async getLocalConfig(baseApplicationId: string) { + return Api.get(`${GitSyncAPI.baseURL}/profile/app/${baseApplicationId}`); } - static async setLocalConfig(payload: GitConfig, applicationId: string) { + static async setLocalConfig(payload: GitConfig, baseApplicationId: string) { return Api.put( - `${GitSyncAPI.baseURL}/profile/app/${applicationId}`, + `${GitSyncAPI.baseURL}/profile/app/${baseApplicationId}`, payload, ); } static async getGitStatus({ applicationId, - branch, compareRemote = true, }: GitStatusParam) { - return Api.get( - `${GitSyncAPI.baseURL}/status/app/${applicationId}`, - { compareRemote }, - { headers: { branchName: branch } }, - ); + return Api.get(`${GitSyncAPI.baseURL}/status/app/${applicationId}`, { + compareRemote, + }); } - static async getGitRemoteStatus({ - applicationId, - branch, - }: GitRemoteStatusParam) { - return Api.get( - `${GitSyncAPI.baseURL}/fetch/remote/app/${applicationId}`, - {}, - { headers: { branchName: branch } }, + static async revokeGit(baseApplicationId: string) { + return Api.post( + `${GitSyncAPI.baseURL}/disconnect/app/${baseApplicationId}`, ); } - static async revokeGit({ applicationId }: { applicationId: string }) { - return Api.post(`${GitSyncAPI.baseURL}/disconnect/app/${applicationId}`); - } - static async importApp(payload: ConnectToGitPayload, workspaceId: string) { return Api.post(`${GitSyncAPI.baseURL}/import/${workspaceId}`, payload); } static async getSSHKeyPair( - applicationId: string, + baseApplicationId: string, ): Promise> { - return Api.get(ApplicationApi.baseURL + "/ssh-keypair/" + applicationId); + return Api.get( + ApplicationApi.baseURL + "/ssh-keypair/" + baseApplicationId, + ); } static async generateSSHKeyPair( - applicationId: string, + baseApplicationId: string, keyType: string, isImporting?: boolean, ): Promise> { const url = isImporting ? `v1/git/import/keys?keyType=${keyType}` - : `${ApplicationApi.baseURL}/ssh-keypair/${applicationId}?keyType=${keyType}`; + : `${ApplicationApi.baseURL}/ssh-keypair/${baseApplicationId}?keyType=${keyType}`; return isImporting ? Api.get(url) : Api.post(url); } static async deleteBranch( - applicationId: string, + baseApplicationId: string, branchName: string, ): Promise> { - return Api.delete(GitSyncAPI.baseURL + "/branch/app/" + applicationId, { + return Api.delete(GitSyncAPI.baseURL + "/branch/app/" + baseApplicationId, { branchName, }); } @@ -222,41 +204,39 @@ class GitSyncAPI extends Api { return Api.put(`${GitSyncAPI.baseURL}/discard/app/${applicationId}`); } - static async getProtectedBranches(applicationId: string) { + static async getProtectedBranches(baseApplicationId: string) { return Api.get( - `${GitSyncAPI.baseURL}/branch/app/${applicationId}/protected`, + `${GitSyncAPI.baseURL}/branch/app/${baseApplicationId}/protected`, ); } static async updateProtectedBranches( - applicationId: string, + baseApplicationId: string, branchNames: string[], ) { return Api.post( - `${GitSyncAPI.baseURL}/branch/app/${applicationId}/protected`, + `${GitSyncAPI.baseURL}/branch/app/${baseApplicationId}/protected`, { branchNames }, ); } - static async getGitMetadata(applicationId: string) { - return Api.get(`${GitSyncAPI.baseURL}/metadata/app/${applicationId}`); + static async getGitMetadata(baseApplicationId: string) { + return Api.get(`${GitSyncAPI.baseURL}/metadata/app/${baseApplicationId}`); } - static async toggleAutocommit(applicationId: string) { + static async toggleAutocommit(baseApplicationId: string) { return Api.patch( - `${GitSyncAPI.baseURL}/auto-commit/toggle/app/${applicationId}`, + `${GitSyncAPI.baseURL}/auto-commit/toggle/app/${baseApplicationId}`, ); } - static async triggerAutocommit(applicationId: string, branchName: string) { - return Api.post( - `${GitSyncAPI.baseURL}/auto-commit/app/${applicationId}?branchName=${branchName}`, - ); + static async triggerAutocommit(applicationId: string) { + return Api.post(`${GitSyncAPI.baseURL}/auto-commit/app/${applicationId}`); } - static async getAutocommitProgress(applicationId: string) { + static async getAutocommitProgress(baseApplicationId: string) { return Api.get( - `${GitSyncAPI.baseURL}/auto-commit/progress/app/${applicationId}`, + `${GitSyncAPI.baseURL}/auto-commit/progress/app/${baseApplicationId}`, ); } } diff --git a/app/client/src/api/PageApi.tsx b/app/client/src/api/PageApi.tsx index 8aeedfac9c..8ed4046f23 100644 --- a/app/client/src/api/PageApi.tsx +++ b/app/client/src/api/PageApi.tsx @@ -7,14 +7,11 @@ import type { PageAction, } from "constants/AppsmithActionConstants/ActionConstants"; import type { DSLWidget } from "WidgetProvider/constants"; -import type { - ClonePageActionPayload, - CreatePageActionPayload, -} from "actions/pageActions"; import type { FetchApplicationResponse } from "@appsmith/api/ApplicationApi"; +import type { APP_MODE } from "entities/App"; export interface FetchPageRequest { - id: string; + pageId: string; isFirstLoad?: boolean; handleResponseLater?: boolean; migrateDSL?: boolean; @@ -51,6 +48,7 @@ export interface PageLayoutsRequest { export interface FetchPageResponseData { id: string; + baseId: string; name: string; slug: string; applicationId: string; @@ -77,13 +75,14 @@ export interface SavePageResponseData { layoutOnLoadActionErrors?: Array; } -export type CreatePageRequest = Omit< - CreatePageActionPayload, - "blockNavigation" ->; +export interface CreatePageRequest { + applicationId: string; + name: string; + layouts: Partial[]; +} export interface UpdatePageRequest { - id: string; + pageId: string; name?: string; isHidden?: boolean; customSlug?: string; @@ -91,6 +90,7 @@ export interface UpdatePageRequest { export interface UpdatePageResponse { id: string; + baseId: string; name: string; slug: string; customSlug?: string; @@ -112,6 +112,7 @@ export type CreatePageResponse = ApiResponse; export interface FetchPageListResponseData { pages: Array<{ id: string; + baseId: string; name: string; isDefault: boolean; isHidden?: boolean; @@ -124,10 +125,12 @@ export interface FetchPageListResponseData { } export interface DeletePageRequest { - id: string; + pageId: string; } -export type ClonePageRequest = Omit; +export interface ClonePageRequest { + pageId: string; +} export interface UpdateWidgetNameRequest { pageId: string; @@ -168,59 +171,41 @@ export type FetchPageResponse = ApiResponse; export type FetchPublishedPageResponse = ApiResponse; +export interface FetchAppAndPagesRequest { + applicationId?: string | null; + pageId?: string | null; + mode: APP_MODE; +} + class PageApi extends Api { static url = "v1/pages"; - static refactorLayoutURL = "v1/layouts/refactor"; static pageUpdateCancelTokenSource?: CancelTokenSource = undefined; - static getLayoutUpdateURL = ( - applicationId: string, - pageId: string, - layoutId: string, - ) => { - return `v1/layouts/${layoutId}/pages/${pageId}?applicationId=${applicationId}`; - }; - - static getGenerateTemplateURL = (pageId?: string) => { - return `${PageApi.url}/crud-page${pageId ? `/${pageId}` : ""}`; - }; static getPublishedPageURL = (pageId: string, bustCache?: boolean) => { const url = `v1/pages/${pageId}/view`; return !!bustCache ? url + "?v=" + +new Date() : url; }; - static getSaveAllPagesURL = (applicationId: string) => { - return `v1/layouts/application/${applicationId}`; - }; - - static updatePageUrl = (pageId: string) => `${PageApi.url}/${pageId}`; - static setPageOrderUrl = ( - applicationId: string, - pageId: string, - order: number, - ) => `v1/applications/${applicationId}/page/${pageId}/reorder?order=${order}`; - static async fetchPage( pageRequest: FetchPageRequest, ): Promise> { const params = { migrateDsl: pageRequest.migrateDSL }; - return Api.get(PageApi.url + "/" + pageRequest.id, undefined, { params }); + return Api.get(PageApi.url + "/" + pageRequest.pageId, undefined, { + params, + }); } static savePage( - savePageRequest: SavePageRequest, + request: SavePageRequest, ): AxiosPromise | undefined { if (PageApi.pageUpdateCancelTokenSource) { PageApi.pageUpdateCancelTokenSource.cancel(); } - const body = { dsl: savePageRequest.dsl }; + const body = { dsl: request.dsl }; PageApi.pageUpdateCancelTokenSource = axios.CancelToken.source(); + const { applicationId, layoutId, pageId } = request; return Api.put( - PageApi.getLayoutUpdateURL( - savePageRequest.applicationId, - savePageRequest.pageId, - savePageRequest.layoutId, - ), + `v1/layouts/${layoutId}/pages/${pageId}?applicationId=${applicationId}`, body, undefined, { cancelToken: PageApi.pageUpdateCancelTokenSource.token }, @@ -231,7 +216,7 @@ class PageApi extends Api { applicationId: string, pageLayouts: PageLayoutsRequest[], ) { - return Api.put(PageApi.getSaveAllPagesURL(applicationId), { + return Api.put(`v1/layouts/application/${applicationId}`, { pageLayouts, }); } @@ -245,78 +230,58 @@ class PageApi extends Api { } static async createPage( - createPageRequest: CreatePageRequest, + request: CreatePageRequest, ): Promise> { - return Api.post(PageApi.url, createPageRequest); + return Api.post(PageApi.url, request); } static async updatePage( request: UpdatePageRequest, ): Promise>> { - return Api.put(PageApi.updatePageUrl(request.id), { - ...request, - id: undefined, - }); + const { pageId, ...rest } = request; + return Api.put(`${PageApi.url}/${pageId}`, rest); } static async generateTemplatePage( request: GenerateTemplatePageRequest, ): Promise> { - const payload = { - ...request, - pageId: undefined, - }; - if (request.pageId) { - return Api.put(PageApi.getGenerateTemplateURL(request.pageId), payload); + const { pageId, ...rest } = request; + if (pageId) { + return Api.put(`${PageApi.url}/crud-page/${pageId}`, rest); } else { - return Api.post(PageApi.getGenerateTemplateURL(), payload); + return Api.post(`${PageApi.url}/crud-page`, rest); } } - static async fetchPageList( - applicationId: string, - ): Promise> { - return Api.get(PageApi.url + "/application/" + applicationId); - } - - static async fetchPageListViewMode( - applicationId: string, - ): Promise> { - return Api.get(PageApi.url + "/view/application/" + applicationId); - } - static async deletePage( request: DeletePageRequest, ): Promise> { - return Api.delete(PageApi.url + "/" + request.id); + return Api.delete(`${PageApi.url}/${request.pageId}`); } static async clonePage( request: ClonePageRequest, - ): Promise> { - return Api.post(PageApi.url + "/clone/" + request.id); + ): Promise> { + return Api.post(`${PageApi.url}/clone/${request.pageId}`); } static async updateWidgetName( request: UpdateWidgetNameRequest, ): Promise> { - return Api.put(PageApi.refactorLayoutURL, request); + return Api.put("v1/layouts/refactor", request); } static async setPageOrder( request: SetPageOrderRequest, ): Promise> { + const { applicationId, order, pageId } = request; return Api.put( - PageApi.setPageOrderUrl( - request.applicationId, - request.pageId, - request.order, - ), + `v1/applications/${applicationId}/page/${pageId}/reorder?order=${order}`, ); } static async fetchAppAndPages( - params: any, + params: FetchAppAndPagesRequest, ): Promise> { return Api.get(PageApi.url, params); } diff --git a/app/client/src/ce/RouteBuilder.ts b/app/client/src/ce/RouteBuilder.ts index 54674eb7b5..785fd518c1 100644 --- a/app/client/src/ce/RouteBuilder.ts +++ b/app/client/src/ce/RouteBuilder.ts @@ -21,11 +21,11 @@ export const fillPathname = ( page: Page, ) => { const replaceValue = page.customSlug - ? getViewerCustomPath(page.customSlug, page.pageId) - : getViewerPath(application.slug, page.slug, page.pageId); + ? getViewerCustomPath(page.customSlug, page.basePageId) + : getViewerPath(application.slug, page.slug, page.basePageId); return pathname.replace( - `/applications/${application.id}/pages/${page.pageId}`, + `/applications/${application.baseId}/pages/${page.basePageId}`, replaceValue, ); }; @@ -54,14 +54,14 @@ export interface WithAddView { export const jsCollectionIdURL = ( props: URLBuilderParams & WithAddView & { - collectionId: string; + baseCollectionId: string; // Pass a function name to set the cursor directly on the function functionName?: string; }, ): string => { return urlBuilder.build({ ...props, - suffix: `jsObjects/${props.collectionId}${props.add ? ADD_PATH : ""}`, + suffix: `jsObjects/${props.baseCollectionId}${props.add ? ADD_PATH : ""}`, hash: props.functionName, }); }; @@ -79,23 +79,23 @@ export const integrationEditorURL = ( export const queryEditorIdURL = ( props: URLBuilderParams & WithAddView & { - queryId: string; + baseQueryId: string; }, ): string => urlBuilder.build({ ...props, - suffix: `queries/${props.queryId}${props.add ? ADD_PATH : ""}`, + suffix: `queries/${props.baseQueryId}${props.add ? ADD_PATH : ""}`, }); export const apiEditorIdURL = ( props: URLBuilderParams & WithAddView & { - apiId: string; + baseApiId: string; }, ): string => urlBuilder.build({ ...props, - suffix: `api/${props.apiId}${props.add ? ADD_PATH : ""}`, + suffix: `api/${props.baseApiId}${props.add ? ADD_PATH : ""}`, }); export const saasEditorDatasourceIdURL = ( @@ -113,12 +113,12 @@ export const saasEditorApiIdURL = ( props: URLBuilderParams & WithAddView & { pluginPackageName: string; - apiId: string; + baseApiId: string; }, ): string => urlBuilder.build({ ...props, - suffix: `saas/${props.pluginPackageName}/api/${props.apiId}${ + suffix: `saas/${props.pluginPackageName}/api/${props.baseApiId}${ props.add ? ADD_PATH : "" }`, }); diff --git a/app/client/src/ce/RouteParamsMiddleware.ts b/app/client/src/ce/RouteParamsMiddleware.ts index ce30cb9e20..da7900c1dc 100644 --- a/app/client/src/ce/RouteParamsMiddleware.ts +++ b/app/client/src/ce/RouteParamsMiddleware.ts @@ -22,13 +22,13 @@ export const handler = (action: ReduxAction) => { const application: ApplicationPayload = action.payload; const { pages } = application; appParams = { - applicationId: application.id, + baseApplicationId: application.baseId, applicationSlug: application.slug, applicationVersion: application.applicationVersion, }; pageParams = pages.map((page) => ({ pageSlug: page.slug, - pageId: page.id, + basePageId: page.baseId, customSlug: page.customSlug, })); break; @@ -38,13 +38,13 @@ export const handler = (action: ReduxAction) => { const application: ApplicationPayload = action.payload.application; const { pages } = application; appParams = { - applicationId: application.id, + baseApplicationId: application.baseId, applicationSlug: application.slug, applicationVersion: application.applicationVersion, }; pageParams = pages.map((page) => ({ pageSlug: page.slug, - pageId: page.id, + basePageId: page.baseId, customSlug: page.customSlug, })); break; @@ -52,7 +52,7 @@ export const handler = (action: ReduxAction) => { case ReduxActionTypes.CURRENT_APPLICATION_NAME_UPDATE: { const application = action.payload; appParams = { - applicationId: application.id, + baseApplicationId: application.baseId, applicationSlug: application.slug, applicationVersion: application.applicationVersion, }; @@ -62,7 +62,7 @@ export const handler = (action: ReduxAction) => { const pages: Page[] = action.payload.pages; pageParams = pages.map((page) => ({ pageSlug: page.slug, - pageId: page.pageId, + basePageId: page.basePageId, customSlug: page.customSlug, })); break; @@ -72,7 +72,7 @@ export const handler = (action: ReduxAction) => { pageParams = [ { pageSlug: page.slug, - pageId: page.id, + basePageId: page.baseId, customSlug: page.customSlug, }, ]; @@ -83,7 +83,7 @@ export const handler = (action: ReduxAction) => { pageParams = [ { pageSlug: page.slug, - pageId: page.pageId, + basePageId: page.basePageId, customSlug: page.customSlug, }, ]; @@ -94,7 +94,7 @@ export const handler = (action: ReduxAction) => { urlBuilder.updateURLParams(null, [ { pageSlug: page.slug, - pageId: page.id, + basePageId: page.baseId, customSlug: page.customSlug, }, ]); @@ -103,16 +103,16 @@ export const handler = (action: ReduxAction) => { case ReduxActionTypes.UPDATE_APPLICATION_SUCCESS: const application = action.payload; appParams = { - applicationId: application.id, + baseApplicationId: application.baseid, applicationSlug: application.slug, applicationVersion: application.applicationVersion, }; break; case ReduxActionTypes.CLONE_PAGE_SUCCESS: - const { pageId, pageSlug } = action.payload; + const { basePageId, pageSlug } = action.payload; pageParams = [ { - pageId, + basePageId, pageSlug, }, ]; diff --git a/app/client/src/ce/api/ApplicationApi.tsx b/app/client/src/ce/api/ApplicationApi.tsx index 7ecb602d18..74782e62a2 100644 --- a/app/client/src/ce/api/ApplicationApi.tsx +++ b/app/client/src/ce/api/ApplicationApi.tsx @@ -29,12 +29,13 @@ export type PublishApplicationResponse = ApiResponse; export interface ApplicationPagePayload { id: string; + baseId: string; name: string; isDefault: boolean; slug: string; isHidden?: boolean; customSlug?: string; - userPermissions?: string; + userPermissions?: string[]; } export type GitApplicationMetadata = @@ -52,6 +53,7 @@ export type GitApplicationMetadata = export interface ApplicationResponsePayload { id: string; + baseId: string; name: string; workspaceId: string; evaluationVersion?: EvaluationVersion; @@ -95,7 +97,7 @@ export interface CreateApplicationRequest { } export interface SetDefaultPageRequest { - id: string; + pageId: string; applicationId: string; } @@ -226,7 +228,7 @@ export interface UpdateApplicationResponse { export interface PageDefaultMeta { id: string; isDefault: boolean; - defaultPageId: string; + baseId: string; default: boolean; } @@ -287,7 +289,7 @@ export class ApplicationApi extends Api { static changeAppViewAccessPath = (applicationId: string) => `/${applicationId}/changeAccess`; static setDefaultPagePath = (request: SetDefaultPageRequest) => - `${ApplicationApi.baseURL}/${request.applicationId}/page/${request.id}/makeDefault`; + `${ApplicationApi.baseURL}/${request.applicationId}/page/${request.pageId}/makeDefault`; static async publishApplication( publishApplicationRequest: PublishApplicationRequest, ): Promise> { diff --git a/app/client/src/ce/constants/ReduxActionConstants.tsx b/app/client/src/ce/constants/ReduxActionConstants.tsx index 8b5570bc5b..3a300e5cae 100644 --- a/app/client/src/ce/constants/ReduxActionConstants.tsx +++ b/app/client/src/ce/constants/ReduxActionConstants.tsx @@ -30,7 +30,13 @@ const ActionSelectorReduxActionTypes = { "CLEAR_EVALUATED_ACTION_SELECTOR_FIELD", }; +const ResourceMapActionTypes = { + SET_PAGE_RESOURCE_MAPS: "SET_PAGE_RESOURCE_MAPS", + RESET_ALL_RESOURCE_MAPS: "RESET_ALL_RESOURCE_MAPS", +}; + const ActionTypes = { + ...ResourceMapActionTypes, TOGGLE_INSTALLER: "TOGGLE_INSTALLER", FETCH_JS_LIBRARIES_INIT: "FETCH_JS_LIBRARIES_INIT", FETCH_JS_LIBRARIES_SUCCESS: "FETCH_JS_LIBRARIES_SUCCESS", @@ -182,7 +188,6 @@ const ActionTypes = { REPORT_ERROR: "REPORT_ERROR", FLUSH_ERRORS: "FLUSH_ERRORS", FLUSH_AND_REDIRECT: "FLUSH_AND_REDIRECT", - REDIRECT_TO_NEW_INTEGRATIONS: "REDIRECT_TO_NEW_INTEGRATIONS", SAFE_CRASH_APPSMITH: "SAFE_CRASH_APPSMITH", SAFE_CRASH_APPSMITH_REQUEST: "SAFE_CRASH_APPSMITH_REQUEST", INIT_CANVAS_LAYOUT: "INIT_CANVAS_LAYOUT", @@ -574,6 +579,8 @@ const ActionTypes = { "RESET_APPLICATION_WIDGET_STATE_REQUEST", SAAS_GET_OAUTH_ACCESS_TOKEN: "SAAS_GET_OAUTH_ACCESS_TOKEN", GET_OAUTH_ACCESS_TOKEN: "GET_OAUTH_ACCESS_TOKEN", + GET_OAUTH_ACCESS_TOKEN_SUCCESS: "GET_OAUTH_ACCESS_TOKEN_SUCCESS", + GET_OAUTH_ACCESS_TOKEN_ERROR: "GET_OAUTH_ACCESS_TOKEN_ERROR", RESTORE_RECENT_ENTITIES_REQUEST: "RESTORE_RECENT_ENTITIES_REQUEST", RESTORE_RECENT_ENTITIES_SUCCESS: "RESTORE_RECENT_ENTITIES_SUCCESS", SET_RECENT_ENTITIES: "SET_RECENT_ENTITIES", @@ -1236,6 +1243,7 @@ export interface Page { pageName: string; description?: string; pageId: string; + basePageId: string; isDefault: boolean; latest?: boolean; isHidden?: boolean; @@ -1248,6 +1256,7 @@ export interface ClonePageSuccessPayload { pageName: string; description?: string; pageId: string; + basePageId: string; layoutId: string; isDefault: boolean; slug: string; @@ -1255,11 +1264,13 @@ export interface ClonePageSuccessPayload { export interface ApplicationPayload { id: string; + baseId: string; name: string; color?: string; icon?: string; workspaceId: string; defaultPageId: string; + defaultBasePageId: string; isPublic?: boolean; userPermissions?: string[]; appIsExample: boolean; diff --git a/app/client/src/ce/constants/routes/appRoutes.ts b/app/client/src/ce/constants/routes/appRoutes.ts index 2a5d91e35a..f582534f7d 100644 --- a/app/client/src/ce/constants/routes/appRoutes.ts +++ b/app/client/src/ce/constants/routes/appRoutes.ts @@ -17,19 +17,20 @@ export const ID_EXTRACTION_REGEX = `(${MONGO_OBJECT_ID_REGEX}|${UUID_REGEX})`; export const BUILDER_BASE_PATH_DEPRECATED = "/applications"; export const BUILDER_VIEWER_PATH_PREFIX = "/app/"; -export const BUILDER_PATH = `${BUILDER_VIEWER_PATH_PREFIX}:applicationSlug/:pageSlug(.*\-):pageId${ID_EXTRACTION_REGEX}/edit`; -export const BUILDER_CUSTOM_PATH = `${BUILDER_VIEWER_PATH_PREFIX}:customSlug(.*\-):pageId${ID_EXTRACTION_REGEX}/edit`; -export const VIEWER_PATH = `${BUILDER_VIEWER_PATH_PREFIX}:applicationSlug/:pageSlug(.*\-):pageId${ID_EXTRACTION_REGEX}`; -export const VIEWER_CUSTOM_PATH = `${BUILDER_VIEWER_PATH_PREFIX}:customSlug(.*\-):pageId${ID_EXTRACTION_REGEX}`; +export const BUILDER_PATH = `${BUILDER_VIEWER_PATH_PREFIX}:applicationSlug/:pageSlug(.*\-):basePageId${ID_EXTRACTION_REGEX}/edit`; +export const BUILDER_CUSTOM_PATH = `${BUILDER_VIEWER_PATH_PREFIX}:customSlug(.*\-):basePageId${ID_EXTRACTION_REGEX}/edit`; +export const VIEWER_PATH = `${BUILDER_VIEWER_PATH_PREFIX}:applicationSlug/:pageSlug(.*\-):basePageId${ID_EXTRACTION_REGEX}`; +export const VIEWER_CUSTOM_PATH = `${BUILDER_VIEWER_PATH_PREFIX}:customSlug(.*\-):basePageId${ID_EXTRACTION_REGEX}`; export const getViewerPath = ( applicationSlug: string, pageSlug: string, - pageId: string, -) => `${BUILDER_VIEWER_PATH_PREFIX}${applicationSlug}/${pageSlug}-${pageId}`; -export const getViewerCustomPath = (customSlug: string, pageId: string) => - `${BUILDER_VIEWER_PATH_PREFIX}${customSlug}-${pageId}`; -export const BUILDER_PATH_DEPRECATED = `/applications/:applicationId${ID_EXTRACTION_REGEX}/pages/:pageId${ID_EXTRACTION_REGEX}/edit`; -export const VIEWER_PATH_DEPRECATED = `/applications/:applicationId${ID_EXTRACTION_REGEX}/pages/:pageId${ID_EXTRACTION_REGEX}`; + basePageId: string, +) => + `${BUILDER_VIEWER_PATH_PREFIX}${applicationSlug}/${pageSlug}-${basePageId}`; +export const getViewerCustomPath = (customSlug: string, basePageId: string) => + `${BUILDER_VIEWER_PATH_PREFIX}${customSlug}-${basePageId}`; +export const BUILDER_PATH_DEPRECATED = `/applications/:baseApplicationId${ID_EXTRACTION_REGEX}/pages/:basePageId${ID_EXTRACTION_REGEX}/edit`; +export const VIEWER_PATH_DEPRECATED = `/applications/:baseApplicationId${ID_EXTRACTION_REGEX}/pages/:basePageId${ID_EXTRACTION_REGEX}`; export const VIEWER_PATH_DEPRECATED_REGEX = /\/applications\/[^/]+\/pages\/[^/]+/; @@ -48,20 +49,20 @@ export const CUSTOM_WIDGETS_DEPRECATED_EDITOR_ID_PATH = `${BUILDER_PATH_DEPRECAT /* */ export const API_EDITOR_BASE_PATH = `/api`; -export const API_EDITOR_ID_PATH = `${API_EDITOR_BASE_PATH}/:apiId`; -export const API_EDITOR_ID_ADD_PATH = `${API_EDITOR_BASE_PATH}/:apiId/add`; +export const API_EDITOR_ID_PATH = `${API_EDITOR_BASE_PATH}/:baseApiId`; +export const API_EDITOR_ID_ADD_PATH = `${API_EDITOR_BASE_PATH}/:baseApiId/add`; export const API_EDITOR_PATH_WITH_SELECTED_PAGE_ID = `${API_EDITOR_BASE_PATH}?importTo=:importTo`; export const QUERIES_EDITOR_BASE_PATH = `/queries`; export const ADD_PATH = `/add`; export const LIST_PATH = "/list"; export const ENTITY_PATH = "/:entity"; -export const QUERIES_EDITOR_ID_PATH = `${QUERIES_EDITOR_BASE_PATH}/:queryId`; +export const QUERIES_EDITOR_ID_PATH = `${QUERIES_EDITOR_BASE_PATH}/:baseQueryId`; export const QUERIES_EDITOR_ADD_PATH = `${QUERIES_EDITOR_BASE_PATH}${ADD_PATH}`; -export const QUERIES_EDITOR_ID_ADD_PATH = `${QUERIES_EDITOR_BASE_PATH}/:queryId/add`; +export const QUERIES_EDITOR_ID_ADD_PATH = `${QUERIES_EDITOR_BASE_PATH}/:baseQueryId/add`; export const JS_COLLECTION_EDITOR_PATH = `/jsObjects`; -export const JS_COLLECTION_ID_PATH = `${JS_COLLECTION_EDITOR_PATH}/:collectionId`; -export const JS_COLLECTION_ID_ADD_PATH = `${JS_COLLECTION_EDITOR_PATH}/:collectionId/add`; +export const JS_COLLECTION_ID_PATH = `${JS_COLLECTION_EDITOR_PATH}/:baseCollectionId`; +export const JS_COLLECTION_ID_ADD_PATH = `${JS_COLLECTION_EDITOR_PATH}/:baseCollectionId/add`; export const DATA_SOURCES_EDITOR_LIST_PATH = `/datasource`; export const DATA_SOURCES_EDITOR_ID_PATH = `/datasource/:datasourceId`; export const APP_LIBRARIES_EDITOR_PATH = `/libraries`; @@ -77,8 +78,8 @@ export const ADMIN_SETTINGS_CATEGORY_DEFAULT_PATH = "/settings/general"; export const ADMIN_SETTINGS_CATEGORY_ACL_PATH = "/settings/groups"; export const ADMIN_SETTINGS_CATEGORY_AUDIT_LOGS_PATH = "/settings/audit-logs"; export const ADMIN_SETTINGS_CATEGORY_PATH = "/settings/:category/:selected?"; -export const BUILDER_PATCH_PATH = `/:applicationSlug/:pageSlug(.*\-):pageId${ID_EXTRACTION_REGEX}/edit`; -export const VIEWER_PATCH_PATH = `/:applicationSlug/:pageSlug(.*\-):pageId${ID_EXTRACTION_REGEX}`; +export const BUILDER_PATCH_PATH = `/:applicationSlug/:pageSlug(.*\-):basePageId${ID_EXTRACTION_REGEX}/edit`; +export const VIEWER_PATCH_PATH = `/:applicationSlug/:pageSlug(.*\-):basePageId${ID_EXTRACTION_REGEX}`; export const matchApiBasePath = match(API_EDITOR_BASE_PATH); export const matchApiPath = match(API_EDITOR_ID_PATH); @@ -133,29 +134,29 @@ export const addBranchParam = (branch: string) => { }; export interface BuilderRouteParams { - pageId: string; - applicationId: string; + basePageId: string; + baseApplicationId: string; } export interface AppViewerRouteParams { - pageId: string; - applicationId?: string; + basePageId: string; + baseApplicationId?: string; } export interface APIEditorRouteParams { - pageId: string; - apiId?: string; + basePageId: string; + baseApiId?: string; } export interface QueryEditorRouteParams { - pageId: string; - queryId?: string; - apiId?: string; + basePageId: string; + baseQueryId?: string; + baseApiId?: string; } export interface JSEditorRouteParams { - pageId: string; - collectionId?: string; + basePageId: string; + baseCollectionId?: string; } export const GIT_BRANCH_QUERY_KEY = "branch"; @@ -171,7 +172,7 @@ export const INTEGRATION_EDITOR_MODES = { }; export const PLACEHOLDER_APP_SLUG = "application"; -export const PLACEHOLDER_PAGE_ID = "pageId"; +export const PLACEHOLDER_PAGE_ID = "basePageId"; export const PLACEHOLDER_PAGE_SLUG = "page"; export const SHOW_FILE_PICKER_KEY = "showPicker"; diff --git a/app/client/src/ce/entities/Engine/actionHelpers.ts b/app/client/src/ce/entities/Engine/actionHelpers.ts index 547e03d62a..c775dd7acc 100644 --- a/app/client/src/ce/entities/Engine/actionHelpers.ts +++ b/app/client/src/ce/entities/Engine/actionHelpers.ts @@ -4,12 +4,19 @@ import { ReduxActionErrorTypes, ReduxActionTypes, } from "@appsmith/constants/ReduxActionConstants"; +import type { ExplorerURLParams } from "@appsmith/pages/Editor/Explorer/helpers"; import type { DependentFeatureFlags } from "@appsmith/selectors/engineSelectors"; import { fetchDatasources } from "actions/datasourceActions"; import { fetchPageDSLs } from "actions/pageActions"; import { fetchPlugins } from "actions/pluginActions"; import type { Plugin } from "api/PluginApi"; +import { useSelector } from "react-redux"; +import { useParams } from "react-router"; import type { EditConsolidatedApi } from "sagas/InitSagas"; +import { + convertToBaseParentEntityIdSelector, + convertToPageIdSelector, +} from "selectors/pageListSelectors"; export const CreateNewActionKey = { PAGE: "pageId", @@ -58,16 +65,28 @@ export const doesPluginRequireDatasource = (plugin: Plugin | undefined) => { export enum APPSMITH_NAMESPACED_FUNCTIONS {} -export const getParentEntityDetailsFromParams = ( - parentEntityIdObject: { pageId?: string }, +export const useParentEntityDetailsFromParams = ( parentEntityIdProp: string, isInsideReconnectModal?: boolean, ) => { - const { pageId } = parentEntityIdObject; - const parentEntityIdQuery = pageId || ""; + const baseParentEntityIdProp = useSelector((state) => + convertToBaseParentEntityIdSelector(state, parentEntityIdProp), + ); + + const { basePageId } = useParams(); + const parentEntityIdQuery = basePageId || ""; + const pageId = useSelector((state) => + convertToPageIdSelector(state, basePageId), + ); + const baseParentEntityIdQuery = pageId || ""; + const parentEntityId = isInsideReconnectModal ? parentEntityIdProp : parentEntityIdQuery; + const baseParentEntityId = isInsideReconnectModal + ? baseParentEntityIdProp + : baseParentEntityIdQuery; + const entityType = ActionParentEntityType.PAGE; - return { parentEntityId, entityType }; + return { baseParentEntityId, parentEntityId, entityType }; }; diff --git a/app/client/src/ce/entities/URLRedirect/URLAssembly.test.ts b/app/client/src/ce/entities/URLRedirect/URLAssembly.test.ts index ac4c667aaa..9fdb8e309f 100644 --- a/app/client/src/ce/entities/URLRedirect/URLAssembly.test.ts +++ b/app/client/src/ce/entities/URLRedirect/URLAssembly.test.ts @@ -10,11 +10,11 @@ describe("URLBuilder", () => { urlBuilder.resetURLParams(); }); - it("should correctly set and use currentPageId in build function when currentPageId is set", () => { - const testPageId = "testPageId"; + it("should correctly set and use currentBasePageId in build function when currentBasePageId is set", () => { + const testBasePageId = "testBasePageId"; const testMode = APP_MODE.EDIT; - urlBuilder.setCurrentPageId(testPageId); + urlBuilder.setCurrentBasePageId(testBasePageId); const builderParams = { suffix: "testSuffix", @@ -24,92 +24,92 @@ describe("URLBuilder", () => { persistExistingParams: true, }; - URLBuilder.prototype.generateBasePath = jest.fn((pageId, mode) => { - expect(pageId).toBe(testPageId); // Ensure the current page id is used + URLBuilder.prototype.generateBasePath = jest.fn((basePageId, mode) => { + expect(basePageId).toBe(testBasePageId); // Ensure the current page id is used expect(mode).toBe(testMode); - return `mockedBasePath/${pageId}/${mode}`; + return `mockedBasePath/${basePageId}/${mode}`; }); const result = urlBuilder.build(builderParams, testMode); expect(URLBuilder.prototype.generateBasePath).toHaveBeenCalledWith( - testPageId, + testBasePageId, testMode, ); expect(result).toEqual( - "mockedBasePath/testPageId/EDIT/testSuffix?param1=value1¶m2=value2&branch=testBranch#testHash", + "mockedBasePath/testBasePageId/EDIT/testSuffix?param1=value1¶m2=value2&branch=testBranch#testHash", ); }); - it("should correctly set and use pageId in build function when currentPageId is set to null", () => { - const testPageId = "testPageId"; + it("should correctly set and use basePageId in build function when currentBasePageId is set to null", () => { + const testBasePageId = "testBasePageId"; const testMode = APP_MODE.EDIT; - // Set currentPageId to null - urlBuilder.setCurrentPageId(null); + // Set currentBasePageId to null + urlBuilder.setCurrentBasePageId(null); const builderParams = { suffix: "testSuffix", branch: "testBranch", hash: "testHash", params: { param1: "value1", param2: "value2" }, - pageId: testPageId, // Set the pageId to be used + basePageId: testBasePageId, // Set the basePageId to be used persistExistingParams: true, }; - URLBuilder.prototype.generateBasePath = jest.fn((pageId, mode) => { - expect(pageId).toBe(testPageId); // Ensure the passed pageId is used + URLBuilder.prototype.generateBasePath = jest.fn((basePageId, mode) => { + expect(basePageId).toBe(testBasePageId); // Ensure the passed basePageId is used expect(mode).toBe(testMode); - return `mockedBasePath/${pageId}/${mode}`; + return `mockedBasePath/${basePageId}/${mode}`; }); const result = urlBuilder.build(builderParams, testMode); expect(URLBuilder.prototype.generateBasePath).toHaveBeenCalledWith( - testPageId, + testBasePageId, testMode, ); expect(result).toEqual( - "mockedBasePath/testPageId/EDIT/testSuffix?param1=value1¶m2=value2&branch=testBranch#testHash", + "mockedBasePath/testBasePageId/EDIT/testSuffix?param1=value1¶m2=value2&branch=testBranch#testHash", ); }); - it("should correctly set and use pageId in build function when currentPageId is set", () => { - const currentPageId = "currentPageId"; - const testPageId = "testPageId"; + it("should correctly set and use basePageId in build function when currentBasePageId is set", () => { + const currentBasePageId = "currentBasePageId"; + const testBasePageId = "testBasePageId"; const testMode = APP_MODE.EDIT; - urlBuilder.setCurrentPageId(currentPageId); + urlBuilder.setCurrentBasePageId(currentBasePageId); const builderParams = { suffix: "testSuffix", branch: "testBranch", hash: "testHash", params: { param1: "value1", param2: "value2" }, - pageId: testPageId, // This should override the current page id + basePageId: testBasePageId, // This should override the current page id persistExistingParams: true, }; - URLBuilder.prototype.generateBasePath = jest.fn((pageId, mode) => { - return `mockedBasePath/${pageId}/${mode}`; + URLBuilder.prototype.generateBasePath = jest.fn((basePageId, mode) => { + return `mockedBasePath/${basePageId}/${mode}`; }); const result = urlBuilder.build(builderParams, testMode); expect(URLBuilder.prototype.generateBasePath).toHaveBeenCalledWith( - testPageId, + testBasePageId, testMode, ); expect(result).toEqual( - "mockedBasePath/testPageId/EDIT/testSuffix?param1=value1¶m2=value2&branch=testBranch#testHash", + "mockedBasePath/testBasePageId/EDIT/testSuffix?param1=value1¶m2=value2&branch=testBranch#testHash", ); }); - it("should throw an error when pageId is missing", () => { - urlBuilder.setCurrentPageId(null); + it("should throw an error when basePageId is missing", () => { + urlBuilder.setCurrentBasePageId(null); expect(() => { urlBuilder.build({}, APP_MODE.EDIT); diff --git a/app/client/src/ce/entities/URLRedirect/URLAssembly.ts b/app/client/src/ce/entities/URLRedirect/URLAssembly.ts index 73ebe8b6b5..28f7885029 100644 --- a/app/client/src/ce/entities/URLRedirect/URLAssembly.ts +++ b/app/client/src/ce/entities/URLRedirect/URLAssembly.ts @@ -19,10 +19,11 @@ export interface URLBuilderParams { branch?: string; hash?: string; params?: Record; - pageId?: string | null; + basePageId?: string | null; persistExistingParams?: boolean; // This is used to pass ID if the sender doesn't know the type of the entity - parentEntityId?: string; + // base version of parent entity id, can be basePageId or moduleId + baseParentEntityId?: string; generateEditorPath?: boolean; } @@ -48,13 +49,13 @@ export const baseURLRegistry = { }; export interface ApplicationURLParams { - applicationId?: string; + baseApplicationId?: string; applicationSlug?: string; applicationVersion?: ApplicationVersion; } export interface PageURLParams { - pageId: string; + basePageId: string; pageSlug: string; customSlug?: string; } @@ -101,8 +102,8 @@ const fetchQueryParamsToPersist = (persistExistingParams: boolean) => { * * This class is inherited in EE and basePath generation is modified based on the type * of editor the user is currently on. This is done to remove the dependency of current - * page as a required param to build any route. However if a pageId is provided while - * building a route, it will override the cache and use the passed pageId value. + * page as a required param to build any route. However if a basePageId is provided while + * building a route, it will override the cache and use the passed basePageId value. * * However the current implementation can be improved and a holistic solution can be * devised to support all different types of routing pattern. The current solution acts as a stop-gap @@ -111,17 +112,17 @@ const fetchQueryParamsToPersist = (persistExistingParams: boolean) => { export class URLBuilder { appParams: ApplicationURLParams; pageParams: Record; - currentPageId?: string | null; + currentBasePageId?: string | null; static _instance: URLBuilder; constructor() { this.appParams = { - applicationId: "", + baseApplicationId: "", applicationSlug: PLACEHOLDER_APP_SLUG, }; this.pageParams = {}; - this.currentPageId; + this.currentBasePageId; } static getInstance() { @@ -143,26 +144,26 @@ export class URLBuilder { return URL_TYPE.SLUG; } - private getFormattedParams(pageId: string) { + private getFormattedParams(basePageId: string) { const currentAppParams = { applicationSlug: this.appParams.applicationSlug || PLACEHOLDER_APP_SLUG, - applicationId: this.appParams.applicationId, + baseApplicationId: this.appParams.baseApplicationId, }; - let currentPageParams = this.pageParams[pageId] || {}; + let currentPageParams = this.pageParams[basePageId] || {}; currentPageParams = { ...currentPageParams, pageSlug: `${currentPageParams.pageSlug || PLACEHOLDER_PAGE_SLUG}-`, customSlug: currentPageParams.customSlug ? `${currentPageParams.customSlug}-` : "", - pageId, + basePageId, }; return { ...currentAppParams, ...currentPageParams }; } - setCurrentPageId(pageId?: string | null) { - this.currentPageId = pageId; + setCurrentBasePageId(basePageId?: string | null) { + this.currentBasePageId = basePageId; } public updateURLParams( @@ -170,8 +171,8 @@ export class URLBuilder { pageParams?: PageURLParams[], ) { if (appParams) { - this.appParams.applicationId = - appParams.applicationId || this.appParams.applicationId; + this.appParams.baseApplicationId = + appParams.baseApplicationId || this.appParams.baseApplicationId; this.appParams.applicationSlug = appParams.applicationSlug || this.appParams.applicationSlug; this.appParams.applicationVersion = @@ -180,7 +181,7 @@ export class URLBuilder { if (pageParams) { const params = pageParams.reduce( (acc, page) => { - acc[page.pageId] = page; + acc[page.basePageId] = page; return acc; }, {} as Record, @@ -192,54 +193,54 @@ export class URLBuilder { // Currently only used in pages/Applications page on mount resetURLParams() { this.appParams = { - applicationId: "", + baseApplicationId: "", applicationSlug: "", }; this.pageParams = {}; } // Current only used in src/pages/slug.test.tsx - getURLParams(pageId: string) { - return { ...this.appParams, ...this.pageParams[pageId] }; + getURLParams(basePageId: string) { + return { ...this.appParams, ...this.pageParams[basePageId] }; } - generateBasePathForApp(pageId: string, mode: APP_MODE) { + generateBasePathForApp(basePageId: string, mode: APP_MODE) { const { applicationVersion } = this.appParams; - const customSlug = this.pageParams[pageId]?.customSlug || ""; + const customSlug = this.pageParams[basePageId]?.customSlug || ""; const urlType = this.getURLType(applicationVersion, customSlug); const urlPattern = baseURLRegistry[urlType][mode]; - const formattedParams = this.getFormattedParams(pageId); + const formattedParams = this.getFormattedParams(basePageId); const basePath = generatePath(urlPattern, formattedParams); return basePath; } - generateBasePath(pageId: string, mode: APP_MODE) { - return this.generateBasePathForApp(pageId, mode); + generateBasePath(basePageId: string, mode: APP_MODE) { + return this.generateBasePathForApp(basePageId, mode); } - getCustomSlugPathPreview(pageId: string, customSlug: string) { + getCustomSlugPathPreview(basePageId: string, customSlug: string) { const urlPattern = baseURLRegistry[URL_TYPE.CUSTOM_SLUG][APP_MODE.PUBLISHED]; return generatePath(urlPattern, { - pageId, + basePageId, customSlug: `${customSlug}-`, }).toLowerCase(); } - getPagePathPreview(pageId: string, pageName: string) { + getPagePathPreview(basePageId: string, pageName: string) { const { applicationVersion } = this.appParams; const urlType = this.getURLType(applicationVersion); const urlPattern = baseURLRegistry[urlType][APP_MODE.PUBLISHED]; - const formattedParams = this.getFormattedParams(pageId); + const formattedParams = this.getFormattedParams(basePageId); formattedParams.pageSlug = `${pageName}-`; @@ -247,18 +248,18 @@ export class URLBuilder { } resolveEntityIdForApp(builderParams: URLBuilderParams) { - const pageId = - builderParams.pageId || - builderParams?.parentEntityId || - this.currentPageId; + const basePageId = + builderParams.basePageId || + builderParams?.baseParentEntityId || + this.currentBasePageId; - if (!pageId) { + if (!basePageId) { throw new URIError( - "Missing pageId. If you are trying to set href inside a react component use the 'useHref' hook.", + "Missing basePageId. If you are trying to set href inside a react component use the 'useHref' hook.", ); } - return pageId; + return basePageId; } resolveEntityId(builderParams: URLBuilderParams): string { diff --git a/app/client/src/ce/hooks/datasourceEditorHooks.tsx b/app/client/src/ce/hooks/datasourceEditorHooks.tsx index 90c9d0da3e..806fa67982 100644 --- a/app/client/src/ce/hooks/datasourceEditorHooks.tsx +++ b/app/client/src/ce/hooks/datasourceEditorHooks.tsx @@ -20,9 +20,8 @@ import { useShowPageGenerationOnHeader } from "pages/Editor/DataSourceEditor/hoo import React from "react"; import { useSelector } from "react-redux"; import { - getCurrentApplication, getCurrentApplicationId, - getCurrentPageId, + getCurrentBasePageId, getPagePermissions, } from "selectors/editorSelectors"; import { getIsAnvilEnabledInCurrentApplication } from "layoutSystems/anvil/integrations/selectors"; @@ -30,6 +29,7 @@ import { isEnabledForPreviewData } from "utils/editorContextUtils"; import history from "utils/history"; import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { EditorNames } from "./"; +import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; export interface HeaderActionProps { datasource: Datasource | ApiDatasourceForm | undefined; @@ -47,7 +47,7 @@ export const useHeaderActions = ( showReconnectButton = false, }: HeaderActionProps, ) => { - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); const releaseDragDropBuildingBlocks = useFeatureFlag( FEATURE_FLAG.release_drag_drop_building_blocks_enabled, @@ -98,7 +98,7 @@ export const useHeaderActions = ( AnalyticsUtil.logEvent("DATASOURCE_CARD_GEN_CRUD_PAGE_ACTION"); history.push( generateTemplateFormURL({ - pageId, + basePageId, params: { datasourceId: (datasource as Datasource).id, new_page: true, @@ -146,11 +146,11 @@ export const useHeaderActions = ( // eslint-disable-next-line @typescript-eslint/no-unused-vars export const useParentEntityInfo = (editorType: string) => { const appId = useSelector(getCurrentApplicationId); - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); return { editorId: appId || "", - parentEntityId: pageId || "", + parentEntityId: basePageId || "", parentEntityType: ActionParentEntityType.PAGE, }; }; diff --git a/app/client/src/ce/navigation/FocusSetters.ts b/app/client/src/ce/navigation/FocusSetters.ts index 168c6a555e..612f6e3e3e 100644 --- a/app/client/src/ce/navigation/FocusSetters.ts +++ b/app/client/src/ce/navigation/FocusSetters.ts @@ -23,21 +23,21 @@ export function setSelectedDatasource(id?: string) { } export function setSelectedQuery(entityInfo?: FocusEntityInfo) { - if (entityInfo && entityInfo.params.pageId) { + if (entityInfo && entityInfo.params.basePageId) { if ([FocusEntity.API, FocusEntity.QUERY].includes(entityInfo.entity)) { - const { apiId, pluginPackageName, queryId } = entityInfo.params; - const key = apiId ? apiId : queryId; + const { baseApiId, baseQueryId, pluginPackageName } = entityInfo.params; + const key = baseApiId ? baseApiId : baseQueryId; if (!key) return undefined; let type: PluginType = PluginType.API; if (pluginPackageName) { type = PluginType.SAAS; - } else if (queryId) { + } else if (baseQueryId) { type = PluginType.DB; } const url = getQueryEntityItemUrl( { type, key, title: key }, - entityInfo.params.pageId, + entityInfo.params.basePageId, ); history.replace(url, { invokedBy: NavigationMethod.ContextSwitching }); } @@ -48,7 +48,7 @@ export function setSelectedJSObject(focusInfo?: FocusEntityInfo) { if (focusInfo && focusInfo.entity === FocusEntity.JS_OBJECT) { history.replace( jsCollectionIdURL({ - collectionId: focusInfo.id, + baseCollectionId: focusInfo.id, }), { invokedBy: NavigationMethod.ContextSwitching }, ); diff --git a/app/client/src/ce/navigation/FocusStrategy/AppIDEFocusStrategy.test.ts b/app/client/src/ce/navigation/FocusStrategy/AppIDEFocusStrategy.test.ts index b6d3ecb2c6..66c7cd39a4 100644 --- a/app/client/src/ce/navigation/FocusStrategy/AppIDEFocusStrategy.test.ts +++ b/app/client/src/ce/navigation/FocusStrategy/AppIDEFocusStrategy.test.ts @@ -5,8 +5,8 @@ import { getIDETestState } from "test/factories/AppIDEFactoryUtils"; import { all, take } from "redux-saga/effects"; import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; -const pageId1 = "0123456789abcdef00000000", - pageId2 = "0123456789abcdef00000001"; +const basePageId1 = "0123456789abcdef00000000"; +const basePageId2 = "0123456789abcdef00000001"; describe("AppIDEFocusStrategy", () => { describe("getEntitiesForSet", () => { @@ -30,8 +30,8 @@ describe("AppIDEFocusStrategy", () => { getState: () => ({ state: "test" }), }, AppIDEFocusStrategy.getEntitiesForSet, - `/app/appSlug/pageSlug-${pageId1}/edit`, - `/app/appSlug/pageSlug-${pageId1}/edit/widgets`, + `/app/appSlug/pageSlug-${basePageId1}/edit`, + `/app/appSlug/pageSlug-${basePageId1}/edit/widgets`, { invokedBy: NavigationMethod.EntityExplorer }, ).toPromise(); @@ -44,8 +44,8 @@ describe("AppIDEFocusStrategy", () => { getState: () => ({ state: "test" }), }, AppIDEFocusStrategy.getEntitiesForSet, - `/app/appSlug/pageSlug-${pageId1}/edit/widgets/1`, - `/app/appSlug/pageSlug-${pageId1}/edit/widgets`, + `/app/appSlug/pageSlug-${basePageId1}/edit/widgets/1`, + `/app/appSlug/pageSlug-${basePageId1}/edit/widgets`, { invokedBy: undefined }, ).toPromise(); @@ -58,8 +58,8 @@ describe("AppIDEFocusStrategy", () => { getState: () => state, }, AppIDEFocusStrategy.getEntitiesForSet, - `/app/appSlug/pageSlug-${pageId1}/edit/widgets/1`, - `/app/appSlug/pageSlug-${pageId2}/edit/widgets`, + `/app/appSlug/pageSlug-${basePageId1}/edit/widgets/1`, + `/app/appSlug/pageSlug-${basePageId2}/edit/widgets`, { invokedBy: undefined }, ).toPromise(); @@ -72,11 +72,11 @@ describe("AppIDEFocusStrategy", () => { params: { applicationSlug: "appSlug", entity: "widgets", - pageId: pageId2, + basePageId: basePageId2, pageSlug: "pageSlug-", }, }, - key: `/app/appSlug/pageSlug-${pageId2}/edit/widgets#main`, + key: `/app/appSlug/pageSlug-${basePageId2}/edit/widgets#main`, }, ]); }); @@ -88,8 +88,8 @@ describe("AppIDEFocusStrategy", () => { getState: () => state, }, AppIDEFocusStrategy.getEntitiesForSet, - `/app/appSlug/pageSlug-${pageId1}/edit/datasource/data_id`, - `/app/appSlug/pageSlug-${pageId1}/edit`, + `/app/appSlug/pageSlug-${basePageId1}/edit/datasource/data_id`, + `/app/appSlug/pageSlug-${basePageId1}/edit`, { invokedBy: undefined }, ).toPromise(); @@ -97,10 +97,10 @@ describe("AppIDEFocusStrategy", () => { entityInfo: { appState: "EDITOR", entity: "EDITOR", - id: `EDITOR.${pageId1}`, + id: `EDITOR.${basePageId1}`, params: {}, }, - key: `EDITOR_STATE.${pageId1}#main`, + key: `EDITOR_STATE.${basePageId1}#main`, }); const pageIdChangeResult = await runSaga( @@ -108,8 +108,8 @@ describe("AppIDEFocusStrategy", () => { getState: () => state, }, AppIDEFocusStrategy.getEntitiesForSet, - `/app/appSlug/pageSlug-${pageId1}/edit/widgets/1`, - `/app/appSlug/pageSlug-${pageId2}/edit`, + `/app/appSlug/pageSlug-${basePageId1}/edit/widgets/1`, + `/app/appSlug/pageSlug-${basePageId2}/edit`, { invokedBy: undefined }, ).toPromise(); @@ -117,10 +117,10 @@ describe("AppIDEFocusStrategy", () => { entityInfo: { appState: "EDITOR", entity: "EDITOR", - id: `EDITOR.${pageId2}`, + id: `EDITOR.${basePageId2}`, params: {}, }, - key: `EDITOR_STATE.${pageId2}#main`, + key: `EDITOR_STATE.${basePageId2}#main`, }); }); @@ -131,8 +131,8 @@ describe("AppIDEFocusStrategy", () => { getState: () => state, }, AppIDEFocusStrategy.getEntitiesForSet, - `/app/appSlug/pageSlug-${pageId1}/edit/datasource/data_id`, - `/app/appSlug/pageSlug-${pageId1}/edit/datasource/data_id2`, + `/app/appSlug/pageSlug-${basePageId1}/edit/datasource/data_id`, + `/app/appSlug/pageSlug-${basePageId1}/edit/datasource/data_id2`, { invokedBy: undefined }, ).toPromise(); @@ -145,11 +145,11 @@ describe("AppIDEFocusStrategy", () => { params: { applicationSlug: "appSlug", datasourceId: "data_id2", - pageId: pageId1, + basePageId: basePageId1, pageSlug: "pageSlug-", }, }, - key: `/app/appSlug/pageSlug-${pageId1}/edit/datasource/data_id2#main`, + key: `/app/appSlug/pageSlug-${basePageId1}/edit/datasource/data_id2#main`, }, ]); }); @@ -163,8 +163,8 @@ describe("AppIDEFocusStrategy", () => { getState: () => state, }, AppIDEFocusStrategy.getEntitiesForStore, - `/app/appSlug/pageSlug-${pageId1}/edit/datasource/data_id`, - `/app/appSlug/pageSlug-${pageId1}/edit/datasource/data_id2`, + `/app/appSlug/pageSlug-${basePageId1}/edit/datasource/data_id`, + `/app/appSlug/pageSlug-${basePageId1}/edit/datasource/data_id2`, ).toPromise(); expect(result).toContainEqual({ @@ -182,8 +182,8 @@ describe("AppIDEFocusStrategy", () => { getState: () => state, }, AppIDEFocusStrategy.getEntitiesForStore, - `/app/appSlug/pageSlug-${pageId1}/edit/jsObjects/js_id`, - `/app/appSlug/pageSlug-${pageId1}/edit/widgets/widget_id`, + `/app/appSlug/pageSlug-${basePageId1}/edit/jsObjects/js_id`, + `/app/appSlug/pageSlug-${basePageId1}/edit/widgets/widget_id`, ).toPromise(); expect(result).toContainEqual({ @@ -191,7 +191,7 @@ describe("AppIDEFocusStrategy", () => { appState: "EDITOR", entity: "EDITOR", }), - key: `EDITOR_STATE.${pageId1}#main`, + key: `EDITOR_STATE.${basePageId1}#main`, }); }); @@ -201,8 +201,8 @@ describe("AppIDEFocusStrategy", () => { getState: () => state, }, AppIDEFocusStrategy.getEntitiesForStore, - `/app/appSlug/pageSlug-${pageId1}/edit/jsObjects`, - `/app/appSlug/pageSlug-${pageId1}/edit/jsObjects/js_id`, + `/app/appSlug/pageSlug-${basePageId1}/edit/jsObjects`, + `/app/appSlug/pageSlug-${basePageId1}/edit/jsObjects/js_id`, ).toPromise(); expect(result).not.toContainEqual({ @@ -217,8 +217,8 @@ describe("AppIDEFocusStrategy", () => { getState: () => state, }, AppIDEFocusStrategy.getEntitiesForStore, - `/app/appSlug/pageSlug-${pageId1}/edit/jsObjects/js_id2`, - `/app/appSlug/pageSlug-${pageId1}/edit/jsObjects/js_id`, + `/app/appSlug/pageSlug-${basePageId1}/edit/jsObjects/js_id2`, + `/app/appSlug/pageSlug-${basePageId1}/edit/jsObjects/js_id`, ).toPromise(); expect(resultWithNoParent).toContainEqual({ @@ -234,8 +234,8 @@ describe("AppIDEFocusStrategy", () => { describe("Wait for Path Load", () => { it("waits for page fetch success when page changes", () => { const pageChangeGen = AppIDEFocusStrategy.waitForPathLoad( - `/app/appSlug/pageSlug1-${pageId1}/edit`, - `/app/appSlug/pageSlug2-${pageId2}/edit`, + `/app/appSlug/pageSlug1-${basePageId1}/edit`, + `/app/appSlug/pageSlug2-${basePageId2}/edit`, ); expect(pageChangeGen.next().value).toEqual( @@ -245,8 +245,8 @@ describe("AppIDEFocusStrategy", () => { it("does not wait for page fetch success when page does not change", () => { const pageChangeGen = AppIDEFocusStrategy.waitForPathLoad( - `/app/appSlug/pageSlug1-${pageId1}/edit/widgets/1`, - `/app/appSlug/pageSlug1-${pageId1}/edit/widgets/2`, + `/app/appSlug/pageSlug1-${basePageId1}/edit/widgets/1`, + `/app/appSlug/pageSlug1-${basePageId1}/edit/widgets/2`, ); expect(pageChangeGen.next().value).toEqual(undefined); diff --git a/app/client/src/ce/navigation/FocusStrategy/AppIDEFocusStrategy.ts b/app/client/src/ce/navigation/FocusStrategy/AppIDEFocusStrategy.ts index 67d4fa59e6..022cad91d0 100644 --- a/app/client/src/ce/navigation/FocusStrategy/AppIDEFocusStrategy.ts +++ b/app/client/src/ce/navigation/FocusStrategy/AppIDEFocusStrategy.ts @@ -71,22 +71,23 @@ const isPageChange = (prevPath: string, currentPath: string) => { const prevFocusEntityInfo = identifyEntityFromPath(prevPath); const currFocusEntityInfo = identifyEntityFromPath(currentPath); if ( - prevFocusEntityInfo.params.pageId === "" || - currFocusEntityInfo.params.pageId === "" + prevFocusEntityInfo.params.basePageId === "" || + currFocusEntityInfo.params.basePageId === "" ) { return false; } return ( - prevFocusEntityInfo.params.pageId !== currFocusEntityInfo.params.pageId + prevFocusEntityInfo.params.basePageId !== + currFocusEntityInfo.params.basePageId ); }; -export const createEditorFocusInfoKey = (pageId: string, branch?: string) => - `EDITOR_STATE.${pageId}#${branch}`; -export const createEditorFocusInfo = (pageId: string, branch?: string) => ({ - key: createEditorFocusInfoKey(pageId, branch), +export const createEditorFocusInfoKey = (basePageId: string, branch?: string) => + `EDITOR_STATE.${basePageId}#${branch}`; +export const createEditorFocusInfo = (basePageId: string, branch?: string) => ({ + key: createEditorFocusInfoKey(basePageId, branch), entityInfo: { - id: `EDITOR.${pageId}`, + id: `EDITOR.${basePageId}`, appState: EditorState.EDITOR, entity: FocusEntity.EDITOR, params: {}, @@ -111,12 +112,13 @@ export const AppIDEFocusStrategy: FocusStrategy = { // Only set the editor state if switching between pages or app states if ( currentEntityInfo.entity === FocusEntity.CANVAS && - (prevEntityInfo.params.pageId !== currentEntityInfo.params.pageId || + (prevEntityInfo.params.basePageId !== + currentEntityInfo.params.basePageId || prevEntityInfo.appState !== currentEntityInfo.appState) ) { - if (currentEntityInfo.params.pageId) { + if (currentEntityInfo.params.basePageId) { entities.push( - createEditorFocusInfo(currentEntityInfo.params.pageId, branch), + createEditorFocusInfo(currentEntityInfo.params.basePageId, branch), ); } } @@ -159,17 +161,17 @@ export const AppIDEFocusStrategy: FocusStrategy = { prevFocusEntityInfo.appState === EditorState.EDITOR && prevFocusEntityInfo.entity !== FocusEntity.NONE && (prevFocusEntityInfo.entity !== currentFocusEntityInfo.entity || - prevFocusEntityInfo.params.pageId !== - currentFocusEntityInfo.params.pageId) + prevFocusEntityInfo.params.basePageId !== + currentFocusEntityInfo.params.basePageId) ) { entities.push({ entityInfo: { entity: FocusEntity.EDITOR, - id: `EDITOR.${prevFocusEntityInfo.params.pageId}`, + id: `EDITOR.${prevFocusEntityInfo.params.basePageId}`, appState: EditorState.EDITOR, params: prevFocusEntityInfo.params, }, - key: `EDITOR_STATE.${prevFocusEntityInfo.params.pageId}#${branch}`, + key: `EDITOR_STATE.${prevFocusEntityInfo.params.basePageId}#${branch}`, }); } @@ -192,22 +194,22 @@ export const AppIDEFocusStrategy: FocusStrategy = { let parentUrl: string = ""; if (parentEntity === FocusEntity.WIDGET_LIST) { parentUrl = widgetListURL({ - pageId: entityInfo.params.pageId, + basePageId: entityInfo.params.basePageId, }); } if (parentEntity === FocusEntity.DATASOURCE_LIST) { parentUrl = datasourcesEditorURL({ - pageId: entityInfo.params.pageId, + basePageId: entityInfo.params.basePageId, }); } if (parentEntity === FocusEntity.JS_OBJECT_LIST) { parentUrl = jsCollectionListURL({ - pageId: entityInfo.params.pageId, + basePageId: entityInfo.params.basePageId, }); } if (parentEntity === FocusEntity.QUERY_LIST) { parentUrl = queryListURL({ - pageId: entityInfo.params.pageId, + basePageId: entityInfo.params.basePageId, }); } // We do not have to add any query params because this url is used as the key diff --git a/app/client/src/ce/pages/AppViewer/NavigationLogo.tsx b/app/client/src/ce/pages/AppViewer/NavigationLogo.tsx index e87dd92426..4599009a12 100644 --- a/app/client/src/ce/pages/AppViewer/NavigationLogo.tsx +++ b/app/client/src/ce/pages/AppViewer/NavigationLogo.tsx @@ -40,7 +40,7 @@ function NavigationLogo(props: NavigationLogoProps) { const pageUrl = useHref( appMode === APP_MODE.PUBLISHED ? viewerURL : builderURL, { - pageId: defaultPage?.pageId, + basePageId: defaultPage?.basePageId, }, ); const logoAssetId = get( diff --git a/app/client/src/ce/pages/Applications/ApplicationCardList.tsx b/app/client/src/ce/pages/Applications/ApplicationCardList.tsx index 87d4c4c714..b3414b490d 100644 --- a/app/client/src/ce/pages/Applications/ApplicationCardList.tsx +++ b/app/client/src/ce/pages/Applications/ApplicationCardList.tsx @@ -59,7 +59,7 @@ function ApplicationCardList({ title={title} titleTag={titleTag} > - {applications.map((application: any) => { + {applications.map((application) => { return ( ({ pageSlug: page.slug, customSlug: page.customSlug, - pageId: page.id, + basePageId: page.baseId, })), ); history.push( builderURL({ - pageId: applicationObject.pages[0].id, + basePageId: applicationObject.pages[0].baseId, }), ); @@ -178,12 +178,12 @@ const CreateNewAppsOption = ({ { applicationSlug: application.slug, applicationVersion: application.applicationVersion, - applicationId: application.id, + baseApplicationId: application.baseId, }, application.pages.map((page) => ({ pageSlug: page.slug, customSlug: page.customSlug, - pageId: page.id, + basePageId: page.baseId, })), ); diff --git a/app/client/src/ce/pages/Applications/EmbedSnippetTab.tsx b/app/client/src/ce/pages/Applications/EmbedSnippetTab.tsx index e5b436f2b6..1db9ac195f 100644 --- a/app/client/src/ce/pages/Applications/EmbedSnippetTab.tsx +++ b/app/client/src/ce/pages/Applications/EmbedSnippetTab.tsx @@ -8,7 +8,6 @@ import { createMessage, IN_APP_EMBED_SETTING, } from "@appsmith/constants/messages"; -import { getCurrentApplication } from "selectors/editorSelectors"; import PrivateEmbeddingContent, { PrivateEmbedRampModal, PrivateEmbedRampSidebar, @@ -17,6 +16,7 @@ import PropertyHelpLabel from "pages/Editor/PropertyPane/PropertyHelpLabel"; import { ADMIN_SETTINGS_PATH } from "constants/routes"; import { defaultOptionSelected, to, getSnippetUrl } from "@appsmith/utils"; import { PrivateEmbedSettings } from "@appsmith/pages/Applications/PrivateEmbedSettings"; +import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; export const StyledPropertyHelpLabel = styled(PropertyHelpLabel)` .bp3-popover-content > div { diff --git a/app/client/src/ce/pages/Editor/Explorer/helpers.tsx b/app/client/src/ce/pages/Editor/Explorer/helpers.tsx index 29fe14b15f..5489fda6a3 100644 --- a/app/client/src/ce/pages/Editor/Explorer/helpers.tsx +++ b/app/client/src/ce/pages/Editor/Explorer/helpers.tsx @@ -37,7 +37,7 @@ export const ContextMenuPopoverModifiers: IPopoverSharedProps["modifiers"] = { }; export interface ExplorerURLParams { - pageId: string; + basePageId: string; } export interface ExplorerFileEntity { @@ -59,36 +59,36 @@ export const getActionIdFromURL = () => { const baseMatch = matchBasePath(window.location.pathname); if (!baseMatch) return; const { path: basePath } = baseMatch; - const apiMatch = matchPath<{ apiId: string }>(window.location.pathname, { + const apiMatch = matchPath<{ baseApiId: string }>(window.location.pathname, { path: `${basePath}${API_EDITOR_ID_PATH}`, }); - if (apiMatch?.params?.apiId) { - return apiMatch.params.apiId; + if (apiMatch?.params?.baseApiId) { + return apiMatch.params.baseApiId; } - const match = matchPath<{ queryId: string }>(window.location.pathname, { + const match = matchPath<{ baseQueryId: string }>(window.location.pathname, { path: `${basePath}${QUERIES_EDITOR_ID_PATH}`, }); - if (match?.params?.queryId) { - return match.params.queryId; + if (match?.params?.baseQueryId) { + return match.params.baseQueryId; } - const saasMatch = matchPath<{ apiId: string }>(window.location.pathname, { + const saasMatch = matchPath<{ baseApiId: string }>(window.location.pathname, { path: `${basePath}${SAAS_EDITOR_API_ID_PATH}`, }); - if (saasMatch?.params?.apiId) { - return saasMatch.params.apiId; + if (saasMatch?.params?.baseApiId) { + return saasMatch.params.baseApiId; } }; export function getAppViewerPageIdFromPath(path: string): string | null { const regexes = [ - `${BUILDER_VIEWER_PATH_PREFIX}:applicationSlug/:pageSlug(.*\\-):pageId`, // VIEWER_PATH - `${BUILDER_VIEWER_PATH_PREFIX}:customSlug(.*\\-):pageId`, // VIEWER_CUSTOM_PATH - `/applications/:applicationId/pages/:pageId`, // VIEWER_PATH_DEPRECATED + `${BUILDER_VIEWER_PATH_PREFIX}:applicationSlug/:pageSlug(.*\\-):basePageId`, // VIEWER_PATH + `${BUILDER_VIEWER_PATH_PREFIX}:customSlug(.*\\-):basePageId`, // VIEWER_CUSTOM_PATH + `/applications/:baseApplicationId/pages/:basePageId`, // VIEWER_PATH_DEPRECATED ]; for (const regex of regexes) { - const match = matchPath<{ pageId: string }>(path, { path: regex }); - if (match?.params.pageId) { - return match.params.pageId; + const match = matchPath<{ basePageId: string }>(path, { path: regex }); + if (match?.params.basePageId) { + return match.params.basePageId; } } return null; @@ -96,7 +96,7 @@ export function getAppViewerPageIdFromPath(path: string): string | null { export const matchEditorPath = ( path: string, -): Match<{ applicationId: string; pageId: string }> => { +): Match<{ baseApplicationId: string; basePageId: string }> => { return matchBuilderPath(path, { end: false }); }; export const isEditorPath = (path: string) => { @@ -111,14 +111,14 @@ export const getJSCollectionIdFromURL = () => { const baseMatch = matchBasePath(window.location.pathname); if (!baseMatch) return; const { path: basePath } = baseMatch; - const functionMatch = matchPath<{ collectionId: string }>( + const functionMatch = matchPath<{ baseCollectionId: string }>( window.location.pathname, { path: `${basePath}${JS_COLLECTION_ID_PATH}`, }, ); - if (functionMatch?.params?.collectionId) { - return functionMatch?.params?.collectionId; + if (functionMatch?.params?.baseCollectionId) { + return functionMatch?.params?.baseCollectionId; } }; @@ -126,11 +126,11 @@ export const getQueryIdFromURL = () => { const baseMatch = matchBasePath(window.location.pathname); if (!baseMatch) return; const { path: basePath } = baseMatch; - const match = matchPath<{ queryId: string }>(window.location.pathname, { + const match = matchPath<{ baseQueryId: string }>(window.location.pathname, { path: `${basePath}${QUERIES_EDITOR_ID_PATH}`, }); - if (match?.params?.queryId) { - return match.params.queryId; + if (match?.params?.baseQueryId) { + return match.params.baseQueryId; } }; diff --git a/app/client/src/ce/pages/Editor/Explorer/hooks.tsx b/app/client/src/ce/pages/Editor/Explorer/hooks.tsx index 3807fd7a11..bac90a8fb0 100644 --- a/app/client/src/ce/pages/Editor/Explorer/hooks.tsx +++ b/app/client/src/ce/pages/Editor/Explorer/hooks.tsx @@ -266,11 +266,11 @@ export const useEntityEditState = (entityId: string) => { ); }; -export function useActiveAction() { +export function useActiveActionBaseId() { const location = useLocation(); const path = basePathForActiveAction; - const baseMatch = matchPath<{ apiId: string }>(location.pathname, { + const baseMatch = matchPath<{ baseApiId: string }>(location.pathname, { path, strict: false, exact: false, @@ -278,29 +278,29 @@ export function useActiveAction() { const basePath = baseMatch?.path || ""; - const apiMatch = matchPath<{ apiId: string }>(location.pathname, { + const apiMatch = matchPath<{ baseApiId: string }>(location.pathname, { path: `${basePath}${API_EDITOR_ID_PATH}`, }); - if (apiMatch?.params?.apiId) { - return apiMatch.params.apiId; + if (apiMatch?.params?.baseApiId) { + return apiMatch.params.baseApiId; } - const queryMatch = matchPath<{ queryId: string }>(location.pathname, { + const queryMatch = matchPath<{ baseQueryId: string }>(location.pathname, { path: `${basePath}${QUERIES_EDITOR_ID_PATH}`, }); - if (queryMatch?.params?.queryId) { - return queryMatch.params.queryId; + if (queryMatch?.params?.baseQueryId) { + return queryMatch.params.baseQueryId; } - const jsMatch = matchPath<{ collectionId: string }>(location.pathname, { + const jsMatch = matchPath<{ baseCollectionId: string }>(location.pathname, { path: `${basePath}${JS_COLLECTION_ID_PATH}`, }); - if (jsMatch?.params?.collectionId) { - return jsMatch.params.collectionId; + if (jsMatch?.params?.baseCollectionId) { + return jsMatch.params.baseCollectionId; } - const saasMatch = matchPath<{ apiId: string }>(location.pathname, { + const saasMatch = matchPath<{ baseApiId: string }>(location.pathname, { path: `${basePath}${SAAS_EDITOR_API_ID_PATH}`, }); - if (saasMatch?.params?.apiId) { - return saasMatch.params.apiId; + if (saasMatch?.params?.baseApiId) { + return saasMatch.params.baseApiId; } } diff --git a/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/ListItem.tsx b/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/ListItem.tsx index cbf027d8db..ebfa4ae04d 100644 --- a/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/ListItem.tsx +++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/ListItem.tsx @@ -16,7 +16,7 @@ export const JSListItem = (props: JSListItemProps) => { return ( { exact: true, key: "AddJS", component: AddJS, - path: [`${path}${ADD_PATH}`, `${path}/:collectionId${ADD_PATH}`], + path: [`${path}${ADD_PATH}`, `${path}/:baseCollectionId${ADD_PATH}`], }, { exact: true, key: "JSEditor", component: JSEditor, - path: [path + "/:collectionId"], + path: [path + "/:baseCollectionId"], }, { key: "JSEmpty", @@ -107,7 +107,11 @@ export const useJSSegmentRoutes = (path: string): UseRoutes => { exact: false, key: "ListJS", component: ListJS, - path: [path, `${path}${ADD_PATH}`, `${path}/:collectionId${ADD_PATH}`], + path: [ + path, + `${path}${ADD_PATH}`, + `${path}/:baseCollectionId${ADD_PATH}`, + ], }, ]; }; diff --git a/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/utils.test.ts b/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/utils.test.ts index 10dd20e4bd..acc18bfdc0 100644 --- a/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/utils.test.ts +++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/utils.test.ts @@ -6,7 +6,7 @@ import { FocusEntity } from "navigation/FocusEntity"; import { EditorState } from "@appsmith/entities/IDE/constants"; describe("getJSEntityItemUrl", () => { - urlBuilder.setCurrentPageId("0123456789abcdef00000000"); + urlBuilder.setCurrentBasePageId("0123456789abcdef00000000"); it("returns a JS url", () => { const url = getJSEntityItemUrl( { @@ -16,7 +16,6 @@ describe("getJSEntityItemUrl", () => { }, "0123456789abcdef00000000", ); - expect(url).toEqual( "/app/application/page-0123456789abcdef00000000/edit/jsObjects/abc", ); @@ -24,7 +23,7 @@ describe("getJSEntityItemUrl", () => { }); describe("getJSUrl", () => { - urlBuilder.setCurrentPageId("0123456789abcdef00000000"); + urlBuilder.setCurrentBasePageId("0123456789abcdef00000000"); it("returns a JS collection url", () => { const focusEntity: FocusEntityInfo = { entity: FocusEntity.JS_OBJECT, @@ -62,8 +61,8 @@ describe("getJSUrl", () => { id: "abc", appState: EditorState.EDITOR, params: { - queryId: "abc", - pageId: "0123456789abcdef00000000", + baseQueryId: "abc", + basePageId: "0123456789abcdef00000000", }, }; const url = getJSUrl(focusEntity, false); diff --git a/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/utils.ts b/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/utils.ts index 23398c093f..216df2b331 100644 --- a/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/utils.ts +++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/utils.ts @@ -8,11 +8,11 @@ import { FocusEntity, type FocusEntityInfo } from "navigation/FocusEntity"; export const getJSEntityItemUrl = ( item: EntityItem, - pageId: string, + basePageId: string, ): string => { return jsCollectionIdURL({ - collectionId: item.key, - pageId, + baseCollectionId: item.key, + basePageId, }); }; @@ -22,13 +22,13 @@ export const getJSUrl = ( ): string => { if (item.entity === FocusEntity.JS_OBJECT) { return jsCollectionIdURL({ - collectionId: item.id, + baseCollectionId: item.id || "", add, }); } else if (item.entity === FocusEntity.JS_OBJECT_ADD) { - return jsCollectionListURL({ pageId: item.params.pageId }); + return jsCollectionListURL({ basePageId: item.params.basePageId }); } return add - ? jsCollectionAddURL({ pageId: item.params.pageId }) - : jsCollectionListURL({ pageId: item.params.pageId }); + ? jsCollectionAddURL({ basePageId: item.params.basePageId }) + : jsCollectionListURL({ basePageId: item.params.basePageId }); }; diff --git a/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem.tsx b/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem.tsx index 69f36fcb86..66457a78e9 100644 --- a/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem.tsx +++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem.tsx @@ -14,7 +14,7 @@ export const QueryListItem = (props: QueryListItemProps) => { const { isActive, item, parentEntityId, parentEntityType } = props; return ( { key: "AddQuery", exact: true, component: AddQuery, - path: [`${path}${ADD_PATH}`, `${path}/:queryId${ADD_PATH}`], + path: [`${path}${ADD_PATH}`, `${path}/:baseQueryId${ADD_PATH}`], }, { key: "SAASEditor", @@ -143,7 +143,7 @@ export const useQuerySegmentRoutes = (path: string): UseRoutes => { key: "QueryEditor", component: QueryEditor, exact: true, - path: [path + "/:queryId"], + path: [path + "/:baseQueryId"], }, { key: "QueryEmpty", @@ -158,7 +158,7 @@ export const useQuerySegmentRoutes = (path: string): UseRoutes => { key: "ListQuery", exact: false, component: ListQuery, - path: [path, `${path}${ADD_PATH}`, `${path}/:queryId${ADD_PATH}`], + path: [path, `${path}${ADD_PATH}`, `${path}/:baseQueryId${ADD_PATH}`], }, ]; }; diff --git a/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils.test.ts b/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils.test.ts index 58e0b9e973..09c2028b91 100644 --- a/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils.test.ts +++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils.test.ts @@ -30,7 +30,7 @@ describe("getQueryEntityItemUrl", () => { }); describe("getQueryUrl", () => { - urlBuilder.setCurrentPageId("0123456789abcdef00000000"); + urlBuilder.setCurrentBasePageId("0123456789abcdef00000000"); it("gets the correct SAAS plugin url", () => { const focusEntity: FocusEntityInfo = { entity: FocusEntity.QUERY, @@ -38,7 +38,7 @@ describe("getQueryUrl", () => { appState: EditorState.EDITOR, params: { pluginPackageName: PluginPackageName.GOOGLE_SHEETS, - apiId: "abc", + baseApiId: "abc", }, }; @@ -59,7 +59,7 @@ describe("getQueryUrl", () => { id: "abc", appState: EditorState.EDITOR, params: { - apiId: "abc", + baseApiId: "abc", }, }; @@ -80,7 +80,7 @@ describe("getQueryUrl", () => { id: "abc", appState: EditorState.EDITOR, params: { - queryId: "abc", + baseQueryId: "abc", }, }; @@ -101,7 +101,7 @@ describe("getQueryUrl", () => { id: "add", appState: EditorState.EDITOR, params: { - queryId: "add", + baseQueryId: "add", }, }; @@ -117,7 +117,7 @@ describe("getQueryUrl", () => { id: "abc", appState: EditorState.EDITOR, params: { - collectionId: "abc", + baseCollectionId: "abc", }, }; diff --git a/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils.ts b/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils.ts index 1d950fe4e8..4ebe1f8d54 100644 --- a/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils.ts +++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/Query/utils.ts @@ -11,42 +11,42 @@ import { export const getQueryEntityItemUrl = ( item: EntityItem, - pageId: string, + basePageId: string, ): string => { const config = getActionConfig(item.type); if (!config) { throw Error(`Cannot find url of plugin type ${item.type}`); } - return config.getURL(pageId, item.key, item.type); + return config.getURL(basePageId, item.key, item.type); }; export const getQueryUrl = ( item: FocusEntityInfo, add: boolean = true, ): string => { - if (item.params.apiId) { + if (item.params.baseApiId) { if (item.params.pluginPackageName) { return saasEditorApiIdURL({ pluginPackageName: item.params.pluginPackageName, - apiId: item.params.apiId, + baseApiId: item.params.baseApiId, add, }); } else { return apiEditorIdURL({ - apiId: item.params.apiId, + baseApiId: item.params.baseApiId, add, }); } - } else if (item.params.queryId) { - if (item.params.queryId === "add") { - return queryListURL({ pageId: item.params.pageId }); + } else if (item.params.baseQueryId) { + if (item.params.baseQueryId === "add") { + return queryListURL({ basePageId: item.params.basePageId }); } return queryEditorIdURL({ - queryId: item.params.queryId, + baseQueryId: item.params.baseQueryId, add, }); } return add - ? queryAddURL({ pageId: item.params.pageId }) - : queryListURL({ pageId: item.params.pageId }); + ? queryAddURL({ basePageId: item.params.basePageId }) + : queryListURL({ basePageId: item.params.basePageId }); }; diff --git a/app/client/src/ce/pages/Editor/gitSync/useReconnectModalData.ts b/app/client/src/ce/pages/Editor/gitSync/useReconnectModalData.ts index 9109ef39af..3a11264931 100644 --- a/app/client/src/ce/pages/Editor/gitSync/useReconnectModalData.ts +++ b/app/client/src/ce/pages/Editor/gitSync/useReconnectModalData.ts @@ -5,6 +5,8 @@ import { createMessage, } from "@appsmith/constants/messages"; import { EditorNames } from "@appsmith/hooks"; +import { getApplicationByIdFromWorkspaces } from "@appsmith/selectors/applicationSelectors"; +import { useSelector } from "react-redux"; interface UseReconnectModalDataProps { pageId: string | null; @@ -12,10 +14,16 @@ interface UseReconnectModalDataProps { } function useReconnectModalData({ appId, pageId }: UseReconnectModalDataProps) { + const application = useSelector((state) => + getApplicationByIdFromWorkspaces(state, appId ?? ""), + ); + const basePageId = application?.pages?.find( + (page) => page.id === pageId, + )?.baseId; const editorURL = - pageId && + basePageId && builderURL({ - pageId, + basePageId, }); return { diff --git a/app/client/src/ce/reducers/entityReducers/actionsReducer.tsx b/app/client/src/ce/reducers/entityReducers/actionsReducer.tsx index f7363709b5..bf3adf65ac 100644 --- a/app/client/src/ce/reducers/entityReducers/actionsReducer.tsx +++ b/app/client/src/ce/reducers/entityReducers/actionsReducer.tsx @@ -31,7 +31,7 @@ export interface ActionDataWithMeta extends ActionData { export type ActionDataState = ActionData[]; export interface PartialActionData { isLoading: boolean; - config: { id: string }; + config: { id: string; baseId: string }; data?: ActionResponse; } @@ -111,7 +111,11 @@ export const handlers = { ) => { return draftMetaState.concat([ { - config: { ...action.payload, id: action.payload.name }, + config: { + ...action.payload, + baseId: action.payload.name, + id: action.payload.name, + }, isLoading: false, }, ]); @@ -196,7 +200,7 @@ export const handlers = { } else { const partialAction: PartialActionData = { isLoading: false, - config: { id: action.payload.id }, + config: { id: action.payload.id, baseId: action.payload.baseId }, data: action.payload.response, }; draftMetaState.push(partialAction); diff --git a/app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx b/app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx index d34b928557..a23d003986 100644 --- a/app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx +++ b/app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx @@ -780,6 +780,7 @@ export interface ApplicationsReduxState { export interface Application { id: string; + baseId: string; name: string; workspaceId: string; isPublic: boolean; diff --git a/app/client/src/ce/sagas/ActionExecution/ActionExecutionSagas.ts b/app/client/src/ce/sagas/ActionExecution/ActionExecutionSagas.ts index bc722bf1cd..c330e80021 100644 --- a/app/client/src/ce/sagas/ActionExecution/ActionExecutionSagas.ts +++ b/app/client/src/ce/sagas/ActionExecution/ActionExecutionSagas.ts @@ -42,8 +42,8 @@ import { } from "sagas/ActionExecution/geolocationSaga"; import { postMessageSaga } from "sagas/ActionExecution/PostMessageSaga"; import type { ActionDescription } from "@appsmith/workers/Evaluation/fns"; -import { getActionById } from "selectors/editorSelectors"; import type { AppState } from "@appsmith/reducers"; +import { getAction } from "@appsmith/selectors/entitiesSelector"; export interface TriggerMeta { source?: TriggerSource; @@ -71,15 +71,8 @@ export function* executeActionTriggers( break; case "CLEAR_PLUGIN_ACTION": yield put(clearActionResponse(trigger.payload.actionId)); - const action: ReturnType = yield select( - (state: AppState) => - getActionById(state, { - match: { - params: { - apiId: trigger.payload.actionId, - }, - }, - }), + const action: ReturnType = yield select( + (state: AppState) => getAction(state, trigger.payload.actionId), ); if (action) { yield put( diff --git a/app/client/src/ce/sagas/ApplicationSagas.tsx b/app/client/src/ce/sagas/ApplicationSagas.tsx index fdc3dcffff..56ae6423c0 100644 --- a/app/client/src/ce/sagas/ApplicationSagas.tsx +++ b/app/client/src/ce/sagas/ApplicationSagas.tsx @@ -68,6 +68,7 @@ import type { Workspace } from "@appsmith/constants/workspaceConstants"; import type { AppColorCode } from "constants/DefaultTheme"; import { getCurrentApplicationId, + getCurrentBasePageId, getCurrentPageId, getIsEditorInitialized, } from "selectors/editorSelectors"; @@ -92,7 +93,7 @@ import type { Datasource } from "entities/Datasource"; import { builderURL, viewerURL } from "@appsmith/RouteBuilder"; import { getDefaultPageId as selectDefaultPageId } from "sagas/selectors"; import PageApi from "api/PageApi"; -import { identity, isEmpty, merge, pickBy } from "lodash"; +import { isEmpty, merge } from "lodash"; import { checkAndGetPluginFormConfigsSaga } from "sagas/PluginSagas"; import { getPageList, @@ -100,6 +101,7 @@ import { } from "@appsmith/selectors/entitiesSelector"; import { getConfigInitialValues } from "components/formControls/utils"; import DatasourcesApi from "api/DatasourcesApi"; +import type { SetDefaultPageActionPayload } from "actions/pageActions"; import { resetApplicationWidgets } from "actions/pageActions"; import { setCanvasCardsState } from "actions/editorActions"; import { toast } from "design-system"; @@ -123,17 +125,10 @@ import { import equal from "fast-deep-equal"; import { getFromServerWhenNoPrefetchedResult } from "sagas/helper"; import { getIsAnvilLayoutEnabled } from "layoutSystems/anvil/integrations/selectors"; -export const getDefaultPageId = ( - pages?: ApplicationPagePayload[], -): string | undefined => { - let defaultPage: ApplicationPagePayload | undefined = undefined; - if (pages) { - defaultPage = pages.find((page) => page.isDefault); - if (!defaultPage) { - defaultPage = pages[0]; - } - } - return defaultPage ? defaultPage.id : undefined; + +export const findDefaultPage = (pages: ApplicationPagePayload[] = []) => { + const defaultPage = pages.find((page) => page.isDefault) ?? pages[0]; + return defaultPage; }; export let windowReference: Window | null = null; @@ -154,10 +149,11 @@ export function* publishApplicationSaga( }); const applicationId: string = yield select(getCurrentApplicationId); + const currentBasePageId: string = yield select(getCurrentBasePageId); const currentPageId: string = yield select(getCurrentPageId); const appicationViewPageUrl = viewerURL({ - pageId: currentPageId, + basePageId: currentBasePageId, }); yield put( @@ -208,9 +204,11 @@ export function* fetchAllApplicationsOfWorkspaceSaga( const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { const applications = response.data.map((application) => { + const defaultPage = findDefaultPage(application.pages); return { ...application, - defaultPageId: getDefaultPageId(application.pages), + defaultPageId: defaultPage?.id, + defaultBasePageId: defaultPage?.baseId, }; }); yield put({ @@ -241,15 +239,20 @@ export function* fetchAppAndPagesSaga( ) { try { const { pages, ...payload } = action.payload; - const params = pickBy(payload, identity); - if (params.pageId && params.applicationId) { - delete params.applicationId; + const request = { + applicationId: payload.applicationId, + pageId: payload.pageId, + mode: payload.mode, + }; + if (request.pageId && request.applicationId) { + delete request.applicationId; } const response: FetchApplicationResponse = yield call( getFromServerWhenNoPrefetchedResult, pages, - () => call(PageApi.fetchAppAndPages, params), + () => call(PageApi.fetchAppAndPages, request), ); + const isValidResponse: boolean = yield call(validateResponse, response); if (isValidResponse) { const prevPagesState: Page[] = yield select(getPageList); @@ -271,6 +274,7 @@ export function* fetchAppAndPagesSaga( pages: response.data.pages.map((page) => ({ pageName: page.name, pageId: page.id, + basePageId: page.baseId, isDefault: page.isDefault, isHidden: !!page.isHidden, slug: page.slug, @@ -280,6 +284,7 @@ export function* fetchAppAndPagesSaga( : pagePermissionsMap[page.id], })), applicationId: response.data.application?.id, + baseApplicationId: response.data.application?.baseId, }, }); @@ -328,12 +333,15 @@ export function* handleFetchApplicationError(error: any) { } export function* setDefaultApplicationPageSaga( - action: ReduxAction, + action: ReduxAction, ) { try { const defaultPageId: string = yield select(selectDefaultPageId); if (defaultPageId !== action.payload.id) { - const request: SetDefaultPageRequest = action.payload; + const request: SetDefaultPageRequest = { + ...action.payload, + pageId: action.payload.id, + }; const response: ApiResponse = yield call( ApplicationApi.setDefaultApplicationPage, request, @@ -341,7 +349,10 @@ export function* setDefaultApplicationPageSaga( const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { yield put( - setDefaultApplicationPageSuccess(request.id, request.applicationId), + setDefaultApplicationPageSuccess( + request.pageId, + request.applicationId, + ), ); } } @@ -564,9 +575,11 @@ export function* createApplicationSaga( ); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { + const defaultPage = findDefaultPage(response.data.pages); const application: ApplicationPayload = { ...response.data, - defaultPageId: getDefaultPageId(response.data.pages) as string, + defaultPageId: defaultPage?.id, + defaultBasePageId: defaultPage?.baseId, }; AnalyticsUtil.logEvent("CREATE_APP", { appName: application.name, @@ -601,13 +614,10 @@ export function* createApplicationSaga( payload: application.id, }); } - // Show cta's in empty canvas for the first page - yield put( - setCanvasCardsState(getDefaultPageId(response.data.pages) ?? ""), - ); + yield put(setCanvasCardsState(defaultPage?.id ?? "")); history.push( builderURL({ - pageId: application.defaultPageId as string, + basePageId: defaultPage?.baseId, }), ); @@ -645,10 +655,11 @@ export function* forkApplicationSaga( const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { yield put(resetCurrentApplication()); + const defaultPage = findDefaultPage(response.data.application.pages); const application: ApplicationPayload = { ...response.data.application, - // @ts-expect-error: response is of type unknown - defaultPageId: getDefaultPageId(response.data.application.pages), + defaultPageId: defaultPage?.id, + defaultBasePageId: defaultPage?.baseId, }; yield put({ type: ReduxActionTypes.FORK_APPLICATION_SUCCESS, @@ -666,18 +677,16 @@ export function* forkApplicationSaga( }); const pageURL = builderURL({ - pageId: application.defaultPageId as string, + basePageId: defaultPage?.baseId, params: { branch: null }, }); if (action.payload.editMode) { - const appId = application.id; - const pageId = application.defaultPageId; yield put({ type: ReduxActionTypes.FETCH_APPLICATION_INIT, payload: { - applicationId: appId, - pageId, + applicationId: application.id, + pageId: defaultPage?.id, }, }); } @@ -773,11 +782,9 @@ export function* importApplicationSaga( // @ts-expect-error: pages is of type any // TODO: Update route params here const { application } = response.data; - const defaultPage = pages.filter( - (eachPage: any) => !!eachPage.isDefault, - ); + const defaultPage = findDefaultPage(pages); const pageURL = builderURL({ - pageId: defaultPage[0].id, + basePageId: defaultPage?.baseId, }); if (isApplicationUrl) { const appId = application.id; diff --git a/app/client/src/ce/sagas/JSActionSagas.ts b/app/client/src/ce/sagas/JSActionSagas.ts index c5d87c97ec..87b5b7d20b 100644 --- a/app/client/src/ce/sagas/JSActionSagas.ts +++ b/app/client/src/ce/sagas/JSActionSagas.ts @@ -31,7 +31,10 @@ import { getPageNameByPageId, } from "@appsmith/selectors/entitiesSelector"; import history from "utils/history"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { + getCurrentBasePageId, + getCurrentPageId, +} from "selectors/editorSelectors"; import type { JSCollectionCreateUpdateResponse } from "@appsmith/api/JSActionAPI"; import JSActionAPI from "@appsmith/api/JSActionAPI"; import { @@ -75,6 +78,7 @@ import { getIDETypeByUrl } from "@appsmith/entities/IDE/utils"; import { IDE_TYPE } from "@appsmith/entities/IDE/constants"; import { CreateNewActionKey } from "@appsmith/entities/Engine/actionHelpers"; import { getAllActionTestPayloads } from "utils/storage"; +import { convertToBasePageIdSelector } from "selectors/pageListSelectors"; export function* fetchJSCollectionsSaga( action: EvaluationReduxAction, @@ -198,11 +202,12 @@ export function* copyJSCollectionSaga( export function* handleMoveOrCopySaga( actionPayload: ReduxAction, ) { - const { id, pageId } = actionPayload.payload; + const { baseId: baseCollectionId, pageId } = actionPayload.payload; + const basePageId: string = yield select(convertToBasePageIdSelector, pageId); history.push( jsCollectionIdURL({ - pageId: pageId, - collectionId: id, + basePageId, + baseCollectionId: baseCollectionId, }), ); } @@ -299,7 +304,7 @@ export function* deleteJSCollectionSaga( try { const id = actionPayload.payload.id; const currentUrl = window.location.pathname; - const pageId: string = yield select(getCurrentPageId); + const basePageId: string = yield select(getCurrentBasePageId); const response: ApiResponse = yield JSActionAPI.deleteJSCollection(id); const isValidResponse: boolean = yield validateResponse(response); const ideType = getIDETypeByUrl(currentUrl); @@ -313,7 +318,7 @@ export function* deleteJSCollectionSaga( if (ideType === IDE_TYPE.App) { yield call(handleJSEntityRedirect, id); } else { - history.push(builderURL({ pageId })); + history.push(builderURL({ basePageId })); } AppsmithConsole.info({ logType: LOG_TYPE.ENTITY_DELETED, @@ -327,11 +332,11 @@ export function* deleteJSCollectionSaga( }, }); yield put(deleteJSCollectionSuccess({ id })); - yield put(closeJsActionTabSuccess({ id, parentId: pageId })); + yield put(closeJsActionTabSuccess({ id, parentId: basePageId })); const widgets: CanvasWidgetsReduxState = yield select(getWidgets); - if (pageId) { + if (basePageId) { yield put( updateAndSaveLayout(widgets, { shouldReplay: false, @@ -388,7 +393,7 @@ export function* refactorJSObjectName( oldName: string, newName: string, ) { - const params: FetchPageRequest = { id: pageId, migrateDSL: true }; + const params: FetchPageRequest = { pageId, migrateDSL: true }; const pageResponse: FetchPageResponse = yield call(PageApi.fetchPage, params); // check if page request is successful const isPageRequestSuccessful: boolean = yield validateResponse(pageResponse); diff --git a/app/client/src/ce/sagas/PageSagas.tsx b/app/client/src/ce/sagas/PageSagas.tsx index 84b3a16931..6ef717976f 100644 --- a/app/client/src/ce/sagas/PageSagas.tsx +++ b/app/client/src/ce/sagas/PageSagas.tsx @@ -11,13 +11,24 @@ import { import type { ClonePageActionPayload, CreatePageActionPayload, + DeletePageActionPayload, + FetchPageActionPayload, + FetchPublishedPageActionPayload, + GenerateTemplatePageActionPayload, + SetPageOrderActionPayload, + SetupPageActionPayload, + SetupPublishedPageActionPayload, + UpdatePageActionPayload, +} from "actions/pageActions"; +import { + createPageAction, + fetchPageAction, + fetchPublishedPageAction, } from "actions/pageActions"; -import { createPage, fetchPublishedPage } from "actions/pageActions"; import { clonePageSuccess, deletePageSuccess, fetchAllPageEntityCompletion, - fetchPage, fetchPageSuccess, fetchPublishedPageSuccess, generateTemplateError, @@ -34,21 +45,15 @@ import { updateWidgetNameSuccess, } from "actions/pageActions"; import type { - ClonePageRequest, - CreatePageRequest, - DeletePageRequest, FetchPageRequest, FetchPageResponse, FetchPageResponseData, - FetchPublishedPageRequest, GenerateTemplatePageRequest, PageLayout, PageLayoutsRequest, SavePageRequest, SavePageResponse, SavePageResponseData, - SetPageOrderRequest, - UpdatePageRequest, UpdatePageResponse, UpdateWidgetNameRequest, UpdateWidgetNameResponse, @@ -63,7 +68,8 @@ import history from "utils/history"; import { isNameValid } from "utils/helpers"; import { extractCurrentDSL } from "utils/WidgetPropsUtils"; import { - getAllPageIds, + getAllPageIdentities, + getDefaultBasePageId, getDefaultPageId, getEditorConfigs, getWidgets, @@ -73,6 +79,7 @@ import type { ApiResponse } from "api/ApiResponses"; import { combinedPreviewModeSelector, getCurrentApplicationId, + getCurrentBasePageId, getCurrentLayoutId, getCurrentPageId, getCurrentPageName, @@ -144,6 +151,7 @@ import { getCurrentWorkspaceId } from "@appsmith/selectors/selectedWorkspaceSele import { ActionExecutionContext } from "entities/Action"; import type { LayoutSystemTypes } from "layoutSystems/types"; import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors"; +import { convertToBasePageIdSelector } from "selectors/pageListSelectors"; export const checkIfMigrationIsNeeded = ( fetchPageResponse?: FetchPageResponse, @@ -162,7 +170,7 @@ export const getWidgetName = (state: AppState, widgetId: string) => export function* refreshTheApp() { try { const currentPageId: string = yield select(getCurrentPageId); - const defaultPageId: string = yield select(getDefaultPageId); + const defaultBasePageId: string = yield select(getDefaultBasePageId); const pagesList: Page[] = yield select(getPageList); const gitBranch: string = yield select(getCurrentGitBranch); @@ -174,7 +182,7 @@ export function* refreshTheApp() { } else { location.assign( builderURL({ - pageId: defaultPageId, + basePageId: defaultBasePageId, branch: gitBranch, }), ); @@ -284,17 +292,19 @@ export function* handleFetchedPage({ export const getLastUpdateTime = (pageResponse: FetchPageResponse): number => pageResponse.data.lastUpdatedTime; -export function* fetchPageSaga( - pageRequestAction: ReduxAction, -) { +export function* fetchPageSaga(action: ReduxAction) { try { - const { id, isFirstLoad, pageWithMigratedDsl } = pageRequestAction.payload; + const { + id: pageId, + isFirstLoad = false, + pageWithMigratedDsl, + } = action.payload; PerformanceTracker.startAsyncTracking( PerformanceTransactionName.FETCH_PAGE_API, - { pageId: id }, + { pageId }, ); - const params: FetchPageRequest = { id, migrateDSL: true }; + const params: FetchPageRequest = { pageId, migrateDSL: true }; const fetchPageResponse: FetchPageResponse = yield call( getFromServerWhenNoPrefetchedResult, pageWithMigratedDsl, @@ -303,7 +313,7 @@ export function* fetchPageSaga( yield handleFetchedPage({ fetchPageResponse, - pageId: id, + pageId, isFirstLoad, }); @@ -328,16 +338,11 @@ export function* fetchPageSaga( } export function* fetchPublishedPageSaga( - pageRequestAction: ReduxAction<{ - pageId: string; - bustCache: boolean; - firstLoad: boolean; - pageWithMigratedDsl?: FetchPageResponse; - }>, + action: ReduxAction, ) { try { const { bustCache, firstLoad, pageId, pageWithMigratedDsl } = - pageRequestAction.payload; + action.payload; PerformanceTracker.startAsyncTracking( PerformanceTransactionName.FETCH_PAGE_API, { @@ -345,15 +350,11 @@ export function* fetchPublishedPageSaga( published: true, }, ); - const request: FetchPublishedPageRequest = { - pageId, - bustCache, - }; - + const params = { pageId, bustCache }; const response: FetchPageResponse = yield call( getFromServerWhenNoPrefetchedResult, pageWithMigratedDsl, - () => call(PageApi.fetchPublishedPage, request), + () => call(PageApi.fetchPublishedPage, params), ); const isValidResponse: boolean = yield validateResponse(response); @@ -415,10 +416,14 @@ export function* fetchPublishedPageSaga( export function* fetchAllPublishedPagesSaga() { try { - const pageIds: string[] = yield select(getAllPageIds); + const pageIdentities: { pageId: string; basePageId: string }[] = + yield select(getAllPageIdentities); yield all( - pageIds.map((pageId: string) => { - return call(PageApi.fetchPublishedPage, { pageId, bustCache: true }); + pageIdentities.map((pageIdentity) => { + return call(PageApi.fetchPublishedPage, { + pageId: pageIdentity.pageId, + bustCache: true, + }); }), ); } catch (error) { @@ -642,7 +647,7 @@ export function* saveLayoutSaga(action: ReduxAction<{ isRetry?: boolean }>) { } export function* createNewPageFromEntity( - createPageAction: ReduxAction, + action: ReduxAction, ) { try { const layoutSystemType: LayoutSystemTypes = @@ -666,7 +671,7 @@ export function* createNewPageFromEntity( }, ]; - const { applicationId, name } = createPageAction?.payload || {}; + const { applicationId, name } = action?.payload || {}; const workspaceId: string = yield select(getCurrentWorkspaceId); const instanceId: string | undefined = yield select(getInstanceId); @@ -676,7 +681,7 @@ export function* createNewPageFromEntity( // At the end we call the `createPage` saga that actually calls the API to // create a page yield put( - createPage( + createPageAction( applicationId, name, defaultPageLayouts, @@ -693,9 +698,7 @@ export function* createNewPageFromEntity( }); } } -export function* createPageSaga( - createPageAction: ReduxAction, -) { +export function* createPageSaga(action: ReduxAction) { try { const layoutSystemType: LayoutSystemTypes = yield select(getLayoutSystemType); @@ -706,14 +709,15 @@ export function* createPageSaga( mainCanvasProps.width, ); - const request: CreatePageRequest = createPageAction.payload; - const response: FetchPageResponse = yield call(PageApi.createPage, request); + const params = { ...action.payload }; + const response: FetchPageResponse = yield call(PageApi.createPage, params); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { yield put({ type: ReduxActionTypes.CREATE_PAGE_SUCCESS, payload: { pageId: response.data.id, + basePageId: response.data.baseId, pageName: response.data.name, layoutId: response.data.layouts[0].id, slug: response.data.slug, @@ -739,7 +743,7 @@ export function* createPageSaga( // route to generate template for new page created history.push( builderURL({ - pageId: response.data.id, + basePageId: response.data.baseId, }), ); } @@ -753,16 +757,13 @@ export function* createPageSaga( } } -export function* updatePageSaga(action: ReduxAction) { +export function* updatePageSaga(action: ReduxAction) { + const params = { ...action.payload, pageId: action.payload.id }; try { - const request: UpdatePageRequest = action.payload; - - // to be done in backend - request.customSlug = request.customSlug?.replaceAll(" ", "-"); - + params.customSlug = params.customSlug?.replaceAll(" ", "-"); const response: ApiResponse = yield call( PageApi.updatePage, - request, + params, ); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { @@ -771,23 +772,25 @@ export function* updatePageSaga(action: ReduxAction) { } catch (error) { yield put( updatePageError({ - request: action.payload, + request: params, error, }), ); } } -export function* deletePageSaga(action: ReduxAction) { +export function* deletePageSaga(action: ReduxAction) { try { - const request: DeletePageRequest = action.payload; - const defaultPageId: string = yield select( - (state: AppState) => state.entities.pageList.defaultPageId, - ); - if (defaultPageId === request.id) { + const { id: pageId } = action.payload; + const defaultPageId: string = yield select(getDefaultPageId); + const defaultBasePageId: string = yield select(getDefaultBasePageId); + const currentPageId: string = yield select(getCurrentPageId); + + if (defaultPageId === pageId) { throw Error("Cannot delete the home page."); } else { - const response: ApiResponse = yield call(PageApi.deletePage, request); + const params = { pageId: pageId }; + const response: ApiResponse = yield call(PageApi.deletePage, params); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { yield put(deletePageSuccess()); @@ -796,18 +799,15 @@ export function* deletePageSaga(action: ReduxAction) { yield put({ type: ReduxActionTypes.FETCH_PAGE_DSL_SUCCESS, payload: { - pageId: request.id, + pageId, dsl: undefined, }, }); // Update route params here - const currentPageId: string = yield select( - (state: AppState) => state.entities.pageList.currentPageId, - ); - if (currentPageId === action.payload.id) + if (currentPageId === pageId) history.push( builderURL({ - pageId: defaultPageId, + basePageId: defaultBasePageId, }), ); } @@ -826,17 +826,22 @@ export function* clonePageSaga( clonePageAction: ReduxAction, ) { try { - const request: ClonePageRequest = clonePageAction.payload; + const request = { + pageId: clonePageAction.payload.id, + }; + const response: FetchPageResponse = yield call(PageApi.clonePage, request); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { yield put( - clonePageSuccess( - response.data.id, - response.data.name, - response.data.layouts[0].id, - response.data.slug, - ), + clonePageSuccess({ + pageId: response.data.id, + basePageId: response.data.baseId, + pageName: response.data.name, + layoutId: response.data.layouts[0].id, + slug: response.data.slug, + isDefault: false, + }), ); // Add this to the page DSLs for entity explorer // We're not sending the `dslTransformer` to the `extractCurrentDSL` function @@ -887,7 +892,7 @@ export function* clonePageSaga( if (!clonePageAction.payload.blockNavigation) { history.push( builderURL({ - pageId: response.data.id, + basePageId: response.data.baseId, }), ); } @@ -1100,7 +1105,7 @@ export function* fetchPageDSLSaga( layoutSystemType, mainCanvasProps.width, ); - const params: FetchPageRequest = { id: pageId, migrateDSL: true }; + const params: FetchPageRequest = { pageId, migrateDSL: true }; const fetchPageResponse: FetchPageResponse = yield call( getFromServerWhenNoPrefetchedResult, pageDSL, @@ -1184,14 +1189,15 @@ export function* populatePageDSLsSaga(action?: { } } -/** - * saga to update the page order - * - * @param action - */ -export function* setPageOrderSaga(action: ReduxAction) { +export function* setPageOrderSaga( + action: ReduxAction, +) { try { - const request: SetPageOrderRequest = action.payload; + const request = { + applicationId: action.payload.applicationId, + pageId: action.payload.pageId, + order: action.payload.order, + }; const response: ApiResponse = yield call(PageApi.setPageOrder, request); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { @@ -1214,7 +1220,7 @@ export function* setPageOrderSaga(action: ReduxAction) { } export function* generateTemplatePageSaga( - action: ReduxAction, + action: ReduxAction, ) { try { const request: GenerateTemplatePageRequest = action.payload; @@ -1246,7 +1252,7 @@ export function* generateTemplatePageSaga( isFirstLoad: true, }); - yield put(fetchPage(pageId)); + yield put(fetchPageAction(pageId)); // trigger evaluation after completion of page success & fetch actions for page + fetch jsobject for page @@ -1275,10 +1281,13 @@ export function* generateTemplatePageSaga( executePageLoadActions(ActionExecutionContext.GENERATE_CRUD_PAGE), ]), ); - + const basePageId: string = yield select( + convertToBasePageIdSelector, + pageId, + ); history.replace( builderURL({ - pageId, + basePageId, }), ); // TODO : Add it to onSuccessCallback @@ -1324,14 +1333,14 @@ export function* setCanvasCardsStateSaga(action: ReduxAction) { } export function* setPreviewModeInitSaga(action: ReduxAction) { - const currentPageId: string = yield select(getCurrentPageId); + const currentBasePageId: string = yield select(getCurrentBasePageId); const isPreviewMode: boolean = yield select(combinedPreviewModeSelector); if (action.payload) { // we animate out elements and then move to the canvas yield put(setPreviewModeAction(action.payload)); history.push( builderURL({ - pageId: currentPageId, + basePageId: currentBasePageId, }), ); } else if (isPreviewMode) { @@ -1346,15 +1355,19 @@ export function* setPreviewModeInitSaga(action: ReduxAction) { } } -export function* setupPageSaga(action: ReduxAction) { +export function* setupPageSaga(action: ReduxAction) { try { - const { id, isFirstLoad, pageWithMigratedDsl } = action.payload; + const { + id: pageId, + isFirstLoad = false, + pageWithMigratedDsl, + } = action.payload; /* Added the first line for isPageSwitching redux state to be true when page is being fetched to fix scroll position issue. Added the second line for sync call instead of async (due to first line) as it was leading to issue with on page load actions trigger. */ - yield put(fetchPage(id, isFirstLoad, pageWithMigratedDsl)); + yield put(fetchPageAction(pageId, isFirstLoad, pageWithMigratedDsl)); yield take(ReduxActionTypes.FETCH_PAGE_SUCCESS); yield put({ @@ -1369,12 +1382,7 @@ export function* setupPageSaga(action: ReduxAction) { } export function* setupPublishedPageSaga( - action: ReduxAction<{ - pageId: string; - bustCache: boolean; - firstLoad: boolean; - pageWithMigratedDsl?: FetchPageResponse; - }>, + action: ReduxAction, ) { try { const { bustCache, firstLoad, pageId, pageWithMigratedDsl } = @@ -1385,7 +1393,12 @@ export function* setupPublishedPageSaga( Added the second line for sync call instead of async (due to first line) as it was leading to issue with on page load actions trigger. */ yield put( - fetchPublishedPage(pageId, bustCache, firstLoad, pageWithMigratedDsl), + fetchPublishedPageAction( + pageId, + bustCache, + firstLoad, + pageWithMigratedDsl, + ), ); yield take(ReduxActionTypes.FETCH_PUBLISHED_PAGE_SUCCESS); diff --git a/app/client/src/ce/sagas/__tests__/PageSaga.test.ts b/app/client/src/ce/sagas/__tests__/PageSaga.test.ts index 50a5127a6e..d9ff1829ca 100644 --- a/app/client/src/ce/sagas/__tests__/PageSaga.test.ts +++ b/app/client/src/ce/sagas/__tests__/PageSaga.test.ts @@ -3,12 +3,17 @@ import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; import { testSaga } from "redux-saga-test-plan"; import { setupPageSaga, setupPublishedPageSaga } from "../PageSagas"; import mockResponse from "./mockConsolidatedApiResponse.json"; -import type { FetchPageRequest, FetchPageResponse } from "api/PageApi"; -import { fetchPage, fetchPublishedPage } from "actions/pageActions"; +import type { FetchPageResponse } from "api/PageApi"; +import { + fetchPageAction, + fetchPublishedPageAction, + type SetupPageActionPayload, + type SetupPublishedPageActionPayload, +} from "actions/pageActions"; describe("ce/PageSaga", () => { it("should put setupPageSaga with pageWithMigratedDsl", () => { - const action: ReduxAction = { + const action: ReduxAction = { type: ReduxActionTypes.SETUP_PAGE_INIT, payload: { id: "pageId", @@ -20,7 +25,7 @@ describe("ce/PageSaga", () => { testSaga(setupPageSaga, action) .next() .put( - fetchPage( + fetchPageAction( action.payload.id, action.payload.isFirstLoad, action.payload.pageWithMigratedDsl, @@ -35,12 +40,7 @@ describe("ce/PageSaga", () => { }); it("should put setupPublishedPageSaga with pageWithMigratedDsl", () => { - const action: ReduxAction<{ - pageId: string; - bustCache: boolean; - firstLoad: boolean; - pageWithMigratedDsl?: FetchPageResponse; - }> = { + const action: ReduxAction = { type: ReduxActionTypes.SETUP_PAGE_INIT, payload: { pageId: "pageId", @@ -54,7 +54,7 @@ describe("ce/PageSaga", () => { testSaga(setupPublishedPageSaga, action) .next() .put( - fetchPublishedPage( + fetchPublishedPageAction( action.payload.pageId, action.payload.bustCache, action.payload.firstLoad, diff --git a/app/client/src/ce/sagas/__tests__/mockConsolidatedApiResponse.json b/app/client/src/ce/sagas/__tests__/mockConsolidatedApiResponse.json index 2d4f531096..9cd7ac1304 100644 --- a/app/client/src/ce/sagas/__tests__/mockConsolidatedApiResponse.json +++ b/app/client/src/ce/sagas/__tests__/mockConsolidatedApiResponse.json @@ -11,6 +11,7 @@ }, "data": { "id": "661c28791c2412092c170119", + "baseId": "661c28791c2412092c170118", "name": "Page1", "slug": "page1", "applicationId": "661c28791c2412092c170116", diff --git a/app/client/src/ce/sagas/analyticsSaga.ts b/app/client/src/ce/sagas/analyticsSaga.ts index cba8509da8..612e14eb2f 100644 --- a/app/client/src/ce/sagas/analyticsSaga.ts +++ b/app/client/src/ce/sagas/analyticsSaga.ts @@ -2,10 +2,7 @@ import { getCurrentUser } from "selectors/usersSelectors"; import { getInstanceId } from "@appsmith/selectors/tenantSelectors"; import { call, select } from "redux-saga/effects"; import type { APP_MODE } from "entities/App"; -import { - getCurrentApplication, - getCurrentPageId, -} from "selectors/editorSelectors"; +import { getCurrentPageId } from "selectors/editorSelectors"; import type { TriggerMeta } from "@appsmith/sagas/ActionExecution/ActionExecutionSagas"; import { TriggerKind } from "constants/AppsmithActionConstants/ActionConstants"; import { isArray } from "lodash"; @@ -14,6 +11,7 @@ import { getAppMode } from "@appsmith/selectors/entitiesSelector"; import type { AppState } from "@appsmith/reducers"; import { getWidget } from "sagas/selectors"; import { getUserSource } from "@appsmith/utils/AnalyticsUtil"; +import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; export interface UserAndAppDetails { pageId: string; diff --git a/app/client/src/ce/selectors/entitiesSelector.ts b/app/client/src/ce/selectors/entitiesSelector.ts index a42257098b..d671098cd9 100644 --- a/app/client/src/ce/selectors/entitiesSelector.ts +++ b/app/client/src/ce/selectors/entitiesSelector.ts @@ -542,7 +542,8 @@ export const getQueryName = (state: AppState, actionId: string): string => { return action?.config.name ?? ""; }; -export const getCurrentPageId = (state: AppState) => +// * This is only for internal use to avoid cyclic dependency issue +const getCurrentPageId = (state: AppState) => state.entities.pageList.currentPageId; export const getDatasourcePlugins = createSelector(getPlugins, (plugins) => { @@ -735,6 +736,17 @@ export const getAction = ( return action ? action.config : undefined; }; +export const getActionByBaseId = ( + state: AppState, + baseActionId: string, +): Action | undefined => { + const action = find( + state.entities.actions, + (a) => a.config.baseId === baseActionId, + ); + return action ? action.config : undefined; +}; + export const getActionData = ( state: AppState, actionId: string, @@ -743,10 +755,21 @@ export const getActionData = ( return action ? action.data : undefined; }; -export const getJSCollection = (state: AppState, actionId: string) => { +export const getJSCollection = (state: AppState, collectionId: string) => { const jsaction = find( state.entities.jsActions, - (a) => a.config.id === actionId, + (a) => a.config.id === collectionId, + ); + return jsaction && jsaction.config; +}; + +export const getJsCollectionByBaseId = ( + state: AppState, + baseCollectionId: string, +) => { + const jsaction = find( + state.entities.jsActions, + (a) => a.config.baseId === baseCollectionId, ); return jsaction && jsaction.config; }; @@ -1519,7 +1542,7 @@ export const getQuerySegmentItems = createSelector( return { icon: ActionUrlIcon(iconUrl), title: action.config.name, - key: action.config.id, + key: action.config.baseId, type: action.config.pluginType, group, }; @@ -1533,7 +1556,7 @@ export const getJSSegmentItems = createSelector( const items: EntityItem[] = jsActions.map((js) => ({ icon: JsFileIconV2(), title: js.config.name, - key: js.config.id, + key: js.config.baseId, type: PluginType.JS, })); return items; diff --git a/app/client/src/ce/utils/actionExecutionUtils.test.ts b/app/client/src/ce/utils/actionExecutionUtils.test.ts index 23edd7864a..f1f1e7d8a9 100644 --- a/app/client/src/ce/utils/actionExecutionUtils.test.ts +++ b/app/client/src/ce/utils/actionExecutionUtils.test.ts @@ -18,6 +18,7 @@ describe("getTestPayloadFromCollectionData", () => { isLoading: false, config: { id: "", + baseId: "", applicationId: "", workspaceId: "", name: "", @@ -37,6 +38,7 @@ describe("getTestPayloadFromCollectionData", () => { isLoading: false, config: { id: "", + baseId: "", applicationId: "", workspaceId: "", name: "", diff --git a/app/client/src/ce/utils/serviceWorkerUtils.test.ts b/app/client/src/ce/utils/serviceWorkerUtils.test.ts index 30c43429d8..46a1dd5335 100644 --- a/app/client/src/ce/utils/serviceWorkerUtils.test.ts +++ b/app/client/src/ce/utils/serviceWorkerUtils.test.ts @@ -18,13 +18,13 @@ import { Request as NFRequest, Response as NFResponse } from "node-fetch"; delete: jest.fn(), }; -const applicationId = "b0123456789abcdef0000000"; -const pageId = "a0123456789abcdef0000000"; +const baseApplicationId = "b0123456789abcdef0000000"; +const basePageId = "a0123456789abcdef0000000"; describe("serviceWorkerUtils", () => { describe("matchBuilderPath", () => { it("should match the standard builder path", () => { - const pathName = `/app/applicationSlug/pageSlug-${pageId}/edit`; + const pathName = `/app/applicationSlug/pageSlug-${basePageId}/edit`; const options = { end: false }; const result = matchBuilderPath(pathName, options); @@ -32,14 +32,14 @@ describe("serviceWorkerUtils", () => { if (result) { expect(result.params).toHaveProperty("applicationSlug"); expect(result.params).toHaveProperty("pageSlug"); - expect(result.params).toHaveProperty("pageId", pageId); + expect(result.params).toHaveProperty("basePageId", basePageId); } else { fail("Expected result to be truthy"); } }); - it("should match the standard builder path for alphanumeric pageId", () => { - const pathName = `/app/applicationSlug/pageSlug-${pageId}/edit`; + it("should match the standard builder path for alphanumeric basePageId", () => { + const pathName = `/app/applicationSlug/pageSlug-${basePageId}/edit`; const options = { end: false }; const result = matchBuilderPath(pathName, options); @@ -47,35 +47,38 @@ describe("serviceWorkerUtils", () => { if (result) { expect(result.params).toHaveProperty("applicationSlug"); expect(result.params).toHaveProperty("pageSlug"); - expect(result.params).toHaveProperty("pageId", pageId); + expect(result.params).toHaveProperty("basePageId", basePageId); } else { fail("Expected result to be truthy"); } }); it("should match the custom builder path", () => { - const pathName = `/app/customSlug-custom-${pageId}/edit`; + const pathName = `/app/customSlug-custom-${basePageId}/edit`; const options = { end: false }; const result = matchBuilderPath(pathName, options); expect(result).toBeTruthy(); if (result) { expect(result.params).toHaveProperty("customSlug"); - expect(result.params).toHaveProperty("pageId", pageId); + expect(result.params).toHaveProperty("basePageId", basePageId); } else { fail("Expected result to be truthy"); } }); it("should match the deprecated builder path", () => { - const pathName = `/applications/${applicationId}/pages/${pageId}/edit`; + const pathName = `/applications/${baseApplicationId}/pages/${basePageId}/edit`; const options = { end: false }; const result = matchBuilderPath(pathName, options); expect(result).toBeTruthy(); if (result) { - expect(result.params).toHaveProperty("applicationId", applicationId); - expect(result.params).toHaveProperty("pageId", pageId); + expect(result.params).toHaveProperty( + "baseApplicationId", + baseApplicationId, + ); + expect(result.params).toHaveProperty("basePageId", basePageId); } else { fail("Expected result to be truthy"); } @@ -89,7 +92,7 @@ describe("serviceWorkerUtils", () => { expect(result).toBeFalsy(); }); - it("should not match when no pageId is present", () => { + it("should not match when no basePageId is present", () => { const pathName = "/app/applicationSlug/pageSlug-edit"; const options = { end: false }; const result = matchBuilderPath(pathName, options); @@ -98,14 +101,14 @@ describe("serviceWorkerUtils", () => { }); it("should match when the path is edit widgets", () => { - const pathName = `/app/applicationSlug/pageSlug-${pageId}/edit/widgets/t36hb2zukr`; + const pathName = `/app/applicationSlug/pageSlug-${basePageId}/edit/widgets/t36hb2zukr`; const options = { end: false }; const result = matchBuilderPath(pathName, options); if (result) { expect(result.params).toHaveProperty("applicationSlug"); expect(result.params).toHaveProperty("pageSlug"); - expect(result.params).toHaveProperty("pageId", pageId); + expect(result.params).toHaveProperty("basePageId", basePageId); } else { fail("Expected result to be truthy"); } @@ -114,46 +117,49 @@ describe("serviceWorkerUtils", () => { describe("matchViewerPath", () => { it("should match the standard viewer path", () => { - const pathName = `/app/applicationSlug/pageSlug-${pageId}`; + const pathName = `/app/applicationSlug/pageSlug-${basePageId}`; const result = matchViewerPath(pathName); expect(result).toBeTruthy(); if (result) { expect(result.params).toHaveProperty("applicationSlug"); expect(result.params).toHaveProperty("pageSlug"); - expect(result.params).toHaveProperty("pageId", pageId); + expect(result.params).toHaveProperty("basePageId", basePageId); } else { fail("Expected result to be truthy"); } }); it("should match the custom viewer path", () => { - const pathName = `/app/customSlug-custom-${pageId}`; + const pathName = `/app/customSlug-custom-${basePageId}`; const result = matchViewerPath(pathName); expect(result).toBeTruthy(); if (result) { expect(result.params).toHaveProperty("customSlug"); - expect(result.params).toHaveProperty("pageId", pageId); + expect(result.params).toHaveProperty("basePageId", basePageId); } else { fail("Expected result to be truthy"); } }); it("should match the deprecated viewer path", () => { - const pathName = `/applications/${applicationId}/pages/${pageId}`; + const pathName = `/applications/${baseApplicationId}/pages/${basePageId}`; const result = matchViewerPath(pathName); expect(result).toBeTruthy(); if (result) { - expect(result.params).toHaveProperty("applicationId", applicationId); - expect(result.params).toHaveProperty("pageId", pageId); + expect(result.params).toHaveProperty( + "baseApplicationId", + baseApplicationId, + ); + expect(result.params).toHaveProperty("basePageId", basePageId); } else { fail("Expected result to be truthy"); } }); - it("should not match when no pageId is present", () => { + it("should not match when no basePageId is present", () => { const pathName = "/app/applicationSlug/pageSlug"; const result = matchViewerPath(pathName); @@ -187,12 +193,12 @@ describe("serviceWorkerUtils", () => { describe("getApplicationParamsFromUrl", () => { it("should parse URL and return correct params for builder path", () => { const url = new URL( - `https://app.appsmith.com/app/my-app/page-${pageId}/edit?branch=main`, + `https://app.appsmith.com/app/my-app/page-${basePageId}/edit?branch=main`, ); const expectedParams: TApplicationParams = { origin: "https://app.appsmith.com", - pageId, - applicationId: undefined, + basePageId, + baseApplicationId: undefined, branchName: "main", appMode: APP_MODE.EDIT, }; @@ -202,12 +208,12 @@ describe("serviceWorkerUtils", () => { it("should parse URL and return correct params for viewer path", () => { const url = new URL( - `https://app.appsmith.com/app/my-app/page-${pageId}?branch=main`, + `https://app.appsmith.com/app/my-app/page-${basePageId}?branch=main`, ); const expectedParams: TApplicationParams = { origin: "https://app.appsmith.com", - pageId, - applicationId: undefined, + basePageId, + baseApplicationId: undefined, branchName: "main", appMode: APP_MODE.PUBLISHED, }; @@ -222,12 +228,12 @@ describe("serviceWorkerUtils", () => { it("should parse deprecated builder path and return correct params", () => { const url = new URL( - `https://app.appsmith.com/applications/${applicationId}/pages/${pageId}/edit?branch=main`, + `https://app.appsmith.com/applications/${baseApplicationId}/pages/${basePageId}/edit?branch=main`, ); const expectedParams: TApplicationParams = { origin: "https://app.appsmith.com", - pageId, - applicationId, + basePageId, + baseApplicationId, branchName: "main", appMode: APP_MODE.EDIT, }; @@ -237,12 +243,12 @@ describe("serviceWorkerUtils", () => { it("should parse deprecated viewer path and return correct params", () => { const url = new URL( - `https://app.appsmith.com/applications/${applicationId}/pages/${pageId}?branch=main`, + `https://app.appsmith.com/applications/${baseApplicationId}/pages/${basePageId}?branch=main`, ); const expectedParams: TApplicationParams = { origin: "https://app.appsmith.com", - pageId, - applicationId, + basePageId, + baseApplicationId, branchName: "main", appMode: APP_MODE.PUBLISHED, }; @@ -252,12 +258,12 @@ describe("serviceWorkerUtils", () => { it("should parse custom builder path and return correct params", () => { const url = new URL( - `https://app.appsmith.com/app/custom-app-${pageId}/edit?branch=main`, + `https://app.appsmith.com/app/custom-app-${basePageId}/edit?branch=main`, ); const expectedParams: TApplicationParams = { origin: "https://app.appsmith.com", - pageId, - applicationId: undefined, + basePageId, + baseApplicationId: undefined, branchName: "main", appMode: APP_MODE.EDIT, }; @@ -267,12 +273,12 @@ describe("serviceWorkerUtils", () => { it("should parse custom viewer path and return correct params", () => { const url = new URL( - `https://app.appsmith.com/app/custom-app-${pageId}?branch=main`, + `https://app.appsmith.com/app/custom-app-${basePageId}?branch=main`, ); const expectedParams: TApplicationParams = { origin: "https://app.appsmith.com", - pageId, - applicationId: undefined, + basePageId, + baseApplicationId: undefined, branchName: "main", appMode: APP_MODE.PUBLISHED, }; @@ -282,12 +288,12 @@ describe("serviceWorkerUtils", () => { it("should parse URL and return params with empty branch name if branch query param is not present", () => { const url = new URL( - `https://app.appsmith.com/app/my-app/page-${pageId}/edit`, + `https://app.appsmith.com/app/my-app/page-${basePageId}/edit`, ); const expectedParams: TApplicationParams = { origin: "https://app.appsmith.com", - pageId, - applicationId: undefined, + basePageId, + baseApplicationId: undefined, branchName: "", appMode: APP_MODE.EDIT, }; @@ -301,7 +307,7 @@ describe("serviceWorkerUtils", () => { (global as any).Request = NFRequest; }); - it("should return null if pageId is not provided", () => { + it("should return null if basePageId is not provided", () => { const params: TApplicationParams = { origin: "https://app.appsmith.com", branchName: "main", @@ -314,8 +320,8 @@ describe("serviceWorkerUtils", () => { it("should create request for EDIT mode with applicationId", () => { const params: TApplicationParams = { origin: "https://app.appsmith.com", - pageId, - applicationId, + basePageId, + baseApplicationId, branchName: "main", appMode: APP_MODE.EDIT, }; @@ -323,7 +329,7 @@ describe("serviceWorkerUtils", () => { const request = getConsolidatedApiPrefetchRequest(params); expect(request).toBeInstanceOf(Request); expect(request?.url).toBe( - `https://app.appsmith.com/api/v1/consolidated-api/edit?defaultPageId=${pageId}&applicationId=${applicationId}`, + `https://app.appsmith.com/api/v1/consolidated-api/edit?defaultPageId=${basePageId}&applicationId=${baseApplicationId}`, ); expect(request?.method).toBe("GET"); expect(request?.headers.get("Branchname")).toBe("main"); @@ -332,8 +338,8 @@ describe("serviceWorkerUtils", () => { it("should create request for PUBLISHED mode with applicationId", () => { const params: TApplicationParams = { origin: "https://app.appsmith.com", - pageId, - applicationId, + basePageId, + baseApplicationId, branchName: "main", appMode: APP_MODE.PUBLISHED, }; @@ -341,7 +347,7 @@ describe("serviceWorkerUtils", () => { const request = getConsolidatedApiPrefetchRequest(params); expect(request).toBeInstanceOf(Request); expect(request?.url).toBe( - `https://app.appsmith.com/api/v1/consolidated-api/view?defaultPageId=${pageId}&applicationId=${applicationId}`, + `https://app.appsmith.com/api/v1/consolidated-api/view?defaultPageId=${basePageId}&applicationId=${baseApplicationId}`, ); expect(request?.method).toBe("GET"); expect(request?.headers.get("Branchname")).toBe("main"); @@ -350,7 +356,7 @@ describe("serviceWorkerUtils", () => { it("should create request for EDIT mode without applicationId", () => { const params: TApplicationParams = { origin: "https://app.appsmith.com", - pageId: "page123", + basePageId: "page123", branchName: "main", appMode: APP_MODE.EDIT, }; @@ -367,7 +373,7 @@ describe("serviceWorkerUtils", () => { it("should create request for PUBLISHED mode without applicationId", () => { const params: TApplicationParams = { origin: "https://app.appsmith.com", - pageId: "page123", + basePageId: "page123", branchName: "main", appMode: APP_MODE.PUBLISHED, }; @@ -384,7 +390,7 @@ describe("serviceWorkerUtils", () => { it("should return null for an unknown app mode", () => { const params: TApplicationParams = { origin: "https://app.appsmith.com", - pageId: "page123", + basePageId: "page123", branchName: "main", appMode: "UNKNOWN" as APP_MODE, }; @@ -399,7 +405,7 @@ describe("serviceWorkerUtils", () => { origin: "https://app.appsmith.com", branchName: "main", appMode: APP_MODE.EDIT, - pageId: "page123", + basePageId: "page123", }; const requests = getPrefetchRequests(params); expect(requests).toHaveLength(1); diff --git a/app/client/src/ce/utils/serviceWorkerUtils.ts b/app/client/src/ce/utils/serviceWorkerUtils.ts index 2589507724..f04645305c 100644 --- a/app/client/src/ce/utils/serviceWorkerUtils.ts +++ b/app/client/src/ce/utils/serviceWorkerUtils.ts @@ -12,14 +12,14 @@ import { } from "@appsmith/constants/routes/appRoutes"; interface TMatchResult { - pageId?: string; - applicationId?: string; + basePageId?: string; + baseApplicationId?: string; } export interface TApplicationParams { origin: string; - pageId?: string; - applicationId?: string; + basePageId?: string; + baseApplicationId?: string; branchName: string; appMode: APP_MODE; } @@ -69,8 +69,8 @@ export const getApplicationParamsFromUrl = ( if (matchedBuilder) { return { origin: url.origin, - pageId: matchedBuilder.params.pageId, - applicationId: matchedBuilder.params.applicationId, + basePageId: matchedBuilder.params.basePageId, + baseApplicationId: matchedBuilder.params.baseApplicationId, branchName, appMode: APP_MODE.EDIT, }; @@ -79,8 +79,8 @@ export const getApplicationParamsFromUrl = ( if (matchedViewer) { return { origin: url.origin, - pageId: matchedViewer.params.pageId, - applicationId: matchedViewer.params.applicationId, + basePageId: matchedViewer.params.basePageId, + baseApplicationId: matchedViewer.params.baseApplicationId, branchName, appMode: APP_MODE.PUBLISHED, }; @@ -95,20 +95,20 @@ export const getApplicationParamsFromUrl = ( export const getConsolidatedApiPrefetchRequest = ( applicationProps: TApplicationParams, ) => { - const { applicationId, appMode, branchName, origin, pageId } = + const { appMode, baseApplicationId, basePageId, branchName, origin } = applicationProps; const headers = new Headers(); const searchParams = new URLSearchParams(); - if (!pageId) { + if (!basePageId) { return null; } - searchParams.append("defaultPageId", pageId); + searchParams.append("defaultPageId", basePageId); - if (applicationId) { - searchParams.append("applicationId", applicationId); + if (baseApplicationId) { + searchParams.append("applicationId", baseApplicationId); } // Add the branch name to the headers diff --git a/app/client/src/ce/utils/signupHelpers.ts b/app/client/src/ce/utils/signupHelpers.ts index 3b0b23d0ec..34f485ebd2 100644 --- a/app/client/src/ce/utils/signupHelpers.ts +++ b/app/client/src/ce/utils/signupHelpers.ts @@ -38,8 +38,8 @@ export const redirectUserAfterSignup = ( urlObject = new URL(redirectUrl); } catch (e) {} const match = matchPath<{ - pageId: string; - applicationId: string; + basePageId: string; + baseApplicationId: string; }>(urlObject?.pathname ?? redirectUrl, { path: [ BUILDER_PATH, @@ -50,16 +50,28 @@ export const redirectUserAfterSignup = ( strict: false, exact: false, }); - const { applicationId, pageId } = match?.params || {}; - if (applicationId || pageId) { + const { baseApplicationId, basePageId } = match?.params || {}; + /** ! Dev Note: + * setCurrentApplicationIdForCreateNewApp & firstTimeUserOnboardingInit + * in the following block support only applicationId + * but since baseId and id are same for applications created outside git context + * and since these redux actions are only called during onboarding, + * passing baseApplicationId as applicationId should be fine + * **/ + if (baseApplicationId || basePageId) { if (isEnabledForCreateNew) { dispatch( - setCurrentApplicationIdForCreateNewApp(applicationId as string), + setCurrentApplicationIdForCreateNewApp( + baseApplicationId as string, + ), ); history.replace(APPLICATIONS_URL); } else { dispatch( - firstTimeUserOnboardingInit(applicationId, pageId as string), + firstTimeUserOnboardingInit( + baseApplicationId, + basePageId as string, + ), ); } } else { diff --git a/app/client/src/components/common/BackToCanvas.tsx b/app/client/src/components/common/BackToCanvas.tsx index 327a2e99da..43e2e4caae 100644 --- a/app/client/src/components/common/BackToCanvas.tsx +++ b/app/client/src/components/common/BackToCanvas.tsx @@ -14,10 +14,10 @@ const BackToCanvasLink = styled(Link)` `; interface BackToCanvasProps { - pageId: string; + basePageId: string; } -function BackToCanvas({ pageId }: BackToCanvasProps) { +function BackToCanvas({ basePageId }: BackToCanvasProps) { const { isOpened: isWalkthroughOpened, popFeature } = useContext(WalkthroughContext) || {}; @@ -32,7 +32,7 @@ function BackToCanvas({ pageId }: BackToCanvasProps) { id="back-to-canvas" kind="secondary" onClick={() => { - history.push(builderURL({ pageId })); + history.push(builderURL({ basePageId })); handleCloseWalkthrough(); }} diff --git a/app/client/src/components/editorComponents/ActionNameEditor.tsx b/app/client/src/components/editorComponents/ActionNameEditor.tsx index 6339e1c797..ffd8bcf3e0 100644 --- a/app/client/src/components/editorComponents/ActionNameEditor.tsx +++ b/app/client/src/components/editorComponents/ActionNameEditor.tsx @@ -10,7 +10,10 @@ import type { AppState } from "@appsmith/reducers"; import { saveActionName } from "actions/pluginActionActions"; import { Flex } from "design-system"; -import { getAction, getPlugin } from "@appsmith/selectors/entitiesSelector"; +import { + getActionByBaseId, + getPlugin, +} from "@appsmith/selectors/entitiesSelector"; import NameEditorComponent, { IconBox, IconWrapper, @@ -44,10 +47,10 @@ interface ActionNameEditorProps { } function ActionNameEditor(props: ActionNameEditorProps) { - const params = useParams<{ apiId?: string; queryId?: string }>(); + const params = useParams<{ baseApiId?: string; baseQueryId?: string }>(); const currentActionConfig = useSelector((state: AppState) => - getAction(state, params.apiId || params.queryId || ""), + getActionByBaseId(state, params.baseApiId || params.baseQueryId || ""), ); const currentPlugin = useSelector((state: AppState) => diff --git a/app/client/src/components/editorComponents/CloseEditor.tsx b/app/client/src/components/editorComponents/CloseEditor.tsx index 6caf88de27..c6cb33b188 100644 --- a/app/client/src/components/editorComponents/CloseEditor.tsx +++ b/app/client/src/components/editorComponents/CloseEditor.tsx @@ -11,7 +11,7 @@ import { widgetListURL, } from "@appsmith/RouteBuilder"; import { useSelector } from "react-redux"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import { Link } from "design-system"; import styled from "styled-components"; @@ -29,7 +29,7 @@ function CloseEditor() { const params: string = location.search; const searchParamsInstance = new URLSearchParams(params); const redirectTo = searchParamsInstance.get("from"); - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const isGeneratePageInitiator = getIsGeneratePageInitiator(); let integrationTab = INTEGRATION_TABS.ACTIVE; @@ -51,13 +51,13 @@ function CloseEditor() { // then route user back to `/generate-page/form` // else go back to BUILDER_PAGE const redirectURL = isGeneratePageInitiator - ? generateTemplateFormURL({ pageId }) - : widgetListURL({ pageId }); + ? generateTemplateFormURL({ basePageId }) + : widgetListURL({ basePageId }); const URL = redirectTo === "datasources" ? integrationEditorURL({ - pageId, + basePageId, selectedTab: integrationTab, params: getQueryParams(), }) diff --git a/app/client/src/components/editorComponents/Debugger/DataSourceLink.tsx b/app/client/src/components/editorComponents/Debugger/DataSourceLink.tsx index 88892999fc..fb11a12885 100644 --- a/app/client/src/components/editorComponents/Debugger/DataSourceLink.tsx +++ b/app/client/src/components/editorComponents/Debugger/DataSourceLink.tsx @@ -3,7 +3,7 @@ import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import { DebuggerEntityLink, type EntityLinkProps } from "./DebuggerEntityLink"; import { useSelector } from "react-redux"; import type { AppState } from "@appsmith/reducers"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import { getDatasource } from "@appsmith/selectors/entitiesSelector"; import history from "utils/history"; import { getQueryParams } from "utils/URLUtils"; @@ -13,13 +13,13 @@ export default function DatasourceLink(props: EntityLinkProps) { const datasource = useSelector((state: AppState) => getDatasource(state, props.id), ); - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const onClick = () => { if (datasource) { history.push( datasourcesEditorIdURL({ - pageId, + basePageId, datasourceId: datasource.id, params: getQueryParams(), }), diff --git a/app/client/src/components/editorComponents/Debugger/hooks/debuggerHooks.ts b/app/client/src/components/editorComponents/Debugger/hooks/debuggerHooks.ts index 4d46282e3f..0168fb4b56 100644 --- a/app/client/src/components/editorComponents/Debugger/hooks/debuggerHooks.ts +++ b/app/client/src/components/editorComponents/Debugger/hooks/debuggerHooks.ts @@ -7,9 +7,13 @@ import type { AppState } from "@appsmith/reducers"; import { getWidget } from "sagas/selectors"; import { getCurrentApplicationId, - getCurrentPageId, + getCurrentBasePageId, } from "selectors/editorSelectors"; -import { getAction, getPlugins } from "@appsmith/selectors/entitiesSelector"; +import { + getAction, + getActionByBaseId, + getPlugins, +} from "@appsmith/selectors/entitiesSelector"; import { onApiEditor, onCanvas, onQueryEditor } from "../helpers"; import { getLastSelectedWidget } from "selectors/ui"; import { getConfigTree, getDataTree } from "selectors/dataTreeSelectors"; @@ -93,9 +97,9 @@ export const useSelectedEntity = () => { const params: any = useParams(); const action = useSelector((state: AppState) => { if (onApiEditor() || onQueryEditor()) { - const id = params.apiId || params.queryId; + const baseId = params.baseApiId || params.baseQueryId; - return getAction(state, id); + return getActionByBaseId(state, baseId); } return null; @@ -128,7 +132,7 @@ export const useSelectedEntity = () => { }; export const useEntityLink = () => { - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const plugins = useSelector(getPlugins); const applicationId = useSelector(getCurrentApplicationId); @@ -136,21 +140,23 @@ export const useEntityLink = () => { const navigateToEntity = useCallback( (name) => { - const dataTree = getDataTree(store.getState()); + const appState = store.getState(); + const dataTree = getDataTree(appState); const configTree = getConfigTree(); const entity = dataTree[name]; const entityConfig = configTree[name]; - if (!pageId) return; + if (!basePageId) return; if (isWidget(entity)) { const widgetEntity = entity as WidgetEntity; navigateToWidget( widgetEntity.widgetId, entity.type, - pageId || "", + basePageId || "", NavigationMethod.Debugger, ); } else if (isAction(entity)) { const actionConfig = getActionConfig(entityConfig.pluginType); + const action = getAction(appState, entity.actionId); let plugin; if (entityConfig?.pluginType === PluginType.SAAS) { plugin = plugins.find( @@ -160,8 +166,8 @@ export const useEntityLink = () => { const url = applicationId && actionConfig?.getURL( - pageId, - entity.actionId, + basePageId, + action?.baseId || "", entityConfig.pluginType, plugin, ); @@ -170,15 +176,16 @@ export const useEntityLink = () => { history.push(url); } } else if (isJSAction(entity)) { + const action = getAction(appState, entity.actionId); history.push( jsCollectionIdURL({ - pageId, - collectionId: entity.actionId, + basePageId, + baseCollectionId: action?.baseId || "", }), ); } }, - [pageId], + [basePageId], ); return { diff --git a/app/client/src/components/editorComponents/Debugger/hooks/useDebuggerTriggerClick.ts b/app/client/src/components/editorComponents/Debugger/hooks/useDebuggerTriggerClick.ts index 4136d5c5d6..57fbeb9eab 100644 --- a/app/client/src/components/editorComponents/Debugger/hooks/useDebuggerTriggerClick.ts +++ b/app/client/src/components/editorComponents/Debugger/hooks/useDebuggerTriggerClick.ts @@ -38,7 +38,7 @@ const queryDebuggerConfig: Config = { const getConfig = (focusInfo: FocusEntityInfo): Config => { switch (focusInfo.entity) { case FocusEntity.QUERY: - if (focusInfo.params.apiId) { + if (focusInfo.params.baseApiId) { if (focusInfo.params.pluginPackageName) { return queryDebuggerConfig; } diff --git a/app/client/src/components/editorComponents/GlobalSearch/GlobalSearchHooks.tsx b/app/client/src/components/editorComponents/GlobalSearch/GlobalSearchHooks.tsx index e8c2017b7e..a3dfa55525 100644 --- a/app/client/src/components/editorComponents/GlobalSearch/GlobalSearchHooks.tsx +++ b/app/client/src/components/editorComponents/GlobalSearch/GlobalSearchHooks.tsx @@ -168,10 +168,10 @@ export const useFilteredAndSortedFileOperations = ({ .filter((ds) => ds.title.toLowerCase().includes(query.toLowerCase())); // Add genetic datasource creation - const onRedirect = (pageId: string) => { + const onRedirect = (basePageId: string) => { history.push( integrationEditorURL({ - pageId, + basePageId, selectedTab: INTEGRATION_TABS.NEW, generateEditorPath: true, }), diff --git a/app/client/src/components/editorComponents/GlobalSearch/SearchResults.tsx b/app/client/src/components/editorComponents/GlobalSearch/SearchResults.tsx index c0579045b3..675f44b7cf 100644 --- a/app/client/src/components/editorComponents/GlobalSearch/SearchResults.tsx +++ b/app/client/src/components/editorComponents/GlobalSearch/SearchResults.tsx @@ -46,7 +46,7 @@ export const SearchItemContainer = styled.div<{ : "default"}; display: flex; align-items: center; - padding: ${(props) => props.theme.spaces[4]}px}; + padding: ${(props) => props.theme.spaces[4] + "px"}; transition: 0.3s background-color ease; border-radius: var(--ads-v2-border-radius); background-color: ${(props) => diff --git a/app/client/src/components/editorComponents/GlobalSearch/index.tsx b/app/client/src/components/editorComponents/GlobalSearch/index.tsx index 59281199cb..b7353e1ea7 100644 --- a/app/client/src/components/editorComponents/GlobalSearch/index.tsx +++ b/app/client/src/components/editorComponents/GlobalSearch/index.tsx @@ -71,6 +71,10 @@ import { import { getHasCreateActionPermission } from "@appsmith/utils/BusinessFeatures/permissionPageHelpers"; import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; +import { + getBasePageIdToPageIdMap, + getPageIdToBasePageIdMap, +} from "selectors/pageListSelectors"; const StyledContainer = styled.div<{ category: SearchCategory; query: string }>` max-height: 530px; @@ -171,6 +175,8 @@ function GlobalSearch() { [dispatch], ); const params = useParams(); + const pageIdToBasePageIdMap = useSelector(getPageIdToBasePageIdMap); + const basePageIdToPageIdMap = useSelector(getBasePageIdToPageIdMap); const toggleShow = () => { if (modalOpen) { @@ -209,9 +215,9 @@ function GlobalSearch() { const datasourcesList = useMemo(() => { return reducerDatasources.map((datasource) => ({ ...datasource, - pageId: params?.pageId, + pageId: basePageIdToPageIdMap[params?.basePageId], })); - }, [params?.pageId, reducerDatasources]); + }, [basePageIdToPageIdMap, params?.basePageId, reducerDatasources]); const filteredDatasources = useMemo(() => { if (!query) return datasourcesList; @@ -354,7 +360,7 @@ function GlobalSearch() { navigateToWidget( activeItem.widgetId, activeItem.type, - activeItem.pageId, + pageIdToBasePageIdMap[activeItem.pageId], NavigationMethod.Omnibar, lastSelectedWidgetId === activeItem.widgetId, false, @@ -365,21 +371,28 @@ function GlobalSearch() { const handleActionClick = (item: SearchItem) => { const { config } = item; - const { id, pageId, pluginId, pluginType } = config; + const { baseId: baseActionId, pageId, pluginId, pluginType } = config; const actionConfig = getActionConfig(pluginType); const plugin = plugins.find((plugin) => plugin?.id === pluginId); - const url = actionConfig?.getURL(pageId, id, pluginType, plugin); + const basePageId = pageIdToBasePageIdMap[pageId]; + const url = actionConfig?.getURL( + basePageId, + baseActionId, + pluginType, + plugin, + ); toggleShow(); url && history.push(url, { invokedBy: NavigationMethod.Omnibar }); }; const handleJSCollectionClick = (item: SearchItem) => { const { config } = item; - const { id, pageId } = config; + const { baseId: baseCollectionId, pageId } = config; + const basePageId = pageIdToBasePageIdMap[pageId]; history.push( jsCollectionIdURL({ - pageId, - collectionId: id, + basePageId, + baseCollectionId, }), { invokedBy: NavigationMethod.Omnibar }, ); @@ -388,9 +401,10 @@ function GlobalSearch() { const handleDatasourceClick = (item: SearchItem) => { toggleShow(); + const basePageId = pageIdToBasePageIdMap[item.pageId]; history.push( datasourcesEditorIdURL({ - pageId: item.pageId, + basePageId: basePageId, datasourceId: item.id, params: getQueryParams(), }), @@ -402,7 +416,7 @@ function GlobalSearch() { toggleShow(); history.push( builderURL({ - pageId: item.pageId, + basePageId: item.basePageId, }), { invokedBy: NavigationMethod.Omnibar }, ); diff --git a/app/client/src/components/editorComponents/JSResponseView.test.tsx b/app/client/src/components/editorComponents/JSResponseView.test.tsx index f1a3499e58..4647f4b61a 100644 --- a/app/client/src/components/editorComponents/JSResponseView.test.tsx +++ b/app/client/src/components/editorComponents/JSResponseView.test.tsx @@ -69,6 +69,7 @@ const collectionData: JSCollectionData = { isLoading: false, config: { id: "12", + baseId: "b12", applicationId: "app1", workspaceId: "w1234", name: "asas", diff --git a/app/client/src/components/editorComponents/StoreAsDatasource.tsx b/app/client/src/components/editorComponents/StoreAsDatasource.tsx index c8e400bdd1..7ecc9422d0 100644 --- a/app/client/src/components/editorComponents/StoreAsDatasource.tsx +++ b/app/client/src/components/editorComponents/StoreAsDatasource.tsx @@ -7,7 +7,7 @@ import { connect, useDispatch, useSelector } from "react-redux"; import history from "utils/history"; import { datasourcesEditorIdURL } from "@appsmith/RouteBuilder"; import { getQueryParams } from "utils/URLUtils"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import { createMessage, EDIT_DATASOURCE, @@ -34,7 +34,7 @@ interface ReduxDispatchProps { function StoreAsDatasource(props: storeDataSourceProps) { const dispatch = useDispatch(); - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const saveOrEditDatasource = () => { if (props.shouldSave) { @@ -47,7 +47,7 @@ function StoreAsDatasource(props: storeDataSourceProps) { }); history.push( datasourcesEditorIdURL({ - pageId, + basePageId, datasourceId: props.datasourceId, params: getQueryParams(), generateEditorPath: true, diff --git a/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/CommonControls/DatasourceDropdown/useSource/useOtherOptions.tsx b/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/CommonControls/DatasourceDropdown/useSource/useOtherOptions.tsx index 1cc9cb9fd1..6fccf75359 100644 --- a/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/CommonControls/DatasourceDropdown/useSource/useOtherOptions.tsx +++ b/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/CommonControls/DatasourceDropdown/useSource/useOtherOptions.tsx @@ -30,7 +30,7 @@ function useOtherOptions(props: OtherOptionsProps) { sampleData, updateConfig, } = useContext(WidgetQueryGeneratorFormContext); - const { pageId: currentPageId } = useParams(); + const { basePageId } = useParams(); const isAddBindingAllowed = datasourceDropdownVariant === DROPDOWN_VARIANT.CREATE_OR_EDIT_RECORDS; const { widget } = props; @@ -44,7 +44,7 @@ function useOtherOptions(props: OtherOptionsProps) { onSelect: () => { history.push( integrationEditorURL({ - pageId: currentPageId, + basePageId, selectedTab: INTEGRATION_TABS.NEW, }), ); @@ -117,14 +117,7 @@ function useOtherOptions(props: OtherOptionsProps) { } return options; - }, [ - currentPageId, - sampleData, - addBinding, - updateConfig, - widget, - propertyName, - ]); + }, [basePageId, sampleData, addBinding, updateConfig, widget, propertyName]); return otherOptions; } diff --git a/app/client/src/components/editorComponents/utils.test.ts b/app/client/src/components/editorComponents/utils.test.ts index f04673d47e..4a88124161 100644 --- a/app/client/src/components/editorComponents/utils.test.ts +++ b/app/client/src/components/editorComponents/utils.test.ts @@ -2,8 +2,10 @@ import { JSResponseState } from "./JSResponseView"; import { getJSResponseViewState } from "./utils"; const TEST_JS_FUNCTION_ID = "627ccff468e1fa5185b7f901"; +const TEST_JS_FUNCTION_BASE_ID = "627ccff468e1fa5185b7f912"; const TEST_JS_FUNCTION = { id: TEST_JS_FUNCTION_ID, + baseId: TEST_JS_FUNCTION_BASE_ID, applicationId: "627aaf637e9e9b75e43ad2ff", workspaceId: "61e52bb4847aa804d79fc7c1", pluginType: "JS", diff --git a/app/client/src/components/formControls/DropDownControl.tsx b/app/client/src/components/formControls/DropDownControl.tsx index 239fdaa289..9e82fe58a8 100644 --- a/app/client/src/components/formControls/DropDownControl.tsx +++ b/app/client/src/components/formControls/DropDownControl.tsx @@ -322,6 +322,9 @@ const mapStateToProps = ( options = dynamicFetchedValues.data; } } catch (e) { + // Printing error to console + // eslint-disable-next-line no-console + console.error(e); } finally { return { isLoading, options, formValues }; } diff --git a/app/client/src/constants/routes.test.ts b/app/client/src/constants/routes.test.ts index 52e82a53e7..7937fb5829 100644 --- a/app/client/src/constants/routes.test.ts +++ b/app/client/src/constants/routes.test.ts @@ -9,12 +9,12 @@ describe("builderURL", () => { urlBuilder.updateURLParams( { applicationSlug: ":applicationSlug", - applicationId: ":applicationId", + baseApplicationId: ":baseApplicationId", applicationVersion: 2, }, [ { - pageId: "0123456789abcdef00000000", + basePageId: "0123456789abcdef00000000", pageSlug: ":pageSlug", }, ], @@ -24,7 +24,7 @@ describe("builderURL", () => { it("persists embed query param", () => { (window as any).location = new URL("https://example.com?embed=true"); const pageURL = builderURL({ - pageId: "0123456789abcdef00000000", + basePageId: "0123456789abcdef00000000", }); const pageURLObject = new URL(`${window.origin}${pageURL}`); expect(pageURLObject.searchParams.get("embed")).toBe("true"); @@ -33,7 +33,7 @@ describe("builderURL", () => { it("does not append embed query param when it does not exist", () => { (window as any).location = new URL("https://example.com"); const pageURL = builderURL({ - pageId: "0123456789abcdef00000000", + basePageId: "0123456789abcdef00000000", }); const pageURLObject = new URL(`${window.origin}${pageURL}`); expect(pageURLObject.searchParams.get("embed")).toBe(null); @@ -52,12 +52,12 @@ describe("viewerURL", () => { urlBuilder.updateURLParams( { applicationSlug: ":applicationSlug", - applicationId: ":applicationId", + baseApplicationId: ":baseApplicationId", applicationVersion: 2, }, [ { - pageId: "0123456789abcdef00000000", + basePageId: "0123456789abcdef00000000", pageSlug: ":pageSlug", }, ], @@ -67,7 +67,7 @@ describe("viewerURL", () => { it("persists embed query param", () => { (window as any).location = new URL("https://example.com?embed=true"); const pageURL = viewerURL({ - pageId: "0123456789abcdef00000000", + basePageId: "0123456789abcdef00000000", }); const pageURLObject = new URL(`${window.origin}${pageURL}`); expect(pageURLObject.searchParams.get("embed")).toBe("true"); @@ -76,7 +76,7 @@ describe("viewerURL", () => { it("does not append embed query param when it does not exist", () => { (window as any).location = new URL("https://example.com"); const pageURL = viewerURL({ - pageId: "0123456789abcdef00000000", + basePageId: "0123456789abcdef00000000", }); const pageURLObject = new URL(`${window.origin}${pageURL}`); expect(pageURLObject.searchParams.get("embed")).toBe(null); diff --git a/app/client/src/entities/Action/actionProperties.test.ts b/app/client/src/entities/Action/actionProperties.test.ts index e33f5f2462..9ee1511749 100644 --- a/app/client/src/entities/Action/actionProperties.test.ts +++ b/app/client/src/entities/Action/actionProperties.test.ts @@ -12,11 +12,13 @@ const DEFAULT_ACTION: Action = { dynamicBindingPathList: [], executeOnLoad: false, id: "", + baseId: "", invalids: [], isValid: false, jsonPathKeys: [], name: "", workspaceId: "", + applicationId: "", pageId: "", pluginId: "", messages: [], diff --git a/app/client/src/entities/Action/index.ts b/app/client/src/entities/Action/index.ts index 87d08621d3..7cd21b439d 100644 --- a/app/client/src/entities/Action/index.ts +++ b/app/client/src/entities/Action/index.ts @@ -161,8 +161,10 @@ export interface StoredDatasource { export interface BaseAction { id: string; + baseId: string; name: string; workspaceId: string; + applicationId: string; pageId: string; collectionId?: string; pluginId: string; @@ -233,6 +235,7 @@ export interface QueryAction extends BaseAction { export interface ActionViewMode { id: string; + baseId: string; name: string; pageId: string; jsonPathKeys: string[]; diff --git a/app/client/src/entities/Engine/AppEditorEngine.ts b/app/client/src/entities/Engine/AppEditorEngine.ts index c5c91ac69a..cb3d121ebd 100644 --- a/app/client/src/entities/Engine/AppEditorEngine.ts +++ b/app/client/src/entities/Engine/AppEditorEngine.ts @@ -10,7 +10,10 @@ import { } from "actions/gitSyncActions"; import { restoreRecentEntitiesRequest } from "actions/globalSearchActions"; import { resetEditorSuccess } from "actions/initActions"; -import { fetchAllPageEntityCompletion, setupPage } from "actions/pageActions"; +import { + fetchAllPageEntityCompletion, + setupPageAction, +} from "actions/pageActions"; import { executePageLoadActions, fetchActions, @@ -30,7 +33,6 @@ import { reportSWStatus, waitForWidgetConfigBuild, } from "sagas/InitSagas"; -import { getCurrentApplication } from "selectors/editorSelectors"; import { getCurrentGitBranch } from "selectors/gitSyncSelectors"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import history from "utils/history"; @@ -66,6 +68,7 @@ import { fetchAppThemesAction, fetchSelectedAppThemeAction, } from "actions/appThemingActions"; +import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; import type { Span } from "@opentelemetry/api"; import { endSpan, startNestedSpan } from "UITelemetry/generateTraces"; @@ -134,7 +137,7 @@ export default class AppEditorEngine extends AppEngine { unpublishedActions, } = allResponses; const initActionsCalls = [ - setupPage(toLoadPageId, true, pageWithMigratedDsl), + setupPageAction(toLoadPageId, true, pageWithMigratedDsl), fetchActions({ applicationId, unpublishedActions }, []), fetchJSCollections({ applicationId, unpublishedActionCollections }), fetchSelectedAppThemeAction(applicationId, currentTheme), diff --git a/app/client/src/entities/Engine/index.ts b/app/client/src/entities/Engine/index.ts index 6c8e9776a5..b11d534408 100644 --- a/app/client/src/entities/Engine/index.ts +++ b/app/client/src/entities/Engine/index.ts @@ -11,7 +11,7 @@ import log from "loglevel"; import { call, put, select } from "redux-saga/effects"; import type { InitConsolidatedApi } from "sagas/InitSagas"; import { failFastApiCalls } from "sagas/InitSagas"; -import { getDefaultPageId } from "sagas/selectors"; +import { getDefaultBasePageId, getDefaultPageId } from "sagas/selectors"; import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; import history from "utils/history"; import type URLRedirect from "entities/URLRedirect/index"; @@ -24,7 +24,7 @@ import { endSpan, startNestedSpan } from "UITelemetry/generateTraces"; export interface AppEnginePayload { applicationId?: string; - pageId?: string; + basePageId?: string; branch?: string; mode: APP_MODE; shouldInitialiseUserDetails?: boolean; @@ -74,13 +74,14 @@ export default abstract class AppEngine { rootSpan: Span, ) { const loadAppDataSpan = startNestedSpan("AppEngine.loadAppData", rootSpan); - const { applicationId, branch, pageId } = payload; + const { applicationId, basePageId, branch } = payload; const { pages } = allResponses; + const page = pages.data?.pages?.find((page) => page.baseId === basePageId); const apiCalls: boolean = yield failFastApiCalls( [ fetchApplication({ applicationId, - pageId, + pageId: page?.id, mode: this._mode, pages, }), @@ -94,11 +95,9 @@ export default abstract class AppEngine { ReduxActionErrorTypes.FETCH_PAGE_LIST_ERROR, ], ); - if (!apiCalls) { - throw new PageNotFoundError(`Cannot find page with id: ${pageId}`); + throw new PageNotFoundError(`Cannot find page with pageId: ${page?.id}`); } - const application: ApplicationPayload = yield select(getCurrentApplication); const currentGitBranch: ReturnType = yield select(getCurrentGitBranch); @@ -107,14 +106,16 @@ export default abstract class AppEngine { getPersistentAppStore(application.id, branch || currentGitBranch), ), ); - const toLoadPageId: string = pageId || (yield select(getDefaultPageId)); + const defaultPageId: string = yield select(getDefaultPageId); + const defaultPageBaseId: string = yield select(getDefaultBasePageId); + const toLoadPageId: string = page?.id || defaultPageId; + const toLoadBasePageId: string = page?.baseId || defaultPageBaseId; this._urlRedirect = URLGeneratorFactory.create( application.applicationVersion, this._mode, ); - endSpan(loadAppDataSpan); - return { toLoadPageId, applicationId: application.id }; + return { toLoadPageId, toLoadBasePageId, applicationId: application.id }; } *setupEngine(payload: AppEnginePayload, rootSpan: Span): any { @@ -130,12 +131,12 @@ export default abstract class AppEngine { } *loadAppURL({ - pageId, - pageIdInUrl, + basePageId, + basePageIdInUrl, rootSpan, }: { - pageId: string; - pageIdInUrl?: string; + basePageId: string; + basePageIdInUrl?: string; rootSpan: Span; }) { try { @@ -144,8 +145,8 @@ export default abstract class AppEngine { const loadAppUrlSpan = startNestedSpan("AppEngine.loadAppURL", rootSpan); const newURL: string = yield call( this._urlRedirect.generateRedirectURL.bind(this), - pageId, - pageIdInUrl, + basePageId, + basePageIdInUrl, ); endSpan(loadAppUrlSpan); diff --git a/app/client/src/entities/JSCollection/index.ts b/app/client/src/entities/JSCollection/index.ts index 567e2fcec4..32dc24f6b1 100644 --- a/app/client/src/entities/JSCollection/index.ts +++ b/app/client/src/entities/JSCollection/index.ts @@ -9,6 +9,7 @@ export interface Variable { } export interface JSCollection { id: string; + baseId: string; applicationId: string; workspaceId: string; name: string; diff --git a/app/client/src/entities/URLRedirect/DefaultURLRedirect.ts b/app/client/src/entities/URLRedirect/DefaultURLRedirect.ts index 5a380bd717..836f93000b 100644 --- a/app/client/src/entities/URLRedirect/DefaultURLRedirect.ts +++ b/app/client/src/entities/URLRedirect/DefaultURLRedirect.ts @@ -12,7 +12,7 @@ export default class DefaultURLRedirect extends URLRedirect { super(mode); } - *generateRedirectURL(pageId: string) { + *generateRedirectURL(basePageId: string) { const currentApplication: ApplicationPayload = yield select( getCurrentApplication, ); @@ -28,7 +28,7 @@ export default class DefaultURLRedirect extends URLRedirect { // we need to compute the legacy url // This scenario can happen only in edit mode. newURL = builderURL({ - pageId: pageId, + basePageId, hash, }); return newURL; diff --git a/app/client/src/entities/URLRedirect/SlugURLRedirect.ts b/app/client/src/entities/URLRedirect/SlugURLRedirect.ts index 3b2b13ba49..329d4b8ef1 100644 --- a/app/client/src/entities/URLRedirect/SlugURLRedirect.ts +++ b/app/client/src/entities/URLRedirect/SlugURLRedirect.ts @@ -6,7 +6,7 @@ import { APP_MODE } from "entities/App"; import { select } from "redux-saga/effects"; import { fillPathname, viewerURL } from "@appsmith/RouteBuilder"; import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; -import { getPageById } from "selectors/editorSelectors"; +import { getPageByBaseId } from "selectors/editorSelectors"; import { getUpdatedRoute, isURLDeprecated } from "utils/helpers"; import URLRedirect from "."; @@ -15,22 +15,23 @@ export class SlugURLRedirect extends URLRedirect { super(mode); } - *generateRedirectURL(pageId: string, pageIdInUrl: string) { + *generateRedirectURL(basePageId: string, basePageIdInUrl: string) { const currentApplication: ApplicationPayload = yield select( getCurrentApplication, ); const applicationSlug = currentApplication.slug; - const currentPage: Page = yield select(getPageById(pageId)); + const currentPage: Page = yield select(getPageByBaseId(basePageId)); const { customSlug = "", slug: pageSlug } = currentPage; let newURL = ""; const { hash, pathname, search } = window.location; - const isCurrentURLDeprecated = isURLDeprecated(pathname) || !pageIdInUrl; + const isCurrentURLDeprecated = + isURLDeprecated(pathname) || !basePageIdInUrl; if (!isCurrentURLDeprecated) { newURL = getUpdatedRoute(pathname, { applicationSlug, pageSlug, - pageId, + basePageId, customSlug, }) + search + @@ -43,7 +44,7 @@ export class SlugURLRedirect extends URLRedirect { fillPathname(pathname, currentApplication, currentPage) + search + hash; } else { // View Mode - generate a new viewer URL - auto updates query params - newURL = viewerURL({ pageId, hash }); + newURL = viewerURL({ basePageId, hash }); } return newURL; } diff --git a/app/client/src/entities/URLRedirect/index.ts b/app/client/src/entities/URLRedirect/index.ts index 964e552531..1d5910b56e 100644 --- a/app/client/src/entities/URLRedirect/index.ts +++ b/app/client/src/entities/URLRedirect/index.ts @@ -5,5 +5,8 @@ export default abstract class URLRedirect { constructor(mode: APP_MODE) { this._mode = mode; } - abstract generateRedirectURL(pageId: string, pageIdInUrl?: string): any; + abstract generateRedirectURL( + basePageId: string, + basePageIdInUrl?: string, + ): any; } diff --git a/app/client/src/layoutSystems/anvil/integrations/sagas/pasteSagas/index.ts b/app/client/src/layoutSystems/anvil/integrations/sagas/pasteSagas/index.ts index a268b35a83..26aecdfffe 100644 --- a/app/client/src/layoutSystems/anvil/integrations/sagas/pasteSagas/index.ts +++ b/app/client/src/layoutSystems/anvil/integrations/sagas/pasteSagas/index.ts @@ -5,7 +5,7 @@ import { getSelectedWidgetWhenPasting } from "sagas/WidgetOperationUtils"; import { getWidgets } from "sagas/selectors"; import { updateAndSaveAnvilLayout } from "../../../utils/anvilChecksUtils"; import { builderURL } from "@appsmith/RouteBuilder"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import { type ReduxAction, ReduxActionErrorTypes, @@ -134,10 +134,10 @@ export function* pasteWidgetSagas() { */ yield call(updateAndSaveAnvilLayout, allWidgets); - const pageId: string = yield select(getCurrentPageId); + const basePageId: string = yield select(getCurrentBasePageId); if (originalWidgets?.length) { - history.push(builderURL({ pageId })); + history.push(builderURL({ basePageId })); } const widgetsToSelect = copiedWidgets.map( diff --git a/app/client/src/layoutSystems/anvil/integrations/sagas/pasteSagas/pasteSagas.test.ts b/app/client/src/layoutSystems/anvil/integrations/sagas/pasteSagas/pasteSagas.test.ts index e9316c9636..7dab0377c3 100644 --- a/app/client/src/layoutSystems/anvil/integrations/sagas/pasteSagas/pasteSagas.test.ts +++ b/app/client/src/layoutSystems/anvil/integrations/sagas/pasteSagas/pasteSagas.test.ts @@ -9,7 +9,7 @@ import { } from "sagas/WidgetOperationUtils"; import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants"; import { getWidgets } from "sagas/selectors"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import { SelectionRequestType } from "sagas/WidgetSelectUtils"; import { getDataTree } from "selectors/dataTreeSelectors"; import { generateReactKey } from "utils/generators"; @@ -45,7 +45,7 @@ jest.mock("selectors/layoutSystemSelectors", () => ({ getLayoutSystemType: jest.fn(), })); describe("pasteSagas", () => { - const pageId = "0123456789abcdef00000000"; + const basePageId = "0123456789abcdef00000000"; beforeAll(() => { registerLayoutComponents(); @@ -101,7 +101,7 @@ describe("pasteSagas", () => { const { effects } = await expectSaga(pasteWidgetSagas as any) .provide([ [select(getWidgets), allWidgets], - [select(getCurrentPageId), pageId], + [select(getCurrentBasePageId), basePageId], ]) .run(); // check the effects @@ -203,7 +203,7 @@ describe("pasteSagas", () => { const { effects } = await expectSaga(pasteWidgetSagas as any) .provide([ [select(getWidgets), allWidgets], - [select(getCurrentPageId), pageId], + [select(getCurrentBasePageId), basePageId], ]) .run(); // Check the effects diff --git a/app/client/src/navigation/FocusEntity.test.ts b/app/client/src/navigation/FocusEntity.test.ts index 22ab15150e..6d2dcd5a6c 100644 --- a/app/client/src/navigation/FocusEntity.test.ts +++ b/app/client/src/navigation/FocusEntity.test.ts @@ -7,158 +7,158 @@ interface TestCase { expected: FocusEntityInfo; } -const applicationId = "a0123456789abcdef0000000"; -const pageId = "b0123456789abcdef0000000"; +const baseApplicationId = "a0123456789abcdef0000000"; +const basePageId = "b0123456789abcdef0000000"; describe("identifyEntityFromPath", () => { const oldUrlCases: TestCase[] = [ { - path: `/applications/${applicationId}/pages/${pageId}/edit`, + path: `/applications/${baseApplicationId}/pages/${basePageId}/edit`, expected: { entity: FocusEntity.CANVAS, id: "", appState: EditorState.EDITOR, params: { - applicationId, - pageId, + baseApplicationId, + basePageId, }, }, }, { - path: `/applications/${applicationId}/pages/${pageId}/edit/widgets/ryvc8i7oja`, + path: `/applications/${baseApplicationId}/pages/${basePageId}/edit/widgets/ryvc8i7oja`, expected: { entity: FocusEntity.PROPERTY_PANE, id: "ryvc8i7oja", appState: EditorState.EDITOR, params: { - applicationId, - pageId, + baseApplicationId, + basePageId, widgetIds: "ryvc8i7oja", }, }, }, { - path: `/applications/${applicationId}/pages/${pageId}/edit/queries`, + path: `/applications/${baseApplicationId}/pages/${basePageId}/edit/queries`, expected: { entity: FocusEntity.QUERY_LIST, id: "", appState: EditorState.EDITOR, params: { - applicationId, + baseApplicationId, entity: "queries", - pageId, + basePageId, }, }, }, { - path: `/applications/${applicationId}/pages/${pageId}/edit/api/myApiId`, + path: `/applications/${baseApplicationId}/pages/${basePageId}/edit/api/myApiId`, expected: { entity: FocusEntity.QUERY, id: "myApiId", appState: EditorState.EDITOR, params: { - apiId: "myApiId", - applicationId, - pageId, + baseApiId: "myApiId", + baseApplicationId, + basePageId, }, }, }, { - path: `/applications/${applicationId}/pages/${pageId}/edit/queries/myQueryId`, + path: `/applications/${baseApplicationId}/pages/${basePageId}/edit/queries/myQueryId`, expected: { entity: FocusEntity.QUERY, id: "myQueryId", appState: EditorState.EDITOR, params: { - queryId: "myQueryId", - applicationId, - pageId, + baseQueryId: "myQueryId", + baseApplicationId, + basePageId, }, }, }, { - path: `/applications/${applicationId}/pages/${pageId}/edit/jsObjects`, + path: `/applications/${baseApplicationId}/pages/${basePageId}/edit/jsObjects`, expected: { entity: FocusEntity.JS_OBJECT_LIST, id: "", appState: EditorState.EDITOR, params: { - applicationId, + baseApplicationId, entity: "jsObjects", - pageId, + basePageId, }, }, }, { - path: `/applications/${applicationId}/pages/${pageId}/edit/jsObjects/myJSId`, + path: `/applications/${baseApplicationId}/pages/${basePageId}/edit/jsObjects/myJSId`, expected: { entity: FocusEntity.JS_OBJECT, id: "myJSId", appState: EditorState.EDITOR, params: { - applicationId, - collectionId: "myJSId", - pageId, + baseApplicationId, + baseCollectionId: "myJSId", + basePageId, }, }, }, { - path: `/applications/${applicationId}/pages/${pageId}/edit/datasource`, + path: `/applications/${baseApplicationId}/pages/${basePageId}/edit/datasource`, expected: { entity: FocusEntity.DATASOURCE_LIST, id: "", appState: EditorState.DATA, params: { - applicationId, + baseApplicationId, entity: "datasource", - pageId, + basePageId, }, }, }, { - path: `/applications/${applicationId}/pages/${pageId}/edit/datasource/myDatasourceId`, + path: `/applications/${baseApplicationId}/pages/${basePageId}/edit/datasource/myDatasourceId`, expected: { entity: FocusEntity.DATASOURCE, id: "myDatasourceId", appState: EditorState.DATA, params: { - applicationId, + baseApplicationId, datasourceId: "myDatasourceId", - pageId, + basePageId, }, }, }, ]; const pageSlugCases: TestCase[] = [ { - path: `/app/eval/page1-${pageId}/edit`, + path: `/app/eval/page1-${basePageId}/edit`, expected: { entity: FocusEntity.CANVAS, id: "", appState: EditorState.EDITOR, params: { applicationSlug: "eval", - pageId, + basePageId, pageSlug: "page1-", }, }, }, { - path: `/app/app-slug/page1-${pageId}/edit/widgets/ryvc8i7oja`, + path: `/app/app-slug/page1-${basePageId}/edit/widgets/ryvc8i7oja`, expected: { entity: FocusEntity.PROPERTY_PANE, id: "ryvc8i7oja", appState: EditorState.EDITOR, params: { applicationSlug: "app-slug", - pageId, + basePageId, pageSlug: "page1-", widgetIds: "ryvc8i7oja", }, }, }, { - path: `/app/eval/page1-${pageId}/edit/queries`, + path: `/app/eval/page1-${basePageId}/edit/queries`, expected: { entity: FocusEntity.QUERY_LIST, id: "", @@ -166,41 +166,41 @@ describe("identifyEntityFromPath", () => { params: { applicationSlug: "eval", entity: "queries", - pageId, + basePageId, pageSlug: "page1-", }, }, }, { - path: `/app/eval/page1-${pageId}/edit/api/myApiId`, + path: `/app/eval/page1-${basePageId}/edit/api/myApiId`, expected: { entity: FocusEntity.QUERY, id: "myApiId", appState: EditorState.EDITOR, params: { - apiId: "myApiId", + baseApiId: "myApiId", applicationSlug: "eval", - pageId, + basePageId, pageSlug: "page1-", }, }, }, { - path: `/app/eval/page1-${pageId}/edit/queries/myQueryId`, + path: `/app/eval/page1-${basePageId}/edit/queries/myQueryId`, expected: { entity: FocusEntity.QUERY, id: "myQueryId", appState: EditorState.EDITOR, params: { applicationSlug: "eval", - pageId, + basePageId, pageSlug: "page1-", - queryId: "myQueryId", + baseQueryId: "myQueryId", }, }, }, { - path: `/app/eval/page1-${pageId}/edit/jsObjects`, + path: `/app/eval/page1-${basePageId}/edit/jsObjects`, expected: { entity: FocusEntity.JS_OBJECT_LIST, id: "", @@ -208,27 +208,27 @@ describe("identifyEntityFromPath", () => { params: { applicationSlug: "eval", entity: "jsObjects", - pageId, + basePageId, pageSlug: "page1-", }, }, }, { - path: `/app/eval/page1-${pageId}/edit/jsObjects/myJSId`, + path: `/app/eval/page1-${basePageId}/edit/jsObjects/myJSId`, expected: { entity: FocusEntity.JS_OBJECT, id: "myJSId", appState: EditorState.EDITOR, params: { applicationSlug: "eval", - collectionId: "myJSId", - pageId, + baseCollectionId: "myJSId", + basePageId, pageSlug: "page1-", }, }, }, { - path: `/app/eval/page1-${pageId}/edit/datasource`, + path: `/app/eval/page1-${basePageId}/edit/datasource`, expected: { entity: FocusEntity.DATASOURCE_LIST, id: "", @@ -236,13 +236,13 @@ describe("identifyEntityFromPath", () => { params: { applicationSlug: "eval", entity: "datasource", - pageId, + basePageId, pageSlug: "page1-", }, }, }, { - path: `/app/eval/page1-${pageId}/edit/datasource/myDatasourceId`, + path: `/app/eval/page1-${basePageId}/edit/datasource/myDatasourceId`, expected: { entity: FocusEntity.DATASOURCE, id: "myDatasourceId", @@ -250,7 +250,7 @@ describe("identifyEntityFromPath", () => { params: { applicationSlug: "eval", datasourceId: "myDatasourceId", - pageId, + basePageId, pageSlug: "page1-", }, }, @@ -258,116 +258,116 @@ describe("identifyEntityFromPath", () => { ]; const customSlugCases: TestCase[] = [ { - path: `/app/myCustomSlug-${pageId}/edit`, + path: `/app/myCustomSlug-${basePageId}/edit`, expected: { entity: FocusEntity.CANVAS, id: "", appState: EditorState.EDITOR, params: { - pageId, + basePageId, customSlug: "myCustomSlug-", }, }, }, { - path: `/app/myCustomSlug-${pageId}/edit/widgets/ryvc8i7oja`, + path: `/app/myCustomSlug-${basePageId}/edit/widgets/ryvc8i7oja`, expected: { entity: FocusEntity.PROPERTY_PANE, id: "ryvc8i7oja", appState: EditorState.EDITOR, params: { - pageId, + basePageId, customSlug: "myCustomSlug-", widgetIds: "ryvc8i7oja", }, }, }, { - path: `/app/myCustomSlug-${pageId}/edit/queries`, + path: `/app/myCustomSlug-${basePageId}/edit/queries`, expected: { entity: FocusEntity.QUERY_LIST, id: "", appState: EditorState.EDITOR, params: { - pageId, + basePageId, customSlug: "myCustomSlug-", entity: "queries", }, }, }, { - path: `/app/myCustomSlug-${pageId}/edit/api/myApiId`, + path: `/app/myCustomSlug-${basePageId}/edit/api/myApiId`, expected: { entity: FocusEntity.QUERY, id: "myApiId", appState: EditorState.EDITOR, params: { - pageId, + basePageId, customSlug: "myCustomSlug-", - apiId: "myApiId", + baseApiId: "myApiId", }, }, }, { - path: `/app/myCustomSlug-${pageId}/edit/queries/myQueryId`, + path: `/app/myCustomSlug-${basePageId}/edit/queries/myQueryId`, expected: { entity: FocusEntity.QUERY, id: "myQueryId", appState: EditorState.EDITOR, params: { - pageId, + basePageId, customSlug: "myCustomSlug-", - queryId: "myQueryId", + baseQueryId: "myQueryId", }, }, }, { - path: `/app/myCustomSlug-${pageId}/edit/jsObjects`, + path: `/app/myCustomSlug-${basePageId}/edit/jsObjects`, expected: { entity: FocusEntity.JS_OBJECT_LIST, id: "", appState: EditorState.EDITOR, params: { - pageId, + basePageId, entity: "jsObjects", customSlug: "myCustomSlug-", }, }, }, { - path: `/app/myCustomSlug-${pageId}/edit/jsObjects/myJSId`, + path: `/app/myCustomSlug-${basePageId}/edit/jsObjects/myJSId`, expected: { entity: FocusEntity.JS_OBJECT, id: "myJSId", appState: EditorState.EDITOR, params: { - collectionId: "myJSId", - pageId, + baseCollectionId: "myJSId", + basePageId, customSlug: "myCustomSlug-", }, }, }, { - path: `/app/myCustomSlug-${pageId}/edit/datasource`, + path: `/app/myCustomSlug-${basePageId}/edit/datasource`, expected: { entity: FocusEntity.DATASOURCE_LIST, id: "", appState: EditorState.DATA, params: { entity: "datasource", - pageId, + basePageId, customSlug: "myCustomSlug-", }, }, }, { - path: `/app/myCustomSlug-${pageId}/edit/datasource/myDatasourceId`, + path: `/app/myCustomSlug-${basePageId}/edit/datasource/myDatasourceId`, expected: { entity: FocusEntity.DATASOURCE, id: "myDatasourceId", appState: EditorState.DATA, params: { - pageId, + basePageId, customSlug: "myCustomSlug-", datasourceId: "myDatasourceId", }, diff --git a/app/client/src/navigation/FocusEntity.ts b/app/client/src/navigation/FocusEntity.ts index dc0c439083..936ac687c8 100644 --- a/app/client/src/navigation/FocusEntity.ts +++ b/app/client/src/navigation/FocusEntity.ts @@ -60,20 +60,20 @@ const getMatchPaths = memoize((type: IDEType): string[] => { }); export interface MatchEntityFromPath { - applicationId?: string; + baseApplicationId?: string; customSlug?: string; applicationSlug?: string; packageId?: string; moduleId?: string; workflowId?: string; pageSlug?: string; - apiId?: string; + baseApiId?: string; datasourceId?: string; pluginPackageName?: string; - queryId?: string; + baseQueryId?: string; appId?: string; - pageId?: string; - collectionId?: string; + basePageId?: string; + baseCollectionId?: string; widgetIds?: string; selectedTab?: string; moduleType?: string; @@ -120,14 +120,14 @@ export function identifyEntityFromPath(path: string): FocusEntityInfo { params: {}, }; } - if (match.params.apiId) { + if (match.params.baseApiId) { if (match.params.pluginPackageName) { if (match.url.endsWith(ADD_PATH)) { return getQueryAddPathObj(match); } return { entity: FocusEntity.QUERY, - id: match.params.apiId, + id: match.params.baseApiId, appState: EditorState.EDITOR, params: match.params, }; @@ -137,7 +137,7 @@ export function identifyEntityFromPath(path: string): FocusEntityInfo { } return { entity: FocusEntity.QUERY, - id: match.params.apiId, + id: match.params.baseApiId, appState: EditorState.EDITOR, params: match.params, }; @@ -175,13 +175,13 @@ export function identifyEntityFromPath(path: string): FocusEntityInfo { params: match.params, }; } - if (match.params.queryId) { - if (match.params.queryId == "add" || match.url.endsWith(ADD_PATH)) { + if (match.params.baseQueryId) { + if (match.params.baseQueryId == "add" || match.url.endsWith(ADD_PATH)) { return getQueryAddPathObj(match); } return { entity: FocusEntity.QUERY, - id: match.params.queryId, + id: match.params.baseQueryId, appState: EditorState.EDITOR, params: match.params, }; @@ -210,13 +210,16 @@ export function identifyEntityFromPath(path: string): FocusEntityInfo { }; } } - if (match.params.collectionId) { - if (match.params.collectionId == "add" || match.url.endsWith(ADD_PATH)) { + if (match.params.baseCollectionId) { + if ( + match.params.baseCollectionId == "add" || + match.url.endsWith(ADD_PATH) + ) { return getJSAddPathObj(match); } return { entity: FocusEntity.JS_OBJECT, - id: match.params.collectionId, + id: match.params.baseCollectionId, appState: EditorState.EDITOR, params: match.params, }; diff --git a/app/client/src/pages/AppViewer/AppPage/AppPage.tsx b/app/client/src/pages/AppViewer/AppPage/AppPage.tsx index 91b85abe6d..d3418bd79b 100644 --- a/app/client/src/pages/AppViewer/AppPage/AppPage.tsx +++ b/app/client/src/pages/AppViewer/AppPage/AppPage.tsx @@ -15,13 +15,14 @@ import { useCanvasWidthAutoResize } from "../../hooks/useCanvasWidthAutoResize"; interface AppPageProps { appName?: string; canvasWidth: number; - pageId?: string; + basePageId?: string; pageName?: string; widgetsStructure: CanvasWidgetStructure; } export function AppPage(props: AppPageProps) { - const { appName, canvasWidth, pageId, pageName, widgetsStructure } = props; + const { appName, basePageId, canvasWidth, pageName, widgetsStructure } = + props; const appMode = useSelector(getAppMode); const isPublished = appMode === APP_MODE.PUBLISHED; @@ -38,11 +39,11 @@ export function AppPage(props: AppPageProps) { useEffect(() => { AnalyticsUtil.logEvent("PAGE_LOAD", { pageName: pageName, - pageId: pageId, + pageId: basePageId, appName: appName, mode: "VIEW", }); - }, [appName, pageId, pageName]); + }, [appName, basePageId, pageName]); return ( Appsmith Editor @@ -94,8 +94,8 @@ function AppViewerPageContainer(props: AppViewerPageContainerProps) {
diff --git a/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx b/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx index 64aa8273a1..3610a64cd9 100644 --- a/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx +++ b/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx @@ -16,7 +16,7 @@ import { useHref } from "pages/Editor/utils"; import { builderURL } from "@appsmith/RouteBuilder"; import { combinedPreviewModeSelector, - getCurrentPageId, + getCurrentBasePageId, } from "selectors/editorSelectors"; import type { User } from "constants/userConstants"; import SidebarProfileComponent from "./components/SidebarProfileComponent"; @@ -76,8 +76,8 @@ export function Sidebar(props: SidebarProps) { const location = useLocation(); const { pathname } = location; const [query, setQuery] = useState(""); - const pageId = useSelector(getCurrentPageId); - const editorURL = useHref(builderURL, { pageId }); + const basePageId = useSelector(getCurrentBasePageId); + const editorURL = useHref(builderURL, { basePageId }); const dispatch = useDispatch(); const isPinned = useSelector(getAppSidebarPinned); const [isOpen, setIsOpen] = useState(true); diff --git a/app/client/src/pages/AppViewer/Navigation/components/MenuItem.tsx b/app/client/src/pages/AppViewer/Navigation/components/MenuItem.tsx index 05f6ff13bd..b29f908545 100644 --- a/app/client/src/pages/AppViewer/Navigation/components/MenuItem.tsx +++ b/app/client/src/pages/AppViewer/Navigation/components/MenuItem.tsx @@ -32,7 +32,7 @@ const MenuItem = ({ const appMode = useSelector(getAppMode); const pageURL = useHref( appMode === APP_MODE.PUBLISHED ? viewerURL : builderURL, - { pageId: page.pageId }, + { basePageId: page.basePageId }, ); const selectedTheme = useSelector(getSelectedAppTheme); const navColorStyle = diff --git a/app/client/src/pages/AppViewer/Navigation/components/MoreDropdownButton.tsx b/app/client/src/pages/AppViewer/Navigation/components/MoreDropdownButton.tsx index aeac34fc23..c658f83580 100644 --- a/app/client/src/pages/AppViewer/Navigation/components/MoreDropdownButton.tsx +++ b/app/client/src/pages/AppViewer/Navigation/components/MoreDropdownButton.tsx @@ -105,10 +105,10 @@ const MoreDropdownButton = ({ const pageURL = appMode === APP_MODE.PUBLISHED ? viewerURL({ - pageId: page.pageId, + basePageId: page.basePageId, }) : builderURL({ - pageId: page.pageId, + basePageId: page.basePageId, }); return ( diff --git a/app/client/src/pages/AppViewer/Navigation/components/TopHeader.tsx b/app/client/src/pages/AppViewer/Navigation/components/TopHeader.tsx index e368c56126..57307d3d57 100644 --- a/app/client/src/pages/AppViewer/Navigation/components/TopHeader.tsx +++ b/app/client/src/pages/AppViewer/Navigation/components/TopHeader.tsx @@ -9,7 +9,7 @@ import React from "react"; import { useSelector } from "react-redux"; import { builderURL } from "@appsmith/RouteBuilder"; import { getSelectedAppTheme } from "selectors/appThemingSelectors"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import MobileNavToggle from "./MobileNavToggle"; import ApplicationName from "./ApplicationName"; import ShareButton from "./ShareButton"; @@ -59,8 +59,8 @@ const TopHeader = (props: TopHeaderProps) => { "properties.colors.primaryColor", "inherit", ); - const pageId = useSelector(getCurrentPageId); - const editorURL = useHref(builderURL, { pageId }); + const basePageId = useSelector(getCurrentBasePageId); + const editorURL = useHref(builderURL, { basePageId }); return ( (null); - const pageId = useSelector(getCurrentPageId); - const editorURL = useHref(builderURL, { pageId }); + const basePageId = useSelector(getCurrentBasePageId); + const editorURL = useHref(builderURL, { basePageId }); const currentWorkspaceId: string = useSelector(getCurrentWorkspaceId); const currentUser: User | undefined = useSelector(getCurrentUser); const lightTheme: Theme = useSelector((state: AppState) => diff --git a/app/client/src/pages/AppViewer/PageMenu.tsx b/app/client/src/pages/AppViewer/PageMenu.tsx index e0e484de1a..10a89431d6 100644 --- a/app/client/src/pages/AppViewer/PageMenu.tsx +++ b/app/client/src/pages/AppViewer/PageMenu.tsx @@ -180,7 +180,7 @@ function PageNavLink({ const selectedTheme = useSelector(getSelectedAppTheme); const pathname = useHref( appMode === APP_MODE.PUBLISHED ? viewerURL : builderURL, - { pageId: page.pageId }, + { basePageId: page.basePageId }, ); return ( @@ -190,7 +190,7 @@ function PageNavLink({ borderColor: selectedTheme.properties.colors.primaryColor, }} className="flex flex-col px-4 py-2 no-underline border-transparent border-r-3 hover:no-underline" - key={page.pageId} + key={page.basePageId} navColorStyle={navColorStyle} onClick={closeMenu} primaryColor={primaryColor} diff --git a/app/client/src/pages/AppViewer/PageTabs.tsx b/app/client/src/pages/AppViewer/PageTabs.tsx index b6a7b391d9..16c36aee2e 100644 --- a/app/client/src/pages/AppViewer/PageTabs.tsx +++ b/app/client/src/pages/AppViewer/PageTabs.tsx @@ -166,7 +166,7 @@ export function PageTabs(props: Props) { {appPages.map((page) => { return ( -1} + isTabActive={pathname.indexOf(page.basePageId) > -1} key={page.pageId} setShowScrollArrows={props.setShowScrollArrows} tabsScrollable={props.tabsScrollable} @@ -197,7 +197,7 @@ function PageTabItem({ const appMode = useSelector(getAppMode); const pageURL = useHref( appMode === APP_MODE.PUBLISHED ? viewerURL : builderURL, - { pageId: page.pageId }, + { basePageId: page.basePageId }, ); const selectedTheme = useSelector(getSelectedAppTheme); const navColorStyle = diff --git a/app/client/src/pages/AppViewer/PrimaryCTA.test.tsx b/app/client/src/pages/AppViewer/PrimaryCTA.test.tsx index a215ba109c..3b97e31cee 100644 --- a/app/client/src/pages/AppViewer/PrimaryCTA.test.tsx +++ b/app/client/src/pages/AppViewer/PrimaryCTA.test.tsx @@ -27,9 +27,11 @@ export const initialState: any = { pageList: { applicationId: 1, currentPageId: "0123456789abcdef00000000", + currentBasePageId: "0123456789abcdef00000123", pages: [ { pageId: "0123456789abcdef00000000", + basePageId: "0123456789abcdef00000123", slug: "pageSlug", }, ], @@ -67,6 +69,7 @@ export const initialState: any = { applications: { currentApplication: { id: "605c435a91dea93f0eaf91b8", + baseId: "605c435a91dea93f0eaf9123", name: "My Application", slug: "my-application", workspaceId: "", @@ -126,6 +129,7 @@ export const fetchApplicationMockResponse = { data: { application: { id: "605c435a91dea93f0eaf91b8", + baseId: "605c435a91dea93f0eaf9123", name: "My Application", slug: "my-application", workspaceId: "", @@ -139,12 +143,14 @@ export const fetchApplicationMockResponse = { pages: [ { id: "605c435a91dea93f0eaf91ba", + baseId: "605c435a91dea93f0eaf9123", name: "Page1", isDefault: true, slug: "page-1", }, { id: "605c435a91dea93f0eaf91bc", + baseId: "605c435a91dea93f0eaf9123", name: "Page2", isDefault: false, slug: "page-2", @@ -162,7 +168,7 @@ describe("App viewer fork button", () => { , @@ -178,7 +184,7 @@ describe("App viewer fork button", () => { , diff --git a/app/client/src/pages/AppViewer/PrimaryCTA.tsx b/app/client/src/pages/AppViewer/PrimaryCTA.tsx index b2ae4dfcb6..e106accd3e 100644 --- a/app/client/src/pages/AppViewer/PrimaryCTA.tsx +++ b/app/client/src/pages/AppViewer/PrimaryCTA.tsx @@ -7,8 +7,7 @@ import { isPermitted, } from "@appsmith/utils/permissionHelpers"; import { - getCurrentApplication, - getCurrentPageId, + getCurrentBasePageId, previewModeSelector, } from "selectors/editorSelectors"; import { getSelectedAppTheme } from "selectors/appThemingSelectors"; @@ -30,6 +29,7 @@ import { getApplicationNameTextColor } from "./utils"; import { ButtonVariantTypes } from "components/constants"; import { setPreviewModeInitAction } from "actions/editorActions"; import { protectedModeSelector } from "selectors/gitSyncSelectors"; +import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; /** * --------------------------------------------------------------------------------------------------- @@ -61,7 +61,7 @@ function PrimaryCTA(props: Props) { url, } = props; const currentUser = useSelector(getCurrentUser); - const currentPageID = useSelector(getCurrentPageId); + const currentBasePageId = useSelector(getCurrentBasePageId); const selectedTheme = useSelector(getSelectedAppTheme); const currentApplication = useSelector(getCurrentApplication); const history = useHistory(); @@ -116,7 +116,7 @@ function PrimaryCTA(props: Props) { }, [currentApplication?.forkingEnabled, currentUser?.username]); const appViewerURL = useHref(viewerURL, { - pageId: currentPageID, + basePageId: currentBasePageId, params: { fork: "true", branch: null, diff --git a/app/client/src/pages/AppViewer/index.tsx b/app/client/src/pages/AppViewer/index.tsx index 2f711b6ae1..ee11d39ef4 100644 --- a/app/client/src/pages/AppViewer/index.tsx +++ b/app/client/src/pages/AppViewer/index.tsx @@ -32,7 +32,7 @@ import { setupPublishedPage } from "actions/pageActions"; import usePrevious from "utils/hooks/usePrevious"; import { getIsBranchUpdated } from "../utils"; import { APP_MODE } from "entities/App"; -import { initAppViewer } from "actions/initActions"; +import { initAppViewerAction } from "actions/initActions"; import { WidgetGlobaStyles } from "globalStyles/WidgetGlobalStyles"; import useWidgetFocus from "utils/hooks/useWidgetFocus/useWidgetFocus"; import HtmlTitle from "./AppViewerHtmlTitle"; @@ -86,7 +86,7 @@ const DEFAULT_FONT_NAME = "System Default"; function AppViewer(props: Props) { const dispatch = useDispatch(); const { pathname, search } = props.location; - const { applicationId, pageId } = props.match.params; + const { baseApplicationId, basePageId } = props.match.params; const isInitialized = useSelector(getIsInitialized); const pages = useSelector(getViewModePageList); const selectedTheme = useSelector(getSelectedAppTheme); @@ -95,7 +95,11 @@ function AppViewer(props: Props) { ); const headerHeight = useSelector(getAppViewHeaderHeight); const branch = getSearchQuery(search, GIT_BRANCH_QUERY_KEY); - const prevValues = usePrevious({ branch, location: props.location, pageId }); + const prevValues = usePrevious({ + branch, + location: props.location, + basePageId, + }); const hideWatermark = useSelector(getHideWatermark); const pageDescription = useSelector(getCurrentPageDescription); const currentApplicationDetails: ApplicationPayload | undefined = useSelector( @@ -135,20 +139,20 @@ function AppViewer(props: Props) { useEffect(() => { const prevBranch = prevValues?.branch; const prevLocation = prevValues?.location; - const prevPageId = prevValues?.pageId; + const prevPageBaseId = prevValues?.basePageId; let isBranchUpdated = false; if (prevBranch && prevLocation) { isBranchUpdated = getIsBranchUpdated(props.location, prevLocation); } - const isPageIdUpdated = pageId !== prevPageId; + const isPageIdUpdated = basePageId !== prevPageBaseId; - if (prevBranch && isBranchUpdated && (applicationId || pageId)) { + if (prevBranch && isBranchUpdated && (baseApplicationId || basePageId)) { dispatch( - initAppViewer({ - applicationId, + initAppViewerAction({ + baseApplicationId, branch, - pageId, + basePageId, mode: APP_MODE.PUBLISHED, }), ); @@ -158,19 +162,24 @@ function AppViewer(props: Props) { * If we don't check for `prevPageId`: fetch page is retriggered * when redirected to the default page */ - if (prevPageId && pageId && isPageIdUpdated) { - dispatch(setupPublishedPage(pageId, true)); + if (prevPageBaseId && basePageId && isPageIdUpdated) { + const pageId = pages.find( + (page) => page.basePageId === basePageId, + )?.pageId; + if (pageId) { + dispatch(setupPublishedPage(pageId, true)); + } } } - }, [branch, pageId, applicationId, pathname]); + }, [branch, basePageId, baseApplicationId, pathname]); useEffect(() => { - urlBuilder.setCurrentPageId(pageId); + urlBuilder.setCurrentBasePageId(basePageId); return () => { - urlBuilder.setCurrentPageId(null); + urlBuilder.setCurrentBasePageId(null); }; - }, [pageId]); + }, [basePageId]); useEffect(() => { const header = document.querySelector(".js-appviewer-header"); diff --git a/app/client/src/pages/AppViewer/loader.tsx b/app/client/src/pages/AppViewer/loader.tsx index 67cca202ad..53d46aaff6 100644 --- a/app/client/src/pages/AppViewer/loader.tsx +++ b/app/client/src/pages/AppViewer/loader.tsx @@ -3,7 +3,7 @@ import type { RouteComponentProps } from "react-router"; import PageLoadingBar from "pages/common/PageLoadingBar"; import { retryPromise } from "utils/AppsmithUtils"; import type { InitAppViewerPayload } from "actions/initActions"; -import { initAppViewer } from "actions/initActions"; +import { initAppViewerAction } from "actions/initActions"; import { APP_MODE } from "entities/App"; import { connect } from "react-redux"; import { getSearchQuery } from "utils/helpers"; @@ -13,7 +13,7 @@ import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; type Props = { initAppViewer: (payload: InitAppViewerPayload) => void; clearCache: () => void; -} & RouteComponentProps<{ pageId: string; applicationId?: string }>; +} & RouteComponentProps<{ basePageId: string; baseApplicationId?: string }>; class AppViewerLoader extends React.PureComponent { constructor(props: any) { @@ -44,14 +44,14 @@ class AppViewerLoader extends React.PureComponent { location: { search }, match: { params }, } = this.props; - const { applicationId, pageId } = params; + const { baseApplicationId, basePageId } = params; const branch = getSearchQuery(search, GIT_BRANCH_QUERY_KEY); // onMount initPage - if (applicationId || pageId) { + if (baseApplicationId || basePageId) { initAppViewer({ - applicationId, + baseApplicationId, branch, - pageId, + basePageId, mode: APP_MODE.PUBLISHED, }); } @@ -65,7 +65,7 @@ class AppViewerLoader extends React.PureComponent { const mapDispatchToProps = (dispatch: any) => { return { initAppViewer: (payload: InitAppViewerPayload) => - dispatch(initAppViewer(payload)), + dispatch(initAppViewerAction(payload)), clearCache: () => { dispatch({ type: ReduxActionTypes.CLEAR_CACHE }); }, diff --git a/app/client/src/pages/Applications/ApplicationCard.tsx b/app/client/src/pages/Applications/ApplicationCard.tsx index 3d3bbd0918..63f5b4fd01 100644 --- a/app/client/src/pages/Applications/ApplicationCard.tsx +++ b/app/client/src/pages/Applications/ApplicationCard.tsx @@ -403,31 +403,27 @@ export function ApplicationCard(props: ApplicationCardProps) { { applicationSlug: props.application.slug, applicationVersion: props.application.applicationVersion, - applicationId: props.application.id, + baseApplicationId: props.application.baseId, }, props.application.pages.map((page) => ({ pageSlug: page.slug, customSlug: page.customSlug, - pageId: page.id, + basePageId: page.baseId, })), ); } const editModeURL = useMemo(() => { - if (!props.application.defaultPageId) return ""; - return builderURL({ - pageId: props.application.defaultPageId, - params, - }); - }, [props.application.defaultPageId, params]); + const basePageId = props.application.defaultBasePageId; + if (!basePageId) return ""; + return builderURL({ basePageId, params }); + }, [props.application.defaultBasePageId, params]); const viewModeURL = useMemo(() => { - if (!props.application.defaultPageId) return ""; - return viewerURL({ - pageId: props.application.defaultPageId, - params, - }); - }, [props.application.defaultPageId, params]); + const basePageId = props.application.defaultBasePageId; + if (!basePageId) return ""; + return viewerURL({ basePageId, params }); + }, [props.application.defaultBasePageId, params]); const launchApp = useCallback(() => { setURLParams(); @@ -443,7 +439,7 @@ export function ApplicationCard(props: ApplicationCardProps) { setURLParams(); history.push( viewerURL({ - pageId: props.application.defaultPageId, + basePageId: props.application.defaultBasePageId, params, }), ); diff --git a/app/client/src/pages/Applications/EmbedSnippet/useUpdateEmbedSnippet.tsx b/app/client/src/pages/Applications/EmbedSnippet/useUpdateEmbedSnippet.tsx index 243551c007..431c5e7989 100644 --- a/app/client/src/pages/Applications/EmbedSnippet/useUpdateEmbedSnippet.tsx +++ b/app/client/src/pages/Applications/EmbedSnippet/useUpdateEmbedSnippet.tsx @@ -1,6 +1,6 @@ import { useCallback, useEffect, useMemo, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; -import { getDefaultPageId } from "sagas/selectors"; +import { getDefaultBasePageId } from "sagas/selectors"; import { getSettings } from "selectors/settingsSelectors"; import { getCurrentUser } from "selectors/usersSelectors"; import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; @@ -43,7 +43,7 @@ function useUpdateEmbedSnippet() { const application = useSelector(getCurrentApplication); const settings = useSelector(getSettings); const user = useSelector(getCurrentUser); - const defaultPageId = useSelector(getDefaultPageId); + const defaultBasePageId = useSelector(getDefaultBasePageId); const featureFlags = useSelector(selectFeatureFlags); const currentSetting: EmbedSetting = formatEmbedSettings( settings["APPSMITH_ALLOWED_FRAME_ANCESTORS"] as string, @@ -104,7 +104,7 @@ function useUpdateEmbedSnippet() { const appViewEndPoint = useMemo(() => { const url = viewerURL({ - pageId: defaultPageId, + basePageId: defaultBasePageId, }); const allowHidingShareSettingsInEmbedView = featureFlags.release_embed_hide_share_settings_enabled; @@ -119,7 +119,7 @@ function useUpdateEmbedSnippet() { fullUrl.searchParams.append("embed", "true"); return fullUrl.toString(); - }, [defaultPageId, embedSetting?.showNavigationBar]); + }, [defaultBasePageId, embedSetting?.showNavigationBar]); const snippet = useMemo(() => { return ``; diff --git a/app/client/src/pages/Editor/APIEditor/ApiRightPane.tsx b/app/client/src/pages/Editor/APIEditor/ApiRightPane.tsx index 80f3c757ca..8f6bb54c0e 100644 --- a/app/client/src/pages/Editor/APIEditor/ApiRightPane.tsx +++ b/app/client/src/pages/Editor/APIEditor/ApiRightPane.tsx @@ -23,7 +23,7 @@ interface ApiRightPaneProps { actionRightPaneBackLink: React.ReactNode; applicationId?: string; currentActionDatasourceId: string; - currentPageId?: string; + currentBasePageId?: string; datasourceId: string; datasources: any; hasResponse: boolean; @@ -290,7 +290,7 @@ function ApiRightPane(props: ApiRightPaneProps) { e.stopPropagation(); history.push( datasourcesEditorIdURL({ - pageId: props.currentPageId, + basePageId: props.currentBasePageId, datasourceId: d.id, params: getQueryParams(), }), diff --git a/app/client/src/pages/Editor/APIEditor/CommonEditorForm.tsx b/app/client/src/pages/Editor/APIEditor/CommonEditorForm.tsx index 3c5946d38b..7207cc6065 100644 --- a/app/client/src/pages/Editor/APIEditor/CommonEditorForm.tsx +++ b/app/client/src/pages/Editor/APIEditor/CommonEditorForm.tsx @@ -534,7 +534,7 @@ function CommonEditorForm(props: CommonFormPropsWithExtraParams) { } = props; const dispatch = useDispatch(); - const params = useParams<{ apiId?: string; queryId?: string }>(); + const params = useParams<{ baseApiId?: string; baseQueryId?: string }>(); // passing lodash's equality function to ensure that this selector does not cause a rerender multiple times. // it checks each value to make sure none has changed before recomputing the actions. @@ -544,7 +544,8 @@ function CommonEditorForm(props: CommonFormPropsWithExtraParams) { ); const currentActionConfig: Action | undefined = actions.find( - (action) => action.id === params.apiId || action.id === params.queryId, + (action) => + action.baseId === params.baseApiId || action.id === params.baseQueryId, ); const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); const isChangePermitted = getHasManageActionPermission( diff --git a/app/client/src/pages/Editor/APIEditor/Editor.tsx b/app/client/src/pages/Editor/APIEditor/Editor.tsx index 7ae389bc82..760218d240 100644 --- a/app/client/src/pages/Editor/APIEditor/Editor.tsx +++ b/app/client/src/pages/Editor/APIEditor/Editor.tsx @@ -11,14 +11,12 @@ import type { import _ from "lodash"; import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; import { - getActionById, getCurrentApplicationId, getCurrentPageName, } from "selectors/editorSelectors"; import type { Plugin } from "api/PluginApi"; import type { Action, PaginationType } from "entities/Action"; import { PluginPackageName } from "entities/Action"; -import { getApiName } from "selectors/formSelectors"; import Spinner from "components/editorComponents/Spinner"; import type { CSSProperties } from "styled-components"; import styled from "styled-components"; @@ -30,7 +28,11 @@ import PerformanceTracker, { import * as Sentry from "@sentry/react"; import EntityNotFoundPane from "pages/Editor/EntityNotFoundPane"; import type { ApplicationPayload } from "@appsmith/constants/ReduxActionConstants"; -import { getPageList, getPlugins } from "@appsmith/selectors/entitiesSelector"; +import { + getActionByBaseId, + getPageList, + getPlugins, +} from "@appsmith/selectors/entitiesSelector"; import history from "utils/history"; import { saasEditorApiIdURL } from "@appsmith/RouteBuilder"; import GraphQLEditorForm from "./GraphQL/GraphQLEditorForm"; @@ -46,6 +48,7 @@ interface ReduxStateProps { isRunning: boolean; isDeleting: boolean; isCreating: boolean; + apiId: string; apiName: string; currentApplication?: ApplicationPayload; currentPageName: string | undefined; @@ -85,8 +88,8 @@ class ApiEditor extends React.Component { actionType: "API", }); const type = this.getFormName(); - if (this.props.match.params.apiId) { - this.props.changeAPIPage(this.props.match.params.apiId, type === "SAAS"); + if (this.props.apiId) { + this.props.changeAPIPage(this.props.apiId, type === "SAAS"); } } @@ -105,12 +108,9 @@ class ApiEditor extends React.Component { if (prevProps.isRunning && !this.props.isRunning) { PerformanceTracker.stopTracking(PerformanceTransactionName.RUN_API_CLICK); } - if (prevProps.match.params.apiId !== this.props.match.params.apiId) { + if (prevProps.apiId !== this.props.apiId) { const type = this.getFormName(); - this.props.changeAPIPage( - this.props.match.params.apiId || "", - type === "SAAS", - ); + this.props.changeAPIPage(this.props.apiId || "", type === "SAAS"); } } @@ -138,13 +138,13 @@ class ApiEditor extends React.Component { isEditorInitialized, isRunning, match: { - params: { apiId }, + params: { baseApiId }, }, paginationType, pluginId, plugins, } = this.props; - if (!pluginId && apiId) { + if (!pluginId && baseApiId) { return ; } if (isCreating || !isEditorInitialized) { @@ -156,7 +156,7 @@ class ApiEditor extends React.Component { } let formUiComponent: string | undefined; - if (apiId) { + if (baseApiId) { if (pluginId) { formUiComponent = this.getPluginUiComponentOfId(pluginId, plugins); } else { @@ -204,13 +204,13 @@ class ApiEditor extends React.Component { {formUiComponent === "SaaSEditorForm" && history.push( saasEditorApiIdURL({ - pageId: this.props.match.params.pageId, + basePageId: this.props.match.params.basePageId, pluginPackageName: getPackageNameFromPluginId( this.props.pluginId, this.props.plugins, ) ?? "", - apiId: this.props.match.params.apiId || "", + baseApiId: this.props.match.params.baseApiId || "", }), )} @@ -226,8 +226,9 @@ const formStyles: CSSProperties = { }; const mapStateToProps = (state: AppState, props: any): ReduxStateProps => { - const apiAction = getActionById(state, props); - const apiName = getApiName(state, props.match.params.apiId); + const apiAction = getActionByBaseId(state, props?.match?.params?.baseApiId); + const apiName = apiAction?.name ?? ""; + const apiId = apiAction?.id ?? ""; const { isCreating, isDeleting, isRunning } = state.ui.apiPane; const pluginId = _.get(apiAction, "pluginId", ""); return { @@ -235,13 +236,14 @@ const mapStateToProps = (state: AppState, props: any): ReduxStateProps => { currentApplication: getCurrentApplication(state), currentPageName: getCurrentPageName(state), pages: getPageList(state), - apiName: apiName || "", + apiId, + apiName, plugins: getPlugins(state), pluginId, paginationType: _.get(apiAction, "actionConfiguration.paginationType"), apiAction, - isRunning: isRunning[props.match.params.apiId], - isDeleting: isDeleting[props.match.params.apiId], + isRunning: isRunning[apiId], + isDeleting: isDeleting[apiId], isCreating: isCreating, applicationId: getCurrentApplicationId(state), }; diff --git a/app/client/src/pages/Editor/APIEditor/GraphQL/GraphQLEditorForm.tsx b/app/client/src/pages/Editor/APIEditor/GraphQL/GraphQLEditorForm.tsx index b7791e7fe0..edb990b8bd 100644 --- a/app/client/src/pages/Editor/APIEditor/GraphQL/GraphQLEditorForm.tsx +++ b/app/client/src/pages/Editor/APIEditor/GraphQL/GraphQLEditorForm.tsx @@ -7,12 +7,14 @@ import styled from "styled-components"; import { API_EDITOR_FORM_NAME } from "@appsmith/constants/forms"; import type { Action } from "entities/Action"; import type { AppState } from "@appsmith/reducers"; -import { getApiName } from "selectors/formSelectors"; import { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig"; import useHorizontalResize from "utils/hooks/useHorizontalResize"; import get from "lodash/get"; import type { Datasource } from "entities/Datasource"; -import { getAction, getActionData } from "@appsmith/selectors/entitiesSelector"; +import { + getActionByBaseId, + getActionData, +} from "@appsmith/selectors/entitiesSelector"; import { isEmpty } from "lodash"; import type { CommonFormProps } from "../CommonEditorForm"; import CommonEditorForm from "../CommonEditorForm"; @@ -179,11 +181,11 @@ export default connect( ); } - // get messages from action itself - const { apiId, queryId } = props.match?.params || {}; - const actionId = queryId || apiId; - // const actionId = selector(state, "id"); - const action = getAction(state, actionId); + const { baseApiId, baseQueryId } = props.match?.params || {}; + const baseActionId = baseQueryId || baseApiId; + const action = getActionByBaseId(state, baseActionId); + const apiId = action?.id ?? ""; + const actionName = action?.name ?? ""; const hintMessages = action?.messages; const datasourceHeaders = @@ -192,10 +194,8 @@ export default connect( get(datasourceFromAction, "datasourceConfiguration.queryParameters") || []; - // const apiId = selector(state, "id"); const currentActionDatasourceId = selector(state, "datasource.id"); - const actionName = getApiName(state, apiId) || ""; const headers = selector(state, "actionConfiguration.headers"); let headersCount = 0; diff --git a/app/client/src/pages/Editor/APIEditor/index.tsx b/app/client/src/pages/Editor/APIEditor/index.tsx index ef3d66b34f..b2c227dad5 100644 --- a/app/client/src/pages/Editor/APIEditor/index.tsx +++ b/app/client/src/pages/Editor/APIEditor/index.tsx @@ -17,7 +17,7 @@ import { getIsEditorInitialized, getPagePermissions, } from "selectors/editorSelectors"; -import { getAction } from "@appsmith/selectors/entitiesSelector"; +import { getActionByBaseId } from "@appsmith/selectors/entitiesSelector"; import type { APIEditorRouteParams } from "constants/routes"; import { getHasCreateActionPermission, @@ -44,22 +44,22 @@ import { EditorViewMode } from "@appsmith/entities/IDE/constants"; type ApiEditorWrapperProps = RouteComponentProps; -function getPageName(pages: any, pageId: string) { - const page = pages.find((page: any) => page.pageId === pageId); +function getPageName(pages: any, basePageId: string) { + const page = pages.find((page: any) => page.basePageId === basePageId); return page ? page.pageName : ""; } function ApiEditorWrapper(props: ApiEditorWrapperProps) { - const { apiId = "", pageId } = props.match.params; + const { baseApiId = "", basePageId } = props.match.params; const dispatch = useDispatch(); const isEditorInitialized = useSelector(getIsEditorInitialized); - const action = useSelector((state) => getAction(state, apiId)); + const action = useSelector((state) => getActionByBaseId(state, baseApiId)); const apiName = action?.name || ""; const pluginId = get(action, "pluginId", ""); const datasourceId = action?.datasource.id || ""; const plugins = useSelector(getPlugins); const pages = useSelector(getPageList); - const pageName = getPageName(pages, pageId); + const pageName = getPageName(pages, basePageId); const settingsConfig = useSelector((state) => getPluginSettingConfigs(state, pluginId), ); @@ -106,12 +106,12 @@ function ApiEditorWrapper(props: ApiEditorWrapperProps) { return ( <> @@ -128,7 +128,7 @@ function ApiEditorWrapper(props: ApiEditorWrapperProps) { action?.name, isChangePermitted, isDeletePermitted, - pageId, + basePageId, isCreatePermitted, editorMode, ]); @@ -139,34 +139,42 @@ function ApiEditorWrapper(props: ApiEditorWrapperProps) { PerformanceTracker.startTracking( PerformanceTransactionName.RUN_API_CLICK, { - apiId, + apiId: action?.id, }, ); AnalyticsUtil.logEvent("RUN_API_CLICK", { apiName, - apiID: apiId, + apiID: action?.id, pageName: pageName, datasourceId, pluginName: pluginName, isMock: false, // as mock db exists only for postgres and mongo plugins }); - dispatch(runAction(apiId, paginationField)); + dispatch(runAction(action?.id ?? "", paginationField)); }, - [apiId, apiName, pageName, getPageName, plugins, pluginId, datasourceId], + [ + action?.id, + apiName, + pageName, + getPageName, + plugins, + pluginId, + datasourceId, + ], ); const actionRightPaneBackLink = useMemo(() => { - return ; - }, [pageId]); + return ; + }, [basePageId]); const handleDeleteClick = useCallback(() => { AnalyticsUtil.logEvent("DELETE_API_CLICK", { apiName, - apiID: apiId, + apiID: action?.id, pageName, }); - dispatch(deleteAction({ id: apiId, name: apiName })); - }, [getPageName, pages, pageId, apiName]); + dispatch(deleteAction({ id: action?.id ?? "", name: apiName })); + }, [getPageName, pages, basePageId, apiName]); const notification = useMemo(() => { if (!isConverting) return null; diff --git a/app/client/src/pages/Editor/AppSettingsPane/AppSettings/PageSettings.tsx b/app/client/src/pages/Editor/AppSettingsPane/AppSettings/PageSettings.tsx index e721f2d23b..dd6c501eb8 100644 --- a/app/client/src/pages/Editor/AppSettingsPane/AppSettings/PageSettings.tsx +++ b/app/client/src/pages/Editor/AppSettingsPane/AppSettings/PageSettings.tsx @@ -1,6 +1,6 @@ import { ApplicationVersion } from "@appsmith/actions/applicationActions"; -import { setPageAsDefault, updatePage } from "actions/pageActions"; -import type { UpdatePageRequest } from "api/PageApi"; +import type { UpdatePageActionPayload } from "actions/pageActions"; +import { setPageAsDefault, updatePageAction } from "actions/pageActions"; import { PAGE_SETTINGS_SHOW_PAGE_NAV, PAGE_SETTINGS_PAGE_NAME_LABEL, @@ -129,33 +129,33 @@ function PageSettings(props: { page: Page }) { const savePageName = useCallback(() => { if (!canManagePages || !!isPageNameValid || page.pageName === pageName) return; - const payload: UpdatePageRequest = { + const payload: UpdatePageActionPayload = { id: page.pageId, name: pageName, }; setIsPageNameSaving(true); - dispatch(updatePage(payload)); + dispatch(updatePageAction(payload)); }, [page.pageId, page.pageName, pageName, isPageNameValid]); const saveCustomSlug = useCallback(() => { if (!canManagePages || page.customSlug === customSlug) return; - const payload: UpdatePageRequest = { + const payload: UpdatePageActionPayload = { id: page.pageId, customSlug: customSlug || "", }; setIsCustomSlugSaving(true); - dispatch(updatePage(payload)); + dispatch(updatePageAction(payload)); }, [page.pageId, page.customSlug, customSlug]); const saveIsShown = useCallback( (isShown: boolean) => { if (!canManagePages) return; - const payload: UpdatePageRequest = { + const payload: UpdatePageActionPayload = { id: page.pageId, isHidden: !isShown, }; setIsShownSaving(true); - dispatch(updatePage(payload)); + dispatch(updatePageAction(payload)); }, [page.pageId, isShown], ); diff --git a/app/client/src/pages/Editor/CommunityTemplates/Modals/PublishCommunityTemplate/CommunityTemplateForm.tsx b/app/client/src/pages/Editor/CommunityTemplates/Modals/PublishCommunityTemplate/CommunityTemplateForm.tsx index 15c0c17879..729d4e314e 100644 --- a/app/client/src/pages/Editor/CommunityTemplates/Modals/PublishCommunityTemplate/CommunityTemplateForm.tsx +++ b/app/client/src/pages/Editor/CommunityTemplates/Modals/PublishCommunityTemplate/CommunityTemplateForm.tsx @@ -6,7 +6,7 @@ import { publishCommunityTemplate } from "actions/communityTemplateActions"; import { Button, Checkbox } from "design-system"; import React, { useEffect, useMemo, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; -import { getCurrentApplication } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import { getCurrentUser } from "selectors/usersSelectors"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import { @@ -20,7 +20,7 @@ import AuthorDetailsInput from "./components/AuthorDetailsInput"; import PublishedInfo from "./components/PublishedInfo"; import TemplateInfoForm from "./components/TemplateInfoForm"; import { viewerURL } from "@appsmith/RouteBuilder"; -import { getCurrentPageId } from "@appsmith/selectors/entitiesSelector"; +import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; interface Props { onPublishSuccess: () => void; @@ -43,7 +43,7 @@ const CommunityTemplateForm = ({ onPublishSuccess }: Props) => { const [isForkableSetting, setIsForkableSetting] = useState(true); const [tnCCheck, setTnCCheck] = useState(false); - const currentPageId: string = useSelector(getCurrentPageId); + const currentBasePageId: string = useSelector(getCurrentBasePageId); useEffect(() => { AnalyticsUtil.logEvent("COMMUNITY_TEMPLATE_PUBLISH_INTENTION", { @@ -81,7 +81,8 @@ const CommunityTemplateForm = ({ onPublishSuccess }: Props) => { AnalyticsUtil.logEvent("COMMUNITY_TEMPLATE_PUBLISH_CLICK", { id: currentApplication?.id, }); - const pageId = currentApplication?.defaultPageId || currentPageId; + const basePageId = + currentApplication?.defaultBasePageId || currentBasePageId; dispatch( publishCommunityTemplate({ title: templateName, @@ -95,7 +96,7 @@ const CommunityTemplateForm = ({ onPublishSuccess }: Props) => { branchName: currentApplication?.gitApplicationMetadata?.branchName || "", appUrl: `${window.location.origin}${viewerURL({ - pageId, + basePageId, })}`, }), ); diff --git a/app/client/src/pages/Editor/DataSourceEditor/BackButton.tsx b/app/client/src/pages/Editor/DataSourceEditor/BackButton.tsx index 3855f2d644..529e3c7dc1 100644 --- a/app/client/src/pages/Editor/DataSourceEditor/BackButton.tsx +++ b/app/client/src/pages/Editor/DataSourceEditor/BackButton.tsx @@ -4,7 +4,7 @@ import { getIsGeneratePageInitiator } from "utils/GenerateCrudUtil"; import { builderURL, generateTemplateFormURL } from "@appsmith/RouteBuilder"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import { useSelector } from "react-redux"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import { Link } from "design-system"; import type { AppsmithLocationState } from "utils/history"; import { NavigationMethod } from "utils/history"; @@ -18,12 +18,12 @@ const Back = styled(Link)` function BackButton() { const history = useHistory(); - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const goBack = () => { const isGeneratePageInitiator = getIsGeneratePageInitiator(); const redirectURL = isGeneratePageInitiator - ? generateTemplateFormURL({ pageId }) - : builderURL({ pageId }); + ? generateTemplateFormURL({ basePageId }) + : builderURL({ basePageId }); AnalyticsUtil.logEvent("BACK_BUTTON_CLICK", { type: "BACK_BUTTON", diff --git a/app/client/src/pages/Editor/DataSourceEditor/hooks.ts b/app/client/src/pages/Editor/DataSourceEditor/hooks.ts index 92dbc646e9..e2074c10b9 100644 --- a/app/client/src/pages/Editor/DataSourceEditor/hooks.ts +++ b/app/client/src/pages/Editor/DataSourceEditor/hooks.ts @@ -18,13 +18,11 @@ import { } from "@appsmith/selectors/entitiesSelector"; import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; import type { AppState } from "@appsmith/reducers"; -import { - getCurrentApplication, - getPagePermissions, -} from "selectors/editorSelectors"; +import { getPagePermissions } from "selectors/editorSelectors"; import { get } from "lodash"; import { useEditorType } from "@appsmith/hooks"; import history from "utils/history"; +import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; interface FetchPreviewData { datasourceId: string; diff --git a/app/client/src/pages/Editor/DataSourceEditor/index.tsx b/app/client/src/pages/Editor/DataSourceEditor/index.tsx index 1857103ed5..013b8362f3 100644 --- a/app/client/src/pages/Editor/DataSourceEditor/index.tsx +++ b/app/client/src/pages/Editor/DataSourceEditor/index.tsx @@ -102,6 +102,8 @@ import { } from "@appsmith/utils/BusinessFeatures/permissionPageHelpers"; import DatasourceTabs from "../DatasourceInfo/DatasorceTabs"; import DatasourceInformation, { ViewModeWrapper } from "./DatasourceSection"; +import { convertToPageIdSelector } from "selectors/pageListSelectors"; +import { getApplicationByIdFromWorkspaces } from "@appsmith/selectors/applicationSelectors"; interface ReduxStateProps { canDeleteDatasource: boolean; @@ -116,6 +118,7 @@ interface ReduxStateProps { isDeleting: boolean; isNewDatasource: boolean; isPluginAuthorized: boolean; + basePageId: string; pageId: string; pluginImage: string; pluginId: string; @@ -153,7 +156,7 @@ type Props = ReduxStateProps & DatasourcePaneFunctions & RouteComponentProps<{ datasourceId: string; - pageId: string; + basePageId: string; }>; export const DSEditorWrapper = styled.div` @@ -890,6 +893,7 @@ class DatasourceEditorRouter extends React.Component { render() { const { + basePageId, canDeleteDatasource, canManageDatasource, datasource, @@ -936,7 +940,7 @@ class DatasourceEditorRouter extends React.Component { } history.push( saasEditorDatasourceIdURL({ - pageId, + basePageId, pluginPackageName, datasourceId, }), @@ -1058,6 +1062,15 @@ class DatasourceEditorRouter extends React.Component { } const mapStateToProps = (state: AppState, props: any): ReduxStateProps => { + const applicationId = props.applicationId ?? getCurrentApplicationId(state); + const application = getApplicationByIdFromWorkspaces(state, applicationId); + + const basePageIdFromUrl = props?.match?.params?.basePageId; + const pageIdFromUrl = convertToPageIdSelector(state, basePageIdFromUrl); + const pageId = props.pageId || pageIdFromUrl; + const basePageId = + application?.pages?.find((page) => page.id === pageId)?.baseId ?? ""; + const datasourceId = props.datasourceId ?? props.match?.params?.datasourceId; const { datasourcePane } = state.ui; const { datasources, plugins } = state.entities; @@ -1146,13 +1159,14 @@ const mapStateToProps = (state: AppState, props: any): ReduxStateProps => { formConfig: formConfigs[pluginId] || [], isNewDatasource, isPluginAllowedToPreviewData, - pageId: props.pageId ?? props.match?.params?.pageId, + pageId, + basePageId, viewMode, pluginType: plugin?.type ?? "", pluginName: plugin?.name ?? "", pluginDatasourceForm, pluginPackageName, - applicationId: props.applicationId ?? getCurrentApplicationId(state), + applicationId, applicationSlug, pageSlug, isDatasourceBeingSaved: datasources.isDatasourceBeingSaved, diff --git a/app/client/src/pages/Editor/DatasourceInfo/DatasourceEntity.tsx b/app/client/src/pages/Editor/DatasourceInfo/DatasourceEntity.tsx index 8c2ad916c3..f96ce1eb44 100644 --- a/app/client/src/pages/Editor/DatasourceInfo/DatasourceEntity.tsx +++ b/app/client/src/pages/Editor/DatasourceInfo/DatasourceEntity.tsx @@ -39,7 +39,7 @@ const ExplorerDatasourceEntity = React.memo( let url; if (props.plugin && props.plugin.type === PluginType.SAAS) { url = saasEditorDatasourceIdURL({ - pageId: entityId, + basePageId: entityId, pluginPackageName: props.plugin.packageName, datasourceId: props.datasource.id, params: { @@ -48,7 +48,7 @@ const ExplorerDatasourceEntity = React.memo( }); } else { url = datasourcesEditorIdURL({ - pageId: entityId, + basePageId: entityId, datasourceId: props.datasource.id, params: omit(getQueryParams(), "viewMode"), }); diff --git a/app/client/src/pages/Editor/DatasourceInfo/DatasourceStructureNotFound.tsx b/app/client/src/pages/Editor/DatasourceInfo/DatasourceStructureNotFound.tsx index dbc59c0565..41cd71f7de 100644 --- a/app/client/src/pages/Editor/DatasourceInfo/DatasourceStructureNotFound.tsx +++ b/app/client/src/pages/Editor/DatasourceInfo/DatasourceStructureNotFound.tsx @@ -10,7 +10,7 @@ import history from "utils/history"; import { getQueryParams } from "utils/URLUtils"; import { datasourcesEditorIdURL } from "@appsmith/RouteBuilder"; import { omit } from "lodash"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import { DatasourceStructureContext } from "entities/Datasource"; export interface Props { @@ -40,7 +40,7 @@ const ButtonWrapper = styled.div` const DatasourceStructureNotFound = (props: Props) => { const { datasourceId, error, pluginName } = props; - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const editDatasource = () => { let entryPoint = DatasourceEditEntryPoints.QUERY_EDITOR_DATASOURCE_SCHEMA; @@ -61,7 +61,7 @@ const DatasourceStructureNotFound = (props: Props) => { } const url = datasourcesEditorIdURL({ - pageId, + basePageId, datasourceId: datasourceId, params: { ...omit(getQueryParams(), "viewMode"), viewMode: false }, generateEditorPath: true, diff --git a/app/client/src/pages/Editor/DatasourceInfo/DatasourceViewModeSchema.tsx b/app/client/src/pages/Editor/DatasourceInfo/DatasourceViewModeSchema.tsx index 91752ef69d..cb914426f6 100644 --- a/app/client/src/pages/Editor/DatasourceInfo/DatasourceViewModeSchema.tsx +++ b/app/client/src/pages/Editor/DatasourceInfo/DatasourceViewModeSchema.tsx @@ -15,10 +15,9 @@ import { } from "@appsmith/constants/messages"; import Table from "pages/Editor/QueryEditor/Table"; import { generateTemplateToUpdatePage } from "actions/pageActions"; -import { useParams } from "react-router"; -import type { ExplorerURLParams } from "@appsmith/pages/Editor/Explorer/helpers"; import { getCurrentApplicationId, + getCurrentPageId, getPagePermissions, } from "selectors/editorSelectors"; import { GENERATE_PAGE_MODE } from "../GeneratePage/components/GeneratePageForm/GeneratePageForm"; @@ -98,7 +97,7 @@ const DatasourceViewModeSchema = (props: Props) => { }); const applicationId: string = useSelector(getCurrentApplicationId); - const { pageId: currentPageId } = useParams(); + const pageId = useSelector(getCurrentPageId); const [previewData, setPreviewData] = useState([]); // this error is for when there's an issue with the datasource structure @@ -208,9 +207,7 @@ const DatasourceViewModeSchema = (props: Props) => { const payload = { applicationId: applicationId || "", pageId: - currentMode.current === GENERATE_PAGE_MODE.NEW - ? "" - : currentPageId || "", + currentMode.current === GENERATE_PAGE_MODE.NEW ? "" : pageId || "", columns: [], searchColumn: "", tableName: tableName, diff --git a/app/client/src/pages/Editor/DatasourceInfo/QueryTemplates.tsx b/app/client/src/pages/Editor/DatasourceInfo/QueryTemplates.tsx index 693b7e7983..11fcd49e34 100644 --- a/app/client/src/pages/Editor/DatasourceInfo/QueryTemplates.tsx +++ b/app/client/src/pages/Editor/DatasourceInfo/QueryTemplates.tsx @@ -4,6 +4,7 @@ import { createActionRequest } from "actions/pluginActionActions"; import type { AppState } from "@appsmith/reducers"; import { getCurrentApplicationId, + getCurrentBasePageId, getCurrentPageId, } from "selectors/editorSelectors"; import type { QueryAction } from "entities/Action"; @@ -62,7 +63,8 @@ export function QueryTemplates(props: QueryTemplatesProps) { useContext(WalkthroughContext) || {}; const applicationId = useSelector(getCurrentApplicationId); const actions = useSelector((state: AppState) => state.entities.actions); - const currentPageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); + const pageId = useSelector(getCurrentPageId); const dataSource: Datasource | undefined = useSelector((state: AppState) => getDatasource(state, props.datasourceId), ); @@ -90,7 +92,7 @@ export function QueryTemplates(props: QueryTemplatesProps) { dispatch( createActionRequest({ - pageId: currentPageId, + pageId, pluginId: dataSource?.pluginId, datasource: { id: props.datasourceId, @@ -114,7 +116,7 @@ export function QueryTemplates(props: QueryTemplatesProps) { history.push( integrationEditorURL({ - pageId: currentPageId, + basePageId, selectedTab: INTEGRATION_TABS.ACTIVE, }), ); @@ -122,7 +124,7 @@ export function QueryTemplates(props: QueryTemplatesProps) { [ dispatch, actions, - currentPageId, + basePageId, applicationId, props.datasourceId, dataSource, @@ -183,7 +185,7 @@ export function QueryTemplates(props: QueryTemplatesProps) { [ dispatch, actions, - currentPageId, + basePageId, applicationId, props.datasourceId, dataSource, diff --git a/app/client/src/pages/Editor/EditorHeader.tsx b/app/client/src/pages/Editor/EditorHeader.tsx index 0ba381b983..4a5516bcea 100644 --- a/app/client/src/pages/Editor/EditorHeader.tsx +++ b/app/client/src/pages/Editor/EditorHeader.tsx @@ -4,7 +4,7 @@ import AppInviteUsersForm from "pages/workspace/AppInviteUsersForm"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import { getCurrentApplicationId, - getCurrentPageId, + getCurrentBasePageId, getIsPageSaving, getIsPublishingApplication, getPageSavingError, @@ -93,13 +93,13 @@ export function EditorHeader() { const applicationId = useSelector(getCurrentApplicationId); const currentApplication = useSelector(getCurrentApplication); const isPublishing = useSelector(getIsPublishingApplication); - const pageId = useSelector(getCurrentPageId) as string; + const basePageId = useSelector(getCurrentBasePageId) as string; const featureFlags = useSelector(selectFeatureFlags); const isSaving = useSelector(getIsPageSaving); const pageSaveError = useSelector(getPageSavingError); const isProtectedMode = useSelector(protectedModeSelector); - const deployLink = useHref(viewerURL, { pageId }); + const deployLink = useHref(viewerURL, { basePageId }); const [isPopoverOpen, setIsPopoverOpen] = useState(false); const [showModal, setShowModal] = useState(false); diff --git a/app/client/src/pages/Editor/EntityNavigation/ActionPane/ActionPaneNavigation.ts b/app/client/src/pages/Editor/EntityNavigation/ActionPane/ActionPaneNavigation.ts index e8d3b64e54..75b0775169 100644 --- a/app/client/src/pages/Editor/EntityNavigation/ActionPane/ActionPaneNavigation.ts +++ b/app/client/src/pages/Editor/EntityNavigation/ActionPane/ActionPaneNavigation.ts @@ -13,6 +13,7 @@ import { getActionConfig } from "pages/Editor/Explorer/Actions/helpers"; import history from "utils/history"; import { NAVIGATION_DELAY } from "../costants"; import { setFocusableInputField } from "actions/editorContextActions"; +import { convertToBasePageIdSelector } from "selectors/pageListSelectors"; export default class ActionPaneNavigation extends PaneNavigation { action!: Action; @@ -53,17 +54,28 @@ export default class ActionPaneNavigation extends PaneNavigation { } *navigateToUrl() { - const { id, pageId, pluginId, pluginType } = this.action; + const { + baseId: baseActionId, + id: actionId, + pageId, + pluginId, + pluginType, + } = this.action; const applicationId: string = yield select(getCurrentApplicationId); const plugin: Plugin | undefined = yield select(getPlugin, pluginId); const actionConfig = getActionConfig(pluginType); + const basePageId: string = yield select( + convertToBasePageIdSelector, + pageId, + ); const url = - applicationId && actionConfig?.getURL(pageId, id, pluginType, plugin); + applicationId && + actionConfig?.getURL(basePageId, baseActionId, pluginType, plugin); if (!url) return; history.push(url); yield delay(NAVIGATION_DELAY); // Reset context switching field for the id, to allow scrolling to the error field - yield put(setFocusableInputField(id)); + yield put(setFocusableInputField(actionId)); } *scrollToView(propertyPath: string) { diff --git a/app/client/src/pages/Editor/EntityNavigation/JSObjectsPane/index.ts b/app/client/src/pages/Editor/EntityNavigation/JSObjectsPane/index.ts index a66d6b42bd..0c317c8f98 100644 --- a/app/client/src/pages/Editor/EntityNavigation/JSObjectsPane/index.ts +++ b/app/client/src/pages/Editor/EntityNavigation/JSObjectsPane/index.ts @@ -1,7 +1,4 @@ -import { - getCurrentPageId, - getJSCollectionById, -} from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import PaneNavigation from "../PaneNavigation"; import type { JSCollection } from "entities/JSCollection"; import { call, delay, put, select } from "redux-saga/effects"; @@ -16,6 +13,7 @@ import { setFocusableInputField, } from "actions/editorContextActions"; import { CursorPositionOrigin } from "@appsmith/reducers/uiReducers/editorContextReducer"; +import { getJSCollection } from "@appsmith/selectors/entitiesSelector"; export default class JSObjectsPaneNavigation extends PaneNavigation { jsCollection!: JSCollection; @@ -32,14 +30,8 @@ export default class JSObjectsPaneNavigation extends PaneNavigation { *init() { if (!this?.entityInfo) throw Error(`Initialisation failed`); const jsCollection: JSCollection | undefined = yield select( - getJSCollectionById, - { - match: { - params: { - collectionId: this.entityInfo?.id, - }, - }, - }, + getJSCollection, + this.entityInfo?.id, ); if (!jsCollection) @@ -102,10 +94,10 @@ export default class JSObjectsPaneNavigation extends PaneNavigation { functionName = this.entityInfo.propertyPath; } - const pageId: string = yield select(getCurrentPageId); + const basePageId: string = yield select(getCurrentBasePageId); const url = jsCollectionIdURL({ - pageId, - collectionId: this.entityInfo.id, + basePageId, + baseCollectionId: this.jsCollection.baseId, functionName, }); history.push(url); diff --git a/app/client/src/pages/Editor/Explorer/Actions/ActionEntity.tsx b/app/client/src/pages/Editor/Explorer/Actions/ActionEntity.tsx index d837d29f40..d3f1e5e2d7 100644 --- a/app/client/src/pages/Editor/Explorer/Actions/ActionEntity.tsx +++ b/app/client/src/pages/Editor/Explorer/Actions/ActionEntity.tsx @@ -7,7 +7,7 @@ import PerformanceTracker, { PerformanceTransactionName, } from "utils/PerformanceTracker"; import { - getAction, + getActionByBaseId, getDatasource, getPlugins, } from "@appsmith/selectors/entitiesSelector"; @@ -26,6 +26,7 @@ import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; import { saveActionNameBasedOnParentEntity } from "@appsmith/actions/helpers"; import type { ActionParentEntityTypeInterface } from "@appsmith/entities/Engine/actionHelpers"; +import { convertToBaseParentEntityIdSelector } from "selectors/pageListSelectors"; const getUpdateActionNameReduxAction = ( id: string, @@ -38,7 +39,7 @@ const getUpdateActionNameReduxAction = ( interface ExplorerActionEntityProps { step: number; searchKeyword?: string; - id: string; + baseId: string; type: PluginType; isActive: boolean; parentEntityId: string; @@ -46,18 +47,23 @@ interface ExplorerActionEntityProps { } export const ExplorerActionEntity = memo((props: ExplorerActionEntityProps) => { - const action = useSelector((state) => getAction(state, props.id)) as Action; + const action = useSelector((state) => + getActionByBaseId(state, props.baseId), + ) as Action; const plugins = useSelector(getPlugins); const pluginGroups = useMemo(() => keyBy(plugins, "id"), [plugins]); const location = useLocation(); const datasource = useSelector((state) => getDatasource(state, (action?.datasource as StoredDatasource)?.id), ) as Datasource; + const baseParentEntityId = useSelector((state) => + convertToBaseParentEntityIdSelector(state, props.parentEntityId), + ); const config = getActionConfig(props.type); const url = config?.getURL( - props.parentEntityId, - action.id, + baseParentEntityId ?? "", + action.baseId, action.pluginType, pluginGroups[action.pluginId], ); diff --git a/app/client/src/pages/Editor/Explorer/Actions/ActionEntityContextMenu.tsx b/app/client/src/pages/Editor/Explorer/Actions/ActionEntityContextMenu.tsx index 54cf23689f..63e408ac9f 100644 --- a/app/client/src/pages/Editor/Explorer/Actions/ActionEntityContextMenu.tsx +++ b/app/client/src/pages/Editor/Explorer/Actions/ActionEntityContextMenu.tsx @@ -32,6 +32,7 @@ import { import { useConvertToModuleOptions } from "@appsmith/pages/Editor/Explorer/hooks"; import { MODULE_TYPE } from "@appsmith/constants/ModuleConstants"; import { PluginType } from "entities/Action"; +import { convertToBaseParentEntityIdSelector } from "selectors/pageListSelectors"; interface EntityContextMenuProps { id: string; @@ -45,6 +46,9 @@ export function ActionEntityContextMenu(props: EntityContextMenuProps) { // Import the context const context = useContext(FilesContext); const { menuItems, parentEntityId } = context; + const baseParentEntityId = useSelector((state) => + convertToBaseParentEntityIdSelector(state, parentEntityId), + ); const { canDeleteAction, canManageAction } = props; const dispatch = useDispatch(); @@ -170,7 +174,7 @@ export function ActionEntityContextMenu(props: EntityContextMenuProps) { onSelect: () => { confirmDelete ? deleteActionFromPage(props.id, props.name, () => { - history.push(builderURL({ pageId: parentEntityId })); + history.push(builderURL({ basePageId: baseParentEntityId })); setConfirmDelete(false); }) : setConfirmDelete(true); diff --git a/app/client/src/pages/Editor/Explorer/Actions/MoreActionsMenu.tsx b/app/client/src/pages/Editor/Explorer/Actions/MoreActionsMenu.tsx index 46a090317c..7ade42b8ef 100644 --- a/app/client/src/pages/Editor/Explorer/Actions/MoreActionsMenu.tsx +++ b/app/client/src/pages/Editor/Explorer/Actions/MoreActionsMenu.tsx @@ -27,12 +27,13 @@ import { MenuTrigger, } from "design-system"; import { useToggle } from "@mantine/hooks"; +import { convertToPageIdSelector } from "selectors/pageListSelectors"; interface EntityContextMenuProps { id: string; name: string; className?: string; - pageId: string; + basePageId: string; isChangePermitted?: boolean; isDeletePermitted?: boolean; prefixAdditionalMenus?: React.ReactNode | React.ReactNode[]; @@ -42,6 +43,9 @@ interface EntityContextMenuProps { export function MoreActionsMenu(props: EntityContextMenuProps) { const [isMenuOpen, toggleMenuOpen] = useToggle([false, true]); const [confirmDelete, setConfirmDelete] = useState(false); + const propPageId = useSelector((state) => + convertToPageIdSelector(state, props.basePageId), + ); const { isChangePermitted = false, isDeletePermitted = false, @@ -71,11 +75,11 @@ export function MoreActionsMenu(props: EntityContextMenuProps) { moveActionRequest({ id: actionId, destinationPageId, - originalPageId: props.pageId, + originalPageId: propPageId ?? "", name: actionName, }), ), - [dispatch, props.pageId], + [dispatch, propPageId], ); const deleteActionFromPage = useCallback( (actionId: string, actionName: string) => { @@ -92,6 +96,7 @@ export function MoreActionsMenu(props: EntityContextMenuProps) { return state.entities.pageList.pages.map((page) => ({ label: page.pageName, id: page.pageId, + baseId: page.basePageId, value: page.pageName, })); }); @@ -122,7 +127,7 @@ export function MoreActionsMenu(props: EntityContextMenuProps) { {menuPages.map((page) => { return ( @@ -145,11 +150,11 @@ export function MoreActionsMenu(props: EntityContextMenuProps) { {/* Isn't it better ux to perform this check outside the menu and then simply not show the option?*/} {menuPages.length > 1 ? ( menuPages - .filter((page) => page.id !== props.pageId) // Remove current page from the list + .filter((page) => page.baseId !== props.basePageId) // Remove current page from the list .map((page) => { return ( diff --git a/app/client/src/pages/Editor/Explorer/Actions/helpers.tsx b/app/client/src/pages/Editor/Explorer/Actions/helpers.tsx index 7b349d4832..1da5301a17 100644 --- a/app/client/src/pages/Editor/Explorer/Actions/helpers.tsx +++ b/app/client/src/pages/Editor/Explorer/Actions/helpers.tsx @@ -30,7 +30,7 @@ export interface ActionGroupConfig { key: string; getURL: ( parentEntityId: string, - id: string, + baseId: string, pluginType: PluginType, plugin?: Plugin, ) => string; @@ -39,22 +39,22 @@ export interface ActionGroupConfig { export interface ResolveActionURLProps { plugin?: Plugin; - parentEntityId: string; + baseParentEntityId: string; pluginType: PluginType; - id: string; + baseId: string; } export const resolveActionURL = ({ - id, - parentEntityId, + baseId, + baseParentEntityId, pluginType, }: ResolveActionURLProps) => { if (pluginType === PluginType.SAAS) { return saasEditorApiIdURL({ - parentEntityId, + baseParentEntityId, // It is safe to assume at this date, that only Google Sheets uses and will use PluginType.SAAS pluginPackageName: PluginPackageName.GOOGLE_SHEETS, - apiId: id, + baseApiId: baseId, }); } else if ( pluginType === PluginType.DB || @@ -63,11 +63,11 @@ export const resolveActionURL = ({ pluginType === PluginType.INTERNAL ) { return queryEditorIdURL({ - parentEntityId, - queryId: id, + baseParentEntityId, + baseQueryId: baseId, }); } else { - return apiEditorIdURL({ parentEntityId, apiId: id }); + return apiEditorIdURL({ baseParentEntityId, baseApiId: baseId }); } }; @@ -88,12 +88,17 @@ export const ACTION_PLUGIN_MAP: Array = [ icon: dbQueryIcon, key: generateReactKey(), getURL: ( - parentEntityId: string, - id: string, + baseParentEntityId: string, + baseId: string, pluginType: PluginType, plugin?: Plugin, ) => { - return resolveActionURL({ pluginType, plugin, id, parentEntityId }); + return resolveActionURL({ + pluginType, + plugin, + baseId, + baseParentEntityId, + }); }, getIcon: (action: any, plugin: Plugin, remoteIcon?: boolean) => { const isGraphql = isGraphqlPlugin(plugin); diff --git a/app/client/src/pages/Editor/Explorer/EntityExplorer.test.tsx b/app/client/src/pages/Editor/Explorer/EntityExplorer.test.tsx index 0a2f29044c..4e93a083d0 100644 --- a/app/client/src/pages/Editor/Explorer/EntityExplorer.test.tsx +++ b/app/client/src/pages/Editor/Explorer/EntityExplorer.test.tsx @@ -58,13 +58,13 @@ describe("Entity Explorer tests", () => { beforeEach(() => { urlBuilder.updateURLParams( { - applicationId: "appId", + baseApplicationId: "appId", applicationSlug: "appSlug", applicationVersion: 2, }, [ { - pageId: "pageId", + basePageId: "pageId", pageSlug: "pageSlug", }, ], diff --git a/app/client/src/pages/Editor/Explorer/EntityExplorer.tsx b/app/client/src/pages/Editor/Explorer/EntityExplorer.tsx index a6afacbfcc..b4bb5aef0d 100644 --- a/app/client/src/pages/Editor/Explorer/EntityExplorer.tsx +++ b/app/client/src/pages/Editor/Explorer/EntityExplorer.tsx @@ -17,6 +17,7 @@ import ExplorerWidgetGroup from "./Widgets/WidgetGroup"; import { builderURL } from "@appsmith/RouteBuilder"; import history from "utils/history"; import { + getCurrentBasePageId, getCurrentPageId, getPagePermissions, } from "selectors/editorSelectors"; @@ -49,7 +50,7 @@ const NoResult = styled(NonIdealState)` svg { height: 52px; width: 144px; - + } } div { @@ -74,15 +75,16 @@ function EntityExplorer({ isActive }: { isActive: boolean }) { getIsFirstTimeUserOnboardingEnabled, ); const noResults = false; + const basePageId = useSelector(getCurrentBasePageId); const pageId = useSelector(getCurrentPageId); const showWidgetsSidebar = useCallback(() => { AnalyticsUtil.logEvent("EXPLORER_WIDGET_CLICK"); - history.push(builderURL({ pageId })); + history.push(builderURL({ basePageId })); dispatch(forceOpenWidgetPanel(true)); if (isFirstTimeUserOnboardingEnabled) { dispatch(toggleInOnboardingWidgetSelection(true)); } - }, [isFirstTimeUserOnboardingEnabled, pageId]); + }, [isFirstTimeUserOnboardingEnabled, basePageId]); const currentWorkspaceId = useSelector(getCurrentWorkspaceId); diff --git a/app/client/src/pages/Editor/Explorer/Files/index.tsx b/app/client/src/pages/Editor/Explorer/Files/index.tsx index f0711a58d8..1df3a3af3b 100644 --- a/app/client/src/pages/Editor/Explorer/Files/index.tsx +++ b/app/client/src/pages/Editor/Explorer/Files/index.tsx @@ -5,7 +5,7 @@ import React, { useMemo, useState, } from "react"; -import { useActiveAction } from "@appsmith/pages/Editor/Explorer/hooks"; +import { useActiveActionBaseId } from "@appsmith/pages/Editor/Explorer/hooks"; import { Entity, EntityClassNames } from "../Entity/index"; import { createMessage, @@ -69,15 +69,15 @@ function Files() { openMenu(true); }, [dispatch, openMenu]); - const activeActionId = useActiveAction(); + const activeActionBaseId = useActiveActionBaseId(); useEffect(() => { - if (!activeActionId) return; - document.getElementById(`entity-${activeActionId}`)?.scrollIntoView({ + if (!activeActionBaseId) return; + document.getElementById(`entity-${activeActionBaseId}`)?.scrollIntoView({ block: "nearest", inline: "nearest", }); - }, [activeActionId]); + }, [activeActionBaseId]); const onFilesToggle = useCallback( (isOpen: boolean) => { @@ -105,7 +105,7 @@ function Files() { return ( { const jsAction = useSelector((state: AppState) => - getJSCollection(state, props.id), + getJsCollectionByBaseId(state, props.baseCollectionId), ) as JSCollection; const location = useLocation(); const { parentEntityId, parentEntityType } = props; + const baseParentEntityId = useSelector((state) => + convertToBaseParentEntityIdSelector(state, parentEntityId), + ); const navigateToUrl = jsCollectionIdURL({ - parentEntityId, - collectionId: jsAction.id, + baseParentEntityId, + baseCollectionId: jsAction.baseId, params: {}, }); const navigateToJSCollection = useCallback(() => { - if (jsAction.id) { + if (jsAction.baseId) { AnalyticsUtil.logEvent("ENTITY_EXPLORER_CLICK", { type: "JSOBJECT", fromUrl: location.pathname, @@ -62,7 +66,7 @@ export const ExplorerJSCollectionEntity = memo( invokedBy: NavigationMethod.EntityExplorer, }); } - }, [parentEntityId, jsAction.id, jsAction.name, location.pathname]); + }, [baseParentEntityId, jsAction.baseId, jsAction.name, location.pathname]); const jsActionPermissions = jsAction.userPermissions || []; diff --git a/app/client/src/pages/Editor/Explorer/Pages/AddPageContextMenu.tsx b/app/client/src/pages/Editor/Explorer/Pages/AddPageContextMenu.tsx index 03d6a15731..2b497a3475 100644 --- a/app/client/src/pages/Editor/Explorer/Pages/AddPageContextMenu.tsx +++ b/app/client/src/pages/Editor/Explorer/Pages/AddPageContextMenu.tsx @@ -60,7 +60,7 @@ function AddPageContextMenu({ }: SubMenuProps) { const [show, setShow] = useState(openMenu); const dispatch = useDispatch(); - const { pageId } = useParams(); + const { basePageId } = useParams(); const isAirgappedInstance = isAirgapped(); const checkLayoutSystemFeatures = useLayoutSystemFeatures(); @@ -84,7 +84,7 @@ function AddPageContextMenu({ items.push({ title: createMessage(GENERATE_PAGE_ACTION_TITLE), icon: "database-2-line", - onClick: () => history.push(generateTemplateFormURL({ pageId })), + onClick: () => history.push(generateTemplateFormURL({ basePageId })), "data-testid": "generate-page", key: "GENERATE_PAGE", }); @@ -102,7 +102,7 @@ function AddPageContextMenu({ } return items; - }, [pageId, enableGenerateCrud]); + }, [basePageId, enableGenerateCrud]); const handleOpenChange = (open: boolean) => { if (open) { diff --git a/app/client/src/pages/Editor/Explorer/Pages/PageContextMenu.tsx b/app/client/src/pages/Editor/Explorer/Pages/PageContextMenu.tsx index 2bd7b23d7c..31faee5c8b 100644 --- a/app/client/src/pages/Editor/Explorer/Pages/PageContextMenu.tsx +++ b/app/client/src/pages/Editor/Explorer/Pages/PageContextMenu.tsx @@ -5,9 +5,9 @@ import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import { initExplorerEntityNameEdit } from "actions/explorerActions"; import { clonePageInit, - deletePage, + deletePageAction, setPageAsDefault, - updatePage, + updatePageAction, } from "actions/pageActions"; import styled from "styled-components"; import { Icon } from "design-system"; @@ -62,7 +62,7 @@ export function PageContextMenu(props: { * @return void */ const deletePageCallback = useCallback((): void => { - dispatch(deletePage(props.pageId)); + dispatch(deletePageAction(props.pageId)); AnalyticsUtil.logEvent("DELETE_PAGE", { pageName: props.name, }); @@ -105,7 +105,7 @@ export function PageContextMenu(props: { const setHiddenField = useCallback( () => dispatch( - updatePage({ + updatePageAction({ id: props.pageId, name: props.name, isHidden: !props.isHidden, diff --git a/app/client/src/pages/Editor/Explorer/Pages/index.tsx b/app/client/src/pages/Editor/Explorer/Pages/index.tsx index 62ee647e10..531171d587 100644 --- a/app/client/src/pages/Editor/Explorer/Pages/index.tsx +++ b/app/client/src/pages/Editor/Explorer/Pages/index.tsx @@ -7,7 +7,6 @@ import React, { } from "react"; import { useDispatch, useSelector } from "react-redux"; import { - getCurrentApplication, getCurrentApplicationId, getCurrentPageId, } from "selectors/editorSelectors"; @@ -38,6 +37,7 @@ import { } from "../Common/components"; import { EntityExplorerResizeHandler } from "../Common/EntityExplorerResizeHandler"; import { PageElement } from "pages/Editor/IDE/EditorPane/components/PageElement"; +import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; function Pages() { const applicationId = useSelector(getCurrentApplicationId); diff --git a/app/client/src/pages/Editor/Explorer/Widgets/WidgetEntity.tsx b/app/client/src/pages/Editor/Explorer/Widgets/WidgetEntity.tsx index ea3a5395a6..96f16c5202 100644 --- a/app/client/src/pages/Editor/Explorer/Widgets/WidgetEntity.tsx +++ b/app/client/src/pages/Editor/Explorer/Widgets/WidgetEntity.tsx @@ -19,6 +19,7 @@ import { getEntityExplorerWidgetsToExpand } from "selectors/widgetSelectors"; import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; import { getHasManagePagePermission } from "@appsmith/utils/BusinessFeatures/permissionPageHelpers"; +import { convertToPageIdSelector } from "selectors/pageListSelectors"; export type WidgetTree = WidgetProps & { children?: WidgetTree[] }; @@ -27,7 +28,7 @@ const UNREGISTERED_WIDGETS: WidgetType[] = ["ICON_WIDGET"]; const useWidget = ( widgetId: string, widgetType: WidgetType, - pageId: string, + basePageId: string, ) => { const selectedWidgets = useSelector(getSelectedWidgets); const lastSelectedWidget = useSelector(getLastSelectedWidget); @@ -43,14 +44,14 @@ const useWidget = ( navigateToWidget( widgetId, widgetType, - pageId, + basePageId, NavigationMethod.EntityExplorer, isWidgetSelected, isMultiSelect, isShiftSelect, ); }, - [widgetId, widgetType, pageId, isWidgetSelected, navigateToWidget], + [widgetId, widgetType, basePageId, isWidgetSelected, navigateToWidget], ); return { @@ -66,7 +67,7 @@ export interface WidgetEntityProps { widgetName: string; widgetType: WidgetType; step: number; - pageId: string; + basePageId: string; childWidgets?: CanvasStructure[]; parentModalId?: string; searchKeyword?: string; @@ -75,6 +76,9 @@ export interface WidgetEntityProps { } export const WidgetEntity = memo((props: WidgetEntityProps) => { + const pageId = useSelector((state) => + convertToPageIdSelector(state, props.basePageId), + ); const widgetsToExpand = useSelector(getEntityExplorerWidgetsToExpand); // If the widget icon is a React component, then we get it from the Widget methods. const { IconCmp } = WidgetFactory.getWidgetMethods(props.widgetType); @@ -97,7 +101,7 @@ export const WidgetEntity = memo((props: WidgetEntityProps) => { lastSelectedWidget, multipleWidgetsSelected, navigateToWidget, - } = useWidget(props.widgetId, props.widgetType, props.pageId); + } = useWidget(props.widgetId, props.widgetType, props.basePageId); const { parentModalId, widgetId, widgetType } = props; /** @@ -115,14 +119,14 @@ export const WidgetEntity = memo((props: WidgetEntityProps) => { type: "WIDGETS", fromUrl: location.pathname, toUrl: `${builderURL({ - pageId: props.pageId, + basePageId: props.basePageId, hash: widgetId, })}`, name: props.widgetName, }); navigateToWidget(e); }, - [location.pathname, props.pageId, widgetId, props.widgetName], + [location.pathname, props.basePageId, widgetId, props.widgetName], ); if (UNREGISTERED_WIDGETS.indexOf(props.widgetType) > -1) return null; @@ -131,12 +135,12 @@ export const WidgetEntity = memo((props: WidgetEntityProps) => { ); - const showContextMenu = !multipleWidgetsSelected; + const showContextMenu = !multipleWidgetsSelected && pageId; const widgetsInStep = props?.childWidgets ? props?.childWidgets?.map((child) => child.widgetId) : []; @@ -166,9 +170,9 @@ export const WidgetEntity = memo((props: WidgetEntityProps) => { props.childWidgets.length > 0 && props.childWidgets.map((child) => ( { const applicationId = useSelector(getCurrentApplicationId); - const pageId = useSelector(getCurrentPageId) || ""; + const basePageId = useSelector(getCurrentBasePageId) || ""; const widgets = useSelector(selectWidgetsForCurrentPage); let isWidgetsOpen = getExplorerStatus(applicationId, "widgets"); if (isWidgetsOpen === null || isWidgetsOpen === undefined) { @@ -68,11 +68,11 @@ export const ExplorerWidgetGroup = memo((props: ExplorerWidgetGroupProps) => { canEditEntityName={canManagePages} className={`group widgets ${props.addWidgetsFn ? "current" : ""}`} disabled={!widgets && !!props.searchKeyword} - entityId={pageId + "_widgets"} + entityId={basePageId + "_widgets"} icon={""} isDefaultExpanded={isWidgetsOpen} isSticky - key={pageId + "_widgets"} + key={basePageId + "_widgets"} name="Widgets" onCreate={props.addWidgetsFn} onToggle={onWidgetToggle} @@ -82,9 +82,9 @@ export const ExplorerWidgetGroup = memo((props: ExplorerWidgetGroupProps) => { > {widgets?.children?.map((child) => ( { {widgets?.children && widgets?.children?.length > 0 && canManagePages && ( } name={createMessage(ADD_WIDGET_BUTTON)} step={props.step + 1} diff --git a/app/client/src/pages/Editor/Explorer/Widgets/useNavigateToWidget.ts b/app/client/src/pages/Editor/Explorer/Widgets/useNavigateToWidget.ts index 96c742899c..76e148f962 100644 --- a/app/client/src/pages/Editor/Explorer/Widgets/useNavigateToWidget.ts +++ b/app/client/src/pages/Editor/Explorer/Widgets/useNavigateToWidget.ts @@ -30,7 +30,7 @@ export const useNavigateToWidget = () => { ( widgetId: string, widgetType: WidgetType, - pageId: string, + basePageId: string, navigationMethod: NavigationMethod, isWidgetSelected?: boolean, isMultiSelect?: boolean, @@ -45,7 +45,7 @@ export const useNavigateToWidget = () => { SelectionRequestType.UnsafeSelect, [widgetId], navigationMethod, - pageId, + basePageId, ); return; } diff --git a/app/client/src/pages/Editor/Explorer/Widgets/utils.ts b/app/client/src/pages/Editor/Explorer/Widgets/utils.ts deleted file mode 100644 index bbe4395106..0000000000 --- a/app/client/src/pages/Editor/Explorer/Widgets/utils.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { builderURL } from "@appsmith/RouteBuilder"; -import history from "utils/history"; - -export const navigateToCanvas = (pageId: string) => { - const currentPath = window.location.pathname; - const canvasEditorURL = `${builderURL({ - pageId, - persistExistingParams: true, - })}`; - if (currentPath !== canvasEditorURL) { - history.push(canvasEditorURL); - } -}; diff --git a/app/client/src/pages/Editor/Explorer/index.tsx b/app/client/src/pages/Editor/Explorer/index.tsx index ae9144d346..31a61a1c49 100644 --- a/app/client/src/pages/Editor/Explorer/index.tsx +++ b/app/client/src/pages/Editor/Explorer/index.tsx @@ -6,7 +6,7 @@ import { useDispatch, useSelector } from "react-redux"; import { useLocation } from "react-router"; import type { AppState } from "@appsmith/reducers"; import { builderURL } from "@appsmith/RouteBuilder"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import { getIsFirstTimeUserOnboardingEnabled } from "selectors/onboardingSelectors"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import { trimQueryString } from "utils/helpers"; @@ -36,7 +36,7 @@ function ExplorerContent() { const isFirstTimeUserOnboardingEnabled = useSelector( getIsFirstTimeUserOnboardingEnabled, ); - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const location = useLocation(); const activeSwitchIndex = useSelector(getExplorerSwitchIndex); @@ -56,12 +56,14 @@ function ExplorerContent() { if (value === options[0].value) { dispatch(forceOpenWidgetPanel(false)); } else if (value === options[1].value) { - if (!(trimQueryString(builderURL({ pageId })) === location.pathname)) { - history.push(builderURL({ pageId })); + if ( + !(trimQueryString(builderURL({ basePageId })) === location.pathname) + ) { + history.push(builderURL({ basePageId })); AnalyticsUtil.logEvent("WIDGET_TAB_CLICK", { type: "WIDGET_TAB", fromUrl: location.pathname, - toUrl: builderURL({ pageId }), + toUrl: builderURL({ basePageId }), }); } diff --git a/app/client/src/pages/Editor/FirstTimeUserOnboarding/Checklist.test.tsx b/app/client/src/pages/Editor/FirstTimeUserOnboarding/Checklist.test.tsx index 0f594240ec..0db57b6da4 100644 --- a/app/client/src/pages/Editor/FirstTimeUserOnboarding/Checklist.test.tsx +++ b/app/client/src/pages/Editor/FirstTimeUserOnboarding/Checklist.test.tsx @@ -55,13 +55,13 @@ describe("Checklist", () => { urlBuilder.updateURLParams( { applicationSlug: initialState.ui.applications.currentApplication.slug, - applicationId: initialState.entities.pageList.applicationId, + baseApplicationId: initialState.entities.pageList.baseApplicationId, applicationVersion: 2, }, [ { pageSlug: initialState.entities.pageList.pages[0].slug, - pageId: initialState.entities.pageList.currentPageId, + basePageId: initialState.entities.pageList.currentBasePageId, }, ], ); @@ -92,7 +92,7 @@ describe("Checklist", () => { fireEvent.click(datasourceButton[0]); expect(history).toHaveBeenCalledWith( integrationEditorURL({ - pageId: initialState.entities.pageList.currentPageId, + basePageId: initialState.entities.pageList.currentBasePageId, selectedTab: INTEGRATION_TABS.NEW, }), ); @@ -122,7 +122,7 @@ describe("Checklist", () => { fireEvent.click(actionButton[0]); expect(history).toHaveBeenCalledWith( integrationEditorURL({ - pageId: initialState.entities.pageList.currentPageId, + basePageId: initialState.entities.pageList.currentBasePageId, selectedTab: INTEGRATION_TABS.ACTIVE, }), ); @@ -135,7 +135,9 @@ describe("Checklist", () => { const widgetButton = screen.queryAllByTestId("checklist-widget"); fireEvent.click(widgetButton[0]); expect(history).toHaveBeenCalledWith( - builderURL({ pageId: initialState.entities.pageList.currentPageId }), + builderURL({ + basePageId: initialState.entities.pageList.currentBasePageId, + }), ); expect(dispatch).toHaveBeenCalledWith({ type: ReduxActionTypes.TOGGLE_ONBOARDING_WIDGET_SELECTION, @@ -158,7 +160,7 @@ describe("Checklist", () => { bindDataOnCanvas({ queryId: store.getState().entities.actions[0].config.id, applicationId: store.getState().entities.pageList.applicationId, - pageId: store.getState().entities.pageList.currentPageId, + basePageId: store.getState().entities.pageList.currentBasePageId, }), ); }); diff --git a/app/client/src/pages/Editor/FirstTimeUserOnboarding/Checklist.tsx b/app/client/src/pages/Editor/FirstTimeUserOnboarding/Checklist.tsx index 00ec5c9082..47ffbdbece 100644 --- a/app/client/src/pages/Editor/FirstTimeUserOnboarding/Checklist.tsx +++ b/app/client/src/pages/Editor/FirstTimeUserOnboarding/Checklist.tsx @@ -11,6 +11,7 @@ import { INTEGRATION_TABS } from "constants/routes"; import { getApplicationLastDeployedAt, getCurrentApplicationId, + getCurrentBasePageId, getCurrentPageId, } from "selectors/editorSelectors"; import history from "utils/history"; @@ -346,6 +347,7 @@ export default function OnboardingChecklist() { const dispatch = useDispatch(); const datasources = useSelector(getSavedDatasources); const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const actions = useSelector(getPageActions(pageId)); const widgets = useSelector(getCanvasWidgets); const isConnectionPresent = useSelector(isWidgetActionConnectionPresent); @@ -365,16 +367,16 @@ export default function OnboardingChecklist() { const onconnectYourWidget = () => { const action = actions[0]; dispatch(showSignpostingModal(false)); - if (action && applicationId && pageId) { + if (action && applicationId && basePageId) { dispatch( bindDataOnCanvas({ queryId: action.config.id, applicationId, - pageId, + basePageId, }), ); } else { - history.push(builderURL({ pageId })); + history.push(builderURL({ basePageId })); } AnalyticsUtil.logEvent("SIGNPOSTING_MODAL_CONNECT_WIDGET_CLICK"); }; @@ -496,7 +498,7 @@ export default function OnboardingChecklist() { history.push( integrationEditorURL({ - pageId, + basePageId, selectedTab: INTEGRATION_TABS.NEW, }), ); @@ -517,7 +519,7 @@ export default function OnboardingChecklist() { dispatch(showSignpostingModal(false)); history.push( integrationEditorURL({ - pageId, + basePageId, selectedTab: INTEGRATION_TABS.ACTIVE, }), ); @@ -543,7 +545,7 @@ export default function OnboardingChecklist() { dispatch(showSignpostingModal(false)); dispatch(toggleInOnboardingWidgetSelection(true)); dispatch(forceOpenWidgetPanel(true)); - history.push(builderURL({ pageId })); + history.push(builderURL({ basePageId })); }} step={SIGNPOSTING_STEP.ADD_WIDGETS} testid={"checklist-widget"} diff --git a/app/client/src/pages/Editor/FirstTimeUserOnboarding/testUtils.ts b/app/client/src/pages/Editor/FirstTimeUserOnboarding/testUtils.ts index 9cf51e2331..66790cf2f5 100644 --- a/app/client/src/pages/Editor/FirstTimeUserOnboarding/testUtils.ts +++ b/app/client/src/pages/Editor/FirstTimeUserOnboarding/testUtils.ts @@ -2,14 +2,17 @@ import _ from "lodash"; import configureStore from "redux-mock-store"; const PAGE_ID = "0123456789abcdef00000000"; +const BASE_PAGE_ID = "0123456789abcdef00000022"; export const initialState: any = { entities: { pageList: { applicationId: "1", currentPageId: PAGE_ID, + currentBasePageId: BASE_PAGE_ID, pages: [ { pageId: PAGE_ID, + basePageId: BASE_PAGE_ID, slug: "pageSlug", }, ], diff --git a/app/client/src/pages/Editor/GeneratePage/components/GeneratePageForm/GeneratePageForm.tsx b/app/client/src/pages/Editor/GeneratePage/components/GeneratePageForm/GeneratePageForm.tsx index ba4c6b8b89..848bf262ca 100644 --- a/app/client/src/pages/Editor/GeneratePage/components/GeneratePageForm/GeneratePageForm.tsx +++ b/app/client/src/pages/Editor/GeneratePage/components/GeneratePageForm/GeneratePageForm.tsx @@ -13,8 +13,7 @@ import { import type { Datasource } from "entities/Datasource"; import { fetchDatasourceStructure } from "actions/datasourceActions"; import { generateTemplateToUpdatePage } from "actions/pageActions"; -import { useParams, useLocation } from "react-router"; -import type { ExplorerURLParams } from "@appsmith/pages/Editor/Explorer/helpers"; +import { useLocation } from "react-router"; import { INTEGRATION_TABS } from "constants/routes"; import history from "utils/history"; import { getQueryParams } from "utils/URLUtils"; @@ -54,7 +53,11 @@ import { } from "../constants"; import { Bold, Label, SelectWrapper } from "./styles"; import type { GeneratePagePayload } from "./types"; -import { getCurrentApplicationId } from "selectors/editorSelectors"; +import { + getCurrentApplicationId, + getCurrentBasePageId, + getCurrentPageId, +} from "selectors/editorSelectors"; import { datasourcesEditorIdURL, @@ -217,7 +220,8 @@ function GeneratePageForm() { const dispatch = useDispatch(); const querySearch = useLocation().search; - const { pageId: currentPageId } = useParams(); + const basePageId = useSelector(getCurrentBasePageId); + const pageId = useSelector(getCurrentPageId); const pluginImages = useSelector(getPluginImages); @@ -552,7 +556,7 @@ function GeneratePageForm() { AnalyticsUtil.logEvent("GEN_CRUD_PAGE_CREATE_NEW_DATASOURCE"); history.push( integrationEditorURL({ - pageId: currentPageId, + basePageId, selectedTab: INTEGRATION_TABS.NEW, params: { isGeneratePageMode: "generate-page" }, }), @@ -575,9 +579,7 @@ function GeneratePageForm() { const payload = { applicationId: applicationId || "", pageId: - currentMode.current === GENERATE_PAGE_MODE.NEW - ? "" - : currentPageId || "", + currentMode.current === GENERATE_PAGE_MODE.NEW ? "" : pageId || "", columns: data.columns || [], searchColumn: data.searchColumn, tableName: data.tableName, @@ -604,7 +606,7 @@ function GeneratePageForm() { datasourceId: selectedDatasource.id, }); const redirectURL = datasourcesEditorIdURL({ - pageId: currentPageId, + basePageId, datasourceId: selectedDatasource.id as string, params: { isGeneratePageMode: "generate-page" }, }); diff --git a/app/client/src/pages/Editor/IDE/EditorPane/GlobalAdd.tsx b/app/client/src/pages/Editor/IDE/EditorPane/GlobalAdd.tsx index 282c3ef8c4..67d3fca72f 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/GlobalAdd.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/GlobalAdd.tsx @@ -3,7 +3,7 @@ import React, { useCallback } from "react"; import styled from "styled-components"; import { Button, Flex, Icon, Text } from "design-system"; import { useDispatch, useSelector } from "react-redux"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import history from "utils/history"; import { queryAddURL } from "@appsmith/RouteBuilder"; import { createNewJSCollection } from "actions/jsPaneActions"; @@ -58,14 +58,14 @@ const CreateCTA = (props: { }; const GlobalAdd = () => { - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const dispatch = useDispatch(); const onCreateNewQuery = useCallback(() => { - history.push(queryAddURL({ pageId })); - }, [pageId]); + history.push(queryAddURL({ basePageId })); + }, [basePageId]); const onCreateJS = useCallback(() => { - dispatch(createNewJSCollection(pageId, "ADD_PANE")); - }, [pageId]); + dispatch(createNewJSCollection(basePageId, "ADD_PANE")); + }, [basePageId]); return ( { localStorage.setItem("SPLITPANE_ANNOUNCEMENT", "false"); describe("JS Blank State", () => { @@ -27,7 +27,7 @@ describe("IDE Render: JS", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/jsObjects`, + url: `/app/applicationSlug/pageSlug-${basePageId}/edit/jsObjects`, featureFlags: FeatureFlags, }, ); @@ -51,7 +51,7 @@ describe("IDE Render: JS", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/jsObjects`, + url: `/app/applicationSlug/pageSlug-${basePageId}/edit/jsObjects`, initialState: state, featureFlags: FeatureFlags, }, @@ -76,7 +76,7 @@ describe("IDE Render: JS", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/jsObjects/add`, + url: `/app/applicationSlug/pageSlug-${basePageId}/edit/jsObjects/add`, featureFlags: FeatureFlags, }, ); @@ -100,7 +100,7 @@ describe("IDE Render: JS", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/jsObjects/add`, + url: `/app/applicationSlug/pageSlug-${basePageId}/edit/jsObjects/add`, initialState: state, featureFlags: FeatureFlags, }, @@ -121,14 +121,16 @@ describe("IDE Render: JS", () => { describe("JS Edit Render", () => { it("Renders JS routes in Full screen", () => { const page = PageFactory.build(); - const JS = JSObjectFactory.build({ id: "js_id", pageId: page.pageId }); + const js1 = JSObjectFactory.build({ + pageId: page.pageId, + }); const state = getIDETestState({ pages: [page], - js: [JS], + js: [js1], tabs: { [EditorEntityTab.QUERIES]: [], - [EditorEntityTab.JS]: ["js_id"], + [EditorEntityTab.JS]: [js1.baseId], }, }); @@ -137,7 +139,7 @@ describe("IDE Render: JS", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/jsObjects/js_id`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/jsObjects/${js1.baseId}`, initialState: state, featureFlags: FeatureFlags, }, @@ -168,6 +170,7 @@ describe("IDE Render: JS", () => { const page = PageFactory.build(); const js2 = JSObjectFactory.build({ id: "js_id2", + baseId: "js_base_id2", pageId: page.pageId, }); const state = getIDETestState({ @@ -175,7 +178,7 @@ describe("IDE Render: JS", () => { pages: [page], tabs: { [EditorEntityTab.QUERIES]: [], - [EditorEntityTab.JS]: ["js_id2"], + [EditorEntityTab.JS]: [js2.baseId], }, ideView: EditorViewMode.SplitScreen, }); @@ -185,7 +188,7 @@ describe("IDE Render: JS", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/jsObjects/js_id2`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/jsObjects/${js2.baseId}`, initialState: state, featureFlags: FeatureFlags, }, @@ -215,16 +218,17 @@ describe("IDE Render: JS", () => { it("Renders JS add routes in Full Screen", () => { const page = PageFactory.build(); - const JS3 = JSObjectFactory.build({ + const js3 = JSObjectFactory.build({ id: "js_id3", + baseId: "js_base_id3", pageId: page.pageId, }); const state = getIDETestState({ - js: [JS3], + js: [js3], pages: [page], tabs: { [EditorEntityTab.QUERIES]: [], - [EditorEntityTab.JS]: ["js_id3"], + [EditorEntityTab.JS]: [js3.baseId], }, }); @@ -233,7 +237,7 @@ describe("IDE Render: JS", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/jsObjects/js_id3/add`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/jsObjects/${js3.baseId}/add`, initialState: state, featureFlags: FeatureFlags, }, @@ -255,13 +259,17 @@ describe("IDE Render: JS", () => { it("Renders JS add routes in Split Screen", () => { const page = PageFactory.build(); - const js3 = JSObjectFactory.build({ id: "js_id4", pageId: page.pageId }); + const js4 = JSObjectFactory.build({ + id: "js_id4", + baseId: "js_base_id4", + pageId: page.pageId, + }); const state = getIDETestState({ - js: [js3], + js: [js4], pages: [page], tabs: { [EditorEntityTab.QUERIES]: [], - [EditorEntityTab.JS]: ["js_id4"], + [EditorEntityTab.JS]: [js4.baseId], }, ideView: EditorViewMode.SplitScreen, }); @@ -271,7 +279,7 @@ describe("IDE Render: JS", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/jsObjects/js_id4/add`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/jsObjects/${js4.baseId}/add`, initialState: state, featureFlags: FeatureFlags, }, @@ -294,6 +302,7 @@ describe("IDE Render: JS", () => { const page = PageFactory.build(); const Main_JS = JSObjectFactory.build({ id: "js_id", + baseId: "js_base_id", name: "Main", pageId: page.pageId, }); @@ -301,6 +310,7 @@ describe("IDE Render: JS", () => { const Normal_JS = JSObjectFactory.build({ id: "js_id2", + baseId: "js_base_id2", name: "Normal", pageId: page.pageId, }); @@ -310,7 +320,7 @@ describe("IDE Render: JS", () => { js: [Main_JS, Normal_JS], tabs: { [EditorEntityTab.QUERIES]: [], - [EditorEntityTab.JS]: ["js_id"], + [EditorEntityTab.JS]: [Main_JS.baseId], }, }); @@ -319,7 +329,7 @@ describe("IDE Render: JS", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/jsObjects/js_id`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/jsObjects/${Main_JS.baseId}`, initialState: state, featureFlags: FeatureFlags, }, diff --git a/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx b/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx index 3861f9cc28..f052c9691a 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx @@ -5,7 +5,7 @@ import styled from "styled-components"; import type { EditorSegmentList } from "@appsmith/selectors/appIDESelectors"; import { selectJSSegmentEditorList } from "@appsmith/selectors/appIDESelectors"; -import { useActiveAction } from "@appsmith/pages/Editor/Explorer/hooks"; +import { useActiveActionBaseId } from "@appsmith/pages/Editor/Explorer/hooks"; import { getCurrentApplicationId, getCurrentPageId, @@ -39,7 +39,7 @@ const ListJSObjects = () => { const [searchTerm, setSearchTerm] = useState(""); const pageId = useSelector(getCurrentPageId); const files = useSelector(selectJSSegmentEditorList); - const activeActionId = useActiveAction(); + const activeActionBaseId = useActiveActionBaseId(); const applicationId = useSelector(getCurrentApplicationId); const pagePermissions = useSelector(getPagePermissions); @@ -104,7 +104,7 @@ const ListJSObjects = () => { {items.map((item) => { return ( { const [searchTerm, setSearchTerm] = useState(""); const pageId = useSelector(getCurrentPageId) as string; const files = useSelector(selectQuerySegmentEditorList); - const activeActionId = useActiveAction(); + const activeActionBaseId = useActiveActionBaseId(); const pagePermissions = useSelector(getPagePermissions); const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); @@ -84,7 +84,7 @@ const ListQuery = () => { {items.map((file) => { return ( { localStorage.setItem("SPLITPANE_ANNOUNCEMENT", "false"); @@ -33,7 +33,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/queries`, + url: `/app/applicationSlug/pageSlug-${basePageId}/edit/queries`, featureFlags: FeatureFlags, }, ); @@ -55,7 +55,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/queries`, + url: `/app/applicationSlug/pageSlug-${basePageId}/edit/queries`, initialState: state, featureFlags: FeatureFlags, }, @@ -78,7 +78,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/queries/add`, + url: `/app/applicationSlug/pageSlug-${basePageId}/edit/queries/add`, featureFlags: FeatureFlags, }, ); @@ -103,7 +103,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/queries/add`, + url: `/app/applicationSlug/pageSlug-${basePageId}/edit/queries/add`, initialState: state, featureFlags: FeatureFlags, }, @@ -133,12 +133,12 @@ describe("IDE URL rendering of Queries", () => { describe("API Routes", () => { it("Renders Api routes in Full screen", () => { const page = PageFactory.build(); - const anApi = APIFactory.build({ id: "api_id", pageId: page.pageId }); + const anApi = APIFactory.build({ pageId: page.pageId }); const state = getIDETestState({ pages: [page], actions: [anApi], tabs: { - [EditorEntityTab.QUERIES]: ["api_id"], + [EditorEntityTab.QUERIES]: [anApi.baseId], [EditorEntityTab.JS]: [], }, }); @@ -148,7 +148,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/api/api_id`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/api/${anApi.baseId}`, initialState: state, featureFlags: FeatureFlags, }, @@ -176,12 +176,16 @@ describe("IDE URL rendering of Queries", () => { it("Renders Api routes in Split Screen", async () => { const page = PageFactory.build(); - const anApi = APIFactory.build({ id: "api_id2", pageId: page.pageId }); + const anApi = APIFactory.build({ + id: "api_id2", + baseId: "api_base_id2", + pageId: page.pageId, + }); const state = getIDETestState({ actions: [anApi], pages: [page], tabs: { - [EditorEntityTab.QUERIES]: ["api_id2"], + [EditorEntityTab.QUERIES]: [anApi.baseId], [EditorEntityTab.JS]: [], }, ideView: EditorViewMode.SplitScreen, @@ -192,7 +196,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/api/api_id2`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/api/${anApi.baseId}`, initialState: state, featureFlags: FeatureFlags, }, @@ -218,12 +222,16 @@ describe("IDE URL rendering of Queries", () => { it("Renders Api add routes in Full Screen", () => { const page = PageFactory.build(); - const anApi = APIFactory.build({ id: "api_id", pageId: page.pageId }); + const anApi = APIFactory.build({ + id: "api_id", + baseId: "api_base_id", + pageId: page.pageId, + }); const state = getIDETestState({ actions: [anApi], pages: [page], tabs: { - [EditorEntityTab.QUERIES]: ["api_id"], + [EditorEntityTab.QUERIES]: [anApi.baseId], [EditorEntityTab.JS]: [], }, }); @@ -233,7 +241,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/api/api_id/add`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/api/${anApi.baseId}/add`, initialState: state, featureFlags: FeatureFlags, }, @@ -251,14 +259,19 @@ describe("IDE URL rendering of Queries", () => { newTab.querySelector("[data-testid='t--tab-close-btn']"), ).not.toBeNull(); }); + it("Renders Api add routes in Split Screen", () => { const page = PageFactory.build(); - const anApi = APIFactory.build({ id: "api_id", pageId: page.pageId }); + const anApi = APIFactory.build({ + id: "api_id", + baseId: "api_base_id", + pageId: page.pageId, + }); const state = getIDETestState({ actions: [anApi], pages: [page], tabs: { - [EditorEntityTab.QUERIES]: ["api_id"], + [EditorEntityTab.QUERIES]: [anApi.baseId], [EditorEntityTab.JS]: [], }, ideView: EditorViewMode.SplitScreen, @@ -269,7 +282,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/api/api_id/add`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/api/${anApi.baseId}/add`, initialState: state, featureFlags: FeatureFlags, }, @@ -305,13 +318,14 @@ describe("IDE URL rendering of Queries", () => { const page = PageFactory.build(); const anQuery = PostgresFactory.build({ id: "query_id", + baseId: "query_base_id", pageId: page.pageId, }); const state = getIDETestState({ actions: [anQuery], pages: [page], tabs: { - [EditorEntityTab.QUERIES]: ["query_id"], + [EditorEntityTab.QUERIES]: [anQuery.baseId], [EditorEntityTab.JS]: [], }, }); @@ -321,7 +335,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/queries/query_id`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/queries/${anQuery.baseId}`, sagasToRun: sagasToRunForTests, initialState: state, featureFlags: FeatureFlags, @@ -348,17 +362,19 @@ describe("IDE URL rendering of Queries", () => { // Check if the Add new button is shown getByTestId("t--add-item"); }); + it("Renders Postgres routes in Split screen", async () => { const page = PageFactory.build(); const anQuery = PostgresFactory.build({ id: "query_id", + baseId: "query_base_id", pageId: page.pageId, }); const state = getIDETestState({ actions: [anQuery], pages: [page], tabs: { - [EditorEntityTab.QUERIES]: ["query_id"], + [EditorEntityTab.QUERIES]: [anQuery.baseId], [EditorEntityTab.JS]: [], }, ideView: EditorViewMode.SplitScreen, @@ -369,7 +385,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/queries/query_id`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/queries/${anQuery.baseId}`, sagasToRun: sagasToRunForTests, initialState: state, featureFlags: FeatureFlags, @@ -396,17 +412,19 @@ describe("IDE URL rendering of Queries", () => { // Check if the Add new button is shown getByTestId("t--ide-tabs-add-button"); }); + it("Renders Postgres add routes in Full Screen", async () => { const page = PageFactory.build(); const anQuery = PostgresFactory.build({ id: "query_id", + baseId: "query_base_id", pageId: page.pageId, }); const state = getIDETestState({ actions: [anQuery], pages: [page], tabs: { - [EditorEntityTab.QUERIES]: ["query_id"], + [EditorEntityTab.QUERIES]: [anQuery.baseId], [EditorEntityTab.JS]: [], }, }); @@ -416,7 +434,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/${page.slug}-${page.pageId}/edit/queries/query_id/add`, + url: `/app/applicationSlug/${page.slug}-${page.pageId}/edit/queries/${anQuery.baseId}/add`, initialState: state, featureFlags: FeatureFlags, sagasToRun: sagasToRunForTests, @@ -437,17 +455,19 @@ describe("IDE URL rendering of Queries", () => { newTab.querySelector("[data-testid='t--tab-close-btn']"), ).not.toBeNull(); }); + it("Renders Postgres add routes in Split Screen", () => { const page = PageFactory.build(); const anQuery = PostgresFactory.build({ id: "query_id", + baseId: "query_base_id", pageId: page.pageId, }); const state = getIDETestState({ actions: [anQuery], pages: [page], tabs: { - [EditorEntityTab.QUERIES]: ["query_id"], + [EditorEntityTab.QUERIES]: [anQuery.baseId], [EditorEntityTab.JS]: [], }, ideView: EditorViewMode.SplitScreen, @@ -458,7 +478,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/queries/query_id/add`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/queries/${anQuery.baseId}/add`, sagasToRun: sagasToRunForTests, initialState: state, featureFlags: FeatureFlags, @@ -496,13 +516,14 @@ describe("IDE URL rendering of Queries", () => { const anQuery = GoogleSheetFactory.build({ name: "Sheets1", id: "saas_api_id", + baseId: "saas_api_base_id", pageId: page.pageId, }); const state = getIDETestState({ actions: [anQuery], pages: [page], tabs: { - [EditorEntityTab.QUERIES]: ["saas_api_id"], + [EditorEntityTab.QUERIES]: [anQuery.baseId], [EditorEntityTab.JS]: [], }, }); @@ -512,7 +533,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/saas/google-sheets-plugin/api/saas_api_id`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/saas/google-sheets-plugin/api/${anQuery.baseId}`, sagasToRun: sagasToRunForTests, initialState: state, featureFlags: FeatureFlags, @@ -539,18 +560,20 @@ describe("IDE URL rendering of Queries", () => { // Check if the Add new button is shown getByTestId("t--add-item"); }); + it("Renders Google Sheets routes in Split screen", async () => { const page = PageFactory.build(); const anQuery = GoogleSheetFactory.build({ name: "Sheets2", id: "saas_api_id", + baseId: "saas_api_base_id", pageId: page.pageId, }); const state = getIDETestState({ actions: [anQuery], pages: [page], tabs: { - [EditorEntityTab.QUERIES]: ["saas_api_id"], + [EditorEntityTab.QUERIES]: [anQuery.baseId], [EditorEntityTab.JS]: [], }, ideView: EditorViewMode.SplitScreen, @@ -561,7 +584,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/saas/google-sheets-plugin/api/saas_api_id`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/saas/google-sheets-plugin/api/${anQuery.baseId}`, sagasToRun: sagasToRunForTests, initialState: state, featureFlags: FeatureFlags, @@ -590,18 +613,20 @@ describe("IDE URL rendering of Queries", () => { // Check if the Add new button is shown getByTestId("t--ide-tabs-add-button"); }); + it("Renders Google Sheets add routes in Full Screen", async () => { const page = PageFactory.build(); const anQuery = GoogleSheetFactory.build({ name: "Sheets3", id: "saas_api_id", + baseId: "saas_api_base_id", pageId: page.pageId, }); const state = getIDETestState({ actions: [anQuery], pages: [page], tabs: { - [EditorEntityTab.QUERIES]: ["saas_api_id"], + [EditorEntityTab.QUERIES]: [anQuery.baseId], [EditorEntityTab.JS]: [], }, }); @@ -611,7 +636,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/saas/google-sheets-plugin/api/saas_api_id/add`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/saas/google-sheets-plugin/api/${anQuery.baseId}/add`, initialState: state, featureFlags: FeatureFlags, sagasToRun: sagasToRunForTests, @@ -632,18 +657,20 @@ describe("IDE URL rendering of Queries", () => { newTab.querySelector("[data-testid='t--tab-close-btn']"), ).not.toBeNull(); }); + it("Renders Google Sheets add routes in Split Screen", async () => { const page = PageFactory.build(); const anQuery = PostgresFactory.build({ name: "Sheets4", id: "saas_api_id", + baseId: "saas_api_base_id", pageId: page.pageId, }); const state = getIDETestState({ actions: [anQuery], pages: [page], tabs: { - [EditorEntityTab.QUERIES]: ["saas_api_id"], + [EditorEntityTab.QUERIES]: [anQuery.baseId], [EditorEntityTab.JS]: [], }, ideView: EditorViewMode.SplitScreen, @@ -654,7 +681,7 @@ describe("IDE URL rendering of Queries", () => { , { - url: `/app/applicationSlug/pageSlug-${pageId}/edit/saas/google-sheets-plugin/api/saas_api_id/add`, + url: `/app/applicationSlug/pageSlug-${page.basePageId}/edit/saas/google-sheets-plugin/api/${anQuery.baseId}/add`, sagasToRun: sagasToRunForTests, initialState: state, featureFlags: FeatureFlags, diff --git a/app/client/src/pages/Editor/IDE/EditorPane/UI/Add.tsx b/app/client/src/pages/Editor/IDE/EditorPane/UI/Add.tsx index 239492601b..24cfe3e438 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/UI/Add.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/UI/Add.tsx @@ -4,10 +4,10 @@ import { useSelector } from "react-redux"; import styled from "styled-components"; import history from "utils/history"; -import { getCurrentPageId } from "@appsmith/selectors/entitiesSelector"; import UIEntitySidebar from "pages/Editor/widgetSidebar/UIEntitySidebar"; import { widgetListURL } from "@appsmith/RouteBuilder"; import { EDITOR_PANE_TEXTS, createMessage } from "@appsmith/constants/messages"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; const Container = styled(Flex)` padding-right: var(--ads-v2-spaces-2); @@ -15,11 +15,11 @@ const Container = styled(Flex)` `; const AddWidgets = (props: { focusSearchInput?: boolean }) => { - const pageId = useSelector(getCurrentPageId) as string; + const basePageId = useSelector(getCurrentBasePageId) as string; const closeButtonClickHandler = useCallback(() => { - history.push(widgetListURL({ pageId })); - }, [pageId]); + history.push(widgetListURL({ basePageId })); + }, [basePageId]); return ( <> diff --git a/app/client/src/pages/Editor/IDE/EditorPane/UI/List.tsx b/app/client/src/pages/Editor/IDE/EditorPane/UI/List.tsx index 30fad1c93f..07e0fd87b3 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/UI/List.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/UI/List.tsx @@ -3,11 +3,11 @@ import { Button, Flex } from "design-system"; import WidgetEntity from "pages/Editor/Explorer/Widgets/WidgetEntity"; import { useSelector } from "react-redux"; +import { selectWidgetsForCurrentPage } from "@appsmith/selectors/entitiesSelector"; import { - getCurrentPageId, - selectWidgetsForCurrentPage, -} from "@appsmith/selectors/entitiesSelector"; -import { getPagePermissions } from "selectors/editorSelectors"; + getCurrentBasePageId, + getPagePermissions, +} from "selectors/editorSelectors"; import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; import { getHasManagePagePermission } from "@appsmith/utils/BusinessFeatures/permissionPageHelpers"; @@ -29,7 +29,7 @@ const ListContainer = styled(Flex)` const ListWidgets = (props: { setFocusSearchInput: (focusSearchInput: boolean) => void; }) => { - const pageId = useSelector(getCurrentPageId) as string; + const basePageId = useSelector(getCurrentBasePageId) as string; const widgets = useSelector(selectWidgetsForCurrentPage); const pagePermissions = useSelector(getPagePermissions); const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); @@ -97,9 +97,9 @@ const ListWidgets = (props: { > {widgets?.children?.map((child) => ( { const dispatch = useDispatch(); const location = useLocation(); - const navigateToUrl = useGetPageFocusUrl(page.pageId); + const navigateToUrl = useGetPageFocusUrl(page.basePageId); const ref = useRef(null); const currentPageId = useSelector(getCurrentPageId); @@ -118,7 +120,7 @@ const PageElement = ({ searchKeyword={""} step={0} updateEntityName={(id, name) => - updatePage({ id, name, isHidden: !!page.isHidden }) + updatePageAction({ id, name, isHidden: !!page.isHidden }) } /> ); diff --git a/app/client/src/pages/Editor/IDE/EditorPane/components/SegmentedHeader.tsx b/app/client/src/pages/Editor/IDE/EditorPane/components/SegmentedHeader.tsx index d4784c4aef..d513cb264a 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/components/SegmentedHeader.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/components/SegmentedHeader.tsx @@ -5,11 +5,11 @@ import { EditorEntityTab } from "@appsmith/entities/IDE/constants"; import history from "utils/history"; import { globalAddURL } from "@appsmith/RouteBuilder"; import { useSelector } from "react-redux"; -import { getCurrentPageId } from "@appsmith/selectors/entitiesSelector"; import { useCurrentEditorState, useSegmentNavigation } from "../../hooks"; import styled from "styled-components"; import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; const Container = styled(Flex)` #editor-pane-segment-control { @@ -26,9 +26,9 @@ const SegmentedHeader = () => { const isGlobalAddPaneEnabled = useFeatureFlag( FEATURE_FLAG.release_global_add_pane_enabled, ); - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const onAddButtonClick = () => { - history.push(globalAddURL({ pageId })); + history.push(globalAddURL({ basePageId })); }; const { segment } = useCurrentEditorState(); const { onSegmentChange } = useSegmentNavigation(); diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/Editortabs.test.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/Editortabs.test.tsx index d6d6afe83e..2982a47489 100644 --- a/app/client/src/pages/Editor/IDE/EditorTabs/Editortabs.test.tsx +++ b/app/client/src/pages/Editor/IDE/EditorTabs/Editortabs.test.tsx @@ -36,7 +36,7 @@ describe("EditorTabs render checks", () => { it("Do not render component when segment is UI", () => { const state = getIDETestState({ ideView: EditorViewMode.FullScreen }); const { container } = renderComponent( - `/app/applicationSlug/pageSlug-${page.pageId}/edit`, + `/app/applicationSlug/pageSlug-${page.basePageId}/edit`, state, ); expect(container.firstChild).toBeNull(); @@ -45,7 +45,7 @@ describe("EditorTabs render checks", () => { it("Renders correctly in split view", () => { const state = getIDETestState({ ideView: EditorViewMode.SplitScreen }); const { getByTestId, queryByTestId } = renderComponent( - `/app/applicationSlug/pageSlug-${page.pageId}/edit/queries`, + `/app/applicationSlug/pageSlug-${page.basePageId}/edit/queries`, state, ); // check tabs is empty @@ -65,7 +65,7 @@ describe("EditorTabs render checks", () => { it("Renders correctly in fullscreen view", () => { const state = getIDETestState({ ideView: EditorViewMode.FullScreen }); const { getByTestId, queryByTestId } = renderComponent( - `/app/applicationSlug/pageSlug-${page.pageId}/edit/queries`, + `/app/applicationSlug/pageSlug-${page.basePageId}/edit/queries`, state, ); // check toggle @@ -86,18 +86,22 @@ describe("EditorTabs render checks", () => { }); it("Renders correctly with tabs in split view", () => { - const anApi = APIFactory.build({ id: "api_id", pageId: page.pageId }); + const anApi = APIFactory.build({ + id: "api_id", + baseId: "api_base_id", + pageId: page.pageId, + }); const state = getIDETestState({ pages: [page], actions: [anApi], ideView: EditorViewMode.SplitScreen, tabs: { - [EditorEntityTab.QUERIES]: ["api_id"], + [EditorEntityTab.QUERIES]: [anApi.baseId], [EditorEntityTab.JS]: [], }, }); const { getByTestId, queryByTestId } = renderComponent( - `/app/applicationSlug/pageSlug-${page.pageId}/edit/queries`, + `/app/applicationSlug/pageSlug-${page.basePageId}/edit/queries`, state, ); @@ -122,18 +126,22 @@ describe("EditorTabs render checks", () => { }); it("Renders correctly with tabs in fullscreen view", () => { - const anApi = APIFactory.build({ id: "api_id", pageId: page.pageId }); + const anApi = APIFactory.build({ + id: "api_id", + baseId: "api_base_id", + pageId: page.pageId, + }); const state = getIDETestState({ pages: [page], actions: [anApi], ideView: EditorViewMode.FullScreen, tabs: { - [EditorEntityTab.QUERIES]: ["api_id"], + [EditorEntityTab.QUERIES]: [anApi.baseId], [EditorEntityTab.JS]: [], }, }); const { getByTestId, queryByTestId } = renderComponent( - `/app/applicationSlug/pageSlug-${page.pageId}/edit/queries`, + `/app/applicationSlug/pageSlug-${page.basePageId}/edit/queries`, state, ); @@ -155,18 +163,22 @@ describe("EditorTabs render checks", () => { }); it("Render list view onclick of toggle in split view", () => { - const anApi = APIFactory.build({ id: "api_id", pageId: page.pageId }); + const anApi = APIFactory.build({ + id: "api_id", + baseId: "api_base_id", + pageId: page.pageId, + }); const state = getIDETestState({ pages: [page], actions: [anApi], ideView: EditorViewMode.SplitScreen, tabs: { - [EditorEntityTab.QUERIES]: ["api_id"], + [EditorEntityTab.QUERIES]: [anApi.baseId], [EditorEntityTab.JS]: [], }, }); const { getByTestId } = renderComponent( - `/app/applicationSlug/pageSlug-${page.pageId}/edit/queries/api_id`, + `/app/applicationSlug/pageSlug-${page.basePageId}/edit/queries/${anApi.baseId}`, state, ); @@ -177,18 +189,22 @@ describe("EditorTabs render checks", () => { }); it("Render Add tab in split view", () => { - const anApi = APIFactory.build({ id: "api_id", pageId: page.pageId }); + const anApi = APIFactory.build({ + id: "api_id", + baseId: "api_base_id", + pageId: page.pageId, + }); const state = getIDETestState({ pages: [page], actions: [anApi], ideView: EditorViewMode.SplitScreen, tabs: { - [EditorEntityTab.QUERIES]: ["api_id"], + [EditorEntityTab.QUERIES]: [anApi.baseId], [EditorEntityTab.JS]: [], }, }); const { getByTestId } = renderComponent( - `/app/applicationSlug/pageSlug-${page.pageId}/edit/queries/api_id/add`, + `/app/applicationSlug/pageSlug-${page.basePageId}/edit/queries/${anApi.baseId}/add`, state, ); // check list view @@ -196,18 +212,22 @@ describe("EditorTabs render checks", () => { }); it("Render Add tab in fullscreen view", () => { - const anApi = APIFactory.build({ id: "api_id", pageId: page.pageId }); + const anApi = APIFactory.build({ + id: "api_id", + baseId: "api_base_id", + pageId: page.pageId, + }); const state = getIDETestState({ pages: [page], actions: [anApi], ideView: EditorViewMode.FullScreen, tabs: { - [EditorEntityTab.QUERIES]: ["api_id"], + [EditorEntityTab.QUERIES]: [anApi.baseId], [EditorEntityTab.JS]: [], }, }); const { getByTestId } = renderComponent( - `/app/applicationSlug/pageSlug-${page.pageId}/edit/queries/api_id/add`, + `/app/applicationSlug/pageSlug-${page.basePageId}/edit/queries/${anApi.baseId}/add`, state, ); // check list view @@ -215,18 +235,22 @@ describe("EditorTabs render checks", () => { }); it("Render list view on top of add tab", () => { - const anApi = APIFactory.build({ id: "api_id", pageId: page.pageId }); + const anApi = APIFactory.build({ + id: "api_id", + baseId: "api_base_id", + pageId: page.pageId, + }); const state = getIDETestState({ pages: [page], actions: [anApi], ideView: EditorViewMode.SplitScreen, tabs: { - [EditorEntityTab.QUERIES]: ["api_id"], + [EditorEntityTab.QUERIES]: [anApi.baseId], [EditorEntityTab.JS]: [], }, }); const { getByTestId } = renderComponent( - `/app/applicationSlug/pageSlug-${page.pageId}/edit/queries/api_id/add`, + `/app/applicationSlug/pageSlug-${page.basePageId}/edit/queries/${anApi.baseId}/add`, state, ); @@ -238,18 +262,22 @@ describe("EditorTabs render checks", () => { }); it("Check CURL is rendering properly(not to render list view)", () => { - const anApi = APIFactory.build({ id: "api_id", pageId: page.pageId }); + const anApi = APIFactory.build({ + id: "api_id", + baseId: "api_base_id", + pageId: page.pageId, + }); const state = getIDETestState({ pages: [page], actions: [anApi], ideView: EditorViewMode.SplitScreen, tabs: { - [EditorEntityTab.QUERIES]: ["api_id"], + [EditorEntityTab.QUERIES]: [anApi.baseId], [EditorEntityTab.JS]: [], }, }); const { queryByTestId } = renderComponent( - `/app/applicationSlug/pageSlug-${page.pageId}/edit/saas/google-sheets-plugin/api/api_id`, + `/app/applicationSlug/pageSlug-${page.basePageId}/edit/saas/google-sheets-plugin/api/${anApi.baseId}`, state, ); diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/constants.ts b/app/client/src/pages/Editor/IDE/EditorTabs/constants.ts index 0ae461e016..266ad0fdcf 100644 --- a/app/client/src/pages/Editor/IDE/EditorTabs/constants.ts +++ b/app/client/src/pages/Editor/IDE/EditorTabs/constants.ts @@ -17,7 +17,7 @@ export const TabSelectors: Record< { tabsSelector: (state: AppState) => EntityItem[]; listSelector: (state: AppState) => EntityItem[]; - itemUrlSelector: (item: EntityItem, pageId: string) => string; + itemUrlSelector: (item: EntityItem, basePageId: string) => string; } > = { [EditorEntityTab.JS]: { diff --git a/app/client/src/pages/Editor/IDE/Header/index.tsx b/app/client/src/pages/Editor/IDE/Header/index.tsx index b2200c367a..35d22d6414 100644 --- a/app/client/src/pages/Editor/IDE/Header/index.tsx +++ b/app/client/src/pages/Editor/IDE/Header/index.tsx @@ -158,7 +158,9 @@ const Header = () => { FEATURE_FLAG.license_private_embeds_enabled, ); - const deployLink = useHref(viewerURL, { pageId }); + const deployLink = useHref(viewerURL, { + basePageId: currentPage?.basePageId, + }); const updateApplicationDispatch = ( id: string, diff --git a/app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx b/app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx index 3248fdbfd5..8c4e04c3ea 100644 --- a/app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx +++ b/app/client/src/pages/Editor/IDE/LeftPane/DataSidePane.tsx @@ -3,7 +3,6 @@ import styled from "styled-components"; import { Flex, List, Text } from "design-system"; import { useSelector } from "react-redux"; import { - getCurrentPageId, getDatasourceUsageCountForApp, getDatasources, getDatasourcesGroupedByPluginCategory, @@ -33,6 +32,7 @@ import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; import { getHasCreateDatasourcePermission } from "@appsmith/utils/BusinessFeatures/permissionPageHelpers"; import { EmptyState } from "../EditorPane/components/EmptyState"; import { getAssetUrl } from "@appsmith/utils/airgapHelpers"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; const PaneContainer = styled.div` width: 300px; @@ -61,7 +61,7 @@ interface DataSidePaneProps { const DataSidePane = (props: DataSidePaneProps) => { const { dsUsageSelector = getDatasourceUsageCountForApp } = props; const editorType = useEditorType(history.location.pathname); - const pageId = useSelector(getCurrentPageId) as string; + const basePageId = useSelector(getCurrentBasePageId) as string; const [currentSelectedDatasource, setCurrentSelectedDatasource] = useState< string | undefined >(""); @@ -93,7 +93,7 @@ const DataSidePane = (props: DataSidePaneProps) => { const addButtonClickHandler = () => history.push( integrationEditorURL({ - pageId: pageId, + basePageId, selectedTab: INTEGRATION_TABS.NEW, }), ); diff --git a/app/client/src/pages/Editor/IDE/Sidebar.tsx b/app/client/src/pages/Editor/IDE/Sidebar.tsx index 32c92e0a63..9036abd59b 100644 --- a/app/client/src/pages/Editor/IDE/Sidebar.tsx +++ b/app/client/src/pages/Editor/IDE/Sidebar.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; import { builderURL } from "@appsmith/RouteBuilder"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import history, { NavigationMethod } from "utils/history"; import { useCurrentAppState } from "./hooks"; import { getCurrentWorkspaceId } from "@appsmith/selectors/selectedWorkspaceSelectors"; @@ -21,7 +21,7 @@ import { function Sidebar() { const dispatch = useDispatch(); const appState = useCurrentAppState(); - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const currentWorkspaceId = useSelector(getCurrentWorkspaceId); const datasources = useSelector(getDatasources); const datasourcesExist = datasources.length > 0; @@ -50,7 +50,7 @@ function Sidebar() { (suffix) => { history.push( builderURL({ - pageId, + basePageId, suffix, }), { @@ -58,7 +58,7 @@ function Sidebar() { }, ); }, - [pageId], + [basePageId], ); return ( diff --git a/app/client/src/pages/Editor/IDE/hooks.ts b/app/client/src/pages/Editor/IDE/hooks.ts index c7cbb2549e..147efe3fc2 100644 --- a/app/client/src/pages/Editor/IDE/hooks.ts +++ b/app/client/src/pages/Editor/IDE/hooks.ts @@ -11,7 +11,6 @@ import { FocusEntity, identifyEntityFromPath } from "navigation/FocusEntity"; import { useDispatch, useSelector } from "react-redux"; import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors"; import { getPropertyPaneWidth } from "selectors/propertyPaneSelectors"; -import { getCurrentPageId } from "@appsmith/selectors/entitiesSelector"; import history, { NavigationMethod } from "utils/history"; import { builderURL, @@ -34,6 +33,7 @@ import { createEditorFocusInfoKey } from "@appsmith/navigation/FocusStrategy/App import { FocusElement } from "navigation/FocusElements"; import { closeJSActionTab } from "actions/jsActionActions"; import { closeQueryActionTab } from "actions/pluginActionActions"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import { getCurrentEntityInfo } from "../utils"; export const useCurrentAppState = () => { @@ -98,7 +98,7 @@ export const useEditorPaneWidth = (): string => { export const useSegmentNavigation = (): { onSegmentChange: (value: string) => void; } => { - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); /** * Callback to handle the segment change @@ -110,17 +110,17 @@ export const useSegmentNavigation = (): { const onSegmentChange = (value: string) => { switch (value) { case EditorEntityTab.QUERIES: - history.push(queryListURL({ pageId }), { + history.push(queryListURL({ basePageId }), { invokedBy: NavigationMethod.SegmentControl, }); break; case EditorEntityTab.JS: - history.push(jsCollectionListURL({ pageId }), { + history.push(jsCollectionListURL({ basePageId }), { invokedBy: NavigationMethod.SegmentControl, }); break; case EditorEntityTab.UI: - history.push(widgetListURL({ pageId }), { + history.push(widgetListURL({ basePageId }), { invokedBy: NavigationMethod.SegmentControl, }); break; @@ -130,14 +130,12 @@ export const useSegmentNavigation = (): { return { onSegmentChange }; }; -export const useGetPageFocusUrl = (pageId: string): string => { - const [focusPageUrl, setFocusPageUrl] = useState( - builderURL({ pageId: pageId }), - ); +export const useGetPageFocusUrl = (basePageId: string): string => { + const [focusPageUrl, setFocusPageUrl] = useState(builderURL({ basePageId })); const branch = useSelector(getCurrentGitBranch); const editorStateFocusInfo = useSelector((appState) => - getCurrentFocusInfo(appState, createEditorFocusInfoKey(pageId, branch)), + getCurrentFocusInfo(appState, createEditorFocusInfoKey(basePageId, branch)), ); useEffect(() => { @@ -145,7 +143,7 @@ export const useGetPageFocusUrl = (pageId: string): string => { const lastSelectedEntity = editorStateFocusInfo.state[FocusElement.SelectedEntity]; - setFocusPageUrl(builderURL({ pageId, suffix: lastSelectedEntity })); + setFocusPageUrl(builderURL({ basePageId, suffix: lastSelectedEntity })); } }, [editorStateFocusInfo, branch]); @@ -196,7 +194,7 @@ export const useIDETabClickHandlers = () => { const { closeAddQuery, openAddQuery } = useQueryAdd(); const { segment, segmentMode } = useCurrentEditorState(); const tabsConfig = TabSelectors[segment]; - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const addClickHandler = useCallback(() => { if (segment === EditorEntityTab.JS) openAddJS(); @@ -205,12 +203,12 @@ export const useIDETabClickHandlers = () => { const tabClickHandler = useCallback( (item: EntityItem) => { - const navigateToUrl = tabsConfig.itemUrlSelector(item, pageId); + const navigateToUrl = tabsConfig.itemUrlSelector(item, basePageId); history.push(navigateToUrl, { invokedBy: NavigationMethod.EditorTabs, }); }, - [segment, pageId], + [segment, basePageId], ); const closeClickHandler = useCallback( @@ -220,11 +218,11 @@ export const useIDETabClickHandlers = () => { return segment === EditorEntityTab.JS ? closeAddJS() : closeAddQuery(); } if (segment === EditorEntityTab.JS) - dispatch(closeJSActionTab({ id: actionId, parentId: pageId })); + dispatch(closeJSActionTab({ id: actionId, parentId: basePageId })); if (segment === EditorEntityTab.QUERIES) - dispatch(closeQueryActionTab({ id: actionId, parentId: pageId })); + dispatch(closeQueryActionTab({ id: actionId, parentId: basePageId })); }, - [segment, pageId, dispatch], + [segment, basePageId, dispatch], ); return { addClickHandler, tabClickHandler, closeClickHandler }; diff --git a/app/client/src/pages/Editor/IntegrationEditor/ActiveDataSources.tsx b/app/client/src/pages/Editor/IntegrationEditor/ActiveDataSources.tsx index 8d21137f34..f9776c9478 100644 --- a/app/client/src/pages/Editor/IntegrationEditor/ActiveDataSources.tsx +++ b/app/client/src/pages/Editor/IntegrationEditor/ActiveDataSources.tsx @@ -42,7 +42,7 @@ const EmptyActiveDatasource = styled.div` interface ActiveDataSourcesProps { dataSources: Datasource[]; - pageId: string; + basePageId: string; location: { search: string; }; diff --git a/app/client/src/pages/Editor/IntegrationEditor/CreateNewDatasourceTab.tsx b/app/client/src/pages/Editor/IntegrationEditor/CreateNewDatasourceTab.tsx index 76a8755b6a..2da16a55ed 100644 --- a/app/client/src/pages/Editor/IntegrationEditor/CreateNewDatasourceTab.tsx +++ b/app/client/src/pages/Editor/IntegrationEditor/CreateNewDatasourceTab.tsx @@ -353,6 +353,7 @@ const mapStateToProps = (state: AppState) => { const pageId = !!onboardingAppId ? onboardingApplication?.defaultPageId || "" : getCurrentPageId(state); + const showDebugger = showDebuggerFlag(state); const userWorkspacePermissions = getCurrentAppWorkspace(state).userPermissions ?? []; diff --git a/app/client/src/pages/Editor/IntegrationEditor/DatasourceCard.tsx b/app/client/src/pages/Editor/IntegrationEditor/DatasourceCard.tsx index 49a6d6ce3b..df3d90bd05 100644 --- a/app/client/src/pages/Editor/IntegrationEditor/DatasourceCard.tsx +++ b/app/client/src/pages/Editor/IntegrationEditor/DatasourceCard.tsx @@ -34,7 +34,7 @@ import { } from "@appsmith/constants/messages"; import { isDatasourceAuthorizedForQueryCreation } from "utils/editorContextUtils"; import { - getCurrentPageId, + getCurrentBasePageId, getPagePermissions, } from "selectors/editorSelectors"; import { getAssetUrl } from "@appsmith/utils/airgapHelpers"; @@ -152,7 +152,7 @@ function DatasourceCard(props: DatasourceCardProps) { const { datasource, plugin } = props; const envSupportedDs = !DB_NOT_SUPPORTED.includes(plugin.type); - const pageId = useSelector(getCurrentPageId); + const basePageId = useSelector(getCurrentBasePageId); const datasourceFormConfigs = useSelector( (state: AppState) => state.entities.plugins.formConfigs, @@ -226,7 +226,7 @@ function DatasourceCard(props: DatasourceCardProps) { if (plugin && plugin.type === PluginType.SAAS) { history.push( saasEditorDatasourceIdURL({ - pageId, + basePageId, pluginPackageName: plugin.packageName, datasourceId: datasource.id, params: { @@ -238,7 +238,7 @@ function DatasourceCard(props: DatasourceCardProps) { } else { history.push( datasourcesEditorIdURL({ - pageId, + basePageId, datasourceId: datasource.id, params: { from: "datasources", @@ -263,7 +263,7 @@ function DatasourceCard(props: DatasourceCardProps) { AnalyticsUtil.logEvent("DATASOURCE_CARD_GEN_CRUD_PAGE_ACTION"); history.push( generateTemplateFormURL({ - pageId, + basePageId, params: { datasourceId: datasource.id, new_page: true, diff --git a/app/client/src/pages/Editor/IntegrationEditor/IntegrationsHomeScreen.tsx b/app/client/src/pages/Editor/IntegrationEditor/IntegrationsHomeScreen.tsx index 7a21ca10da..495cc8434e 100644 --- a/app/client/src/pages/Editor/IntegrationEditor/IntegrationsHomeScreen.tsx +++ b/app/client/src/pages/Editor/IntegrationEditor/IntegrationsHomeScreen.tsx @@ -86,7 +86,7 @@ const SectionGrid = styled.div<{ isActiveTab?: boolean }>` `; interface IntegrationsHomeScreenProps { - pageId: string; + basePageId: string; selectedTab: string; location: { search: string; @@ -170,7 +170,7 @@ class IntegrationsHomeScreen extends React.Component< }; componentDidMount() { - const { dataSources, history, pageId } = this.props; + const { basePageId, dataSources, history } = this.props; const queryParams = getQueryParams(); const redirectMode = queryParams.mode; @@ -181,7 +181,7 @@ class IntegrationsHomeScreen extends React.Component< delete queryParams.from; history.replace( integrationEditorURL({ - pageId, + basePageId, selectedTab: INTEGRATION_TABS.NEW, params: queryParams, }), @@ -194,7 +194,7 @@ class IntegrationsHomeScreen extends React.Component< // User will be taken to active tab if there are datasources history.replace( integrationEditorURL({ - pageId, + basePageId, selectedTab: INTEGRATION_TABS.ACTIVE, }), ); @@ -202,7 +202,7 @@ class IntegrationsHomeScreen extends React.Component< // If there are no datasources -> new user history.replace( integrationEditorURL({ - pageId, + basePageId, selectedTab: INTEGRATION_TABS.NEW, }), ); @@ -216,11 +216,11 @@ class IntegrationsHomeScreen extends React.Component< componentDidUpdate(prevProps: Props) { this.syncActivePrimaryMenu(); - const { dataSources, history, pageId } = this.props; + const { basePageId, dataSources, history } = this.props; if (dataSources.length === 0 && prevProps.dataSources.length > 0) { history.replace( integrationEditorURL({ - pageId, + basePageId, selectedTab: INTEGRATION_TABS.NEW, }), ); @@ -231,13 +231,13 @@ class IntegrationsHomeScreen extends React.Component< } onSelectPrimaryMenu = (activePrimaryMenuId: string) => { - const { dataSources, history, pageId } = this.props; + const { basePageId, dataSources, history } = this.props; if (activePrimaryMenuId === this.state.activePrimaryMenuId) { return; } history.push( integrationEditorURL({ - pageId, + basePageId, selectedTab: activePrimaryMenuId === PRIMARY_MENU_IDS.ACTIVE ? INTEGRATION_TABS.ACTIVE @@ -258,10 +258,10 @@ class IntegrationsHomeScreen extends React.Component< render() { const { + basePageId, canCreateDatasource = false, dataSources, location, - pageId, showDebugger, } = this.props; const { unsupportedPluginDialogVisible } = this.state; @@ -296,6 +296,7 @@ class IntegrationsHomeScreen extends React.Component< } else { currentScreen = ( ); } diff --git a/app/client/src/pages/Editor/IntegrationEditor/index.tsx b/app/client/src/pages/Editor/IntegrationEditor/index.tsx index 208668f7e9..346fa0e361 100644 --- a/app/client/src/pages/Editor/IntegrationEditor/index.tsx +++ b/app/client/src/pages/Editor/IntegrationEditor/index.tsx @@ -4,7 +4,7 @@ import type { RouteComponentProps } from "react-router"; import * as Sentry from "@sentry/react"; type Props = RouteComponentProps<{ - pageId: string; + basePageId: string; selectedTab: string; }>; @@ -21,9 +21,9 @@ const integrationsEditor = (props: Props) => { }} > diff --git a/app/client/src/pages/Editor/JSEditor/JSObjectNameEditor.tsx b/app/client/src/pages/Editor/JSEditor/JSObjectNameEditor.tsx index 71f0e0c9b0..0f4bb9e16d 100644 --- a/app/client/src/pages/Editor/JSEditor/JSObjectNameEditor.tsx +++ b/app/client/src/pages/Editor/JSEditor/JSObjectNameEditor.tsx @@ -5,7 +5,7 @@ import { useParams } from "react-router-dom"; import { removeSpecialChars } from "utils/helpers"; import type { AppState } from "@appsmith/reducers"; import { - getJSCollection, + getJsCollectionByBaseId, getPlugin, } from "@appsmith/selectors/entitiesSelector"; import { @@ -45,10 +45,13 @@ export interface JSObjectNameEditorProps { } export function JSObjectNameEditor(props: JSObjectNameEditorProps) { - const params = useParams<{ collectionId?: string; queryId?: string }>(); + const params = useParams<{ + baseCollectionId?: string; + baseQueryId?: string; + }>(); const currentJSObjectConfig = useSelector((state: AppState) => - getJSCollection(state, params.collectionId || ""), + getJsCollectionByBaseId(state, params.baseCollectionId || ""), ); const currentPlugin = useSelector((state: AppState) => diff --git a/app/client/src/pages/Editor/JSEditor/index.tsx b/app/client/src/pages/Editor/JSEditor/index.tsx index 0226184e14..76cf2b2ae6 100644 --- a/app/client/src/pages/Editor/JSEditor/index.tsx +++ b/app/client/src/pages/Editor/JSEditor/index.tsx @@ -3,7 +3,10 @@ import type { RouteComponentProps } from "react-router"; import { useDispatch, useSelector } from "react-redux"; import JsEditorForm from "./Form"; import * as Sentry from "@sentry/react"; -import { getJSCollectionDataById } from "selectors/editorSelectors"; +import { + getCurrentPageId, + getJSCollectionDataByBaseId, +} from "selectors/editorSelectors"; import CenteredWrapper from "components/designSystems/appsmith/CenteredWrapper"; import Spinner from "components/editorComponents/Spinner"; import styled from "styled-components"; @@ -19,15 +22,16 @@ const LoadingContainer = styled(CenteredWrapper)` type Props = RouteComponentProps<{ apiId: string; - pageId: string; - collectionId: string; + basePageId: string; + baseCollectionId: string; }>; function JSEditor(props: Props) { - const { collectionId, pageId } = props.match.params; + const { baseCollectionId } = props.match.params; + const pageId = useSelector(getCurrentPageId); const dispatch = useDispatch(); const jsCollectionData = useSelector((state) => - getJSCollectionDataById(state, collectionId), + getJSCollectionDataByBaseId(state, baseCollectionId), ); const { isCreating } = useSelector((state) => state.ui.jsPane); const jsCollection = jsCollectionData?.config; diff --git a/app/client/src/pages/Editor/JSEditor/utils.test.ts b/app/client/src/pages/Editor/JSEditor/utils.test.ts index 2abe4956da..77729d7815 100644 --- a/app/client/src/pages/Editor/JSEditor/utils.test.ts +++ b/app/client/src/pages/Editor/JSEditor/utils.test.ts @@ -41,6 +41,7 @@ const BASE_JS_OBJECT_BODY_WITH_LITERALS = `export default { const BASE_JS_ACTION = (useLiterals = false) => { return { workspaceId: "workspace-id", + applicationId: "application-id", pageId: "page-id", collectionId: "collection-id", pluginId: "plugin-id", @@ -68,6 +69,7 @@ const createJSAction = (name: string, useLiterals = false): JSAction => { return { ...BASE_JS_ACTION(useLiterals), id: uniqueId(name), + baseId: uniqueId(name), name, }; }; diff --git a/app/client/src/pages/Editor/PropertyPane/ConnectDataCTA.tsx b/app/client/src/pages/Editor/PropertyPane/ConnectDataCTA.tsx index b84b07a55d..6324cbf035 100644 --- a/app/client/src/pages/Editor/PropertyPane/ConnectDataCTA.tsx +++ b/app/client/src/pages/Editor/PropertyPane/ConnectDataCTA.tsx @@ -8,7 +8,7 @@ import history from "utils/history"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import type { WidgetType } from "constants/WidgetConstants"; import { integrationEditorURL } from "@appsmith/RouteBuilder"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import { DocsLink, openDoc } from "../../../constants/DocumentationLinks"; import { DatasourceCreateEntryPoints } from "constants/Datasource"; @@ -33,13 +33,13 @@ interface ConnectDataCTAProps { } function ConnectDataCTA(props: ConnectDataCTAProps) { - const pageId: string = useSelector(getCurrentPageId); + const basePageId: string = useSelector(getCurrentBasePageId); const onClick = () => { const { widgetId, widgetTitle, widgetType } = props; history.push( integrationEditorURL({ - pageId, + basePageId, selectedTab: INTEGRATION_TABS.NEW, params: { mode: INTEGRATION_EDITOR_MODES.AUTO }, }), diff --git a/app/client/src/pages/Editor/QueryEditor/BindDataButton.tsx b/app/client/src/pages/Editor/QueryEditor/BindDataButton.tsx index 859faae586..6dfcd9b255 100644 --- a/app/client/src/pages/Editor/QueryEditor/BindDataButton.tsx +++ b/app/client/src/pages/Editor/QueryEditor/BindDataButton.tsx @@ -249,9 +249,9 @@ function BindDataButton(props: BindDataButtonProps) { const pagePermissions = useSelector(getPagePermissions); const params = useParams<{ - pageId: string; - apiId?: string; - queryId?: string; + basePageId: string; + baseApiId?: string; + baseQueryId?: string; moduleInstanceId?: string; }>(); @@ -339,11 +339,11 @@ function BindDataButton(props: BindDataButtonProps) { } dispatch( bindDataOnCanvas({ - queryId: (params.apiId || - params.queryId || + queryId: (params.baseApiId || + params.baseQueryId || params.moduleInstanceId) as string, applicationId: applicationId as string, - pageId: params.pageId, + basePageId: params.basePageId, }), ); diff --git a/app/client/src/pages/Editor/QueryEditor/Editor.tsx b/app/client/src/pages/Editor/QueryEditor/Editor.tsx index 05b4717b8a..98719cffdf 100644 --- a/app/client/src/pages/Editor/QueryEditor/Editor.tsx +++ b/app/client/src/pages/Editor/QueryEditor/Editor.tsx @@ -21,7 +21,7 @@ import type { Datasource } from "entities/Datasource"; import { getPluginIdsOfPackageNames, getPlugins, - getAction, + getActionByBaseId, getActionResponses, getDatasourceByPluginId, getDBAndRemoteDatasources, @@ -90,6 +90,7 @@ interface ReduxStateProps { uiComponent: UIComponentTypes; applicationId: string; actionId: string; + baseActionId: string; actionObjectDiff?: any; isSaas: boolean; datasourceId?: string; @@ -112,11 +113,11 @@ class QueryEditor extends React.Component { super(props); // Call the first evaluations when the page loads // call evaluations only for queries and not google sheets (which uses apiId) - if (this.props.match.params.queryId) { + if (this.props.match.params.baseQueryId) { this.props.initFormEvaluation( this.props.editorConfig, this.props.settingsConfig, - this.props.match.params.queryId, + this.props.match.params.baseQueryId, ); } } @@ -125,7 +126,7 @@ class QueryEditor extends React.Component { // if the current action is non existent, do not dispatch change query page action // this action should only be dispatched when switching from an existent action. if (!this.props.pluginId) return; - this.context?.changeQueryPage?.(this.props.actionId); + this.context?.changeQueryPage?.(this.props.baseActionId); // fixes missing where key issue by populating the action with a where object when the component is mounted. if (this.props.isSaas) { @@ -182,10 +183,10 @@ class QueryEditor extends React.Component { // URL or selecting new query from the query pane // reusing same logic for changing query panes for switching query editor datasources, since the operations are similar. if ( - prevProps.actionId !== this.props.actionId || + prevProps.baseActionId !== this.props.baseActionId || prevProps.pluginId !== this.props.pluginId ) { - this.context?.changeQueryPage?.(this.props.actionId); + this.context?.changeQueryPage?.(this.props.baseActionId); } } @@ -250,14 +251,18 @@ class QueryEditor extends React.Component { } const mapStateToProps = (state: AppState, props: OwnProps): ReduxStateProps => { - const { apiId, queryId } = props.match.params; - const actionId = queryId || apiId || ""; + const { baseApiId, baseQueryId } = props.match.params; + const baseActionId = baseQueryId || baseApiId || ""; const { runErrorMessage } = state.ui.queryPane; const { plugins } = state.entities; const { editorConfigs } = plugins; - const action = getAction(state, actionId) as QueryAction | SaaSAction; + const action = getActionByBaseId(state, baseActionId) as + | QueryAction + | SaaSAction; + const actionId = action?.id; + const formData = getFormValues(QUERY_EDITOR_FORM_NAME)(state) as | QueryAction | SaaSAction; @@ -299,19 +304,20 @@ const mapStateToProps = (state: AppState, props: OwnProps): ReduxStateProps => { return { actionId, + baseActionId, currentEnvironmentId: currentEnvDetails?.id || "", currentEnvironmentName: currentEnvDetails?.name || "", pluginId, plugins: allPlugins, runErrorMessage, pluginIds: getPluginIdsOfPackageNames(state, PLUGIN_PACKAGE_DBS), - dataSources: !!apiId + dataSources: !!baseApiId ? getDatasourceByPluginId(state, action?.pluginId) : getDBAndRemoteDatasources(state), responses: getActionResponses(state), isRunning: state.ui.queryPane.isRunning[actionId], isDeleting: state.ui.queryPane.isDeleting[actionId], - isSaas: !!apiId, + isSaas: !!baseApiId, formData, editorConfig, isCreating: state.ui.apiPane.isCreating, diff --git a/app/client/src/pages/Editor/QueryEditor/EditorJSONtoForm.tsx b/app/client/src/pages/Editor/QueryEditor/EditorJSONtoForm.tsx index 222e5721ea..fa1a13455d 100644 --- a/app/client/src/pages/Editor/QueryEditor/EditorJSONtoForm.tsx +++ b/app/client/src/pages/Editor/QueryEditor/EditorJSONtoForm.tsx @@ -204,13 +204,15 @@ export function EditorJSONtoForm(props: Props) { notification, } = useContext(QueryEditorContext); - const params = useParams<{ apiId?: string; queryId?: string }>(); + const params = useParams<{ baseApiId?: string; baseQueryId?: string }>(); // fetch the error count from the store. const actions: Action[] = useSelector((state: AppState) => state.entities.actions.map((action) => action.config), ); const currentActionConfig: Action | undefined = actions.find( - (action) => action.id === params.apiId || action.id === params.queryId, + (action) => + action.baseId === params.baseApiId || + action.baseId === params.baseQueryId, ); const pluginRequireDatasource = doesPluginRequireDatasource(plugin); diff --git a/app/client/src/pages/Editor/QueryEditor/QueryEditorContext.tsx b/app/client/src/pages/Editor/QueryEditor/QueryEditorContext.tsx index 11e8206218..b49f128244 100644 --- a/app/client/src/pages/Editor/QueryEditor/QueryEditorContext.tsx +++ b/app/client/src/pages/Editor/QueryEditor/QueryEditorContext.tsx @@ -10,7 +10,7 @@ interface QueryEditorContextContextProps { moreActionsMenu?: React.ReactNode; onCreateDatasourceClick?: () => void; onEntityNotFoundBackClick?: () => void; - changeQueryPage?: (queryId: string) => void; + changeQueryPage?: (baseQueryId: string) => void; actionRightPaneBackLink?: React.ReactNode; saveActionName?: ( params: SaveActionNameParams, diff --git a/app/client/src/pages/Editor/QueryEditor/QueryEditorHeader.tsx b/app/client/src/pages/Editor/QueryEditor/QueryEditorHeader.tsx index 46444dc386..4499f36550 100644 --- a/app/client/src/pages/Editor/QueryEditor/QueryEditorHeader.tsx +++ b/app/client/src/pages/Editor/QueryEditor/QueryEditorHeader.tsx @@ -9,10 +9,10 @@ import { getHasExecuteActionPermission, getHasManageActionPermission, } from "@appsmith/utils/BusinessFeatures/permissionPageHelpers"; -import { useActiveAction } from "@appsmith/pages/Editor/Explorer/hooks"; +import { useActiveActionBaseId } from "@appsmith/pages/Editor/Explorer/hooks"; import { useSelector } from "react-redux"; import { - getAction, + getActionByBaseId, getPluginNameFromId, } from "@appsmith/selectors/entitiesSelector"; import { QueryEditorContext } from "./QueryEditorContext"; @@ -62,9 +62,11 @@ const QueryEditorHeader = (props: Props) => { } = props; const { moreActionsMenu, saveActionName } = useContext(QueryEditorContext); - const activeActionId = useActiveAction(); + const activeActionBaseId = useActiveActionBaseId(); const currentActionConfig = useSelector((state) => - activeActionId ? getAction(state, activeActionId) : undefined, + activeActionBaseId + ? getActionByBaseId(state, activeActionBaseId) + : undefined, ); const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); const isChangePermitted = getHasManageActionPermission( diff --git a/app/client/src/pages/Editor/QueryEditor/index.tsx b/app/client/src/pages/Editor/QueryEditor/index.tsx index f1b06e6a13..0279d9cd87 100644 --- a/app/client/src/pages/Editor/QueryEditor/index.tsx +++ b/app/client/src/pages/Editor/QueryEditor/index.tsx @@ -10,14 +10,13 @@ import BackToCanvas from "components/common/BackToCanvas"; import { INTEGRATION_TABS } from "constants/routes"; import { getCurrentApplicationId, - getCurrentPageId, getIsEditorInitialized, getPagePermissions, } from "selectors/editorSelectors"; import { changeQuery } from "actions/queryPaneActions"; import { DatasourceCreateEntryPoints } from "constants/Datasource"; import { - getAction, + getActionByBaseId, getIsActionConverting, getPluginImages, getPluginSettingConfigs, @@ -46,21 +45,22 @@ import { EditorViewMode } from "@appsmith/entities/IDE/constants"; type QueryEditorProps = RouteComponentProps; function QueryEditor(props: QueryEditorProps) { - const { apiId, queryId } = props.match.params; - const actionId = queryId || apiId; + const { baseApiId, basePageId, baseQueryId } = props.match.params; + const baseActionId = baseQueryId || baseApiId; const dispatch = useDispatch(); - const action = useSelector((state) => getAction(state, actionId || "")); + const action = useSelector((state) => + getActionByBaseId(state, baseActionId || ""), + ); const pluginId = action?.pluginId || ""; const isEditorInitialized = useSelector(getIsEditorInitialized); const applicationId: string = useSelector(getCurrentApplicationId); - const pageId: string = useSelector(getCurrentPageId); const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); const settingsConfig = useSelector((state) => getPluginSettingConfigs(state, pluginId), ); const pagePermissions = useSelector(getPagePermissions); const isConverting = useSelector((state) => - getIsActionConverting(state, actionId || ""), + getIsActionConverting(state, action?.id || ""), ); const pluginImages = useSelector(getPluginImages); const editorMode = useSelector(getIDEViewMode); @@ -102,12 +102,12 @@ function QueryEditor(props: QueryEditorProps) { return ( <> @@ -126,26 +126,28 @@ function QueryEditor(props: QueryEditorProps) { action?.name, isChangePermitted, isDeletePermitted, - pageId, + basePageId, isCreatePermitted, editorMode, ]); const actionRightPaneBackLink = useMemo(() => { - return ; - }, [pageId]); + return ; + }, [basePageId]); const changeQueryPage = useCallback( - (queryId: string) => { - dispatch(changeQuery({ id: queryId, pageId, applicationId })); + (baseQueryId: string) => { + dispatch( + changeQuery({ baseQueryId: baseQueryId, basePageId, applicationId }), + ); }, - [pageId, applicationId], + [basePageId, applicationId], ); const onCreateDatasourceClick = useCallback(() => { history.push( integrationEditorURL({ - pageId, + basePageId: basePageId, selectedTab: INTEGRATION_TABS.NEW, }), ); @@ -155,7 +157,7 @@ function QueryEditor(props: QueryEditorProps) { entryPoint, }); }, [ - pageId, + basePageId, history, integrationEditorURL, DatasourceCreateEntryPoints, @@ -167,11 +169,11 @@ function QueryEditor(props: QueryEditorProps) { () => history.push( integrationEditorURL({ - pageId, + basePageId: basePageId, selectedTab: INTEGRATION_TABS.ACTIVE, }), ), - [pageId, history, integrationEditorURL], + [basePageId, history, integrationEditorURL], ); const notification = useMemo(() => { diff --git a/app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx b/app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx index 89d0996bbc..0ac1689234 100644 --- a/app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx +++ b/app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx @@ -94,6 +94,7 @@ import { import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; import DatasourceTabs from "../DatasourceInfo/DatasorceTabs"; import { getCurrentApplicationIdForCreateNewApp } from "@appsmith/selectors/applicationSelectors"; +import { convertToPageIdSelector } from "selectors/pageListSelectors"; const ViewModeContainer = styled.div` display: flex; @@ -174,17 +175,20 @@ interface State { navigation(): void; } -type SaasEditorWrappperProps = RouteProps & { +interface SaasEditorWrappperProps { hiddenHeader?: boolean; // for reconnect modal isInsideReconnectModal?: boolean; // for reconnect modal currentEnvironment: string; isOnboardingFlow?: boolean; -}; -interface RouteProps { datasourceId: string; pageId: string; pluginPackageName: string; } +interface RouteProps { + datasourceId: string; + basePageId: string; + pluginPackageName: string; +} interface SaasEditorWrappperState { requiredFields: Record; @@ -722,6 +726,17 @@ class DatasourceSaaSEditor extends JSONtoForm { } const mapStateToProps = (state: AppState, props: any) => { + // This is only present during onboarding flow + const currentApplicationIdForCreateNewApp = + getCurrentApplicationIdForCreateNewApp(state); + const applicationId = !!currentApplicationIdForCreateNewApp + ? currentApplicationIdForCreateNewApp + : getCurrentApplicationId(state); + + const basePageId = props.match?.params?.basePageId; + const pageIdFromUrl = convertToPageIdSelector(state, basePageId); + const pageId = props.pageId || pageIdFromUrl; + const datasourceId = props.datasourceId || props.match?.params?.datasourceId; const { datasourcePane } = state.ui; const { datasources, plugins } = state.entities; @@ -809,10 +824,6 @@ const mapStateToProps = (state: AppState, props: any) => { ) : false; - // This is only present during onboarding flow - const currentApplicationIdForCreateNewApp = - getCurrentApplicationIdForCreateNewApp(state); - // should plugin be able to preview data const isPluginAllowedToPreviewData = !!plugin && isEnabledForPreviewData(datasource as Datasource, plugin); @@ -829,7 +840,7 @@ const mapStateToProps = (state: AppState, props: any) => { formConfig, viewMode: viewMode ?? !props.isInsideReconnectModal, isNewDatasource: datasourcePane.newDatasource === TEMP_DATASOURCE_ID, - pageId: props.pageId || props.match?.params?.pageId, + pageId, plugin: plugin, pluginImage: getPluginImages(state)[pluginId], pluginPackageName: @@ -839,9 +850,7 @@ const mapStateToProps = (state: AppState, props: any) => { pluginId: pluginId, actions: state.entities.actions, formName: DATASOURCE_SAAS_FORM, - applicationId: !!currentApplicationIdForCreateNewApp - ? currentApplicationIdForCreateNewApp - : getCurrentApplicationId(state), + applicationId, canManageDatasource, canDeleteDatasource, datasourceName: datasource?.name ?? "", diff --git a/app/client/src/pages/Editor/SaaSEditor/ListView.tsx b/app/client/src/pages/Editor/SaaSEditor/ListView.tsx index 65adcc2744..db3bad429e 100644 --- a/app/client/src/pages/Editor/SaaSEditor/ListView.tsx +++ b/app/client/src/pages/Editor/SaaSEditor/ListView.tsx @@ -75,7 +75,7 @@ interface DispatchFunctions { } type RouteProps = RouteComponentProps<{ - pageId: string; + basePageId: string; pluginPackageName: string; }>; @@ -89,13 +89,13 @@ class ListView extends React.Component { const { location, match: { - params: { pageId }, + params: { basePageId }, }, } = this.props; const params: string = location.search; let pgId = new URLSearchParams(params).get("importTo"); if (!pgId) { - pgId = pageId; + pgId = basePageId; } if (pgId) { this.props.createAction({ @@ -163,7 +163,7 @@ class ListView extends React.Component { const { history, match: { - params: { pageId }, + params: { basePageId }, }, } = this.props; return ( @@ -173,7 +173,7 @@ class ListView extends React.Component { onBackButton={() => history.push( integrationEditorURL({ - pageId, + basePageId, selectedTab: INTEGRATION_TABS.ACTIVE, }), ) diff --git a/app/client/src/pages/Editor/SaaSEditor/constants.ts b/app/client/src/pages/Editor/SaaSEditor/constants.ts index 8774e16508..4af70655cb 100644 --- a/app/client/src/pages/Editor/SaaSEditor/constants.ts +++ b/app/client/src/pages/Editor/SaaSEditor/constants.ts @@ -1,7 +1,7 @@ export const SAAS_BASE_PATH = `/saas`; export const SAAS_EDITOR_PATH = `${SAAS_BASE_PATH}/:pluginPackageName`; export const SAAS_EDITOR_DATASOURCE_ID_PATH = `${SAAS_EDITOR_PATH}/datasources/:datasourceId`; -export const SAAS_EDITOR_API_ID_PATH = `${SAAS_EDITOR_PATH}/api/:apiId`; -export const SAAS_EDITOR_API_ID_ADD_PATH = `${SAAS_EDITOR_PATH}/api/:apiId/:sidebarState`; +export const SAAS_EDITOR_API_ID_PATH = `${SAAS_EDITOR_PATH}/api/:baseApiId`; +export const SAAS_EDITOR_API_ID_ADD_PATH = `${SAAS_EDITOR_PATH}/api/:baseApiId/:sidebarState`; export const APPSMITH_TOKEN_STORAGE_KEY = "APPSMITH_AUTH_TOKEN"; diff --git a/app/client/src/pages/Editor/WidgetsEditor/components/NavigationAdjustedPageViewer.tsx b/app/client/src/pages/Editor/WidgetsEditor/components/NavigationAdjustedPageViewer.tsx index 14c8036774..08746e9773 100644 --- a/app/client/src/pages/Editor/WidgetsEditor/components/NavigationAdjustedPageViewer.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor/components/NavigationAdjustedPageViewer.tsx @@ -4,16 +4,14 @@ import { EditorState } from "@appsmith/entities/IDE/constants"; import { useCurrentAppState } from "pages/Editor/IDE/hooks"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; import { useSelector } from "react-redux"; -import { - combinedPreviewModeSelector, - getCurrentApplication, -} from "selectors/editorSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { PageViewWrapper } from "pages/AppViewer/AppPage"; import classNames from "classnames"; import { APP_MODE } from "entities/App"; import { getAppMode } from "@appsmith/selectors/entitiesSelector"; import { getAppSidebarPinned, + getCurrentApplication, getSidebarWidth, } from "@appsmith/selectors/applicationSelectors"; import { useIsMobileDevice } from "utils/hooks/useDeviceDetect"; diff --git a/app/client/src/pages/Editor/WidgetsEditor/components/WidgetEditorNavigation.tsx b/app/client/src/pages/Editor/WidgetsEditor/components/WidgetEditorNavigation.tsx index 154e824eea..9d71dc73c0 100644 --- a/app/client/src/pages/Editor/WidgetsEditor/components/WidgetEditorNavigation.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor/components/WidgetEditorNavigation.tsx @@ -7,10 +7,8 @@ import { getIsAppSettingsPaneWithNavigationTabOpen, } from "selectors/appSettingsPaneSelectors"; import { useSelector } from "react-redux"; -import { - combinedPreviewModeSelector, - getCurrentApplication, -} from "selectors/editorSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; /** * useNavigationPreviewHeight diff --git a/app/client/src/pages/Editor/gitSync/GitSettingsModal/TabGeneral/DangerZone.tsx b/app/client/src/pages/Editor/gitSync/GitSettingsModal/TabGeneral/DangerZone.tsx index 856fe0c7d0..25b377bc09 100644 --- a/app/client/src/pages/Editor/gitSync/GitSettingsModal/TabGeneral/DangerZone.tsx +++ b/app/client/src/pages/Editor/gitSync/GitSettingsModal/TabGeneral/DangerZone.tsx @@ -19,7 +19,6 @@ import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; import { Button, Divider, Text } from "design-system"; import React from "react"; import { useDispatch, useSelector } from "react-redux"; -import { getCurrentApplication } from "selectors/editorSelectors"; import { getAutocommitEnabledSelector, getGitMetadataLoadingSelector, @@ -32,6 +31,7 @@ import { useHasConnectToGitPermission, useHasManageAutoCommitPermission, } from "../../hooks/gitPermissionHooks"; +import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; const Container = styled.div` padding-top: 16px; diff --git a/app/client/src/pages/Editor/gitSync/ReconnectDatasourceModal.tsx b/app/client/src/pages/Editor/gitSync/ReconnectDatasourceModal.tsx index 11beaa2dfa..112a44076a 100644 --- a/app/client/src/pages/Editor/gitSync/ReconnectDatasourceModal.tsx +++ b/app/client/src/pages/Editor/gitSync/ReconnectDatasourceModal.tsx @@ -43,7 +43,7 @@ import DatasourceForm from "../DataSourceEditor"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import { useQuery } from "../utils"; import ListItemWrapper from "./components/DatasourceListItem"; -import { getDefaultPageId } from "@appsmith/sagas/ApplicationSagas"; +import { findDefaultPage } from "@appsmith/sagas/ApplicationSagas"; import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; import { getOAuthAccessToken, @@ -75,6 +75,7 @@ import { getFetchedWorkspaces } from "@appsmith/selectors/workspaceSelectors"; import { getApplicationsOfWorkspace } from "@appsmith/selectors/selectedWorkspaceSelectors"; import useReconnectModalData from "@appsmith/pages/Editor/gitSync/useReconnectModalData"; import { resetImportData } from "@appsmith/actions/workspaceActions"; +import { getLoadingTokenForDatasourceId } from "selectors/datasourceSelectors"; const Section = styled.div` display: flex; @@ -261,6 +262,9 @@ function ReconnectDatasourceModal() { const pluginsArray = useSelector(getDatasourcePlugins); const plugins = keyBy(pluginsArray, "id"); const isLoading = useSelector(getIsListing); + const loadingTokenForDatasourceId = useSelector( + getLoadingTokenForDatasourceId, + ); const isDatasourceTesting = useSelector(getIsDatasourceTesting); const isDatasourceUpdating = useSelector(getDatasourceLoading); @@ -367,11 +371,11 @@ function ReconnectDatasourceModal() { }), ); dispatch(setIsReconnectingDatasourcesModalOpen({ isOpen: true })); - const defaultPageId = getDefaultPageId(app.pages); + const defaultPage = findDefaultPage(app.pages); if (pageIdForImport) { setPageId(pageIdForImport); - } else if (defaultPageId) { - setPageId(defaultPageId); + } else if (defaultPage) { + setPageId(defaultPage?.id); } if (!datasources.length) { dispatch({ @@ -562,7 +566,10 @@ function ReconnectDatasourceModal() { }); const shouldShowDBForm = - isConfigFetched && !isLoading && !checkIfDatasourceIsConfigured(datasource); + isConfigFetched && + !isLoading && + !checkIfDatasourceIsConfigured(datasource) && + datasources.findIndex((ds) => ds.id === loadingTokenForDatasourceId) === -1; const onSkipBtnClick = () => { AnalyticsUtil.logEvent("RECONNECTING_SKIP_TO_APPLICATION_BUTTON_CLICK"); diff --git a/app/client/src/pages/Editor/gitSync/Tabs/Deploy.tsx b/app/client/src/pages/Editor/gitSync/Tabs/Deploy.tsx index f7170da190..aecebd2385 100644 --- a/app/client/src/pages/Editor/gitSync/Tabs/Deploy.tsx +++ b/app/client/src/pages/Editor/gitSync/Tabs/Deploy.tsx @@ -38,7 +38,10 @@ import { } from "selectors/gitSyncSelectors"; import { useDispatch, useSelector } from "react-redux"; -import { getCurrentAppGitMetaData } from "@appsmith/selectors/applicationSelectors"; +import { + getCurrentAppGitMetaData, + getCurrentApplication, +} from "@appsmith/selectors/applicationSelectors"; import DeployPreview from "../components/DeployPreview"; import { clearCommitErrorState, @@ -57,10 +60,7 @@ import ConflictInfo from "../components/ConflictInfo"; import { isEllipsisActive, isMacOrIOS } from "utils/helpers"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; -import { - getApplicationLastDeployedAt, - getCurrentApplication, -} from "selectors/editorSelectors"; +import { getApplicationLastDeployedAt } from "selectors/editorSelectors"; import GIT_ERROR_CODES from "constants/GitErrorCodes"; import { Container, Space } from "../components/StyledComponents"; import DiscardChangesWarning from "../components/DiscardChangesWarning"; diff --git a/app/client/src/pages/Editor/gitSync/components/DeployPreview.tsx b/app/client/src/pages/Editor/gitSync/components/DeployPreview.tsx index a4645db410..e3d7171662 100644 --- a/app/client/src/pages/Editor/gitSync/components/DeployPreview.tsx +++ b/app/client/src/pages/Editor/gitSync/components/DeployPreview.tsx @@ -3,8 +3,8 @@ import React from "react"; import styled from "styled-components"; import { useSelector } from "react-redux"; import { - getCurrentPageId, getApplicationLastDeployedAt, + getCurrentBasePageId, } from "selectors/editorSelectors"; import { createMessage, @@ -34,7 +34,7 @@ const Container = styled.div` `; export default function DeployPreview(props: { showSuccess: boolean }) { - const pageId = useSelector(getCurrentPageId) as string; + const basePageId = useSelector(getCurrentBasePageId); const lastDeployedAt = useSelector(getApplicationLastDeployedAt); const showDeployPreview = () => { @@ -42,7 +42,7 @@ export default function DeployPreview(props: { showSuccess: boolean }) { source: "GIT_DEPLOY_MODAL", }); const path = viewerURL({ - pageId, + basePageId, }); window.open(path, "_blank"); }; diff --git a/app/client/src/pages/Editor/gitSync/hooks/gitPermissionHooks.ts b/app/client/src/pages/Editor/gitSync/hooks/gitPermissionHooks.ts index ec637bb140..ea1de28e94 100644 --- a/app/client/src/pages/Editor/gitSync/hooks/gitPermissionHooks.ts +++ b/app/client/src/pages/Editor/gitSync/hooks/gitPermissionHooks.ts @@ -5,7 +5,7 @@ import { hasManageDefaultBranchPermission, hasManageAutoCommitPermission, } from "@appsmith/utils/permissionHelpers"; -import { getCurrentApplication } from "selectors/editorSelectors"; +import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; export const useHasConnectToGitPermission = () => { const currentApplication = useSelector(getCurrentApplication); diff --git a/app/client/src/pages/Editor/gitSync/utils.test.ts b/app/client/src/pages/Editor/gitSync/utils.test.ts index d3921224ee..7c1b451dce 100644 --- a/app/client/src/pages/Editor/gitSync/utils.test.ts +++ b/app/client/src/pages/Editor/gitSync/utils.test.ts @@ -223,8 +223,10 @@ describe("gitSync utils", () => { appIsExample: false, applicationVersion: ApplicationVersion.DEFAULT, defaultPageId: "", + defaultBasePageId: "", slug: "", id: "", + baseId: "", isAutoUpdate: false, isManualUpdate: false, name: "", @@ -244,7 +246,9 @@ describe("gitSync utils", () => { appIsExample: false, applicationVersion: ApplicationVersion.DEFAULT, defaultPageId: "", + defaultBasePageId: "", id: "", + baseId: "", slug: "", isAutoUpdate: true, isManualUpdate: false, @@ -265,7 +269,9 @@ describe("gitSync utils", () => { appIsExample: false, applicationVersion: ApplicationVersion.DEFAULT, defaultPageId: "", + defaultBasePageId: "", id: "", + baseId: "", slug: "", isAutoUpdate: true, isManualUpdate: true, @@ -286,7 +292,9 @@ describe("gitSync utils", () => { appIsExample: false, applicationVersion: ApplicationVersion.DEFAULT, defaultPageId: "", + defaultBasePageId: "", id: "", + baseId: "", slug: "", isAutoUpdate: false, isManualUpdate: true, diff --git a/app/client/src/pages/Editor/index.tsx b/app/client/src/pages/Editor/index.tsx index 24ac9fba60..e71919cbd2 100644 --- a/app/client/src/pages/Editor/index.tsx +++ b/app/client/src/pages/Editor/index.tsx @@ -11,10 +11,11 @@ import { getIsEditorInitialized, getIsEditorLoading, getIsPublishingApplication, + getPageList, getPublishingError, } from "selectors/editorSelectors"; -import type { InitializeEditorPayload } from "actions/initActions"; -import { initEditor, resetEditorRequest } from "actions/initActions"; +import type { InitEditorActionPayload } from "actions/initActions"; +import { initEditorAction, resetEditorRequest } from "actions/initActions"; import CenteredWrapper from "components/designSystems/appsmith/CenteredWrapper"; import { getCurrentUser } from "selectors/usersSelectors"; import type { User } from "constants/userConstants"; @@ -26,7 +27,7 @@ import type { Theme } from "constants/DefaultTheme"; import GlobalHotKeys from "./GlobalHotKeys"; import GitSyncModal from "pages/Editor/gitSync/GitSyncModal"; import DisconnectGitModal from "pages/Editor/gitSync/DisconnectGitModal"; -import { setupPage, updateCurrentPage } from "actions/pageActions"; +import { setupPageAction, updateCurrentPage } from "actions/pageActions"; import { getCurrentPageId } from "selectors/editorSelectors"; import { getSearchQuery } from "utils/helpers"; import RepoLimitExceededErrorModal from "./gitSync/RepoLimitExceededErrorModal"; @@ -47,12 +48,13 @@ import ReconfigureCDKeyModal from "@appsmith/components/gitComponents/Reconfigur import DisableCDModal from "@appsmith/components/gitComponents/DisableCDModal"; import { PartialExportModal } from "components/editorComponents/PartialImportExport/PartialExportModal"; import { PartialImportModal } from "components/editorComponents/PartialImportExport/PartialImportModal"; +import type { Page } from "@appsmith/constants/ReduxActionConstants"; import { AppCURLImportModal } from "@appsmith/pages/Editor/CurlImport"; interface EditorProps { currentApplicationId?: string; currentApplicationName?: string; - initEditor: (payload: InitializeEditorPayload) => void; + initEditor: (payload: InitEditorActionPayload) => void; isPublishing: boolean; isEditorLoading: boolean; isEditorInitialized: boolean; @@ -69,14 +71,15 @@ interface EditorProps { pageLevelSocketRoomId: string; isMultiPane: boolean; widgetConfigBuildSuccess: () => void; + pages: Page[]; } type Props = EditorProps & RouteComponentProps; class Editor extends Component { componentDidMount() { - const { pageId } = this.props.match.params || {}; - urlBuilder.setCurrentPageId(pageId); + const { basePageId } = this.props.match.params || {}; + urlBuilder.setCurrentBasePageId(basePageId); editorInitializer().then(() => { this.props.widgetConfigBuildSuccess(); @@ -92,7 +95,8 @@ class Editor extends Component { return ( isBranchUpdated || nextProps.currentApplicationName !== this.props.currentApplicationName || - nextProps.match?.params?.pageId !== this.props.match?.params?.pageId || + nextProps.match?.params?.basePageId !== + this.props.match?.params?.basePageId || nextProps.currentApplicationId !== this.props.currentApplicationId || nextProps.isEditorInitialized !== this.props.isEditorInitialized || nextProps.isPublishing !== this.props.isPublishing || @@ -105,8 +109,8 @@ class Editor extends Component { } componentDidUpdate(prevProps: Props) { - const { applicationId, pageId } = this.props.match.params || {}; - const { pageId: prevPageId } = prevProps.match.params || {}; + const { baseApplicationId, basePageId } = this.props.match.params || {}; + const { basePageId: prevPageBaseId } = prevProps.match.params || {}; const isBranchUpdated = getIsBranchUpdated( this.props.location, prevProps.location, @@ -121,13 +125,13 @@ class Editor extends Component { GIT_BRANCH_QUERY_KEY, ); - const isPageIdUpdated = pageId !== prevPageId; + const isPageIdUpdated = basePageId !== prevPageBaseId; // to prevent re-init during connect - if (prevBranch && isBranchUpdated && pageId) { + if (prevBranch && isBranchUpdated && basePageId) { this.props.initEditor({ - applicationId, - pageId, + baseApplicationId, + basePageId, branch, mode: APP_MODE.EDIT, }); @@ -137,17 +141,27 @@ class Editor extends Component { * If we don't check for `prevPageId`: fetch page is re triggered * when redirected to the default page */ - if (prevPageId && pageId && isPageIdUpdated) { - this.props.updateCurrentPage(pageId); - this.props.setupPage(pageId); - urlBuilder.setCurrentPageId(pageId); + if ( + prevPageBaseId && + basePageId && + isPageIdUpdated && + this.props.pages.length + ) { + const pageId = this.props.pages.find( + (page) => page.basePageId === basePageId, + )?.pageId; + if (pageId) { + this.props.updateCurrentPage(pageId); + this.props.setupPage(pageId); + urlBuilder.setCurrentBasePageId(basePageId); + } } } } componentWillUnmount() { this.props.resetEditorRequest(); - urlBuilder.setCurrentPageId(null); + urlBuilder.setCurrentBasePageId(null); } public render() { @@ -204,14 +218,15 @@ const mapStateToProps = (state: AppState) => ({ user: getCurrentUser(state), currentApplicationName: state.ui.applications.currentApplication?.name, currentPageId: getCurrentPageId(state), + pages: getPageList(state), }); const mapDispatchToProps = (dispatch: any) => { return { - initEditor: (payload: InitializeEditorPayload) => - dispatch(initEditor(payload)), + initEditor: (payload: InitEditorActionPayload) => + dispatch(initEditorAction(payload)), resetEditorRequest: () => dispatch(resetEditorRequest()), - setupPage: (pageId: string) => dispatch(setupPage(pageId)), + setupPage: (pageId: string) => dispatch(setupPageAction(pageId)), updateCurrentPage: (pageId: string) => dispatch(updateCurrentPage(pageId)), widgetConfigBuildSuccess: () => dispatch(widgetInitialisationSuccess()), }; diff --git a/app/client/src/pages/Editor/loader.tsx b/app/client/src/pages/Editor/loader.tsx index 5d600075da..59384b9703 100644 --- a/app/client/src/pages/Editor/loader.tsx +++ b/app/client/src/pages/Editor/loader.tsx @@ -2,8 +2,8 @@ import React from "react"; import PageLoadingBar from "pages/common/PageLoadingBar"; import { retryPromise } from "utils/AppsmithUtils"; import { connect } from "react-redux"; -import type { InitializeEditorPayload } from "actions/initActions"; -import { initEditor } from "actions/initActions"; +import type { InitEditorActionPayload } from "actions/initActions"; +import { initEditorAction } from "actions/initActions"; import { getSearchQuery } from "../../utils/helpers"; import { GIT_BRANCH_QUERY_KEY } from "../../constants/routes"; import { APP_MODE } from "../../entities/App"; @@ -11,9 +11,9 @@ import type { RouteComponentProps } from "react-router"; import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; type Props = { - initEditor: (payload: InitializeEditorPayload) => void; + initEditor: (payload: InitEditorActionPayload) => void; clearCache: () => void; -} & RouteComponentProps<{ pageId: string }>; +} & RouteComponentProps<{ basePageId: string }>; class EditorLoader extends React.PureComponent { constructor(props: any) { @@ -32,10 +32,10 @@ class EditorLoader extends React.PureComponent { } = this.props; const branch = getSearchQuery(search, GIT_BRANCH_QUERY_KEY); - const { pageId } = params; - if (pageId) { + const { basePageId } = params; + if (basePageId) { initEditor({ - pageId, + basePageId, branch, mode: APP_MODE.EDIT, }); @@ -63,8 +63,8 @@ class EditorLoader extends React.PureComponent { const mapDispatchToProps = (dispatch: any) => { return { - initEditor: (payload: InitializeEditorPayload) => - dispatch(initEditor(payload)), + initEditor: (payload: InitEditorActionPayload) => + dispatch(initEditorAction(payload)), clearCache: () => { dispatch({ type: ReduxActionTypes.CLEAR_CACHE }); }, diff --git a/app/client/src/pages/Templates/test_config.ts b/app/client/src/pages/Templates/test_config.ts index 849f14f0d9..8c357ac0e3 100644 --- a/app/client/src/pages/Templates/test_config.ts +++ b/app/client/src/pages/Templates/test_config.ts @@ -60,6 +60,7 @@ export const unitTestMockTemplate = { pages: [ { id: "6204a671552a5f63958772aa", + baseId: "6204a671552a5f63958772aa", name: "Investors", slug: "investors", isDefault: true, diff --git a/app/client/src/pages/common/ErrorPageHeader.tsx b/app/client/src/pages/common/ErrorPageHeader.tsx index 6abc1bfadd..952810f9c9 100644 --- a/app/client/src/pages/common/ErrorPageHeader.tsx +++ b/app/client/src/pages/common/ErrorPageHeader.tsx @@ -15,10 +15,10 @@ import { getSafeCrash } from "selectors/errorSelectors"; import { Indices } from "constants/Layers"; import { getTenantConfig } from "@appsmith/selectors/tenantSelectors"; import { getSelectedAppTheme } from "selectors/appThemingSelectors"; -import { getCurrentApplication } from "selectors/editorSelectors"; import { NAVIGATION_SETTINGS } from "constants/AppConstants"; import { get } from "lodash"; import { getAssetUrl } from "@appsmith/utils/airgapHelpers"; +import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; const StyledPageHeader = styled(StyledHeader)` box-shadow: none; diff --git a/app/client/src/pages/common/SearchBar/EntitySearchBar.tsx b/app/client/src/pages/common/SearchBar/EntitySearchBar.tsx index 2162b98956..e390d1e96f 100644 --- a/app/client/src/pages/common/SearchBar/EntitySearchBar.tsx +++ b/app/client/src/pages/common/SearchBar/EntitySearchBar.tsx @@ -11,9 +11,11 @@ import history from "utils/history"; import ProductUpdatesModal from "pages/Applications/ProductUpdatesModal"; import { useDispatch, useSelector } from "react-redux"; import { getTenantConfig } from "@appsmith/selectors/tenantSelectors"; -import { getCurrentApplicationIdForCreateNewApp } from "@appsmith/selectors/applicationSelectors"; +import { + getCurrentApplication, + getCurrentApplicationIdForCreateNewApp, +} from "@appsmith/selectors/applicationSelectors"; import { NAVIGATION_SETTINGS } from "constants/AppConstants"; -import { getCurrentApplication } from "selectors/editorSelectors"; import { getSelectedAppTheme } from "selectors/appThemingSelectors"; import { debounce, get } from "lodash"; import HomepageHeaderAction from "pages/common/SearchBar/HomepageHeaderAction"; @@ -36,6 +38,7 @@ import MobileEntitySearchField from "pages/common/SearchBar/MobileEntitySearchFi import { getPackagesList } from "@appsmith/selectors/packageSelectors"; import Fuse from "fuse.js"; import { useOutsideClick } from "@appsmith/hooks"; +import type { PageDefaultMeta } from "@appsmith/api/ApplicationApi"; const HeaderSection = styled.div` display: flex; @@ -133,11 +136,11 @@ function EntitySearchBar(props: any) { (app: ApplicationPayload) => app.id === applicationId, ); - const defaultPageId = searchedApplication?.pages.find( - (page: any) => page.isDefault === true, - )?.id; + const defaultPage = searchedApplication?.pages.find( + (page: PageDefaultMeta) => page.isDefault === true, + ); const viewURL = viewerURL({ - pageId: defaultPageId, + basePageId: defaultPage.baseId, }); window.location.href = `${viewURL}`; } diff --git a/app/client/src/pages/common/datasourceAuth/index.tsx b/app/client/src/pages/common/datasourceAuth/index.tsx index 7b15ddce7c..dfd6a069be 100644 --- a/app/client/src/pages/common/datasourceAuth/index.tsx +++ b/app/client/src/pages/common/datasourceAuth/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo } from "react"; +import React, { useEffect } from "react"; import styled from "styled-components"; import { useDispatch, useSelector } from "react-redux"; import { @@ -12,8 +12,7 @@ import { } from "actions/datasourceActions"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import { getCurrentApplicationId } from "selectors/editorSelectors"; -import { useParams, useLocation, useHistory } from "react-router"; -import type { ExplorerURLParams } from "@appsmith/pages/Editor/Explorer/helpers"; +import { useLocation, useHistory } from "react-router"; import type { Datasource } from "entities/Datasource"; import { AuthType, AuthenticationStatus } from "entities/Datasource"; import { @@ -43,7 +42,7 @@ import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; import { getHasManageDatasourcePermission } from "@appsmith/utils/BusinessFeatures/permissionPageHelpers"; import { resetCurrentPluginIdForCreateNewApp } from "actions/onboardingActions"; -import { getParentEntityDetailsFromParams } from "@appsmith/entities/Engine/actionHelpers"; +import { useParentEntityDetailsFromParams } from "@appsmith/entities/Engine/actionHelpers"; interface Props { datasource: Datasource; @@ -185,22 +184,16 @@ function DatasourceAuth({ ); const currentEnvDetails = useSelector(getCurrentEnvironmentDetails); - // hooks const dispatch = useDispatch(); const location = useLocation(); - const parentEntityIdObject = useParams(); const history = useHistory(); - const { entityType, parentEntityId } = useMemo( - () => - getParentEntityDetailsFromParams( - parentEntityIdObject, - parentEntityIdProp, - isInsideReconnectModal, - ), - [isInsideReconnectModal, parentEntityIdProp, parentEntityIdObject], - ); + const { baseParentEntityId, entityType, parentEntityId } = + useParentEntityDetailsFromParams( + parentEntityIdProp, + isInsideReconnectModal, + ); useEffect(() => { if ( @@ -231,7 +224,7 @@ function DatasourceAuth({ AnalyticsUtil.logEvent("DATASOURCE_AUTH_COMPLETE", { applicationId: applicationId, datasourceId: datasourceId, - pageId: parentEntityId, + pageId: baseParentEntityId, oAuthPassOrFailVerdict: status, workspaceId: datasource?.workspaceId, datasourceName: datasource?.name, @@ -275,7 +268,7 @@ function DatasourceAuth({ // Handles datasource testing const handleDatasourceTest = () => { AnalyticsUtil.logEvent("TEST_DATA_SOURCE_CLICK", { - pageId: parentEntityId, + pageId: baseParentEntityId, appId: applicationId, datasourceId: datasourceId, environmentId: currentEnvironment, @@ -289,7 +282,7 @@ function DatasourceAuth({ const handleDefaultAuthDatasourceSave = () => { dispatch(toggleSaveActionFlag(true)); AnalyticsUtil.logEvent("SAVE_DATA_SOURCE_CLICK", { - pageId: parentEntityId, + pageId: baseParentEntityId, appId: applicationId, environmentId: currentEnvironment, environmentName: currentEnvDetails.name, @@ -385,7 +378,7 @@ function DatasourceAuth({ dispatch(resetCurrentPluginIdForCreateNewApp()); } else { const URL = integrationEditorURL({ - pageId: parentEntityId, + basePageId: baseParentEntityId, selectedTab: INTEGRATION_TABS.NEW, params: getQueryParams(), }); diff --git a/app/client/src/pages/tests/mockData.ts b/app/client/src/pages/tests/mockData.ts index dbebf01162..7c04ef0e50 100644 --- a/app/client/src/pages/tests/mockData.ts +++ b/app/client/src/pages/tests/mockData.ts @@ -1,81 +1,99 @@ -import type { FetchApplicationResponse } from "@appsmith/api/ApplicationApi"; +import type { ApplicationResponsePayload } from "@appsmith/api/ApplicationApi"; +import type { Page } from "@appsmith/constants/ReduxActionConstants"; import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; +import type { UpdateCurrentPagePayload } from "actions/pageActions"; import store from "store"; -export const fetchPagesMockResponse = { - responseMeta: { - status: 200, - success: true, - }, - data: { - workspaceId: "605c433c91dea93f0eaf91b5", - pages: [ - { - pageId: "605c435a91dea93f0eaf91ba", - name: "Page1", - isDefault: true, - slug: "page-1", - }, - ], - }, +const workspaceId = ""; +const applicationId = "605c435a91dea93f0eaf91b8"; +const baseApplicationId = "605c435a91dea93f0eaf91b8"; +const page1Id = "605c435a91dea93f0eaf91ba"; +const basePage1Id = "605c435a91dea93f0eaf91ba"; +const page2Id = "605c435a91dea93f0eaf91bc"; +const basePage2Id = "605c435a91dea93f0eaf91bc"; + +export const mockApplicationPayload: ApplicationResponsePayload = { + id: applicationId, + baseId: baseApplicationId, + name: "My Application", + slug: "my-application", + workspaceId, + evaluationVersion: 1, + appIsExample: false, + gitApplicationMetadata: undefined, + applicationVersion: 2, + pages: [ + { + id: page1Id, + baseId: basePage1Id, + name: "Page1", + isDefault: true, + slug: "page-1", + }, + { + id: page2Id, + baseId: basePage2Id, + name: "Page2", + isDefault: false, + slug: "page-2", + }, + ], }; -export const fetchApplicationMockResponse: FetchApplicationResponse = { - responseMeta: { - status: 200, - success: true, - }, - data: { - application: { - id: "605c435a91dea93f0eaf91b8", - name: "My Application", - slug: "my-application", - workspaceId: "", - evaluationVersion: 1, - appIsExample: false, - gitApplicationMetadata: undefined, - applicationVersion: 2, +export const mockPageListPayload: { + pages: Page[]; + applicationId: string; + baseApplicationId: string; +} = { + applicationId: applicationId, + baseApplicationId: baseApplicationId, + pages: [ + { + pageId: page1Id, + basePageId: page2Id, + pageName: "Page1", + isDefault: true, + slug: "page-1", }, - pages: [ - { - id: "605c435a91dea93f0eaf91ba", - name: "Page1", - isDefault: true, - slug: "page-1", - }, - { - id: "605c435a91dea93f0eaf91bc", - name: "Page2", - isDefault: false, - slug: "page-2", - }, - ], - workspaceId: "", - }, + { + pageId: page2Id, + basePageId: basePage2Id, + pageName: "Page2", + isDefault: false, + slug: "page-2", + }, + ], +}; + +const mockUpdateCurrentPagePayload: UpdateCurrentPagePayload = { + id: mockApplicationPayload.pages[0].id, + slug: mockApplicationPayload.pages[0].slug, }; export const setMockPageList = () => { store.dispatch({ type: ReduxActionTypes.FETCH_PAGE_LIST_SUCCESS, - payload: { - applicationId: "605c435a91dea93f0eaf91b8", - pages: fetchPagesMockResponse.data.pages, - }, + payload: mockPageListPayload, }); }; export const setMockApplication = () => { store.dispatch({ type: ReduxActionTypes.FETCH_APPLICATION_SUCCESS, - payload: { - ...fetchApplicationMockResponse.data.application, - pages: fetchApplicationMockResponse.data.pages, - }, + payload: mockApplicationPayload, + }); +}; + +export const updateMockCurrentPage = () => { + store.dispatch({ + type: ReduxActionTypes.SWITCH_CURRENT_PAGE_ID, + payload: mockUpdateCurrentPagePayload, }); }; export const updatedApplicationPayload = { - id: "605c435a91dea93f0eaf91b8", + id: applicationId, + baseId: baseApplicationId, name: "Renamed application", slug: "renamed-application", workspaceId: "", @@ -86,7 +104,8 @@ export const updatedApplicationPayload = { }; export const updatedPagePayload = { - id: "605c435a91dea93f0eaf91bc", + id: page2Id, + baseId: basePage2Id, name: "My Page 2", isDefault: false, slug: "my-page-2", diff --git a/app/client/src/pages/tests/slug.test.tsx b/app/client/src/pages/tests/slug.test.tsx index b1b1c7ecff..d91247e636 100644 --- a/app/client/src/pages/tests/slug.test.tsx +++ b/app/client/src/pages/tests/slug.test.tsx @@ -12,9 +12,10 @@ import { matchPath_ViewerCustomSlug, } from "utils/helpers"; import { - fetchApplicationMockResponse, + mockApplicationPayload, setMockApplication, setMockPageList, + updateMockCurrentPage, updatedApplicationPayload, updatedPagePayload, } from "./mockData"; @@ -27,10 +28,7 @@ describe("URL slug names", () => { beforeEach(async () => { setMockApplication(); setMockPageList(); - store.dispatch({ - type: ReduxActionTypes.SWITCH_CURRENT_PAGE_ID, - payload: { id: "605c435a91dea93f0eaf91ba", slug: "page-1" }, - }); + updateMockCurrentPage(); }); it("verifies right slug names from slugs selector", () => { @@ -77,12 +75,12 @@ describe("URL slug names", () => { }); it("verifies that the baseURLBuilder uses applicationVersion", () => { - const applicationId = "a0123456789abcdef0000000"; - const pageId = "b0123456789abcdef0000000"; + const baseApplicationId = "a0123456789abcdef0000000"; + const basePageId = "b0123456789abcdef0000000"; const params = { - applicationId, + baseApplicationId, applicationSlug: "appSlug", - pageId, + basePageId, pageSlug: "pageSlug", customSlug: "customSlug", }; @@ -90,42 +88,45 @@ describe("URL slug names", () => { { applicationVersion: ApplicationVersion.DEFAULT, applicationSlug: params.applicationSlug, - applicationId: params.applicationId, + baseApplicationId: params.baseApplicationId, }, [ { - pageId: params.pageId, + basePageId: params.basePageId, pageSlug: params.pageSlug, }, ], ); - const url1 = builderURL({ pageId: params.pageId }); + const url1 = builderURL({ basePageId: params.basePageId }); urlBuilder.updateURLParams({ applicationVersion: ApplicationVersion.SLUG_URL, }); - const url2 = builderURL({ pageId: params.pageId }); + const url2 = builderURL({ basePageId: params.basePageId }); store.dispatch({ type: ReduxActionTypes.UPDATE_APPLICATION_SUCCESS, payload: { applicationVersion: ApplicationVersion.DEFAULT }, }); - const url3 = builderURL({ pageId: params.pageId }); + const url3 = builderURL({ basePageId: params.basePageId }); store.dispatch({ type: ReduxActionTypes.UPDATE_APPLICATION_SUCCESS, payload: { applicationVersion: ApplicationVersion.SLUG_URL }, }); - const url4 = builderURL({ pageId: params.pageId }); - expect(url1).toBe(`/applications/${applicationId}/pages/${pageId}/edit`); - expect(url2).toBe(`/app/appSlug/pageSlug-${pageId}/edit`); - expect(url3).toBe(`/applications/${applicationId}/pages/${pageId}/edit`); - expect(url4).toBe(`/app/appSlug/pageSlug-${pageId}/edit`); + const url4 = builderURL({ basePageId: params.basePageId }); + expect(url1).toBe( + `/applications/${baseApplicationId}/pages/${basePageId}/edit`, + ); + expect(url2).toBe(`/app/appSlug/pageSlug-${basePageId}/edit`); + expect(url3).toBe( + `/applications/${baseApplicationId}/pages/${basePageId}/edit`, + ); + expect(url4).toBe(`/app/appSlug/pageSlug-${basePageId}/edit`); }); it("tests the manual upgrade option", () => { store.dispatch({ type: ReduxActionTypes.FETCH_APPLICATION_SUCCESS, payload: { - ...fetchApplicationMockResponse.data.application, - pages: fetchApplicationMockResponse.data.pages, + ...mockApplicationPayload, applicationVersion: 1, }, }); @@ -198,7 +199,7 @@ describe("URL slug names", () => { getUpdatedRoute(customSlug_pathname, { applicationSlug: "gsheetreleasetesting-copy", customSlug: "custom", - pageId: "63c63d944ae4345e31af12a7", + basePageId: "63c63d944ae4345e31af12a7", pageSlug: "basicpagination", }), ).toBe(customSlug_pathname); diff --git a/app/client/src/pages/workspace/AppInviteUsersForm.tsx b/app/client/src/pages/workspace/AppInviteUsersForm.tsx index f43b491066..49a736cabc 100644 --- a/app/client/src/pages/workspace/AppInviteUsersForm.tsx +++ b/app/client/src/pages/workspace/AppInviteUsersForm.tsx @@ -50,7 +50,7 @@ function AppInviteUsersForm(props: any) { changeAppViewAccess, currentApplicationDetails, currentUser, - defaultPageId, + defaultBasePageId, fetchCurrentWorkspace, isChangingViewAccess, isFetchingApplication, @@ -96,10 +96,10 @@ function AppInviteUsersForm(props: any) { const appViewEndPoint = React.useMemo(() => { const url = viewerURL({ - pageId: defaultPageId, + basePageId: defaultBasePageId, }); return window.location.origin.toString() + url; - }, [defaultPageId]); + }, [defaultBasePageId]); useEffect(() => { if (currentUser?.name !== ANONYMOUS_USERNAME) { @@ -178,7 +178,7 @@ export default connect( return { currentUser: getCurrentUser(state), currentApplicationDetails: state.ui.applications.currentApplication, - defaultPageId: state.entities.pageList.defaultPageId, + defaultPageId: state.entities.pageList.defaultBasePageId, isFetchingApplication: state.ui.applications.isFetchingApplication, isChangingViewAccess: state.ui.applications.isChangingViewAccess, }; diff --git a/app/client/src/reducers/entityReducers/datasourceReducer.ts b/app/client/src/reducers/entityReducers/datasourceReducer.ts index c184282be2..6586b7b2d5 100644 --- a/app/client/src/reducers/entityReducers/datasourceReducer.ts +++ b/app/client/src/reducers/entityReducers/datasourceReducer.ts @@ -19,6 +19,7 @@ import { assign } from "lodash"; export interface DatasourceDataState { list: Datasource[]; loading: boolean; + loadingTokenForDatasourceId: string | null; isTesting: boolean; isListing: boolean; // fetching unconfigured datasource list fetchingDatasourceStructure: Record; @@ -46,6 +47,7 @@ export interface DatasourceDataState { const initialState: DatasourceDataState = { list: [], loading: false, + loadingTokenForDatasourceId: null, isTesting: false, isListing: false, fetchingDatasourceStructure: {}, @@ -345,6 +347,31 @@ const datasourceReducer = createReducer(initialState, { ], }; }, + [ReduxActionTypes.GET_OAUTH_ACCESS_TOKEN]: ( + state: DatasourceDataState, + action: ReduxAction<{ datasourceId: string }>, + ) => { + return { + ...state, + loadingTokenForDatasourceId: action.payload.datasourceId, + }; + }, + [ReduxActionTypes.GET_OAUTH_ACCESS_TOKEN_SUCCESS]: ( + state: DatasourceDataState, + ) => { + return { + ...state, + loadingTokenForDatasourceId: null, + }; + }, + [ReduxActionTypes.GET_OAUTH_ACCESS_TOKEN_ERROR]: ( + state: DatasourceDataState, + ) => { + return { + ...state, + loadingTokenForDatasourceId: null, + }; + }, [ReduxActionTypes.UPDATE_DATASOURCE_STORAGE_SUCCESS]: ( state: DatasourceDataState, action: ReduxAction, @@ -428,16 +455,6 @@ const datasourceReducer = createReducer(initialState, { } }); }); - - return { - ...state, - loading: false, - list: state.list.map((datasource) => { - if (datasource.id === action.payload.id) return action.payload; - - return datasource; - }), - }; }, [ReduxActionErrorTypes.CREATE_DATASOURCE_ERROR]: ( state: DatasourceDataState, diff --git a/app/client/src/reducers/entityReducers/pageListReducer.tsx b/app/client/src/reducers/entityReducers/pageListReducer.tsx index acf24c650b..b9266f33b5 100644 --- a/app/client/src/reducers/entityReducers/pageListReducer.tsx +++ b/app/client/src/reducers/entityReducers/pageListReducer.tsx @@ -8,10 +8,13 @@ import { ReduxActionTypes, } from "@appsmith/constants/ReduxActionConstants"; import type { + DeletePageActionPayload, GenerateCRUDSuccess, + UpdateCurrentPagePayload, + UpdatePageActionPayload, UpdatePageErrorPayload, } from "actions/pageActions"; -import type { UpdatePageRequest, UpdatePageResponse } from "api/PageApi"; +import type { UpdatePageResponse } from "api/PageApi"; import { sortBy } from "lodash"; import type { DSL } from "reducers/uiReducers/pageCanvasStructureReducer"; import { createReducer } from "utils/ReducerUtils"; @@ -19,8 +22,11 @@ import { createReducer } from "utils/ReducerUtils"; const initialState: PageListReduxState = { pages: [], isGeneratingTemplatePage: false, + baseApplicationId: "", applicationId: "", + currentBasePageId: "", currentPageId: "", + defaultBasePageId: "", defaultPageId: "", loading: {}, }; @@ -28,7 +34,7 @@ const initialState: PageListReduxState = { export const pageListReducer = createReducer(initialState, { [ReduxActionTypes.DELETE_PAGE_INIT]: ( state: PageListReduxState, - action: ReduxAction<{ id: string }>, + action: ReduxAction, ) => { if (state.defaultPageId !== action.payload.id) { const pages = [ @@ -43,14 +49,20 @@ export const pageListReducer = createReducer(initialState, { }, [ReduxActionTypes.FETCH_PAGE_LIST_SUCCESS]: ( state: PageListReduxState, - action: ReduxAction<{ pages: Page[]; applicationId: string }>, + action: ReduxAction<{ + pages: Page[]; + applicationId: string; + baseApplicationId: string; + }>, ) => { + const defaultPage = + action.payload.pages.find((page) => page.isDefault) ?? + action.payload.pages[0]; return { ...state, ...action.payload, - defaultPageId: - action.payload.pages.find((page) => page.isDefault)?.pageId || - action.payload.pages[0].pageId, + defaultPageId: defaultPage?.pageId, + defaultBasePageId: defaultPage?.basePageId, }; }, [ReduxActionTypes.UPDATE_PAGE_LIST]: ( @@ -85,6 +97,7 @@ export const pageListReducer = createReducer(initialState, { pageName: string; description?: string; pageId: string; + basePageId: string; layoutId: string; isDefault: boolean; slug: string; @@ -114,6 +127,9 @@ export const pageListReducer = createReducer(initialState, { state.applicationId === action.payload.applicationId && state.defaultPageId !== action.payload.pageId ) { + const defaultPage: Page | null = + state.pages.find((page) => page.pageId === action.payload.pageId) || + null; const pageList = state.pages.map((page) => { if (page.pageId === state.defaultPageId) page.isDefault = false; if (page.pageId === action.payload.pageId) page.isDefault = true; @@ -122,29 +138,40 @@ export const pageListReducer = createReducer(initialState, { return { ...state, pages: pageList, - defaultPageId: action.payload.pageId, + defaultPageId: defaultPage?.pageId ?? "", + defaultBasePageId: defaultPage?.basePageId ?? "", }; } return state; }, [ReduxActionTypes.SWITCH_CURRENT_PAGE_ID]: ( state: PageListReduxState, - action: ReduxAction<{ id: string; slug?: string; permissions?: string[] }>, + action: ReduxAction, ) => { - const pageList = state.pages.map((page) => { - if (page.pageId === action.payload.id && action.payload.permissions) - page.userPermissions = action.payload.permissions; - return page; + const pageList: Page[] = []; + const currentPageId: string = action.payload.id; + let currentBasePageId: string = ""; + state.pages.forEach((page) => { + const modifiedPage = { ...page }; + if (page.pageId === action.payload.id) { + currentBasePageId = page.basePageId; + if (action.payload.permissions) { + modifiedPage.userPermissions = action.payload.permissions; + } + } + pageList.push(modifiedPage); }); + return { ...state, - currentPageId: action.payload.id, + currentPageId, + currentBasePageId, pages: pageList, }; }, [ReduxActionTypes.UPDATE_PAGE_INIT]: ( state: PageListReduxState, - action: ReduxAction, + action: ReduxAction, ) => { return { ...state, @@ -191,7 +218,7 @@ export const pageListReducer = createReducer(initialState, { ...state, loading: { ...state.loading, - [action.payload.request.id]: false, + [action.payload.request.pageId]: false, }, }; }, @@ -210,6 +237,7 @@ export const pageListReducer = createReducer(initialState, { const newPage = { pageName: action.payload.page.name, pageId: action.payload.page.id, + basePageId: action.payload.page.baseId, layoutId: action.payload.page.layouts[0].id, isDefault: !!action.payload.page.isDefault, slug: action.payload.page.slug, @@ -258,9 +286,12 @@ export interface AppLayoutConfig { export interface PageListReduxState { pages: Page[]; + baseApplicationId: string; applicationId: string; - defaultPageId: string; + currentBasePageId: string; currentPageId: string; + defaultBasePageId: string; + defaultPageId: string; appLayout?: AppLayoutConfig; isGeneratingTemplatePage?: boolean; loading: Record; diff --git a/app/client/src/reducers/evaluationReducers/formEvaluationReducer.ts b/app/client/src/reducers/evaluationReducers/formEvaluationReducer.ts index 59156e90e0..50557ad53c 100644 --- a/app/client/src/reducers/evaluationReducers/formEvaluationReducer.ts +++ b/app/client/src/reducers/evaluationReducers/formEvaluationReducer.ts @@ -1,8 +1,8 @@ import { createReducer } from "utils/ReducerUtils"; import type { ReduxAction } from "@appsmith/constants/ReduxActionConstants"; import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; -import type { FetchPageRequest } from "api/PageApi"; import type { FormConfigType } from "components/formControls/BaseControl"; +import type { FetchPageActionPayload } from "actions/pageActions"; // Type for the object that will store the dynamic values for each component export interface DynamicValues { @@ -65,7 +65,7 @@ const formEvaluation = createReducer(initialState, { ): FormEvaluationState => action.payload, [ReduxActionTypes.FETCH_PAGE_INIT]: ( state: FormEvaluationState, - action: ReduxAction, + action: ReduxAction, ) => { // Init the state on first page load if (!!action.payload && action.payload.isFirstLoad) return initialState; diff --git a/app/client/src/reducers/uiReducers/datasourcePaneReducer.ts b/app/client/src/reducers/uiReducers/datasourcePaneReducer.ts index 4bedd6ad41..b23d416d09 100644 --- a/app/client/src/reducers/uiReducers/datasourcePaneReducer.ts +++ b/app/client/src/reducers/uiReducers/datasourcePaneReducer.ts @@ -21,10 +21,10 @@ export interface DatasourcePaneReduxState { drafts: Record; expandDatasourceId: string; actionRouteInfo: Partial<{ - apiId: string; + baseApiId: string; datasourceId: string; - parentEntityId: string; - applicationId: string; + baseParentEntityId: string; + baseApplicationId: string; }>; newDatasource: string; viewMode: boolean; diff --git a/app/client/src/sagas/ActionExecution/NavigateActionSaga.ts b/app/client/src/sagas/ActionExecution/NavigateActionSaga.ts index 70835fcdd0..ab2b6168ba 100644 --- a/app/client/src/sagas/ActionExecution/NavigateActionSaga.ts +++ b/app/client/src/sagas/ActionExecution/NavigateActionSaga.ts @@ -49,11 +49,11 @@ export default function* navigateActionSaga(action: TNavigateToDescription) { const path = appMode === APP_MODE.EDIT ? builderURL({ - pageId: page.pageId, + basePageId: page.basePageId, params, }) : viewerURL({ - pageId: page.pageId, + basePageId: page.basePageId, params, }); diff --git a/app/client/src/sagas/ActionExecution/PluginActionSaga.ts b/app/client/src/sagas/ActionExecution/PluginActionSaga.ts index 5de49ecf7b..515c7863f1 100644 --- a/app/client/src/sagas/ActionExecution/PluginActionSaga.ts +++ b/app/client/src/sagas/ActionExecution/PluginActionSaga.ts @@ -100,6 +100,7 @@ import { } from "constants/AppsmithActionConstants/ActionConstants"; import { getCurrentApplicationId, + getCurrentBasePageId, getCurrentPageId, getIsSavingEntity, getLayoutOnLoadActions, @@ -153,7 +154,7 @@ import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/helpers" import { FILE_SIZE_LIMIT_FOR_BLOBS } from "constants/WidgetConstants"; import type { ActionData } from "@appsmith/reducers/entityReducers/actionsReducer"; import { handleStoreOperations } from "./StoreActionSaga"; -import { fetchPage } from "actions/pageActions"; +import { fetchPageAction } from "actions/pageActions"; import type { Datasource } from "entities/Datasource"; import { softRefreshDatasourceStructure } from "actions/datasourceActions"; import { @@ -690,15 +691,15 @@ function* runActionShortcutSaga() { }); if (!match || !match.params) return; - const { apiId, pageId, queryId } = match.params; - const actionId = apiId || queryId; + const { baseApiId, basePageId, baseQueryId } = match.params; + const actionId = baseApiId || baseQueryId; if (actionId) { - const trackerId = apiId + const trackerId = baseApiId ? PerformanceTransactionName.RUN_API_SHORTCUT : PerformanceTransactionName.RUN_QUERY_SHORTCUT; PerformanceTracker.startTracking(trackerId, { actionId, - pageId, + basePageId, }); AnalyticsUtil.logEvent(trackerId as EventName, { actionId, @@ -1320,6 +1321,7 @@ function* executePluginActionSaga( parentSpan?: OtlpSpan, ) { const actionId = pluginAction.id; + const baseActionId = pluginAction.baseId; const pluginActionNameToDisplay = getPluginActionNameToDisplay(pluginAction); setAttributesToSpan(parentSpan, { @@ -1407,6 +1409,7 @@ function* executePluginActionSaga( yield put( executePluginActionSuccess({ id: actionId, + baseId: baseActionId, response: payload, isActionCreatedInApp: getIsActionCreatedInApp(pluginAction), }), @@ -1473,6 +1476,7 @@ function* executePluginActionSaga( yield put( executePluginActionSuccess({ id: actionId, + baseId: baseActionId, response: EMPTY_RESPONSE, isActionCreatedInApp: getIsActionCreatedInApp(pluginAction), }), @@ -1587,7 +1591,7 @@ function* softRefreshActionsSaga() { const pageId: string = yield select(getCurrentPageId); const applicationId: string = yield select(getCurrentApplicationId); // Fetch the page data before refreshing the actions. - yield put(fetchPage(pageId)); + yield put(fetchPageAction(pageId)); //wait for the page to be fetched. yield take([ ReduxActionErrorTypes.FETCH_PAGE_ERROR, @@ -1617,10 +1621,11 @@ function* softRefreshActionsSaga() { const isQueryPane = matchQueryBuilderPath(window.location.pathname); //This is reuired only when the query editor is open. if (isQueryPane) { + const basePageId: string = yield select(getCurrentBasePageId); yield put( changeQuery({ - id: isQueryPane.params.queryId, - pageId, + baseQueryId: isQueryPane.params.baseQueryId, + basePageId, applicationId, }), ); diff --git a/app/client/src/sagas/ActionSagas.ts b/app/client/src/sagas/ActionSagas.ts index 7aeed302de..8ebf94cc5b 100644 --- a/app/client/src/sagas/ActionSagas.ts +++ b/app/client/src/sagas/ActionSagas.ts @@ -49,7 +49,10 @@ import { import { getDynamicBindingsChangesSaga } from "utils/DynamicBindingUtils"; import { validateResponse } from "./ErrorSagas"; import { transformRestAction } from "transformers/RestActionTransformer"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { + getCurrentBasePageId, + getCurrentPageId, +} from "selectors/editorSelectors"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import type { Action, @@ -147,6 +150,7 @@ import { } from "actions/ideActions"; import { getIsSideBySideEnabled } from "selectors/ideSelectors"; import { CreateNewActionKey } from "@appsmith/entities/Engine/actionHelpers"; +import { convertToBasePageIdSelector } from "selectors/pageListSelectors"; export const DEFAULT_PREFIX = { QUERY: "Query", @@ -340,7 +344,8 @@ export function* createActionSaga( text: `Action created`, source: { type: ENTITY_TYPE.ACTION, - id: response.data.id, + // since resources are recognized by their baseId in console + id: response.data.baseId, // @ts-expect-error: name does not exists on type ActionCreateUpdateResponse name: response.data.name, }, @@ -607,7 +612,7 @@ export function* deleteActionSaga( const isApi = action.pluginType === PluginType.API; const isQuery = action.pluginType === PluginType.DB; const isSaas = action.pluginType === PluginType.SAAS; - const pageId: string = yield select(getCurrentPageId); + const basePageId: string = yield select(getCurrentBasePageId); const response: ApiResponse = yield ActionAPI.deleteAction(id); const isValidResponse: boolean = yield validateResponse(response); @@ -645,7 +650,7 @@ export function* deleteActionSaga( } else { history.push( integrationEditorURL({ - pageId, + basePageId, selectedTab: INTEGRATION_TABS.NEW, }), ); @@ -666,7 +671,7 @@ export function* deleteActionSaga( }); yield put(deleteActionSuccess({ id })); - yield put(closeQueryActionTabSuccess({ id, parentId: pageId })); + yield put(closeQueryActionTabSuccess({ id, parentId: basePageId })); } catch (error) { yield put({ type: ReduxActionErrorTypes.DELETE_ACTION_ERROR, @@ -777,6 +782,7 @@ function* copyActionSaga( copyAction.source = ActionCreationSourceTypeEnum.COPY_ACTION; delete copyAction.id; + delete copyAction.baseId; const response: ApiResponse = yield ActionAPI.createAction(copyAction); const datasources: Datasource[] = yield select(getDatasources); @@ -847,7 +853,7 @@ export function* refactorActionName( { actionId: id }, ); - const params: FetchPageRequest = { id: pageId, migrateDSL: true }; + const params: FetchPageRequest = { pageId, migrateDSL: true }; const pageResponse: FetchPageResponse = yield call(PageApi.fetchPage, params); // check if page request is successful const isPageRequestSuccessful: boolean = yield validateResponse(pageResponse); @@ -903,14 +909,14 @@ function* bindDataOnCanvasSaga( action: ReduxAction<{ queryId: string; applicationId: string; - pageId: string; + basePageId: string; }>, ) { - const { pageId, queryId } = action.payload; + const { basePageId, queryId } = action.payload; yield put(setSnipingModeAction({ isActive: true, bindTo: queryId })); history.push( builderURL({ - pageId, + basePageId, }), ); } @@ -1029,24 +1035,29 @@ function* toggleActionExecuteOnLoadSaga( } function* handleMoveOrCopySaga(actionPayload: ReduxAction) { - const { id, pageId, pluginId, pluginType } = actionPayload.payload; + const { + baseId: baseActionId, + pageId, + pluginId, + pluginType, + } = actionPayload.payload; const isApi = pluginType === PluginType.API; const isQuery = pluginType === PluginType.DB; const isSaas = pluginType === PluginType.SAAS; - + const basePageId: string = yield select(convertToBasePageIdSelector, pageId); if (isApi) { history.push( apiEditorIdURL({ - pageId: pageId, - apiId: id, + basePageId, + baseApiId: baseActionId, }), ); } if (isQuery) { history.push( queryEditorIdURL({ - pageId: pageId, - queryId: id, + basePageId, + baseQueryId: baseActionId, }), ); } @@ -1057,9 +1068,9 @@ function* handleMoveOrCopySaga(actionPayload: ReduxAction) { ); history.push( saasEditorApiIdURL({ - pageId: pageId, + basePageId, pluginPackageName: plugin.packageName, - apiId: id, + baseApiId: baseActionId, }), ); } @@ -1067,12 +1078,13 @@ function* handleMoveOrCopySaga(actionPayload: ReduxAction) { function* executeCommandSaga(actionPayload: ReduxAction) { const pageId: string = yield select(getCurrentPageId); + const basePageId: string = yield select(getCurrentBasePageId); const callback = get(actionPayload, "payload.callback"); switch (actionPayload.payload.actionType) { case SlashCommand.NEW_INTEGRATION: history.push( integrationEditorURL({ - pageId, + basePageId, selectedTab: INTEGRATION_TABS.NEW, }), ); diff --git a/app/client/src/sagas/ApiPaneSagas.ts b/app/client/src/sagas/ApiPaneSagas.ts index ee8ea63a5f..befcdf7bb0 100644 --- a/app/client/src/sagas/ApiPaneSagas.ts +++ b/app/client/src/sagas/ApiPaneSagas.ts @@ -31,13 +31,13 @@ import { import { DEFAULT_CREATE_API_CONFIG } from "constants/ApiEditorConstants/ApiEditorConstants"; import { DEFAULT_CREATE_GRAPHQL_CONFIG } from "constants/ApiEditorConstants/GraphQLEditorConstants"; import history from "utils/history"; -import { INTEGRATION_EDITOR_MODES, INTEGRATION_TABS } from "constants/routes"; import { initialize, autofill, change, reset } from "redux-form"; import type { Property } from "api/ActionAPI"; import { getQueryParams } from "utils/URLUtils"; import { getPluginIdOfPackageName } from "sagas/selectors"; import { getAction, + getActionByBaseId, getDatasourceActionRouteInfo, getPlugin, } from "@appsmith/selectors/entitiesSelector"; @@ -70,12 +70,8 @@ import { updateReplayEntity } from "actions/pageActions"; import { ENTITY_TYPE } from "@appsmith/entities/AppsmithConsole/utils"; import type { Plugin } from "api/PluginApi"; import { getDisplayFormat } from "selectors/apiPaneSelectors"; -import { - apiEditorIdURL, - datasourcesEditorIdURL, - integrationEditorURL, -} from "@appsmith/RouteBuilder"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { apiEditorIdURL, datasourcesEditorIdURL } from "@appsmith/RouteBuilder"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import { validateResponse } from "./ErrorSagas"; import type { CreateDatasourceSuccessAction } from "actions/datasourceActions"; import { removeTempDatasource } from "actions/datasourceActions"; @@ -94,6 +90,7 @@ import { } from "@appsmith/selectors/applicationSelectors"; import { DEFAULT_CREATE_APPSMITH_AI_CONFIG } from "constants/ApiEditorConstants/AppsmithAIEditorConstants"; import { checkAndGetPluginFormConfigsSaga } from "./PluginSagas"; +import { convertToBasePageIdSelector } from "selectors/pageListSelectors"; function* syncApiParamsSaga( actionPayload: ReduxActionWithMeta, @@ -144,24 +141,6 @@ function* syncApiParamsSaga( PerformanceTracker.stopTracking(); } -function* redirectToNewIntegrations( - action: ReduxAction<{ - pageId: string; - params?: Record; - }>, -) { - history.push( - integrationEditorURL({ - pageId: action.payload.pageId, - selectedTab: INTEGRATION_TABS.ACTIVE, - params: { - ...action.payload.params, - mode: INTEGRATION_EDITOR_MODES.AUTO, - }, - }), - ); -} - function* handleUpdateBodyContentType( action: ReduxAction<{ title: string; apiId: string }>, ) { @@ -568,16 +547,36 @@ function* formValueChangeSaga( } function* handleActionCreatedSaga(actionPayload: ReduxAction) { - const { id, pageId, pluginType } = actionPayload.payload; - const action: Action | undefined = yield select(getAction, id); + const { + applicationId, + baseId: baseActionId, + pageId, + pluginType, + } = actionPayload.payload; + const action: Action | undefined = yield select( + getActionByBaseId, + baseActionId, + ); const data = action ? { ...action } : {}; if (pluginType === PluginType.API) { yield put(initialize(API_EDITOR_FORM_NAME, omit(data, "name"))); + let basePageId: string = yield select(convertToBasePageIdSelector, pageId); + if (!basePageId) { + const application: ApplicationPayload = yield select( + getApplicationByIdFromWorkspaces, + applicationId, + ); + if (application && Array.isArray(application.pages)) { + basePageId = + application.pages.find((page) => page.id === pageId)?.baseId || ""; + } + } + history.push( apiEditorIdURL({ - pageId, - apiId: id, + basePageId, + baseApiId: baseActionId, params: { editName: "true", from: "datasources", @@ -604,9 +603,6 @@ export function* handleDatasourceCreatedSaga( getApplicationByIdFromWorkspaces, currentApplicationIdForCreateNewApp || "", ); - const pageId: string = !!currentApplicationIdForCreateNewApp - ? application?.defaultPageId - : yield select(getCurrentPageId); const actionRouteInfo: ReturnType = yield select(getDatasourceActionRouteInfo); @@ -614,12 +610,16 @@ export function* handleDatasourceCreatedSaga( // This will ensure that API if saved as datasource, will get attached with datasource // once the datasource is saved if ( - !!actionRouteInfo.apiId && + !!actionRouteInfo.baseApiId && actionPayload.payload?.id !== TEMP_DATASOURCE_ID ) { + const action: Action = yield select( + getActionByBaseId, + actionRouteInfo.baseApiId, + ); yield put( setActionProperty({ - actionId: actionRouteInfo.apiId, + actionId: action?.id, propertyName: "datasource", value: actionPayload.payload, }), @@ -645,8 +645,8 @@ export function* handleDatasourceCreatedSaga( if (actionRouteInfo && redirect) { history.push( apiEditorIdURL({ - parentEntityId: actionRouteInfo?.parentEntityId ?? "", - apiId: actionRouteInfo.apiId ?? "", + baseParentEntityId: actionRouteInfo?.baseParentEntityId ?? "", + baseApiId: actionRouteInfo.baseApiId ?? "", }), ); } else if ( @@ -654,9 +654,12 @@ export function* handleDatasourceCreatedSaga( (!!currentApplicationIdForCreateNewApp && actionPayload.payload.id !== TEMP_DATASOURCE_ID) ) { + const basePageId: string = !!currentApplicationIdForCreateNewApp + ? application?.defaultBasePageId + : yield select(getCurrentBasePageId); history.push( datasourcesEditorIdURL({ - pageId, + basePageId, datasourceId: actionPayload.payload.id, params: { from: "datasources", @@ -769,10 +772,14 @@ function* handleApiNameChangeSuccessSaga( if (params.editName) { params.editName = "false"; } + const basePageId: string = yield select( + convertToBasePageIdSelector, + actionObj.pageId, + ); history.push( apiEditorIdURL({ - pageId: actionObj.pageId, - apiId: actionId, + basePageId, + baseApiId: actionObj.baseId, params, }), ); @@ -810,11 +817,6 @@ export default function* root() { ReduxActionTypes.UPDATE_API_ACTION_BODY_CONTENT_TYPE, handleUpdateBodyContentType, ), - takeEvery( - ReduxActionTypes.REDIRECT_TO_NEW_INTEGRATIONS, - redirectToNewIntegrations, - ), - // Intercepting the redux-form change actionType takeEvery(ReduxFormActionTypes.VALUE_CHANGE, formValueChangeSaga), takeEvery(ReduxFormActionTypes.ARRAY_REMOVE, formValueChangeSaga), takeEvery(ReduxFormActionTypes.ARRAY_PUSH, formValueChangeSaga), diff --git a/app/client/src/sagas/AppThemingSaga.tsx b/app/client/src/sagas/AppThemingSaga.tsx index 476e2e1a8f..9ea239a59e 100644 --- a/app/client/src/sagas/AppThemingSaga.tsx +++ b/app/client/src/sagas/AppThemingSaga.tsx @@ -41,7 +41,7 @@ import { import { find } from "lodash"; import * as Sentry from "@sentry/react"; import { Severity } from "@sentry/react"; -import { getAllPageIds } from "./selectors"; +import { getAllPageIdentities } from "./selectors"; import type { SagaIterator } from "@redux-saga/types"; import type { AxiosPromise } from "axios"; import { getFromServerWhenNoPrefetchedResult } from "./helper"; @@ -105,7 +105,8 @@ export function* fetchAppSelectedTheme( const { applicationId, currentTheme } = action.payload; const mode: APP_MODE = yield select(getAppMode); - const pageIds = yield select(getAllPageIds); + const pageIdentities: { pageId: string; basePageId: string }[] = + yield select(getAllPageIdentities); const userDetails = yield select(getCurrentUser); const applicationVersion = yield select(selectApplicationVersion); try { @@ -124,7 +125,7 @@ export function* fetchAppSelectedTheme( Sentry.captureException("Unable to fetch the selected theme", { level: Severity.Critical, extra: { - pageIds, + pageIdentities, applicationId, applicationVersion, userDetails, diff --git a/app/client/src/sagas/BuildingBlockSagas/BuildingBlockAdditionSagas.ts b/app/client/src/sagas/BuildingBlockSagas/BuildingBlockAdditionSagas.ts index b24c645f89..c72e34fe41 100644 --- a/app/client/src/sagas/BuildingBlockSagas/BuildingBlockAdditionSagas.ts +++ b/app/client/src/sagas/BuildingBlockSagas/BuildingBlockAdditionSagas.ts @@ -15,6 +15,7 @@ import type { import { all, call, put, select, take } from "redux-saga/effects"; import { getCanvasWidth, + getCurrentBasePageId, getCurrentPageId, getIsAutoLayoutMobileBreakPoint, } from "selectors/editorSelectors"; @@ -80,10 +81,7 @@ import type { DragDetails } from "reducers/uiReducers/dragResizeReducer"; import { race } from "redux-saga/effects"; import { SelectionRequestType } from "sagas/WidgetSelectUtils"; import { getBuildingBlockDragStartTimestamp } from "selectors/buildingBlocksSelectors"; -import { - getCurrentApplicationId, - getJSCollectionById, -} from "selectors/editorSelectors"; +import { getCurrentApplicationId } from "selectors/editorSelectors"; import { getTemplatesSelector } from "selectors/templatesSelectors"; import { initiateBuildingBlockDropEvent } from "utils/buildingBlockUtils"; import { @@ -97,6 +95,7 @@ import { postPageAdditionSaga } from "../TemplatesSagas"; import { addChildSaga } from "../WidgetAdditionSagas"; import { calculateNewWidgetPosition } from "../WidgetOperationSagas"; import { getDragDetails, getWidgetByName } from "../selectors"; +import { getJSCollection } from "@appsmith/selectors/entitiesSelector"; function* addBuildingBlockActionsToApplication(dragDetails: DragDetails) { const applicationId: string = yield select(getCurrentApplicationId); @@ -146,13 +145,10 @@ function* runNewlyCreatedJSActions( // Run each action sequentially. We have a max of 2-3 actions per building block. // If we run this in parallel, we will have a racing condition when multiple building blocks are drag and dropped quickly. for (const jsAction of jsActions) { - const actionCollection: JSCollection = yield select(getJSCollectionById, { - match: { - params: { - collectionId: jsAction.collectionId, - }, - }, - }); + const actionCollection: JSCollection = yield select( + getJSCollection, + jsAction.collectionId, + ); for (const action of actionCollection.actions) { yield put({ @@ -752,10 +748,10 @@ export function* pasteBuildingBlockWidgetsSaga( ); yield call(updateAndSaveAnvilLayout, updatedWidgets); - const pageId: string = yield select(getCurrentPageId); + const basePageId: string = yield select(getCurrentBasePageId); if (copiedWidgetGroups && copiedWidgetGroups.length > 0) { - history.push(builderURL({ pageId })); + history.push(builderURL({ basePageId })); } yield put({ diff --git a/app/client/src/sagas/BuildingBlockSagas/tests/fixtures.ts b/app/client/src/sagas/BuildingBlockSagas/tests/fixtures.ts index ccfb15c5ea..ce4e9d8c68 100644 --- a/app/client/src/sagas/BuildingBlockSagas/tests/fixtures.ts +++ b/app/client/src/sagas/BuildingBlockSagas/tests/fixtures.ts @@ -105,7 +105,9 @@ export const addEntityAction: ReduxAction = { export const newlyCreatedActions: Action[] = [ { id: "6673f0a0b64fdc719809bf28", + baseId: "6673f0a0b64fdc719809bf29", workspaceId: "6672debbb64fdc719809bf05", + applicationId: "6672debbb64fdc719809b111", cacheResponse: "", pluginType: PluginType.DB, pluginId: "667115877cb2c839782babdd", diff --git a/app/client/src/sagas/CurlImportSagas.ts b/app/client/src/sagas/CurlImportSagas.ts index 8a95b6f6b6..be86baef22 100644 --- a/app/client/src/sagas/CurlImportSagas.ts +++ b/app/client/src/sagas/CurlImportSagas.ts @@ -14,6 +14,7 @@ import transformCurlImport from "transformers/CurlImportTransformer"; import history from "utils/history"; import { CURL } from "constants/AppsmithActionConstants/ActionConstants"; import { apiEditorIdURL } from "@appsmith/RouteBuilder"; +import { convertToBaseParentEntityIdSelector } from "selectors/pageListSelectors"; export function* curlImportSaga(action: ReduxAction) { const { contextId, contextType, name, type } = action.payload; @@ -30,7 +31,8 @@ export function* curlImportSaga(action: ReduxAction) { contextType, }; - const response: ApiResponse = yield CurlImportApi.curlImport(request); + const response: ApiResponse<{ id: string; baseId: string }> = + yield CurlImportApi.curlImport(request); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { @@ -42,10 +44,15 @@ export function* curlImportSaga(action: ReduxAction) { type: ReduxActionTypes.SUBMIT_CURL_FORM_SUCCESS, payload: response.data, }); - + const baseParentEntityId: string = yield select( + convertToBaseParentEntityIdSelector, + contextId, + ); history.push( - // @ts-expect-error: response.data is of type unknown - apiEditorIdURL({ parentEntityId: contextId, apiId: response.data.id }), + apiEditorIdURL({ + baseParentEntityId: baseParentEntityId, + baseApiId: response.data.baseId, + }), ); } } catch (error) { diff --git a/app/client/src/sagas/DatasourcesSagas.ts b/app/client/src/sagas/DatasourcesSagas.ts index 049e752839..8d4970698e 100644 --- a/app/client/src/sagas/DatasourcesSagas.ts +++ b/app/client/src/sagas/DatasourcesSagas.ts @@ -31,6 +31,7 @@ import { } from "@appsmith/constants/ReduxActionConstants"; import { getCurrentApplicationId, + getCurrentBasePageId, getCurrentPageId, } from "selectors/editorSelectors"; import type { DatasourceGroupByPluginCategory } from "@appsmith/selectors/entitiesSelector"; @@ -133,6 +134,7 @@ import OAuthApi from "api/OAuthApi"; import type { AppState } from "@appsmith/reducers"; import { getApplicationByIdFromWorkspaces, + getCurrentApplication, getCurrentApplicationIdForCreateNewApp, getWorkspaceIdForImport, } from "@appsmith/selectors/applicationSelectors"; @@ -289,9 +291,9 @@ export function* addMockDbToDatasources(actionPayload: addMockDb) { getApplicationByIdFromWorkspaces, currentApplicationIdForCreateNewApp || "", ); - const pageId: string = !!currentApplicationIdForCreateNewApp - ? application?.defaultPageId - : yield select(getCurrentPageId); + const basePageId: string = !!currentApplicationIdForCreateNewApp + ? application?.defaultBasePageId + : yield select(getCurrentBasePageId); const response: ApiResponse = yield DatasourcesApi.addMockDbToDatasources( name, @@ -320,7 +322,7 @@ export function* addMockDbToDatasources(actionPayload: addMockDb) { if (isGeneratePageInitiator) { history.push( generateTemplateFormURL({ - pageId, + basePageId, params: { datasourceId: response.data.id, }, @@ -335,7 +337,7 @@ export function* addMockDbToDatasources(actionPayload: addMockDb) { const plugin: Plugin = yield select(getPlugin, response.data.pluginId); if (plugin && plugin.type === PluginType.SAAS) { url = saasEditorDatasourceIdURL({ - pageId, + basePageId, pluginPackageName: plugin.packageName, datasourceId: response.data.id, params: { @@ -344,7 +346,7 @@ export function* addMockDbToDatasources(actionPayload: addMockDb) { }); } else { url = datasourcesEditorIdURL({ - pageId, + basePageId, datasourceId: response.data.id, params: omit(getQueryParams(), "viewMode"), }); @@ -732,6 +734,10 @@ function* getOAuthAccessTokenSaga( toast.show(OAUTH_AUTHORIZATION_APPSMITH_ERROR, { kind: "error", }); + yield put({ + type: ReduxActionTypes.GET_OAUTH_ACCESS_TOKEN_ERROR, + payload: { datasourceId: datasourceId }, + }); return; } try { @@ -782,8 +788,16 @@ function* getOAuthAccessTokenSaga( } // Remove the token because it is supposed to be short lived localStorage.removeItem(APPSMITH_TOKEN_STORAGE_KEY); + yield put({ + type: ReduxActionTypes.GET_OAUTH_ACCESS_TOKEN_SUCCESS, + payload: { datasourceId: datasourceId }, + }); } } catch (e) { + yield put({ + type: ReduxActionTypes.GET_OAUTH_ACCESS_TOKEN_ERROR, + payload: { datasourceId: datasourceId }, + }); toast.show(OAUTH_AUTHORIZATION_FAILED, { kind: "error", }); @@ -1145,7 +1159,11 @@ function* createDatasourceFromFormSaga( payload: response.data, }); yield put( - createDatasourceSuccess(response.data, true, !!actionRouteInfo.apiId), + createDatasourceSuccess( + response.data, + true, + !!actionRouteInfo.baseApiId, + ), ); // Set datasource page to view mode @@ -1183,7 +1201,7 @@ function* createDatasourceFromFormSaga( // for all datasources, except for REST and GraphQL, need to delete temp datasource data // as soon as possible, for REST and GraphQL it is getting deleted in APIPaneSagas.ts - if (!actionRouteInfo.apiId) { + if (!actionRouteInfo.baseApiId) { yield put(removeTempDatasource()); } @@ -1211,7 +1229,6 @@ function* changeDatasourceSaga( const currentApplicationIdForCreateNewApp: string | undefined = yield select( getCurrentApplicationIdForCreateNewApp, ); - const pageId: string = yield select(getCurrentPageId); let data; if (isEmpty(draft)) { data = datasource; @@ -1230,9 +1247,10 @@ function* changeDatasourceSaga( // on create new app onboarding flow, it shouldn't redirect either if (shouldNotRedirect || currentApplicationIdForCreateNewApp) return; // this redirects to the same route, so checking first. + const basePageId: string = yield select(getCurrentBasePageId); const datasourcePath = trimQueryString( datasourcesEditorIdURL({ - pageId, + basePageId, datasourceId: datasource.id, generateEditorPath: true, }), @@ -1241,7 +1259,7 @@ function* changeDatasourceSaga( if (history.location.pathname !== datasourcePath) history.push( datasourcesEditorIdURL({ - pageId, + basePageId, datasourceId: datasource.id, params: getQueryParams(), generateEditorPath: true, @@ -1300,8 +1318,9 @@ function* updateDraftsSaga(form: string) { function* storeAsDatasourceSaga() { const { values } = yield select(getFormData, API_EDITOR_FORM_NAME); - const applicationId: string = yield select(getCurrentApplicationId); - const pageId: string | undefined = yield select(getCurrentPageId); + // const applicationId: string = yield select(getCurrentApplicationId); + const application: ApplicationPayload = yield select(getCurrentApplication); + const basePageId: string | undefined = yield select(getCurrentBasePageId); const moduleId: string | undefined = yield select(getCurrentModuleId); let datasource = get(values, "datasource"); datasource = omit(datasource, ["name"]); @@ -1358,9 +1377,9 @@ function* storeAsDatasourceSaga() { yield put({ type: ReduxActionTypes.STORE_AS_DATASOURCE_UPDATE, payload: { - applicationId, - apiId: values.id, - parentEntityId: pageId || moduleId, + baseApplicationId: application?.baseId, + baseApiId: values.baseId, + baseParentEntityId: basePageId || moduleId, datasourceId: createdDatasource.id, }, }); @@ -1373,7 +1392,7 @@ function* updateDatasourceSuccessSaga(action: UpdateDatasourceSuccessAction) { const actionRouteInfo = get(state, "ui.datasourcePane.actionRouteInfo"); const generateCRUDSupportedPlugin: GenerateCRUDEnabledPluginMap = yield select(getGenerateCRUDEnabledPluginMap); - const pageId: string = yield select(getCurrentPageId); + const basePageId: string = yield select(getCurrentBasePageId); const updatedDatasource = action.payload; const { queryParams = {} } = action; @@ -1389,7 +1408,7 @@ function* updateDatasourceSuccessSaga(action: UpdateDatasourceSuccessAction) { ) { history.push( generateTemplateFormURL({ - pageId, + basePageId, params: { datasourceId: updatedDatasource.id, }, @@ -1402,8 +1421,8 @@ function* updateDatasourceSuccessSaga(action: UpdateDatasourceSuccessAction) { ) { history.push( apiEditorIdURL({ - parentEntityId: actionRouteInfo.parentEntityId || "", - apiId: actionRouteInfo.apiId!, + baseParentEntityId: actionRouteInfo.baseParentEntityId || "", + baseApiId: actionRouteInfo.baseApiId!, }), ); } diff --git a/app/client/src/sagas/GitSyncSagas.ts b/app/client/src/sagas/GitSyncSagas.ts index a390d8c086..4f179fd284 100644 --- a/app/client/src/sagas/GitSyncSagas.ts +++ b/app/client/src/sagas/GitSyncSagas.ts @@ -30,6 +30,8 @@ import GitSyncAPI, { AutocommitResponseEnum } from "api/GitSyncAPI"; import { getCurrentApplicationId, getCurrentPageId, + getCurrentBasePageId, + getCurrentBaseApplicationId, } from "selectors/editorSelectors"; import { validateResponse } from "./ErrorSagas"; import type { @@ -91,7 +93,6 @@ import type { ApiResponse } from "api/ApiResponses"; import type { GitConfig } from "entities/GitSync"; import { GitSyncModalTab } from "entities/GitSync"; import { - getCurrentAppGitMetaData, getCurrentApplication, getWorkspaceIdForImport, } from "@appsmith/selectors/applicationSelectors"; @@ -107,7 +108,6 @@ import { PROTECT_BRANCH_SUCCESS, IMPORT_APP_SUCCESSFUL, } from "@appsmith/constants/messages"; -import type { GitApplicationMetadata } from "@appsmith/api/ApplicationApi"; import history from "utils/history"; import { addBranchParam, GIT_BRANCH_QUERY_KEY } from "constants/routes"; @@ -116,8 +116,8 @@ import { getDisconnectingGitApplication, getGitMetadataSelector, } from "selectors/gitSyncSelectors"; -import { initEditor } from "actions/initActions"; -import { fetchPage } from "actions/pageActions"; +import { initEditorAction } from "actions/initActions"; +import { fetchPageAction } from "actions/pageActions"; import { getLogToSentryFromResponse } from "utils/helpers"; import { getFetchedWorkspaces } from "@appsmith/selectors/workspaceSelectors"; import type { Workspace } from "@appsmith/constants/workspaceConstants"; @@ -164,13 +164,9 @@ function* commitToGitRepoSaga( try { const applicationId: string = yield select(getCurrentApplicationId); - const gitMetaData: GitApplicationMetadata = yield select( - getCurrentAppGitMetaData, - ); response = yield GitSyncAPI.commit({ ...action.payload, - branch: gitMetaData?.branchName || "", - applicationId, + applicationId: applicationId, }); const isValidResponse: boolean = yield validateResponse( @@ -231,9 +227,9 @@ function* connectToGitSaga(action: ConnectToGitReduxAction) { | ApiResponse<{ gitApplicationMetadata: { branchName: string } }> | undefined; try { - const applicationId: string = yield select(getCurrentApplicationId); + const baseApplicationId: string = yield select(getCurrentBaseApplicationId); const currentPageId: string = yield select(getCurrentPageId); - response = yield GitSyncAPI.connect(action.payload, applicationId); + response = yield GitSyncAPI.connect(action.payload, baseApplicationId); const isValidResponse: boolean = yield validateResponse( response, @@ -245,7 +241,7 @@ function* connectToGitSaga(action: ConnectToGitReduxAction) { // @ts-expect-error: response is of type unknown yield put(connectToGitSuccess(response?.data)); - yield put(fetchPage(currentPageId)); + yield put(fetchPageAction(currentPageId)); if (action.onSuccessCallback) { // @ts-expect-error: response is of type unknown action.onSuccessCallback(response?.data); @@ -386,21 +382,18 @@ function* switchBranch(action: ReduxAction) { // Check if page exists in the branch. If not, instead of 404, take them to // the app home page - const page = response.data.pages.find( - (page) => page.id === entityInfo.params.pageId, + const existingPage = response.data.pages.find( + (page) => page.baseId === entityInfo.params.basePageId, ); yield put(setShowBranchPopupAction(false)); yield put({ type: ReduxActionTypes.SWITCH_GIT_BRANCH_SUCCESS }); - - const homePage = response.data.pages.find((page) => page.isDefault); - if (!page) { - if (homePage) { - history.push( - builderURL({ pageId: homePage.id, branch: trimmedBranch }), - ); - return; - } + const defaultPage = response.data.pages.find((page) => page.isDefault); + if (!existingPage && defaultPage) { + history.push( + builderURL({ basePageId: defaultPage.baseId, branch: trimmedBranch }), + ); + return; } // Page exists, so we will try to go to the destination history.push(destinationHref); @@ -428,13 +421,14 @@ function* switchBranch(action: ReduxAction) { } } - if (shouldGoToHomePage) { - if (homePage) { - // We will replace so that the user does not go back to the 404 url - history.replace( - builderURL({ pageId: homePage.id, persistExistingParams: true }), - ); - } + if (shouldGoToHomePage && defaultPage) { + // We will replace so that the user does not go back to the 404 url + history.replace( + builderURL({ + basePageId: defaultPage.baseId, + persistExistingParams: true, + }), + ); } } catch (e) { // non api error @@ -475,8 +469,8 @@ function* fetchBranches(action: ReduxAction<{ pruneBranches: boolean }>) { function* fetchLocalGitConfig() { let response: ApiResponse | undefined; try { - const applicationId: string = yield select(getCurrentApplicationId); - response = yield GitSyncAPI.getLocalConfig(applicationId); + const baseApplicationId: string = yield select(getCurrentBaseApplicationId); + response = yield GitSyncAPI.getLocalConfig(baseApplicationId); const isValidResponse: boolean = yield validateResponse( response, false, @@ -538,8 +532,11 @@ function* updateLocalGitConfig(action: ReduxAction) { let response: ApiResponse | undefined; try { - const applicationId: string = yield select(getCurrentApplicationId); - response = yield GitSyncAPI.setLocalConfig(action.payload, applicationId); + const baseApplicationId: string = yield select(getCurrentBaseApplicationId); + response = yield GitSyncAPI.setLocalConfig( + action.payload, + baseApplicationId, + ); const isValidResponse: boolean = yield validateResponse( response, false, @@ -570,12 +567,8 @@ function* fetchGitStatusSaga(action: ReduxAction) { let response: ApiResponse | undefined; try { const applicationId: string = yield select(getCurrentApplicationId); - const gitMetaData: GitApplicationMetadata = yield select( - getCurrentAppGitMetaData, - ); response = yield GitSyncAPI.getGitStatus({ applicationId, - branch: gitMetaData?.branchName || "", compareRemote: action.payload.compareRemote ?? true, }); const isValidResponse: boolean = yield validateResponse( @@ -700,15 +693,18 @@ function* gitPullSaga( false, getLogToSentryFromResponse(response), ); - const currentBranch: string | undefined = yield select(getCurrentGitBranch); - const currentPageId: string = yield select(getCurrentPageId); if (isValidResponse) { // @ts-expect-error: response is of type unknown const { mergeStatus } = response?.data; yield put(gitPullSuccess(mergeStatus)); + + const currentBasePageId: string = yield select(getCurrentBasePageId); + const currentBranch: string | undefined = + yield select(getCurrentGitBranch); + yield put( - initEditor({ - pageId: currentPageId, + initEditorAction({ + basePageId: currentBasePageId, branch: currentBranch, mode: APP_MODE.EDIT, }), @@ -755,10 +751,9 @@ function* disconnectGitSaga() { id: string; name: string; } = yield select(getDisconnectingGitApplication); - const currentApplicationId: string = yield select(getCurrentApplicationId); - response = yield GitSyncAPI.revokeGit({ - applicationId: application.id, - }); + const applicationId: string = yield select(getCurrentApplicationId); + const baseApplicationId: string = yield select(getCurrentBaseApplicationId); + response = yield GitSyncAPI.revokeGit(baseApplicationId); const isValidResponse: boolean = yield validateResponse( response, false, @@ -783,9 +778,7 @@ function* disconnectGitSaga() { yield put({ type: ReduxActionTypes.FETCH_ALL_APPLICATIONS_OF_WORKSPACE_INIT, }); - - // while disconnecting another application, i.e. not the current one - if (currentApplicationId !== application.id) { + if (applicationId !== application?.id) { yield put( setIsGitSyncModalOpen({ isOpen: true, @@ -832,7 +825,7 @@ function* importAppFromGitSaga(action: ConnectToGitReduxAction) { ); if (currentWorkspace.length > 0) { // @ts-expect-error: response can be undefined - const { application: app, isPartialImport } = response?.data; + const { application, isPartialImport } = response?.data; yield put(importAppViaGitSuccess()); // reset flag for loader yield put(setIsGitSyncModalOpen({ isOpen: false })); // there is configuration-missing datasources @@ -847,17 +840,16 @@ function* importAppFromGitSaga(action: ConnectToGitReduxAction) { }), ); } else { - let pageId = ""; - if (app.pages && app.pages.length > 0) { - const defaultPage = app.pages.find( + let basePageId = ""; + if (application.pages && application.pages.length > 0) { + const defaultPage = application.pages.find( // @ts-expect-error: eachPage is any (eachPage) => !!eachPage.isDefault, ); - pageId = defaultPage ? defaultPage.id : ""; + basePageId = defaultPage ? defaultPage.baseId : ""; } - // TODO: Update URL Params const pageURL = builderURL({ - pageId, + basePageId, }); history.push(pageURL); toast.show(createMessage(IMPORT_APP_SUCCESSFUL), { @@ -897,10 +889,10 @@ function* importAppFromGitSaga(action: ConnectToGitReduxAction) { export function* getSSHKeyPairSaga(action: GetSSHKeyPairReduxAction) { try { - const applicationId: string = yield select(getCurrentApplicationId); + const baseApplicationId: string = yield select(getCurrentBaseApplicationId); const response: ApiResponse = yield call( GitSyncAPI.getSSHKeyPair, - applicationId, + baseApplicationId, ); const isValidResponse: boolean = yield validateResponse(response, false); if (isValidResponse) { @@ -924,13 +916,13 @@ export function* getSSHKeyPairSaga(action: GetSSHKeyPairReduxAction) { export function* generateSSHKeyPairSaga(action: GenerateSSHKeyPairReduxAction) { let response: ApiResponse | undefined; try { - const applicationId: string = yield select(getCurrentApplicationId); + const baseApplicationId: string = yield select(getCurrentBaseApplicationId); const isImporting: string = yield select(getWorkspaceIdForImport); const keyType = action.payload?.keyType || "ECDSA"; response = yield call( GitSyncAPI.generateSSHKeyPair, - applicationId, + baseApplicationId, keyType, !!isImporting, ); @@ -962,9 +954,9 @@ export function* deleteBranch({ payload }: ReduxAction) { const { branchToDelete } = payload; let response: ApiResponse | undefined; try { - const applicationId: string = yield select(getCurrentApplicationId); + const baseApplicationId: string = yield select(getCurrentBaseApplicationId); - response = yield GitSyncAPI.deleteBranch(applicationId, branchToDelete); + response = yield GitSyncAPI.deleteBranch(baseApplicationId, branchToDelete); const isValidResponse: boolean = yield validateResponse( response, false, @@ -987,8 +979,8 @@ function* discardChanges({ }: ReduxAction<{ successToastMessage: string } | null | undefined>) { let response: ApiResponse; try { - const appId: string = yield select(getCurrentApplicationId); - response = yield GitSyncAPI.discardChanges(appId); + const applicationId: string = yield select(getCurrentApplicationId); + response = yield GitSyncAPI.discardChanges(applicationId); const isValidResponse: boolean = yield validateResponse( response, false, @@ -1003,10 +995,10 @@ function* discardChanges({ }); // adding delay to show toast animation before reloading yield delay(500); - const pageId: string = - response.data?.pages?.find((page: any) => page.isDefault)?.id || ""; + const basePageId: string = + response.data?.pages?.find((page: any) => page.isDefault)?.baseId || ""; const branch = response.data.gitApplicationMetadata.branchName; - window.open(builderURL({ pageId, branch }), "_self"); + window.open(builderURL({ basePageId, branch }), "_self"); } else { yield put( discardChangesFailure({ @@ -1023,8 +1015,8 @@ function* discardChanges({ function* fetchGitProtectedBranchesSaga() { let response: ApiResponse; try { - const appId: string = yield select(getCurrentApplicationId); - response = yield GitSyncAPI.getProtectedBranches(appId); + const baseApplicationId: string = yield select(getCurrentBaseApplicationId); + response = yield GitSyncAPI.getProtectedBranches(baseApplicationId); const isValidResponse: boolean = yield validateResponse( response, @@ -1058,12 +1050,12 @@ function* updateGitProtectedBranchesSaga({ payload, }: ReduxAction<{ protectedBranches: string[] }>) { const { protectedBranches } = payload; - const applicationId: string = yield select(getCurrentApplicationId); + const baseApplicationId: string = yield select(getCurrentBaseApplicationId); let response: ApiResponse; try { response = yield call( GitSyncAPI.updateProtectedBranches, - applicationId, + baseApplicationId, protectedBranches, ); const isValidResponse: boolean = yield validateResponse( @@ -1097,10 +1089,10 @@ function* updateGitProtectedBranchesSaga({ } function* toggleAutocommitSaga() { - const applicationId: string = yield select(getCurrentApplicationId); + const baseApplicationId: string = yield select(getCurrentBaseApplicationId); let response: ApiResponse; try { - response = yield call(GitSyncAPI.toggleAutocommit, applicationId); + response = yield call(GitSyncAPI.toggleAutocommit, baseApplicationId); const isValidResponse: boolean = yield validateResponse( response, false, @@ -1138,10 +1130,10 @@ function* toggleAutocommitSaga() { } function* getGitMetadataSaga() { - const applicationId: string = yield select(getCurrentApplicationId); + const baseApplicationId: string = yield select(getCurrentBaseApplicationId); let response: ApiResponse; try { - response = yield call(GitSyncAPI.getGitMetadata, applicationId); + response = yield call(GitSyncAPI.getGitMetadata, baseApplicationId); const isValidResponse: boolean = yield validateResponse( response, false, @@ -1187,15 +1179,11 @@ function isAutocommitHappening( function* pollAutocommitProgressSaga(): any { const applicationId: string = yield select(getCurrentApplicationId); - const branchName: string = yield select(getCurrentGitBranch); + const baseApplicationId: string = yield select(getCurrentBaseApplicationId); let triggerResponse: ApiResponse | undefined; try { - const res = yield call( - GitSyncAPI.triggerAutocommit, - applicationId, - branchName, - ); + const res = yield call(GitSyncAPI.triggerAutocommit, applicationId); const isValidResponse: boolean = yield validateResponse( res, false, @@ -1221,7 +1209,7 @@ function* pollAutocommitProgressSaga(): any { yield put(startAutocommitProgressPollingAction()); while (true) { const progressResponse: ApiResponse = - yield call(GitSyncAPI.getAutocommitProgress, applicationId); + yield call(GitSyncAPI.getAutocommitProgress, baseApplicationId); const isValidResponse: boolean = yield validateResponse( progressResponse, false, diff --git a/app/client/src/sagas/GlobalSearchSagas.ts b/app/client/src/sagas/GlobalSearchSagas.ts index 2f50403ae8..3131a17f10 100644 --- a/app/client/src/sagas/GlobalSearchSagas.ts +++ b/app/client/src/sagas/GlobalSearchSagas.ts @@ -23,6 +23,7 @@ import type { RecentEntity } from "components/editorComponents/GlobalSearch/util import log from "loglevel"; import { getCurrentGitBranch } from "selectors/gitSyncSelectors"; import type { FocusEntity, FocusEntityInfo } from "navigation/FocusEntity"; +import { convertToPageIdSelector } from "selectors/pageListSelectors"; const getRecentEntitiesKey = (applicationId: string, branch?: string) => branch ? `${applicationId}-${branch}` : applicationId; @@ -55,8 +56,12 @@ export function* updateRecentEntitySaga(entityInfo: FocusEntityInfo) { const { entity, id, - params: { pageId }, + params: { basePageId }, } = entityInfo; + const pageId: string = yield select( + convertToPageIdSelector, + basePageId ?? "", + ); let recentEntities: RecentEntity[] = yield select( (state: AppState) => state.ui.globalSearch.recentEntities, ); @@ -67,7 +72,12 @@ export function* updateRecentEntitySaga(entityInfo: FocusEntityInfo) { (recentEntity: { type: FocusEntity; id: string }) => recentEntity.id !== id, ); - recentEntities.unshift({ type: entity, id, pageId }); + + recentEntities.unshift({ + type: entity, + id, + pageId, + }); recentEntities = recentEntities.slice(0, 6); yield put(setRecentEntities(recentEntities)); diff --git a/app/client/src/sagas/IDESaga.tsx b/app/client/src/sagas/IDESaga.tsx index c1956e99bc..7526a8033e 100644 --- a/app/client/src/sagas/IDESaga.tsx +++ b/app/client/src/sagas/IDESaga.tsx @@ -15,7 +15,6 @@ import { queryListURL, } from "@appsmith/RouteBuilder"; import type { EntityItem } from "@appsmith/entities/IDE/constants"; -import { getCurrentPageId } from "@appsmith/selectors/entitiesSelector"; import { getQueryEntityItemUrl } from "@appsmith/pages/Editor/IDE/EditorPane/Query/utils"; import { getJSEntityItemUrl } from "@appsmith/pages/Editor/IDE/EditorPane/JS/utils"; import log from "loglevel"; @@ -27,17 +26,18 @@ import { selectJSSegmentEditorTabs, selectQuerySegmentEditorTabs, } from "@appsmith/selectors/appIDESelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; export function* updateIDETabsOnRouteChangeSaga(entityInfo: FocusEntityInfo) { const { entity, id, params } = entityInfo; - if (!params.pageId) return; + if (!params.basePageId) return; if ( entity === FocusEntity.JS_OBJECT || entity === FocusEntity.JS_MODULE_INSTANCE ) { const jsTabs: string[] = yield select(getJSTabs); const newTabs: string[] = yield call(getUpdatedTabs, id, jsTabs); - yield put(setJSTabs(newTabs, params.pageId)); + yield put(setJSTabs(newTabs, params.basePageId)); } if ( entity === FocusEntity.QUERY || @@ -45,7 +45,7 @@ export function* updateIDETabsOnRouteChangeSaga(entityInfo: FocusEntityInfo) { ) { const queryTabs: string[] = yield select(getQueryTabs); const newTabs: string[] = yield call(getUpdatedTabs, id, queryTabs); - yield put(setQueryTabs(newTabs, params.pageId)); + yield put(setQueryTabs(newTabs, params.basePageId)); } } @@ -56,41 +56,41 @@ function* getUpdatedTabs(newId: string, currentTabs: string[]) { } export function* handleJSEntityRedirect(deletedId: string) { - const pageId: string = yield select(getCurrentPageId); + const basePageId: string = yield select(getCurrentBasePageId); const jsTabs: EntityItem[] = yield select(selectJSSegmentEditorTabs); const redirectAction = getNextEntityAfterRemove(deletedId, jsTabs); switch (redirectAction.action) { case RedirectAction.LIST: - history.push(jsCollectionListURL({ pageId })); + history.push(jsCollectionListURL({ basePageId })); break; case RedirectAction.ITEM: if (!redirectAction.payload) { log.error("Redirect item does not have a payload"); - history.push(jsCollectionAddURL({ pageId })); + history.push(jsCollectionAddURL({ basePageId })); break; } const { payload } = redirectAction; - history.push(getJSEntityItemUrl(payload, pageId)); + history.push(getJSEntityItemUrl(payload, basePageId)); break; } } export function* handleQueryEntityRedirect(deletedId: string) { - const pageId: string = yield select(getCurrentPageId); + const basePageId: string = yield select(getCurrentBasePageId); const queryTabs: EntityItem[] = yield select(selectQuerySegmentEditorTabs); const redirectAction = getNextEntityAfterRemove(deletedId, queryTabs); switch (redirectAction.action) { case RedirectAction.LIST: - history.push(queryListURL({ pageId })); + history.push(queryListURL({ basePageId })); break; case RedirectAction.ITEM: if (!redirectAction.payload) { - history.push(queryAddURL({ pageId })); + history.push(queryAddURL({ basePageId })); log.error("Redirect item does not have a payload"); break; } const { payload } = redirectAction; - history.push(getQueryEntityItemUrl(payload, pageId)); + history.push(getQueryEntityItemUrl(payload, basePageId)); break; } } diff --git a/app/client/src/sagas/InitSagas.ts b/app/client/src/sagas/InitSagas.ts index f6081ce828..49715bba6e 100644 --- a/app/client/src/sagas/InitSagas.ts +++ b/app/client/src/sagas/InitSagas.ts @@ -26,8 +26,8 @@ import * as Sentry from "@sentry/react"; import { resetRecentEntities } from "actions/globalSearchActions"; import { - initAppViewer, - initEditor, + initAppViewerAction, + initEditorAction, resetEditorSuccess, } from "actions/initActions"; import { @@ -204,12 +204,12 @@ function* executeActionDuringUserDetailsInitialisation( export function* getInitResponses({ applicationId, + basePageId, mode, - pageId, shouldInitialiseUserDetails, }: { applicationId?: string; - pageId?: string; + basePageId?: string; branch?: string; mode?: APP_MODE; shouldInitialiseUserDetails?: boolean; @@ -217,7 +217,7 @@ export function* getInitResponses({ const params = pickBy( { applicationId, - defaultPageId: pageId, + defaultPageId: basePageId, }, identity, ); @@ -255,13 +255,12 @@ export function* getInitResponses({ ReduxActionTypes.END_CONSOLIDATED_PAGE_LOAD, shouldInitialiseUserDetails, ); - Sentry.captureMessage( `consolidated api failure for ${JSON.stringify( params, )} errored message response ${e}`, ); - throw new PageNotFoundError(`Cannot find page with id: ${pageId}`); + throw new PageNotFoundError(`Cannot find page with base id: ${basePageId}`); } const { featureFlags, productAlert, tenantConfig, userProfile, ...rest } = @@ -291,7 +290,7 @@ export function* getInitResponses({ export function* startAppEngine(action: ReduxAction) { const rootSpan = startRootSpan("startAppEngine", { mode: action.payload.mode, - pageId: action.payload.pageId, + pageId: action.payload.basePageId, applicationId: action.payload.applicationId, branch: action.payload.branch, }); @@ -316,8 +315,7 @@ export function* startAppEngine(action: ReduxAction) { endSpan(getInitResponsesSpan); yield put({ type: ReduxActionTypes.LINT_SETUP }); - - const { applicationId, toLoadPageId } = yield call( + const { applicationId, toLoadBasePageId, toLoadPageId } = yield call( engine.loadAppData, action.payload, allResponses, @@ -325,8 +323,8 @@ export function* startAppEngine(action: ReduxAction) { ); yield call(engine.loadAppURL, { - pageId: toLoadPageId, - pageIdInUrl: action.payload.pageId, + basePageId: toLoadBasePageId, + basePageIdInUrl: action.payload.basePageId, rootSpan, }); @@ -433,14 +431,14 @@ function* eagerPageInitSaga() { const matchedEditorParams = matchEditorPath(url); if (matchedEditorParams) { const { - params: { applicationId, pageId }, + params: { baseApplicationId, basePageId }, } = matchedEditorParams; const branch = getSearchQuery(search, GIT_BRANCH_QUERY_KEY); - if (pageId) { + if (basePageId) { yield put( - initEditor({ - pageId, - applicationId, + initEditorAction({ + basePageId, + baseApplicationId, branch, mode: APP_MODE.EDIT, shouldInitialiseUserDetails: true, @@ -453,15 +451,15 @@ function* eagerPageInitSaga() { const matchedViewerParams = matchViewerPath(url); if (matchedViewerParams) { const { - params: { applicationId, pageId }, + params: { baseApplicationId, basePageId }, } = matchedViewerParams; const branch = getSearchQuery(search, GIT_BRANCH_QUERY_KEY); - if (applicationId || pageId) { + if (baseApplicationId || basePageId) { yield put( - initAppViewer({ - applicationId, + initAppViewerAction({ + baseApplicationId, branch, - pageId, + basePageId, mode: APP_MODE.PUBLISHED, shouldInitialiseUserDetails: true, }), diff --git a/app/client/src/sagas/JSPaneSagas.ts b/app/client/src/sagas/JSPaneSagas.ts index 9990f3dd4d..382734aba2 100644 --- a/app/client/src/sagas/JSPaneSagas.ts +++ b/app/client/src/sagas/JSPaneSagas.ts @@ -102,6 +102,7 @@ import { getIsSideBySideEnabled } from "selectors/ideSelectors"; import { setIdeEditorViewMode } from "actions/ideActions"; import { EditorViewMode } from "@appsmith/entities/IDE/constants"; import { updateJSCollectionAPICall } from "@appsmith/sagas/ApiCallerSagas"; +import { convertToBasePageIdSelector } from "selectors/pageListSelectors"; export interface GenerateDefaultJSObjectProps { name: string; @@ -186,11 +187,12 @@ export function* generateDefaultJSObject({ function* handleJSCollectionCreatedSaga( actionPayload: ReduxAction, ) { - const { id, pageId } = actionPayload.payload; + const { baseId: baseCollectionId, pageId } = actionPayload.payload; + const basePageId: string = yield select(convertToBasePageIdSelector, pageId); history.push( jsCollectionIdURL({ - pageId, - collectionId: id, + basePageId, + baseCollectionId, params: { editName: true, }, @@ -385,10 +387,14 @@ function* handleJSObjectNameChangeSuccessSaga( if (params.editName) { params.editName = "false"; } + const basePageId: string = yield select( + convertToBasePageIdSelector, + actionObj.pageId, + ); history.push( jsCollectionIdURL({ - pageId: actionObj.pageId, - collectionId: actionId, + basePageId, + baseCollectionId: actionObj.baseId, params, }), ); diff --git a/app/client/src/sagas/OnboardingSagas.ts b/app/client/src/sagas/OnboardingSagas.ts index 8f5abb4eff..0951862ce7 100644 --- a/app/client/src/sagas/OnboardingSagas.ts +++ b/app/client/src/sagas/OnboardingSagas.ts @@ -88,7 +88,7 @@ function* endFirstTimeUserOnboardingSaga() { function* firstTimeUserOnboardingInitSaga( action: ReduxAction<{ applicationId: string; - pageId: string; + basePageId: string; suffix?: string; }>, ) { @@ -99,7 +99,7 @@ function* firstTimeUserOnboardingInitSaga( }); history.replace( builderURL({ - pageId: action.payload.pageId, + basePageId: action.payload.basePageId, suffix: action.payload.suffix || "", }), ); diff --git a/app/client/src/sagas/QueryPaneSagas.ts b/app/client/src/sagas/QueryPaneSagas.ts index 7f6a4f1d86..ea1a7b114a 100644 --- a/app/client/src/sagas/QueryPaneSagas.ts +++ b/app/client/src/sagas/QueryPaneSagas.ts @@ -25,7 +25,7 @@ import { } from "@appsmith/constants/forms"; import history from "utils/history"; import { APPLICATIONS_URL, INTEGRATION_TABS } from "constants/routes"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import { autofill, change, initialize, reset } from "redux-form"; import { getAction, @@ -36,6 +36,7 @@ import { getSettingConfig, getPlugins, getGenerateCRUDEnabledPluginMap, + getActionByBaseId, } from "@appsmith/selectors/entitiesSelector"; import type { Action, QueryAction } from "entities/Action"; import { PluginType } from "entities/Action"; @@ -91,23 +92,37 @@ import { } from "@appsmith/selectors/applicationSelectors"; import { TEMP_DATASOURCE_ID } from "constants/Datasource"; import { doesPluginRequireDatasource } from "@appsmith/entities/Engine/actionHelpers"; +import { convertToBasePageIdSelector } from "selectors/pageListSelectors"; // Called whenever the query being edited is changed via the URL or query pane function* changeQuerySaga(actionPayload: ReduxAction) { - const { applicationId, id, moduleId, packageId, pageId, workflowId } = - actionPayload.payload; + const { + applicationId, + basePageId, + baseQueryId, + moduleId, + packageId, + workflowId, + } = actionPayload.payload; let configInitialValues = {}; - if (!(packageId && moduleId) && !(applicationId && pageId) && !workflowId) { + if ( + !(packageId && moduleId) && + !(applicationId && basePageId) && + !workflowId + ) { history.push(APPLICATIONS_URL); return; } - const action: Action | undefined = yield select(getAction, id); + const action: Action | undefined = yield select( + getActionByBaseId, + baseQueryId, + ); if (!action) { - if (pageId) { + if (basePageId) { history.push( integrationEditorURL({ - pageId, + basePageId, selectedTab: INTEGRATION_TABS.ACTIVE, }), ); @@ -122,7 +137,9 @@ function* changeQuerySaga(actionPayload: ReduxAction) { // Update the evaluations when the queryID is changed by changing the // URL or selecting new query from the query pane - yield put(initFormEvaluations(currentEditorConfig, currentSettingConfig, id)); + yield put( + initFormEvaluations(currentEditorConfig, currentSettingConfig, action.id), + ); const allPlugins: Plugin[] = yield select(getPlugins); let uiComponent = UIComponentTypes.DbEditorForm; @@ -157,7 +174,7 @@ function* changeQuerySaga(actionPayload: ReduxAction) { // Once the initial values are set, we can run the evaluations based on them. yield put( startFormEvaluations( - id, + action.id, formInitialValues.actionConfiguration, //@ts-expect-error: id does not exists action.datasource.id, @@ -353,8 +370,13 @@ function* formValueChangeSaga( } function* handleQueryCreatedSaga(actionPayload: ReduxAction) { - const { actionConfiguration, id, pageId, pluginId, pluginType } = - actionPayload.payload; + const { + actionConfiguration, + baseId: baseActionId, + pageId, + pluginId, + pluginType, + } = actionPayload.payload; if ( ![ PluginType.DB, @@ -373,10 +395,12 @@ function* handleQueryCreatedSaga(actionPayload: ReduxAction) { !!actionConfiguration.formData?.body || isEmpty(queryTemplate) ); + + const basePageId: string = yield select(convertToBasePageIdSelector, pageId); history.replace( queryEditorIdURL({ - pageId, - queryId: id, + basePageId, + baseQueryId: baseActionId, params: { editName: "true", showTemplate, @@ -407,9 +431,9 @@ function* handleDatasourceCreatedSaga( getApplicationByIdFromWorkspaces, currentApplicationIdForCreateNewApp || "", ); - const pageId: string = !!currentApplicationIdForCreateNewApp - ? application?.defaultPageId - : yield select(getCurrentPageId); + const basePageId: string = !!currentApplicationIdForCreateNewApp + ? application?.defaultBasePageId + : yield select(getCurrentBasePageId); yield put(initialize(DATASOURCE_DB_FORM, omit(payload, "name"))); @@ -434,7 +458,7 @@ function* handleDatasourceCreatedSaga( ) { history.push( generateTemplateFormURL({ - pageId, + basePageId, params: { datasourceId: updatedDatasource.id, }, @@ -446,7 +470,7 @@ function* handleDatasourceCreatedSaga( ) { history.push( datasourcesEditorIdURL({ - pageId, + basePageId, datasourceId: payload.id, params: { from: "datasources", @@ -491,10 +515,14 @@ function* handleNameChangeSuccessSaga( if (params.editName) { params.editName = "false"; } + const basePageId: string = yield select( + convertToBasePageIdSelector, + actionObj.pageId, + ); history.replace( queryEditorIdURL({ - pageId: actionObj.pageId, - queryId: actionId, + basePageId, + baseQueryId: actionObj.baseId, params, }), ); diff --git a/app/client/src/sagas/RecentEntitiesSagas.ts b/app/client/src/sagas/RecentEntitiesSagas.ts index 0d40e40210..8b00c25c6a 100644 --- a/app/client/src/sagas/RecentEntitiesSagas.ts +++ b/app/client/src/sagas/RecentEntitiesSagas.ts @@ -14,7 +14,7 @@ export const getEntityInCurrentPath = (pathName: string) => { if (builderMatch) return { type: "page", - id: builderMatch?.params?.pageId, + id: builderMatch?.params?.basePageId, params: builderMatch?.params, pageType: "canvas", }; @@ -22,7 +22,7 @@ export const getEntityInCurrentPath = (pathName: string) => { const baseMatch = matchBasePath(pathName); if (!baseMatch) return { type: "", id: "" }; const { path: basePath } = baseMatch; - const apiMatch = matchPath<{ apiId: string }>(pathName, { + const apiMatch = matchPath<{ baseApiId: string }>(pathName, { path: [ `${basePath}${API_EDITOR_ID_PATH}`, `${basePath}${SAAS_EDITOR_API_ID_PATH}`, @@ -31,18 +31,18 @@ export const getEntityInCurrentPath = (pathName: string) => { if (apiMatch) return { type: "action", - id: apiMatch?.params?.apiId, + id: apiMatch?.params?.baseApiId, params: apiMatch?.params, pageType: "apiEditor", }; - const queryMatch = matchPath<{ queryId: string }>(pathName, { + const queryMatch = matchPath<{ baseQueryId: string }>(pathName, { path: `${basePath}${QUERIES_EDITOR_ID_PATH}`, }); if (queryMatch) return { type: "action", - id: queryMatch.params?.queryId, + id: queryMatch.params?.baseQueryId, params: queryMatch?.params, pageType: "queryEditor", }; @@ -58,13 +58,13 @@ export const getEntityInCurrentPath = (pathName: string) => { pageType: "datasourceEditor", }; - const jsObjectMatch = matchPath<{ collectionId: string }>(pathName, { + const jsObjectMatch = matchPath<{ baseCollectionId: string }>(pathName, { path: `${basePath}${JS_COLLECTION_ID_PATH}`, }); if (jsObjectMatch) { return { type: "jsAction", - id: jsObjectMatch?.params?.collectionId, + id: jsObjectMatch?.params?.baseCollectionId, params: jsObjectMatch?.params, pageType: "jsEditor", }; diff --git a/app/client/src/sagas/SaaSPaneSagas.ts b/app/client/src/sagas/SaaSPaneSagas.ts index 04558f9fe1..aca6985705 100644 --- a/app/client/src/sagas/SaaSPaneSagas.ts +++ b/app/client/src/sagas/SaaSPaneSagas.ts @@ -17,7 +17,7 @@ import { saasEditorApiIdURL, saasEditorDatasourceIdURL, } from "@appsmith/RouteBuilder"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import type { CreateDatasourceSuccessAction } from "actions/datasourceActions"; import { getQueryParams } from "utils/URLUtils"; import { getIsGeneratePageInitiator } from "utils/GenerateCrudUtil"; @@ -29,6 +29,7 @@ import { getCurrentApplicationIdForCreateNewApp, } from "@appsmith/selectors/applicationSelectors"; import { TEMP_DATASOURCE_ID } from "constants/Datasource"; +import { convertToBasePageIdSelector } from "selectors/pageListSelectors"; function* handleDatasourceCreatedSaga( actionPayload: CreateDatasourceSuccessAction, @@ -47,9 +48,9 @@ function* handleDatasourceCreatedSaga( getApplicationByIdFromWorkspaces, currentApplicationIdForCreateNewApp || "", ); - const pageId: string = !!currentApplicationIdForCreateNewApp - ? application?.defaultPageId - : yield select(getCurrentPageId); + const basePageId: string = !!currentApplicationIdForCreateNewApp + ? application?.defaultBasePageId + : yield select(getCurrentBasePageId); yield put(initialize(DATASOURCE_SAAS_FORM, omit(payload, "name"))); @@ -74,7 +75,7 @@ function* handleDatasourceCreatedSaga( ) { history.push( generateTemplateFormURL({ - pageId, + basePageId, params: { datasourceId: updatedDatasource.id, }, @@ -86,7 +87,7 @@ function* handleDatasourceCreatedSaga( ) { history.push( saasEditorDatasourceIdURL({ - pageId, + basePageId, pluginPackageName: plugin.packageName, datasourceId: payload.id, params: { @@ -100,16 +101,17 @@ function* handleDatasourceCreatedSaga( } function* handleActionCreatedSaga(actionPayload: ReduxAction) { - const { id, pageId, pluginId } = actionPayload.payload; + const { baseId: baseActionId, pageId, pluginId } = actionPayload.payload; const plugin: Plugin | undefined = yield select(getPlugin, pluginId); if (!plugin) return; if (plugin.type !== "SAAS") return; + const basePageId: string = yield select(convertToBasePageIdSelector, pageId); history.push( saasEditorApiIdURL({ - pageId, + basePageId, pluginPackageName: plugin.packageName, - apiId: id, + baseApiId: baseActionId, params: { editName: "true", from: "datasources", diff --git a/app/client/src/sagas/SnapshotSagas.ts b/app/client/src/sagas/SnapshotSagas.ts index 2d330679a9..38d44585ec 100644 --- a/app/client/src/sagas/SnapshotSagas.ts +++ b/app/client/src/sagas/SnapshotSagas.ts @@ -98,9 +98,11 @@ function* restoreApplicationFromSnapshotSaga() { payload: { pages: response.data.pages.map((page: PageDefaultMeta) => ({ pageId: page.id, + basePageId: page.baseId, isDefault: page.isDefault, })), applicationId, + baseApplicationId: response.data.baseId, }, }); } diff --git a/app/client/src/sagas/TemplatesSagas.ts b/app/client/src/sagas/TemplatesSagas.ts index bada303d40..aee392cd3b 100644 --- a/app/client/src/sagas/TemplatesSagas.ts +++ b/app/client/src/sagas/TemplatesSagas.ts @@ -12,7 +12,7 @@ import { ReduxActionTypes, } from "@appsmith/constants/ReduxActionConstants"; import urlBuilder from "@appsmith/entities/URLRedirect/URLAssembly"; -import { getDefaultPageId } from "@appsmith/sagas/ApplicationSagas"; +import { findDefaultPage } from "@appsmith/sagas/ApplicationSagas"; import { fetchPageDSLSaga } from "@appsmith/sagas/PageSagas"; import { getCurrentWorkspaceId } from "@appsmith/selectors/selectedWorkspaceSelectors"; import { isAirgapped } from "@appsmith/utils/airgapHelpers"; @@ -47,7 +47,7 @@ import { } from "utils/storage"; import { validateResponse } from "./ErrorSagas"; import { failFastApiCalls } from "./InitSagas"; -import { getAllPageIds } from "./selectors"; +import { getAllPageIdentities } from "./selectors"; const isAirgappedInstance = isAirgapped(); @@ -84,11 +84,11 @@ function* importTemplateToWorkspaceSaga( ); const isValid: boolean = yield validateResponse(response); if (isValid) { + const defaultPage = findDefaultPage(response.data.application.pages); const application: ApplicationPayload = { ...response.data.application, - defaultPageId: getDefaultPageId( - response.data.application.pages, - ) as string, + defaultPageId: defaultPage?.id, + defaultBasePageId: defaultPage?.baseId, }; yield put({ type: ReduxActionTypes.IMPORT_TEMPLATE_TO_WORKSPACE_SUCCESS, @@ -106,7 +106,7 @@ function* importTemplateToWorkspaceSaga( ); } else { const pageURL = builderURL({ - pageId: application.defaultPageId, + basePageId: application.defaultBasePageId, }); history.push(pageURL); } @@ -267,7 +267,9 @@ function* apiCallForForkTemplateToApplicaion( : undefined; const applicationId: string = yield select(getCurrentApplicationId); const workspaceId: string = yield select(getCurrentWorkspaceId); - const prevPageIds: string[] = yield select(getAllPageIds); + const prevPages: { pageId: string; basePageId: string }[] = + yield select(getAllPageIdentities); + const prevPageIds = prevPages.map((page) => page.pageId); const response: ImportTemplateResponse = yield call( TemplatesAPI.importTemplateToApplication, action.payload.templateId, @@ -285,10 +287,12 @@ function* apiCallForForkTemplateToApplicaion( const isValid: boolean = yield validateResponse(response); if (isValid) { yield call(postPageAdditionSaga, applicationId); - const pages: string[] = yield select(getAllPageIds); - const templatePageIds: string[] = pages.filter( - (pageId) => !prevPageIds.includes(pageId), - ); + const pages: { pageId: string; basePageId: string }[] = + yield select(getAllPageIdentities); + const templatePageIds: string[] = pages + .filter((page) => !prevPageIds.includes(page.pageId)) + .map((page) => page.pageId); + const pageDSLs: unknown = yield all( templatePageIds.map((pageId: string) => { return call(fetchPageDSLSaga, pageId); @@ -310,13 +314,13 @@ function* apiCallForForkTemplateToApplicaion( application: response.data.application, unConfiguredDatasourceList: response.data.unConfiguredDatasourceList, workspaceId, - pageId: pages[0], + pageId: pages[0].pageId, }), ); } history.push( builderURL({ - pageId: pages[0], + basePageId: pages[0].basePageId, }), ); yield take(ReduxActionTypes.UPDATE_CANVAS_STRUCTURE); @@ -377,17 +381,17 @@ function* forkTemplateToApplicationViaOnboardingFlowSaga( { applicationSlug: application.slug, applicationVersion: application.applicationVersion, - applicationId: application.id, + baseApplicationId: application.baseId, }, application.pages.map((page) => ({ pageSlug: page.slug, customSlug: page.customSlug, - pageId: page.id, + basePageId: page.baseId, })), ); history.push( builderURL({ - pageId: application.pages[0].id, + basePageId: application.pages[0].id, }), ); diff --git a/app/client/src/sagas/WidgetOperationSagas.tsx b/app/client/src/sagas/WidgetOperationSagas.tsx index 923bb1b9f9..7a1e005bec 100644 --- a/app/client/src/sagas/WidgetOperationSagas.tsx +++ b/app/client/src/sagas/WidgetOperationSagas.tsx @@ -52,7 +52,7 @@ import { } from "redux-saga/effects"; import { getCanvasWidth, - getCurrentPageId, + getCurrentBasePageId, getIsAutoLayout, getIsAutoLayoutMobileBreakPoint, } from "selectors/editorSelectors"; @@ -1605,10 +1605,10 @@ function* pasteWidgetSaga(action: ReduxAction) { ); yield call(updateAndSaveAnvilLayout, updatedWidgets); - const pageId: string = yield select(getCurrentPageId); + const basePageId: string = yield select(getCurrentBasePageId); if (copiedWidgetGroups && copiedWidgetGroups.length > 0) { - history.push(builderURL({ pageId })); + history.push(builderURL({ basePageId })); } yield put({ diff --git a/app/client/src/sagas/WidgetSelectionSagas.ts b/app/client/src/sagas/WidgetSelectionSagas.ts index ab2d5fb154..196d2d31d4 100644 --- a/app/client/src/sagas/WidgetSelectionSagas.ts +++ b/app/client/src/sagas/WidgetSelectionSagas.ts @@ -36,7 +36,7 @@ import { unselectWidget, } from "sagas/WidgetSelectUtils"; import { - getCurrentPageId, + getCurrentBasePageId, getIsEditorInitialized, getIsFetchingPage, snipingModeSelector, @@ -67,8 +67,8 @@ import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors"; function* selectWidgetSaga(action: ReduxAction) { try { const { + basePageId, invokedBy, - pageId, payload = [], selectionRequestType, } = action.payload; @@ -193,7 +193,7 @@ function* selectWidgetSaga(action: ReduxAction) { appendSelectedWidgetToUrlSaga, newSelection, selectionRequestType, - pageId, + basePageId, invokedBy, ); } catch (error) { @@ -211,13 +211,13 @@ function* selectWidgetSaga(action: ReduxAction) { * Append Selected widgetId as hash to the url path * @param selectedWidgets * @param type - * @param pageId + * @param basePageId * @param invokedBy */ function* appendSelectedWidgetToUrlSaga( selectedWidgets: string[], type: SelectionRequestType, - pageId?: string, + basePageId?: string, invokedBy?: NavigationMethod, ) { const isSnipingMode: boolean = yield select(snipingModeSelector); @@ -229,17 +229,17 @@ function* appendSelectedWidgetToUrlSaga( if (isSnipingMode || viewMode) return; const { pathname } = window.location; - const currentPageId: string = yield select(getCurrentPageId); + const currentBasePageId: string = yield select(getCurrentBasePageId); const currentURL = pathname; const newUrl = selectedWidgets.length ? widgetURL({ - pageId: pageId ?? currentPageId, + basePageId: basePageId ?? currentBasePageId, persistExistingParams: true, add: type === SelectionRequestType.Create, selectedWidgets, }) : widgetURL({ - pageId: pageId ?? currentPageId, + basePageId: basePageId ?? currentBasePageId, persistExistingParams: true, selectedWidgets: [MAIN_CONTAINER_WIDGET_ID], }); diff --git a/app/client/src/sagas/__tests__/ApiPaneSagas.test.ts b/app/client/src/sagas/__tests__/ApiPaneSagas.test.ts index 5d3591d6d6..e116454494 100644 --- a/app/client/src/sagas/__tests__/ApiPaneSagas.test.ts +++ b/app/client/src/sagas/__tests__/ApiPaneSagas.test.ts @@ -67,8 +67,8 @@ describe("handleDatasourceCreatedSaga", () => { }); it("should pass parentEntityId to apiEditorIdURL and redirect to correct url when in app", async () => { - const applicationId = "app-id"; - const pageId = "669e868199b66f0d2176fc1d"; + const baseApplicationId = "app-id"; + const basePageId = "669e868199b66f0d2176fc1d"; const store = testStore({ entities: { ...({} as any), @@ -78,10 +78,10 @@ describe("handleDatasourceCreatedSaga", () => { ...({} as any), datasourcePane: { actionRouteInfo: { - apiId: "api-id", - applicationId, + baseApiId: "api-id", + baseApplicationId, datasourceId: "ds-id", - parentEntityId: pageId, + baseParentEntityId: basePageId, }, }, }, @@ -91,14 +91,14 @@ describe("handleDatasourceCreatedSaga", () => { const spy = jest.spyOn(history, "push").mockImplementation(jest.fn()); const channel = stdChannel(); const appParams = { - applicationId, + baseApplicationId, applicationSlug: "app-slug", ApplicationVersion: "1", }; const pageParams = [ { - pageId, + basePageId, pageSlug: "page-slug", }, ]; @@ -132,7 +132,7 @@ describe("handleDatasourceCreatedSaga", () => { await new Promise((resolve) => setTimeout(resolve, 3000)); expect(history.push).toHaveBeenCalledWith( - `/app/app-slug/page-slug-${pageId}/edit/api/api-id`, + `/app/app-slug/page-slug-${basePageId}/edit/api/api-id`, ); spy.mockReset(); diff --git a/app/client/src/sagas/__tests__/initSagas.test.ts b/app/client/src/sagas/__tests__/initSagas.test.ts index 4b365b9d98..557b9e6fb9 100644 --- a/app/client/src/sagas/__tests__/initSagas.test.ts +++ b/app/client/src/sagas/__tests__/initSagas.test.ts @@ -27,11 +27,13 @@ jest.mock("entities/Engine/factory", () => ({ })); describe("tests the sagas in initSagas", () => { + const pageId = "pageId"; + const basePageId = "basePageId"; const action: ReduxAction = { type: ReduxActionTypes.INITIALIZE_EDITOR, payload: { mode: APP_MODE.EDIT, - pageId: "pageId", + basePageId: basePageId, applicationId: "applicationId", }, }; @@ -42,7 +44,8 @@ describe("tests the sagas in initSagas", () => { setupEngine: jest.fn(), loadAppData: jest.fn().mockResolvedValue({ applicationId: action.payload.applicationId, - toLoadPageId: action.payload.pageId, + toLoadPageId: pageId, + toLoadBasePageId: action.payload.basePageId, }), loadAppURL: jest.fn(), loadAppEntities: jest.fn(), @@ -66,17 +69,18 @@ describe("tests the sagas in initSagas", () => { .call(engine.loadAppData, action.payload, mockResponse.data, mockRootSpan) .next({ applicationId: action.payload.applicationId, - toLoadPageId: action.payload.pageId, + toLoadPageId: pageId, + toLoadBasePageId: basePageId, }) .call(engine.loadAppURL, { - pageId: action.payload.pageId, - pageIdInUrl: action.payload.pageId, + basePageId: action.payload.basePageId, + basePageIdInUrl: action.payload.basePageId, rootSpan: mockRootSpan, }) .next() .call( engine.loadAppEntities, - action.payload.pageId, + pageId, action.payload.applicationId, mockResponse.data, mockRootSpan, diff --git a/app/client/src/sagas/selectors.tsx b/app/client/src/sagas/selectors.tsx index 059d693793..277e09957a 100644 --- a/app/client/src/sagas/selectors.tsx +++ b/app/client/src/sagas/selectors.tsx @@ -124,6 +124,9 @@ export const getEditorConfigs = ( export const getDefaultPageId = (state: AppState): string => state.entities.pageList.defaultPageId; +export const getDefaultBasePageId = (state: AppState): string => + state.entities.pageList.defaultBasePageId; + export const getExistingWidgetNames = createSelector( getWidgets, (widgets: { [widgetId: string]: FlattenedWidgetProps }) => { @@ -182,8 +185,11 @@ export const getWidgetByName = ( ); }; -export const getAllPageIds = (state: AppState) => { - return state.entities.pageList.pages.map((page) => page.pageId); +export const getAllPageIdentities = (state: AppState) => { + return state.entities.pageList.pages.map((page) => ({ + pageId: page.pageId, + basePageId: page.basePageId, + })); }; export const getPluginIdOfPackageName = ( diff --git a/app/client/src/selectors/datasourceSelectors.ts b/app/client/src/selectors/datasourceSelectors.ts index d511b4bc96..2e87b15c04 100644 --- a/app/client/src/selectors/datasourceSelectors.ts +++ b/app/client/src/selectors/datasourceSelectors.ts @@ -34,3 +34,6 @@ export const getFirstDatasourceId = (state: AppState) => { return list[0].id; } }; + +export const getLoadingTokenForDatasourceId = (state: AppState) => + state.entities.datasources.loadingTokenForDatasourceId; diff --git a/app/client/src/selectors/editorSelectors.tsx b/app/client/src/selectors/editorSelectors.tsx index c1b32e9f53..4204444dbe 100644 --- a/app/client/src/selectors/editorSelectors.tsx +++ b/app/client/src/selectors/editorSelectors.tsx @@ -29,7 +29,6 @@ import { import type { MainCanvasReduxState } from "reducers/uiReducers/mainCanvasReducer"; import { - getActions, getApiPaneSavingMap, getCanvasWidgets, getJSCollections, @@ -48,6 +47,7 @@ import { LayoutSystemTypes } from "layoutSystems/types"; import { getLayoutSystemType } from "./layoutSystemSelectors"; import { protectedModeSelector } from "./gitSyncSelectors"; import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors"; +import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors"; const getIsDraggingOrResizing = (state: AppState) => state.ui.widgetDragResize.isResizing || state.ui.widgetDragResize.isDragging; @@ -142,9 +142,17 @@ export const getPageById = (pageId: string) => pages.find((page) => page.pageId === pageId), ); +export const getPageByBaseId = (basePageId: string) => + createSelector(getPageList, (pages: Page[]) => + pages.find((page) => page.basePageId === basePageId), + ); + export const getCurrentPageId = (state: AppState) => state.entities.pageList.currentPageId; +export const getCurrentBasePageId = (state: AppState) => + state.entities.pageList.currentBasePageId; + export const getCurrentPagePermissions = createSelector( getCurrentPageId, getPageList, @@ -184,12 +192,11 @@ export const selectPageSlugToIdMap = createSelector(getPageList, (pages) => ), ); -export const getCurrentApplication = (state: AppState) => - state.ui.applications.currentApplication; - export const getCurrentApplicationId = (state: AppState) => state.entities.pageList.applicationId || ""; -/** this is set during init can assume it to be defined */ + +export const getCurrentBaseApplicationId = (state: AppState) => + state.entities.pageList.baseApplicationId || ""; export const selectCurrentApplicationSlug = (state: AppState) => state.ui.applications.currentApplication?.slug || PLACEHOLDER_APP_SLUG; @@ -832,22 +839,12 @@ export function getContainerWidgetSpacesSelectorWhileMoving( ); } -export const getActionById = createSelector( - [getActions, (state: any, props: any) => props.match.params.apiId], - (actions, id) => { - const action = actions.find((action) => action.config.id === id); - if (action) { - return action.config; - } else { - return undefined; - } - }, -); - export const getJSCollectionDataById = createSelector( [getJSCollections, (state: AppState, collectionId: string) => collectionId], - (jsActions, id) => { - const action = jsActions.find((action) => action.config.id === id); + (jsActions, collectionId) => { + const action = jsActions.find( + (action) => action.config.id === collectionId, + ); if (action) { return action; } else { @@ -856,15 +853,17 @@ export const getJSCollectionDataById = createSelector( }, ); -export const getJSCollectionById = createSelector( +export const getJSCollectionDataByBaseId = createSelector( [ getJSCollections, - (state: any, props: any) => props.match.params.collectionId, + (state: AppState, baseCollectionId: any) => baseCollectionId, ], - (jsActions, id) => { - const action = jsActions.find((action) => action.config.id === id); + (jsActions, baseCollectionId) => { + const action = jsActions.find( + (action) => action.config.baseId === baseCollectionId, + ); if (action) { - return action.config; + return action; } else { return undefined; } diff --git a/app/client/src/selectors/formSelectors.ts b/app/client/src/selectors/formSelectors.ts index 5ad57dd0e5..ecb80e2ecd 100644 --- a/app/client/src/selectors/formSelectors.ts +++ b/app/client/src/selectors/formSelectors.ts @@ -14,6 +14,7 @@ import type { Action } from "entities/Action"; import type { EvaluationError } from "utils/DynamicBindingUtils"; import { getActionIdFromURL } from "@appsmith/pages/Editor/Explorer/helpers"; import { extractConditionalOutput } from "components/formControls/utils"; +import { getActionByBaseId } from "@appsmith/selectors/entitiesSelector"; export interface GetFormData { initialValues: Record; @@ -43,9 +44,12 @@ export const getDynamicFetchedValues = ( state: AppState, config: any, ): DynamicValues => { + const baseActionId = getActionIdFromURL(); + const action = getActionByBaseId(state, baseActionId as string); + const actionId = action?.id ?? ""; const conditionalOutput = extractConditionalOutput( config, - state.evaluations.triggers[getActionIdFromURL() as string], + state.evaluations.triggers[actionId], ); return !!conditionalOutput.fetchDynamicValues ? conditionalOutput.fetchDynamicValues diff --git a/app/client/src/selectors/ideSelectors.tsx b/app/client/src/selectors/ideSelectors.tsx index 6bb835c132..d38ad84aa6 100644 --- a/app/client/src/selectors/ideSelectors.tsx +++ b/app/client/src/selectors/ideSelectors.tsx @@ -6,7 +6,7 @@ import { EditorEntityTab, EditorViewMode, } from "@appsmith/entities/IDE/constants"; -import { getCurrentPageId } from "./editorSelectors"; +import { getCurrentBasePageId } from "./editorSelectors"; import type { ParentEntityIDETabs } from "../reducers/uiReducers/ideReducer"; import { get } from "lodash"; @@ -45,17 +45,17 @@ export const getWidgetsCount = (state: AppState, pageId: string) => export const getIDETabs = (state: AppState) => state.ui.ide.tabs; export const getJSTabs = createSelector( - getCurrentPageId, + getCurrentBasePageId, getIDETabs, - (pageId: string, tabs: ParentEntityIDETabs) => - get(tabs, [pageId, EditorEntityTab.JS], []), + (basePageId: string, tabs: ParentEntityIDETabs) => + get(tabs, [basePageId, EditorEntityTab.JS], []), ); export const getQueryTabs = createSelector( - getCurrentPageId, + getCurrentBasePageId, getIDETabs, - (pageId: string, tabs: ParentEntityIDETabs): string[] => - get(tabs, [pageId, EditorEntityTab.QUERIES], []), + (basePageId: string, tabs: ParentEntityIDETabs): string[] => + get(tabs, [basePageId, EditorEntityTab.QUERIES], []), ); export const getShowCreateNewModal = (state: AppState) => diff --git a/app/client/src/selectors/jsPaneSelectors.ts b/app/client/src/selectors/jsPaneSelectors.ts index 5dfb7d7314..3400a27ae9 100644 --- a/app/client/src/selectors/jsPaneSelectors.ts +++ b/app/client/src/selectors/jsPaneSelectors.ts @@ -1,9 +1,9 @@ import type { AppState } from "@appsmith/reducers"; -import { getCurrentPageId } from "@appsmith/selectors/entitiesSelector"; import { getJSEntityItemUrl } from "@appsmith/pages/Editor/IDE/EditorPane/JS/utils"; import type { FocusEntityInfo } from "navigation/FocusEntity"; import { identifyEntityFromPath } from "navigation/FocusEntity"; import { selectJSSegmentEditorTabs } from "@appsmith/selectors/appIDESelectors"; +import { getCurrentBasePageId } from "./editorSelectors"; export const getJSPaneConfigSelectedTab = (state: AppState) => state.ui.jsPane.selectedConfigTab; @@ -13,9 +13,9 @@ export const getJsPaneDebuggerState = (state: AppState) => export const getLastJSTab = (state: AppState): FocusEntityInfo | undefined => { const tabs = selectJSSegmentEditorTabs(state); - const pageId = getCurrentPageId(state); + const basePageId = getCurrentBasePageId(state); if (tabs.length) { - const url = getJSEntityItemUrl(tabs[tabs.length - 1], pageId); + const url = getJSEntityItemUrl(tabs[tabs.length - 1], basePageId); const urlWithoutQueryParams = url.split("?")[0]; return identifyEntityFromPath(urlWithoutQueryParams); } diff --git a/app/client/src/selectors/navigationSelectors.ts b/app/client/src/selectors/navigationSelectors.ts index 7481cc0ef8..e877125148 100644 --- a/app/client/src/selectors/navigationSelectors.ts +++ b/app/client/src/selectors/navigationSelectors.ts @@ -12,7 +12,10 @@ import { getPlugins, } from "@appsmith/selectors/entitiesSelector"; import { getWidgets } from "sagas/selectors"; -import { getCurrentPageId } from "selectors/editorSelectors"; +import { + getCurrentBasePageId, + getCurrentPageId, +} from "selectors/editorSelectors"; import { getActionConfig } from "pages/Editor/Explorer/Actions/helpers"; import { jsCollectionIdURL, widgetURL } from "@appsmith/RouteBuilder"; import { getDataTree } from "selectors/dataTreeSelectors"; @@ -65,6 +68,7 @@ export const getEntitiesForNavigation = createSelector( getJSCollections, getWidgets, getCurrentPageId, + getCurrentBasePageId, getDataTree, getDatasources, getModulesData, @@ -75,6 +79,7 @@ export const getEntitiesForNavigation = createSelector( jsActions, widgets, pageId, + basePageId, dataTree: DataTree, datasources: Datasource[], modulesData, @@ -100,8 +105,8 @@ export const getEntitiesForNavigation = createSelector( name: action.config.name, type: ENTITY_TYPE.ACTION, url: config.getURL( - pageId, - action.config.id, + basePageId, + action.config.baseId, action.config.pluginType, plugin, ), @@ -118,12 +123,15 @@ export const getEntitiesForNavigation = createSelector( jsActions.forEach((jsAction) => { // dataTree for null check - const result = getJsChildrenNavData(jsAction, pageId, dataTree); + const result = getJsChildrenNavData(jsAction, basePageId, dataTree); navigationData[jsAction.config.name] = createNavData({ id: jsAction.config.id, name: jsAction.config.name, type: ENTITY_TYPE.JSACTION, - url: jsCollectionIdURL({ pageId, collectionId: jsAction.config.id }), + url: jsCollectionIdURL({ + basePageId, + baseCollectionId: jsAction.config.baseId, + }), children: result?.childNavData || {}, }); }); @@ -134,13 +142,13 @@ export const getEntitiesForNavigation = createSelector( widget.widgetName, widget.type, dataTree, - pageId, + basePageId, ); navigationData[widget.widgetName] = createNavData({ id: widget.widgetId, name: widget.widgetName, type: ENTITY_TYPE.WIDGET, - url: widgetURL({ pageId, selectedWidgets: [widget.widgetId] }), + url: widgetURL({ basePageId, selectedWidgets: [widget.widgetId] }), children: result?.childNavData || {}, widgetType: widget.type, }); @@ -186,12 +194,9 @@ export const getPathNavigationUrl = createSelector( const jsPropertyNavigationData = navigationData.children[propertyPath]; return jsPropertyNavigationData.url; } - - case ACTION_TYPE: - { - return navigationData.url; - } - break; + case ACTION_TYPE: { + return navigationData.url; + } default: return undefined; } diff --git a/app/client/src/selectors/pageListSelectors.tsx b/app/client/src/selectors/pageListSelectors.tsx index 2be2f431b3..3d8beefcd0 100644 --- a/app/client/src/selectors/pageListSelectors.tsx +++ b/app/client/src/selectors/pageListSelectors.tsx @@ -15,3 +15,40 @@ export const getIsGeneratingTemplatePage = createSelector( getPageListState, (pageList: PageListReduxState) => pageList.isGeneratingTemplatePage, ); + +export const convertToPageIdSelector = (state: AppState, basePageId: string) => + state.entities.pageList.pages?.find((page) => page.basePageId === basePageId) + ?.pageId; + +export const convertToBasePageIdSelector = (state: AppState, pageId: string) => + state.entities.pageList.pages?.find((page) => page.pageId === pageId) + ?.basePageId; + +export const convertToBaseParentEntityIdSelector = ( + state: AppState, + parentEntityId: string, +) => { + let baseParentEntityId = convertToBasePageIdSelector(state, parentEntityId); + if (!baseParentEntityId) { + baseParentEntityId = parentEntityId; + } + return baseParentEntityId; +}; + +export const getPageIdToBasePageIdMap = createSelector( + getPageListState, + (pageList: PageListReduxState) => + pageList.pages.reduce((acc: Record, page) => { + acc[page.pageId] = page.basePageId; + return acc; + }, {}), +); + +export const getBasePageIdToPageIdMap = createSelector( + getPageListState, + (pageList: PageListReduxState) => + pageList.pages.reduce((acc: Record, page) => { + acc[page.basePageId] = page.pageId; + return acc; + }, {}), +); diff --git a/app/client/src/transformers/RestActionTransformers.test.ts b/app/client/src/transformers/RestActionTransformers.test.ts index ea99afcd03..f6e8fc3d59 100644 --- a/app/client/src/transformers/RestActionTransformers.test.ts +++ b/app/client/src/transformers/RestActionTransformers.test.ts @@ -20,9 +20,11 @@ const BASE_ACTION: ApiAction = { invalids: [], isValid: false, workspaceId: "", + applicationId: "", pageId: "", pluginId: "", id: "testId", + baseId: "testBaseId", datasource: { id: "testDataSource", }, diff --git a/app/client/src/usagePulse/index.ts b/app/client/src/usagePulse/index.ts index eb0d6b3b1e..166c669f10 100644 --- a/app/client/src/usagePulse/index.ts +++ b/app/client/src/usagePulse/index.ts @@ -16,6 +16,8 @@ import { getFirstTimeUserOnboardingIntroModalVisibility } from "utils/storage"; // eslint-disable-next-line @typescript-eslint/no-restricted-imports import { PULSE_INTERVAL as PULSE_INTERVAL_CE } from "ce/constants/UsagePulse"; import { PULSE_INTERVAL as PULSE_INTERVAL_EE } from "ee/constants/UsagePulse"; +import store from "store"; +import type { PageListReduxState } from "reducers/entityReducers/pageListReducer"; class UsagePulse { static userAnonymousId: string | undefined; @@ -37,8 +39,15 @@ class UsagePulse { If it is private app with non-logged in user, we do not send pulse at this point instead we redirect to the login page. And for login page no usage pulse is required. */ + const basePageId = getAppViewerPageIdFromPath(path); + const { pages } = store.getState().entities + .pageList as PageListReduxState; + const pageId = pages?.find( + (page) => page.basePageId === basePageId, + )?.pageId; + const response: any = await PageApi.fetchAppAndPages({ - pageId: getAppViewerPageIdFromPath(path), + pageId, mode: APP_MODE.PUBLISHED, }); const { data } = response ?? {}; diff --git a/app/client/src/utils/NavigationSelector/JsChildren.ts b/app/client/src/utils/NavigationSelector/JsChildren.ts index 4064f18091..803017553d 100644 --- a/app/client/src/utils/NavigationSelector/JsChildren.ts +++ b/app/client/src/utils/NavigationSelector/JsChildren.ts @@ -12,7 +12,7 @@ import { createNavData } from "./common"; export const getJsChildrenNavData = ( jsAction: JSCollectionData, - pageId: string, + basePageId: string, dataTree: DataTree, ) => { let childNavData: EntityNavigationData = {}; @@ -27,8 +27,8 @@ export const getJsChildrenNavData = ( type: ENTITY_TYPE.JSACTION, isfunction: true, // use this to identify function url: jsCollectionIdURL({ - pageId, - collectionId: jsAction.config.id, + basePageId, + baseCollectionId: jsAction.config.baseId, functionName: jsChild.name, }), children: {}, @@ -44,8 +44,8 @@ export const getJsChildrenNavData = ( type: ENTITY_TYPE.JSACTION, isfunction: false, url: jsCollectionIdURL({ - pageId, - collectionId: jsAction.config.id, + basePageId, + baseCollectionId: jsAction.config.baseId, functionName: jsChild.name, }), children: {}, diff --git a/app/client/src/utils/NavigationSelector/WidgetChildren.ts b/app/client/src/utils/NavigationSelector/WidgetChildren.ts index 923aa1b0b4..fa80ddcb03 100644 --- a/app/client/src/utils/NavigationSelector/WidgetChildren.ts +++ b/app/client/src/utils/NavigationSelector/WidgetChildren.ts @@ -9,7 +9,7 @@ export const getWidgetChildrenNavData = ( widgetName: string, widgetType: string, dataTree: DataTree, - pageId: string, + basePageId: string, ) => { const dataTreeWidget: WidgetEntity = dataTree[widgetName] as WidgetEntity; if (widgetType === "FORM_WIDGET") { @@ -23,7 +23,7 @@ export const getWidgetChildrenNavData = ( id: `${widgetName}.data.${childWidgetName}`, name: childWidgetName, type: ENTITY_TYPE.WIDGET, - url: builderURL({ pageId, hash: childWidgetId }), + url: builderURL({ basePageId, hash: childWidgetId }), children: {}, }); }); diff --git a/app/client/src/utils/hooks/useWidgetSelection.ts b/app/client/src/utils/hooks/useWidgetSelection.ts index 23b6a145af..e33544b9f4 100644 --- a/app/client/src/utils/hooks/useWidgetSelection.ts +++ b/app/client/src/utils/hooks/useWidgetSelection.ts @@ -16,9 +16,9 @@ export const useWidgetSelection = () => { type: SelectionRequestType, payload?: string[], invokedBy?: NavigationMethod, - pageId?: string, + basePageId?: string, ) => { - dispatch(selectWidgetInitAction(type, payload, invokedBy, pageId)); + dispatch(selectWidgetInitAction(type, payload, invokedBy, basePageId)); }, [dispatch], ), diff --git a/app/client/test/factories/Actions/API.ts b/app/client/test/factories/Actions/API.ts index 5abac52848..e1045e0dd6 100644 --- a/app/client/test/factories/Actions/API.ts +++ b/app/client/test/factories/Actions/API.ts @@ -7,10 +7,12 @@ const pageId = "0123456789abcdef00000000"; export const APIFactory = Factory.Sync.makeFactory({ name: Factory.each((i) => `Api${i + 1}`), id: "api_id", + baseId: "api_base_id", pageId: pageId, pluginId: PluginIDs[PluginPackageName.REST_API], pluginType: PluginType.API, workspaceId: "workspaceId", + applicationId: "applicationId", actionConfiguration: { timeoutInMillisecond: 10000, paginationType: PaginationType.NONE, diff --git a/app/client/test/factories/Actions/GoogleSheetFactory.ts b/app/client/test/factories/Actions/GoogleSheetFactory.ts index 84b8daaae5..5eb367d7ab 100644 --- a/app/client/test/factories/Actions/GoogleSheetFactory.ts +++ b/app/client/test/factories/Actions/GoogleSheetFactory.ts @@ -7,7 +7,9 @@ const pageId = "0123456789abcdef00000000"; export const GoogleSheetFactory = Factory.Sync.makeFactory({ dynamicBindingPathList: [], id: "api_id", + baseId: "api_base_id", workspaceId: "workspaceID", + applicationId: "applicationID", pluginType: PluginType.SAAS, pluginId: PluginIDs[PluginPackageName.GOOGLE_SHEETS], name: Factory.each((i) => `Api${i + 1}`), diff --git a/app/client/test/factories/Actions/JSObject.ts b/app/client/test/factories/Actions/JSObject.ts index 9f6e686544..9518d10fa3 100644 --- a/app/client/test/factories/Actions/JSObject.ts +++ b/app/client/test/factories/Actions/JSObject.ts @@ -6,6 +6,7 @@ import { PluginIDs } from "test/factories/MockPluginsState"; const pageId = "0123456789abcdef00000000"; export const JSObjectFactory = Factory.Sync.makeFactory({ id: "js_id", + baseId: "js_base_id", workspaceId: "workspaceId", applicationId: "appId", name: Factory.each((i) => `JSObject${i + 1}`), @@ -15,7 +16,9 @@ export const JSObjectFactory = Factory.Sync.makeFactory({ actions: [ { id: "myFunc1_id", + baseId: "myFunc1_base_id", workspaceId: "workspaceId", + applicationId: "applicationId", pluginId: PluginIDs[PluginPackageName.JS], name: "myFun1", fullyQualifiedName: "JSObject1.myFun1", @@ -50,7 +53,9 @@ export const JSObjectFactory = Factory.Sync.makeFactory({ }, { id: "myFunc2_id", + baseId: "myFunc2_base_id", workspaceId: "workspaceId", + applicationId: "applicationId", pluginId: "613a26d921750e4b557a9241", name: "myFun2", fullyQualifiedName: "JSObject1.myFun2", diff --git a/app/client/test/factories/Actions/Postgres.ts b/app/client/test/factories/Actions/Postgres.ts index 3e8a4c54be..01e72a762d 100644 --- a/app/client/test/factories/Actions/Postgres.ts +++ b/app/client/test/factories/Actions/Postgres.ts @@ -8,7 +8,9 @@ const pageId = "0123456789abcdef00000000"; export const PostgresFactory = Factory.Sync.makeFactory({ cacheResponse: "", id: "query_id", + baseId: "query_base_id", workspaceId: "workspaceId", + applicationId: "applicationId", pluginType: PluginType.DB, pluginId: PluginIDs[PluginPackageName.POSTGRES], name: Factory.each((i) => `Query${i + 1}`), diff --git a/app/client/test/factories/AppIDEFactoryUtils.ts b/app/client/test/factories/AppIDEFactoryUtils.ts index 60c925159e..2528843adf 100644 --- a/app/client/test/factories/AppIDEFactoryUtils.ts +++ b/app/client/test/factories/AppIDEFactoryUtils.ts @@ -43,14 +43,17 @@ export const getIDETestState = ({ pages, isGeneratingTemplatePage: false, applicationId: "655716e035e2c9432e4bd94b", + baseApplicationId: "655716e035e2c9432e4bd94b", currentPageId: pages[0]?.pageId, + currentBasePageId: pages[0]?.basePageId, defaultPageId: pages[0]?.pageId, + defaultBasePageId: pages[0]?.basePageId, loading: {}, }; let ideTabs: ParentEntityIDETabs = {}; - if (pageList.currentPageId) { - ideTabs = { [pageList.currentPageId]: tabs }; + if (pageList.currentBasePageId) { + ideTabs = { [pageList.currentBasePageId]: tabs }; } const actionData = actions.map((a) => ({ isLoading: false, config: a })); diff --git a/app/client/test/factories/PageFactory.ts b/app/client/test/factories/PageFactory.ts index 2bf473379b..47df69d15f 100644 --- a/app/client/test/factories/PageFactory.ts +++ b/app/client/test/factories/PageFactory.ts @@ -13,6 +13,7 @@ function generateRandomHexId() { export const PageFactory = Factory.Sync.makeFactory({ pageName: Factory.each((i) => `Page${i + 1}`), pageId: Factory.each(() => generateRandomHexId()), + basePageId: Factory.each(() => generateRandomHexId()), isDefault: false, isHidden: false, slug: Factory.each((i) => `pageSlug${i + 1}`), diff --git a/app/client/test/testCommon.ts b/app/client/test/testCommon.ts index 6684619907..305f3079a3 100644 --- a/app/client/test/testCommon.ts +++ b/app/client/test/testCommon.ts @@ -1,21 +1,17 @@ import type { Page } from "@appsmith/constants/ReduxActionConstants"; import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; -import { initEditor } from "actions/initActions"; +import { initEditorAction } from "actions/initActions"; import { setAppMode, updateCurrentPage } from "actions/pageActions"; import { APP_MODE } from "entities/App"; import { useDispatch } from "react-redux"; import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer"; -import { createSelector } from "reselect"; import { getCanvasWidgetsPayload } from "@appsmith/sagas/PageSagas"; -import { getCanvasWidgets } from "@appsmith/selectors/entitiesSelector"; import { editorInitializer } from "utils/editor/EditorUtils"; import { extractCurrentDSL } from "utils/WidgetPropsUtils"; import type { AppState } from "@appsmith/reducers"; import type { WidgetEntity } from "@appsmith/entities/DataTree/types"; import urlBuilder from "@appsmith/entities/URLRedirect/URLAssembly"; import type { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsStructureReducer"; -import type { DSLWidget } from "WidgetProvider/constants"; -import { nestDSL } from "@shared/dsl"; const pageId = "0123456789abcdef00000000"; @@ -61,6 +57,7 @@ export const useMockDsl = (dsl: any, mode?: APP_MODE) => { { pageName: mockResp.data.name, pageId: mockResp.data.id, + basePageId: mockResp.data.id, isDefault: mockResp.data.isDefault, isHidden: !!mockResp.data.isHidden, slug: mockResp.data.slug, @@ -153,12 +150,13 @@ export const syntheticTestMouseEvent = ( export function MockApplication({ children }: any) { editorInitializer(); const dispatch = useDispatch(); - dispatch(initEditor({ pageId: pageId, mode: APP_MODE.EDIT })); + dispatch(initEditorAction({ basePageId: pageId, mode: APP_MODE.EDIT })); const mockResp: any = { workspaceId: "workspace_id", pages: [ { id: pageId, + baseId: pageId, pageId: pageId, name: "Page1", isDefault: true, @@ -172,6 +170,7 @@ export function MockApplication({ children }: any) { }, ], id: "app_id", + baseId: "app_id", isDefault: true, name: "appName", slug: "app-name", @@ -179,13 +178,13 @@ export function MockApplication({ children }: any) { }; urlBuilder.updateURLParams( { - applicationId: mockResp.id, + baseApplicationId: mockResp.baseId, applicationSlug: mockResp.slug, applicationVersion: mockResp.applicationVersion, }, [ { - pageId: mockResp.pages[0].id, + basePageId: mockResp.pages[0].baseId, pageSlug: mockResp.pages[0].slug, }, ], diff --git a/app/server/appsmith-git/src/main/java/com/appsmith/git/files/FileUtilsCEImpl.java b/app/server/appsmith-git/src/main/java/com/appsmith/git/files/FileUtilsCEImpl.java index c960e50a7e..fafe489f32 100644 --- a/app/server/appsmith-git/src/main/java/com/appsmith/git/files/FileUtilsCEImpl.java +++ b/app/server/appsmith-git/src/main/java/com/appsmith/git/files/FileUtilsCEImpl.java @@ -72,7 +72,7 @@ public class FileUtilsCEImpl implements FileInterface { private final GitServiceConfig gitServiceConfig; private final GitExecutor gitExecutor; - private final FileOperations fileOperations; + protected final FileOperations fileOperations; private final ObservationHelper observationHelper; private static final String EDIT_MODE_URL_TEMPLATE = "{{editModeUrl}}"; @@ -515,15 +515,15 @@ public class FileUtilsCEImpl implements FileInterface { * This will reconstruct the application from the repo * * @param organisationId To which organisation application needs to be rehydrated - * @param defaultApplicationId To which organisation application needs to be rehydrated + * @param baseApplicationId To which organisation application needs to be rehydrated * @param branchName for which the application needs to be rehydrate * @return application reference from which entire application can be rehydrated */ public Mono reconstructApplicationReferenceFromGitRepo( - String organisationId, String defaultApplicationId, String repoName, String branchName) { + String organisationId, String baseApplicationId, String repoName, String branchName) { Stopwatch processStopwatch = new Stopwatch("FS reconstruct application"); - Path baseRepoSuffix = Paths.get(organisationId, defaultApplicationId, repoName); + Path baseRepoSuffix = Paths.get(organisationId, baseApplicationId, repoName); // Checkout to mentioned branch if not already checked-out return gitExecutor @@ -956,7 +956,7 @@ public class FileUtilsCEImpl implements FileInterface { @Override public Mono reconstructMetadataFromGitRepo( String workspaceId, - String defaultArtifactId, + String baseArtifactId, String repoName, String branchName, Path baseRepoSuffix, diff --git a/app/server/appsmith-git/src/main/java/com/appsmith/git/service/ce/GitExecutorCEImpl.java b/app/server/appsmith-git/src/main/java/com/appsmith/git/service/ce/GitExecutorCEImpl.java index d5adac72ea..d0c71d7028 100644 --- a/app/server/appsmith-git/src/main/java/com/appsmith/git/service/ce/GitExecutorCEImpl.java +++ b/app/server/appsmith-git/src/main/java/com/appsmith/git/service/ce/GitExecutorCEImpl.java @@ -600,8 +600,7 @@ public class GitExecutorCEImpl implements GitExecutor { } // Remove modified changes from current branch so that checkout to other branches - // will be - // possible + // will be possible if (!status.isClean()) { return resetToLastCommit(git).map(ref -> { processStopwatch.stopAndLogTimeInMillis(); @@ -884,6 +883,47 @@ public class GitExecutorCEImpl implements GitExecutor { .subscribeOn(scheduler); } + @Override + public Mono fetchRemote( + Path repoSuffix, String publicKey, String privateKey, boolean isRepoPath, String... branchNames) { + Stopwatch processStopwatch = + StopwatchHelpers.startStopwatch(repoSuffix, AnalyticsEvents.GIT_FETCH.getEventName()); + Path repoPath = TRUE.equals(isRepoPath) ? repoSuffix : createRepoPath(repoSuffix); + return Mono.using( + () -> Git.open(repoPath.toFile()), + git -> Mono.fromCallable(() -> { + TransportConfigCallback config = + new SshTransportConfigCallback(privateKey, publicKey); + String fetchMessages; + + List refSpecs = new ArrayList<>(); + for (String branchName : branchNames) { + RefSpec ref = new RefSpec( + "refs/heads/" + branchName + ":refs/remotes/origin/" + branchName); + refSpecs.add(ref); + } + + fetchMessages = git.fetch() + .setRefSpecs(refSpecs.toArray(new RefSpec[0])) + .setRemoveDeletedRefs(true) + .setTransportConfigCallback(config) + .call() + .getMessages(); + + processStopwatch.stopAndLogTimeInMillis(); + return fetchMessages; + }) + .onErrorResume(error -> { + log.error(error.getMessage()); + return Mono.error(error); + }) + .timeout(Duration.ofMillis(Constraint.TIMEOUT_MILLIS)) + .name(GitSpan.FS_FETCH_REMOTE) + .tap(Micrometer.observation(observationRegistry)), + Git::close) + .subscribeOn(scheduler); + } + @Override public Mono isMergeBranch(Path repoSuffix, String sourceBranch, String destinationBranch) { Stopwatch processStopwatch = diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/DslExecutableDTO.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/DslExecutableDTO.java index a0868594aa..ac7acad929 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/DslExecutableDTO.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/DslExecutableDTO.java @@ -20,12 +20,6 @@ public class DslExecutableDTO { @JsonView(Views.Public.class) String id; - @JsonView(Views.Internal.class) - String defaultActionId; - - @JsonView(Views.Internal.class) - String defaultCollectionId; - @JsonView(Views.Public.class) String name; @@ -46,9 +40,4 @@ public class DslExecutableDTO { @JsonView(Views.Public.class) Integer timeoutInMillisecond = DEFAULT_ACTION_EXECUTION_TIMEOUT_MS; - - public void sanitiseForExport() { - this.setDefaultActionId(null); - this.setDefaultCollectionId(null); - } } diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/ExecuteActionDTO.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/ExecuteActionDTO.java index c50fe9757f..1704e0e1cf 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/ExecuteActionDTO.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/ExecuteActionDTO.java @@ -17,7 +17,6 @@ import java.util.stream.Collectors; public class ExecuteActionDTO { String actionId; - String datasourceId; String workspaceId; String instanceId; diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/LayoutExecutableUpdateDTO.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/LayoutExecutableUpdateDTO.java index 9ed78ec609..0109901357 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/LayoutExecutableUpdateDTO.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/LayoutExecutableUpdateDTO.java @@ -23,7 +23,4 @@ public class LayoutExecutableUpdateDTO { @JsonView(Views.Public.class) Boolean executeOnLoad; - - @JsonView(Views.Internal.class) - String defaultActionId; } diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/FileInterface.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/FileInterface.java index 332b833a44..fd17dd1e51 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/FileInterface.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/FileInterface.java @@ -38,13 +38,13 @@ public interface FileInterface { * This method will reconstruct the application from the repo * * @param organisationId To which organisation application needs to be rehydrated - * @param defaultApplicationId Default application needs to be rehydrated + * @param baseApplicationId Base application needs to be rehydrated * @param branchName for which branch the application needs to be rehydrated * @param repoName git repo name to access file system * @return application reference from which entire application can be rehydrated */ Mono reconstructApplicationReferenceFromGitRepo( - String organisationId, String defaultApplicationId, String repoName, String branchName); + String organisationId, String baseApplicationId, String repoName, String branchName); /** * This method just reconstructs the metdata of the json from git repo. diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/GitExecutor.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/GitExecutor.java index 80b329ee49..7342541e3e 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/GitExecutor.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/git/GitExecutor.java @@ -153,6 +153,9 @@ public interface GitExecutor { String branchName, boolean isFetchAll); + Mono fetchRemote( + Path repoSuffix, String publicKey, String privateKey, boolean isRepoPath, String... branchNames); + /** * * @param repoSuffix suffixedPath used to generate the base repo path this includes orgId, defaultAppId, repoName diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/BaseDomain.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/BaseDomain.java index e9725a5148..713225722f 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/BaseDomain.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/BaseDomain.java @@ -5,7 +5,6 @@ import com.appsmith.external.views.FromRequest; import com.appsmith.external.views.Git; import com.appsmith.external.views.Views; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonView; import lombok.AccessLevel; import lombok.Getter; @@ -93,12 +92,6 @@ public abstract class BaseDomain implements Persistable, AppsmithDomain, @JsonView(Views.Public.class) public Set userPermissions = new HashSet<>(); - // This field will only be used for git related functionality to sync the action object across different instances. - // This field will be deprecated once we move to the new git sync implementation. - @JsonProperty(access = JsonProperty.Access.READ_ONLY) - @JsonView({Views.Internal.class, Git.class}) - String gitSyncId; - public void sanitiseToExportDBObject() { this.setCreatedAt(null); this.setUpdatedAt(null); diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/BranchAwareDomain.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/BranchAwareDomain.java index aae686b3c7..8b3a9524a0 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/BranchAwareDomain.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/BranchAwareDomain.java @@ -6,30 +6,34 @@ import lombok.Getter; import lombok.Setter; import lombok.experimental.FieldNameConstants; -import static com.appsmith.external.helpers.StringUtils.dotted; - @Setter @Getter @FieldNameConstants -public abstract class BranchAwareDomain extends BaseDomain { - // This field will be used to store the default/root resource IDs for branched resources generated for git - // connected applications and will be used to connect resources across the branches +public abstract class BranchAwareDomain extends GitSyncedDomain { + + @JsonView(Views.Public.class) + String baseId; + @JsonView(Views.Internal.class) - DefaultResources defaultResources; + String branchName; + + @JsonView(Views.Internal.class) + public String getBaseIdOrFallback() { + return baseId == null ? this.getId() : baseId; + } @Override public void sanitiseToExportDBObject() { - this.setDefaultResources(null); + this.setBaseId(null); + this.setBranchName(null); super.sanitiseToExportDBObject(); } - public static class Fields extends BaseDomain.Fields { - public static final String defaultResources_applicationId = - dotted(defaultResources, DefaultResources.Fields.applicationId); - public static final String defaultResources_branchName = - dotted(defaultResources, DefaultResources.Fields.branchName); - public static final String defaultResources_pageId = dotted(defaultResources, DefaultResources.Fields.pageId); - public static final String defaultResources_actionId = - dotted(defaultResources, DefaultResources.Fields.actionId); + @Override + public void makePristine() { + super.makePristine(); + this.setBaseId(null); } + + public static class Fields extends GitSyncedDomain.Fields {} } diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/Datasource.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/Datasource.java index e70dc8a0d3..e2b41d1c80 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/Datasource.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/Datasource.java @@ -25,7 +25,7 @@ import java.util.Set; @NoArgsConstructor @Document @FieldNameConstants -public class Datasource extends BranchAwareDomain { +public class Datasource extends GitSyncedDomain { @Transient public static final String DEFAULT_NAME_PREFIX = "Untitled datasource"; diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DatasourceStorage.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DatasourceStorage.java index da83038dcc..a038402c7c 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DatasourceStorage.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DatasourceStorage.java @@ -27,7 +27,7 @@ import static com.appsmith.external.constants.PluginConstants.DEFAULT_REST_DATAS @NoArgsConstructor @Document @FieldNameConstants -public class DatasourceStorage extends BaseDomain { +public class DatasourceStorage extends GitSyncedDomain { @JsonView(Views.Public.class) String datasourceId; @@ -158,4 +158,6 @@ public class DatasourceStorage extends BaseDomain { return (DEFAULT_REST_DATASOURCE.equals(this.name) || DEFAULT_APPSMITH_AI_DATASOURCE.equals(this.name)) && !StringUtils.hasText(this.datasourceId); } + + public static class Fields extends BaseDomain.Fields {} } diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DefaultResources.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DefaultResources.java deleted file mode 100644 index 8c8c473137..0000000000 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/DefaultResources.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.appsmith.external.models; - -import com.appsmith.external.models.ce.DefaultResourcesCE; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.experimental.FieldNameConstants; - -/** - * This class will be used for connecting resources across branches for git connected application - * e.g. Page1 in branch1 will have the same defaultResources.pageId as of Page1 of branch2 - */ -@EqualsAndHashCode(callSuper = true) -@Data -@FieldNameConstants -public class DefaultResources extends DefaultResourcesCE { - public static class Fields extends DefaultResourcesCE.Fields {} -} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/Executable.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/Executable.java index 9e9eb691d5..b7e2aad60e 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/Executable.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/Executable.java @@ -64,15 +64,12 @@ public interface Executable { EntityReferenceType getEntityReferenceType(); - DefaultResources getDefaultResources(); - default LayoutExecutableUpdateDTO createLayoutExecutableUpdateDTO() { LayoutExecutableUpdateDTO layoutExecutableUpdateDTO = new LayoutExecutableUpdateDTO(); layoutExecutableUpdateDTO.setId(this.getId()); layoutExecutableUpdateDTO.setName(this.getValidName()); layoutExecutableUpdateDTO.setExecuteOnLoad(this.getExecuteOnLoad()); - layoutExecutableUpdateDTO.setDefaultActionId(this.getDefaultResources().getActionId()); return layoutExecutableUpdateDTO; } diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/GitSyncedDomain.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/GitSyncedDomain.java new file mode 100644 index 0000000000..10b9ca1b55 --- /dev/null +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/GitSyncedDomain.java @@ -0,0 +1,21 @@ +package com.appsmith.external.models; + +import com.appsmith.external.views.Git; +import com.appsmith.external.views.Views; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonView; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.FieldNameConstants; + +@Getter +@Setter +@FieldNameConstants +public abstract class GitSyncedDomain extends BaseDomain { + // This field will only be used for git related functionality to sync the action object across different instances. + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + @JsonView({Views.Internal.class, Git.class}) + String gitSyncId; + + public static class Fields extends BaseDomain.Fields {} +} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/ce/ActionCE_DTO.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/ce/ActionCE_DTO.java index a99034a694..ab71ebb214 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/ce/ActionCE_DTO.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/ce/ActionCE_DTO.java @@ -8,7 +8,6 @@ import com.appsmith.external.helpers.Identifiable; import com.appsmith.external.models.ActionConfiguration; import com.appsmith.external.models.CreatorContextType; import com.appsmith.external.models.Datasource; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.Documentation; import com.appsmith.external.models.EntityReferenceType; import com.appsmith.external.models.Executable; @@ -43,6 +42,10 @@ public class ActionCE_DTO implements Identifiable, Executable { @JsonView({Views.Public.class, FromRequest.class}) private String id; + @Transient + @JsonView({Views.Public.class, FromRequest.class}) + private String baseId; + @Transient @JsonView({Views.Public.class, FromRequest.class}) String applicationId; @@ -150,11 +153,6 @@ public class ActionCE_DTO implements Identifiable, Executable { @JsonView({Views.Public.class, FromRequest.class}) public Set userPermissions = new HashSet<>(); - // This field will be used to store the default/root actionId and applicationId for actions generated for git - // connected applications and will be used to connect actions across the branches - @JsonView(Views.Internal.class) - DefaultResources defaultResources; - @JsonView(Views.Internal.class) protected Instant createdAt; @@ -169,6 +167,10 @@ public class ActionCE_DTO implements Identifiable, Executable { @JsonView({Views.Public.class, FromRequest.class}) ActionCreationSourceTypeEnum source; + @Transient + @JsonView({Views.Internal.class}) + private String branchName; + @Override @JsonView({Views.Internal.class}) public String getValidName() { @@ -205,7 +207,6 @@ public class ActionCE_DTO implements Identifiable, Executable { public void sanitiseToExportDBObject() { this.resetTransientFields(); - this.setDefaultResources(null); this.setUpdatedAt(null); this.setCacheResponse(null); if (this.getDatasource() != null) { @@ -269,10 +270,6 @@ public class ActionCE_DTO implements Identifiable, Executable { dslExecutableDTO.setCollectionId(this.getCollectionId()); dslExecutableDTO.setClientSideExecution(this.getClientSideExecution()); dslExecutableDTO.setConfirmBeforeExecute(this.getConfirmBeforeExecute()); - if (this.getDefaultResources() != null) { - dslExecutableDTO.setDefaultActionId(this.getDefaultResources().getActionId()); - dslExecutableDTO.setDefaultCollectionId(this.getDefaultResources().getCollectionId()); - } if (this.getExecutableConfiguration() != null) { dslExecutableDTO.setTimeoutInMillisecond( @@ -304,6 +301,7 @@ public class ActionCE_DTO implements Identifiable, Executable { protected void resetTransientFields() { this.setId(null); + this.setBaseId(null); this.setApplicationId(null); this.setWorkspaceId(null); this.setPluginId(null); diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/ce/DefaultResourcesCE.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/ce/DefaultResourcesCE.java deleted file mode 100644 index 698739d9f3..0000000000 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/ce/DefaultResourcesCE.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.appsmith.external.models.ce; - -import lombok.Data; -import lombok.experimental.FieldNameConstants; - -/** - * This class will be used for connecting resources across branches for git connected application - * e.g. Page1 in branch1 will have the same defaultResources.pageId as of Page1 of branch2 - */ -@Data -@FieldNameConstants -public class DefaultResourcesCE { - /** - * When present, actionId will hold the default action id - */ - String actionId; - - /** - * When present, applicationId will hold the default application id - */ - String applicationId; - - /** - * When present, pageId will hold the default page id - */ - String pageId; - - /** - * When present, collectionId will hold the default collection id - */ - String collectionId; - - /** - * When present, branchName will hold the current branch name. - * For example, if we've a page in both main and develop branch, then default resources of those two pages will - * have same applicationId, pageId but branchName will contain the corresponding branch name. - */ - String branchName; - - public static class Fields {} -} diff --git a/app/server/appsmith-server/pom.xml b/app/server/appsmith-server/pom.xml index eba1802811..3afbd2751d 100644 --- a/app/server/appsmith-server/pom.xml +++ b/app/server/appsmith-server/pom.xml @@ -148,7 +148,7 @@ io.mongock - mongodb-springdata-v4-driver + mongodb-reactive-driver org.springframework.boot diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCE.java index f0306aaf6a..b048168c81 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCE.java @@ -26,7 +26,7 @@ public interface ActionCollectionServiceCE extends CrudService saveAll(List collections); - Mono findByIdAndBranchName(String id, String branchName); + Mono findByBaseIdAndBranchName(String id, String branchName); Flux getPopulatedActionCollectionsByViewMode( MultiValueMap params, Boolean viewMode); @@ -51,8 +51,6 @@ public interface ActionCollectionServiceCE extends CrudService deleteWithoutPermissionUnpublishedActionCollection(String id); - Mono deleteUnpublishedActionCollection(String id, String branchName); - Mono generateActionCollectionByViewMode(ActionCollection actionCollection, Boolean viewMode); Mono findById(String id, AclPermission aclPermission); @@ -71,19 +69,18 @@ public interface ActionCollectionServiceCE extends CrudService archiveById(String id); - Mono findByBranchNameAndDefaultCollectionId( - String branchName, String defaultCollectionId, AclPermission permission); + Mono findByBranchNameAndBaseCollectionId( + String branchName, String baseCollectionId, AclPermission permission); Mono> archiveActionCollectionByApplicationId(String applicationId, AclPermission permission); - void populateDefaultResources( - ActionCollection actionCollection, ActionCollection branchedActionCollection, String branchName); - Flux findAllActionCollectionsByContextIdAndContextTypeAndViewMode( String contextId, CreatorContextType contextType, AclPermission permission, boolean viewMode); Mono validateAndSaveCollection(ActionCollection actionCollection); + Flux getActionCollectionsForViewMode(String branchedApplicationId); + Mono generateActionCollectionViewDTO(ActionCollection actionCollection); Mono bulkValidateAndInsertActionCollectionInRepository(List actionCollectionList); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java index 909a7a3ed1..49635f17a0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceCEImpl.java @@ -1,15 +1,12 @@ package com.appsmith.server.actioncollections.base; -import com.appsmith.external.helpers.AppsmithBeanUtils; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.CreatorContextType; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.Policy; import com.appsmith.server.acl.AclPermission; import com.appsmith.server.acl.PolicyGenerator; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.constants.FieldName; -import com.appsmith.server.defaultresources.DefaultResourcesService; import com.appsmith.server.domains.ActionCollection; import com.appsmith.server.domains.NewAction; import com.appsmith.server.domains.NewPage; @@ -17,7 +14,6 @@ import com.appsmith.server.dtos.ActionCollectionDTO; import com.appsmith.server.dtos.ActionCollectionViewDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.repositories.ActionCollectionRepository; import com.appsmith.server.services.AnalyticsService; @@ -55,13 +51,8 @@ public class ActionCollectionServiceCEImpl extends BaseService defaultResourcesService; - private final DefaultResourcesService dtoDefaultResourcesService; - private final DefaultResourcesService newActionDefaultResourcesService; - private final DefaultResourcesService actionDTODefaultResourcesService; @Autowired public ActionCollectionServiceCEImpl( @@ -71,25 +62,15 @@ public class ActionCollectionServiceCEImpl extends BaseService defaultResourcesService, - DefaultResourcesService dtoDefaultResourcesService, - DefaultResourcesService newActionDefaultResourcesService, - DefaultResourcesService actionDTODefaultResourcesService) { + ActionPermission actionPermission) { super(validator, repository, analyticsService); this.newActionService = newActionService; this.policyGenerator = policyGenerator; this.applicationService = applicationService; - this.responseUtils = responseUtils; this.applicationPermission = applicationPermission; this.actionPermission = actionPermission; - this.defaultResourcesService = defaultResourcesService; - this.dtoDefaultResourcesService = dtoDefaultResourcesService; - this.newActionDefaultResourcesService = newActionDefaultResourcesService; - this.actionDTODefaultResourcesService = actionDTODefaultResourcesService; } @Override @@ -141,9 +122,9 @@ public class ActionCollectionServiceCEImpl extends BaseService findByIdAndBranchName(String id, String branchName) { + public Mono findByBaseIdAndBranchName(String id, String branchName) { // TODO sanitise response for default IDs - return this.findByBranchNameAndDefaultCollectionId(branchName, id, actionPermission.getReadPermission()); + return this.findByBranchNameAndBaseCollectionId(branchName, id, actionPermission.getReadPermission()); } @Override @@ -157,11 +138,10 @@ public class ActionCollectionServiceCEImpl extends BaseService getPopulatedActionCollectionsByViewMode( MultiValueMap params, Boolean viewMode, String branchName) { MultiValueMap updatedMap = new LinkedMultiValueMap<>(params); - if (!StringUtils.isEmpty(branchName)) { + if (StringUtils.hasLength(branchName)) { updatedMap.add(FieldName.BRANCH_NAME, branchName); } - return this.getPopulatedActionCollectionsByViewMode(updatedMap, viewMode) - .map(responseUtils::updateCollectionDTOWithDefaultResources); + return this.getPopulatedActionCollectionsByViewMode(updatedMap, viewMode); } @Override @@ -197,6 +177,7 @@ public class ActionCollectionServiceCEImpl extends BaseService getActionCollectionsForViewMode(String applicationId, String branchName) { if (applicationId == null || applicationId.isEmpty()) { @@ -211,6 +192,13 @@ public class ActionCollectionServiceCEImpl extends BaseService getActionCollectionsForViewMode(String branchedApplicationId) { + return repository + .findByApplicationIdAndViewMode(branchedApplicationId, true, actionPermission.getExecutePermission()) + .flatMap(this::generateActionCollectionViewDTO); + } + @Override public Mono generateActionCollectionViewDTO(ActionCollection actionCollection) { return generateActionCollectionViewDTO(actionCollection, actionPermission.getExecutePermission(), true); @@ -229,30 +217,13 @@ public class ActionCollectionServiceCEImpl extends BaseService newActionService.generateActionByViewMode(action, viewMode)) @@ -260,8 +231,7 @@ public class ActionCollectionServiceCEImpl extends BaseService { actionCollectionViewDTO.setActions(actionDTOList); return actionCollectionViewDTO; - }) - .map(responseUtils::updateActionCollectionViewDTOWithDefaultResources); + }); } @Override @@ -287,27 +257,12 @@ public class ActionCollectionServiceCEImpl extends BaseService repository.findByApplicationIdAndViewMode( childApplicationId, viewMode, actionPermission.getReadPermission())); } - - String name = null; - List pageIds = new ArrayList<>(); - String branch = null; - - // In the edit mode, the actions should be displayed in the order they were created. - Sort sort = Sort.by(FieldName.CREATED_AT); - - if (params.getFirst(FieldName.NAME) != null) { - name = params.getFirst(FieldName.NAME); - } - - if (params.getFirst(FieldName.BRANCH_NAME) != null) { - branch = params.getFirst(FieldName.BRANCH_NAME); - } + String pageId = null; if (params.getFirst(FieldName.PAGE_ID) != null) { - pageIds.add(params.getFirst(FieldName.PAGE_ID)); + pageId = params.getFirst(FieldName.PAGE_ID); } - return repository.findAllActionCollectionsByNameDefaultPageIdsViewModeAndBranch( - name, pageIds, viewMode, branch, actionPermission.getReadPermission(), sort); + return repository.findByPageIdAndViewMode(pageId, viewMode, actionPermission.getReadPermission()); } @Override @@ -325,12 +280,6 @@ public class ActionCollectionServiceCEImpl extends BaseService { copyNewFieldValuesIntoOldObject(actionCollectionDTO, dbActionCollection.getUnpublishedCollection()); - // No need to save defaultPageId at actionCollection level as this will be stored inside the - // actionCollectionDTO - defaultResourcesService.initialize( - dbActionCollection, - dbActionCollection.getDefaultResources().getBranchName(), - false); return dbActionCollection; }) .flatMap(actionCollection -> this.update(id, actionCollection)) @@ -395,20 +344,6 @@ public class ActionCollectionServiceCEImpl extends BaseService generateActionCollectionByViewMode(updatedAction, false)); } - @Override - public Mono deleteUnpublishedActionCollection(String id, String branchName) { - Mono branchedCollectionId = StringUtils.isEmpty(branchName) - ? Mono.just(id) - : this.findByBranchNameAndDefaultCollectionId(branchName, id, actionPermission.getDeletePermission()) - .map(ActionCollection::getId); - - return branchedCollectionId - .flatMap(this::deleteUnpublishedActionCollection) - .map(responseUtils::updateCollectionDTOWithDefaultResources) - .flatMap(actionCollectionDTO -> - saveLastEditInformationInParent(actionCollectionDTO).thenReturn(actionCollectionDTO)); - } - @Override public Mono generateActionCollectionByViewMode( ActionCollection actionCollection, Boolean viewMode) { @@ -515,20 +450,20 @@ public class ActionCollectionServiceCEImpl extends BaseService findByBranchNameAndDefaultCollectionId( - String branchName, String defaultCollectionId, AclPermission permission) { + public Mono findByBranchNameAndBaseCollectionId( + String branchName, String baseCollectionId, AclPermission permission) { - if (StringUtils.isEmpty(defaultCollectionId)) { + if (StringUtils.isEmpty(baseCollectionId)) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.COLLECTION_ID)); } else if (StringUtils.isEmpty(branchName)) { - return this.findById(defaultCollectionId, permission) + return this.findById(baseCollectionId, permission) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.ACTION_COLLECTION, defaultCollectionId))); + AppsmithError.NO_RESOURCE_FOUND, FieldName.ACTION_COLLECTION, baseCollectionId))); } return repository - .findByBranchNameAndDefaultCollectionId(branchName, defaultCollectionId, permission) + .findByBranchNameAndBaseCollectionId(branchName, baseCollectionId, permission) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.ACTION_COLLECTION, defaultCollectionId))); + AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.ACTION_COLLECTION, baseCollectionId))); } @Override @@ -549,40 +484,6 @@ public class ActionCollectionServiceCEImpl extends BaseService findAllActionCollectionsByContextIdAndContextTypeAndViewMode( String contextId, CreatorContextType contextType, AclPermission permission, boolean viewMode) { @@ -615,9 +516,6 @@ public class ActionCollectionServiceCEImpl extends BaseService sendAnalyticsMono = analyticsService.sendCreateEvent(newAction, newActionService.getAnalyticsProperties(newAction)); @@ -670,21 +564,15 @@ public class ActionCollectionServiceCEImpl extends BaseService { - populateDefaultResources(actionCollection, collectionDTO, actions); - // Create collection and return with actions final Mono actionCollectionMono = this.create(actionCollection) .flatMap(savedActionCollection -> { - // If the default collection is not set then current collection will be the default one - if (StringUtils.isEmpty(savedActionCollection - .getDefaultResources() - .getCollectionId())) { - savedActionCollection - .getDefaultResources() - .setCollectionId(savedActionCollection.getId()); - return this.save(savedActionCollection); + if (StringUtils.hasLength(savedActionCollection.getBaseId())) { + return Mono.just(savedActionCollection); } - return Mono.just(savedActionCollection); + // If the base collection is not set then current collection will be the default one + savedActionCollection.setBaseId(savedActionCollection.getId()); + return this.save(savedActionCollection); }) .flatMap(repository::setUserPermissionsInObject) .cache(); @@ -694,10 +582,6 @@ public class ActionCollectionServiceCEImpl extends BaseService { // Update all the actions in the list to belong to this collection actionDTO.setCollectionId(actionCollection1.getId()); - if (StringUtils.isEmpty( - actionDTO.getDefaultResources().getCollectionId())) { - actionDTO.getDefaultResources().setCollectionId(actionCollection1.getId()); - } }); return actions; }) @@ -725,15 +609,6 @@ public class ActionCollectionServiceCEImpl extends BaseService actions) { - // Store the default resource ids - // Only store defaultPageId for collectionDTO level resource - DefaultResources defaultDTOResource = new DefaultResources(); - AppsmithBeanUtils.copyNewFieldValuesIntoOldObject(collectionDTO.getDefaultResources(), defaultDTOResource); - - defaultDTOResource.setApplicationId(null); - defaultDTOResource.setCollectionId(null); - defaultDTOResource.setBranchName(null); - if (StringUtils.isEmpty(defaultDTOResource.getPageId())) { - defaultDTOResource.setPageId(collectionDTO.getPageId()); - } - collectionDTO.setDefaultResources(defaultDTOResource); - - // Only store branchName, defaultApplicationId and defaultActionCollectionId for ActionCollection - // level resource - DefaultResources defaults = new DefaultResources(); - AppsmithBeanUtils.copyNewFieldValuesIntoOldObject(actionCollection.getDefaultResources(), defaults); - defaults.setPageId(null); - if (StringUtils.isEmpty(defaults.getApplicationId())) { - defaults.setApplicationId(actionCollection.getApplicationId()); - } - actionCollection.setDefaultResources(defaults); - } - @Override public Mono saveLastEditInformationInParent(ActionCollectionDTO actionCollectionDTO) { // Do nothing as this is already taken care for JS objects in the context of page diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceImpl.java index c0bbe886c3..e24740b823 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/base/ActionCollectionServiceImpl.java @@ -1,13 +1,7 @@ package com.appsmith.server.actioncollections.base; -import com.appsmith.external.models.ActionDTO; import com.appsmith.server.acl.PolicyGenerator; import com.appsmith.server.applications.base.ApplicationService; -import com.appsmith.server.defaultresources.DefaultResourcesService; -import com.appsmith.server.domains.ActionCollection; -import com.appsmith.server.domains.NewAction; -import com.appsmith.server.dtos.ActionCollectionDTO; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.repositories.ActionCollectionRepository; import com.appsmith.server.services.AnalyticsService; @@ -27,13 +21,8 @@ public class ActionCollectionServiceImpl extends ActionCollectionServiceCEImpl i NewActionService newActionService, PolicyGenerator policyGenerator, ApplicationService applicationService, - ResponseUtils responseUtils, ApplicationPermission applicationPermission, - ActionPermission actionPermission, - DefaultResourcesService defaultResourcesService, - DefaultResourcesService dtoDefaultResourcesService, - DefaultResourcesService newActionDefaultResourcesService, - DefaultResourcesService actionDTODefaultResourcesService) { + ActionPermission actionPermission) { super( validator, repository, @@ -41,12 +30,7 @@ public class ActionCollectionServiceImpl extends ActionCollectionServiceCEImpl i newActionService, policyGenerator, applicationService, - responseUtils, applicationPermission, - actionPermission, - defaultResourcesService, - dtoDefaultResourcesService, - newActionDefaultResourcesService, - actionDTODefaultResourcesService); + actionPermission); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/clonepage/ActionCollectionClonePageServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/clonepage/ActionCollectionClonePageServiceCEImpl.java index ac773365e7..fa7c67428e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/clonepage/ActionCollectionClonePageServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/clonepage/ActionCollectionClonePageServiceCEImpl.java @@ -1,6 +1,5 @@ package com.appsmith.server.actioncollections.clonepage; -import com.appsmith.external.models.DefaultResources; import com.appsmith.server.actioncollections.base.ActionCollectionService; import com.appsmith.server.clonepage.ClonePageServiceCE; import com.appsmith.server.domains.ActionCollection; @@ -25,8 +24,6 @@ public class ActionCollectionClonePageServiceCEImpl implements ClonePageServiceC public Mono cloneEntities(ClonePageMetaDTO clonePageMetaDTO) { return getCloneableActionCollections(clonePageMetaDTO.getBranchedSourcePageId()) .flatMap(sourceActionCollection -> { - final DefaultResources clonedPageDefaultResources = - clonePageMetaDTO.getClonedPageDTO().getDefaultResources(); ActionCollection toBeClonedActionCollection = new ActionCollection(); copyNestedNonNullProperties(sourceActionCollection, toBeClonedActionCollection); @@ -37,21 +34,13 @@ public class ActionCollectionClonePageServiceCEImpl implements ClonePageServiceC toBeClonedActionCollection.setApplicationId( clonePageMetaDTO.getClonedPageDTO().getApplicationId()); - DefaultResources defaultResources = new DefaultResources(); - copyNestedNonNullProperties(clonedPageDefaultResources, defaultResources); - toBeClonedActionCollection.setDefaultResources(defaultResources); - - DefaultResources defaultResourcesForDTO = new DefaultResources(); - defaultResourcesForDTO.setPageId(clonedPageDefaultResources.getPageId()); - toBeClonedActionCollection.getUnpublishedCollection().setDefaultResources(defaultResourcesForDTO); - // Set id as null, otherwise create (which is using under the hood save) // will try to overwrite same resource instead of creating a new resource toBeClonedActionCollection.setId(null); + toBeClonedActionCollection.setBaseId(null); // Set published version to null as the published version of the page does // not exist when we clone the page. toBeClonedActionCollection.setPublishedCollection(null); - toBeClonedActionCollection.getDefaultResources().setPageId(null); // Assign new gitSyncId for cloned actionCollection toBeClonedActionCollection.setGitSyncId( toBeClonedActionCollection.getApplicationId() + "_" + UUID.randomUUID()); @@ -61,12 +50,8 @@ public class ActionCollectionClonePageServiceCEImpl implements ClonePageServiceC clonePageMetaDTO .getOldToNewCollectionIds() .put(sourceActionCollection.getId(), clonedActionCollection.getId()); - if (!StringUtils.hasLength(clonedActionCollection - .getDefaultResources() - .getCollectionId())) { - clonedActionCollection - .getDefaultResources() - .setCollectionId(clonedActionCollection.getId()); + if (!StringUtils.hasLength(clonedActionCollection.getBaseId())) { + clonedActionCollection.setBaseId(clonedActionCollection.getId()); return actionCollectionService.update( clonedActionCollection.getId(), clonedActionCollection); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/defaultresources/ActionCollectionDTODefaultResourcesServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/defaultresources/ActionCollectionDTODefaultResourcesServiceCEImpl.java deleted file mode 100644 index fd3e27e904..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/defaultresources/ActionCollectionDTODefaultResourcesServiceCEImpl.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.appsmith.server.actioncollections.defaultresources; - -import com.appsmith.external.models.DefaultResources; -import com.appsmith.server.defaultresources.DefaultResourcesServiceCE; -import com.appsmith.server.dtos.ActionCollectionDTO; -import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; - -@Service -public class ActionCollectionDTODefaultResourcesServiceCEImpl - implements DefaultResourcesServiceCE { - - @Override - public ActionCollectionDTO initialize( - ActionCollectionDTO domainObject, String branchName, boolean resetExistingValues) { - DefaultResources existingDefaultResources = domainObject.getDefaultResources(); - DefaultResources defaultResources = new DefaultResources(); - - String defaultPageId = domainObject.getPageId(); - - if (existingDefaultResources != null && !resetExistingValues) { - // Check if there are properties to be copied over from existing - if (StringUtils.hasText(existingDefaultResources.getPageId())) { - defaultPageId = existingDefaultResources.getPageId(); - } - } - - defaultResources.setPageId(defaultPageId); - - domainObject.setDefaultResources(defaultResources); - return domainObject; - } - - @Override - public ActionCollectionDTO setFromOtherBranch( - ActionCollectionDTO domainObject, ActionCollectionDTO defaultDomainObject, String branchName) { - DefaultResources defaultResources = new DefaultResources(); - - defaultResources.setPageId(defaultDomainObject.getDefaultResources().getPageId()); - - domainObject.setDefaultResources(defaultResources); - return domainObject; - } -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/defaultresources/ActionCollectionDTODefaultResourcesServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/defaultresources/ActionCollectionDTODefaultResourcesServiceImpl.java deleted file mode 100644 index 9772d5b9c9..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/defaultresources/ActionCollectionDTODefaultResourcesServiceImpl.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.appsmith.server.actioncollections.defaultresources; - -import com.appsmith.server.defaultresources.DefaultResourcesService; -import com.appsmith.server.dtos.ActionCollectionDTO; -import org.springframework.stereotype.Service; - -@Service -public class ActionCollectionDTODefaultResourcesServiceImpl extends ActionCollectionDTODefaultResourcesServiceCEImpl - implements DefaultResourcesService {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/defaultresources/ActionCollectionDefaultResourcesServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/defaultresources/ActionCollectionDefaultResourcesServiceCEImpl.java deleted file mode 100644 index fc357a048c..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/defaultresources/ActionCollectionDefaultResourcesServiceCEImpl.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.appsmith.server.actioncollections.defaultresources; - -import com.appsmith.external.models.DefaultResources; -import com.appsmith.server.defaultresources.DefaultResourcesServiceCE; -import com.appsmith.server.domains.ActionCollection; -import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; - -@Service -public class ActionCollectionDefaultResourcesServiceCEImpl implements DefaultResourcesServiceCE { - - @Override - public ActionCollection initialize(ActionCollection domainObject, String branchName, boolean resetExistingValues) { - DefaultResources existingDefaultResources = domainObject.getDefaultResources(); - DefaultResources defaultResources = new DefaultResources(); - - String defaultApplicationId = domainObject.getApplicationId(); - String defaultCollectionId = domainObject.getId(); - - if (existingDefaultResources != null && !resetExistingValues) { - // Check if there are properties to be copied over from existing - if (StringUtils.hasText(existingDefaultResources.getApplicationId())) { - defaultApplicationId = existingDefaultResources.getApplicationId(); - } - - if (StringUtils.hasText(existingDefaultResources.getCollectionId())) { - defaultCollectionId = existingDefaultResources.getCollectionId(); - } - } - - defaultResources.setCollectionId(defaultCollectionId); - defaultResources.setApplicationId(defaultApplicationId); - defaultResources.setBranchName(branchName); - - domainObject.setDefaultResources(defaultResources); - return domainObject; - } - - @Override - public ActionCollection setFromOtherBranch( - ActionCollection domainObject, ActionCollection branchedDomainObject, String branchName) { - DefaultResources defaultResources = domainObject.getDefaultResources(); - if (defaultResources == null) { - defaultResources = new DefaultResources(); - } - - DefaultResources otherDefaultResources = branchedDomainObject.getDefaultResources(); - - defaultResources.setCollectionId(otherDefaultResources.getCollectionId()); - defaultResources.setApplicationId(otherDefaultResources.getApplicationId()); - defaultResources.setBranchName(branchName); - - domainObject.setDefaultResources(defaultResources); - return domainObject; - } -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/defaultresources/ActionCollectionDefaultResourcesServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/defaultresources/ActionCollectionDefaultResourcesServiceImpl.java deleted file mode 100644 index 521bb023c3..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/defaultresources/ActionCollectionDefaultResourcesServiceImpl.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.appsmith.server.actioncollections.defaultresources; - -import com.appsmith.server.defaultresources.DefaultResourcesService; -import com.appsmith.server.domains.ActionCollection; -import org.springframework.stereotype.Service; - -@Service -public class ActionCollectionDefaultResourcesServiceImpl extends ActionCollectionDefaultResourcesServiceCEImpl - implements DefaultResourcesService {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/ActionCollectionImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/ActionCollectionImportableServiceCEImpl.java index 7213df99e9..5586e16eb3 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/ActionCollectionImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/ActionCollectionImportableServiceCEImpl.java @@ -145,10 +145,9 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic Mono> actionCollectionsInBranchesMono; if (artifact.getGitArtifactMetadata() != null) { - final String defaultArtifactId = - artifact.getGitArtifactMetadata().getDefaultArtifactId(); actionCollectionsInBranchesMono = artifactBasedImportableService - .getExistingResourcesInOtherBranchesFlux(defaultArtifactId, artifact.getId()) + .getExistingResourcesInOtherBranchesFlux( + importingMetaDTO.getBranchedArtifactIds(), artifact.getId()) .filter(actionCollection -> actionCollection.getGitSyncId() != null) .collectMap(ActionCollection::getGitSyncId); } else { @@ -197,7 +196,7 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic actionCollection); } - Context defaultContext = populateIdReferencesAndReturnDefaultContext( + Context baseContext = populateIdReferencesAndReturnBaseContext( importingMetaDTO, mappedImportableResourcesDTO, artifact, @@ -229,7 +228,7 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic .put(idFromJsonFile, existingActionCollection); } else { artifactBasedImportableService.createNewResource( - importingMetaDTO, actionCollection, defaultContext); + importingMetaDTO, actionCollection, baseContext); populateDomainMappedReferences(mappedImportableResourcesDTO, actionCollection); @@ -259,7 +258,7 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic }); } - private Context populateIdReferencesAndReturnDefaultContext( + private Context populateIdReferencesAndReturnBaseContext( ImportingMetaDTO importingMetaDTO, MappedImportableResourcesDTO mappedImportableResourcesDTO, Artifact artifact, @@ -276,14 +275,14 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic Context parentContext = null; // If contextId is missing in the actionCollectionDTO create a fallback contextId - final String fallbackDefaultContextId = unpublishedCollection.calculateContextId(); + final String fallbackBaseContextId = unpublishedCollection.calculateContextId(); if (unpublishedCollection.getName() != null) { unpublishedCollection.setPluginId( mappedImportableResourcesDTO.getPluginMap().get(unpublishedCollection.getPluginId())); parentContext = artifactBasedImportableService.updateContextInResource( - unpublishedCollection, mappedImportableResourcesDTO.getContextMap(), fallbackDefaultContextId); + unpublishedCollection, mappedImportableResourcesDTO.getContextMap(), fallbackBaseContextId); } if (publishedCollection != null && publishedCollection.getName() != null) { @@ -291,15 +290,17 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic mappedImportableResourcesDTO.getPluginMap().get(publishedCollection.getPluginId())); Context publishedCollectionContext = artifactBasedImportableService.updateContextInResource( - publishedCollection, mappedImportableResourcesDTO.getContextMap(), fallbackDefaultContextId); + publishedCollection, mappedImportableResourcesDTO.getContextMap(), fallbackBaseContextId); parentContext = parentContext == null ? publishedCollectionContext : parentContext; } actionCollection.makePristine(); actionCollection.setWorkspaceId(workspaceId); - artifactBasedImportableService.populateDefaultResources( - importingMetaDTO, mappedImportableResourcesDTO, artifact, branchedActionCollection, actionCollection); + artifactBasedImportableService.updateArtifactId(actionCollection, artifact); + + artifactBasedImportableService.populateBaseId( + importingMetaDTO, artifact, branchedActionCollection, actionCollection); return parentContext; } @@ -345,7 +346,7 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic populateDomainMappedReferences(mappedImportableResourcesDTO, existingActionCollection); // Update branchName - existingActionCollection.getDefaultResources().setBranchName(importingMetaDTO.getBranchName()); + existingActionCollection.setBranchName(importingMetaDTO.getBranchName()); // Recover the deleted state present in DB from imported actionCollection existingActionCollection .getUnpublishedCollection() diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/applications/ActionCollectionApplicationImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/applications/ActionCollectionApplicationImportableServiceCEImpl.java index b82d86cdb3..fd077fa62d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/applications/ActionCollectionApplicationImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/applications/ActionCollectionApplicationImportableServiceCEImpl.java @@ -1,9 +1,7 @@ package com.appsmith.server.actioncollections.importable.applications; -import com.appsmith.external.models.DefaultResources; import com.appsmith.server.actioncollections.base.ActionCollectionService; import com.appsmith.server.constants.FieldName; -import com.appsmith.server.defaultresources.DefaultResourcesService; import com.appsmith.server.domains.ActionCollection; import com.appsmith.server.domains.Application; import com.appsmith.server.domains.Artifact; @@ -14,7 +12,6 @@ import com.appsmith.server.dtos.ImportingMetaDTO; import com.appsmith.server.dtos.MappedImportableResourcesDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.DefaultResourcesUtils; import com.appsmith.server.imports.importable.artifactbased.ArtifactBasedImportableServiceCE; import com.appsmith.server.repositories.ActionCollectionRepository; import lombok.RequiredArgsConstructor; @@ -34,8 +31,6 @@ public class ActionCollectionApplicationImportableServiceCEImpl implements ArtifactBasedImportableServiceCE { private final ActionCollectionRepository repository; - private final DefaultResourcesService defaultResourcesService; - private final DefaultResourcesService dtoDefaultResourcesService; private final ActionCollectionService actionCollectionService; @Override @@ -63,19 +58,24 @@ public class ActionCollectionApplicationImportableServiceCEImpl @Override public Flux getExistingResourcesInOtherBranchesFlux( - String defaultArtifactId, String currentArtifactId) { + List branchedArtifactIds, String currentArtifactId) { return repository - .findByDefaultApplicationId(defaultArtifactId, null) + .findAllByApplicationIds(branchedArtifactIds, null) .filter(actionCollection -> !Objects.equals(actionCollection.getApplicationId(), currentArtifactId)); } + @Override + public void updateArtifactId(ActionCollection resource, Artifact artifact) { + resource.setApplicationId(artifact.getId()); + } + @Override public Context updateContextInResource( - Object dtoObject, Map contextMap, String fallbackDefaultContextId) { + Object dtoObject, Map contextMap, String fallbackBaseContextId) { ActionCollectionDTO collectionDTO = (ActionCollectionDTO) dtoObject; if (StringUtils.isEmpty(collectionDTO.getPageId())) { - collectionDTO.setPageId(fallbackDefaultContextId); + collectionDTO.setPageId(fallbackBaseContextId); } NewPage parentPage = (NewPage) contextMap.get(collectionDTO.getPageId()); @@ -84,66 +84,25 @@ public class ActionCollectionApplicationImportableServiceCEImpl return null; } collectionDTO.setPageId(parentPage.getId()); - - // Update defaultResources in actionCollectionDTO - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setPageId(parentPage.getDefaultResources().getPageId()); - collectionDTO.setDefaultResources(defaultResources); - return parentPage; } - @Override - public void populateDefaultResources( - ImportingMetaDTO importingMetaDTO, - MappedImportableResourcesDTO mappedImportableResourcesDTO, - Artifact artifact, - ActionCollection branchedActionCollection, - ActionCollection actionCollection) { - actionCollection.setApplicationId(artifact.getId()); - - if (artifact.getGitArtifactMetadata() != null) { - if (branchedActionCollection != null) { - defaultResourcesService.setFromOtherBranch( - actionCollection, branchedActionCollection, importingMetaDTO.getBranchName()); - dtoDefaultResourcesService.setFromOtherBranch( - actionCollection.getUnpublishedCollection(), - branchedActionCollection.getUnpublishedCollection(), - importingMetaDTO.getBranchName()); - } else { - // This is the first action collection we are saving with given gitSyncId - // in this instance - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setApplicationId( - artifact.getGitArtifactMetadata().getDefaultArtifactId()); - defaultResources.setCollectionId(actionCollection.getId()); - defaultResources.setBranchName(importingMetaDTO.getBranchName()); - actionCollection.setDefaultResources(defaultResources); - } - } else { - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setApplicationId(artifact.getId()); - defaultResources.setCollectionId(actionCollection.getId()); - actionCollection.setDefaultResources(defaultResources); - } - } - @Override public void createNewResource( - ImportingMetaDTO importingMetaDTO, ActionCollection actionCollection, Context defaultContext) { - if (!importingMetaDTO.getPermissionProvider().canCreateAction((NewPage) defaultContext)) { + ImportingMetaDTO importingMetaDTO, ActionCollection actionCollection, Context baseContext) { + if (!importingMetaDTO.getPermissionProvider().canCreateAction((NewPage) baseContext)) { throw new AppsmithException( - AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.PAGE, ((NewPage) defaultContext).getId()); + AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.PAGE, ((NewPage) baseContext).getId()); } // this will generate the id and other auto generated fields e.g. createdAt actionCollection.updateForBulkWriteOperation(); - actionCollectionService.generateAndSetPolicies((NewPage) defaultContext, actionCollection); + actionCollectionService.generateAndSetPolicies((NewPage) baseContext, actionCollection); - // create or update default resources for the action - // values already set to defaultResources are kept unchanged - DefaultResourcesUtils.createDefaultIdsOrUpdateWithGivenResourceIds( - actionCollection, importingMetaDTO.getBranchName()); + // create or update base id for the action + // values already set to base id are kept unchanged + actionCollection.setBaseId(actionCollection.getBaseIdOrFallback()); + actionCollection.setBranchName(importingMetaDTO.getBranchName()); // generate gitSyncId if it's not present if (actionCollection.getGitSyncId() == null) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/applications/ActionCollectionApplicationImportableServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/applications/ActionCollectionApplicationImportableServiceImpl.java index 56ac738068..8885d666cb 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/applications/ActionCollectionApplicationImportableServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/importable/applications/ActionCollectionApplicationImportableServiceImpl.java @@ -1,10 +1,8 @@ package com.appsmith.server.actioncollections.importable.applications; import com.appsmith.server.actioncollections.base.ActionCollectionService; -import com.appsmith.server.defaultresources.DefaultResourcesService; import com.appsmith.server.domains.ActionCollection; import com.appsmith.server.domains.Application; -import com.appsmith.server.dtos.ActionCollectionDTO; import com.appsmith.server.imports.importable.artifactbased.ArtifactBasedImportableService; import com.appsmith.server.repositories.ActionCollectionRepository; import org.springframework.stereotype.Service; @@ -12,12 +10,8 @@ import org.springframework.stereotype.Service; @Service public class ActionCollectionApplicationImportableServiceImpl extends ActionCollectionApplicationImportableServiceCEImpl implements ArtifactBasedImportableService { - public ActionCollectionApplicationImportableServiceImpl( - ActionCollectionRepository repository, - DefaultResourcesService defaultResourcesService, - DefaultResourcesService dtoDefaultResourcesService, - ActionCollectionService actionCollectionService) { - super(repository, defaultResourcesService, dtoDefaultResourcesService, actionCollectionService); + ActionCollectionRepository repository, ActionCollectionService actionCollectionService) { + super(repository, actionCollectionService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/refactors/ActionCollectionRefactoringServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/refactors/ActionCollectionRefactoringServiceCEImpl.java index 55338f5604..b6416cb1ac 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/refactors/ActionCollectionRefactoringServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/refactors/ActionCollectionRefactoringServiceCEImpl.java @@ -16,7 +16,6 @@ import com.appsmith.server.services.AstService; import com.appsmith.server.solutions.ActionPermission; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -100,21 +99,13 @@ public class ActionCollectionRefactoringServiceCEImpl implements EntityRefactori } @Override - public Mono updateRefactoredEntity(RefactorEntityNameDTO refactorEntityNameDTO, String branchName) { + public Mono updateRefactoredEntity(RefactorEntityNameDTO refactorEntityNameDTO) { String newName = refactorEntityNameDTO.getNewName(); String actionCollectionId = refactorEntityNameDTO.getActionCollectionId(); Mono branchedActionCollectionDTOMono; - if (!StringUtils.hasLength(branchName)) { - branchedActionCollectionDTOMono = actionCollectionService.findActionCollectionDTObyIdAndViewMode( - actionCollectionId, false, actionPermission.getEditPermission()); - } else { - branchedActionCollectionDTOMono = actionCollectionService - .findByBranchNameAndDefaultCollectionId( - branchName, actionCollectionId, actionPermission.getEditPermission()) - .flatMap(actionCollection -> - actionCollectionService.generateActionCollectionByViewMode(actionCollection, false)); - } + branchedActionCollectionDTOMono = actionCollectionService.findActionCollectionDTObyIdAndViewMode( + actionCollectionId, false, actionPermission.getEditPermission()); return branchedActionCollectionDTOMono .flatMap(branchedActionCollection -> { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceCE.java index 6906857d3d..fd8e5a67ef 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceCE.java @@ -19,9 +19,7 @@ public interface ApplicationServiceCE extends CrudService { Mono getById(String id); - Mono findByIdAndBranchName(String id, String branchName); - - Mono findByIdAndBranchName(String id, List projectionFieldNames, String branchName); + Mono findByBranchedId(String id, List projectionFieldNames); Mono findById(String id); @@ -29,52 +27,54 @@ public interface ApplicationServiceCE extends CrudService { Flux findByWorkspaceId(String workspaceId, AclPermission permission); - Flux findByWorkspaceIdAndDefaultApplicationsInRecentlyUsedOrder(String workspaceId); + Flux findByWorkspaceIdAndBaseApplicationsInRecentlyUsedOrder(String workspaceId); Mono save(Application application); - Mono update(String defaultApplicationId, Application application, String branchName); + Mono updateApplicationWithPresets(String branchedApplicationId, Application application); - Mono update(String defaultApplicationId, Map fieldNameValueMap, String branchName); + Mono updateByBranchedIdAndFieldsMap(String branchedApplicationId, Map fieldNameValueMap); - Mono createDefaultApplication(Application object); + Mono createBaseApplication(Application object); Mono archive(Application application); - Mono changeViewAccess(String id, ApplicationAccessDTO applicationAccessDTO); + Mono changeViewAccessForSingleBranchByBranchedApplicationId( + String branchedApplicationId, ApplicationAccessDTO applicationAccessDTO); - Mono changeViewAccess( - String defaultApplicationId, String branchName, ApplicationAccessDTO applicationAccessDTO); + Mono changeViewAccessForAllBranchesByBranchedApplicationId( + String branchedApplicationId, ApplicationAccessDTO applicationAccessDTO); Flux findAllApplicationsByWorkspaceId(String workspaceId); Mono getApplicationInViewMode(String applicationId); - Mono getApplicationInViewMode(String defaultApplicationId, String branchName); - Mono saveLastEditInformation(String applicationId); Mono setTransientFields(Application application); - Mono createOrUpdateSshKeyPair(String applicationId, String keyType); + Mono createOrUpdateSshKeyPair(String branchedApplicationId, String keyType); Mono getSshKey(String applicationId); - Mono findByBranchNameAndDefaultApplicationId( - String branchName, String defaultApplicationId, AclPermission aclPermission); + Mono findByBranchNameAndBaseApplicationId( + String branchName, String baseApplicationId, AclPermission aclPermission); Mono findBranchedApplicationId( - Optional branchName, String defaultApplicationId, Optional permission); + Optional branchName, String baseApplicationId, Optional permission); - Mono findByBranchNameAndDefaultApplicationId( + Mono findByBranchNameAndBaseApplicationId( String branchName, - String defaultApplicationId, + String baseApplicationId, List projectionFieldNames, AclPermission aclPermission); - Mono findBranchedApplicationId(String branchName, String defaultApplicationId, AclPermission permission); + Mono findBranchedApplicationId(String branchName, String baseApplicationId, AclPermission permission); - Flux findAllApplicationsByDefaultApplicationId(String defaultApplicationId, AclPermission permission); + Flux findAllApplicationsByBaseApplicationId(String baseApplicationId, AclPermission permission); + + Flux findAllBranchedApplicationIdsByBranchedApplicationId( + String branchedApplicationId, AclPermission permission); Mono getGitConnectedApplicationsCountWithPrivateRepoByWorkspaceId(String workspaceId); @@ -83,13 +83,13 @@ public interface ApplicationServiceCE extends CrudService { Mono setAppTheme( String applicationId, String editModeThemeId, String publishedModeThemeId, AclPermission aclPermission); - Mono getApplicationByDefaultApplicationIdAndDefaultBranch(String defaultApplicationId); + Mono getApplicationByBaseApplicationIdAndDefaultBranch(String baseApplicationId); Mono findByIdAndExportWithConfiguration(String applicationId, Boolean exportWithConfiguration); - Mono saveAppNavigationLogo(String branchName, String applicationId, Part filePart); + Mono saveAppNavigationLogo(String branchedApplicationId, Part filePart); - Mono deleteAppNavigationLogo(String branchName, String applicationId); + Mono deleteAppNavigationLogo(String branchedApplicationId); Mono isApplicationNameTaken(String applicationName, String workspaceId, AclPermission permission); @@ -97,6 +97,10 @@ public interface ApplicationServiceCE extends CrudService { Mono updateProtectedBranches(String applicationId, List protectedBranches); - Mono findByDefaultIdBranchNameAndApplicationMode( + Flux findBranchedApplicationIdsByBaseApplicationId(String artifactId); + + Mono findByBaseIdBranchNameAndApplicationMode( String defaultApplicationId, String branchName, ApplicationMode mode); + + Mono findByBranchedApplicationIdAndApplicationMode(String branchedApplicationId, ApplicationMode mode); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceCEImpl.java index 9254892260..37ddd81371 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceCEImpl.java @@ -27,7 +27,6 @@ import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.exceptions.util.DuplicateKeyExceptionUtils; import com.appsmith.server.helpers.GitDeployKeyGenerator; import com.appsmith.server.helpers.GitUtils; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.helpers.TextUtils; import com.appsmith.server.migrations.ApplicationVersion; import com.appsmith.server.repositories.ApplicationRepository; @@ -68,7 +67,6 @@ import static com.appsmith.server.acl.AclPermission.MANAGE_APPLICATIONS; import static com.appsmith.server.acl.AclPermission.READ_APPLICATIONS; import static com.appsmith.server.constants.Constraint.MAX_LOGO_SIZE_KB; import static com.appsmith.server.helpers.ce.DomainSorter.sortDomainsBasedOnOrderedDomainIds; -import static org.apache.commons.lang3.StringUtils.isBlank; @Slf4j @Service @@ -76,7 +74,6 @@ public class ApplicationServiceCEImpl extends BaseService findByIdAndBranchName(String id, String branchName) { - return findByIdAndBranchName(id, null, branchName); - } - - @Override - public Mono findByIdAndBranchName(String id, List projectionFieldNames, String branchName) { - return this.findByBranchNameAndDefaultApplicationId( - branchName, id, projectionFieldNames, applicationPermission.getReadPermission()) - .map(responseUtils::updateApplicationWithDefaultResources); + public Mono findByBranchedId(String id, List projectionFieldNames) { + return repository + .queryBuilder() + .byId(id) + .fields(projectionFieldNames) + .one() + .switchIfEmpty( + Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, id))); } @Override @@ -169,7 +163,7 @@ public class ApplicationServiceCEImpl extends BaseService findByWorkspaceIdAndDefaultApplicationsInRecentlyUsedOrder(String workspaceId) { + public Flux findByWorkspaceIdAndBaseApplicationsInRecentlyUsedOrder(String workspaceId) { if (!StringUtils.hasLength(workspaceId)) { return Flux.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.WORKSPACE_ID)); @@ -208,8 +202,7 @@ public class ApplicationServiceCEImpl extends BaseService createDefaultApplication(Application application) { + public Mono createBaseApplication(Application application) { return createSuffixedApplication(application, application.getName(), 0); } @@ -302,7 +295,7 @@ public class ApplicationServiceCEImpl extends BaseService update(String defaultApplicationId, Map fieldNameValueMap, String branchName) { - String defaultIdPath = "id"; - if (!isBlank(branchName)) { - defaultIdPath = "gitApplicationMetadata.defaultApplicationId"; - } - return repository.updateFieldByDefaultIdAndBranchName( - defaultApplicationId, - defaultIdPath, - fieldNameValueMap, - branchName, - "gitApplicationMetadata.branchName", - MANAGE_APPLICATIONS); + public Mono updateByBranchedIdAndFieldsMap( + String branchedApplicationId, Map fieldNameValueMap) { + return repository.updateFieldById( + branchedApplicationId, Application.Fields.id, fieldNameValueMap, MANAGE_APPLICATIONS); } - public Mono update(String defaultApplicationId, Application application, String branchName) { - return this.findByBranchNameAndDefaultApplicationId( - branchName, defaultApplicationId, applicationPermission.getEditPermission()) + public Mono updateApplicationWithPresets(String branchedApplicationId, Application application) { + return this.findById(branchedApplicationId, applicationPermission.getEditPermission()) .flatMap(branchedApplication -> { application.setPages(null); application.setGitApplicationMetadata(null); @@ -427,14 +409,15 @@ public class ApplicationServiceCEImpl extends BaseService changeViewAccess(String id, ApplicationAccessDTO applicationAccessDTO) { + public Mono changeViewAccessForSingleBranchByBranchedApplicationId( + String branchedApplicationId, ApplicationAccessDTO applicationAccessDTO) { Mono publicPermissionGroupIdMono = permissionGroupService.getPublicPermissionGroupId().cache(); Mono updateApplicationMono = repository - .findById(id, applicationPermission.getMakePublicPermission()) - .switchIfEmpty(Mono.error( - new AppsmithException(AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.APPLICATION, id))) + .findById(branchedApplicationId, applicationPermission.getMakePublicPermission()) + .switchIfEmpty(Mono.error(new AppsmithException( + AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.APPLICATION, branchedApplicationId))) .zipWith(publicPermissionGroupIdMono) .flatMap(tuple -> { Application application = tuple.getT1(); @@ -463,18 +446,17 @@ public class ApplicationServiceCEImpl extends BaseService changeViewAccess( - String defaultApplicationId, String branchName, ApplicationAccessDTO applicationAccessDTO) { + public Mono changeViewAccessForAllBranchesByBranchedApplicationId( + String branchedApplicationId, ApplicationAccessDTO applicationAccessDTO) { // For git connected application update the policy for all the branch's - return findAllApplicationsByDefaultApplicationId( - defaultApplicationId, applicationPermission.getMakePublicPermission()) - .switchIfEmpty(this.findByBranchNameAndDefaultApplicationId( - branchName, defaultApplicationId, applicationPermission.getMakePublicPermission())) - .flatMap(branchedApplication -> changeViewAccess(branchedApplication.getId(), applicationAccessDTO)) + return findAllBranchedApplicationIdsByBranchedApplicationId( + branchedApplicationId, applicationPermission.getMakePublicPermission()) + .switchIfEmpty(Mono.just(branchedApplicationId)) + .flatMap(branchedApplicationId1 -> changeViewAccessForSingleBranchByBranchedApplicationId( + branchedApplicationId1, applicationAccessDTO)) .then(repository - .findById(defaultApplicationId, applicationPermission.getMakePublicPermission()) - .flatMap(this::setTransientFields) - .map(responseUtils::updateApplicationWithDefaultResources)); + .findById(branchedApplicationId, applicationPermission.getMakePublicPermission()) + .flatMap(this::setTransientFields)); } @Override @@ -482,15 +464,6 @@ public class ApplicationServiceCEImpl extends BaseService getApplicationInViewMode(String defaultApplicationId, String branchName) { - - return this.findBranchedApplicationId( - branchName, defaultApplicationId, applicationPermission.getReadPermission()) - .flatMap(this::getApplicationInViewMode) - .map(responseUtils::updateApplicationWithDefaultResources); - } - @Override public Mono getApplicationInViewMode(String applicationId) { return repository @@ -675,23 +648,23 @@ public class ApplicationServiceCEImpl extends BaseService createOrUpdateSshKeyPair(String applicationId, String keyType) { + public Mono createOrUpdateSshKeyPair(String branchedApplicationId, String keyType) { GitAuth gitAuth = GitDeployKeyGenerator.generateSSHKey(keyType); return repository - .findById(applicationId, applicationPermission.getEditPermission()) + .findById(branchedApplicationId, applicationPermission.getEditPermission()) .switchIfEmpty(Mono.error( - new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, "application", applicationId))) + new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, "application", branchedApplicationId))) .flatMap(application -> { GitArtifactMetadata gitData = application.getGitApplicationMetadata(); // Check if the current application is the root application if (gitData != null && !StringUtils.isEmpty(gitData.getDefaultArtifactId()) - && applicationId.equals(gitData.getDefaultArtifactId())) { + && branchedApplicationId.equals(gitData.getDefaultArtifactId())) { // This is the root application with update SSH key request gitAuth.setRegeneratedKey(true); gitData.setGitAuth(gitAuth); @@ -699,7 +672,7 @@ public class ApplicationServiceCEImpl extends BaseService { - GitArtifactMetadata gitArtifactMetadata = - defaultApplication.getGitApplicationMetadata(); - gitArtifactMetadata.setDefaultApplicationId(defaultApplication.getId()); + .flatMap(baseApplication -> { + GitArtifactMetadata gitArtifactMetadata = baseApplication.getGitApplicationMetadata(); + gitArtifactMetadata.setDefaultApplicationId(baseApplication.getId()); gitArtifactMetadata.setGitAuth(gitAuth); - defaultApplication.setGitApplicationMetadata(gitArtifactMetadata); - return save(defaultApplication); + baseApplication.setGitApplicationMetadata(gitArtifactMetadata); + return save(baseApplication); }); }) .flatMap(application -> { @@ -802,34 +774,32 @@ public class ApplicationServiceCEImpl extends BaseService findByBranchNameAndDefaultApplicationId( - String branchName, String defaultApplicationId, AclPermission aclPermission) { - return findByBranchNameAndDefaultApplicationId(branchName, defaultApplicationId, null, aclPermission); + public Mono findByBranchNameAndBaseApplicationId( + String branchName, String baseApplicationId, AclPermission aclPermission) { + return findByBranchNameAndBaseApplicationId(branchName, baseApplicationId, null, aclPermission); } @Override - public Mono findByBranchNameAndDefaultApplicationId( + public Mono findByBranchNameAndBaseApplicationId( String branchName, - String defaultApplicationId, + String baseApplicationId, List projectionFieldNames, AclPermission aclPermission) { if (StringUtils.isEmpty(branchName)) { return repository .queryBuilder() - .byId(defaultApplicationId) + .byId(baseApplicationId) .fields(projectionFieldNames) .permission(aclPermission) .one() .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, defaultApplicationId))); + AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, baseApplicationId))); } return repository - .getApplicationByGitBranchAndDefaultApplicationId( - defaultApplicationId, projectionFieldNames, branchName, aclPermission) + .getApplicationByGitBranchAndBaseApplicationId( + baseApplicationId, projectionFieldNames, branchName, aclPermission) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, - FieldName.APPLICATION, - defaultApplicationId + "," + branchName))); + AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, baseApplicationId + "," + branchName))); } /** @@ -861,38 +831,34 @@ public class ApplicationServiceCEImpl extends BaseService findBranchedApplicationId( - String branchName, String defaultApplicationId, AclPermission permission) { + String branchName, String baseApplicationId, AclPermission permission) { if (!StringUtils.hasLength(branchName)) { - if (!StringUtils.hasLength(defaultApplicationId)) { + if (!StringUtils.hasLength(baseApplicationId)) { return Mono.error(new AppsmithException( - AppsmithError.INVALID_PARAMETER, FieldName.APPLICATION_ID, defaultApplicationId)); + AppsmithError.INVALID_PARAMETER, FieldName.APPLICATION_ID, baseApplicationId)); } - return Mono.just(defaultApplicationId); + return Mono.just(baseApplicationId); } return repository - .getApplicationByGitBranchAndDefaultApplicationId(defaultApplicationId, branchName, permission) + .getApplicationByGitBranchAndBaseApplicationId(baseApplicationId, branchName, permission) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, - FieldName.APPLICATION, - defaultApplicationId + ", " + branchName))) + AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, baseApplicationId + ", " + branchName))) .map(application -> application.getId()); } public Mono findBranchedApplicationId( - Optional branchName, String defaultApplicationId, Optional permission) { + Optional branchName, String baseApplicationId, Optional permission) { if (branchName.isEmpty()) { - if (!StringUtils.hasLength(defaultApplicationId)) { + if (!StringUtils.hasLength(baseApplicationId)) { return Mono.error(new AppsmithException( - AppsmithError.INVALID_PARAMETER, FieldName.APPLICATION_ID, defaultApplicationId)); + AppsmithError.INVALID_PARAMETER, FieldName.APPLICATION_ID, baseApplicationId)); } - return Mono.just(defaultApplicationId); + return Mono.just(baseApplicationId); } return repository - .getApplicationByGitBranchAndDefaultApplicationId(defaultApplicationId, branchName.get(), permission) + .getApplicationByGitBranchAndBaseApplicationId(baseApplicationId, branchName.get(), permission) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, - FieldName.APPLICATION, - defaultApplicationId + ", " + branchName))) + AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, baseApplicationId + ", " + branchName))) .map(Application::getId); } @@ -902,13 +868,19 @@ public class ApplicationServiceCEImpl extends BaseService findAllApplicationsByDefaultApplicationId( - String defaultApplicationId, AclPermission permission) { - return repository.getApplicationByGitDefaultApplicationId(defaultApplicationId, permission); + public Flux findAllApplicationsByBaseApplicationId( + String baseApplicationId, AclPermission permission) { + return repository.getApplicationByGitBaseApplicationId(baseApplicationId, permission); + } + + @Override + public Flux findAllBranchedApplicationIdsByBranchedApplicationId( + String branchedApplicationId, AclPermission permission) { + return repository.findAllBranchedApplicationIdsByBranchedApplicationId(branchedApplicationId, permission); } @Override @@ -928,8 +900,8 @@ public class ApplicationServiceCEImpl extends BaseService getApplicationByDefaultApplicationIdAndDefaultBranch(String defaultApplicationId) { - return repository.getApplicationByDefaultApplicationIdAndDefaultBranch(defaultApplicationId); + public Mono getApplicationByBaseApplicationIdAndDefaultBranch(String baseApplicationId) { + return repository.getApplicationByBaseApplicationIdAndDefaultBranch(baseApplicationId); } @Override @@ -938,9 +910,8 @@ public class ApplicationServiceCEImpl extends BaseService saveAppNavigationLogo(String branchName, String applicationId, Part filePart) { - return this.findByBranchNameAndDefaultApplicationId( - branchName, applicationId, applicationPermission.getEditPermission()) + public Mono saveAppNavigationLogo(String branchedApplicationId, Part filePart) { + return this.findById(branchedApplicationId, applicationPermission.getEditPermission()) .flatMap(branchedApplication -> { branchedApplication.setUnpublishedApplicationDetail(ObjectUtils.defaultIfNull( branchedApplication.getUnpublishedApplicationDetail(), new ApplicationDetail())); @@ -969,7 +940,7 @@ public class ApplicationServiceCEImpl extends BaseService updateMono = - this.update(applicationId, branchedApplication, branchName); + this.updateApplicationWithPresets(branchedApplicationId, branchedApplication); if (!StringUtils.hasLength(oldAssetId)) { return updateMono; @@ -996,9 +967,8 @@ public class ApplicationServiceCEImpl extends BaseService deleteAppNavigationLogo(String branchName, String applicationId) { - return this.findByBranchNameAndDefaultApplicationId( - branchName, applicationId, applicationPermission.getEditPermission()) + public Mono deleteAppNavigationLogo(String branchedApplicationId) { + return this.findById(branchedApplicationId, applicationPermission.getEditPermission()) .flatMap(branchedApplication -> { branchedApplication.setUnpublishedApplicationDetail(ObjectUtils.defaultIfNull( branchedApplication.getUnpublishedApplicationDetail(), new ApplicationDetail())); @@ -1042,6 +1012,11 @@ public class ApplicationServiceCEImpl extends BaseService findBranchedApplicationIdsByBaseApplicationId(String baseApplicationId) { + return repository.findBranchedApplicationIdsByBaseApplicationId(baseApplicationId); + } + /** * Gets branched application with the right permission set based on mode of application * @param defaultApplicationId : default app id @@ -1050,14 +1025,24 @@ public class ApplicationServiceCEImpl extends BaseService findByDefaultIdBranchNameAndApplicationMode( + public Mono findByBaseIdBranchNameAndApplicationMode( String defaultApplicationId, String branchName, ApplicationMode mode) { AclPermission permissionForApplication = ApplicationMode.PUBLISHED.equals(mode) ? applicationPermission.getReadPermission() : applicationPermission.getEditPermission(); - return findByBranchNameAndDefaultApplicationId(branchName, defaultApplicationId, permissionForApplication) - // sets isPublic field in the application - .flatMap(this::setTransientFields); + return findByBranchNameAndBaseApplicationId(branchName, defaultApplicationId, permissionForApplication); + } + + @Override + public Mono findByBranchedApplicationIdAndApplicationMode( + String branchedApplicationId, ApplicationMode mode) { + AclPermission permissionForApplication = ApplicationMode.PUBLISHED.equals(mode) + ? applicationPermission.getReadPermission() + : applicationPermission.getEditPermission(); + + return findById(branchedApplicationId, permissionForApplication) + .switchIfEmpty(Mono.error(new AppsmithException( + AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, branchedApplicationId))); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceImpl.java index d9ed08a21b..f0e00e247c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationServiceImpl.java @@ -1,6 +1,5 @@ package com.appsmith.server.applications.base; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.repositories.ApplicationRepository; import com.appsmith.server.repositories.NewActionRepository; import com.appsmith.server.services.AnalyticsService; @@ -27,7 +26,6 @@ public class ApplicationServiceImpl extends ApplicationServiceCECompatibleImpl i ApplicationRepository repository, AnalyticsService analyticsService, PolicySolution policySolution, - ResponseUtils responseUtils, PermissionGroupService permissionGroupService, NewActionRepository newActionRepository, AssetService assetService, @@ -37,13 +35,11 @@ public class ApplicationServiceImpl extends ApplicationServiceCECompatibleImpl i UserDataService userDataService, WorkspaceService workspaceService, WorkspacePermission workspacePermission) { - super( validator, repository, analyticsService, policySolution, - responseUtils, permissionGroupService, newActionRepository, assetService, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/exports/ApplicationExportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/exports/ApplicationExportServiceCEImpl.java index 4a594718bd..7bb62f9655 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/exports/ApplicationExportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/exports/ApplicationExportServiceCEImpl.java @@ -82,7 +82,7 @@ public class ApplicationExportServiceCEImpl implements ArtifactBasedExportServic String artifactId, String branchName, AclPermission aclPermission) { if (StringUtils.hasText(branchName)) { - return applicationService.findByBranchNameAndDefaultApplicationId(branchName, artifactId, aclPermission); + return applicationService.findByBranchNameAndBaseApplicationId(branchName, artifactId, aclPermission); } // find the application with appropriate permission diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/ApplicationGitFileUtilsCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/ApplicationGitFileUtilsCEImpl.java index efa457376e..39a87d72fa 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/ApplicationGitFileUtilsCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/ApplicationGitFileUtilsCEImpl.java @@ -346,17 +346,16 @@ public class ApplicationGitFileUtilsCEImpl implements ArtifactGitFileUtilsCE reconstructArtifactExchangeJsonFromFilesInRepository( - String workspaceId, String defaultArtifactId, String repoName, String branchName) { - - Mono appReferenceMono = fileUtils.reconstructApplicationReferenceFromGitRepo( - workspaceId, defaultArtifactId, repoName, branchName); + String workspaceId, String baseArtifactId, String repoName, String branchName) { + Mono appReferenceMono = + fileUtils.reconstructApplicationReferenceFromGitRepo(workspaceId, baseArtifactId, repoName, branchName); return appReferenceMono.flatMap(applicationReference -> { // Extract application metadata from the json ApplicationJson metadata = diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/GitApplicationHelperCECompatibleImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/GitApplicationHelperCECompatibleImpl.java index a713b1a2b9..f5d236e5b1 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/GitApplicationHelperCECompatibleImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/GitApplicationHelperCECompatibleImpl.java @@ -5,7 +5,6 @@ import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.domains.Application; import com.appsmith.server.helpers.CommonGitFileUtils; import com.appsmith.server.helpers.GitPrivateRepoHelper; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.migrations.JsonSchemaVersions; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; @@ -28,7 +27,6 @@ public class GitApplicationHelperCECompatibleImpl extends GitApplicationHelperCE NewPageService newPageService, ActionCollectionService actionCollectionService, NewActionService newActionService, - ResponseUtils responseUtils, JsonSchemaVersions jsonSchemaVersions) { super( commonGitFileUtils, @@ -39,7 +37,6 @@ public class GitApplicationHelperCECompatibleImpl extends GitApplicationHelperCE newPageService, actionCollectionService, newActionService, - responseUtils, jsonSchemaVersions); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/GitApplicationHelperCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/GitApplicationHelperCEImpl.java index 00f390266f..366465523c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/GitApplicationHelperCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/GitApplicationHelperCEImpl.java @@ -19,7 +19,6 @@ import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.CollectionUtils; import com.appsmith.server.helpers.CommonGitFileUtils; import com.appsmith.server.helpers.GitPrivateRepoHelper; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.migrations.JsonSchemaVersions; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; @@ -42,8 +41,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import static com.appsmith.server.helpers.DefaultResourcesUtils.createDefaultIdsOrUpdateWithGivenResourceIds; - @Slf4j @Service @RequiredArgsConstructor @@ -58,7 +55,6 @@ public class GitApplicationHelperCEImpl implements GitArtifactHelperCE getAllArtifactByDefaultId(String defaultArtifactId, AclPermission aclPermission) { - return applicationService.findAllApplicationsByDefaultApplicationId(defaultArtifactId, aclPermission); + public Flux getAllArtifactByBaseId(String baseArtifactId, AclPermission aclPermission) { + return applicationService.findAllApplicationsByBaseApplicationId(baseArtifactId, aclPermission); } @Override - public Mono getArtifactByDefaultIdAndBranchName( - String defaultArtifactId, String branchName, AclPermission aclPermission) { - return applicationService.findByBranchNameAndDefaultApplicationId(branchName, defaultArtifactId, aclPermission); + public Mono getArtifactByBaseIdAndBranchName( + String baseArtifactId, String branchName, AclPermission aclPermission) { + return applicationService.findByBranchNameAndBaseApplicationId(branchName, baseArtifactId, aclPermission); } @Override - public Mono getSshKeys(String defaultArtifactId) { - return applicationService.getSshKey(defaultArtifactId); + public Mono getSshKeys(String baseArtifactId) { + return applicationService.getSshKey(baseArtifactId); } @Override @@ -156,8 +152,8 @@ public class GitApplicationHelperCEImpl implements GitArtifactHelperCE updateArtifactWithProtectedBranches(String defaultArtifactId, List branchNames) { - return applicationService.updateProtectedBranches(defaultArtifactId, branchNames); + public Mono updateArtifactWithProtectedBranches(String baseArtifactId, List branchNames) { + return applicationService.updateProtectedBranches(baseArtifactId, branchNames); } @Override @@ -183,7 +179,7 @@ public class GitApplicationHelperCEImpl implements GitArtifactHelperCE publishArtifact(Artifact artifact, Boolean isPublishedManually) { Application application = (Application) artifact; - return applicationPageService.publish(application.getId(), isPublishedManually); + return applicationPageService.publishWithoutPermissionChecks(application.getId(), isPublishedManually); } // TODO: scope for improvement @@ -192,16 +188,16 @@ public class GitApplicationHelperCEImpl implements GitArtifactHelperCE applicationPage.getIsDefault().equals(Boolean.TRUE)) .toList() .get(0) .getId(); } - String viewModeUrl = Paths.get("/", Entity.APPLICATIONS, "/", artifact.getId(), Entity.PAGES, defaultPageId) + String viewModeUrl = Paths.get("/", Entity.APPLICATIONS, "/", artifact.getId(), Entity.PAGES, basePageId) .toString(); String editModeUrl = Paths.get(viewModeUrl, "edit").toString(); @@ -218,12 +214,11 @@ public class GitApplicationHelperCEImpl implements GitArtifactHelperCE deleteAllBranches(String defaultArtifactId, List branches) { + public Flux deleteAllBranches(String baseArtifactId, List branches) { AclPermission appEditPermission = getArtifactEditPermission(); return Flux.fromIterable(branches) - .flatMap(branchName -> - getArtifactByDefaultIdAndBranchName(defaultArtifactId, branchName, appEditPermission)) + .flatMap(branchName -> getArtifactByBaseIdAndBranchName(baseArtifactId, branchName, appEditPermission)) .flatMap(applicationPageService::deleteApplicationByResource); } @@ -234,32 +229,33 @@ public class GitApplicationHelperCEImpl implements GitArtifactHelperCE page.setDefaultPageId(page.getId())); + if (!CollectionUtils.isNullOrEmpty(baseApplication.getPages())) { + baseApplication.getPages().forEach(page -> page.setDefaultPageId(page.getId())); } - if (!CollectionUtils.isNullOrEmpty(defaultApplication.getPublishedPages())) { - defaultApplication.getPublishedPages().forEach(page -> page.setDefaultPageId(page.getId())); + if (!CollectionUtils.isNullOrEmpty(baseApplication.getPublishedPages())) { + baseApplication.getPublishedPages().forEach(page -> page.setDefaultPageId(page.getId())); } } @Override - public Mono disconnectEntitiesOfDefaultArtifact(Artifact defaultArtifact) { - Application defaultApplication = (Application) defaultArtifact; + public Mono disconnectEntitiesOfBaseArtifact(Artifact baseArtifact) { + Application baseApplication = (Application) baseArtifact; - // Update all the resources to replace defaultResource Ids with the resource Ids as branchName + // Update all the resources to replace base Ids with the resource Ids as branchName // will be deleted - Flux newPageFlux = Flux.fromIterable(defaultApplication.getPages()) + Flux newPageFlux = Flux.fromIterable(baseApplication.getPages()) .flatMap(page -> newPageService.findById(page.getId(), null)) .map(newPage -> { - newPage.setDefaultResources(null); - return createDefaultIdsOrUpdateWithGivenResourceIds(newPage, null); + newPage.setBaseId(newPage.getId()); + newPage.setBranchName(null); + return newPage; }) .collectList() .flatMapMany(newPageService::saveAll) @@ -269,14 +265,9 @@ public class GitApplicationHelperCEImpl implements GitArtifactHelperCE { - newAction.setDefaultResources(null); - if (newAction.getUnpublishedAction() != null) { - newAction.getUnpublishedAction().setDefaultResources(null); - } - if (newAction.getPublishedAction() != null) { - newAction.getPublishedAction().setDefaultResources(null); - } - return createDefaultIdsOrUpdateWithGivenResourceIds(newAction, null); + newAction.setBaseId(newAction.getId()); + newAction.setBranchName(null); + return newAction; }) .collectList() .flatMapMany(newActionService::saveAll); @@ -286,27 +277,15 @@ public class GitApplicationHelperCEImpl implements GitArtifactHelperCE { - actionCollection.setDefaultResources(null); - if (actionCollection.getUnpublishedCollection() != null) { - actionCollection.getUnpublishedCollection().setDefaultResources(null); - } - if (actionCollection.getPublishedCollection() != null) { - actionCollection.getPublishedCollection().setDefaultResources(null); - } - return createDefaultIdsOrUpdateWithGivenResourceIds(actionCollection, null); + actionCollection.setBaseId(actionCollection.getId()); + actionCollection.setBranchName(null); + return actionCollection; }) .collectList() .flatMapMany(actionCollectionService::saveAll); }); - return Flux.merge(actionCollectionFlux, newActionFlux) - .then(Mono.just(defaultApplication)) - .map(responseUtils::updateApplicationWithDefaultResources); - } - - @Override - public Application updateArtifactWithDefaultReponseUtils(Artifact artifact) { - return responseUtils.updateApplicationWithDefaultResources((Application) artifact); + return Flux.merge(actionCollectionFlux, newActionFlux).then(Mono.just(baseApplication)); } @Override diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/GitApplicationHelperImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/GitApplicationHelperImpl.java index 1faeff54d0..c9f3bd9b8a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/GitApplicationHelperImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/git/GitApplicationHelperImpl.java @@ -5,7 +5,6 @@ import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.domains.Application; import com.appsmith.server.helpers.CommonGitFileUtils; import com.appsmith.server.helpers.GitPrivateRepoHelper; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.migrations.JsonSchemaVersions; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; @@ -21,7 +20,7 @@ public class GitApplicationHelperImpl extends GitApplicationHelperCECompatibleIm implements GitArtifactHelper { public GitApplicationHelperImpl( - CommonGitFileUtils gitFileUtils, + CommonGitFileUtils commonGitFileUtils, GitPrivateRepoHelper gitPrivateRepoHelper, ApplicationService applicationService, ApplicationPageService applicationPageService, @@ -29,10 +28,9 @@ public class GitApplicationHelperImpl extends GitApplicationHelperCECompatibleIm NewPageService newPageService, ActionCollectionService actionCollectionService, NewActionService newActionService, - ResponseUtils responseUtils, JsonSchemaVersions jsonSchemaVersions) { super( - gitFileUtils, + commonGitFileUtils, gitPrivateRepoHelper, applicationService, applicationPageService, @@ -40,7 +38,6 @@ public class GitApplicationHelperImpl extends GitApplicationHelperCECompatibleIm newPageService, actionCollectionService, newActionService, - responseUtils, jsonSchemaVersions); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/imports/ApplicationImportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/imports/ApplicationImportServiceCEImpl.java index 3babdf67da..e00e3db119 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/imports/ApplicationImportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/imports/ApplicationImportServiceCEImpl.java @@ -310,10 +310,8 @@ public class ApplicationImportServiceCEImpl } if (applicationJson.getCustomJSLibList() != null) { - List importedCustomJSLibList = applicationJson.getCustomJSLibList().stream() - .peek(customJSLib -> customJSLib.setGitSyncId( - null)) // setting this null so that this custom js lib can be imported again - .collect(Collectors.toList()); + List importedCustomJSLibList = + applicationJson.getCustomJSLibList().stream().collect(Collectors.toList()); applicationJson.setCustomJSLibList(importedCustomJSLibList); } } @@ -459,6 +457,12 @@ public class ApplicationImportServiceCEImpl } } return importApplicationMono + .doOnNext(application -> { + if (application.getGitArtifactMetadata() != null) { + importingMetaDTO.setBranchName( + application.getGitArtifactMetadata().getBranchName()); + } + }) .elapsed() .map(tuples -> { log.debug("time to create or update application object: {}", tuples.getT1()); @@ -585,8 +589,8 @@ public class ApplicationImportServiceCEImpl Mono importableArtifactMono, ArtifactExchangeJson artifactExchangeJson) { - return importableArtifactMono.flatMapMany(importableContext -> { - Application application = (Application) importableContext; + return importableArtifactMono.flatMapMany(importableArtifact -> { + Application application = (Application) importableArtifact; ApplicationJson applicationJson = (ApplicationJson) artifactExchangeJson; List> pageDependentImportables = getPageDependentImportables( @@ -621,13 +625,18 @@ public class ApplicationImportServiceCEImpl } @Override - public Mono> getDatasourceIdSetConsumedInArtifact(String defaultApplicationId) { + public Mono> getDatasourceIdSetConsumedInArtifact(String baseArtifactId) { return newActionService - .findAllByApplicationIdAndViewMode(defaultApplicationId, false, Optional.empty(), Optional.empty()) + .findAllByApplicationIdAndViewMode(baseArtifactId, false, Optional.empty(), Optional.empty()) .filter(newAction -> StringUtils.hasText( newAction.getUnpublishedAction().getDatasource().getId())) .mapNotNull(newAction -> newAction.getUnpublishedAction().getDatasource().getId()) .collect(Collectors.toSet()); } + + @Override + public Flux getBranchedArtifactIdsByBranchedArtifactId(String branchedArtifactId) { + return applicationService.findAllBranchedApplicationIdsByBranchedApplicationId(branchedArtifactId, null); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/jslibs/ApplicationJsLibServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/jslibs/ApplicationJsLibServiceCEImpl.java index 8aab08d76e..56f2002cc5 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/jslibs/ApplicationJsLibServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/jslibs/ApplicationJsLibServiceCEImpl.java @@ -21,15 +21,14 @@ public class ApplicationJsLibServiceCEImpl implements ContextBasedJsLibServiceCE @Override public Mono> getAllVisibleJSLibContextDTOFromContext( - String contextId, String branchName, Boolean isViewMode) { + String branchedContextId, Boolean isViewMode) { return applicationService - .findByIdAndBranchName( - contextId, + .findByBranchedId( + branchedContextId, List.of( isViewMode ? Application.Fields.publishedCustomJSLibs - : Application.Fields.unpublishedCustomJSLibs), - branchName) + : Application.Fields.unpublishedCustomJSLibs)) .map(application -> { if (isViewMode) { return application.getPublishedCustomJSLibs() == null @@ -45,8 +44,8 @@ public class ApplicationJsLibServiceCEImpl implements ContextBasedJsLibServiceCE @Override public Mono updateJsLibsInContext( - String contextId, String branchName, Set updatedJSLibDTOSet) { + String branchedContextId, Set updatedJSLibDTOSet) { Map fieldNameValueMap = Map.of(Application.Fields.unpublishedCustomJSLibs, updatedJSLibDTOSet); - return applicationService.update(contextId, fieldNameValueMap, branchName); + return applicationService.updateByBranchedIdAndFieldsMap(branchedContextId, fieldNameValueMap); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/MongoConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/MongoConfig.java index 6cbf63c2b7..4f7fd3fb63 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/MongoConfig.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/MongoConfig.java @@ -12,14 +12,16 @@ import com.google.common.collect.ImmutableSet; import com.google.common.reflect.ClassPath; import com.mongodb.ReadConcern; import com.mongodb.WriteConcern; +import com.mongodb.reactivestreams.client.MongoClient; import io.mongock.api.annotations.ChangeUnit; -import io.mongock.driver.mongodb.springdata.v4.SpringDataMongoV4Driver; +import io.mongock.driver.mongodb.reactive.driver.MongoReactiveDriver; import io.mongock.runner.springboot.MongockSpringboot; import io.mongock.runner.springboot.RunnerSpringbootBuilder; import io.mongock.runner.springboot.base.MongockInitializingBeanRunner; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.bson.conversions.Bson; +import org.springframework.boot.autoconfigure.mongo.MongoProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -65,7 +67,7 @@ import java.util.Set; public class MongoConfig { private static final Set FORBIDDEN_IDS = Set.of( - // List generated during PR developmeng with the following command: + // List generated during PR development with the following command: // git diff release HEAD | awk -F\" '/^-[[:space:]]+@ChangeSet/ {print "\"" $4 "\","}' // Any deleted migration in the future, should go into this list. "remove-org-name-index", @@ -168,13 +170,14 @@ public class MongoConfig { */ @Bean public MongockInitializingBeanRunner mongockInitializingBeanRunner( - ApplicationContext springContext, MongoTemplate mongoTemplate) { - SpringDataMongoV4Driver mongoDriver = SpringDataMongoV4Driver.withDefaultLock(mongoTemplate); - mongoDriver.setWriteConcern(WriteConcern.JOURNALED.withJournal(false)); - mongoDriver.setReadConcern(ReadConcern.LOCAL); + ApplicationContext springContext, MongoClient mongoClient, MongoProperties mongoProperties) { + MongoReactiveDriver driver = + MongoReactiveDriver.withDefaultLock(mongoClient, mongoProperties.getMongoClientDatabase()); + driver.setWriteConcern(WriteConcern.JOURNALED.withJournal(false)); + driver.setReadConcern(ReadConcern.LOCAL); final RunnerSpringbootBuilder runnerBuilder = MongockSpringboot.builder() - .setDriver(mongoDriver) + .setDriver(driver) .addChangeLogsScanPackages(List.of("com.appsmith.server.migrations")) .addMigrationScanPackage("com.appsmith.server.migrations.db") .setSpringContext(springContext); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java index f11aed5390..4dc3e36c20 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java @@ -25,7 +25,6 @@ public class FieldNameCE { public static final String LAYOUT_ID = "layoutId"; public static final String APPLICATION_ID = "applicationId"; public static final String SOURCE_APPLICATION_ID = "sourceApplicationId"; - public static final String DEFAULT_RESOURCES = "defaultResources"; public static final String PLUGIN_ID = "pluginId"; public static final String DATASOURCE = "datasource"; public static final String CONFIG = "config"; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ConsolidatedAPIController.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ConsolidatedAPIController.java index 3b1d165176..ee2b15db45 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ConsolidatedAPIController.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ConsolidatedAPIController.java @@ -45,23 +45,23 @@ public class ConsolidatedAPIController { @JsonView(Views.Public.class) @GetMapping("/edit") public Mono> getAllDataForFirstPageLoadForEditMode( - @RequestParam(required = false) String applicationId, - @RequestParam(required = false) String defaultPageId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @RequestParam(name = FieldName.APPLICATION_ID, required = false) String baseApplicationId, + @RequestParam(name = "defaultPageId", required = false) String basePageId, + @RequestHeader(required = false) String branchName) { log.debug( - "Going to fetch consolidatedAPI response for applicationId: {}, defaultPageId: {}, branchName: {}, " + "Going to fetch consolidatedAPI response for baseApplicationId: {}, basePageId: {}, branchName: {}, " + "mode: {}", - applicationId, - defaultPageId, + baseApplicationId, + basePageId, branchName, ApplicationMode.EDIT); return consolidatedAPIService - .getConsolidatedInfoForPageLoad(defaultPageId, applicationId, branchName, ApplicationMode.EDIT) + .getConsolidatedInfoForPageLoad(basePageId, baseApplicationId, branchName, ApplicationMode.EDIT) .map(consolidatedAPIResponseDTO -> new ResponseDTO<>(HttpStatus.OK.value(), consolidatedAPIResponseDTO, null)) - .tag("pageId", Objects.toString(defaultPageId)) - .tag("applicationId", Objects.toString(applicationId)) + .tag("pageId", Objects.toString(basePageId)) + .tag("applicationId", Objects.toString(baseApplicationId)) .tag("branchName", Objects.toString(branchName)) .name(CONSOLIDATED_API_ROOT_EDIT) .tap(Micrometer.observation(observationRegistry)); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ActionCollectionControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ActionCollectionControllerCE.java index dcb8b1069a..633dbf2fe4 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ActionCollectionControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ActionCollectionControllerCE.java @@ -2,7 +2,6 @@ package com.appsmith.server.controllers.ce; import com.appsmith.external.views.Views; import com.appsmith.server.actioncollections.base.ActionCollectionService; -import com.appsmith.server.constants.FieldName; import com.appsmith.server.constants.Url; import com.appsmith.server.dtos.ActionCollectionDTO; import com.appsmith.server.dtos.ActionCollectionMoveDTO; @@ -25,7 +24,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; @@ -53,26 +51,20 @@ public class ActionCollectionControllerCE { @JsonView(Views.Public.class) @PostMapping @ResponseStatus(HttpStatus.CREATED) - public Mono> create( - @Valid @RequestBody ActionCollectionDTO resource, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug( - "Going to create action collection {}, branch: {}", - resource.getClass().getName(), - branchName); + public Mono> create(@Valid @RequestBody ActionCollectionDTO resource) { + log.debug("Going to create action collection {}", resource.getClass().getName()); return layoutCollectionService - .createCollection(resource, branchName) + .createCollection(resource) .map(created -> new ResponseDTO<>(HttpStatus.CREATED.value(), created, null)); } @JsonView(Views.Public.class) @GetMapping("") public Mono>> getAllUnpublishedActionCollections( - @RequestParam MultiValueMap params, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to get all unpublished action collections with params: {}, branch: {}", params, branchName); + @RequestParam MultiValueMap params) { + log.debug("Going to get all unpublished action collections with params: {}", params); return actionCollectionService - .getPopulatedActionCollectionsByViewMode(params, false, branchName) + .getPopulatedActionCollectionsByViewMode(params, false) .collectList() .map(resources -> new ResponseDTO<>(HttpStatus.OK.value(), resources, null)); } @@ -80,40 +72,33 @@ public class ActionCollectionControllerCE { @JsonView(Views.Public.class) @PutMapping("/move") public Mono> moveActionCollection( - @RequestBody @Valid ActionCollectionMoveDTO actionCollectionMoveDTO, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @RequestBody @Valid ActionCollectionMoveDTO actionCollectionMoveDTO) { log.debug( - "Going to move action collection with id {} to page {}, on branch:{}", + "Going to move action collection with id {} to page {}", actionCollectionMoveDTO.getCollectionId(), - actionCollectionMoveDTO.getDestinationPageId(), - branchName); + actionCollectionMoveDTO.getDestinationPageId()); return layoutCollectionService - .moveCollection(actionCollectionMoveDTO, branchName) + .moveCollection(actionCollectionMoveDTO) .map(actionCollection -> new ResponseDTO<>(HttpStatus.OK.value(), actionCollection, null)); } @JsonView(Views.Public.class) @PutMapping("/refactor") public Mono> refactorActionCollectionName( - @RequestBody RefactorEntityNameDTO refactorEntityNameDTO, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @RequestBody RefactorEntityNameDTO refactorEntityNameDTO) { refactorEntityNameDTO.setEntityType(EntityType.JS_OBJECT); return refactoringService - .refactorEntityName(refactorEntityNameDTO, branchName) + .refactorEntityName(refactorEntityNameDTO) .map(created -> new ResponseDTO<>(HttpStatus.OK.value(), created, null)); } @JsonView(Views.Public.class) @GetMapping("/view") public Mono>> getAllPublishedActionCollections( - @RequestParam String applicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug( - "Going to get all published action collections with application Id: {}, branch: {}", - applicationId, - branchName); + @RequestParam String applicationId) { + log.debug("Going to get all published action collections with application Id: {}", applicationId); return actionCollectionService - .getActionCollectionsForViewMode(applicationId, branchName) + .getActionCollectionsForViewMode(applicationId, null) .collectList() .map(resources -> new ResponseDTO<>(HttpStatus.OK.value(), resources, null)); } @@ -121,49 +106,43 @@ public class ActionCollectionControllerCE { @JsonView(Views.Public.class) @PutMapping("/{id}") public Mono> updateActionCollection( - @PathVariable String id, - @Valid @RequestBody ActionCollectionDTO resource, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to update action collection with id: {}, branch: {}", id, branchName); + @PathVariable String id, @Valid @RequestBody ActionCollectionDTO resource) { + log.debug("Going to update action collection with id: {}", id); return layoutCollectionService - .updateUnpublishedActionCollection(id, resource, branchName) + .updateUnpublishedActionCollection(id, resource) .map(updatedResource -> new ResponseDTO<>(HttpStatus.OK.value(), updatedResource, null)); } @JsonView(Views.Public.class) @PutMapping("/{id}/body") public Mono> updateActionCollectionBody( - @PathVariable String id, - @Valid @RequestBody ActionCollectionDTO resource, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to update action collection body with id: {}, branch: {}", id, branchName); + @PathVariable String id, @Valid @RequestBody ActionCollectionDTO resource) { + log.debug("Going to update action collection body with id: {}", id); return layoutCollectionService - .updateUnpublishedActionCollectionBody(id, resource, branchName) + .updateUnpublishedActionCollectionBody(id, resource) .map(updatedResource -> new ResponseDTO<>(HttpStatus.OK.value(), updatedResource, null)); } @JsonView(Views.Public.class) @PutMapping("/refactorAction") public Mono> refactorActionCollection( - @Valid @RequestBody RefactorEntityNameDTO refactorEntityNameDTO, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @Valid @RequestBody RefactorEntityNameDTO refactorEntityNameDTO) { log.debug( "Going to refactor action collection with id: {}", refactorEntityNameDTO.getActionCollection().getId()); refactorEntityNameDTO.setEntityType(EntityType.JS_ACTION); return refactoringService - .refactorEntityName(refactorEntityNameDTO, branchName) + .refactorEntityName(refactorEntityNameDTO) .map(updatedResource -> new ResponseDTO<>(HttpStatus.OK.value(), updatedResource, null)); } @JsonView(Views.Public.class) @DeleteMapping("/{id}") - public Mono> deleteActionCollection( - @PathVariable String id, @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + public Mono> deleteActionCollection(@PathVariable String id) { log.debug("Going to delete unpublished action collection with id: {}", id); return actionCollectionService - .deleteUnpublishedActionCollection(id, branchName) + .deleteUnpublishedActionCollection(id) .map(deletedResource -> new ResponseDTO<>(HttpStatus.OK.value(), deletedResource, null)); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ActionControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ActionControllerCE.java index e4c1089626..62f437a437 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ActionControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ActionControllerCE.java @@ -54,23 +54,21 @@ public class ActionControllerCE { @PostMapping @ResponseStatus(HttpStatus.CREATED) public Mono> createAction( - @Valid @RequestBody @JsonView(FromRequest.class) ActionDTO resource, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @Valid @RequestBody @JsonView(FromRequest.class) ActionDTO resource) { log.debug("Going to create resource {}", resource.getClass().getName()); return layoutActionService - .createSingleActionWithBranch(resource, branchName) + .createSingleAction(resource) .map(created -> new ResponseDTO<>(HttpStatus.CREATED.value(), created, null)); } @JsonView(Views.Public.class) - @PutMapping("/{defaultActionId}") + @PutMapping("/{branchedActionId}") public Mono> updateAction( - @PathVariable String defaultActionId, - @Valid @RequestBody @JsonView(FromRequest.class) ActionDTO resource, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to update resource with defaultActionId: {}, branch: {}", defaultActionId, branchName); + @PathVariable String branchedActionId, + @Valid @RequestBody @JsonView(FromRequest.class) ActionDTO resource) { + log.debug("Going to update resource with branchedActionId: {}", branchedActionId); return layoutActionService - .updateSingleActionWithBranchName(defaultActionId, resource, branchName) + .updateNewActionByBranchedId(branchedActionId, resource) .map(updatedResource -> new ResponseDTO<>(HttpStatus.OK.value(), updatedResource, null)); } @@ -78,71 +76,54 @@ public class ActionControllerCE { @PostMapping(value = "/execute", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public Mono> executeAction( @RequestBody Flux partFlux, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, @RequestHeader(name = FieldName.HEADER_ENVIRONMENT_ID, required = false) String environmentId, ServerWebExchange serverWebExchange) { return actionExecutionSolution .executeAction( - partFlux, - branchName, - environmentId, - serverWebExchange.getRequest().getHeaders(), - Boolean.FALSE) + partFlux, environmentId, serverWebExchange.getRequest().getHeaders(), Boolean.FALSE) .map(updatedResource -> new ResponseDTO<>(HttpStatus.OK.value(), updatedResource, null)); } @JsonView(Views.Public.class) @PutMapping("/move") - public Mono> moveAction( - @RequestBody @Valid ActionMoveDTO actionMoveDTO, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + public Mono> moveAction(@RequestBody @Valid ActionMoveDTO actionMoveDTO) { log.debug( - "Going to move action {} from page {} to page {} on branch {}", + "Going to move action {} from page {} to page {}", actionMoveDTO.getAction().getName(), actionMoveDTO.getAction().getPageId(), - actionMoveDTO.getDestinationPageId(), - branchName); + actionMoveDTO.getDestinationPageId()); return layoutActionService - .moveAction(actionMoveDTO, branchName) + .moveAction(actionMoveDTO) .map(action -> new ResponseDTO<>(HttpStatus.OK.value(), action, null)); } @JsonView(Views.Public.class) @PutMapping("/refactor") - public Mono> refactorActionName( - @RequestBody RefactorEntityNameDTO refactorEntityNameDTO, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + public Mono> refactorActionName(@RequestBody RefactorEntityNameDTO refactorEntityNameDTO) { refactorEntityNameDTO.setEntityType(EntityType.ACTION); return refactoringService - .refactorEntityName(refactorEntityNameDTO, branchName) + .refactorEntityName(refactorEntityNameDTO) .map(created -> new ResponseDTO<>(HttpStatus.OK.value(), created, null)); } @JsonView(Views.Public.class) @GetMapping("/view") public Mono>> getActionsForViewMode( - @RequestParam String applicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @RequestParam(name = FieldName.APPLICATION_ID) String branchedApplicationId) { return newActionService - .getActionsForViewMode(applicationId, branchName) + .getActionsForViewMode(branchedApplicationId) .collectList() .map(actions -> new ResponseDTO<>(HttpStatus.OK.value(), actions, null)); } @JsonView(Views.Public.class) - @PutMapping("/executeOnLoad/{defaultActionId}") + @PutMapping("/executeOnLoad/{branchedActionId}") public Mono> setExecuteOnLoad( - @PathVariable String defaultActionId, - @RequestParam Boolean flag, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug( - "Going to set execute on load for action id {} and branchName {} to {}", - defaultActionId, - branchName, - flag); + @PathVariable String branchedActionId, @RequestParam Boolean flag) { + log.debug("Going to set execute on load for action id {} to {}", branchedActionId, flag); return layoutActionService - .setExecuteOnLoad(defaultActionId, branchName, flag) + .setExecuteOnLoad(branchedActionId, flag) .map(action -> new ResponseDTO<>(HttpStatus.OK.value(), action, null)); } @@ -152,7 +133,7 @@ public class ActionControllerCE { @PathVariable String id, @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { log.debug("Going to delete unpublished action with id: {}, branchName: {}", id, branchName); return layoutActionService - .deleteUnpublishedAction(id, branchName) + .deleteUnpublishedAction(id) .map(deletedResource -> new ResponseDTO<>(HttpStatus.OK.value(), deletedResource, null)); } @@ -166,13 +147,12 @@ public class ActionControllerCE { @JsonView(Views.Public.class) @GetMapping("") public Mono>> getAllUnpublishedActions( - @RequestParam MultiValueMap params, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to get all actions with params: {}, branch: {}", params, branchName); - // We handle JS actions as part of the collections request, so that all the contextual variables are also picked - // up + @RequestParam MultiValueMap params) { + log.debug("Going to get all actions with params: {}", params); + // We handle JS actions as part of the collections request, + // so that all the contextual variables are also picked up return newActionService - .getUnpublishedActionsExceptJs(params, branchName) + .getUnpublishedActionsExceptJs(params) .collectList() .map(resources -> new ResponseDTO<>(HttpStatus.OK.value(), resources, null)); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ApplicationControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ApplicationControllerCE.java index 872c9ab606..90f7e717d2 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ApplicationControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ApplicationControllerCE.java @@ -84,44 +84,41 @@ public class ApplicationControllerCE { } @JsonView(Views.Public.class) - @PostMapping("/publish/{defaultApplicationId}") + @PostMapping("/publish/{branchedApplicationId}") public Mono> publish( - @PathVariable String defaultApplicationId, + @PathVariable String branchedApplicationId, @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { return applicationPageService - .publish(defaultApplicationId, branchName, true) + .publish(branchedApplicationId, true) .thenReturn(new ResponseDTO<>(HttpStatus.OK.value(), true, null)); } @JsonView(Views.Public.class) - @PutMapping("/{defaultApplicationId}/page/{defaultPageId}/makeDefault") + @PutMapping("/{branchedApplicationId}/page/{branchedPageId}/makeDefault") public Mono> makeDefault( - @PathVariable String defaultApplicationId, - @PathVariable String defaultPageId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @PathVariable String branchedApplicationId, @PathVariable String branchedPageId) { return applicationPageService - .makePageDefault(defaultApplicationId, defaultPageId, branchName) + .makePageDefault(branchedApplicationId, branchedPageId) .map(updatedApplication -> new ResponseDTO<>(HttpStatus.OK.value(), updatedApplication, null)); } @JsonView(Views.Public.class) - @PutMapping("/{defaultApplicationId}/page/{defaultPageId}/reorder") + @PutMapping("/{branchedApplicationId}/page/{branchedPageId}/reorder") public Mono> reorderPage( - @PathVariable String defaultApplicationId, - @PathVariable String defaultPageId, - @RequestParam Integer order, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @PathVariable String branchedApplicationId, + @PathVariable String branchedPageId, + @RequestParam Integer order) { return applicationPageService - .reorderPage(defaultApplicationId, defaultPageId, order, branchName) + .reorderPage(branchedApplicationId, branchedPageId, order) .map(updatedApplication -> new ResponseDTO<>(HttpStatus.OK.value(), updatedApplication, null)); } @JsonView(Views.Public.class) - @DeleteMapping("/{id}") - public Mono> delete(@PathVariable String id) { - log.debug("Going to delete application with id: {}", id); + @DeleteMapping("/{branchedApplicationId}") + public Mono> delete(@PathVariable String branchedApplicationId) { + log.debug("Going to delete application with branchedApplicationId: {}", branchedApplicationId); return applicationPageService - .deleteApplication(id) + .deleteApplication(branchedApplicationId) .map(deletedResource -> new ResponseDTO<>(HttpStatus.OK.value(), deletedResource, null)); } @@ -130,7 +127,7 @@ public class ApplicationControllerCE { public Mono>> findByWorkspaceIdAndRecentlyUsedOrder( @RequestParam(required = false) String workspaceId) { log.debug("Going to get all applications by workspace id {}", workspaceId); - return service.findByWorkspaceIdAndDefaultApplicationsInRecentlyUsedOrder(workspaceId) + return service.findByWorkspaceIdAndBaseApplicationsInRecentlyUsedOrder(workspaceId) .collectList() .map(applications -> new ResponseDTO<>(HttpStatus.OK.value(), applications, null)); } @@ -145,57 +142,48 @@ public class ApplicationControllerCE { } @JsonView(Views.Public.class) - @PutMapping("/{defaultApplicationId}/changeAccess") + @PutMapping("/{branchedApplicationId}/changeAccess") public Mono> shareApplication( - @PathVariable String defaultApplicationId, - @RequestBody ApplicationAccessDTO applicationAccessDTO, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @PathVariable String branchedApplicationId, @RequestBody ApplicationAccessDTO applicationAccessDTO) { log.debug( - "Going to change access for application {}, branch {} to {}", - defaultApplicationId, - branchName, + "Going to change access for application {} to {}", + branchedApplicationId, applicationAccessDTO.getPublicAccess()); - return service.changeViewAccess(defaultApplicationId, branchName, applicationAccessDTO) + return service.changeViewAccessForAllBranchesByBranchedApplicationId( + branchedApplicationId, applicationAccessDTO) .map(application -> new ResponseDTO<>(HttpStatus.OK.value(), application, null)); } @JsonView(Views.Public.class) - @PostMapping("/clone/{applicationId}") - public Mono> cloneApplication( - @PathVariable String applicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @PostMapping("/clone/{branchedApplicationId}") + public Mono> cloneApplication(@PathVariable String branchedApplicationId) { return applicationPageService - .cloneApplication(applicationId, branchName) + .cloneApplication(branchedApplicationId) .map(created -> new ResponseDTO<>(HttpStatus.CREATED.value(), created, null)); } @JsonView(Views.Public.class) - @GetMapping("/view/{defaultApplicationId}") - public Mono> getApplicationInViewMode( - @PathVariable String defaultApplicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - return service.getApplicationInViewMode(defaultApplicationId, branchName) + @GetMapping("/view/{branchedApplicationId}") + public Mono> getApplicationInViewMode(@PathVariable String branchedApplicationId) { + return service.getApplicationInViewMode(branchedApplicationId) .map(application -> new ResponseDTO<>(HttpStatus.OK.value(), application, null)); } @JsonView(Views.Public.class) - @PostMapping("/{defaultApplicationId}/fork/{workspaceId}") + @PostMapping("/{branchedApplicationId}/fork/{workspaceId}") public Mono> forkApplication( - @PathVariable String defaultApplicationId, - @PathVariable String workspaceId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @PathVariable String branchedApplicationId, @PathVariable String workspaceId) { return applicationForkingService - .forkApplicationToWorkspace(defaultApplicationId, workspaceId, branchName) + .forkApplicationToWorkspace(branchedApplicationId, workspaceId) .map(fetchedResource -> new ResponseDTO<>(HttpStatus.OK.value(), fetchedResource, null)); } @JsonView(Views.Public.class) - @GetMapping("/export/{id}") - public Mono> getApplicationFile( - @PathVariable String id, @RequestParam(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to export application with id: {}, branch: {}", id, branchName); + @GetMapping("/export/{branchedApplicationId}") + public Mono> getApplicationFile(@PathVariable String branchedApplicationId) { + log.debug("Going to export application with branchedApplicationId: {}", branchedApplicationId); - return exportService.getArtifactFile(id, branchName, APPLICATION).map(fetchedResource -> { + return exportService.getArtifactFile(branchedApplicationId, APPLICATION).map(fetchedResource -> { HttpHeaders responseHeaders = fetchedResource.getHttpHeaders(); Object applicationResource = fetchedResource.getArtifactResource(); return new ResponseEntity<>(applicationResource, responseHeaders, HttpStatus.OK); @@ -203,47 +191,44 @@ public class ApplicationControllerCE { } @JsonView(Views.Public.class) - @PostMapping("/snapshot/{id}") + @PostMapping("/snapshot/{branchedApplicationId}") @ResponseStatus(HttpStatus.CREATED) - public Mono> createSnapshot( - @PathVariable String id, @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to create snapshot with application id: {}, branch: {}", id, branchName); + public Mono> createSnapshot(@PathVariable String branchedApplicationId) { + log.debug("Going to create snapshot with application branchedApplicationId: {}", branchedApplicationId); return applicationSnapshotService - .createApplicationSnapshot(id, branchName) + .createApplicationSnapshot(branchedApplicationId) .map(result -> new ResponseDTO<>(HttpStatus.CREATED.value(), result, null)); } @JsonView(Views.Public.class) - @GetMapping("/snapshot/{id}") + @GetMapping("/snapshot/{branchedApplicationId}") public Mono> getSnapshotWithoutApplicationJson( - @PathVariable String id, @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to get snapshot with application id: {}, branch: {}", id, branchName); + @PathVariable String branchedApplicationId) { + log.debug("Going to get snapshot with application branchedApplicationId: {}", branchedApplicationId); return applicationSnapshotService - .getWithoutDataByApplicationId(id, branchName) + .getWithoutDataByBranchedApplicationId(branchedApplicationId) .map(applicationSnapshot -> new ResponseDTO<>(HttpStatus.OK.value(), applicationSnapshot, null)); } @JsonView(Views.Public.class) - @DeleteMapping("/snapshot/{id}") - public Mono> deleteSnapshotWithoutApplicationJson( - @PathVariable String id, @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to delete snapshot with application id: {}, branch: {}", id, branchName); + @DeleteMapping("/snapshot/{branchedApplicationId}") + public Mono> deleteSnapshotWithoutApplicationJson(@PathVariable String branchedApplicationId) { + log.debug("Going to delete snapshot with application branchedApplicationId: {}", branchedApplicationId); return applicationSnapshotService - .deleteSnapshot(id, branchName) + .deleteSnapshot(branchedApplicationId) .map(isDeleted -> new ResponseDTO<>(HttpStatus.OK.value(), isDeleted, null)); } @JsonView(Views.Public.class) - @PostMapping("/snapshot/{id}/restore") - public Mono> restoreSnapshot( - @PathVariable String id, @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to restore snapshot with application id: {}, branch: {}", id, branchName); + @PostMapping("/snapshot/{branchedApplicationId}/restore") + public Mono> restoreSnapshot(@PathVariable String branchedApplicationId) { + log.debug("Going to restore snapshot with application branchedApplicationId: {}", branchedApplicationId); return applicationSnapshotService - .restoreSnapshot(id, branchName) + .restoreSnapshot(branchedApplicationId) .map(application -> new ResponseDTO<>(HttpStatus.OK.value(), application, null)); } @@ -252,113 +237,103 @@ public class ApplicationControllerCE { public Mono> importApplicationFromFile( @RequestPart("file") Mono fileMono, @PathVariable String workspaceId, - @RequestParam(name = FieldName.APPLICATION_ID, required = false) String applicationId) { + @RequestParam(name = FieldName.APPLICATION_ID, required = false) String branchedApplicationId) { log.debug("Going to import application in workspace with id: {}", workspaceId); - return fileMono.flatMap(file -> - importService.extractArtifactExchangeJsonAndSaveArtifact(file, workspaceId, applicationId)) + return fileMono.flatMap(file -> importService.extractArtifactExchangeJsonAndSaveArtifact( + file, workspaceId, branchedApplicationId)) .map(fetchedResource -> new ResponseDTO<>(HttpStatus.OK.value(), fetchedResource, null)); } @JsonView(Views.Public.class) - @PostMapping("/ssh-keypair/{applicationId}") + @PostMapping("/ssh-keypair/{branchedApplicationId}") public Mono> generateSSHKeyPair( - @PathVariable String applicationId, @RequestParam(required = false) String keyType) { - return service.createOrUpdateSshKeyPair(applicationId, keyType) + @PathVariable String branchedApplicationId, @RequestParam(required = false) String keyType) { + return service.createOrUpdateSshKeyPair(branchedApplicationId, keyType) .map(created -> new ResponseDTO<>(HttpStatus.CREATED.value(), created, null)); } @JsonView(Views.Public.class) - @GetMapping("/ssh-keypair/{applicationId}") - public Mono> getSSHKey(@PathVariable String applicationId) { - return service.getSshKey(applicationId) + @GetMapping("/ssh-keypair/{branchedApplicationId}") + public Mono> getSSHKey(@PathVariable String branchedApplicationId) { + return service.getSshKey(branchedApplicationId) .map(created -> new ResponseDTO<>(HttpStatus.CREATED.value(), created, null)); } @JsonView(Views.Public.class) - @PutMapping("/{defaultApplicationId}") + @PutMapping("/{branchedApplicationId}") public Mono> update( - @PathVariable String defaultApplicationId, - @RequestBody Application resource, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to update resource from base controller with id: {}", defaultApplicationId); - return service.update(defaultApplicationId, resource, branchName) + @PathVariable String branchedApplicationId, @RequestBody Application resource) { + log.debug("Going to update resource from base controller with id: {}", branchedApplicationId); + return service.updateApplicationWithPresets(branchedApplicationId, resource) .map(updatedResource -> new ResponseDTO<>(HttpStatus.OK.value(), updatedResource, null)); } @JsonView(Views.Public.class) - @PatchMapping("{applicationId}/themes/{themeId}") + @PatchMapping("{branchedApplicationId}/themes/{themeId}") public Mono> setCurrentTheme( - @PathVariable String applicationId, - @PathVariable String themeId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @PathVariable String branchedApplicationId, @PathVariable String themeId) { return themeService - .changeCurrentTheme(themeId, applicationId, branchName) + .changeCurrentTheme(themeId, branchedApplicationId) .map(theme -> new ResponseDTO<>(HttpStatus.OK.value(), theme, null)); } @JsonView(Views.Public.class) @GetMapping("/import/{workspaceId}/datasources") public Mono>> getUnConfiguredDatasource( - @PathVariable String workspaceId, @RequestParam String defaultApplicationId) { + @PathVariable String workspaceId, @RequestParam(name = "defaultApplicationId") String baseApplicationId) { return importService - .findDatasourceByArtifactId(workspaceId, defaultApplicationId, APPLICATION) + .findDatasourceByArtifactId(workspaceId, baseApplicationId, APPLICATION) .map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null)); } @JsonView(Views.Public.class) - @PostMapping(value = "/{defaultApplicationId}/logo", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PostMapping(value = "/{branchedApplicationId}/logo", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public Mono> uploadAppNavigationLogo( - @PathVariable String defaultApplicationId, - @RequestPart("file") Mono fileMono, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - return fileMono.flatMap(part -> service.saveAppNavigationLogo(branchName, defaultApplicationId, part)) + @PathVariable String branchedApplicationId, @RequestPart("file") Mono fileMono) { + return fileMono.flatMap(part -> service.saveAppNavigationLogo(branchedApplicationId, part)) .map(url -> new ResponseDTO<>(HttpStatus.OK.value(), url, null)); } @JsonView(Views.Public.class) - @DeleteMapping("/{defaultApplicationId}/logo") - public Mono> deleteAppNavigationLogo( - @PathVariable String defaultApplicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - return service.deleteAppNavigationLogo(branchName, defaultApplicationId) + @DeleteMapping("/{branchedApplicationId}/logo") + public Mono> deleteAppNavigationLogo(@PathVariable String branchedApplicationId) { + return service.deleteAppNavigationLogo(branchedApplicationId) .thenReturn(new ResponseDTO<>(HttpStatus.OK.value(), null, null)); } @JsonView(Views.Public.class) - @PostMapping(value = "/export/partial/{applicationId}/{pageId}", consumes = MediaType.APPLICATION_JSON_VALUE) + @PostMapping( + value = "/export/partial/{branchedApplicationId}/{branchedPageId}", + consumes = MediaType.APPLICATION_JSON_VALUE) public Mono> exportApplicationPartially( - @PathVariable String applicationId, - @PathVariable String pageId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, + @PathVariable String branchedApplicationId, + @PathVariable String branchedPageId, @Valid @RequestBody PartialExportFileDTO fileDTO) { // params - contains ids of jsLib, actions and datasourceIds to be exported return partialExportService - .getPartialExportResources(applicationId, pageId, branchName, fileDTO) + .getPartialExportResources(branchedApplicationId, branchedPageId, fileDTO) .map(fetchedResource -> new ResponseDTO<>(HttpStatus.OK.value(), fetchedResource, null)); } @JsonView(Views.Public.class) @PostMapping( - value = "/import/partial/{workspaceId}/{applicationId}", + value = "/import/partial/{workspaceId}/{branchedApplicationId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public Mono> importApplicationPartially( @RequestPart("file") Mono fileMono, @PathVariable String workspaceId, - @PathVariable String applicationId, - @RequestParam String pageId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @PathVariable String branchedApplicationId, + @RequestParam(name = FieldName.PAGE_ID) String branchedPageId) { return fileMono.flatMap(fileData -> partialImportService.importResourceInPage( - workspaceId, applicationId, pageId, branchName, fileData)) + workspaceId, branchedApplicationId, branchedPageId, null, fileData)) .map(fetchedResource -> new ResponseDTO<>(HttpStatus.CREATED.value(), fetchedResource, null)); } @JsonView(Views.Public.class) @PostMapping("/import/partial/block") - public Mono> importBlock( - @RequestBody BuildingBlockDTO buildingBlockDTO, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + public Mono> importBlock(@RequestBody BuildingBlockDTO buildingBlockDTO) { return partialImportService - .importBuildingBlock(buildingBlockDTO, branchName) + .importBuildingBlock(buildingBlockDTO) .map(fetchedResource -> new ResponseDTO<>(HttpStatus.CREATED.value(), fetchedResource, null)); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ApplicationTemplateControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ApplicationTemplateControllerCE.java index 0a3ecd9d00..a010965c27 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ApplicationTemplateControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ApplicationTemplateControllerCE.java @@ -1,7 +1,6 @@ package com.appsmith.server.controllers.ce; import com.appsmith.external.views.Views; -import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.Application; import com.appsmith.server.dtos.ApplicationImportDTO; import com.appsmith.server.dtos.ApplicationTemplate; @@ -16,7 +15,6 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestParam; import reactor.core.publisher.Mono; @@ -75,15 +73,14 @@ public class ApplicationTemplateControllerCE { } @JsonView(Views.Public.class) - @PostMapping("{templateId}/merge/{applicationId}/{organizationId}") + @PostMapping("{templateId}/merge/{branchedApplicationId}/{organizationId}") public Mono> mergeTemplateWithApplication( @PathVariable String templateId, - @PathVariable String applicationId, + @PathVariable String branchedApplicationId, @PathVariable String organizationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, @RequestBody(required = false) List pagesToImport) { return applicationTemplateService - .mergeTemplateWithApplication(templateId, applicationId, organizationId, branchName, pagesToImport) + .mergeTemplateWithApplication(templateId, branchedApplicationId, organizationId, pagesToImport) .map(importedApp -> new ResponseDTO<>(HttpStatus.OK.value(), importedApp, null)); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/CustomJSLibControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/CustomJSLibControllerCE.java index 1e888cd287..b847a40260 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/CustomJSLibControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/CustomJSLibControllerCE.java @@ -33,73 +33,67 @@ public class CustomJSLibControllerCE { } @JsonView(Views.Public.class) - @PatchMapping("/{applicationId}/add") + @PatchMapping("/{branchedApplicationId}/add") public Mono> addJSLibToApplication( @RequestBody @Valid CustomJSLib customJSLib, - @PathVariable String applicationId, + @PathVariable String branchedApplicationId, @RequestParam(defaultValue = "APPLICATION") CreatorContextType contextType, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, @RequestHeader(name = FieldName.IS_FORCE_INSTALL, defaultValue = "false") Boolean isForceInstall) { log.debug( - "Going to add JS lib: {}_{} to {}: {}, on branch:{}", + "Going to add JS lib: {}_{} to {}: {}", customJSLib.getName(), customJSLib.getVersion(), contextType.name().toLowerCase(), - applicationId, - branchName); + branchedApplicationId); return customJSLibService - .addJSLibsToContext(applicationId, contextType, Set.of(customJSLib), branchName, isForceInstall) + .addJSLibsToContext(branchedApplicationId, contextType, Set.of(customJSLib), isForceInstall) .map(actionCollection -> new ResponseDTO<>(HttpStatus.OK.value(), actionCollection, null)); } @JsonView(Views.Public.class) - @PatchMapping("/{applicationId}/remove") + @PatchMapping("/{branchedApplicationId}/remove") public Mono> removeJSLibFromApplication( @RequestBody @Valid CustomJSLib customJSLib, - @PathVariable String applicationId, + @PathVariable String branchedApplicationId, @RequestParam(defaultValue = "APPLICATION") CreatorContextType contextType, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, @RequestHeader(name = FieldName.IS_FORCE_REMOVE, defaultValue = "false") Boolean isForceRemove) { log.debug( - "Going to remove JS lib: {} from {}: {}, on branch:{}", + "Going to remove JS lib: {} from {}: {}", customJSLib.getUidString(), contextType.name().toLowerCase(), - applicationId, - branchName); + branchedApplicationId); return customJSLibService - .removeJSLibFromContext(applicationId, contextType, customJSLib, branchName, isForceRemove) + .removeJSLibFromContext(branchedApplicationId, contextType, customJSLib, isForceRemove) .map(actionCollection -> new ResponseDTO<>(HttpStatus.OK.value(), actionCollection, null)); } @JsonView(Views.Public.class) - @GetMapping("/{contextId}") + @GetMapping("/{branchedContextId}") public Mono>> getAllUserInstalledJSLibInApplication( - @PathVariable String contextId, - @RequestParam(defaultValue = "APPLICATION") CreatorContextType contextType, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @PathVariable String branchedContextId, + @RequestParam(defaultValue = "APPLICATION") CreatorContextType contextType) { log.debug( "Going to get all unpublished JS libs in {}: {}, on branch: {}", contextType.name().toLowerCase(), - contextId, - branchName); + branchedContextId); return customJSLibService - .getAllJSLibsInContext(contextId, contextType, branchName, false) + .getAllJSLibsInContext(branchedContextId, contextType, false) .map(actionCollection -> new ResponseDTO<>(HttpStatus.OK.value(), actionCollection, null)); } @JsonView(Views.Public.class) - @GetMapping("/{contextId}/view") + @GetMapping("/{branchedContextId}/view") public Mono>> getAllUserInstalledJSLibInApplicationForViewMode( - @PathVariable String contextId, + @PathVariable String branchedContextId, @RequestParam(defaultValue = "APPLICATION") CreatorContextType contextType, @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { log.debug( "Going to get all published JS libs in {}: {}, on branch: {}", contextType.name().toLowerCase(), - contextId, + branchedContextId, branchName); return customJSLibService - .getAllJSLibsInContext(contextId, contextType, branchName, true) + .getAllJSLibsInContext(branchedContextId, contextType, true) .map(actionCollection -> new ResponseDTO<>(HttpStatus.OK.value(), actionCollection, null)); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/DatasourceControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/DatasourceControllerCE.java index a3c6961ba1..73db8c5ae0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/DatasourceControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/DatasourceControllerCE.java @@ -147,7 +147,7 @@ public class DatasourceControllerCE { "Going to retrieve token request URL for datasource with id: {} and page id: {}", datasourceId, pageId); return authenticationService .getAuthorizationCodeURLForGenericOAuth2( - datasourceId, environmentId, pageId, branchName, serverWebExchange.getRequest()) + datasourceId, environmentId, pageId, serverWebExchange.getRequest()) .flatMap(url -> { serverWebExchange.getResponse().setStatusCode(HttpStatus.FOUND); serverWebExchange.getResponse().getHeaders().setLocation(URI.create(url)); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/GitControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/GitControllerCE.java index c058097cc2..bb9c056898 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/GitControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/GitControllerCE.java @@ -1,7 +1,6 @@ package com.appsmith.server.controllers.ce; import com.appsmith.external.dtos.GitBranchDTO; -import com.appsmith.external.dtos.GitLogDTO; import com.appsmith.external.dtos.GitStatusDTO; import com.appsmith.external.dtos.MergeStatusDTO; import com.appsmith.external.views.Views; @@ -71,11 +70,11 @@ public class GitControllerCE { } @JsonView(Views.Public.class) - @PutMapping("/profile/app/{defaultApplicationId}") + @PutMapping("/profile/app/{baseApplicationId}") public Mono>> saveGitProfile( - @PathVariable String defaultApplicationId, @RequestBody GitProfile gitProfile) { - log.debug("Going to add repo specific git profile for application: {}", defaultApplicationId); - return service.updateOrCreateGitProfileForCurrentUser(gitProfile, defaultApplicationId) + @PathVariable String baseApplicationId, @RequestBody GitProfile gitProfile) { + log.debug("Going to add repo specific git profile for application: {}", baseApplicationId); + return service.updateOrCreateGitProfileForCurrentUser(gitProfile, baseApplicationId) .map(response -> new ResponseDTO<>(HttpStatus.ACCEPTED.value(), response, null)); } @@ -87,173 +86,147 @@ public class GitControllerCE { } @JsonView(Views.Public.class) - @GetMapping("/profile/app/{defaultApplicationId}") - public Mono> getGitConfigForUser(@PathVariable String defaultApplicationId) { - return service.getGitProfileForUser(defaultApplicationId) + @GetMapping("/profile/app/{baseApplicationId}") + public Mono> getGitConfigForUser(@PathVariable String baseApplicationId) { + return service.getGitProfileForUser(baseApplicationId) .map(gitConfigResponse -> new ResponseDTO<>(HttpStatus.OK.value(), gitConfigResponse, null)); } @JsonView({Views.Metadata.class}) - @GetMapping("/metadata/app/{defaultApplicationId}") - public Mono> getGitMetadata(@PathVariable String defaultApplicationId) { - return service.getGitArtifactMetadata(defaultApplicationId, ArtifactType.APPLICATION) + @GetMapping("/metadata/app/{baseArtifactId}") + public Mono> getGitMetadata(@PathVariable String baseArtifactId) { + return service.getGitArtifactMetadata(baseArtifactId, ArtifactType.APPLICATION) .map(metadata -> new ResponseDTO<>(HttpStatus.OK.value(), metadata, null)); } @JsonView(Views.Public.class) - @PostMapping("/connect/app/{defaultApplicationId}") + @PostMapping("/connect/app/{baseApplicationId}") public Mono> connectApplicationToRemoteRepo( - @PathVariable String defaultApplicationId, + @PathVariable String baseApplicationId, @RequestBody GitConnectDTO gitConnectDTO, @RequestHeader("Origin") String originHeader) { - return service.connectArtifactToGit(defaultApplicationId, gitConnectDTO, originHeader, ArtifactType.APPLICATION) - .map(artefact -> (Application) artefact) + return service.connectArtifactToGit(baseApplicationId, gitConnectDTO, originHeader, ArtifactType.APPLICATION) + .map(artifact -> (Application) artifact) .map(application -> new ResponseDTO<>(HttpStatus.OK.value(), application, null)); } @JsonView(Views.Public.class) - @PostMapping("/commit/app/{defaultApplicationId}") + @PostMapping("/commit/app/{branchedApplicationId}") @ResponseStatus(HttpStatus.CREATED) public Mono> commit( @RequestBody GitCommitDTO commitDTO, - @PathVariable String defaultApplicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, + @PathVariable String branchedApplicationId, @RequestParam(required = false, defaultValue = "false") Boolean doAmend) { - log.debug("Going to commit application {}, branch : {}", defaultApplicationId, branchName); - return service.commitArtifact(commitDTO, defaultApplicationId, branchName, doAmend, ArtifactType.APPLICATION) + log.debug("Going to commit branchedApplicationId {}", branchedApplicationId); + return service.commitArtifact(commitDTO, branchedApplicationId, doAmend, ArtifactType.APPLICATION) .map(result -> new ResponseDTO<>(HttpStatus.CREATED.value(), result, null)); } @JsonView(Views.Public.class) - @GetMapping("/commit-history/app/{defaultApplicationId}") - public Mono>> getCommitHistory( - @PathVariable String defaultApplicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Fetching commit-history for application {}, branch : {}", defaultApplicationId, branchName); - return service.getCommitHistory(defaultApplicationId, branchName, ArtifactType.APPLICATION) - .map(logs -> new ResponseDTO<>(HttpStatus.OK.value(), logs, null)); - } - - @JsonView(Views.Public.class) - @PostMapping("/push/app/{defaultApplicationId}") + @PostMapping("/push/app/{branchedApplicationId}") @ResponseStatus(HttpStatus.CREATED) - public Mono> push( - @PathVariable String defaultApplicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to push application application {}, branch : {}", defaultApplicationId, branchName); - return service.pushArtifact(defaultApplicationId, branchName, ArtifactType.APPLICATION) + public Mono> push(@PathVariable String branchedApplicationId) { + log.debug("Going to push branchedApplicationId {}", branchedApplicationId); + return service.pushArtifact(branchedApplicationId, ArtifactType.APPLICATION) .map(result -> new ResponseDTO<>(HttpStatus.CREATED.value(), result, null)); } @JsonView(Views.Public.class) - @PostMapping("/create-branch/app/{defaultApplicationId}") + @PostMapping("/create-branch/app/{branchedApplicationId}") @ResponseStatus(HttpStatus.CREATED) public Mono> createBranch( - @PathVariable String defaultApplicationId, + @PathVariable String branchedApplicationId, @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String srcBranch, @RequestBody GitBranchDTO branchDTO) { - log.debug("Going to create a branch from root application {}, srcBranch {}", defaultApplicationId, srcBranch); - return service.createBranch(defaultApplicationId, branchDTO, srcBranch, ArtifactType.APPLICATION) - .map(artefact -> (Application) artefact) + log.debug( + "Going to create a branch from branchedApplicationId {}, srcBranch {}", + branchedApplicationId, + srcBranch); + return service.createBranch(branchedApplicationId, branchDTO, ArtifactType.APPLICATION) + .map(artifact -> (Application) artifact) .map(result -> new ResponseDTO<>(HttpStatus.CREATED.value(), result, null)); } @JsonView(Views.Public.class) - @GetMapping("/checkout-branch/app/{defaultApplicationId}") + @GetMapping("/checkout-branch/app/{branchedApplicationId}") public Mono> checkoutBranch( - @PathVariable String defaultApplicationId, + @PathVariable String branchedApplicationId, @RequestParam(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to checkout to branch {} application {} ", branchName, defaultApplicationId); - return service.checkoutBranch(defaultApplicationId, branchName, true, ArtifactType.APPLICATION) - .map(artefact -> (Application) artefact) + log.debug("Going to checkout to branch {} application {} ", branchName, branchedApplicationId); + return service.checkoutBranch(branchedApplicationId, branchName, true, ArtifactType.APPLICATION) + .map(artifact -> (Application) artifact) .map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null)); } @JsonView(Views.Public.class) - @PostMapping("/disconnect/app/{defaultApplicationId}") - public Mono> disconnectFromRemote(@PathVariable String defaultApplicationId) { - log.debug("Going to remove the remoteUrl for application {}", defaultApplicationId); - return service.detachRemote(defaultApplicationId, ArtifactType.APPLICATION) - .map(artefact -> (Application) artefact) + @PostMapping("/disconnect/app/{branchedApplicationId}") + public Mono> disconnectFromRemote(@PathVariable String branchedApplicationId) { + log.debug("Going to remove the remoteUrl for application {}", branchedApplicationId); + return service.detachRemote(branchedApplicationId, ArtifactType.APPLICATION) + .map(artifact -> (Application) artifact) .map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null)); } @JsonView(Views.Public.class) - @GetMapping("/pull/app/{defaultApplicationId}") - public Mono> pull( - @PathVariable String defaultApplicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to pull the latest for application {}, branch {}", defaultApplicationId, branchName); - return service.pullArtifact(defaultApplicationId, branchName, ArtifactType.APPLICATION) + @GetMapping("/pull/app/{branchedApplicationId}") + public Mono> pull(@PathVariable String branchedApplicationId) { + log.debug("Going to pull the latest for branchedApplicationId {}", branchedApplicationId); + return service.pullArtifact(branchedApplicationId, ArtifactType.APPLICATION) .map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null)); } @JsonView(Views.Public.class) - @GetMapping("/branch/app/{defaultApplicationId}") + @GetMapping("/branch/app/{branchedApplicationId}") public Mono>> branch( - @PathVariable String defaultApplicationId, - @RequestParam(required = false, defaultValue = "false") Boolean pruneBranches, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to get branch list for application {}", defaultApplicationId); + @PathVariable String branchedApplicationId, + @RequestParam(required = false, defaultValue = "false") Boolean pruneBranches) { + log.debug("Going to get branch list for application {}", branchedApplicationId); return service.listBranchForArtifact( - defaultApplicationId, BooleanUtils.isTrue(pruneBranches), branchName, ArtifactType.APPLICATION) + branchedApplicationId, BooleanUtils.isTrue(pruneBranches), ArtifactType.APPLICATION) .map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null)); } @JsonView(Views.Public.class) - @GetMapping("/status/app/{defaultApplicationId}") + @GetMapping("/status/app/{branchedApplicationId}") public Mono> getStatus( - @PathVariable String defaultApplicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, + @PathVariable String branchedApplicationId, @RequestParam(required = false, defaultValue = "true") Boolean compareRemote) { - log.debug("Going to get status for default application {}, branch {}", defaultApplicationId, branchName); - return service.getStatus(defaultApplicationId, compareRemote, branchName, ArtifactType.APPLICATION) + log.debug("Going to get status for default branchedApplicationId {}", branchedApplicationId); + return service.getStatus(branchedApplicationId, compareRemote, ArtifactType.APPLICATION) .map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null)); } @JsonView(Views.Public.class) - @GetMapping("/fetch/remote/app/{defaultApplicationId}") - public Mono> fetchRemoteChanges( - @PathVariable String defaultApplicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug( - "Going to compare with remote for default application {}, branch {}", defaultApplicationId, branchName); - return service.fetchRemoteChanges(defaultApplicationId, branchName, true, ArtifactType.APPLICATION) + @GetMapping("/fetch/remote/app/{branchedApplicationId}") + public Mono> fetchRemoteChanges(@PathVariable String branchedApplicationId) { + log.debug("Going to compare with remote for default branchedApplicationId {}", branchedApplicationId); + return service.fetchRemoteChanges(branchedApplicationId, true, ArtifactType.APPLICATION) .map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null)); } @JsonView(Views.Public.class) - @PostMapping("/merge/app/{defaultApplicationId}") + @PostMapping("/merge/app/{branchedApplicationId}") public Mono> merge( - @PathVariable String defaultApplicationId, @RequestBody GitMergeDTO gitMergeDTO) { + @PathVariable String branchedApplicationId, @RequestBody GitMergeDTO gitMergeDTO) { log.debug( "Going to merge branch {} with branch {} for application {}", gitMergeDTO.getSourceBranch(), gitMergeDTO.getDestinationBranch(), - defaultApplicationId); - return service.mergeBranch(defaultApplicationId, gitMergeDTO, ArtifactType.APPLICATION) + branchedApplicationId); + return service.mergeBranch(branchedApplicationId, gitMergeDTO, ArtifactType.APPLICATION) .map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null)); } @JsonView(Views.Public.class) - @PostMapping("/merge/status/app/{defaultApplicationId}") + @PostMapping("/merge/status/app/{branchedApplicationId}") public Mono> mergeStatus( - @PathVariable String defaultApplicationId, @RequestBody GitMergeDTO gitMergeDTO) { + @PathVariable String branchedApplicationId, @RequestBody GitMergeDTO gitMergeDTO) { log.debug( "Check if branch {} can be merged with branch {} for application {}", gitMergeDTO.getSourceBranch(), gitMergeDTO.getDestinationBranch(), - defaultApplicationId); - return service.isBranchMergeable(defaultApplicationId, gitMergeDTO, ArtifactType.APPLICATION) - .map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null)); - } - - @JsonView(Views.Public.class) - @PostMapping("/conflicted-branch/app/{defaultApplicationId}") - public Mono> createConflictedBranch( - @PathVariable String defaultApplicationId, @RequestHeader(name = FieldName.BRANCH_NAME) String branchName) { - log.debug("Going to create conflicted state branch {} for application {}", branchName, defaultApplicationId); - return service.createConflictedBranch(defaultApplicationId, branchName, ArtifactType.APPLICATION) + branchedApplicationId); + return service.isBranchMergeable(branchedApplicationId, gitMergeDTO, ArtifactType.APPLICATION) .map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null)); } @@ -273,32 +246,21 @@ public class GitControllerCE { } @JsonView(Views.Public.class) - @GetMapping("/test-connection/app/{defaultApplicationId}") - public Mono> testGitConnection(@PathVariable String defaultApplicationId) { - return service.testConnection(defaultApplicationId, ArtifactType.APPLICATION) - .map(result -> new ResponseDTO<>((HttpStatus.OK.value()), result, null)); - } - - @JsonView(Views.Public.class) - @DeleteMapping("/branch/app/{defaultApplicationId}") + @DeleteMapping("/branch/app/{baseArtifactId}") public Mono> deleteBranch( - @PathVariable String defaultApplicationId, @RequestParam String branchName) { - log.debug("Going to delete branch {} for defaultApplicationId {}", branchName, defaultApplicationId); - return service.deleteBranch(defaultApplicationId, branchName, ArtifactType.APPLICATION) - .map(artefact -> (Application) artefact) + @PathVariable String baseArtifactId, @RequestParam String branchName) { + log.debug("Going to delete branch {} for baseApplicationId {}", branchName, baseArtifactId); + return service.deleteBranch(baseArtifactId, branchName, ArtifactType.APPLICATION) + .map(artifact -> (Application) artifact) .map(application -> new ResponseDTO<>(HttpStatus.OK.value(), application, null)); } @JsonView(Views.Public.class) - @PutMapping("/discard/app/{defaultApplicationId}") - public Mono> discardChanges( - @PathVariable String defaultApplicationId, @RequestHeader(name = FieldName.BRANCH_NAME) String branchName) { - log.debug( - "Going to discard changes for branch {} with defaultApplicationId {}", - branchName, - defaultApplicationId); - return service.discardChanges(defaultApplicationId, branchName, ArtifactType.APPLICATION) - .map(artefact -> (Application) artefact) + @PutMapping("/discard/app/{branchedApplicationId}") + public Mono> discardChanges(@PathVariable String branchedApplicationId) { + log.debug("Going to discard changes for branchedApplicationId {}", branchedApplicationId); + return service.discardChanges(branchedApplicationId, ArtifactType.APPLICATION) + .map(artifact -> (Application) artifact) .map(result -> new ResponseDTO<>((HttpStatus.OK.value()), result, null)); } @@ -317,43 +279,43 @@ public class GitControllerCE { } @JsonView(Views.Public.class) - @PostMapping("/branch/app/{defaultApplicationId}/protected") + @PostMapping("/branch/app/{baseArtifactId}/protected") public Mono>> updateProtectedBranches( - @PathVariable String defaultApplicationId, + @PathVariable String baseArtifactId, @RequestBody @Valid BranchProtectionRequestDTO branchProtectionRequestDTO) { return service.updateProtectedBranches( - defaultApplicationId, branchProtectionRequestDTO.getBranchNames(), ArtifactType.APPLICATION) + baseArtifactId, branchProtectionRequestDTO.getBranchNames(), ArtifactType.APPLICATION) .map(data -> new ResponseDTO<>(HttpStatus.OK.value(), data, null)); } @JsonView(Views.Public.class) - @GetMapping("/branch/app/{defaultApplicationId}/protected") - public Mono>> getProtectedBranches(@PathVariable String defaultApplicationId) { - return service.getProtectedBranches(defaultApplicationId, ArtifactType.APPLICATION) + @GetMapping("/branch/app/{baseArtifactId}/protected") + public Mono>> getProtectedBranches(@PathVariable String baseArtifactId) { + return service.getProtectedBranches(baseArtifactId, ArtifactType.APPLICATION) .map(list -> new ResponseDTO<>(HttpStatus.OK.value(), list, null)); } @JsonView(Views.Public.class) - @PostMapping("/auto-commit/app/{defaultApplicationId}") - public Mono> autoCommitApplication( - @PathVariable String defaultApplicationId, @RequestHeader(name = FieldName.BRANCH_NAME) String branchName) { + @PostMapping("/auto-commit/app/{branchedApplicationId}") + public Mono> autoCommitApplication(@PathVariable String branchedApplicationId) { return autoCommitService - .autoCommitApplication(defaultApplicationId, branchName) + .autoCommitApplication(branchedApplicationId) .map(data -> new ResponseDTO<>(HttpStatus.OK.value(), data, null)); } @JsonView(Views.Public.class) - @GetMapping("/auto-commit/progress/app/{defaultApplicationId}") + @GetMapping("/auto-commit/progress/app/{baseApplicationId}") public Mono> getAutoCommitProgress( - @PathVariable String defaultApplicationId, @RequestHeader(name = FieldName.BRANCH_NAME) String branchName) { - return service.getAutoCommitProgress(defaultApplicationId, branchName, ArtifactType.APPLICATION) + @PathVariable String baseApplicationId, + @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + return service.getAutoCommitProgress(baseApplicationId, branchName, ArtifactType.APPLICATION) .map(data -> new ResponseDTO<>(HttpStatus.OK.value(), data, null)); } @JsonView(Views.Public.class) - @PatchMapping("/auto-commit/toggle/app/{defaultApplicationId}") - public Mono> toggleAutoCommitEnabled(@PathVariable String defaultApplicationId) { - return service.toggleAutoCommitEnabled(defaultApplicationId, ArtifactType.APPLICATION) + @PatchMapping("/auto-commit/toggle/app/{baseArtifactId}") + public Mono> toggleAutoCommitEnabled(@PathVariable String baseArtifactId) { + return service.toggleAutoCommitEnabled(baseArtifactId, ArtifactType.APPLICATION) .map(data -> new ResponseDTO<>(HttpStatus.OK.value(), data, null)); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/LayoutControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/LayoutControllerCE.java index 6b80e1e61a..a49f25596c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/LayoutControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/LayoutControllerCE.java @@ -1,7 +1,6 @@ package com.appsmith.server.controllers.ce; import com.appsmith.external.views.Views; -import com.appsmith.server.constants.FieldName; import com.appsmith.server.constants.Url; import com.appsmith.server.domains.Layout; import com.appsmith.server.dtos.EntityType; @@ -22,7 +21,6 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import reactor.core.publisher.Mono; @@ -46,59 +44,48 @@ public class LayoutControllerCE { } @JsonView(Views.Public.class) - @GetMapping("/{layoutId}/pages/{defaultPageId}") - public Mono> getLayout( - @PathVariable String defaultPageId, - @PathVariable String layoutId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - return service.getLayout(defaultPageId, layoutId, false, branchName) + @GetMapping("/{layoutId}/pages/{branchedPageId}") + public Mono> getLayout(@PathVariable String branchedPageId, @PathVariable String layoutId) { + return service.getLayout(branchedPageId, layoutId, false) .map(created -> new ResponseDTO<>(HttpStatus.OK.value(), created, null)); } @JsonView(Views.Public.class) @PutMapping("/application/{applicationId}") public Mono> updateMultipleLayouts( - @PathVariable String applicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, - @RequestBody @Valid UpdateMultiplePageLayoutDTO request) { - log.debug("update multiple layout received for application {} branch {}", applicationId, branchName); + @PathVariable String applicationId, @RequestBody @Valid UpdateMultiplePageLayoutDTO request) { + log.debug("update multiple layout received for applicationId {}", applicationId); return updateLayoutService - .updateMultipleLayouts(applicationId, branchName, request) + .updateMultipleLayouts(applicationId, request) .map(updatedCount -> new ResponseDTO<>(HttpStatus.OK.value(), updatedCount, null)); } @JsonView(Views.Public.class) - @PutMapping("/{layoutId}/pages/{pageId}") + @PutMapping("/{layoutId}/pages/{branchedPageId}") public Mono> updateLayout( - @PathVariable String pageId, + @PathVariable String branchedPageId, @RequestParam String applicationId, @PathVariable String layoutId, - @RequestBody LayoutUpdateDTO dto, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("update layout received for page {}", pageId); + @RequestBody LayoutUpdateDTO dto) { + log.debug("update layout received for page {}", branchedPageId); return updateLayoutService - .updateLayout(pageId, applicationId, layoutId, dto.toLayout(), branchName) + .updateLayout(branchedPageId, applicationId, layoutId, dto.toLayout()) .map(created -> new ResponseDTO<>(HttpStatus.OK.value(), created, null)); } @JsonView(Views.Public.class) - @GetMapping("/{layoutId}/pages/{pageId}/view") - public Mono> getLayoutView( - @PathVariable String pageId, - @PathVariable String layoutId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - return service.getLayout(pageId, layoutId, true, branchName) + @GetMapping("/{layoutId}/pages/{branchedPageId}/view") + public Mono> getLayoutView(@PathVariable String branchedPageId, @PathVariable String layoutId) { + return service.getLayout(branchedPageId, layoutId, true) .map(created -> new ResponseDTO<>(HttpStatus.OK.value(), created, null)); } @JsonView(Views.Public.class) @PutMapping("/refactor") - public Mono> refactorWidgetName( - @RequestBody RefactorEntityNameDTO refactorEntityNameDTO, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + public Mono> refactorWidgetName(@RequestBody RefactorEntityNameDTO refactorEntityNameDTO) { refactorEntityNameDTO.setEntityType(EntityType.WIDGET); return refactoringService - .refactorEntityName(refactorEntityNameDTO, branchName) + .refactorEntityName(refactorEntityNameDTO) .map(created -> new ResponseDTO<>(HttpStatus.OK.value(), created, null)); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/PageControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/PageControllerCE.java index 45500af333..16f0f321f5 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/PageControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/PageControllerCE.java @@ -47,12 +47,10 @@ public class PageControllerCE { @JsonView(Views.Public.class) @PostMapping @ResponseStatus(HttpStatus.CREATED) - public Mono> createPage( - @Valid @RequestBody PageCreationDTO page, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to create page {}", page.getClass().getName()); + public Mono> createPage(@Valid @RequestBody PageCreationDTO page) { + log.debug("Going to create page {}", page.name()); return applicationPageService - .createPageWithBranchName(page.toPageDTO(), branchName) + .createPage(page.toPageDTO()) .map(created -> new ResponseDTO<>(HttpStatus.CREATED.value(), created, null)); } @@ -61,69 +59,63 @@ public class PageControllerCE { @ResponseStatus(HttpStatus.CREATED) public Mono> createCRUDPage( @RequestBody @NonNull CRUDPageResourceDTO resource, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, @RequestHeader(name = FieldName.HEADER_ENVIRONMENT_ID, required = false) String environmentId) { - log.debug( - "Going to create crud-page in application {}, branchName {}", resource.getApplicationId(), branchName); + log.debug("Going to create crud-page in application {}", resource.getApplicationId()); return createDBTablePageSolution - .createPageFromDBTable(null, resource, environmentId, branchName, Boolean.TRUE) + .createPageFromDBTable(null, resource, environmentId, null, Boolean.TRUE) .map(created -> new ResponseDTO<>(HttpStatus.CREATED.value(), created, null)); } @JsonView(Views.Public.class) - @PutMapping("/crud-page/{defaultPageId}") + @PutMapping("/crud-page/{branchedPageId}") @ResponseStatus(HttpStatus.OK) public Mono> createCRUDPage( - @PathVariable String defaultPageId, + @PathVariable String branchedPageId, @NonNull @RequestBody CRUDPageResourceDTO resource, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, @RequestHeader(name = FieldName.HEADER_ENVIRONMENT_ID, required = false) String environmentId) { - log.debug("Going to create CRUD page {}, branchName {}", defaultPageId, branchName); + log.debug("Going to create CRUD page {}", branchedPageId); return createDBTablePageSolution - .createPageFromDBTable(defaultPageId, resource, environmentId, branchName, Boolean.TRUE) + .createPageFromDBTable(branchedPageId, resource, environmentId, null, Boolean.TRUE) .map(created -> new ResponseDTO<>(HttpStatus.CREATED.value(), created, null)); } @Deprecated @JsonView(Views.Public.class) - @GetMapping("/application/{applicationId}") + @GetMapping("/application/{branchedApplicationId}") public Mono> getPageNamesByApplicationId( - @PathVariable String applicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @PathVariable String branchedApplicationId) { return newPageService - .findApplicationPagesByApplicationIdViewModeAndBranch(applicationId, branchName, false, true) + .findApplicationPagesByBranchedApplicationIdAndViewMode(branchedApplicationId, false, true) .map(resources -> new ResponseDTO<>(HttpStatus.OK.value(), resources, null)); } @JsonView(Views.Public.class) - @GetMapping("/view/application/{applicationId}") + @GetMapping("/view/application/{branchedApplicationId}") public Mono> getPageNamesByApplicationIdInViewMode( - @PathVariable String applicationId, + @PathVariable String branchedApplicationId, @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { return newPageService - .findApplicationPagesByApplicationIdViewModeAndBranch(applicationId, branchName, true, true) + .findApplicationPagesByBranchedApplicationIdAndViewMode(branchedApplicationId, true, true) .map(resources -> new ResponseDTO<>(HttpStatus.OK.value(), resources, null)); } @JsonView(Views.Public.class) - @GetMapping("/{defaultPageId}") + @GetMapping("/{branchedPageId}") public Mono> getPageById( - @PathVariable String defaultPageId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, + @PathVariable String branchedPageId, @RequestParam(required = false, defaultValue = "false") Boolean migrateDsl) { return applicationPageService - .getPageAndMigrateDslByBranchAndDefaultPageId(defaultPageId, branchName, false, migrateDsl) + .getPageAndMigrateDslByBranchedPageId(branchedPageId, false, migrateDsl) .map(page -> new ResponseDTO<>(HttpStatus.OK.value(), page, null)); } @JsonView(Views.Public.class) - @GetMapping("/{defaultPageId}/view") + @GetMapping("/{branchedPageId}/view") public Mono> getPageView( - @PathVariable String defaultPageId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, + @PathVariable String branchedPageId, @RequestParam(required = false, defaultValue = "false") Boolean migrateDsl) { return applicationPageService - .getPageAndMigrateDslByBranchAndDefaultPageId(defaultPageId, branchName, true, migrateDsl) + .getPageAndMigrateDslByBranchedPageId(branchedPageId, true, migrateDsl) .map(page -> new ResponseDTO<>(HttpStatus.OK.value(), page, null)); } @@ -133,40 +125,33 @@ public class PageControllerCE { * In case the page has been published, this page would eventually get deleted whenever the application is published * next. * - * @param defaultPageId defaultPageId which will be needed to find the actual page that needs to be deleted - * @param branchName git branch to find the exact page which needs to be deleted + * @param branchedPageId branchedPageId which will be needed to find the actual page that needs to be deleted * @return deleted page DTO */ @JsonView(Views.Public.class) - @DeleteMapping("/{defaultPageId}") - public Mono> deletePage( - @PathVariable String defaultPageId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to delete page with id: {}, branchName: {}", defaultPageId, branchName); + @DeleteMapping("/{branchedPageId}") + public Mono> deletePage(@PathVariable String branchedPageId) { + log.debug("Going to delete page with id: {}", branchedPageId); return applicationPageService - .deleteUnpublishedPageByBranchAndDefaultPageId(defaultPageId, branchName) + .deleteUnpublishedPage(branchedPageId) .map(deletedResource -> new ResponseDTO<>(HttpStatus.OK.value(), deletedResource, null)); } @JsonView(Views.Public.class) - @PostMapping("/clone/{defaultPageId}") - public Mono> clonePage( - @PathVariable String defaultPageId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @PostMapping("/clone/{branchedPageId}") + public Mono> clonePage(@PathVariable String branchedPageId) { return applicationPageService - .clonePageByDefaultPageIdAndBranch(defaultPageId, branchName) + .clonePage(branchedPageId) .map(page -> new ResponseDTO<>(HttpStatus.CREATED.value(), page, null)); } @JsonView(Views.Public.class) - @PutMapping("/{defaultPageId}") + @PutMapping("/{branchedPageId}") public Mono> updatePage( - @PathVariable String defaultPageId, - @RequestBody @Valid PageUpdateDTO resource, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - log.debug("Going to update page with id: {}, branchName: {}", defaultPageId, branchName); + @PathVariable String branchedPageId, @RequestBody @Valid PageUpdateDTO resource) { + log.debug("Going to update page with id: {}", branchedPageId); return newPageService - .updatePageByDefaultPageIdAndBranch(defaultPageId, resource, branchName) + .updatePage(branchedPageId, resource.toPageDTO()) .map(updatedResource -> new ResponseDTO<>(HttpStatus.OK.value(), updatedResource, null)); } @@ -176,27 +161,24 @@ public class PageControllerCE { * if Page ID is present, it'll fetch all pages of the corresponding Application. * If both IDs are present, it'll use the Application ID only and ignore the Page ID * - * @param applicationId Id of the application - * @param pageId id of a page + * @param branchedApplicationId Id of the application + * @param branchedPageId id of a page * @param mode In which mode it's in - * @param branchName name of the current branch * @return List of ApplicationPagesDTO along with other meta data */ @JsonView(Views.Public.class) @GetMapping public Mono> getAllPages( - @RequestParam(required = false) String applicationId, - @RequestParam(required = false) String pageId, - @RequestParam(required = true, defaultValue = "EDIT") ApplicationMode mode, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { + @RequestParam(name = FieldName.APPLICATION_ID, required = false) String branchedApplicationId, + @RequestParam(name = FieldName.PAGE_ID, required = false) String branchedPageId, + @RequestParam(defaultValue = "EDIT") ApplicationMode mode) { log.debug( - "Going to fetch applicationPageDTO for applicationId: {}, pageId: {}, branchName: {}, mode: {}", - applicationId, - pageId, - branchName, + "Going to fetch applicationPageDTO for branchedApplicationId: {}, branchedPageId: {}, mode: {}", + branchedApplicationId, + branchedPageId, mode); return newPageService - .findApplicationPages(applicationId, pageId, branchName, mode) + .findApplicationPages(branchedApplicationId, branchedPageId, mode) .map(resources -> new ResponseDTO<>(HttpStatus.OK.value(), resources, null)); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/RestApiImportControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/RestApiImportControllerCE.java index f49ac3f1be..21099164b8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/RestApiImportControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/RestApiImportControllerCE.java @@ -3,7 +3,6 @@ package com.appsmith.server.controllers.ce; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.CreatorContextType; import com.appsmith.external.views.Views; -import com.appsmith.server.constants.FieldName; import com.appsmith.server.constants.Url; import com.appsmith.server.domains.RestApiImporterType; import com.appsmith.server.dtos.ResponseDTO; @@ -14,7 +13,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; @@ -39,9 +37,7 @@ public class RestApiImportControllerCE { @RequestParam String contextId, @RequestParam String name, @RequestParam String workspaceId, - @RequestParam(required = false) CreatorContextType contextType, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, - @RequestHeader(name = "Origin", required = false) String originHeader) { + @RequestParam(required = false) CreatorContextType contextType) { log.debug("Going to import API"); ApiImporter service; @@ -53,7 +49,7 @@ public class RestApiImportControllerCE { throw new IllegalStateException("Unexpected value: " + type); } - return service.importAction(input, contextType, contextId, name, workspaceId, branchName) + return service.importAction(input, contextType, contextId, name, workspaceId) .map(created -> new ResponseDTO<>(HttpStatus.CREATED.value(), created, null)); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/SaasControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/SaasControllerCE.java index 99604bb75b..81028d4b4a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/SaasControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/SaasControllerCE.java @@ -36,7 +36,6 @@ public class SaasControllerCE { public Mono> getAppsmithToken( @PathVariable String datasourceId, @RequestBody RequestAppsmithTokenDTO requestAppsmithTokenDTO, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName, @RequestHeader(name = FieldName.HEADER_ENVIRONMENT_ID, required = false) String environmentId, @RequestParam(required = false) String importForGit, ServerWebExchange serverWebExchange) { @@ -47,7 +46,6 @@ public class SaasControllerCE { datasourceId, environmentId, requestAppsmithTokenDTO, - branchName, serverWebExchange.getRequest().getHeaders(), importForGit) .map(token -> new ResponseDTO<>(HttpStatus.OK.value(), token, null)); @@ -58,8 +56,7 @@ public class SaasControllerCE { public Mono> getAccessToken( @PathVariable String datasourceId, @RequestParam String appsmithToken, - @RequestHeader(name = FieldName.HEADER_ENVIRONMENT_ID, required = false) String environmentId, - ServerWebExchange serverWebExchange) { + @RequestHeader(name = FieldName.HEADER_ENVIRONMENT_ID, required = false) String environmentId) { log.debug("Received callback for an OAuth2 authorization request"); return authenticationService diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ThemeControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ThemeControllerCE.java index e205bb904d..1cc71a3390 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ThemeControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/ThemeControllerCE.java @@ -1,7 +1,6 @@ package com.appsmith.server.controllers.ce; import com.appsmith.external.views.Views; -import com.appsmith.server.constants.FieldName; import com.appsmith.server.constants.Url; import com.appsmith.server.domains.ApplicationMode; import com.appsmith.server.domains.Theme; @@ -17,7 +16,6 @@ import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import reactor.core.publisher.Mono; @@ -32,32 +30,27 @@ public class ThemeControllerCE { private final ThemeService service; @JsonView(Views.Public.class) - @GetMapping("applications/{applicationId}") - public Mono>> getApplicationThemes( - @PathVariable String applicationId, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - return service.getApplicationThemes(applicationId, branchName) + @GetMapping("applications/{branchedApplicationId}") + public Mono>> getApplicationThemes(@PathVariable String branchedApplicationId) { + return service.getApplicationThemes(branchedApplicationId) .collectList() .map(themes -> new ResponseDTO<>(HttpStatus.OK.value(), themes, null)); } @JsonView(Views.Public.class) - @GetMapping("applications/{applicationId}/current") + @GetMapping("applications/{branchedApplicationId}/current") public Mono> getCurrentTheme( - @PathVariable String applicationId, - @RequestParam(required = false, defaultValue = "EDIT") ApplicationMode mode, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - return service.getApplicationTheme(applicationId, mode, branchName) + @PathVariable String branchedApplicationId, + @RequestParam(required = false, defaultValue = "EDIT") ApplicationMode mode) { + return service.getApplicationTheme(branchedApplicationId, mode) .map(theme -> new ResponseDTO<>(HttpStatus.OK.value(), theme, null)); } @JsonView(Views.Public.class) - @PutMapping("applications/{applicationId}") + @PutMapping("applications/{branchedApplicationId}") public Mono> updateTheme( - @PathVariable String applicationId, - @Valid @RequestBody Theme resource, - @RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) { - return service.updateTheme(applicationId, branchName, resource) + @PathVariable String branchedApplicationId, @Valid @RequestBody Theme resource) { + return service.updateTheme(branchedApplicationId, resource) .map(theme -> new ResponseDTO<>(HttpStatus.OK.value(), theme, null)); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/WorkspaceControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/WorkspaceControllerCE.java index a9d3f52421..e64efd8992 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/WorkspaceControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/WorkspaceControllerCE.java @@ -36,7 +36,7 @@ public class WorkspaceControllerCE { @JsonView(Views.Public.class) @GetMapping("/{id}") - public Mono> getByIdAndBranchName(@PathVariable String id) { + public Mono> getById(@PathVariable String id) { return service.getById(id).map(workspace -> new ResponseDTO<>(HttpStatus.OK.value(), workspace, null)); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java index 619025beac..9d03ab90ae 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java @@ -544,7 +544,8 @@ public class DatasourceServiceCEImpl implements DatasourceServiceCE { .map(dbDatasourceStorage -> { copyNestedNonNullProperties(datasourceStorage, dbDatasourceStorage); return dbDatasourceStorage; - }); + }) + .switchIfEmpty(Mono.just(datasourceStorage)); }) .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.UNAUTHORIZED_ACCESS))); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/fork/DatasourceForkableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/fork/DatasourceForkableServiceCEImpl.java index 2e183dc651..e965543147 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/fork/DatasourceForkableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/fork/DatasourceForkableServiceCEImpl.java @@ -132,6 +132,7 @@ public class DatasourceForkableServiceCEImpl implements ForkableServiceCE()); newDs.setIsConfigured(null); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/defaultresources/DefaultResourcesService.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/defaultresources/DefaultResourcesService.java deleted file mode 100644 index 5eca6eedd2..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/defaultresources/DefaultResourcesService.java +++ /dev/null @@ -1,3 +0,0 @@ -package com.appsmith.server.defaultresources; - -public interface DefaultResourcesService extends DefaultResourcesServiceCE {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/defaultresources/DefaultResourcesServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/defaultresources/DefaultResourcesServiceCE.java deleted file mode 100644 index 362d160ca9..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/defaultresources/DefaultResourcesServiceCE.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.appsmith.server.defaultresources; - -public interface DefaultResourcesServiceCE { - - T initialize(T domainObject, String branchName, boolean resetExistingValues); - - T setFromOtherBranch(T domainObject, T defaultDomainObject, String branchName); -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ApplicationPage.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ApplicationPage.java index 15fb365b23..7ccc92f8d1 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ApplicationPage.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ApplicationPage.java @@ -10,6 +10,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; import org.springframework.data.annotation.Transient; +import org.springframework.util.StringUtils; @Getter @Setter @@ -40,4 +41,9 @@ public class ApplicationPage { public boolean isDefault() { return Boolean.TRUE.equals(isDefault); } + + @JsonView({Views.Internal.class, Views.Public.class}) + public String getBaseId() { + return StringUtils.hasLength(defaultPageId) ? defaultPageId : id; + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Context.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Context.java index 6ae04332d0..7536e1b101 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Context.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Context.java @@ -7,4 +7,8 @@ public interface Context { String getArtifactId(); Layout getLayout(); + + String getBranchName(); + + String getUnpublishedName(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Layout.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Layout.java index c99949d8d8..5d9c8cf2ec 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Layout.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Layout.java @@ -125,7 +125,6 @@ public class Layout { for (int dslActionIndex = 0; dslActionIndex < layoutOnLoadActions.size(); dslActionIndex++) { TreeSet sortedActions = new TreeSet<>(new CompareDslActionDTO()); sortedActions.addAll(layoutOnLoadActions.get(dslActionIndex)); - sortedActions.forEach(DslExecutableDTO::sanitiseForExport); layoutOnLoadActions.set(dslActionIndex, sortedActions); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/NewPage.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/NewPage.java index 5295bff2ba..dec5d52390 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/NewPage.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/NewPage.java @@ -57,6 +57,15 @@ public class NewPage extends BranchAwareDomain implements Context { return !layouts.isEmpty() ? layouts.get(0) : null; } + @JsonView(Views.Internal.class) + @Override + public String getUnpublishedName() { + if (this.getUnpublishedPage() == null) { + return null; + } + return this.getUnpublishedPage().getName(); + } + public static class Fields extends BranchAwareDomain.Fields { public static String unpublishedPage_layouts = unpublishedPage + "." + PageDTO.Fields.layouts; public static String unpublishedPage_name = unpublishedPage + "." + PageDTO.Fields.name; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/ActionCollectionCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/ActionCollectionCE.java index b924a2b5c2..7eb005d1ef 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/ActionCollectionCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/ActionCollectionCE.java @@ -2,7 +2,6 @@ package com.appsmith.server.domains.ce; import com.appsmith.external.models.BranchAwareDomain; import com.appsmith.external.models.CreatorContextType; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.views.Git; import com.appsmith.external.views.Views; import com.appsmith.server.dtos.ActionCollectionDTO; @@ -42,7 +41,6 @@ public class ActionCollectionCE extends BranchAwareDomain { @Override public void sanitiseToExportDBObject() { - this.setDefaultResources(null); ActionCollectionDTO unpublishedCollection = this.getUnpublishedCollection(); if (unpublishedCollection != null) { unpublishedCollection.sanitiseForExport(); @@ -69,11 +67,7 @@ public class ActionCollectionCE extends BranchAwareDomain { dotted(publishedCollection, ActionCollectionDTO.Fields.contextType); public static final String unpublishedCollection_contextType = dotted(unpublishedCollection, ActionCollectionDTO.Fields.contextType); - public static final String unpublishedCollection_deletedAt = dotted(unpublishedCollection, ActionCollectionDTO.Fields.deletedAt); - - public static final String defaultResources_collectionId = - dotted(defaultResources, DefaultResources.Fields.collectionId); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/ArtifactCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/ArtifactCE.java index 3cd3996d4a..a3c9bd2594 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/ArtifactCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/ArtifactCE.java @@ -1,10 +1,8 @@ package com.appsmith.server.domains.ce; import com.appsmith.external.models.Policy; -import com.appsmith.external.views.Views; import com.appsmith.server.constants.ArtifactType; import com.appsmith.server.domains.GitArtifactMetadata; -import com.fasterxml.jackson.annotation.JsonView; import java.util.Set; @@ -12,7 +10,6 @@ public interface ArtifactCE { String getId(); - @JsonView(Views.Internal.class) default String getBaseId() { return getId(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/CustomJSLibCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/CustomJSLibCE.java index bb45cb3c9e..428f96f1cd 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/CustomJSLibCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/CustomJSLibCE.java @@ -1,5 +1,6 @@ package com.appsmith.server.domains.ce; +import com.appsmith.external.models.BaseDomain; import com.appsmith.external.models.BranchAwareDomain; import com.appsmith.external.views.Git; import com.appsmith.external.views.Views; @@ -21,7 +22,7 @@ import java.util.Set; @ToString @NoArgsConstructor @FieldNameConstants -public class CustomJSLibCE extends BranchAwareDomain { +public class CustomJSLibCE extends BaseDomain { /* Library name */ @JsonView({Views.Public.class, Git.class}) String name; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/CRUDPageResourceDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/CRUDPageResourceDTO.java index c4a57cfead..081d9c2c56 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/CRUDPageResourceDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/CRUDPageResourceDTO.java @@ -16,7 +16,7 @@ import java.util.Set; @Setter public class CRUDPageResourceDTO { - // This will be defaultApplicationId if the application is connected with git + // This will be branchedApplicationId if the application is connected with git String applicationId; String datasourceId; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ExecuteActionMetaDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ExecuteActionMetaDTO.java index 3a20cb1710..6684a61822 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ExecuteActionMetaDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ExecuteActionMetaDTO.java @@ -12,7 +12,6 @@ import org.springframework.http.HttpHeaders; @Builder(toBuilder = true) public class ExecuteActionMetaDTO { String environmentId; - String branchName; HttpHeaders headers; boolean operateWithoutPermission = false; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ImportedActionAndCollectionMapsDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ImportedActionAndCollectionMapsDTO.java index 40931d3bf3..45436c03eb 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ImportedActionAndCollectionMapsDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ImportedActionAndCollectionMapsDTO.java @@ -3,11 +3,10 @@ package com.appsmith.server.dtos; import lombok.Getter; import java.util.HashMap; -import java.util.List; import java.util.Map; @Getter public class ImportedActionAndCollectionMapsDTO { - Map> unpublishedActionIdToCollectionIdMap = new HashMap<>(); - Map> publishedActionIdToCollectionIdMap = new HashMap<>(); + Map unpublishedActionIdToCollectionIdMap = new HashMap<>(); + Map publishedActionIdToCollectionIdMap = new HashMap<>(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ImportingMetaDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ImportingMetaDTO.java index cf7bb590d5..b706e23c0b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ImportingMetaDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ImportingMetaDTO.java @@ -6,6 +6,7 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.List; import java.util.Set; @Data @@ -23,6 +24,8 @@ public class ImportingMetaDTO { String branchName; + List branchedArtifactIds; + /** * this flag is for verifying whether the artifact in focus needs to be updated with the given provided json */ diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/LayoutExecutableUpdateDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/LayoutExecutableUpdateDTO.java index 004c8387c6..07b29ace28 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/LayoutExecutableUpdateDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/LayoutExecutableUpdateDTO.java @@ -23,7 +23,4 @@ public class LayoutExecutableUpdateDTO { @JsonView(Views.Public.class) Boolean executeOnLoad; - - @JsonView(Views.Internal.class) - String defaultActionId; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/PageDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/PageDTO.java index 3b61de875c..1ba7f086ba 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/PageDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/PageDTO.java @@ -1,6 +1,5 @@ package com.appsmith.server.dtos; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.Policy; import com.appsmith.external.views.Git; import com.appsmith.external.views.Views; @@ -31,6 +30,10 @@ public class PageDTO { @JsonView({Views.Public.class}) private String id; + @Transient + @JsonView({Views.Public.class}) + private String baseId; + @JsonView({Views.Public.class, Views.Export.class, Git.class}) String name; @@ -72,11 +75,9 @@ public class PageDTO { @JsonView(Views.Public.class) Long lastUpdatedTime; - // This field will be used to store the default/root pageId and applicationId for actions generated for git - // connected applications and will be used to connect actions across the branches @Transient - @JsonView(Views.Public.class) - DefaultResources defaultResources; + @JsonView({Views.Internal.class}) + String branchName; @JsonView(Views.Public.class) Map> dependencyMap; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/PageNameIdDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/PageNameIdDTO.java index cb3ae11f46..7e19bb5e44 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/PageNameIdDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/PageNameIdDTO.java @@ -13,6 +13,9 @@ public class PageNameIdDTO { @JsonView(Views.Public.class) String id; + @JsonView(Views.Public.class) + String baseId; + @JsonView(Views.Public.class) String name; @@ -33,9 +36,4 @@ public class PageNameIdDTO { @JsonView(Views.Public.class) Set userPermissions; - - // This field will represent the default pageId for current page in git system where we are connecting resources - // among the branches - @JsonView(Views.Internal.class) - String defaultPageId; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionCollectionCE_DTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionCollectionCE_DTO.java index 612ffd083c..3ae34fcc15 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionCollectionCE_DTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionCollectionCE_DTO.java @@ -3,7 +3,6 @@ package com.appsmith.server.dtos.ce; import com.appsmith.external.exceptions.ErrorDTO; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.CreatorContextType; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.JSValue; import com.appsmith.external.models.PluginType; import com.appsmith.external.views.Git; @@ -26,8 +25,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNewFieldValuesIntoOldObject; - @Getter @Setter @NoArgsConstructor @@ -39,6 +36,10 @@ public class ActionCollectionCE_DTO { @JsonView(Views.Public.class) private String id; + @Transient + @JsonView(Views.Public.class) + private String baseId; + @Transient @JsonView(Views.Public.class) String applicationId; @@ -92,11 +93,6 @@ public class ActionCollectionCE_DTO { @JsonView({Views.Public.class, Git.class}) List variables; - // This will be used to store the defaultPageId but other fields like branchName, applicationId will act as - // transient - @JsonView(Views.Internal.class) - DefaultResources defaultResources; - // Instead of storing the entire action object, we only populate this field while interacting with the client side @Transient @JsonView(Views.Public.class) @@ -118,19 +114,14 @@ public class ActionCollectionCE_DTO { public void populateTransientFields(ActionCollection actionCollection) { this.setId(actionCollection.getId()); + this.setBaseId(actionCollection.getBaseIdOrFallback()); this.setApplicationId(actionCollection.getApplicationId()); this.setWorkspaceId(actionCollection.getWorkspaceId()); this.setUserPermissions(actionCollection.userPermissions); - if (this.getDefaultResources() == null) { - this.setDefaultResources(actionCollection.getDefaultResources()); - } else { - copyNewFieldValuesIntoOldObject(actionCollection.getDefaultResources(), this.getDefaultResources()); - } } public void sanitiseForExport() { this.resetTransientFields(); - this.setDefaultResources(null); this.setUserPermissions(Set.of()); } @@ -141,6 +132,7 @@ public class ActionCollectionCE_DTO { protected void resetTransientFields() { this.setId(null); + this.setBaseId(null); this.setWorkspaceId(null); this.setApplicationId(null); this.setErrorReports(null); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionCollectionViewCE_DTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionCollectionViewCE_DTO.java index 2358a2f658..c790321db8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionCollectionViewCE_DTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionCollectionViewCE_DTO.java @@ -1,7 +1,6 @@ package com.appsmith.server.dtos.ce; import com.appsmith.external.models.ActionDTO; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.JSValue; import lombok.Getter; import lombok.NoArgsConstructor; @@ -22,5 +21,4 @@ public class ActionCollectionViewCE_DTO { List variables; List actions; String body; - DefaultResources defaultResources; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionViewCE_DTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionViewCE_DTO.java index 7a75d5d650..2a5663d086 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionViewCE_DTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ActionViewCE_DTO.java @@ -1,6 +1,5 @@ package com.appsmith.server.dtos.ce; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.views.Views; import com.fasterxml.jackson.annotation.JsonView; import lombok.Getter; @@ -20,6 +19,9 @@ public class ActionViewCE_DTO { @JsonView(Views.Public.class) String id; + @JsonView(Views.Public.class) + String baseId; + @JsonView(Views.Public.class) String name; @@ -35,9 +37,6 @@ public class ActionViewCE_DTO { @JsonView(Views.Public.class) Set jsonPathKeys; - @JsonView(Views.Internal.class) - DefaultResources defaultResources; - // Overriding the getter to ensure that for actions missing action configuration, the timeout is // still set for the client to use as a guideline (even though this would be an invalid action // and hence would return an action execution error. diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/UserProfileCE_DTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/UserProfileCE_DTO.java index 66fc913710..cdfe7399cd 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/UserProfileCE_DTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/UserProfileCE_DTO.java @@ -8,6 +8,7 @@ import java.util.Set; @Data public class UserProfileCE_DTO { + String email; Set workspaceIds; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/ExportServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/ExportServiceCE.java index e10da9e60d..bdf88ccea6 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/ExportServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/ExportServiceCE.java @@ -26,5 +26,5 @@ public interface ExportServiceCE { Mono exportByArtifactIdAndBranchName( String artifactId, String branchName, ArtifactType artifactType); - Mono getArtifactFile(String artifactId, String branchName, ArtifactType artifactType); + Mono getArtifactFile(String branchedArtifactId, ArtifactType artifactType); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/ExportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/ExportServiceCEImpl.java index c4ac38b477..b430db8c64 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/ExportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/ExportServiceCEImpl.java @@ -113,8 +113,7 @@ public class ExportServiceCEImpl implements ExportServiceCE { SerialiseArtifactObjective serialiseArtifactObjective = objective == null ? SerialiseArtifactObjective.SHARE : objective; - boolean isGitSync = SerialiseArtifactObjective.VERSION_CONTROL.equals(serialiseArtifactObjective) - || SerialiseArtifactObjective.KNOWLEDGE_BASE_GENERATION.equals(serialiseArtifactObjective); + boolean isGitSync = SerialiseArtifactObjective.VERSION_CONTROL.equals(serialiseArtifactObjective); // We need edit permission for git-related tasks, otherwise export permissions are required AclPermission permission = @@ -130,7 +129,7 @@ public class ExportServiceCEImpl implements ExportServiceCE { // Find the transaction artifact with appropriate permission Mono exportableArtifactMono = artifactBasedExportService - .findExistingArtifactByIdAndBranchName(artifactId, branchName, permission) + .findExistingArtifactByIdAndBranchName(artifactId, null, permission) .map(transactionArtifact -> { // Since we have moved the setting of artifactId from the repository, the MetaDTO needs to assigned // from here @@ -285,8 +284,8 @@ public class ExportServiceCEImpl implements ExportServiceCE { artifactId, branchName, SerialiseArtifactObjective.SHARE, artifactType); } - public Mono getArtifactFile(String artifactId, String branchName, ArtifactType artifactType) { - return exportByArtifactIdAndBranchName(artifactId, branchName, artifactType) + public Mono getArtifactFile(String branchedArtifactId, ArtifactType artifactType) { + return exportByArtifactId(branchedArtifactId, SerialiseArtifactObjective.SHARE, artifactType) .doOnNext(artifactExchangeJson -> artifactExchangeJson.setModifiedResources(null)) .map(artifactExchangeJson -> { String stringifiedFile = gson.toJson(artifactExchangeJson); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/partial/PartialExportServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/partial/PartialExportServiceCE.java index bd2672183d..ebd55cf764 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/partial/PartialExportServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/partial/PartialExportServiceCE.java @@ -6,5 +6,5 @@ import reactor.core.publisher.Mono; public interface PartialExportServiceCE { Mono getPartialExportResources( - String applicationId, String pageId, String branchName, PartialExportFileDTO partialExportFileDTO); + String branchedApplicationId, String branchedPageId, PartialExportFileDTO partialExportFileDTO); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/partial/PartialExportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/partial/PartialExportServiceCEImpl.java index 9488b4e195..2fd276dc31 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/partial/PartialExportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/exports/internal/partial/PartialExportServiceCEImpl.java @@ -31,7 +31,6 @@ import com.appsmith.server.services.SessionUserService; import com.appsmith.server.solutions.ApplicationPermission; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import reactor.core.publisher.Mono; import java.util.List; @@ -61,7 +60,7 @@ public class PartialExportServiceCEImpl implements PartialExportServiceCE { @Override public Mono getPartialExportResources( - String applicationId, String pageId, String branchName, PartialExportFileDTO partialExportFileDTO) { + String branchedApplicationId, String branchedPageId, PartialExportFileDTO partialExportFileDTO) { /* * Params has ids for actions, customJsLibs and datasource * Export the resources based on the value of these entities @@ -72,7 +71,7 @@ public class PartialExportServiceCEImpl implements PartialExportServiceCE { final ExportingMetaDTO exportingMetaDTO = new ExportingMetaDTO(); exportingMetaDTO.setArtifactType(FieldName.APPLICATION); - exportingMetaDTO.setArtifactId(applicationId); + exportingMetaDTO.setArtifactId(branchedApplicationId); exportingMetaDTO.setBranchName(null); exportingMetaDTO.setIsGitSync(false); exportingMetaDTO.setExportWithConfiguration(false); @@ -82,13 +81,11 @@ public class PartialExportServiceCEImpl implements PartialExportServiceCE { applicationJson.setClientSchemaVersion(jsonSchemaVersions.getClientVersion()); AclPermission permission = applicationPermission.getExportPermission(false, false); - Mono branchedPageIdMono = - newPageService.findBranchedPageId(branchName, pageId, AclPermission.MANAGE_PAGES); Mono applicationMono = applicationService - .findById(applicationId, applicationPermission.getEditPermission()) - .switchIfEmpty(Mono.error( - new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, applicationId))) + .findById(branchedApplicationId, applicationPermission.getEditPermission()) + .switchIfEmpty(Mono.error(new AppsmithException( + AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, branchedApplicationId))) .cache(); return applicationMono @@ -111,41 +108,31 @@ public class PartialExportServiceCEImpl implements PartialExportServiceCE { .flatMap(appJson -> { if (partialExportFileDTO.getCustomJsLib().size() > 0) { return exportFilteredCustomJSLib( - applicationId, - partialExportFileDTO.getCustomJsLib(), - applicationJson, - branchName) + branchedApplicationId, partialExportFileDTO.getCustomJsLib(), applicationJson) .flatMap(jsLibList -> { - if (StringUtils.isEmpty(branchName)) { - return Mono.just(pageId); - } - return branchedPageIdMono; + return Mono.just(branchedPageId); }); } else { - if (StringUtils.isEmpty(branchName)) { - return Mono.just(pageId); - } - return branchedPageIdMono; + return Mono.just(branchedPageId); } }) // update page name in meta and exportable DTO for resource to name mapping - .flatMap(branchedPageId -> updatePageNameInResourceMapDTO(branchedPageId, mappedResourcesDTO)) + .flatMap(branchedPageId1 -> updatePageNameInResourceMapDTO(branchedPageId, mappedResourcesDTO)) // export actions // export js objects - .flatMap(branchedPageId -> { + .flatMap(branchedPageId1 -> { if (partialExportFileDTO.getActionCollectionList().size() > 0) { return exportActionCollections( branchedPageId, partialExportFileDTO.getActionCollectionList(), applicationJson, exportingMetaDTO, - mappedResourcesDTO, - branchName) + mappedResourcesDTO) .then(Mono.just(branchedPageId)); } return Mono.just(branchedPageId); }) - .flatMap(branchedPageId -> { + .flatMap(branchedPageId1 -> { if (partialExportFileDTO.getActionCollectionList().size() > 0 || partialExportFileDTO.getActionList().size() > 0) { return exportActions( @@ -153,8 +140,7 @@ public class PartialExportServiceCEImpl implements PartialExportServiceCE { partialExportFileDTO.getActionList(), applicationJson, exportingMetaDTO, - mappedResourcesDTO, - branchName) + mappedResourcesDTO) .then(Mono.just(branchedPageId)); } return Mono.just(branchedPageId); @@ -201,9 +187,9 @@ public class PartialExportServiceCEImpl implements PartialExportServiceCE { } private Mono exportFilteredCustomJSLib( - String applicationId, List customJSLibSet, ApplicationJson applicationJson, String branchName) { + String branchedApplicationId, List customJSLibSet, ApplicationJson applicationJson) { return customJSLibService - .getAllJSLibsInContext(applicationId, CreatorContextType.APPLICATION, branchName, false) + .getAllJSLibsInContext(branchedApplicationId, CreatorContextType.APPLICATION, false) .flatMap(customJSLibs -> { List updatedCustomJSLibList = customJSLibs.stream() .filter(customJSLib -> customJSLibSet.contains(customJSLib.getId())) @@ -215,19 +201,16 @@ public class PartialExportServiceCEImpl implements PartialExportServiceCE { } private Mono exportActions( - String pageId, + String branchedPageId, List validActions, ApplicationJson applicationJson, ExportingMetaDTO exportingMetaDTO, - MappedExportableResourcesDTO mappedResourcesDTO, - String branchName) { - return newActionService.findByPageId(pageId).collectList().flatMap(actions -> { + MappedExportableResourcesDTO mappedResourcesDTO) { + return newActionService.findByPageId(branchedPageId).collectList().flatMap(actions -> { // For git connected app, the filtering has to be done on the default action id // since the client is not aware of the branched resource id List updatedActionList = actions.stream() - .filter(action -> branchName != null - ? validActions.contains(action.getDefaultResources().getActionId()) - : validActions.contains(action.getId())) + .filter(action -> validActions.contains(action.getId())) .toList(); // Map name to id for exportable entities @@ -243,31 +226,30 @@ public class PartialExportServiceCEImpl implements PartialExportServiceCE { } private Mono exportActionCollections( - String pageId, + String branchedPageId, List validActions, ApplicationJson applicationJson, ExportingMetaDTO exportingMetaDTO, - MappedExportableResourcesDTO mappedResourcesDTO, - String branchName) { - return actionCollectionService.findByPageId(pageId).collectList().flatMap(actionCollections -> { - // For git connected app, the filtering has to be done on the default actionCollection id - // since the client is not aware of the branched resource id - List updatedActionCollectionList = actionCollections.stream() - .filter(actionCollection -> branchName != null - ? validActions.contains( - actionCollection.getDefaultResources().getCollectionId()) - : validActions.contains(actionCollection.getId())) - .toList(); - // Map name to id for exportable entities - actionCollectionExportableService.mapNameToIdForExportableEntities( - exportingMetaDTO, mappedResourcesDTO, updatedActionCollectionList); - // Make it exportable by removing the ids - updatedActionCollectionList = updatedActionCollectionList.stream() - .peek(ActionCollection::sanitiseToExportDBObject) - .collect(Collectors.toList()); - applicationJson.setActionCollectionList(updatedActionCollectionList); - return Mono.just(applicationJson); - }); + MappedExportableResourcesDTO mappedResourcesDTO) { + return actionCollectionService + .findByPageId(branchedPageId) + .collectList() + .flatMap(actionCollections -> { + // For git connected app, the filtering has to be done on the default actionCollection id + // since the client is not aware of the branched resource id + List updatedActionCollectionList = actionCollections.stream() + .filter(actionCollection -> validActions.contains(actionCollection.getId())) + .toList(); + // Map name to id for exportable entities + actionCollectionExportableService.mapNameToIdForExportableEntities( + exportingMetaDTO, mappedResourcesDTO, updatedActionCollectionList); + // Make it exportable by removing the ids + updatedActionCollectionList = updatedActionCollectionList.stream() + .peek(ActionCollection::sanitiseToExportDBObject) + .collect(Collectors.toList()); + applicationJson.setActionCollectionList(updatedActionCollectionList); + return Mono.just(applicationJson); + }); } private Mono updatePageNameInResourceMapDTO( diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceCE.java index 7a4d9d99e5..b0de6fec2d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceCE.java @@ -13,6 +13,5 @@ public interface ApplicationForkingServiceCE { Mono forkApplicationToWorkspaceWithEnvironment( String srcApplicationId, String targetWorkspaceId, String sourceEnvironmentId); - Mono forkApplicationToWorkspace( - String srcApplicationId, String targetWorkspaceId, String branchName); + Mono forkApplicationToWorkspace(String branchedSourceApplicationId, String targetWorkspaceId); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceCEImpl.java index a1dd2e59d5..2c9de9e1eb 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceCEImpl.java @@ -7,8 +7,6 @@ import com.appsmith.external.helpers.AppsmithEventContextType; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.BaseDomain; import com.appsmith.external.models.Datasource; -import com.appsmith.external.models.DefaultResources; -import com.appsmith.server.acl.AclPermission; import com.appsmith.server.actioncollections.base.ActionCollectionService; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.constants.ArtifactType; @@ -29,7 +27,6 @@ import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.fork.forkable.ForkableService; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.helpers.UserPermissionUtils; import com.appsmith.server.imports.internal.ImportService; import com.appsmith.server.layouts.UpdateLayoutService; @@ -51,7 +48,6 @@ import com.appsmith.server.solutions.WorkspacePermission; import com.appsmith.server.themes.base.ThemeService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang.StringUtils; import org.bson.types.ObjectId; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -74,7 +70,6 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic protected final WorkspaceService workspaceService; protected final SessionUserService sessionUserService; private final AnalyticsService analyticsService; - private final ResponseUtils responseUtils; protected final WorkspacePermission workspacePermission; protected final ApplicationPermission applicationPermission; private final ImportService importService; @@ -159,10 +154,8 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic final NewPage newPage = tuple.getT1(); final boolean isDefault = tuple.getT2(); final String templatePageId = newPage.getId(); - DefaultResources defaults = new DefaultResources(); - defaults.setApplicationId(newPage.getApplicationId()); - newPage.setDefaultResources(defaults); newPage.makePristine(); + newPage.setGitSyncId(null); PageDTO page = newPage.getUnpublishedPage(); if (page.getLayouts() != null) { @@ -172,7 +165,6 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic } page.setApplicationId(newPage.getApplicationId()); - page.setDefaultResources(defaults); ForkingMetaDTO sourceMetaForPage = sourceMeta.toBuilder() .applicationId(page.getApplicationId()) @@ -227,22 +219,15 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic log.info("Creating clone of action collection {}", originalCollectionId); // Sanitize them actionCollection.makePristine(); + actionCollection.setGitSyncId(null); actionCollection.setPublishedCollection(null); final ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); unpublishedCollection.setPageId(savedPage.getId()); - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setPageId(savedPage.getId()); - unpublishedCollection.setDefaultResources(defaultResources); - actionCollection.setWorkspaceId(toWorkspaceId); actionCollection.setApplicationId(savedPage.getApplicationId()); - DefaultResources defaultResources1 = new DefaultResources(); - defaultResources1.setApplicationId(savedPage.getApplicationId()); - actionCollection.setDefaultResources(defaultResources1); - actionCollectionService.generateAndSetPolicies(savedPage, actionCollection); return actionCollectionService @@ -252,14 +237,10 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic Mono.just(clonedActionCollection.getId()), Mono.just(originalCollectionId)); - if (org.springframework.util.StringUtils.isEmpty(clonedActionCollection - .getDefaultResources() - .getCollectionId())) { + if (org.springframework.util.StringUtils.isEmpty( + clonedActionCollection.getBaseId())) { ActionCollection updates = new ActionCollection(); - DefaultResources defaultResources2 = - clonedActionCollection.getDefaultResources(); - defaultResources2.setCollectionId(clonedActionCollection.getId()); - updates.setDefaultResources(defaultResources2); + updates.setBaseId(clonedActionCollection.getId()); return actionCollectionService .update(clonedActionCollection.getId(), updates) .then(tuple2Mono); @@ -282,7 +263,8 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic action.getName(), newAction.getId()); action.setPageId(savedPage.getId()); - action.setDefaultResources(null); + action.setBaseId(null); + action.setBranchName(null); return newAction; }) .flatMap(newAction -> { @@ -293,6 +275,7 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic String forkedCollectionId = collectionIdMap.get(originalCollectionId); log.info("Creating clone of action {}", originalActionId); newAction.makePristine(); + newAction.setGitSyncId(null); newAction.setWorkspaceId(toWorkspaceId); ActionDTO action = newAction.getUnpublishedAction(); action.setCollectionId(forkedCollectionId); @@ -430,7 +413,7 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic return applicationPageService .setApplicationPolicies(userMono, workspaceId, application) - .flatMap(applicationService::createDefaultApplication); + .flatMap(applicationService::createBaseApplication); } @Override @@ -501,39 +484,34 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic } public Mono forkApplicationToWorkspace( - String srcApplicationId, String targetWorkspaceId, String branchName) { + String branchedSourceApplicationId, String targetWorkspaceId) { // First we try to find the correct database entry of application to fork, based on git Mono applicationMono; - if (StringUtils.isEmpty(branchName)) { - applicationMono = applicationService - .findById(srcApplicationId, applicationPermission.getReadPermission()) - .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, srcApplicationId))) - .flatMap(application -> { - // For git connected application user can update the default branch - // In such cases we should fork the application from the new default branch - if (!(application.getGitApplicationMetadata() == null) - && !application - .getGitApplicationMetadata() - .getBranchName() - .equals(application - .getGitApplicationMetadata() - .getDefaultBranchName())) { - return applicationService.findByBranchNameAndDefaultApplicationId( - application.getGitApplicationMetadata().getDefaultBranchName(), - srcApplicationId, - applicationPermission.getReadPermission()); - } + applicationMono = applicationService + .findById(branchedSourceApplicationId, applicationPermission.getReadPermission()) + .switchIfEmpty(Mono.error(new AppsmithException( + AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, branchedSourceApplicationId))) + .flatMap(application -> { + if ((application.getGitApplicationMetadata() == null) + || application + .getGitApplicationMetadata() + .getBranchName() + .equals(application + .getGitApplicationMetadata() + .getDefaultBranchName())) { return Mono.just(application); - }); - } else { - applicationMono = applicationService.findByBranchNameAndDefaultApplicationId( - branchName, srcApplicationId, applicationPermission.getReadPermission()); - } + } + // For git connected application user can update the default branch + // In such cases we should fork the application from the new default branch + return applicationService.findByBranchNameAndBaseApplicationId( + application.getGitApplicationMetadata().getDefaultBranchName(), + application.getGitApplicationMetadata().getDefaultArtifactId(), + applicationPermission.getReadPermission()); + }); - return checkPermissionsForForking(srcApplicationId, targetWorkspaceId, branchName) + return checkPermissionsForForking(branchedSourceApplicationId, targetWorkspaceId) .then(applicationMono) // We will be forking to the default environment in the new workspace .zipWhen(application -> workspaceService.getDefaultEnvironmentId(application.getWorkspaceId(), null)) @@ -542,7 +520,6 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic String sourceEnvironmentId = tuple.getT2(); return forkApplicationToWorkspaceWithEnvironment( fromApplicationId, targetWorkspaceId, sourceEnvironmentId) - .map(responseUtils::updateApplicationWithDefaultResources) .flatMap(application -> importService.getArtifactImportDTO( application.getWorkspaceId(), application.getId(), @@ -575,31 +552,21 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic }); } - private Mono checkPermissionsForForking( - String srcApplicationId, String targetWorkspaceId, String branchName) { - Optional optionalBranchName = Optional.ofNullable(branchName); - Optional optionalAclPermission = Optional.empty(); + private Mono checkPermissionsForForking(String branchedApplicationId1, String targetWorkspaceId) { Mono applicationMonoWithOutPermission = applicationService - .findBranchedApplicationId(optionalBranchName, srcApplicationId, optionalAclPermission) - .flatMap(branchedApplicationId -> applicationService.findById(branchedApplicationId, null)) + .findById(branchedApplicationId1, null) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, srcApplicationId))); + AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, branchedApplicationId1))) + .cache(); // For sample apps that are marked as forked, we allow forking to any workspace without any permission checks return isForkingEnabled(applicationMonoWithOutPermission).flatMap(isForkingEnabled -> { if (isForkingEnabled) { return Mono.just(Boolean.TRUE); } - Mono applicationMono = applicationService - .findBranchedApplicationId(branchName, srcApplicationId, applicationPermission.getEditPermission()) - .flatMap(branchedApplicationId -> applicationService.findById( - branchedApplicationId, applicationPermission.getEditPermission())) - .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, srcApplicationId))) - .cache(); // Normal Application forking with developer/edit access - Flux pageFlux = applicationMono.flatMapMany(application -> newPageRepository + Flux pageFlux = applicationMonoWithOutPermission.flatMapMany(application -> newPageRepository .findIdsAndPoliciesByApplicationIdIn(List.of(application.getId())) .map(idPoliciesOnly -> { NewPage newPage = new NewPage(); @@ -609,18 +576,19 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic }) .flatMap(newPageRepository::setUserPermissionsInObject)); - Flux actionFlux = applicationMono.flatMapMany(application -> newActionRepository - .findIdsAndPoliciesByApplicationIdIn(List.of(application.getId())) - .map(idPoliciesOnly -> { - NewAction newAction = new NewAction(); - newAction.setId(idPoliciesOnly.getId()); - newAction.setPolicies(idPoliciesOnly.getPolicies()); - return newAction; - }) - .flatMap(newActionRepository::setUserPermissionsInObject)); + Flux actionFlux = + applicationMonoWithOutPermission.flatMapMany(application -> newActionRepository + .findIdsAndPoliciesByApplicationIdIn(List.of(application.getId())) + .map(idPoliciesOnly -> { + NewAction newAction = new NewAction(); + newAction.setId(idPoliciesOnly.getId()); + newAction.setPolicies(idPoliciesOnly.getPolicies()); + return newAction; + }) + .flatMap(newActionRepository::setUserPermissionsInObject)); Flux actionCollectionFlux = - applicationMono.flatMapMany(application -> actionCollectionRepository + applicationMonoWithOutPermission.flatMapMany(application -> actionCollectionRepository .findByApplicationId(application.getId(), Optional.empty(), Optional.empty()) .flatMap(actionCollectionRepository::setUserPermissionsInObject)); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceImpl.java index 019687dcd7..980fb3a0c2 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/fork/internal/ApplicationForkingServiceImpl.java @@ -4,7 +4,6 @@ import com.appsmith.external.models.Datasource; import com.appsmith.server.actioncollections.base.ActionCollectionService; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.fork.forkable.ForkableService; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.imports.internal.ImportService; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; @@ -36,7 +35,6 @@ public class ApplicationForkingServiceImpl extends ApplicationForkingServiceCEIm WorkspaceService workspaceService, SessionUserService sessionUserService, AnalyticsService analyticsService, - ResponseUtils responseUtils, WorkspacePermission workspacePermission, ApplicationPermission applicationPermission, ImportService importService, @@ -59,7 +57,6 @@ public class ApplicationForkingServiceImpl extends ApplicationForkingServiceCEIm workspaceService, sessionUserService, analyticsService, - responseUtils, workspacePermission, applicationPermission, importService, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitServiceCE.java index b65b0a8307..e6cbc64a12 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitServiceCE.java @@ -5,5 +5,5 @@ import reactor.core.publisher.Mono; public interface AutoCommitServiceCE { - Mono autoCommitApplication(String defaultApplicationId, String branchName); + Mono autoCommitApplication(String defaultApplicationId); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitServiceCEImpl.java index 829dba7ed0..5115c99f08 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/AutoCommitServiceCEImpl.java @@ -44,21 +44,16 @@ public class AutoCommitServiceCEImpl implements AutoCommitServiceCE { private final GitAutoCommitHelperImpl gitAutoCommitHelper; @Override - public Mono autoCommitApplication(String defaultApplicationId, String branchName) { + public Mono autoCommitApplication(String branchedApplicationId) { - if (!hasText(defaultApplicationId)) { + if (!hasText(branchedApplicationId)) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.APPLICATION_ID)); } - if (!hasText(branchName)) { - return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.BRANCH_NAME)); - } - Mono applicationMonoCached = applicationService - .findByBranchNameAndDefaultApplicationId( - branchName, defaultApplicationId, applicationPermission.getEditPermission()) + .findById(branchedApplicationId, applicationPermission.getEditPermission()) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, defaultApplicationId))) + AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, branchedApplicationId))) .cache(); // A page-dto which must exist in the git file system is required, @@ -71,7 +66,7 @@ public class AutoCommitServiceCEImpl implements AutoCommitServiceCE { application.getId(), pagePermission.getEditPermission(), ApplicationMode.PUBLISHED) .next()) .switchIfEmpty(Mono.error( - new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, defaultApplicationId))); + new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, branchedApplicationId))); return applicationMonoCached.zipWith(pageDTOMono).flatMap(tuple2 -> { Application branchedApplication = tuple2.getT1(); @@ -85,19 +80,25 @@ public class AutoCommitServiceCEImpl implements AutoCommitServiceCE { } String workspaceId = branchedApplication.getWorkspaceId(); - GitArtifactMetadata gitArtifactMetadata = branchedApplication.getGitArtifactMetadata(); + GitArtifactMetadata branchedGitMetadata = branchedApplication.getGitArtifactMetadata(); + final String baseApplicationId = branchedGitMetadata.getDefaultArtifactId(); + final String branchName = branchedGitMetadata.getBranchName(); + + if (!hasText(branchName)) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.BRANCH_NAME)); + } Mono isAutoCommitRequiredMono = - autoCommitEligibilityHelper.isAutoCommitRequired(workspaceId, gitArtifactMetadata, pageDTO); + autoCommitEligibilityHelper.isAutoCommitRequired(workspaceId, branchedGitMetadata, pageDTO); Mono autoCommitProgressDTOMono = - gitAutoCommitHelper.getAutoCommitProgress(defaultApplicationId, branchName); + gitAutoCommitHelper.getAutoCommitProgress(baseApplicationId, branchName); return autoCommitProgressDTOMono.flatMap(autoCommitProgressDTO -> { if (Set.of(LOCKED, IN_PROGRESS).contains(autoCommitProgressDTO.getAutoCommitResponse())) { log.info( "application with id: {}, has requested auto-commit for branch name: {}, however an event for branch name: {} is already in progress", - defaultApplicationId, + baseApplicationId, branchName, autoCommitProgressDTO.getBranchName()); autoCommitResponseDTO.setAutoCommitResponse(autoCommitProgressDTO.getAutoCommitResponse()); @@ -110,7 +111,7 @@ public class AutoCommitServiceCEImpl implements AutoCommitServiceCE { if (!Boolean.TRUE.equals(autoCommitTriggerDTO.getIsAutoCommitRequired())) { log.info( "application with id: {}, and branch name: {} is not eligible for autocommit", - defaultApplicationId, + baseApplicationId, branchName); autoCommitResponseDTO.setAutoCommitResponse(IDLE); return Mono.just(autoCommitResponseDTO); @@ -119,15 +120,15 @@ public class AutoCommitServiceCEImpl implements AutoCommitServiceCE { // Autocommit can be started log.info( "application with id: {}, and branch name: {} is eligible for autocommit", - defaultApplicationId, + baseApplicationId, branchName); return gitAutoCommitHelper - .publishAutoCommitEvent(autoCommitTriggerDTO, defaultApplicationId, branchName) + .publishAutoCommitEvent(autoCommitTriggerDTO, baseApplicationId, branchName) .map(isEventPublished -> { if (TRUE.equals(isEventPublished)) { log.info( "autocommit event for application with id: {}, and branch name: {} is published", - defaultApplicationId, + baseApplicationId, branchName); autoCommitResponseDTO.setAutoCommitResponse(PUBLISHED); return autoCommitResponseDTO; @@ -135,7 +136,7 @@ public class AutoCommitServiceCEImpl implements AutoCommitServiceCE { log.info( "application with id: {}, and branch name: {} does not fulfil the prerequisite for autocommit", - defaultApplicationId, + baseApplicationId, branchName); autoCommitResponseDTO.setAutoCommitResponse(REQUIRED); return autoCommitResponseDTO; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/helpers/GitAutoCommitHelperImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/helpers/GitAutoCommitHelperImpl.java index e13e1e1815..eb399c0cae 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/helpers/GitAutoCommitHelperImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/autocommit/helpers/GitAutoCommitHelperImpl.java @@ -147,7 +147,7 @@ public class GitAutoCommitHelperImpl extends GitAutoCommitHelperFallbackImpl imp .cache(); Mono branchedApplicationMono = applicationService - .findByBranchNameAndDefaultApplicationId( + .findByBranchNameAndBaseApplicationId( finalBranchName, defaultApplicationId, applicationPermission.getEditPermission()) .cache(); @@ -166,7 +166,7 @@ public class GitAutoCommitHelperImpl extends GitAutoCommitHelperFallbackImpl imp Application defaultApplication = tuple2.getT1(); Application branchedApplication = tuple2.getT2(); return commonGitService - .fetchRemoteChanges(defaultApplication, branchedApplication, finalBranchName, true) + .fetchRemoteChanges(defaultApplication, branchedApplication, true) .flatMap(branchTrackingStatus -> { if (branchTrackingStatus.getBehindCount() > 0) { log.debug( diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/common/CommonGitServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/common/CommonGitServiceCE.java index 4c19d46218..b07fe7d90b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/common/CommonGitServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/common/CommonGitServiceCE.java @@ -1,7 +1,6 @@ package com.appsmith.server.git.common; import com.appsmith.external.dtos.GitBranchDTO; -import com.appsmith.external.dtos.GitLogDTO; import com.appsmith.external.dtos.GitStatusDTO; import com.appsmith.external.dtos.MergeStatusDTO; import com.appsmith.server.constants.ArtifactType; @@ -26,90 +25,74 @@ public interface CommonGitServiceCE { Mono> updateOrCreateGitProfileForCurrentUser(GitProfile gitProfile); - Mono> updateOrCreateGitProfileForCurrentUser( - GitProfile gitProfile, String defaultArtifactId); + Mono> updateOrCreateGitProfileForCurrentUser(GitProfile gitProfile, String baseArtifactId); Mono getDefaultGitProfileOrCreateIfEmpty(); - Mono getGitProfileForUser(String defaultArtifactId); + Mono getGitProfileForUser(String baseArtifactId); Mono updateGitMetadata( String applicationId, GitArtifactMetadata gitArtifactMetadata, ArtifactType artifactType); - Mono getGitArtifactMetadata(String defaultApplicationId, ArtifactType artifactType); + Mono getGitArtifactMetadata(String baseArtifactId, ArtifactType artifactType); Mono generateSSHKey(String keyType); - Mono testConnection(String defaultApplicationId, ArtifactType artifactType); - Mono> getGitDocUrls(); Mono> listBranchForArtifact( - String defaultArtifactId, Boolean pruneBranches, String currentBranch, ArtifactType artifactType); + String branchedArtifactId, Boolean pruneBranches, ArtifactType artifactType); // Git Operations: basic git operation of the interface - Mono createBranch( - String defaultArtifactId, GitBranchDTO branchDTO, String srcBranch, ArtifactType artifactType); + Mono createBranch(String branchedArtifactId, GitBranchDTO branchDTO, ArtifactType artifactType); - Mono getStatus( - String defaultArtifactId, boolean compareRemote, String branchName, ArtifactType artifactType); + Mono getStatus(String branchedArtifactId, boolean compareRemote, ArtifactType artifactType); - Mono> getCommitHistory(String branchName, String defaultArtifactId, ArtifactType artifactType); + Mono fetchRemoteChanges(Artifact baseArtifact, Artifact branchedArtifact, boolean isFileLock); Mono fetchRemoteChanges( - Artifact defaultArtifact, Artifact branchedArtifact, String branchName, boolean isFileLock); - - Mono fetchRemoteChanges( - String defaultApplicationId, String branchName, boolean isFileLock, ArtifactType artifactType); + String branchedArtifactId, boolean isFileLock, ArtifactType artifactType); Mono commitArtifact( - GitCommitDTO commitDTO, - String defaultArtifactId, - String branchName, - boolean doAmend, - ArtifactType artifactType); + GitCommitDTO commitDTO, String branchedArtifactId, boolean doAmend, ArtifactType artifactType); - Mono commitArtifact( - GitCommitDTO commitDTO, String defaultApplicationId, String branchName, ArtifactType artifactType); + Mono commitArtifact(GitCommitDTO commitDTO, String branchedArtifactId, ArtifactType artifactType); Mono checkoutBranch( - String defaultArtifactId, String branchName, boolean addFileLock, ArtifactType artifactType); + String branchedArtifactId, String branchToBeCheckedOut, boolean addFileLock, ArtifactType artifactType); - Mono deleteBranch(String defaultArtifactId, String branchName, ArtifactType artifactType); + Mono deleteBranch(String baseArtifactId, String branchName, ArtifactType artifactType); - Mono pullArtifact(String defaultArtifactId, String branchName, ArtifactType artifactType); + Mono pullArtifact(String branchedArtifactId, ArtifactType artifactType); - Mono pushArtifact(String defaultArtifactId, String branchName, ArtifactType artifactType); + Mono pushArtifact(String branchedArtifactId, ArtifactType artifactType); - Mono detachRemote(String defaultArtifactId, ArtifactType artifactType); + Mono detachRemote(String branchedArtifactId, ArtifactType artifactType); - Mono mergeBranch(String applicationId, GitMergeDTO gitMergeDTO, ArtifactType artifactType); + Mono mergeBranch(String branchedArtifactId, GitMergeDTO gitMergeDTO, ArtifactType artifactType); - Mono isBranchMergeable(String applicationId, GitMergeDTO gitMergeDTO, ArtifactType artifactType); - - Mono createConflictedBranch(String defaultApplicationId, String branchName, ArtifactType artifactType); + Mono isBranchMergeable( + String branchedArtifactId, GitMergeDTO gitMergeDTO, ArtifactType artifactType); // Artifact Git OPS Mono connectArtifactToGit( - String defaultArtifactId, GitConnectDTO gitConnectDTO, String origin, ArtifactType artifactType); + String baseArtifactId, GitConnectDTO gitConnectDTO, String origin, ArtifactType artifactType); - Mono discardChanges(String defaultApplicationId, String branchName, ArtifactType artifactType); + Mono discardChanges(String branchedArtifactId, ArtifactType artifactType); // Autocommit methods Mono> updateProtectedBranches( - String defaultArtifactId, List branchNames, ArtifactType artifactType); + String baseArtifactId, List branchNames, ArtifactType artifactType); - Mono> getProtectedBranches(String defaultArtifactId, ArtifactType artifactType); + Mono> getProtectedBranches(String baseArtifactId, ArtifactType artifactType); - Mono toggleAutoCommitEnabled(String defaultArtifactId, ArtifactType artifactType); + Mono toggleAutoCommitEnabled(String baseArtifactId, ArtifactType artifactType); Mono getAutoCommitProgress( String applicationId, String branchName, ArtifactType artifactType); - Mono autoCommitApplication(String defaultApplicationId, String branchName, ArtifactType artifactType); - Mono importArtifactFromGit( String workspaceId, GitConnectDTO gitConnectDTO, ArtifactType artifactType); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/common/CommonGitServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/common/CommonGitServiceCEImpl.java index 824d4e8b66..098f8c6667 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/common/CommonGitServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/common/CommonGitServiceCEImpl.java @@ -80,6 +80,7 @@ import reactor.core.Exceptions; import reactor.core.observability.micrometer.Micrometer; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import reactor.util.function.Tuple2; import reactor.util.function.Tuple3; import java.io.IOException; @@ -100,13 +101,12 @@ import static com.appsmith.external.git.constants.GitConstants.DEFAULT_COMMIT_ME import static com.appsmith.external.git.constants.GitConstants.EMPTY_COMMIT_ERROR_MESSAGE; import static com.appsmith.external.git.constants.GitConstants.GIT_CONFIG_ERROR; import static com.appsmith.external.git.constants.GitConstants.GIT_PROFILE_ERROR; -import static com.appsmith.external.git.constants.ce.GitConstantsCE.CONFLICTED_SUCCESS_MESSAGE; -import static com.appsmith.external.git.constants.ce.GitConstantsCE.MERGE_CONFLICT_BRANCH_NAME; import static com.appsmith.external.git.constants.ce.GitSpanCE.OPS_COMMIT; import static com.appsmith.external.git.constants.ce.GitSpanCE.OPS_STATUS; -import static com.appsmith.git.constants.AppsmithBotAsset.APPSMITH_BOT_USERNAME; +import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNestedNonNullProperties; import static com.appsmith.server.constants.ArtifactType.APPLICATION; import static com.appsmith.server.constants.SerialiseArtifactObjective.VERSION_CONTROL; +import static com.appsmith.server.constants.ce.FieldNameCE.BRANCH_NAME; import static com.appsmith.server.constants.ce.FieldNameCE.DEFAULT; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; @@ -146,29 +146,29 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { private static final String ORIGIN = "origin/"; private static final String REMOTE_NAME_REPLACEMENT = ""; - private Mono addFileLock(String defaultArtifactId, String commandName, boolean isLockRequired) { + private Mono addFileLock(String baseArtifactId, String commandName, boolean isLockRequired) { if (!Boolean.TRUE.equals(isLockRequired)) { return Mono.just(Boolean.TRUE); } - return Mono.defer(() -> addFileLock(defaultArtifactId, commandName)); + return Mono.defer(() -> addFileLock(baseArtifactId, commandName)); } - private Mono addFileLock(String defaultArtifactId, String commandName) { - return gitRedisUtils.addFileLock(defaultArtifactId, commandName); + private Mono addFileLock(String baseArtifactId, String commandName) { + return gitRedisUtils.addFileLock(baseArtifactId, commandName); } - private Mono releaseFileLock(String defaultArtifactId, boolean isLockRequired) { + private Mono releaseFileLock(String baseArtifactId, boolean isLockRequired) { if (!Boolean.TRUE.equals(isLockRequired)) { return Mono.just(Boolean.TRUE); } - return releaseFileLock(defaultArtifactId); + return releaseFileLock(baseArtifactId); } - private Mono releaseFileLock(String defaultArtifactId) { + private Mono releaseFileLock(String baseArtifactId) { return gitRedisUtils - .releaseFileLock(defaultArtifactId) + .releaseFileLock(baseArtifactId) .name(GitSpan.RELEASE_FILE_LOCK) .tap(Micrometer.observation(observationRegistry)); } @@ -208,7 +208,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { @Override public Mono updateGitMetadata( - String defaultArtifactId, GitArtifactMetadata gitArtifactMetadata, ArtifactType artifactType) { + String baseArtifactId, GitArtifactMetadata gitArtifactMetadata, ArtifactType artifactType) { if (Optional.ofNullable(gitArtifactMetadata).isEmpty()) { return Mono.error( @@ -221,28 +221,10 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); return gitArtifactHelper - .getArtifactById(defaultArtifactId, artifactEditPermission) + .getArtifactById(baseArtifactId, artifactEditPermission) .flatMap(artifact -> updateArtifactWithGitMetadataGivenPermission(artifact, gitArtifactMetadata)); } - /** - * Method to get commit history for application branch - * - * @param defaultArtifactId artifact for which the commit history is needed - * @return list of commits - **/ - @Override - public Mono> getCommitHistory( - String branchName, String defaultArtifactId, ArtifactType artifactType) { - GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); - AclPermission artifactReadPermission = gitArtifactHelper.getArtifactReadPermission(); - - Mono artifactMono = gitArtifactHelper.getArtifactByDefaultIdAndBranchName( - defaultArtifactId, branchName, artifactReadPermission); - - return artifactMono.flatMap(this::getCommitHistory); - } - protected Mono> getCommitHistory(Artifact branchedArtifact) { GitArtifactMetadata gitData = branchedArtifact.getGitArtifactMetadata(); if (gitData == null @@ -269,52 +251,50 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } @Override - public Mono getStatus( - String defaultArtifactId, boolean compareRemote, String branchName, ArtifactType artifactType) { - return getStatus(defaultArtifactId, branchName, true, compareRemote, artifactType); + public Mono getStatus(String branchedArtifactId, boolean compareRemote, ArtifactType artifactType) { + return getStatus(branchedArtifactId, true, compareRemote, artifactType); } - private Mono getStatus( - String defaultArtifactId, String branchName, boolean isFileLock, ArtifactType artifactType) { - return getStatus(defaultArtifactId, branchName, isFileLock, true, artifactType); + private Mono getStatusAfterComparingWithRemote( + String baseArtifactId, boolean isFileLock, ArtifactType artifactType) { + return getStatus(baseArtifactId, isFileLock, true, artifactType); } protected Mono getStatus( - Artifact defaultArtifact, - Artifact branchedArtifact, - String branchName, - boolean isFileLock, - boolean compareRemote) { + Artifact baseArtifact, Artifact branchedArtifact, boolean isFileLock, boolean compareRemote) { - if (StringUtils.isEmptyOrNull(branchName)) { + ArtifactType artifactType = baseArtifact.getArtifactType(); + GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); + + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + final String baseArtifactId = baseGitMetadata.getDefaultArtifactId(); + + GitArtifactMetadata branchedGitMetadata = branchedArtifact.getGitArtifactMetadata(); + branchedGitMetadata.setGitAuth(baseGitMetadata.getGitAuth()); + + final String finalBranchName = branchedGitMetadata.getBranchName(); + + if (StringUtils.isEmptyOrNull(finalBranchName)) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.BRANCH_NAME)); } - ArtifactType artifactType = defaultArtifact.getArtifactType(); - GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); - - GitArtifactMetadata defaultGitMetadata = defaultArtifact.getGitArtifactMetadata(); - final String defaultArtifactId = defaultGitMetadata.getDefaultArtifactId(); - final String finalBranchName = branchName.replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT); - - GitArtifactMetadata gitData = branchedArtifact.getGitArtifactMetadata(); - gitData.setGitAuth(defaultGitMetadata.getGitAuth()); - // create suffix to the git repository of the application. final Path repoSuffix = gitArtifactHelper.getRepoSuffixPath( - branchedArtifact.getWorkspaceId(), gitData.getDefaultArtifactId(), gitData.getRepoName()); + branchedArtifact.getWorkspaceId(), + branchedGitMetadata.getDefaultArtifactId(), + branchedGitMetadata.getRepoName()); Mono exportedArtifactJsonMono = exportService.exportByArtifactId(branchedArtifact.getId(), VERSION_CONTROL, artifactType); Mono statusMono = exportedArtifactJsonMono .flatMap(artifactExchangeJson -> { - return addFileLock(defaultArtifactId, GitCommandConstants.STATUS, isFileLock) + return addFileLock(baseArtifactId, GitCommandConstants.STATUS, isFileLock) .thenReturn(artifactExchangeJson); }) .flatMap(artifactExchangeJson -> { try { - GitAuth gitAuth = gitData.getGitAuth(); + GitAuth gitAuth = branchedGitMetadata.getGitAuth(); Mono fetchRemoteMono; if (compareRemote) { @@ -323,7 +303,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { gitAuth.getPublicKey(), gitAuth.getPrivateKey(), false, - branchName, + finalBranchName, false)) .onErrorResume(error -> Mono.error(new AppsmithException( AppsmithError.GIT_GENERIC_ERROR, error.getMessage()))); @@ -340,27 +320,10 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { new AppsmithException(AppsmithError.GIT_ACTION_FAILED, "status", e.getMessage())); } }) - .flatMap(tuple -> { - return gitExecutor.getStatus(tuple.getT1(), finalBranchName).flatMap(gitStatusDTO -> { - // Remove any files which are copied by hard resetting the repo - try { - return gitExecutor - .resetToLastCommit(repoSuffix, branchName) - .thenReturn(gitStatusDTO); - } catch (Exception e) { - log.error( - "failed to reset to last commit for application: {}, branch: {}", - defaultArtifactId, - branchName, - e); - return Mono.error( - new AppsmithException(AppsmithError.GIT_ACTION_FAILED, "status", e.getMessage())); - } - }); - }) + .flatMap(tuple -> gitExecutor.getStatus(tuple.getT1(), finalBranchName)) .flatMap(gitStatusDTO -> { // release the lock if there's a successful response - return releaseFileLock(defaultArtifactId, isFileLock).thenReturn(gitStatusDTO); + return releaseFileLock(baseArtifactId, isFileLock).thenReturn(gitStatusDTO); }) .onErrorResume(throwable -> { /* @@ -369,8 +332,8 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { */ log.error( "Error to get status for application: {}, branch: {}", - defaultArtifactId, - branchName, + baseArtifactId, + finalBranchName, throwable); return Mono.error(new AppsmithException(AppsmithError.GIT_GENERIC_ERROR, throwable.getMessage())); }); @@ -396,72 +359,51 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } /** - * Get the status of the mentioned branch + * Get the status of the artifact for given branched id * - * @param defaultArtifactId root/default application - * @param branchName for which the status is required - * @param isFileLock if the locking is required, since the status API is used in the other flows of git - * Only for the direct hits from the client the locking will be added - * @param artifactType Type of artifact in context + * @param branchedArtifactId branched id of the artifact + * @param isFileLock if the locking is required, since the status API is used in the other flows of git + * Only for the direct hits from the client the locking will be added + * @param artifactType Type of artifact in context * @return Map of json file names which are added, modified, conflicting, removed and the working tree if this is clean */ private Mono getStatus( - String defaultArtifactId, - String branchName, - boolean isFileLock, - boolean compareRemote, - ArtifactType artifactType) { + String branchedArtifactId, boolean isFileLock, boolean compareRemote, ArtifactType artifactType) { - if (StringUtils.isEmptyOrNull(branchName)) { - return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.BRANCH_NAME)); - } + Mono> baseAndBranchedArtifacts = + getBaseAndBranchedArtifacts(branchedArtifactId, artifactType); - final String finalBranchName = branchName.replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT); - - GitArtifactHelper artifactGitHelper = getArtifactGitService(artifactType); - AclPermission artifactEditPermission = artifactGitHelper.getArtifactEditPermission(); - - Mono defaultArtifactMono = artifactGitHelper - .getArtifactById(defaultArtifactId, artifactEditPermission) - .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.GIT_GENERIC_ERROR))); - - Mono branchedArtifactMono = artifactGitHelper - .getArtifactByDefaultIdAndBranchName(defaultArtifactId, finalBranchName, artifactEditPermission) - .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.GIT_GENERIC_ERROR))); - - Mono statusMono = defaultArtifactMono.flatMap(defaultArtifact -> { - return branchedArtifactMono.flatMap(branchedArtifact -> { - return getStatus(defaultArtifact, branchedArtifact, finalBranchName, isFileLock, compareRemote); - }); + return baseAndBranchedArtifacts.flatMap(artifactTuple -> { + Artifact baseArtifact = artifactTuple.getT1(); + Artifact branchedArtifact = artifactTuple.getT2(); + return getStatus(baseArtifact, branchedArtifact, isFileLock, compareRemote); }); - - return statusMono; } @Override public Mono fetchRemoteChanges( - Artifact defaultArtifact, Artifact branchedArtifact, String branchName, boolean isFileLock) { + Artifact baseArtifact, Artifact branchedArtifact, boolean isFileLock) { - if (StringUtils.isEmptyOrNull(branchName)) { - return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.BRANCH_NAME)); - } - - if (branchedArtifact == null || defaultArtifact == null || defaultArtifact.getGitArtifactMetadata() == null) { + if (branchedArtifact == null || baseArtifact == null || baseArtifact.getGitArtifactMetadata() == null) { return Mono.error(new AppsmithException(AppsmithError.GIT_GENERIC_ERROR)); } - final String finalBranchName = branchName.replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT); - GitArtifactMetadata defaultGitData = defaultArtifact.getGitArtifactMetadata(); - String defaultArtifactId = defaultGitData.getDefaultArtifactId(); + GitArtifactMetadata baseGitData = baseArtifact.getGitArtifactMetadata(); + GitArtifactMetadata branchedGitData = branchedArtifact.getGitArtifactMetadata(); - GitArtifactHelper artifactGitHelper = getArtifactGitService(defaultArtifact.getArtifactType()); + String baseArtifactId = baseGitData.getDefaultArtifactId(); + if (branchedGitData == null || !hasText(branchedGitData.getBranchName())) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, BRANCH_NAME)); + } + + final String finalBranchName = branchedArtifact.getGitArtifactMetadata().getBranchName(); + + GitArtifactHelper artifactGitHelper = getArtifactGitService(baseArtifact.getArtifactType()); Mono currUserMono = sessionUserService.getCurrentUser().cache(); // will be used to send analytics event - Mono addFileLockMono = Mono.just(Boolean.TRUE); - if (Boolean.TRUE.equals(isFileLock)) { - addFileLockMono = addFileLock(defaultArtifactId, GitCommandConstants.FETCH_REMOTE); - } + Mono addFileLockMono = addFileLock(baseArtifactId, GitCommandConstants.FETCH_REMOTE, isFileLock); + /* 1. Copy resources from DB to local repo 2. Fetch the current status from local repo @@ -470,18 +412,19 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { // current user mono has been zipped just to run in parallel. Mono fetchRemoteStatusMono = addFileLockMono .flatMap(isFileLocked -> { - GitArtifactMetadata gitData = branchedArtifact.getGitArtifactMetadata(); - gitData.setGitAuth(defaultGitData.getGitAuth()); + branchedGitData.setGitAuth(baseGitData.getGitAuth()); Path repoSuffix = artifactGitHelper.getRepoSuffixPath( - branchedArtifact.getWorkspaceId(), gitData.getDefaultArtifactId(), gitData.getRepoName()); + branchedArtifact.getWorkspaceId(), + branchedGitData.getDefaultArtifactId(), + branchedGitData.getRepoName()); Path repoPath = gitExecutor.createRepoPath(repoSuffix); Mono checkoutBranchMono = gitExecutor.checkoutToBranch(repoSuffix, finalBranchName); Mono fetchRemoteMono = gitExecutor.fetchRemote( repoPath, - gitData.getGitAuth().getPublicKey(), - gitData.getGitAuth().getPrivateKey(), + branchedGitData.getGitAuth().getPublicKey(), + branchedGitData.getGitAuth().getPrivateKey(), true, finalBranchName, false); @@ -493,10 +436,8 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { .then(Mono.defer(() -> fetchRemoteMono)) .then(Mono.defer(() -> branchedStatusMono)) .flatMap(branchTrackingStatus -> { - if (isFileLock) { - return releaseFileLock(defaultArtifactId).thenReturn(branchTrackingStatus); - } - return Mono.just(branchTrackingStatus); + return releaseFileLock(baseArtifactId, isFileLock) + .thenReturn(branchTrackingStatus); }) .onErrorResume(throwable -> { /* @@ -505,8 +446,8 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { */ log.error( "Error to fetch from remote for application: {}, branch: {}", - defaultArtifactId, - branchName, + baseArtifactId, + finalBranchName, throwable); return Mono.error(new AppsmithException( AppsmithError.GIT_ACTION_FAILED, "fetch", throwable.getMessage())); @@ -540,110 +481,26 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { * 1. Checkout (if required) to the branch to make sure we are comparing the right branch * 2. Run a git fetch command to fetch the latest changes from the remote * - * @param defaultArtifactId Default application id - * @param branchName name of the branch to compare with remote - * @param isFileLock whether to add file lock or not + * @param branchedArtifactId branched artifact id + * @param isFileLock whether to add file lock or not * @param artifactType * @return Mono of {@link BranchTrackingStatus} */ @Override public Mono fetchRemoteChanges( - String defaultArtifactId, String branchName, boolean isFileLock, ArtifactType artifactType) { - - if (StringUtils.isEmptyOrNull(branchName)) { - return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.BRANCH_NAME)); - } - - final String finalBranchName = branchName.replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT); + String branchedArtifactId, boolean isFileLock, ArtifactType artifactType) { GitArtifactHelper artifactGitHelper = getArtifactGitService(artifactType); AclPermission artifactEditPermission = artifactGitHelper.getArtifactEditPermission(); - Mono branchedArtifactMono = artifactGitHelper - .getArtifactByDefaultIdAndBranchName(defaultArtifactId, finalBranchName, artifactEditPermission) - .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.GIT_GENERIC_ERROR))) - .cache(); + Mono> baseAndBranchedArtifactMono = + getBaseAndBranchedArtifacts(branchedArtifactId, artifactType, artifactEditPermission); - Mono gitDataMono = getGitArtifactMetadata(defaultArtifactId, artifactType); + return baseAndBranchedArtifactMono.flatMap(artifactTuples -> { + Artifact baseArtifact = artifactTuples.getT1(); + Artifact branchedArtifact = artifactTuples.getT2(); - Mono currUserMono = sessionUserService.getCurrentUser().cache(); // will be used to send analytics event - - /* - 1. Copy resources from DB to local repo - 2. Fetch the current status from local repo - */ - - // current user mono has been zipped just to run in parallel. - Mono fetchRemoteStatusMono = Mono.zip(gitDataMono, branchedArtifactMono, currUserMono) - .flatMap(tuple3 -> { - if (!Boolean.TRUE.equals(isFileLock)) { - return Mono.just(tuple3); - } - - return addFileLock(tuple3.getT1().getDefaultArtifactId(), GitCommandConstants.FETCH_REMOTE) - .then(Mono.just(tuple3)); - }) - .flatMap(tuple3 -> { - GitArtifactMetadata defaultArtifactMetadata = tuple3.getT1(); - Artifact artifact = tuple3.getT2(); - GitArtifactMetadata gitData = artifact.getGitArtifactMetadata(); - gitData.setGitAuth(defaultArtifactMetadata.getGitAuth()); - - Path repoSuffix = artifactGitHelper.getRepoSuffixPath( - artifact.getWorkspaceId(), gitData.getDefaultArtifactId(), gitData.getRepoName()); - - Path repoPath = gitExecutor.createRepoPath(repoSuffix); - Mono checkoutBranchMono = gitExecutor.checkoutToBranch(repoSuffix, finalBranchName); - Mono fetchRemoteMono = gitExecutor.fetchRemote( - repoPath, - gitData.getGitAuth().getPublicKey(), - gitData.getGitAuth().getPrivateKey(), - true, - finalBranchName, - false); - - Mono branchedStatusMono = - gitExecutor.getBranchTrackingStatus(repoPath, finalBranchName); - - return checkoutBranchMono - .then(fetchRemoteMono) - .then(branchedStatusMono) - .flatMap(branchTrackingStatus -> { - if (isFileLock) { - return releaseFileLock(defaultArtifactId).thenReturn(branchTrackingStatus); - } - return Mono.just(branchTrackingStatus); - }) - .onErrorResume(throwable -> { - /* - in case of any error, the global exception handler will release the lock - hence we don't need to do that manually - */ - log.error( - "Error to fetch from remote for application: {}, branch: {}", - defaultArtifactId, - branchName, - throwable); - return Mono.error(new AppsmithException( - AppsmithError.GIT_ACTION_FAILED, "fetch", throwable.getMessage())); - }); - }) - .elapsed() - .zipWith(Mono.zip(currUserMono, branchedArtifactMono)) - .flatMap(objects -> { - Long elapsedTime = objects.getT1().getT1(); - BranchTrackingStatus branchTrackingStatus = objects.getT1().getT2(); - User currentUser = objects.getT2().getT1(); - Artifact artifact = objects.getT2().getT2(); - return sendUnitExecutionTimeAnalyticsEvent( - AnalyticsEvents.GIT_FETCH.getEventName(), elapsedTime, currentUser, artifact) - .thenReturn(branchTrackingStatus); - }) - .name(GitSpan.OPS_FETCH_REMOTE) - .tap(Micrometer.observation(observationRegistry)); - - return Mono.create(sink -> { - fetchRemoteStatusMono.subscribe(sink::success, sink::error, null, sink.currentContext()); + return fetchRemoteChanges(baseArtifact, branchedArtifact, isFileLock); }); } @@ -671,37 +528,36 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } @Override - public Mono getGitArtifactMetadata(String defaultApplicationId, ArtifactType artifactType) { + public Mono getGitArtifactMetadata(String baseArtifactId, ArtifactType artifactType) { GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); - AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); - Mono defaultArtifactMono = - gitArtifactHelper.getArtifactById(defaultApplicationId, artifactEditPermission); - return Mono.zip(defaultArtifactMono, userDataService.getForCurrentUser()) - .map(tuple -> { - Artifact artifact = tuple.getT1(); - UserData userData = tuple.getT2(); - Map gitProfiles = new HashMap<>(); - GitArtifactMetadata gitData = artifact.getGitArtifactMetadata(); + Mono baseArtifactMono = + gitArtifactHelper.getArtifactById(baseArtifactId, artifactEditPermission); - if (!CollectionUtils.isNullOrEmpty(userData.getGitProfiles())) { - gitProfiles.put(DEFAULT, userData.getGitProfileByKey(DEFAULT)); - gitProfiles.put(defaultApplicationId, userData.getGitProfileByKey(defaultApplicationId)); - } - if (gitData == null) { - GitArtifactMetadata res = new GitArtifactMetadata(); - res.setGitProfiles(gitProfiles); - return res; - } - gitData.setGitProfiles(gitProfiles); - if (gitData.getGitAuth() != null) { - gitData.setPublicKey(gitData.getGitAuth().getPublicKey()); - } - gitData.setDocUrl(Assets.GIT_DEPLOY_KEY_DOC_URL); - return gitData; - }); + return Mono.zip(baseArtifactMono, userDataService.getForCurrentUser()).map(tuple -> { + Artifact baseArtifact = tuple.getT1(); + UserData userData = tuple.getT2(); + Map gitProfiles = new HashMap<>(); + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + + if (!CollectionUtils.isNullOrEmpty(userData.getGitProfiles())) { + gitProfiles.put(DEFAULT, userData.getGitProfileByKey(DEFAULT)); + gitProfiles.put(baseArtifactId, userData.getGitProfileByKey(baseArtifactId)); + } + if (baseGitMetadata == null) { + GitArtifactMetadata res = new GitArtifactMetadata(); + res.setGitProfiles(gitProfiles); + return res; + } + baseGitMetadata.setGitProfiles(gitProfiles); + if (baseGitMetadata.getGitAuth() != null) { + baseGitMetadata.setPublicKey(baseGitMetadata.getGitAuth().getPublicKey()); + } + baseGitMetadata.setDocUrl(Assets.GIT_DEPLOY_KEY_DOC_URL); + return baseGitMetadata; + }); } /** @@ -717,7 +573,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { */ @Override public Mono connectArtifactToGit( - String defaultArtifactId, GitConnectDTO gitConnectDTO, String originHeader, ArtifactType artifactType) { + String baseArtifactId, GitConnectDTO gitConnectDTO, String originHeader, ArtifactType artifactType) { /* * Connecting the application for the first time * The ssh keys is already present in application object from generate SSH key step @@ -739,7 +595,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_PROFILE_ERROR))); Mono> profileMono = updateOrCreateGitProfileForCurrentUser( - gitConnectDTO.getGitProfile(), defaultArtifactId) + gitConnectDTO.getGitProfile(), baseArtifactId) .switchIfEmpty( Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_PROFILE_ERROR))); @@ -757,7 +613,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { AclPermission connectToGitPermission = gitArtifactHelper.getArtifactGitConnectPermission(); Mono artifactToConnectMono = - gitArtifactHelper.getArtifactById(defaultArtifactId, connectToGitPermission); + gitArtifactHelper.getArtifactById(baseArtifactId, connectToGitPermission); Mono connectedArtifactMono = Mono.zip(profileMono, isPrivateRepoMono, artifactToConnectMono) .flatMap(tuple -> { @@ -789,12 +645,12 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { }) .flatMap(artifact -> { GitArtifactMetadata gitArtifactMetadata = artifact.getGitArtifactMetadata(); - if (isDefaultGitMetadataInvalid(artifact.getGitArtifactMetadata())) { + if (isBaseGitMetadataInvalid(artifact.getGitArtifactMetadata())) { return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_SSH_CONFIGURATION)); } else { String repoName = GitUtils.getRepoName(gitConnectDTO.getRemoteUrl()); Path repoSuffix = gitArtifactHelper.getRepoSuffixPath( - artifact.getWorkspaceId(), defaultArtifactId, repoName); + artifact.getWorkspaceId(), baseArtifactId, repoName); Mono defaultBranchMono = gitExecutor .cloneRemoteIntoArtifactRepo( @@ -905,13 +761,13 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { .flatMap(artifact -> { String repoName = GitUtils.getRepoName(gitConnectDTO.getRemoteUrl()); Path readMePath = gitArtifactHelper.getRepoSuffixPath( - artifact.getWorkspaceId(), defaultArtifactId, repoName, "README.md"); + artifact.getWorkspaceId(), baseArtifactId, repoName, "README.md"); try { Mono readMeMono = gitArtifactHelper.intialiseReadMe(artifact, readMePath, originHeader); return Mono.zip(readMeMono, currentUserMono) .flatMap(tuple -> { UserData userData = tuple.getT2(); - GitProfile profile = userData.getGitProfileByKey(defaultArtifactId); + GitProfile profile = userData.getGitProfileByKey(baseArtifactId); if (profile == null || StringUtils.isEmptyOrNull(profile.getAuthorName()) || Boolean.TRUE.equals(profile.getUseGlobalProfile())) { @@ -934,16 +790,10 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { commitDTO.setCommitMessage( DEFAULT_COMMIT_MESSAGE + GitDefaultCommitMessage.CONNECT_FLOW.getReason()); - return this.commitArtifact( - commitDTO, - defaultArtifactId, - artifact.getGitArtifactMetadata() - .getBranchName(), - true, - artifactType) + return this.commitArtifact(commitDTO, baseArtifactId, true, artifactType) .onErrorResume(error -> // If the push fails remove all the cloned files from local repo - this.detachRemote(defaultArtifactId, artifactType) + this.detachRemote(baseArtifactId, artifactType) .flatMap(isDeleted -> { if (error instanceof TransportException) { return addAnalyticsForGitOperation( @@ -968,8 +818,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { .then(addAnalyticsForGitOperation( AnalyticsEvents.GIT_CONNECT, artifact, - artifact.getGitArtifactMetadata().getIsRepoPrivate())) - .map(gitArtifactHelper::updateArtifactWithDefaultReponseUtils); + artifact.getGitArtifactMetadata().getIsRepoPrivate())); } catch (IOException e) { log.error("Error while cloning the remote repo, {}", e.getMessage()); return Mono.error(new AppsmithException(AppsmithError.GIT_FILE_SYSTEM_ERROR, e.getMessage())); @@ -984,48 +833,41 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { * This method will make a commit to local repo * This is used directly from client, and we need to acquire file lock before starting to keep the application in a sane state * - * @param commitDTO information required for making a commit - * @param defaultArtifactId application branch on which the commit needs to be done - * @param doAmend if we want to amend the commit with the earlier one, used in connect flow + * @param commitDTO information required for making a commit + * @param branchedArtifactId application branch on which the commit needs to be done + * @param doAmend if we want to amend the commit with the earlier one, used in connect flow * @param artifactType * @return success message */ @Override public Mono commitArtifact( - GitCommitDTO commitDTO, - String defaultArtifactId, - String branchName, - boolean doAmend, - ArtifactType artifactType) { - return this.commitArtifact(commitDTO, defaultArtifactId, branchName, doAmend, true, artifactType); + GitCommitDTO commitDTO, String branchedArtifactId, boolean doAmend, ArtifactType artifactType) { + return this.commitArtifact(commitDTO, branchedArtifactId, doAmend, true, artifactType); } /** * This method will make a commit to local repo and is used internally in flows like create, merge branch * Since the lock is already acquired by the other flows, we do not need to acquire file lock again * - * @param commitDTO information required for making a commit - * @param defaultArtifactId application branch on which the commit needs to be done + * @param commitDTO information required for making a commit + * @param branchedArtifactId application branch on which the commit needs to be done * @return success message */ @Override - public Mono commitArtifact( - GitCommitDTO commitDTO, String defaultArtifactId, String branchName, ArtifactType artifactType) { - return this.commitArtifact(commitDTO, defaultArtifactId, branchName, false, false, artifactType); + public Mono commitArtifact(GitCommitDTO commitDTO, String branchedArtifactId, ArtifactType artifactType) { + return this.commitArtifact(commitDTO, branchedArtifactId, false, false, artifactType); } /** - * @param commitDTO information required for making a commit - * @param defaultArtifactId application branch on which the commit needs to be done - * @param branchName branch name for the commit flow - * @param doAmend if we want to amend the commit with the earlier one, used in connect flow - * @param isFileLock boolean value indicates whether the file lock is needed to complete the operation + * @param commitDTO information required for making a commit + * @param branchedArtifactId application branch on which the commit needs to be done + * @param doAmend if we want to amend the commit with the earlier one, used in connect flow + * @param isFileLock boolean value indicates whether the file lock is needed to complete the operation * @return success message */ private Mono commitArtifact( GitCommitDTO commitDTO, - String defaultArtifactId, - String branchName, + String branchedArtifactId, boolean doAmend, boolean isFileLock, ArtifactType artifactType) { @@ -1037,6 +879,32 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { 4. Commit application : git add, git commit (Also check if git init required) */ + String commitMessage = commitDTO.getCommitMessage(); + + if (commitMessage == null || commitMessage.isEmpty()) { + commitDTO.setCommitMessage(DEFAULT_COMMIT_MESSAGE + GitDefaultCommitMessage.CONNECT_FLOW.getReason()); + } + + GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); + AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); + Mono> baseAndBranchedArtifactMono = getBaseAndBranchedArtifacts( + branchedArtifactId, artifactType, artifactEditPermission) + .cache(); + + return baseAndBranchedArtifactMono.flatMap(artifactTuples -> { + Artifact baseArtifact = artifactTuples.getT1(); + Artifact branchedArtifact = artifactTuples.getT2(); + return commitArtifact(commitDTO, baseArtifact, branchedArtifact, doAmend, isFileLock); + }); + } + + private Mono commitArtifact( + GitCommitDTO commitDTO, + Artifact baseArtifact, + Artifact branchedArtifact, + boolean doAmend, + boolean isFileLock) { + String commitMessage = commitDTO.getCommitMessage(); StringBuilder result = new StringBuilder(); @@ -1044,78 +912,89 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { commitDTO.setCommitMessage(DEFAULT_COMMIT_MESSAGE + GitDefaultCommitMessage.CONNECT_FLOW.getReason()); } - if (StringUtils.isEmptyOrNull(branchName)) { - throw new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.BRANCH_NAME); - } - GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); boolean isSystemGenerated = commitDTO.getCommitMessage().contains(DEFAULT_COMMIT_MESSAGE); - AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); - Mono artifactMono = - gitArtifactHelper.getArtifactById(defaultArtifactId, artifactEditPermission); - Mono commitMono = artifactMono - .zipWhen(artifact -> - gitPrivateRepoHelper.isBranchProtected(artifact.getGitArtifactMetadata(), branchName)) - .map(objects -> { - if (objects.getT2()) { - throw new AppsmithException( - AppsmithError.GIT_ACTION_FAILED, - "commit", - "Cannot commit to protected branch " + branchName); - } - return objects.getT1(); - }) - .flatMap(artifact -> { - GitArtifactMetadata gitData = artifact.getGitArtifactMetadata(); - if (Boolean.TRUE.equals(isFileLock)) { - return addFileLock(gitData.getDefaultArtifactId(), GitCommandConstants.COMMIT) - .then(Mono.just(artifact)); - } - return Mono.just(artifact); - }) - .flatMap(defaultArtifact -> { - GitArtifactMetadata defaultGitMetadata = defaultArtifact.getGitArtifactMetadata(); - if (Optional.ofNullable(defaultGitMetadata).isEmpty()) { - return Mono.error( - new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_CONFIG_ERROR)); + GitArtifactHelper gitArtifactHelper = getArtifactGitService(baseArtifact.getArtifactType()); + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + GitArtifactMetadata branchedGitMetadata = branchedArtifact.getGitArtifactMetadata(); + + if (isBaseGitMetadataInvalid(baseGitMetadata)) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_CONFIG_ERROR)); + } + + if (branchedGitMetadata == null) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_CONFIG_ERROR)); + } + + final String branchName = branchedGitMetadata.getBranchName(); + + if (!hasText(branchName)) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.BRANCH_NAME)); + } + + Mono isBranchProtectedMono = gitPrivateRepoHelper.isBranchProtected(baseGitMetadata, branchName); + Mono commitMono = isBranchProtectedMono + .flatMap(isBranchProtected -> { + if (!TRUE.equals(isBranchProtected)) { + return addFileLock( + baseGitMetadata.getDefaultArtifactId(), GitCommandConstants.COMMIT, isFileLock); } + return Mono.error(new AppsmithException( + AppsmithError.GIT_ACTION_FAILED, + "commit", + "Cannot commit to protected branch " + branchName)); + }) + .flatMap(fileLocked -> { // Check if the repo is public for current artifact and if the user have changed the access after // the connection - return GitUtils.isRepoPrivate(defaultGitMetadata.getBrowserSupportedRemoteUrl()) + + return GitUtils.isRepoPrivate(baseGitMetadata.getBrowserSupportedRemoteUrl()) .flatMap(isPrivate -> { // Check the repo limit if the visibility status is updated, or it is private if (isPrivate.equals( - defaultGitMetadata.getIsRepoPrivate() && !Boolean.TRUE.equals(isPrivate))) { - return Mono.just(defaultArtifact); + baseGitMetadata.getIsRepoPrivate() && !Boolean.TRUE.equals(isPrivate))) { + return Mono.just(baseArtifact); } - defaultGitMetadata.setIsRepoPrivate(isPrivate); - defaultArtifact.setGitArtifactMetadata(defaultGitMetadata); + baseGitMetadata.setIsRepoPrivate(isPrivate); + baseArtifact.setGitArtifactMetadata(baseGitMetadata); + + /** + * A separate GitAuth object has been created in which the private key for + * authentication is held. It's done to avoid getting the encrypted value back + * for private key after mongo save. + * + * When an object having an encrypted attribute is saved, the response is still encrypted. + * The value in db would be corrupted if it's saved again, + * as it would encrypt and already encrypted field + * Private key is using encrypted annotation, which means that it's encrypted before + * being persisted in the db. When it's fetched from db, the listener decrypts it. + */ + GitAuth copiedGitAuth = new GitAuth(); + copyNestedNonNullProperties(baseGitMetadata.getGitAuth(), copiedGitAuth); return gitArtifactHelper - .saveArtifact(defaultArtifact) - .flatMap(savedArtifact -> - gitArtifactHelper.isPrivateRepoLimitReached(savedArtifact, false)); + .saveArtifact(baseArtifact) + .map(artifact -> { + baseArtifact + .getGitArtifactMetadata() + .setGitAuth(copiedGitAuth); + return artifact; + }) + .then(Mono.defer(() -> + gitArtifactHelper.isPrivateRepoLimitReached(baseArtifact, false))); }); }) - .flatMap(artifact -> gitArtifactHelper.getArtifactByDefaultIdAndBranchName( - defaultArtifactId, branchName, artifactEditPermission)) - .flatMap(branchedArtifact -> { - GitArtifactMetadata gitArtifactMetadata = branchedArtifact.getGitArtifactMetadata(); - if (gitArtifactMetadata == null) { - return Mono.error( - new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_CONFIG_ERROR)); - } - + .flatMap(artifact -> { String errorEntity = ""; - if (StringUtils.isEmptyOrNull(gitArtifactMetadata.getBranchName())) { + if (StringUtils.isEmptyOrNull(branchedGitMetadata.getBranchName())) { errorEntity = "branch name"; - } else if (StringUtils.isEmptyOrNull(gitArtifactMetadata.getDefaultArtifactId())) { + } else if (StringUtils.isEmptyOrNull(branchedGitMetadata.getDefaultArtifactId())) { // TODO: make this artifact errorEntity = "default artifact"; - } else if (StringUtils.isEmptyOrNull(gitArtifactMetadata.getRepoName())) { + } else if (StringUtils.isEmptyOrNull(branchedGitMetadata.getRepoName())) { errorEntity = "repository name"; } @@ -1124,33 +1003,32 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { AppsmithError.INVALID_GIT_CONFIGURATION, "Unable to find " + errorEntity)); } - return Mono.zip( - exportService.exportByArtifactId(branchedArtifact.getId(), VERSION_CONTROL, artifactType), - Mono.just(branchedArtifact)); + return exportService.exportByArtifactId( + branchedArtifact.getId(), VERSION_CONTROL, branchedArtifact.getArtifactType()); }) - .flatMap(tuple -> { - ArtifactExchangeJson artifactExchangeJson = tuple.getT1(); - Artifact branchedArtifact = tuple.getT2(); - GitArtifactMetadata gitData = branchedArtifact.getGitArtifactMetadata(); + .flatMap(artifactExchangeJson -> { Path baseRepoSuffix = gitArtifactHelper.getRepoSuffixPath( - branchedArtifact.getWorkspaceId(), gitData.getDefaultArtifactId(), gitData.getRepoName()); - Mono repoPathMono = commonGitFileUtils.saveArtifactToLocalRepoWithAnalytics( - baseRepoSuffix, artifactExchangeJson, gitData.getBranchName()); + branchedArtifact.getWorkspaceId(), + branchedGitMetadata.getDefaultArtifactId(), + branchedGitMetadata.getRepoName()); - gitData.setLastCommittedAt(Instant.now()); - // We don't require to check for permission from this point because, permission is already - // established + Mono repoPathMono = commonGitFileUtils.saveArtifactToLocalRepoWithAnalytics( + baseRepoSuffix, artifactExchangeJson, branchName); + + branchedGitMetadata.setLastCommittedAt(Instant.now()); Mono branchedArtifactMono = - updateArtifactWithGitMetadataGivenPermission(branchedArtifact, gitData); + updateArtifactWithGitMetadataGivenPermission(branchedArtifact, branchedGitMetadata); + return Mono.zip( repoPathMono, - userDataService.getGitProfileForCurrentUser(defaultArtifactId), + userDataService.getGitProfileForCurrentUser(branchedGitMetadata.getDefaultArtifactId()), branchedArtifactMono); }) .onErrorResume(e -> { log.error("Error in commit flow: ", e); if (e instanceof RepositoryNotFoundException) { - return Mono.error(new AppsmithException(AppsmithError.REPOSITORY_NOT_FOUND, defaultArtifactId)); + return Mono.error(new AppsmithException( + AppsmithError.REPOSITORY_NOT_FOUND, branchedGitMetadata.getDefaultArtifactId())); } else if (e instanceof AppsmithException) { return Mono.error(e); } @@ -1159,15 +1037,16 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { .flatMap(tuple -> { Path baseRepoPath = tuple.getT1(); GitProfile authorProfile = tuple.getT2(); - Artifact branchedArtifact = tuple.getT3(); - GitArtifactMetadata gitArtifactMetadata = branchedArtifact.getGitArtifactMetadata(); + Artifact updatedBranchedArtifact = tuple.getT3(); + GitArtifactMetadata gitArtifactMetadata = updatedBranchedArtifact.getGitArtifactMetadata(); + if (authorProfile == null || StringUtils.isEmptyOrNull(authorProfile.getAuthorName())) { String errorMessage = "Unable to find git author configuration for logged-in user. You can set " + "up a git profile from the user profile section."; return addAnalyticsForGitOperation( AnalyticsEvents.GIT_COMMIT, - branchedArtifact, + updatedBranchedArtifact, AppsmithError.INVALID_GIT_CONFIGURATION.getErrorType(), AppsmithError.INVALID_GIT_CONFIGURATION.getMessage(errorMessage), gitArtifactMetadata.getIsRepoPrivate()) @@ -1190,58 +1069,50 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } return addAnalyticsForGitOperation( AnalyticsEvents.GIT_COMMIT, - branchedArtifact, + updatedBranchedArtifact, error.getClass().getName(), error.getMessage(), gitArtifactMetadata.getIsRepoPrivate()) .then(Mono.error(new AppsmithException( AppsmithError.GIT_ACTION_FAILED, "commit", error.getMessage()))); }); - return Mono.zip(gitCommitMono, gitArtifactHelper.getArtifactById(branchedArtifact.getId(), null)); + return Mono.zip( + gitCommitMono, gitArtifactHelper.getArtifactById(updatedBranchedArtifact.getId(), null)); }) .flatMap(tuple -> { String commitStatus = tuple.getT1(); - Artifact branchedArtifact = tuple.getT2(); + Artifact artifactFromBranch = tuple.getT2(); result.append(commitStatus); if (Boolean.TRUE.equals(commitDTO.getDoPush())) { // Push flow result.append(".\nPush Result : "); - return pushArtifact(branchedArtifact, false, false) + return pushArtifact(artifactFromBranch, false, false) .map(pushResult -> result.append(pushResult).toString()) - .zipWith(Mono.just(branchedArtifact)); + .zipWith(Mono.just(artifactFromBranch)); } - - return Mono.zip(Mono.just(result.toString()), Mono.just(branchedArtifact)); + return Mono.zip(Mono.just(result.toString()), Mono.just(artifactFromBranch)); }) .flatMap(tuple2 -> { String status = tuple2.getT1(); - Artifact branchedArtifact = tuple2.getT2(); - return Mono.zip(Mono.just(status), publishArtifact(branchedArtifact, commitDTO.getDoPush())); + Artifact artifactFromBranch = tuple2.getT2(); + return Mono.zip(Mono.just(status), publishArtifact(artifactFromBranch, commitDTO.getDoPush())); }) - // Add BE analytics .flatMap(tuple -> { String status = tuple.getT1(); - Artifact branchedArtifact = tuple.getT2(); - - Mono releaseFileLockMono = Mono.just(Boolean.TRUE).flatMap(flag -> { - if (!Boolean.TRUE.equals(isFileLock)) { - return Mono.just(flag); - } - - return releaseFileLock( - branchedArtifact.getGitArtifactMetadata().getDefaultArtifactId()); - }); + Artifact artifactFromBranch = tuple.getT2(); + Mono releaseFileLockMono = releaseFileLock( + artifactFromBranch.getGitArtifactMetadata().getDefaultArtifactId(), isFileLock); Mono updatedArtifactMono = - gitArtifactHelper.updateArtifactWithSchemaVersions(branchedArtifact); + gitArtifactHelper.updateArtifactWithSchemaVersions(artifactFromBranch); return Mono.zip(updatedArtifactMono, releaseFileLockMono) .then(addAnalyticsForGitOperation( AnalyticsEvents.GIT_COMMIT, - branchedArtifact, + artifactFromBranch, "", "", - branchedArtifact.getGitArtifactMetadata().getIsRepoPrivate(), + artifactFromBranch.getGitArtifactMetadata().getIsRepoPrivate(), isSystemGenerated)) .thenReturn(status) .name(OPS_COMMIT) @@ -1269,17 +1140,13 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } @Override - public Mono pushArtifact(String defaultArtifactId, String branchName, ArtifactType artifactType) { - - if (StringUtils.isEmptyOrNull(branchName)) { - throw new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.BRANCH_NAME); - } + public Mono pushArtifact(String branchedArtifactId, ArtifactType artifactType) { GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); return gitArtifactHelper - .getArtifactByDefaultIdAndBranchName(defaultArtifactId, branchName, artifactEditPermission) + .getArtifactById(branchedArtifactId, artifactEditPermission) .flatMap(branchedArtifact -> pushArtifact(branchedArtifact, true, true)); } @@ -1304,9 +1171,9 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { // TODO: check if permission null is okay. return gitArtifactHelper .getArtifactById(artifact.getGitArtifactMetadata().getDefaultArtifactId(), null) - .map(defaultArtifact -> { + .map(baseArtifact -> { artifact.getGitArtifactMetadata() - .setGitAuth(defaultArtifact + .setGitAuth(baseArtifact .getGitArtifactMetadata() .getGitAuth()); return artifact; @@ -1445,77 +1312,77 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { @Override public Mono checkoutBranch( - String defaultArtifactId, String branchName, boolean addFileLock, ArtifactType artifactType) { + String branchedArtifactId, String branchToBeCheckedOut, boolean addFileLock, ArtifactType artifactType) { - if (StringUtils.isEmptyOrNull(branchName)) { + if (!hasText(branchToBeCheckedOut)) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.BRANCH_NAME)); } - GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); - AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); + Mono> baseAndBranchedArtifactMono = + getBaseAndBranchedArtifacts(branchedArtifactId, artifactType); - Mono sourceArtifactMono = - gitArtifactHelper.getArtifactById(defaultArtifactId, artifactEditPermission); - return sourceArtifactMono.flatMap(sourceArtifact -> checkoutBranch(sourceArtifact, branchName, addFileLock)); + return baseAndBranchedArtifactMono.flatMap(artifactTuples -> { + Artifact sourceArtifact = artifactTuples.getT1(); + return checkoutBranch(sourceArtifact, branchToBeCheckedOut, addFileLock); + }); } - protected Mono checkoutBranch(Artifact sourceArtifact, String branchName, boolean addFileLock) { + protected Mono checkoutBranch( + Artifact baseArtifact, String branchToBeCheckedOut, boolean addFileLock) { - if (StringUtils.isEmptyOrNull(branchName)) { + if (!hasText(branchToBeCheckedOut)) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.BRANCH_NAME)); } - GitArtifactMetadata gitArtifactMetadata = sourceArtifact.getGitArtifactMetadata(); - String defaultArtifactId = gitArtifactMetadata.getDefaultArtifactId(); - GitArtifactHelper gitArtifactHelper = getArtifactGitService(sourceArtifact.getArtifactType()); + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); - Mono sourceAritfactMono = Mono.just(sourceArtifact); + if (isBaseGitMetadataInvalid(baseGitMetadata)) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_SSH_CONFIGURATION)); + } + + String baseArtifactId = baseGitMetadata.getDefaultArtifactId(); + final String finalBranchName = branchToBeCheckedOut.replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT); + + GitArtifactHelper gitArtifactHelper = getArtifactGitService(baseArtifact.getArtifactType()); + + Mono fileLockMono = addFileLock(baseArtifactId, GitCommandConstants.CHECKOUT_BRANCH, addFileLock); + Mono checkedOutArtifactMono; // If the user is trying to check out remote branch, create a new branch if the branch does not exist already - if (branchName.startsWith(ORIGIN)) { - String finalBranchName = branchName.replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT); + if (branchToBeCheckedOut.startsWith(ORIGIN)) { + Path repoPath = gitArtifactHelper.getRepoSuffixPath( - sourceArtifact.getWorkspaceId(), - gitArtifactMetadata.getDefaultArtifactId(), - gitArtifactMetadata.getRepoName()); + baseArtifact.getWorkspaceId(), + baseGitMetadata.getDefaultArtifactId(), + baseGitMetadata.getRepoName()); - sourceAritfactMono = addFileLock(defaultArtifactId, GitCommandConstants.CHECKOUT_BRANCH) - .then(gitExecutor.listBranches(repoPath)) - .flatMap(branchList -> releaseFileLock(defaultArtifactId).thenReturn(branchList)) - .flatMap(gitBranchDTOList -> { - long branchMatchCount = gitBranchDTOList.stream() - .filter(gitBranchDTO -> - gitBranchDTO.getBranchName().equals(finalBranchName)) - .count(); - if (branchMatchCount == 0) { - return checkoutRemoteBranch( - defaultArtifactId, finalBranchName, sourceArtifact.getArtifactType()); - } else { - return Mono.error(new AppsmithException( - AppsmithError.GIT_ACTION_FAILED, - "checkout", - branchName + " already exists in local - " - + branchName.replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT))); - } - }); + checkedOutArtifactMono = gitExecutor.listBranches(repoPath).flatMap(gitBranchDTOList -> { + long branchMatchCount = gitBranchDTOList.stream() + .filter(gitBranchDTO -> gitBranchDTO.getBranchName().equals(finalBranchName)) + .count(); + + if (branchMatchCount == 0) { + return checkoutRemoteBranch(baseArtifact, finalBranchName); + } + + return Mono.error(new AppsmithException( + AppsmithError.GIT_ACTION_FAILED, + "checkout", + branchToBeCheckedOut + " already exists in local - " + finalBranchName)); + }); } else { - - if (isDefaultGitMetadataInvalid(gitArtifactMetadata)) { - return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_SSH_CONFIGURATION)); - } - - sourceAritfactMono = gitArtifactHelper - .getArtifactByDefaultIdAndBranchName( - defaultArtifactId, branchName, gitArtifactHelper.getArtifactReadPermission()) + checkedOutArtifactMono = Mono.defer(() -> gitArtifactHelper + .getArtifactByBaseIdAndBranchName( + baseArtifactId, finalBranchName, gitArtifactHelper.getArtifactReadPermission()) .flatMap(artifact -> addAnalyticsForGitOperation( AnalyticsEvents.GIT_CHECKOUT_BRANCH, artifact, - artifact.getGitArtifactMetadata().getIsRepoPrivate())) - .map(gitArtifactHelper::updateArtifactWithDefaultReponseUtils); + artifact.getGitArtifactMetadata().getIsRepoPrivate()))); } - return releaseFileLock(defaultArtifactId, addFileLock) - .then(sourceAritfactMono) + return checkedOutArtifactMono + .flatMap(checkedOutArtifact -> + releaseFileLock(baseArtifactId, addFileLock).thenReturn(checkedOutArtifact)) .tag(GitConstants.GitMetricConstants.CHECKOUT_REMOTE, FALSE.toString()) .name(GitSpan.OPS_CHECKOUT_BRANCH) .tap(Micrometer.observation(observationRegistry)) @@ -1525,35 +1392,49 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } private Mono checkoutRemoteBranch( - String defaultArtifactId, String branchName, ArtifactType artifactType) { + String baseArtifactId, String remoteBranchName, ArtifactType artifactType) { + GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); - Mono defaultArtifactMono = - gitArtifactHelper.getArtifactById(defaultArtifactId, artifactEditPermission); - Mono checkoutRemoteBranchMono = defaultArtifactMono - .flatMap(artifact -> { - GitArtifactMetadata gitArtifactMetadata = artifact.getGitArtifactMetadata(); - String repoName = gitArtifactMetadata.getRepoName(); + Mono baseArtifactMono = gitArtifactHelper + .getArtifactById(baseArtifactId, artifactEditPermission) + .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.GIT_GENERIC_ERROR))) + .cache(); - Path repoPath = - gitArtifactHelper.getRepoSuffixPath(artifact.getWorkspaceId(), defaultArtifactId, repoName); + return baseArtifactMono.flatMap(baseArtifact -> checkoutRemoteBranch(baseArtifact, remoteBranchName)); + } - return gitExecutor - .fetchRemote( - repoPath, - gitArtifactMetadata.getGitAuth().getPublicKey(), - gitArtifactMetadata.getGitAuth().getPrivateKey(), - false, - branchName, - true) - .flatMap(fetchStatus -> gitExecutor - .checkoutRemoteBranch(repoPath, branchName) - .zipWith(Mono.just(artifact)) - .onErrorResume(error -> Mono.error(new AppsmithException( - AppsmithError.GIT_ACTION_FAILED, "checkout branch", error.getMessage())))); - }) - .flatMap(tuple2 -> { + private Mono checkoutRemoteBranch(Artifact baseArtifact, String remoteBranchName) { + + GitArtifactHelper gitArtifactHelper = getArtifactGitService(baseArtifact.getArtifactType()); + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + + if (isBaseGitMetadataInvalid(baseGitMetadata)) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_SSH_CONFIGURATION)); + } + + final String repoName = baseGitMetadata.getRepoName(); + final String baseArtifactId = baseGitMetadata.getDefaultArtifactId(); + final String baseBranchName = baseGitMetadata.getBranchName(); + final String workspaceId = baseArtifact.getWorkspaceId(); + final String finalRemoteBranchName = remoteBranchName.replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT); + + Path repoSuffixPath = gitArtifactHelper.getRepoSuffixPath(workspaceId, baseArtifactId, repoName); + + Mono checkedOutRemoteArtifactMono = gitExecutor + .fetchRemote( + repoSuffixPath, + baseGitMetadata.getGitAuth().getPublicKey(), + baseGitMetadata.getGitAuth().getPrivateKey(), + false, + remoteBranchName, + true) + .flatMap(fetchStatus -> gitExecutor + .checkoutRemoteBranch(repoSuffixPath, remoteBranchName) + .onErrorResume(error -> Mono.error(new AppsmithException( + AppsmithError.GIT_ACTION_FAILED, "checkout branch", error.getMessage())))) + .flatMap(checkedOutBranch -> { /* * create a new application(each application => git branch) * Populate the application from the file system @@ -1561,32 +1442,31 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { * Use the create branch method with isRemoteFlag or use the setStartPoint ,method in createBranch method * */ - Artifact artifact = tuple2.getT2(); Mono artifactMono; - GitArtifactMetadata srcBranchGitData = artifact.getGitArtifactMetadata(); - if (branchName.equals(srcBranchGitData.getBranchName())) { + if (baseBranchName.equals(finalRemoteBranchName)) { /* in this case, user deleted the initial default branch and now wants to check out to that branch. as we didn't delete the application object but only the branch from git repo, we can just use this existing application without creating a new one. */ - artifactMono = Mono.just(artifact); + artifactMono = Mono.just(baseArtifact); } else { // create new Artifact - artifactMono = gitArtifactHelper.createNewArtifactForCheckout(artifact, branchName); + artifactMono = + gitArtifactHelper.createNewArtifactForCheckout(baseArtifact, finalRemoteBranchName); } Mono artifactExchangeJsonMono = commonGitFileUtils.reconstructArtifactExchangeJsonFromGitRepoWithAnalytics( - artifact.getWorkspaceId(), - defaultArtifactId, - srcBranchGitData.getRepoName(), - branchName, - artifactType); + workspaceId, + baseArtifactId, + repoName, + finalRemoteBranchName, + baseArtifact.getArtifactType()); return artifactExchangeJsonMono.zipWith(artifactMono).onErrorResume(throwable -> { if (throwable instanceof DuplicateKeyException) { - artifactExchangeJsonMono.zipWith(Mono.just(artifact)); + artifactExchangeJsonMono.zipWith(Mono.just(baseArtifact)); } log.error(" Git checkout remote branch failed {}", throwable.getMessage()); @@ -1609,63 +1489,69 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { Artifact artifact = tuple.getT2(); return importService .importArtifactInWorkspaceFromGit( - artifact.getWorkspaceId(), artifact.getId(), artifactExchangeJson, branchName) + artifact.getWorkspaceId(), + artifact.getId(), + artifactExchangeJson, + finalRemoteBranchName) .flatMap(artifact1 -> addAnalyticsForGitOperation( AnalyticsEvents.GIT_CHECKOUT_REMOTE_BRANCH, artifact1, Boolean.TRUE.equals( - artifact1.getGitArtifactMetadata().getIsRepoPrivate()))) - .map(gitArtifactHelper::updateArtifactWithDefaultReponseUtils); + artifact1.getGitArtifactMetadata().getIsRepoPrivate()))); }) .tag(GitConstants.GitMetricConstants.CHECKOUT_REMOTE, TRUE.toString()) .name(GitSpan.OPS_CHECKOUT_BRANCH) .tap(Micrometer.observation(observationRegistry)); - return Mono.create( - sink -> checkoutRemoteBranchMono.subscribe(sink::success, sink::error, null, sink.currentContext())); + return Mono.create(sink -> + checkedOutRemoteArtifactMono.subscribe(sink::success, sink::error, null, sink.currentContext())); } /** - * Method to remove all the git metadata for the application and connected resources. This will remove: + * Method to remove all the git metadata for the artifact and connected resources. This will remove: * - local repo * - all the branched applications present in DB except for default application * - * @param defaultArtifactId application which needs to be disconnected from git connection - * @return Application data + * @param branchedArtifactId : id of any branched artifact for the given repo + * @param artifactType : type of artifact + * @return : the base artifact after removal of git flow. */ @Override - public Mono detachRemote(String defaultArtifactId, ArtifactType artifactType) { + public Mono detachRemote(String branchedArtifactId, ArtifactType artifactType) { + GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission gitConnectPermission = gitArtifactHelper.getArtifactGitConnectPermission(); - Mono disconnectMono = gitArtifactHelper - .getArtifactById(defaultArtifactId, gitConnectPermission) - .flatMap(defaultArtifact -> { - if (Optional.ofNullable(defaultArtifact.getGitArtifactMetadata()) - .isEmpty() - || isDefaultGitMetadataInvalid(defaultArtifact.getGitArtifactMetadata())) { + Mono> baseAndBranchedArtifactMono = + getBaseAndBranchedArtifacts(branchedArtifactId, artifactType, gitConnectPermission); + + Mono disconnectMono = baseAndBranchedArtifactMono + .flatMap(artifactTuples -> { + Artifact baseArtifact = artifactTuples.getT1(); + Artifact branchedArtifact = artifactTuples.getT2(); + + if (isBaseGitMetadataInvalid(baseArtifact.getGitArtifactMetadata())) { return Mono.error(new AppsmithException( AppsmithError.INVALID_GIT_CONFIGURATION, "Please reconfigure the application to connect to git repo")); } + // Remove the git contents from file system - GitArtifactMetadata gitArtifactMetadata = defaultArtifact.getGitArtifactMetadata(); - String repoName = gitArtifactMetadata.getRepoName(); + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + String repoName = baseGitMetadata.getRepoName(); Path repoSuffix = gitArtifactHelper.getRepoSuffixPath( - defaultArtifact.getWorkspaceId(), gitArtifactMetadata.getDefaultArtifactId(), repoName); - String defaultApplicationBranchName = gitArtifactMetadata.getBranchName(); - String remoteUrl = gitArtifactMetadata.getRemoteUrl(); - String privateKey = gitArtifactMetadata.getGitAuth().getPrivateKey(); - String publicKey = gitArtifactMetadata.getGitAuth().getPublicKey(); + baseArtifact.getWorkspaceId(), baseGitMetadata.getDefaultArtifactId(), repoName); + + String baseApplicationBranchName = baseGitMetadata.getBranchName(); return Mono.zip( gitExecutor.listBranches(repoSuffix), - Mono.just(defaultArtifact), + Mono.just(baseArtifact), Mono.just(repoSuffix), - Mono.just(defaultApplicationBranchName)); + Mono.just(baseApplicationBranchName)); }) .flatMap(tuple -> { - Artifact defaultArtifact = tuple.getT2(); + Artifact baseArtifact = tuple.getT2(); Path repoSuffix = tuple.getT3(); List localBranches = tuple.getT1().stream() .map(GitBranchDTO::getBranchName) @@ -1674,25 +1560,24 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { // Remove the parent application branch name from the list localBranches.remove(tuple.getT4()); - defaultArtifact.setGitArtifactMetadata(null); - gitArtifactHelper.resetAttributeInDefaultArtifact(defaultArtifact); + baseArtifact.setGitArtifactMetadata(null); + gitArtifactHelper.resetAttributeInBaseArtifact(baseArtifact); Mono removeRepoMono = commonGitFileUtils.deleteLocalRepo(repoSuffix); - Mono updatedArtifactMono = gitArtifactHelper.saveArtifact(defaultArtifact); + Mono updatedArtifactMono = gitArtifactHelper.saveArtifact(baseArtifact); Flux deleteAllBranchesFlux = - gitArtifactHelper.deleteAllBranches(defaultArtifactId, localBranches); + gitArtifactHelper.deleteAllBranches(branchedArtifactId, localBranches); return Mono.zip(updatedArtifactMono, removeRepoMono, deleteAllBranchesFlux.collectList()) .map(Tuple3::getT1); }) - .flatMap(updatedDefaultArtifact -> { + .flatMap(updatedBaseArtifact -> { return gitArtifactHelper - .disconnectEntitiesOfDefaultArtifact(updatedDefaultArtifact) + .disconnectEntitiesOfBaseArtifact(updatedBaseArtifact) .then(addAnalyticsForGitOperation( - AnalyticsEvents.GIT_DISCONNECT, updatedDefaultArtifact, false)) - .map(gitArtifactHelper::updateArtifactWithDefaultReponseUtils); + AnalyticsEvents.GIT_DISCONNECT, updatedBaseArtifact, false)); }) .name(GitSpan.OPS_DETACH_REMOTE) .tap(Micrometer.observation(observationRegistry)); @@ -1702,49 +1587,35 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { @Override public Mono createBranch( - String defaultArtifactId, GitBranchDTO branchDTO, String srcBranch, ArtifactType artifactType) { - + String branchedArtifactId, GitBranchDTO branchDTO, ArtifactType artifactType) { /* 1. Check if the src artifact is available and user have sufficient permissions 2. Create and checkout to requested branch 3. Rehydrate the artifact from source artifact reference */ - if (StringUtils.isEmptyOrNull(srcBranch) - || srcBranch.startsWith(ORIGIN) - || branchDTO.getBranchName().startsWith(ORIGIN)) { - return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.BRANCH_NAME)); + if (!hasText(branchDTO.getBranchName()) || branchDTO.getBranchName().startsWith(ORIGIN)) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, BRANCH_NAME)); } GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); - Mono createBranchMono = gitArtifactHelper - .getArtifactByDefaultIdAndBranchName(defaultArtifactId, srcBranch, artifactEditPermission) - .zipWhen(sourceArtifact -> { - GitArtifactMetadata gitData = sourceArtifact.getGitArtifactMetadata(); - if (sourceArtifact.getId().equals(gitData.getDefaultArtifactId())) { - return Mono.just(sourceArtifact.getGitArtifactMetadata().getGitAuth()); - } + Mono> baseAndBranchedArtifactMono = + getBaseAndBranchedArtifacts(branchedArtifactId, artifactType, artifactEditPermission); - return gitArtifactHelper - .getSshKeys(gitData.getDefaultArtifactId()) - .map(gitAuthDTO -> { - GitAuth gitAuth = new GitAuth(); - gitAuth.setPrivateKey(gitAuthDTO.getPrivateKey()); - gitAuth.setPublicKey(gitAuthDTO.getPublicKey()); - gitAuth.setDocUrl(gitAuthDTO.getDocUrl()); - return gitAuth; - }); - }) - .flatMap(tuple -> { - Artifact sourceArtifact = tuple.getT1(); - GitAuth defaultGitAuth = tuple.getT2(); - GitArtifactMetadata srcBranchGitData = sourceArtifact.getGitArtifactMetadata(); + Mono createBranchMono = baseAndBranchedArtifactMono + .flatMap(artifactTuples -> { + Artifact baseArtifact = artifactTuples.getT1(); + Artifact parentArtifact = artifactTuples.getT2(); - if (srcBranchGitData == null - || StringUtils.isEmptyOrNull(srcBranchGitData.getDefaultArtifactId()) - || StringUtils.isEmptyOrNull(srcBranchGitData.getRepoName())) { + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + GitAuth baseGitAuth = baseGitMetadata.getGitAuth(); + GitArtifactMetadata parentGitMetadata = parentArtifact.getGitArtifactMetadata(); + + if (parentGitMetadata == null + || !hasText(parentGitMetadata.getDefaultArtifactId()) + || !hasText(parentGitMetadata.getRepoName())) { return Mono.error( new AppsmithException( AppsmithError.INVALID_GIT_CONFIGURATION, @@ -1752,22 +1623,25 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } Path repoSuffix = gitArtifactHelper.getRepoSuffixPath( - sourceArtifact.getWorkspaceId(), - srcBranchGitData.getDefaultArtifactId(), - srcBranchGitData.getRepoName()); + baseArtifact.getWorkspaceId(), + baseGitMetadata.getDefaultArtifactId(), + baseGitMetadata.getRepoName()); // Create a new branch from the parent checked out branch - return addFileLock(srcBranchGitData.getDefaultArtifactId(), GitCommandConstants.CREATE_BRANCH) - .flatMap(status -> gitExecutor.checkoutToBranch(repoSuffix, srcBranch)) + return addFileLock(baseGitMetadata.getDefaultArtifactId(), GitCommandConstants.CREATE_BRANCH) + .flatMap(status -> + gitExecutor.checkoutToBranch(repoSuffix, parentGitMetadata.getBranchName())) .onErrorResume(error -> Mono.error(new AppsmithException( - AppsmithError.GIT_ACTION_FAILED, "checkout", "Unable to find " + srcBranch))) + AppsmithError.GIT_ACTION_FAILED, + "checkout", + "Unable to find " + parentGitMetadata.getBranchName()))) .zipWhen(isCheckedOut -> gitExecutor .fetchRemote( repoSuffix, - defaultGitAuth.getPublicKey(), - defaultGitAuth.getPrivateKey(), + baseGitAuth.getPublicKey(), + baseGitAuth.getPrivateKey(), false, - srcBranch, + parentGitMetadata.getBranchName(), true) .onErrorResume(error -> Mono.error( new AppsmithException(AppsmithError.GIT_ACTION_FAILED, "fetch", error)))) @@ -1792,13 +1666,11 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { repoSuffix, branchDTO.getBranchName()); })) .flatMap(branchName -> { - final String sourceArtifactId = sourceArtifact.getId(); - Mono artifactExchangeJsonMono = exportService.exportByArtifactId( - sourceArtifactId, VERSION_CONTROL, artifactType); + parentArtifact.getId(), VERSION_CONTROL, artifactType); Mono newArtifactFromSourceMono = - gitArtifactHelper.createNewArtifactForCheckout(sourceArtifact, branchName); + gitArtifactHelper.createNewArtifactForCheckout(parentArtifact, branchName); return Mono.zip(newArtifactFromSourceMono, artifactExchangeJsonMono); }) @@ -1806,37 +1678,37 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { AppsmithError.GIT_ACTION_FAILED, "branch", error.getMessage()))); }) .flatMap(tuple -> { - Artifact savedArtifact = tuple.getT1(); + Artifact newBranchedArtifact = tuple.getT1(); return importService .importArtifactInWorkspaceFromGit( - savedArtifact.getWorkspaceId(), - savedArtifact.getId(), + newBranchedArtifact.getWorkspaceId(), + newBranchedArtifact.getId(), tuple.getT2(), branchDTO.getBranchName()) - .flatMap(newBranchArtifact -> { + .flatMap(importedBranchedArtifact -> { // Commit and push for new branch created this is to avoid issues when user tries to // create a new branch from uncommitted branch - GitArtifactMetadata gitData = newBranchArtifact.getGitArtifactMetadata(); + GitArtifactMetadata branchedGitMetadata = + importedBranchedArtifact.getGitArtifactMetadata(); GitCommitDTO commitDTO = new GitCommitDTO(); commitDTO.setCommitMessage(DEFAULT_COMMIT_MESSAGE + GitDefaultCommitMessage.BRANCH_CREATED.getReason() - + gitData.getBranchName()); + + branchedGitMetadata.getBranchName()); commitDTO.setDoPush(true); return commitArtifact( - commitDTO, - gitData.getDefaultArtifactId(), - gitData.getBranchName(), - artifactType) - .thenReturn(newBranchArtifact); + commitDTO, importedBranchedArtifact.getId(), false, false, artifactType) + .thenReturn(importedBranchedArtifact); }); }) - .flatMap(newBranchArtifact -> releaseFileLock( - newBranchArtifact.getGitArtifactMetadata().getDefaultArtifactId()) + .flatMap(importedBranchedArtifact -> releaseFileLock(importedBranchedArtifact + .getGitArtifactMetadata() + .getDefaultArtifactId()) .then(addAnalyticsForGitOperation( AnalyticsEvents.GIT_CREATE_BRANCH, - newBranchArtifact, - newBranchArtifact.getGitArtifactMetadata().getIsRepoPrivate()))) - .map(gitArtifactHelper::updateArtifactWithDefaultReponseUtils) + importedBranchedArtifact, + importedBranchedArtifact + .getGitArtifactMetadata() + .getIsRepoPrivate()))) .name(GitSpan.OPS_CREATE_BRANCH) .tap(Micrometer.observation(observationRegistry)); @@ -1847,13 +1719,12 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { * Method to pull artifact json files from remote repo, make a commit with the changes present in local DB and * make a system commit to remote repo * - * @param defaultArtifactId artifact for which we want to pull remote changes and merge - * @param branchName remoteBranch from which the changes will be pulled and merged + * @param branchedArtifactId artifact for which we want to pull remote changes and merge * @param artifactType * @return return the status of pull operation */ @Override - public Mono pullArtifact(String defaultArtifactId, String branchName, ArtifactType artifactType) { + public Mono pullArtifact(String branchedArtifactId, ArtifactType artifactType) { /* * 1.Dehydrate the artifact from DB so that the file system has the latest artifact data * 2.Do git pull after the rehydration and merge the remote changes to the current branch @@ -1863,34 +1734,25 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { * 4.Get the latest artifact from the DB and send it back to client * */ - if (!hasText(branchName)) { - return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, branchName)); - } - GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); - - final String finalBranchName = branchName.replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT); AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); - Mono defaultArtifactMono = - gitArtifactHelper.getArtifactById(defaultArtifactId, artifactEditPermission); + Mono> baseAndBranchedArtifactMono = + getBaseAndBranchedArtifacts(branchedArtifactId, artifactType, artifactEditPermission); - Mono branchedArtifactMono = gitArtifactHelper.getArtifactByDefaultIdAndBranchName( - defaultArtifactId, finalBranchName, artifactEditPermission); + Mono pullDTOMono = baseAndBranchedArtifactMono + .flatMap(artifactTuples -> { + Artifact baseArtifact = artifactTuples.getT1(); + Artifact branchedArtifact = artifactTuples.getT2(); + GitArtifactMetadata branchedGitMetadata = branchedArtifact.getGitArtifactMetadata(); - Mono pullDTOMono = Mono.zip(defaultArtifactMono, branchedArtifactMono) - .flatMap(tuple2 -> { - Artifact defaultArtifact = tuple2.getT1(); - Artifact branchedArtifact = tuple2.getT2(); - GitArtifactMetadata gitMetadata = defaultArtifact.getGitArtifactMetadata(); - Mono statusMono = - getStatus(defaultArtifact, branchedArtifact, finalBranchName, false, true); - return addFileLock(gitMetadata.getDefaultArtifactId(), GitCommandConstants.PULL) - .then(Mono.zip(statusMono, Mono.just(defaultArtifact), Mono.just(branchedArtifact))); + Mono statusMono = getStatus(baseArtifact, branchedArtifact, false, true); + return addFileLock(branchedGitMetadata.getDefaultArtifactId(), GitCommandConstants.PULL) + .then(Mono.zip(statusMono, Mono.just(baseArtifact), Mono.just(branchedArtifact))); }) .flatMap(tuple -> { GitStatusDTO status = tuple.getT1(); - Artifact defaultArtifact = tuple.getT2(); + Artifact baseArtifact = tuple.getT2(); Artifact branchedArtifact = tuple.getT3(); // Check if the repo is clean @@ -1901,10 +1763,12 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { "pull", "There are uncommitted changes present in your local. Please commit them first and then try git pull")); } - return pullAndRehydrateArtifact(defaultArtifact, branchedArtifact, branchName) + return pullAndRehydrateArtifact(baseArtifact, branchedArtifact) // Release file lock after the pull operation - .flatMap(gitPullDTO -> - releaseFileLock(defaultArtifactId).then(Mono.just(gitPullDTO))); + .flatMap(gitPullDTO -> releaseFileLock(baseArtifact + .getGitArtifactMetadata() + .getDefaultArtifactId()) + .then(Mono.just(gitPullDTO))); }) .name(GitSpan.OPS_PULL) .tap(Micrometer.observation(observationRegistry)); @@ -1915,13 +1779,11 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { /** * Method to pull the files from remote repo and rehydrate the application * - * @param defaultArtifact : base artifact + * @param baseArtifact : base artifact * @param branchedArtifact : a branch created from branches of base artifact - * @param branchName branch for which the pull is required * @return pull DTO with updated application */ - private Mono pullAndRehydrateArtifact( - Artifact defaultArtifact, Artifact branchedArtifact, String branchName) { + private Mono pullAndRehydrateArtifact(Artifact baseArtifact, Artifact branchedArtifact) { /* 1. Checkout to the concerned branch 2. Do git pull after @@ -1930,28 +1792,34 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { 3. Rehydrate the application from filesystem so that the latest changes from remote are rendered to the application */ - GitArtifactMetadata gitData = defaultArtifact.getGitArtifactMetadata(); - if (isDefaultGitMetadataInvalid(gitData)) { + ArtifactType artifactType = baseArtifact.getArtifactType(); + GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); + + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + if (isBaseGitMetadataInvalid(baseGitMetadata)) { return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_CONFIG_ERROR)); } - ArtifactType artifactType = defaultArtifact.getArtifactType(); - GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); - Path repoSuffix = gitArtifactHelper.getRepoSuffixPath( - defaultArtifact.getWorkspaceId(), gitData.getDefaultArtifactId(), gitData.getRepoName()); + GitArtifactMetadata branchedGitMetadata = branchedArtifact.getGitArtifactMetadata(); - return Mono.just(branchedArtifact) - .flatMap(branchedArtifact1 -> { + final String workspaceId = branchedArtifact.getWorkspaceId(); + final String baseArtifactId = branchedGitMetadata.getDefaultArtifactId(); + final String repoName = branchedGitMetadata.getRepoName(); + final String branchName = branchedGitMetadata.getBranchName(); + + Path repoSuffix = gitArtifactHelper.getRepoSuffixPath(workspaceId, baseArtifactId, repoName); + + return Mono.defer(() -> { // git checkout and pull origin branchName try { Mono pullStatusMono = gitExecutor .checkoutToBranch(repoSuffix, branchName) .then(gitExecutor.pullApplication( repoSuffix, - gitData.getRemoteUrl(), + baseGitMetadata.getRemoteUrl(), branchName, - gitData.getGitAuth().getPrivateKey(), - gitData.getGitAuth().getPublicKey())) + baseGitMetadata.getGitAuth().getPrivateKey(), + baseGitMetadata.getGitAuth().getPublicKey())) .onErrorResume(error -> { if (error.getMessage().contains("conflict")) { return Mono.error(new AppsmithException( @@ -1970,58 +1838,40 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { // Rehydrate the application from file system Mono artifactExchangeJsonMono = pullStatusMono.flatMap( status -> commonGitFileUtils.reconstructArtifactExchangeJsonFromGitRepoWithAnalytics( - branchedArtifact1.getWorkspaceId(), - branchedArtifact1 - .getGitArtifactMetadata() - .getDefaultArtifactId(), - branchedArtifact1 - .getGitArtifactMetadata() - .getRepoName(), - branchName, - artifactType)); + workspaceId, baseArtifactId, repoName, branchName, artifactType)); + + return Mono.zip(pullStatusMono, artifactExchangeJsonMono); - return Mono.zip(pullStatusMono, Mono.just(branchedArtifact1), artifactExchangeJsonMono); } catch (IOException e) { return Mono.error(new AppsmithException(AppsmithError.GIT_FILE_SYSTEM_ERROR, e.getMessage())); } }) .flatMap(tuple -> { MergeStatusDTO status = tuple.getT1(); - Artifact branchedApplication = tuple.getT2(); - ArtifactExchangeJson artifactExchangeJson = tuple.getT3(); - - // Get the latest application with all the changes + ArtifactExchangeJson artifactExchangeJson = tuple.getT2(); + // Get the latest artifact with all the changes // Commit and push changes to sync with remote return importService .importArtifactInWorkspaceFromGit( - branchedApplication.getWorkspaceId(), - branchedApplication.getId(), - artifactExchangeJson, - branchName) - .flatMap(artifact -> addAnalyticsForGitOperation( - AnalyticsEvents.GIT_PULL, - artifact, - artifact.getGitArtifactMetadata().getIsRepoPrivate()) - .thenReturn(artifact)) - .flatMap(artifact -> { + workspaceId, branchedArtifact.getId(), artifactExchangeJson, branchName) + .flatMap(importedBranchedArtifact -> addAnalyticsForGitOperation( + AnalyticsEvents.GIT_PULL, + importedBranchedArtifact, + importedBranchedArtifact + .getGitArtifactMetadata() + .getIsRepoPrivate())) + .flatMap(importedBranchedArtifact -> { GitCommitDTO commitDTO = new GitCommitDTO(); commitDTO.setCommitMessage(DEFAULT_COMMIT_MESSAGE + GitDefaultCommitMessage.SYNC_WITH_REMOTE_AFTER_PULL.getReason()); commitDTO.setDoPush(true); - Artifact artifactWithUpdatedResource = - gitArtifactHelper.updateArtifactWithDefaultReponseUtils(artifact); GitPullDTO gitPullDTO = new GitPullDTO(); gitPullDTO.setMergeStatus(status); - gitPullDTO.setArtifact(artifactWithUpdatedResource); + gitPullDTO.setArtifact(importedBranchedArtifact); - // Make commit and push after pull is successful to have a clean repo return this.commitArtifact( - commitDTO, - artifact.getGitArtifactMetadata() - .getDefaultArtifactId(), - branchName, - artifactType) + commitDTO, baseArtifact, importedBranchedArtifact, false, false) .thenReturn(gitPullDTO); }); }); @@ -2029,7 +1879,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { @Override public Mono> updateOrCreateGitProfileForCurrentUser( - GitProfile gitProfile, String defaultArtifactId) { + GitProfile gitProfile, String baseArtifactId) { // Throw error in following situations: // 1. Updating or creating global git profile (defaultApplicationId = "default") and update is made with empty @@ -2037,17 +1887,17 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { // 2. Updating or creating repo specific profile and user want to use repo specific profile but provided empty // values for authorName and email - if ((DEFAULT.equals(defaultArtifactId) || Boolean.FALSE.equals(gitProfile.getUseGlobalProfile())) + if ((DEFAULT.equals(baseArtifactId) || Boolean.FALSE.equals(gitProfile.getUseGlobalProfile())) && StringUtils.isEmptyOrNull(gitProfile.getAuthorName())) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, "Author Name")); - } else if ((DEFAULT.equals(defaultArtifactId) || Boolean.FALSE.equals(gitProfile.getUseGlobalProfile())) + } else if ((DEFAULT.equals(baseArtifactId) || Boolean.FALSE.equals(gitProfile.getUseGlobalProfile())) && StringUtils.isEmptyOrNull(gitProfile.getAuthorEmail())) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, "Author Email")); - } else if (StringUtils.isEmptyOrNull(defaultArtifactId)) { + } else if (StringUtils.isEmptyOrNull(baseArtifactId)) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ARTIFACT_ID)); } - if (DEFAULT.equals(defaultArtifactId)) { + if (DEFAULT.equals(baseArtifactId)) { gitProfile.setUseGlobalProfile(null); } else if (!Boolean.TRUE.equals(gitProfile.getUseGlobalProfile())) { gitProfile.setUseGlobalProfile(Boolean.FALSE); @@ -2060,11 +1910,11 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { .getForUser(user.getId()) .flatMap(userData -> { // GitProfiles will be null if the user has not created any git profile. - GitProfile savedProfile = userData.getGitProfileByKey(defaultArtifactId); + GitProfile savedProfile = userData.getGitProfileByKey(baseArtifactId); GitProfile defaultGitProfile = userData.getGitProfileByKey(DEFAULT); if (savedProfile == null || !savedProfile.equals(gitProfile) || defaultGitProfile == null) { - userData.setGitProfiles(userData.setGitProfileByKey(defaultArtifactId, gitProfile)); + userData.setGitProfiles(userData.setGitProfileByKey(baseArtifactId, gitProfile)); // Assign appsmith user profile as a fallback git profile if (defaultGitProfile == null) { @@ -2126,9 +1976,9 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } @Override - public Mono getGitProfileForUser(String defaultArtifactId) { + public Mono getGitProfileForUser(String baseArtifactId) { return userDataService.getForCurrentUser().map(userData -> { - GitProfile gitProfile = userData.getGitProfileByKey(defaultArtifactId); + GitProfile gitProfile = userData.getGitProfileByKey(baseArtifactId); if (gitProfile != null && gitProfile.getUseGlobalProfile() == null) { gitProfile.setUseGlobalProfile(true); } else if (gitProfile == null) { @@ -2265,7 +2115,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { .thenReturn(artifact)); } - private boolean isDefaultGitMetadataInvalid(GitArtifactMetadata gitArtifactMetadata) { + private boolean isBaseGitMetadataInvalid(GitArtifactMetadata gitArtifactMetadata) { return Optional.ofNullable(gitArtifactMetadata).isEmpty() || Optional.ofNullable(gitArtifactMetadata.getGitAuth()).isEmpty() || StringUtils.isEmptyOrNull(gitArtifactMetadata.getGitAuth().getPrivateKey()) @@ -2273,40 +2123,68 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } @Override - public Mono deleteBranch( - String defaultArtifactId, String branchName, ArtifactType artifactType) { + public Mono deleteBranch(String baseArtifactId, String branchName, ArtifactType artifactType) { + + if (!hasText(branchName)) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, BRANCH_NAME)); + } + + if (!hasText(baseArtifactId)) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID)); + } GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); - Mono defaultArtifactMono = - gitArtifactHelper.getArtifactById(defaultArtifactId, artifactEditPermission); + Mono baseArtifactMono = + gitArtifactHelper.getArtifactById(baseArtifactId, artifactEditPermission); + Mono branchedArtifactMono = + gitArtifactHelper.getArtifactByBaseIdAndBranchName(baseArtifactId, branchName, artifactEditPermission); - Mono deleteBranchMono = defaultArtifactMono - .zipWhen(defaultArtifact -> - gitPrivateRepoHelper.isBranchProtected(defaultArtifact.getGitArtifactMetadata(), branchName)) - .map(objects -> { - if (objects.getT2()) { - throw new AppsmithException( - AppsmithError.GIT_ACTION_FAILED, - "delete", - "Cannot delete protected branch " + branchName); - } - return objects.getT1(); + Mono deleteBranchMono = Mono.zip(baseArtifactMono, branchedArtifactMono) + .flatMap(artifactTuples -> { + Artifact baseArtifact = artifactTuples.getT1(); + Artifact branchedArtifact = artifactTuples.getT2(); + + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + GitArtifactMetadata branchedGitMetadata = branchedArtifact.getGitArtifactMetadata(); + final String finalBranchName = branchedGitMetadata.getBranchName(); + + return gitPrivateRepoHelper + .isBranchProtected(baseGitMetadata, finalBranchName) + .flatMap(isBranchProtected -> { + if (!TRUE.equals(isBranchProtected)) { + return addFileLock( + baseGitMetadata.getDefaultArtifactId(), GitCommandConstants.DELETE); + } + + return Mono.error(new AppsmithException( + AppsmithError.GIT_ACTION_FAILED, + "delete", + "Cannot delete protected branch " + finalBranchName)); + }) + .thenReturn(artifactTuples); }) - .flatMap(defaultArtifact -> addFileLock(defaultArtifactId, GitCommandConstants.DELETE) - .map(status -> defaultArtifact)) - .flatMap(defaultArtifact -> { - GitArtifactMetadata gitArtifactMetadata = defaultArtifact.getGitArtifactMetadata(); - Path repoPath = gitArtifactHelper.getRepoSuffixPath( - defaultArtifact.getWorkspaceId(), defaultArtifactId, gitArtifactMetadata.getRepoName()); + .flatMap(artifactTuples -> { + Artifact baseArtifact = artifactTuples.getT1(); + Artifact branchedArtifact = artifactTuples.getT2(); - if (branchName.equals(gitArtifactMetadata.getDefaultBranchName())) { + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + GitArtifactMetadata branchedGitMetadata = branchedArtifact.getGitArtifactMetadata(); + final String finalBranchName = branchedGitMetadata.getBranchName(); + + Path repoPath = gitArtifactHelper.getRepoSuffixPath( + baseArtifact.getWorkspaceId(), + baseGitMetadata.getDefaultArtifactId(), + baseGitMetadata.getRepoName()); + + if (finalBranchName.equals(baseGitMetadata.getDefaultBranchName())) { return Mono.error(new AppsmithException( AppsmithError.GIT_ACTION_FAILED, "delete branch", " Cannot delete default branch")); } + return gitExecutor - .deleteBranch(repoPath, branchName) + .deleteBranch(repoPath, finalBranchName) .onErrorResume(throwable -> { log.error("Delete branch failed {}", throwable.getMessage()); if (throwable instanceof CannotDeleteCurrentBranchException) { @@ -2319,7 +2197,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { AppsmithError.GIT_ACTION_FAILED, "delete branch", throwable.getMessage())); }) .flatMap(isBranchDeleted -> - releaseFileLock(defaultArtifactId).map(status -> isBranchDeleted)) + releaseFileLock(baseArtifactId).map(status -> isBranchDeleted)) .flatMap(isBranchDeleted -> { if (FALSE.equals(isBranchDeleted)) { return Mono.error(new AppsmithException( @@ -2327,29 +2205,22 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { " delete branch. Branch does not exists in the repo")); } - return gitArtifactHelper - .getArtifactByDefaultIdAndBranchName( - defaultArtifactId, branchName, artifactEditPermission) - .flatMap(branchedArtifact -> { - if (branchedArtifact - .getId() - .equals(branchedArtifact - .getGitArtifactMetadata() - .getDefaultArtifactId())) { - return Mono.just(branchedArtifact); - } + if (branchedArtifact.getId().equals(branchedGitMetadata.getDefaultArtifactId())) { + return Mono.just(branchedArtifact); + } - return gitArtifactHelper.deleteArtifactByResource(branchedArtifact); - }) + return gitArtifactHelper + .deleteArtifactByResource(branchedArtifact) .onErrorResume(throwable -> { - log.warn("Unable to find branch with name ", throwable); return addAnalyticsForGitOperation( AnalyticsEvents.GIT_DELETE_BRANCH, - defaultArtifact, + branchedArtifact, throwable.getClass().getName(), throwable.getMessage(), - gitArtifactMetadata.getIsRepoPrivate()) - .flatMap(application1 -> Mono.just(application1)); + baseGitMetadata.getIsRepoPrivate()) + .then(Mono.error(new AppsmithException( + AppsmithError.GIT_ACTION_FAILED, + "Cannot delete branch from database"))); }); }); }) @@ -2357,7 +2228,6 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { AnalyticsEvents.GIT_DELETE_BRANCH, branchedArtifact, branchedArtifact.getGitArtifactMetadata().getIsRepoPrivate())) - .map(gitArtifactHelper::updateArtifactWithDefaultReponseUtils) .name(GitSpan.OPS_DELETE_BRANCH) .tap(Micrometer.observation(observationRegistry)); @@ -2365,47 +2235,45 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } @Override - public Mono discardChanges( - String defaultArtifactId, String branchName, ArtifactType artifactType) { + public Mono discardChanges(String branchedArtifactId, ArtifactType artifactType) { - if (StringUtils.isEmptyOrNull(defaultArtifactId)) { + if (!hasText(branchedArtifactId)) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.APPLICATION_ID)); } GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); - Mono branchedArtifactMonoCached = gitArtifactHelper.getArtifactByDefaultIdAndBranchName( - defaultArtifactId, branchName, artifactEditPermission); - + Mono branchedArtifactMonoCached = + gitArtifactHelper.getArtifactById(branchedArtifactId, artifactEditPermission); Mono discardChangeMono; // Rehydrate the artifact from local file system discardChangeMono = branchedArtifactMonoCached - // Add file lock before proceeding with the git operation - .flatMap(branchedArtifact -> addFileLock(defaultArtifactId, GitCommandConstants.DISCARD) - .thenReturn(branchedArtifact)) .flatMap(branchedArtifact -> { - GitArtifactMetadata gitData = branchedArtifact.getGitArtifactMetadata(); - if (gitData == null || StringUtils.isEmptyOrNull(gitData.getDefaultArtifactId())) { + GitArtifactMetadata branchedGitData = branchedArtifact.getGitArtifactMetadata(); + if (branchedGitData == null || !hasText(branchedGitData.getDefaultArtifactId())) { return Mono.error( new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_CONFIG_ERROR)); } - Path repoSuffix = Paths.get( - branchedArtifact.getWorkspaceId(), gitData.getDefaultArtifactId(), gitData.getRepoName()); + + return addFileLock(branchedGitData.getDefaultArtifactId(), GitCommandConstants.DISCARD) + .thenReturn(branchedArtifact); + }) + .flatMap(branchedArtifact -> { + GitArtifactMetadata branchedGitData = branchedArtifact.getGitArtifactMetadata(); + final String branchName = branchedGitData.getBranchName(); + final String defaultArtifactId = branchedGitData.getDefaultArtifactId(); + final String repoName = branchedGitData.getRepoName(); + final String workspaceId = branchedArtifact.getWorkspaceId(); + + Path repoSuffix = Paths.get(workspaceId, defaultArtifactId, repoName); + return gitExecutor .rebaseBranch(repoSuffix, branchName) .flatMap(rebaseStatus -> { return commonGitFileUtils.reconstructArtifactExchangeJsonFromGitRepoWithAnalytics( - branchedArtifact.getWorkspaceId(), - branchedArtifact - .getGitArtifactMetadata() - .getDefaultArtifactId(), - branchedArtifact - .getGitArtifactMetadata() - .getRepoName(), - branchName, - artifactType); + workspaceId, defaultArtifactId, repoName, branchName, artifactType); }) .onErrorResume(throwable -> { log.error("Git Discard & Rebase failed {}", throwable.getMessage()); @@ -2423,10 +2291,10 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { // Update the last deployed status after the rebase .flatMap(importedArtifact -> publishArtifact(importedArtifact, true)); }) - .flatMap(branchedArtifact -> releaseFileLock(defaultArtifactId) + .flatMap(branchedArtifact -> releaseFileLock( + branchedArtifact.getGitArtifactMetadata().getDefaultArtifactId()) .then(this.addAnalyticsForGitOperation( AnalyticsEvents.GIT_DISCARD_CHANGES, branchedArtifact, null))) - .map(gitArtifactHelper::updateArtifactWithDefaultReponseUtils) .name(GitSpan.OPS_DISCARD_CHANGES) .tap(Micrometer.observation(observationRegistry)); @@ -2436,7 +2304,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { @Override public Mono mergeBranch( - String defaultArtifactId, GitMergeDTO gitMergeDTO, ArtifactType artifactType) { + String branchedArtifactId, GitMergeDTO gitMergeDTO, ArtifactType artifactType) { /* * 1.Dehydrate the artifact from Mongodb so that the file system has the latest artifact data for both the source and destination branch artifact * 2.Do git checkout destinationBranch ---> git merge sourceBranch after the rehydration @@ -2461,142 +2329,163 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); - Mono defaultArtifactMono = - gitArtifactHelper.getArtifactById(defaultArtifactId, artifactEditPermission); + Mono> baseAndBranchedArtifactsMono = + getBaseAndBranchedArtifacts(branchedArtifactId, artifactType).cache(); - Mono mergeMono = defaultArtifactMono - .flatMap(defaultArtifact -> { - GitArtifactMetadata gitData = defaultArtifact.getGitArtifactMetadata(); - return addFileLock(gitData.getDefaultArtifactId(), GitCommandConstants.MERGE_BRANCH) - .then(Mono.just(defaultArtifact)); - }) - .flatMap(defaultArtifact -> { - GitArtifactMetadata gitArtifactMetadata = defaultArtifact.getGitArtifactMetadata(); - if (isDefaultGitMetadataInvalid(defaultArtifact.getGitArtifactMetadata())) { + Mono destinationArtifactMono = baseAndBranchedArtifactsMono.flatMap(artifactTuples -> { + Artifact baseArtifact = artifactTuples.getT1(); + if (destinationBranch.equals(baseArtifact.getGitArtifactMetadata().getBranchName())) { + return Mono.just(baseArtifact); + } + + return gitArtifactHelper.getArtifactByBaseIdAndBranchName( + baseArtifact.getId(), destinationBranch, artifactEditPermission); + }); + + Mono mergeMono = baseAndBranchedArtifactsMono + .zipWith(destinationArtifactMono) + .flatMap(artifactTuples -> { + Artifact baseArtifact = artifactTuples.getT1().getT1(); + Artifact sourceArtifact = artifactTuples.getT1().getT2(); + Artifact destinationArtifact = artifactTuples.getT2(); + + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + if (isBaseGitMetadataInvalid(baseArtifact.getGitArtifactMetadata())) { return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_SSH_CONFIGURATION)); } - Path repoSuffix = gitArtifactHelper.getRepoSuffixPath( - defaultArtifact.getWorkspaceId(), - gitArtifactMetadata.getDefaultArtifactId(), - gitArtifactMetadata.getRepoName()); - // 1. Hydrate from db to file system for both branch Artifacts - Mono pathToFile = this.getStatus(defaultArtifactId, sourceBranch, false, artifactType) - .flatMap(status -> { - if (!Integer.valueOf(0).equals(status.getBehindCount())) { - return Mono.error(new AppsmithException( - AppsmithError.GIT_MERGE_FAILED_REMOTE_CHANGES, - status.getBehindCount(), - sourceBranch)); - } else if (!status.getIsClean()) { - return Mono.error(new AppsmithException( - AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES, sourceBranch)); - } - return this.getStatus(defaultArtifactId, destinationBranch, false, artifactType) - .map(status1 -> { - if (!Integer.valueOf(0).equals(status.getBehindCount())) { - return Mono.error(new AppsmithException( - AppsmithError.GIT_MERGE_FAILED_REMOTE_CHANGES, - status.getBehindCount(), - destinationBranch)); - } else if (!status.getIsClean()) { - return Mono.error(new AppsmithException( - AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES, - destinationBranch)); + final String workspaceId = baseArtifact.getWorkspaceId(); + final String baseArtifactId = baseGitMetadata.getDefaultArtifactId(); + final String repoName = baseGitMetadata.getRepoName(); + + final String publicKey = baseGitMetadata.getGitAuth().getPublicKey(); + final String privateKey = baseGitMetadata.getGitAuth().getPrivateKey(); + + Path repoSuffix = gitArtifactHelper.getRepoSuffixPath(workspaceId, baseArtifactId, repoName); + + // 1. Hydrate from db to file system for both branch Applications + // Update function call + Mono pathFileMono = addFileLock(baseArtifactId, GitCommandConstants.MERGE_BRANCH) + .flatMap(fileLock -> gitExecutor.fetchRemote( + repoSuffix, publicKey, privateKey, false, sourceBranch, destinationBranch)) + .flatMap(fetchMessage -> { + Mono sourceBranchStatusMono = + Mono.defer(() -> getStatus(baseArtifact, sourceArtifact, false, false) + .flatMap(srcBranchStatus -> { + if (!Integer.valueOf(0).equals(srcBranchStatus.getBehindCount())) { + return releaseFileLock(baseArtifactId) + .then(Mono.error(new AppsmithException( + AppsmithError.GIT_MERGE_FAILED_REMOTE_CHANGES, + srcBranchStatus.getBehindCount(), + sourceBranch))); + } else if (!srcBranchStatus.getIsClean()) { + return releaseFileLock(baseArtifactId) + .then(Mono.error(new AppsmithException( + AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES, + sourceBranch))); + } + + return Mono.just(srcBranchStatus); + })); + + Mono destinationBranchStatusMono = Mono.defer(() -> getStatus( + baseArtifact, destinationArtifact, false, false) + .flatMap(destinationBranchStatus -> { + if (!Integer.valueOf(0).equals(destinationBranchStatus.getBehindCount())) { + return releaseFileLock(baseArtifactId) + .then(Mono.error(new AppsmithException( + AppsmithError.GIT_MERGE_FAILED_REMOTE_CHANGES, + destinationBranchStatus.getBehindCount(), + destinationBranch))); + } else if (!destinationBranchStatus.getIsClean()) { + return releaseFileLock(baseArtifactId) + .then(Mono.error(new AppsmithException( + AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES, + destinationBranch))); } - return status1; + return Mono.just(destinationBranchStatus); + })); + + return sourceBranchStatusMono.then(destinationBranchStatusMono); + }) + .thenReturn(repoSuffix) + .onErrorResume(error -> { + log.error("Error in repo status check for application " + branchedArtifactId, error); + if (error instanceof AppsmithException) { + return releaseFileLock(baseArtifactId).then(Mono.error(error)); + } + return releaseFileLock(baseArtifactId) + .then(Mono.error(new AppsmithException( + AppsmithError.GIT_ACTION_FAILED, "status", error))); + }); + + return pathFileMono + // 2. git checkout destinationBranch ---> git merge sourceBranch + .then(Mono.defer(() -> gitExecutor.mergeBranch(repoSuffix, sourceBranch, destinationBranch)) + .onErrorResume(error -> addAnalyticsForGitOperation( + AnalyticsEvents.GIT_MERGE, + baseArtifact, + error.getClass().getName(), + error.getMessage(), + baseArtifact + .getGitArtifactMetadata() + .getIsRepoPrivate()) + .flatMap(artifact -> releaseFileLock(baseArtifactId) + .thenReturn(artifact)) + .flatMap(artifact -> { + if (error instanceof GitAPIException) { + return Mono.error(new AppsmithException( + AppsmithError.GIT_MERGE_CONFLICTS, error.getMessage())); + } + return Mono.error(new AppsmithException( + AppsmithError.GIT_ACTION_FAILED, "merge", error.getMessage())); + }))) + // 3. rehydrate from file system to db + .zipWhen(mergeStatus -> + Mono.defer(() -> commonGitFileUtils.reconstructArtifactExchangeJsonFromGitRepo( + workspaceId, baseArtifactId, repoName, destinationBranch, artifactType))) + .flatMap(tuple -> { + ArtifactExchangeJson artifactExchangeJson = tuple.getT2(); + MergeStatusDTO mergeStatusDTO = new MergeStatusDTO(); + mergeStatusDTO.setStatus(tuple.getT1()); + mergeStatusDTO.setMergeAble(TRUE); + + // 4. Get the latest artifact mono with all the changes + return importService + .importArtifactInWorkspaceFromGit( + workspaceId, + destinationArtifact.getId(), + artifactExchangeJson, + destinationBranch.replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT)) + .flatMap(importedDestinationArtifact -> { + GitCommitDTO commitDTO = new GitCommitDTO(); + commitDTO.setDoPush(true); + commitDTO.setCommitMessage(DEFAULT_COMMIT_MESSAGE + + GitDefaultCommitMessage.SYNC_REMOTE_AFTER_MERGE.getReason() + + sourceBranch); + + return this.commitArtifact( + commitDTO, + importedDestinationArtifact.getId(), + artifactType) + .map(commitStatus -> mergeStatusDTO) + .zipWith(Mono.just(importedDestinationArtifact)); }); }) - .thenReturn(repoSuffix); + .flatMap(tuple -> { + MergeStatusDTO mergeStatusDTO = tuple.getT1(); + Artifact artifact = tuple.getT2(); - return Mono.zip(Mono.just(defaultArtifact), pathToFile).onErrorResume(error -> { - log.error("Error in repo status check for application " + defaultArtifactId, error); - if (error instanceof AppsmithException) { - return Mono.error(error); - } - return Mono.error(new AppsmithException(AppsmithError.GIT_ACTION_FAILED, "status", error)); - }); - }) - .flatMap(tuple -> { - Artifact defaultArtifact = tuple.getT1(); - Path repoSuffix = tuple.getT2(); - - // 2. git checkout destinationBranch ---> git merge sourceBranch - return Mono.zip( - gitExecutor.mergeBranch(repoSuffix, sourceBranch, destinationBranch), - Mono.just(defaultArtifact)) - .onErrorResume(error -> addAnalyticsForGitOperation( - AnalyticsEvents.GIT_MERGE, - defaultArtifact, - error.getClass().getName(), - error.getMessage(), - defaultArtifact - .getGitArtifactMetadata() - .getIsRepoPrivate()) - .flatMap(application -> { - if (error instanceof GitAPIException) { - return Mono.error(new AppsmithException( - AppsmithError.GIT_MERGE_CONFLICTS, error.getMessage())); - } - return Mono.error(new AppsmithException( - AppsmithError.GIT_ACTION_FAILED, "merge", error.getMessage())); - })); - }) - .flatMap(mergeStatusTuple -> { - Artifact defaultArtifact = mergeStatusTuple.getT2(); - String mergeStatus = mergeStatusTuple.getT1(); - - // 3. rehydrate from file system to db - Mono artifactExchangeJsonMono = - commonGitFileUtils.reconstructArtifactExchangeJsonFromGitRepo( - defaultArtifact.getWorkspaceId(), - defaultArtifact.getGitArtifactMetadata().getDefaultArtifactId(), - defaultArtifact.getGitArtifactMetadata().getRepoName(), - destinationBranch, - artifactType); - - return Mono.zip( - Mono.just(mergeStatus), - gitArtifactHelper.getArtifactByDefaultIdAndBranchName( - defaultArtifactId, destinationBranch, artifactEditPermission), - artifactExchangeJsonMono); - }) - .flatMap(tuple -> { - Artifact destinationArtifact = tuple.getT2(); - ArtifactExchangeJson artifactExchangeJson = tuple.getT3(); - MergeStatusDTO mergeStatusDTO = new MergeStatusDTO(); - mergeStatusDTO.setStatus(tuple.getT1()); - mergeStatusDTO.setMergeAble(TRUE); - - // 4. Get the latest application mono with all the changes - return importService - .importArtifactInWorkspaceFromGit( - destinationArtifact.getWorkspaceId(), - destinationArtifact.getId(), - artifactExchangeJson, - destinationBranch.replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT)) - .flatMap(artifact -> { - GitCommitDTO commitDTO = new GitCommitDTO(); - commitDTO.setDoPush(true); - commitDTO.setCommitMessage(DEFAULT_COMMIT_MESSAGE - + GitDefaultCommitMessage.SYNC_REMOTE_AFTER_MERGE.getReason() - + sourceBranch); - return this.commitArtifact( - commitDTO, defaultArtifactId, destinationBranch, artifactType) - .map(commitStatus -> mergeStatusDTO) - .zipWith(Mono.just(artifact)); - }); - }) - .flatMap(tuple -> { - MergeStatusDTO mergeStatusDTO = tuple.getT1(); - Artifact artifact = tuple.getT2(); - - // Send analytics event - return releaseFileLock(defaultArtifactId).flatMap(status -> addAnalyticsForGitOperation( - AnalyticsEvents.GIT_MERGE, - artifact, - artifact.getGitArtifactMetadata().getIsRepoPrivate()) - .thenReturn(mergeStatusDTO)); + // Send analytics event + return releaseFileLock(baseArtifactId).flatMap(status -> addAnalyticsForGitOperation( + AnalyticsEvents.GIT_MERGE, + artifact, + artifact.getGitArtifactMetadata() + .getIsRepoPrivate()) + .thenReturn(mergeStatusDTO)); + }) + .onErrorResume( + error -> releaseFileLock(baseArtifactId).then(Mono.error(error))); }) .name(GitSpan.OPS_MERGE_BRANCH) .tap(Micrometer.observation(observationRegistry)); @@ -2606,7 +2495,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { @Override public Mono isBranchMergeable( - String defaultArtifactId, GitMergeDTO gitMergeDTO, ArtifactType artifactType) { + String branchedArtifactId, GitMergeDTO gitMergeDTO, ArtifactType artifactType) { final String sourceBranch = gitMergeDTO.getSourceBranch(); final String destinationBranch = gitMergeDTO.getDestinationBranch(); @@ -2624,291 +2513,210 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); - Mono defaultArtifactMono = - gitArtifactHelper.getArtifactById(defaultArtifactId, artifactEditPermission); + Mono> baseAndBranchedArtifactsMono = + getBaseAndBranchedArtifacts(branchedArtifactId, artifactType).cache(); - Mono mergeableStatusMono = defaultArtifactMono.flatMap(artifact -> { - GitArtifactMetadata gitArtifactMetadata = artifact.getGitArtifactMetadata(); - if (isDefaultGitMetadataInvalid(artifact.getGitArtifactMetadata())) { - return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_SSH_CONFIGURATION)); + Mono destinationArtifactMono = baseAndBranchedArtifactsMono.flatMap(artifactTuples -> { + Artifact baseArtifact = artifactTuples.getT1(); + if (destinationBranch.equals(baseArtifact.getGitArtifactMetadata().getBranchName())) { + return Mono.just(baseArtifact); } - Path repoSuffix = gitArtifactHelper.getRepoSuffixPath( - artifact.getWorkspaceId(), - gitArtifactMetadata.getDefaultArtifactId(), - gitArtifactMetadata.getRepoName()); - - // 1. Hydrate from db to file system for both branch Applications - // Update function call - return addFileLock(defaultArtifactId, GitCommandConstants.STATUS) - .flatMap(status -> this.getStatus(defaultArtifactId, sourceBranch, false, artifactType)) - .flatMap(srcBranchStatus -> { - if (!Integer.valueOf(0).equals(srcBranchStatus.getBehindCount())) { - return addAnalyticsForGitOperation( - AnalyticsEvents.GIT_MERGE_CHECK, - artifact, - AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES.name(), - AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES.getMessage( - srcBranchStatus.getBehindCount(), destinationBranch), - artifact.getGitArtifactMetadata().getIsRepoPrivate(), - false, - false) - .then(Mono.error(Exceptions.propagate(new AppsmithException( - AppsmithError.GIT_MERGE_FAILED_REMOTE_CHANGES, - srcBranchStatus.getBehindCount(), - sourceBranch)))); - } else if (!srcBranchStatus.getIsClean()) { - return addAnalyticsForGitOperation( - AnalyticsEvents.GIT_MERGE_CHECK, - artifact, - AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES.name(), - AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES.getMessage(destinationBranch), - artifact.getGitArtifactMetadata().getIsRepoPrivate(), - false, - false) - .then(Mono.error(Exceptions.propagate(new AppsmithException( - AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES, sourceBranch)))); - } - return this.getStatus(defaultArtifactId, destinationBranch, false, artifactType) - .map(destBranchStatus -> { - if (!Integer.valueOf(0).equals(destBranchStatus.getBehindCount())) { - return addAnalyticsForGitOperation( - AnalyticsEvents.GIT_MERGE_CHECK, - artifact, - AppsmithError.GIT_MERGE_FAILED_REMOTE_CHANGES.name(), - AppsmithError.GIT_MERGE_FAILED_REMOTE_CHANGES.getMessage( - destBranchStatus.getBehindCount(), destinationBranch), - artifact.getGitArtifactMetadata() - .getIsRepoPrivate(), - false, - false) - .then(Mono.error(Exceptions.propagate(new AppsmithException( - AppsmithError.GIT_MERGE_FAILED_REMOTE_CHANGES, - destBranchStatus.getBehindCount(), - destinationBranch)))); - } else if (!destBranchStatus.getIsClean()) { - return addAnalyticsForGitOperation( - AnalyticsEvents.GIT_MERGE_CHECK, - artifact, - AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES.name(), - AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES.getMessage( - destinationBranch), - artifact.getGitArtifactMetadata() - .getIsRepoPrivate(), - false, - false) - .then(Mono.error(Exceptions.propagate(new AppsmithException( - AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES, - destinationBranch)))); - } - return destBranchStatus; - }); - }) - .onErrorResume(error -> { - log.error("Error in merge status check artifact " + defaultArtifactId, error); - if (error instanceof AppsmithException) { - return Mono.error(error); - } - return Mono.error(new AppsmithException(AppsmithError.GIT_ACTION_FAILED, "status", error)); - }) - .then(gitExecutor - .isMergeBranch(repoSuffix, sourceBranch, destinationBranch) - .flatMap(mergeStatusDTO -> releaseFileLock(defaultArtifactId) - .flatMap(mergeStatus -> addAnalyticsForGitOperation( - AnalyticsEvents.GIT_MERGE_CHECK, - artifact, - null, - null, - artifact.getGitArtifactMetadata().getIsRepoPrivate(), - false, - mergeStatusDTO.isMergeAble())) - .then(Mono.just(mergeStatusDTO)))) - .onErrorResume(error -> { - try { - return gitExecutor - .resetToLastCommit(repoSuffix, destinationBranch) - .map(reset -> { - MergeStatusDTO mergeStatus = new MergeStatusDTO(); - mergeStatus.setMergeAble(false); - mergeStatus.setStatus("Merge check failed!"); - mergeStatus.setMessage(error.getMessage()); - if (error instanceof CheckoutConflictException) { - mergeStatus.setConflictingFiles( - ((CheckoutConflictException) error).getConflictingPaths()); - } - mergeStatus.setReferenceDoc( - ErrorReferenceDocUrl.GIT_MERGE_CONFLICT.getDocUrl()); - return mergeStatus; - }) - .flatMap(mergeStatusDTO -> addAnalyticsForGitOperation( - AnalyticsEvents.GIT_MERGE_CHECK, - artifact, - error.getClass().getName(), - error.getMessage(), - artifact.getGitArtifactMetadata() - .getIsRepoPrivate(), - false, - false) - .map(application1 -> mergeStatusDTO)); - } catch (GitAPIException | IOException e) { - log.error("Error while resetting to last commit", e); - return Mono.error(new AppsmithException( - AppsmithError.GIT_ACTION_FAILED, "reset --hard HEAD", e.getMessage())); - } - }); + return gitArtifactHelper.getArtifactByBaseIdAndBranchName( + baseArtifact.getId(), destinationBranch, artifactEditPermission); }); + Mono mergeableStatusMono = baseAndBranchedArtifactsMono + .zipWith(destinationArtifactMono) + .flatMap(artifactTuples -> { + Artifact baseArtifact = artifactTuples.getT1().getT1(); + Artifact sourceArtifact = artifactTuples.getT1().getT2(); + Artifact destinationArtifact = artifactTuples.getT2(); + + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + if (isBaseGitMetadataInvalid(baseArtifact.getGitArtifactMetadata())) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_SSH_CONFIGURATION)); + } + + final String workspaceId = baseArtifact.getWorkspaceId(); + final String baseArtifactId = baseGitMetadata.getDefaultArtifactId(); + final String repoName = baseGitMetadata.getRepoName(); + + final String publicKey = baseGitMetadata.getGitAuth().getPublicKey(); + final String privateKey = baseGitMetadata.getGitAuth().getPrivateKey(); + + Path repoSuffix = gitArtifactHelper.getRepoSuffixPath(workspaceId, baseArtifactId, repoName); + + // 1. Hydrate from db to file system for both branch Applications + // Update function call + return addFileLock(baseArtifactId, GitCommandConstants.STATUS) + .flatMap(fileLock -> gitExecutor.fetchRemote( + repoSuffix, publicKey, privateKey, false, sourceBranch, destinationBranch)) + .flatMap(fetchMessage -> { + return getStatus(baseArtifact, sourceArtifact, false, false) + .flatMap(srcBranchStatus -> { + if (!Integer.valueOf(0).equals(srcBranchStatus.getBehindCount())) { + return addAnalyticsForGitOperation( + AnalyticsEvents.GIT_MERGE_CHECK, + baseArtifact, + AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES.name(), + AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES.getMessage( + srcBranchStatus.getBehindCount(), + destinationBranch), + baseArtifact + .getGitArtifactMetadata() + .getIsRepoPrivate(), + false, + false) + .then(releaseFileLock(baseArtifactId)) + .then(Mono.error(Exceptions.propagate(new AppsmithException( + AppsmithError.GIT_MERGE_FAILED_REMOTE_CHANGES, + srcBranchStatus.getBehindCount(), + sourceBranch)))); + } else if (!srcBranchStatus.getIsClean()) { + return addAnalyticsForGitOperation( + AnalyticsEvents.GIT_MERGE_CHECK, + baseArtifact, + AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES.name(), + AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES.getMessage( + destinationBranch), + baseArtifact + .getGitArtifactMetadata() + .getIsRepoPrivate(), + false, + false) + .then(releaseFileLock(baseArtifactId)) + .then(Mono.error(Exceptions.propagate(new AppsmithException( + AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES, + sourceBranch)))); + } + + return Mono.just(srcBranchStatus); + }) + .flatMap(srcBranchStatus -> { + return getStatus(baseArtifact, destinationArtifact, false, false) + .flatMap(destBranchStatus -> { + if (!Integer.valueOf(0) + .equals(destBranchStatus.getBehindCount())) { + return addAnalyticsForGitOperation( + AnalyticsEvents.GIT_MERGE_CHECK, + baseArtifact, + AppsmithError + .GIT_MERGE_FAILED_REMOTE_CHANGES + .name(), + AppsmithError + .GIT_MERGE_FAILED_REMOTE_CHANGES + .getMessage( + destBranchStatus + .getBehindCount(), + destinationBranch), + baseArtifact + .getGitArtifactMetadata() + .getIsRepoPrivate(), + false, + false) + .then(releaseFileLock(baseArtifactId)) + .then(Mono.error(Exceptions.propagate( + new AppsmithException( + AppsmithError + .GIT_MERGE_FAILED_REMOTE_CHANGES, + destBranchStatus.getBehindCount(), + destinationBranch)))); + } else if (!destBranchStatus.getIsClean()) { + return addAnalyticsForGitOperation( + AnalyticsEvents.GIT_MERGE_CHECK, + baseArtifact, + AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES + .name(), + AppsmithError.GIT_MERGE_FAILED_LOCAL_CHANGES + .getMessage(destinationBranch), + baseArtifact + .getGitArtifactMetadata() + .getIsRepoPrivate(), + false, + false) + .then(releaseFileLock(baseArtifactId)) + .then(Mono.error(Exceptions.propagate( + new AppsmithException( + AppsmithError + .GIT_MERGE_FAILED_LOCAL_CHANGES, + destinationBranch)))); + } + return Mono.just(destBranchStatus); + }); + }) + .onErrorResume(error -> { + log.error( + "Error in merge status check baseArtifact " + branchedArtifactId, + error); + if (error instanceof AppsmithException) { + return Mono.error(error); + } + return releaseFileLock(baseArtifactId) + .then(Mono.error(new AppsmithException( + AppsmithError.GIT_ACTION_FAILED, "status", error))); + }) + .then(gitExecutor + .isMergeBranch(repoSuffix, sourceBranch, destinationBranch) + .flatMap(mergeStatusDTO -> releaseFileLock(baseArtifactId) + .flatMap(mergeStatus -> addAnalyticsForGitOperation( + AnalyticsEvents.GIT_MERGE_CHECK, + baseArtifact, + null, + null, + baseArtifact + .getGitArtifactMetadata() + .getIsRepoPrivate(), + false, + mergeStatusDTO.isMergeAble())) + .then(Mono.just(mergeStatusDTO)))) + .onErrorResume(error -> { + try { + return gitExecutor + .resetToLastCommit(repoSuffix, destinationBranch) + .map(reset -> { + MergeStatusDTO mergeStatus = new MergeStatusDTO(); + mergeStatus.setMergeAble(false); + mergeStatus.setStatus("Merge check failed!"); + mergeStatus.setMessage(error.getMessage()); + if (error instanceof CheckoutConflictException) { + mergeStatus.setConflictingFiles( + ((CheckoutConflictException) error) + .getConflictingPaths()); + } + mergeStatus.setReferenceDoc( + ErrorReferenceDocUrl.GIT_MERGE_CONFLICT + .getDocUrl()); + return mergeStatus; + }) + .flatMap(mergeStatusDTO -> addAnalyticsForGitOperation( + AnalyticsEvents.GIT_MERGE_CHECK, + baseArtifact, + error.getClass() + .getName(), + error.getMessage(), + baseArtifact + .getGitArtifactMetadata() + .getIsRepoPrivate(), + false, + false) + .flatMap(application1 -> releaseFileLock(baseArtifactId) + .thenReturn(mergeStatusDTO))); + } catch (GitAPIException | IOException e) { + log.error("Error while resetting to last commit", e); + return Mono.error(new AppsmithException( + AppsmithError.GIT_ACTION_FAILED, + "reset --hard HEAD", + e.getMessage())); + } + }); + }); + }); + return Mono.create( sink -> mergeableStatusMono.subscribe(sink::success, sink::error, null, sink.currentContext())); } - @Override - public Mono createConflictedBranch(String defaultArtifactId, String branchName, ArtifactType artifactType) { - - if (StringUtils.isEmptyOrNull(branchName)) { - return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.BRANCH_NAME)); - } - - GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); - AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); - Mono gitArtifactMetadataMono = getGitArtifactMetadata(defaultArtifactId, artifactType); - - Mono branchedArtifactMonoCached = gitArtifactHelper - .getArtifactByDefaultIdAndBranchName(defaultArtifactId, branchName, artifactEditPermission) - .cache(); - Mono artifactExchangeJsonMono = branchedArtifactMonoCached.flatMap(artifact -> - exportService.exportByArtifactId(artifact.getId(), VERSION_CONTROL, artifact.getArtifactType())); - - Mono conflictedBranchMono = Mono.zip( - gitArtifactMetadataMono, branchedArtifactMonoCached, artifactExchangeJsonMono) - .flatMap(tuple -> { - GitArtifactMetadata gitArtifactMetadata = tuple.getT1(); - Artifact branchedArtifact = tuple.getT2(); - ArtifactExchangeJson artifactExchangeJson = tuple.getT3(); - GitArtifactMetadata branchedGitArtifactMetadata = branchedArtifact.getGitArtifactMetadata(); - branchedGitArtifactMetadata.setGitAuth(gitArtifactMetadata.getGitAuth()); - - Path repoSuffix = gitArtifactHelper.getRepoSuffixPath( - branchedArtifact.getWorkspaceId(), - branchedGitArtifactMetadata.getDefaultArtifactId(), - branchedGitArtifactMetadata.getRepoName()); - - return Mono.zip( - commonGitFileUtils.saveArtifactToLocalRepoWithAnalytics( - repoSuffix, artifactExchangeJson, branchName), - Mono.just(branchedGitArtifactMetadata), - Mono.just(repoSuffix)); - }) - .flatMap(tuple -> { - GitArtifactMetadata gitData = tuple.getT2(); - Path repoSuffix = tuple.getT3(); - return gitExecutor - .createAndCheckoutToBranch(repoSuffix, branchName + MERGE_CONFLICT_BRANCH_NAME) - .flatMap(conflictedBranchName -> commitAndPushWithDefaultCommit( - repoSuffix, - gitData.getGitAuth(), - gitData, - GitDefaultCommitMessage.CONFLICT_STATE) - .flatMap(successMessage -> gitExecutor.checkoutToBranch(repoSuffix, branchName)) - .flatMap(isCheckedOut -> gitExecutor.deleteBranch(repoSuffix, conflictedBranchName)) - .thenReturn(conflictedBranchName + CONFLICTED_SUCCESS_MESSAGE)); - }); - - return Mono.create( - sink -> conflictedBranchMono.subscribe(sink::success, sink::error, null, sink.currentContext())); - } - - private Mono commitAndPushWithDefaultCommit( - Path repoSuffix, GitAuth auth, GitArtifactMetadata gitArtifactMetadata, GitDefaultCommitMessage reason) { - return gitExecutor - .commitArtifact( - repoSuffix, - DEFAULT_COMMIT_MESSAGE + reason.getReason(), - APPSMITH_BOT_USERNAME, - emailConfig.getSupportEmailAddress(), - true, - false) - .onErrorResume(error -> { - if (error instanceof EmptyCommitException) { - return Mono.just(EMPTY_COMMIT_ERROR_MESSAGE); - } - return Mono.error( - new AppsmithException(AppsmithError.GIT_ACTION_FAILED, "commit", error.getMessage())); - }) - .flatMap(commitMessage -> gitExecutor - .pushApplication( - repoSuffix, - gitArtifactMetadata.getRemoteUrl(), - auth.getPublicKey(), - auth.getPrivateKey(), - gitArtifactMetadata.getBranchName()) - .map(pushResult -> { - if (pushResult.contains("REJECTED")) { - throw new AppsmithException(AppsmithError.GIT_UPSTREAM_CHANGES); - } - return pushResult; - })); - } - - @Override - public Mono testConnection(String defaultArtifactId, ArtifactType artifactType) { - - GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); - AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); - - return gitArtifactHelper - .getArtifactById(defaultArtifactId, artifactEditPermission) - .flatMap(artifact -> { - GitArtifactMetadata gitArtifactMetadata = artifact.getGitArtifactMetadata(); - if (isDefaultGitMetadataInvalid(gitArtifactMetadata)) { - return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_SSH_CONFIGURATION)); - } - return gitExecutor - .testConnection( - gitArtifactMetadata.getGitAuth().getPublicKey(), - gitArtifactMetadata.getGitAuth().getPrivateKey(), - gitArtifactMetadata.getRemoteUrl()) - .zipWith(Mono.just(artifact)) - .onErrorResume(error -> { - log.error( - "Error while testing the connection to th remote repo " - + gitArtifactMetadata.getRemoteUrl() + " ", - error); - return addAnalyticsForGitOperation( - AnalyticsEvents.GIT_TEST_CONNECTION, - artifact, - error.getClass().getName(), - error.getMessage(), - artifact.getGitArtifactMetadata() - .getIsRepoPrivate()) - .flatMap(application1 -> { - if (error instanceof TransportException) { - return Mono.error(new AppsmithException( - AppsmithError.INVALID_GIT_SSH_CONFIGURATION)); - } - if (error instanceof InvalidRemoteException) { - return Mono.error(new AppsmithException( - AppsmithError.INVALID_GIT_CONFIGURATION, error.getMessage())); - } - if (error instanceof TimeoutException) { - return Mono.error( - new AppsmithException(AppsmithError.GIT_EXECUTION_TIMEOUT)); - } - return Mono.error(new AppsmithException( - AppsmithError.GIT_GENERIC_ERROR, error.getMessage())); - }); - }); - }) - .flatMap(objects -> { - Artifact artifact = objects.getT2(); - return addAnalyticsForGitOperation( - AnalyticsEvents.GIT_TEST_CONNECTION, - artifact, - artifact.getGitArtifactMetadata().getIsRepoPrivate()) - .thenReturn(objects.getT1()); - }); - } - /** * In some scenarios: * connect: after loading the modal, keyTypes is not available, so a network call has to be made to ssh-keypair. @@ -2931,14 +2739,13 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { @Override public Mono> listBranchForArtifact( - String defaultArtifactId, Boolean pruneBranches, String currentBranch, ArtifactType artifactType) { - return getBranchList(defaultArtifactId, pruneBranches, currentBranch, true, artifactType); + String branchedArtifactId, Boolean pruneBranches, ArtifactType artifactType) { + return getBranchList(branchedArtifactId, pruneBranches, true, artifactType); } protected Mono> getBranchList( - String defaultArtifactId, + String branchedArtifactId, Boolean pruneBranches, - String currentBranch, boolean syncDefaultBranchWithRemote, ArtifactType artifactType) { @@ -2946,54 +2753,65 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); - Mono defaultArtifactMono = - gitArtifactHelper.getArtifactById(defaultArtifactId, artifactEditPermission); + Mono> baseAndBranchedArtifactMono = + getBaseAndBranchedArtifacts(branchedArtifactId, artifactType, artifactEditPermission); - Mono> branchMono = defaultArtifactMono - .flatMap(defaultArtifact -> { - GitArtifactMetadata gitArtifactMetadata = defaultArtifact.getGitArtifactMetadata(); - if (gitArtifactMetadata == null - || gitArtifactMetadata.getDefaultArtifactId() == null - || gitArtifactMetadata.getRepoName() == null) { - log.error("Git config is not present for application {}", defaultArtifact.getId()); - throw new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_CONFIG_ERROR); + Mono> branchMono = baseAndBranchedArtifactMono + .flatMap(artifactTuples -> { + Artifact baseArtifact = artifactTuples.getT1(); + Artifact branchedArtifact = artifactTuples.getT2(); + + GitArtifactMetadata baseGitData = baseArtifact.getGitArtifactMetadata(); + GitArtifactMetadata branchedGitData = branchedArtifact.getGitArtifactMetadata(); + + if (baseGitData == null || branchedGitData == null) { + return Mono.error( + new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_CONFIG_ERROR)); } - Path repoPath = gitArtifactHelper.getRepoSuffixPath( - defaultArtifact.getWorkspaceId(), - gitArtifactMetadata.getDefaultArtifactId(), - gitArtifactMetadata.getRepoName()); + final String workspaceId = baseArtifact.getWorkspaceId(); + final String baseArtifactId = baseGitData.getDefaultArtifactId(); + final String repoName = baseGitData.getRepoName(); + final String currentBranch = branchedGitData.getBranchName(); - Mono defaultBranchMono; + if (!hasText(baseArtifactId) || !hasText(repoName) || !hasText(currentBranch)) { + log.error( + "Git config is not present for artifact {} of type {}", + baseArtifact.getId(), + artifactType); + return Mono.error( + new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_CONFIG_ERROR)); + } + + Path repoPath = gitArtifactHelper.getRepoSuffixPath(workspaceId, baseArtifactId, repoName); + Mono baseBranchMono; if (TRUE.equals(pruneBranches) && syncDefaultBranchWithRemote) { - defaultBranchMono = syncDefaultBranchNameFromRemote(defaultArtifact, repoPath); + baseBranchMono = syncDefaultBranchNameFromRemote(baseArtifact, repoPath); } else { - defaultBranchMono = - Mono.just(GitUtils.getDefaultBranchName(defaultArtifact.getGitArtifactMetadata())); + baseBranchMono = + Mono.just(GitUtils.getDefaultBranchName(baseArtifact.getGitArtifactMetadata())); } - return Mono.zip(defaultBranchMono, Mono.just(defaultArtifact), Mono.just(repoPath)); + + return baseBranchMono + .flatMap(baseBranchName -> { + return getBranchListWithDefaultBranchName( + baseArtifact, repoPath, baseBranchName, currentBranch, pruneBranches); + }) + .onErrorResume(throwable -> { + if (throwable instanceof RepositoryNotFoundException) { + return handleRepoNotFoundException(baseArtifactId, artifactType); + } + return Mono.error(throwable); + }); }) - .flatMap(objects -> { - String defaultBranchName = objects.getT1(); - Artifact defaultApplication = objects.getT2(); - Path repoPath = objects.getT3(); - return getBranchListWithDefaultBranchName( - defaultApplication, repoPath, defaultBranchName, currentBranch, pruneBranches); - }) - .onErrorResume(throwable -> { - if (throwable instanceof RepositoryNotFoundException) { - // this will clone the repo again - return handleRepoNotFoundException(defaultArtifactId, artifactType); - } - return Mono.error(throwable); - }); + .onErrorResume(Mono::error); return Mono.create(sink -> branchMono.subscribe(sink::success, sink::error, null, sink.currentContext())); } - private Mono syncDefaultBranchNameFromRemote(Artifact defaultArtifact, Path repoPath) { - GitArtifactMetadata metadata = defaultArtifact.getGitArtifactMetadata(); + private Mono syncDefaultBranchNameFromRemote(Artifact baseArtifact, Path repoPath) { + GitArtifactMetadata metadata = baseArtifact.getGitArtifactMetadata(); GitAuth gitAuth = metadata.getGitAuth(); return addFileLock(metadata.getDefaultArtifactId(), GitCommandConstants.SYNC_BRANCH) .then(gitExecutor.getRemoteDefaultBranch( @@ -3013,7 +2831,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { metadata.getDefaultArtifactId(), defaultBranchNameInRemote, repoPath, - defaultArtifact.getArtifactType()) + baseArtifact.getArtifactType()) .then() .thenReturn(defaultBranchNameInRemote); }) @@ -3022,16 +2840,16 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } private Flux updateDefaultBranchName( - String defaultArtifactId, String defaultBranchName, Path repoPath, ArtifactType artifactType) { + String baseArtifactId, String defaultBranchName, Path repoPath, ArtifactType artifactType) { // Get the artifact from DB by new defaultBranch name GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); Mono artifactMono = gitArtifactHelper - .getArtifactByDefaultIdAndBranchName(defaultArtifactId, defaultBranchName, artifactEditPermission) + .getArtifactByBaseIdAndBranchName(baseArtifactId, defaultBranchName, artifactEditPermission) .map(artifact -> (Artifact) artifact); Mono fallbackArtifactMono = - Mono.defer(() -> checkoutRemoteBranch(defaultArtifactId, defaultBranchName, artifactType)); + Mono.defer(() -> checkoutRemoteBranch(baseArtifactId, defaultBranchName, artifactType)); // Check if the branch is already present, If not follow checkout remote flow return artifactMono @@ -3041,7 +2859,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { .createAndCheckoutToBranch(repoPath, defaultBranchName) .onErrorComplete()) // Update the default branch name in all the child applications - .thenMany(gitArtifactHelper.getAllArtifactByDefaultId(defaultArtifactId, artifactEditPermission)) + .thenMany(gitArtifactHelper.getAllArtifactByBaseId(baseArtifactId, artifactEditPermission)) .flatMap(artifact -> { artifact.getGitArtifactMetadata().setDefaultBranchName(defaultBranchName); // clear the branch protection rules as the default branch name has been changed @@ -3050,7 +2868,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { }); } - private Mono> handleRepoNotFoundException(String defaultArtifactId, ArtifactType artifactType) { + private Mono> handleRepoNotFoundException(String baseArtifactId, ArtifactType artifactType) { // clone application to the local filesystem again and update the defaultBranch for the application // list branch and compare with branch applications and checkout if not exists @@ -3060,13 +2878,13 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); AclPermission artifactReadPermission = gitArtifactHelper.getArtifactReadPermission(); - Mono defaultArtifactMono = - gitArtifactHelper.getArtifactById(defaultArtifactId, artifactEditPermission); + Mono baseArtifactMono = + gitArtifactHelper.getArtifactById(baseArtifactId, artifactEditPermission); - return defaultArtifactMono.flatMap(defaultArtifact -> { - GitArtifactMetadata gitArtifactMetadata = defaultArtifact.getGitArtifactMetadata(); + return baseArtifactMono.flatMap(baseArtifact -> { + GitArtifactMetadata gitArtifactMetadata = baseArtifact.getGitArtifactMetadata(); Path repoPath = gitArtifactHelper.getRepoSuffixPath( - defaultArtifact.getWorkspaceId(), defaultArtifact.getId(), gitArtifactMetadata.getRepoName()); + baseArtifact.getWorkspaceId(), baseArtifact.getId(), gitArtifactMetadata.getRepoName()); GitAuth gitAuth = gitArtifactMetadata.getGitAuth(); return gitExecutor .cloneRemoteIntoArtifactRepo( @@ -3098,8 +2916,8 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { return Flux.fromIterable(branchesToCheckout) .flatMap(branchName -> gitArtifactHelper - .getArtifactByDefaultIdAndBranchName( - defaultArtifactId, branchName, artifactReadPermission) + .getArtifactByBaseIdAndBranchName( + baseArtifactId, branchName, artifactReadPermission) // checkout the branch locally .flatMap(artifact -> { // Add the locally checked out branch to the branchList @@ -3123,14 +2941,14 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } private Mono> getBranchListWithDefaultBranchName( - Artifact defaultArtifact, + Artifact baseArtifact, Path repoPath, String defaultBranchName, String currentBranch, boolean pruneBranches) { - return addFileLock(defaultArtifact.getId(), GitCommandConstants.LIST_BRANCH) + return addFileLock(baseArtifact.getId(), GitCommandConstants.LIST_BRANCH) .flatMap(objects -> { - GitArtifactMetadata gitArtifactMetadata = defaultArtifact.getGitArtifactMetadata(); + GitArtifactMetadata gitArtifactMetadata = baseArtifact.getGitArtifactMetadata(); if (TRUE.equals(pruneBranches)) { return gitExecutor @@ -3146,8 +2964,7 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { return gitExecutor.listBranches(repoPath); } }) - .flatMap(branchDTOList -> - releaseFileLock(defaultArtifact.getId()).thenReturn(branchDTOList)) + .flatMap(branchDTOList -> releaseFileLock(baseArtifact.getId()).thenReturn(branchDTOList)) .map(branchDTOList -> { for (GitBranchDTO branchDTO : branchDTOList) { if (StringUtils.equalsIgnoreCase(branchDTO.getBranchName(), defaultBranchName)) { @@ -3161,21 +2978,21 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { ? Mono.just(gitBranchDTOList) : addAnalyticsForGitOperation( AnalyticsEvents.GIT_PRUNE, - defaultArtifact, - defaultArtifact.getGitArtifactMetadata().getIsRepoPrivate()) + baseArtifact, + baseArtifact.getGitArtifactMetadata().getIsRepoPrivate()) .thenReturn(gitBranchDTOList)); } @Override - public Mono> getProtectedBranches(String defaultArtifactId, ArtifactType artifactType) { + public Mono> getProtectedBranches(String baseArtifactId, ArtifactType artifactType) { GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); - Mono defaultArtifactMono = - gitArtifactHelper.getArtifactById(defaultArtifactId, artifactEditPermission); + Mono baseArtifactMono = + gitArtifactHelper.getArtifactById(baseArtifactId, artifactEditPermission); - return defaultArtifactMono.map(defaultArtifact -> { + return baseArtifactMono.map(defaultArtifact -> { GitArtifactMetadata gitArtifactMetadata = defaultArtifact.getGitArtifactMetadata(); /* user may have multiple branches as protected, but we only return the default branch @@ -3192,18 +3009,6 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { }); } - /** - * This method is context aware - * @param defaultArtifactId : id of the root application - * @param branchName : branch name on which autocommit has to be done - * @param artifactType : type of artifact, this is application for now. - * @return flag whether the process has started or not. - */ - @Override - public Mono autoCommitApplication(String defaultArtifactId, String branchName, ArtifactType artifactType) { - return gitAutoCommitHelper.autoCommitClientMigration(defaultArtifactId, branchName); - } - @Override public Mono getAutoCommitProgress( String artifactId, String branchName, ArtifactType artifactType) { @@ -3211,37 +3016,38 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } @Override - public Mono toggleAutoCommitEnabled(String defaultArtifactId, ArtifactType artifactType) { + public Mono toggleAutoCommitEnabled(String baseArtifactId, ArtifactType artifactType) { GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission artifactAutoCommitPermission = gitArtifactHelper.getArtifactAutoCommitPermission(); - Mono defaultArtifactMono = - gitArtifactHelper.getArtifactById(defaultArtifactId, artifactAutoCommitPermission); + Mono baseArtifactMono = + gitArtifactHelper.getArtifactById(baseArtifactId, artifactAutoCommitPermission); + // get base app - return defaultArtifactMono - .map(defaultArtifact -> { - GitArtifactMetadata gitArtifactMetadata = defaultArtifact.getGitArtifactMetadata(); - if (!defaultArtifact.getId().equals(gitArtifactMetadata.getDefaultArtifactId())) { + return baseArtifactMono + .map(baseArtifact -> { + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + if (!baseArtifact.getId().equals(baseGitMetadata.getDefaultArtifactId())) { log.error( - "failed tp toggle auto commit. reason: {} is not the root defaultArtifact id", - defaultArtifactId); - throw new AppsmithException(AppsmithError.INVALID_PARAMETER, "default defaultArtifact id"); + "failed tp toggle auto commit. reason: {} is not the id of the base Artifact", + baseArtifactId); + throw new AppsmithException(AppsmithError.INVALID_PARAMETER, "default baseArtifact id"); } - AutoCommitConfig autoCommitConfig = gitArtifactMetadata.getAutoCommitConfig(); + AutoCommitConfig autoCommitConfig = baseGitMetadata.getAutoCommitConfig(); if (autoCommitConfig.getEnabled()) { autoCommitConfig.setEnabled(FALSE); } else { autoCommitConfig.setEnabled(TRUE); } // need to call the setter because getter returns a default config if attribute is null - defaultArtifact.getGitArtifactMetadata().setAutoCommitConfig(autoCommitConfig); - return defaultArtifact; + baseArtifact.getGitArtifactMetadata().setAutoCommitConfig(autoCommitConfig); + return baseArtifact; }) - .flatMap(defaultArtifact -> gitArtifactHelper - .saveArtifact(defaultArtifact) - .thenReturn(defaultArtifact + .flatMap(baseArtifact -> gitArtifactHelper + .saveArtifact(baseArtifact) + .thenReturn(baseArtifact .getGitArtifactMetadata() .getAutoCommitConfig() .getEnabled())); @@ -3249,43 +3055,56 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { @Override public Mono> updateProtectedBranches( - String defaultArtifactId, List branchNames, ArtifactType artifactType) { + String baseArtifactId, List branchNames, ArtifactType artifactType) { GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); AclPermission artifactManageProtectedBranchPermission = gitArtifactHelper.getArtifactManageProtectedBranchPermission(); - Mono defaultArtifactMono = - gitArtifactHelper.getArtifactById(defaultArtifactId, artifactManageProtectedBranchPermission); + Mono baseArtifactMono = + gitArtifactHelper.getArtifactById(baseArtifactId, artifactManageProtectedBranchPermission); - return defaultArtifactMono - .flatMap(defaultArtifact -> { - GitArtifactMetadata metadata = defaultArtifact.getGitArtifactMetadata(); - String defaultBranchName = metadata.getDefaultBranchName(); + return baseArtifactMono + .flatMap(baseArtifact -> { + GitArtifactMetadata baseGitData = baseArtifact.getGitArtifactMetadata(); + final String defaultBranchName = baseGitData.getDefaultBranchName(); + final List incomingProtectedBranches = + CollectionUtils.isNullOrEmpty(branchNames) ? new ArrayList<>() : branchNames; - if (branchNames.isEmpty() - || (branchNames.size() == 1 && branchNames.get(0).equals(defaultBranchName))) { - // keep a copy of old protected branches as it's required to send analytics event later - List oldProtectedBranches = metadata.getBranchProtectionRules() != null - ? metadata.getBranchProtectionRules() - : List.of(); - - // user wants to unprotect all branches or user wants to protect only default branch - metadata.setBranchProtectionRules(branchNames); - return gitArtifactHelper - .saveArtifact(defaultArtifact) - .then(gitArtifactHelper.updateArtifactWithProtectedBranches( - defaultArtifactId, branchNames)) - .then(sendBranchProtectionAnalytics(defaultArtifact, oldProtectedBranches, branchNames)) - .thenReturn(branchNames); - } else { - // user want to protect multiple branches, not allowed + // user cannot protect multiple branches + if (incomingProtectedBranches.size() > 1) { return Mono.error(new AppsmithException(AppsmithError.UNSUPPORTED_OPERATION)); } + + // user cannot protect a branch which is not default + if (incomingProtectedBranches.size() == 1 + && !defaultBranchName.equals(incomingProtectedBranches.get(0))) { + return Mono.error(new AppsmithException(AppsmithError.UNSUPPORTED_OPERATION)); + } + + return updateProtectedBranchesInArtifactAfterVerification(baseArtifact, incomingProtectedBranches); }) .as(transactionalOperator::transactional); } + protected Mono> updateProtectedBranchesInArtifactAfterVerification( + Artifact baseArtifact, List branchNames) { + GitArtifactHelper gitArtifactHelper = getArtifactGitService(baseArtifact.getArtifactType()); + GitArtifactMetadata baseGitData = baseArtifact.getGitArtifactMetadata(); + + // keep a copy of old protected branches as it's required to send analytics event later + List oldProtectedBranches = baseGitData.getBranchProtectionRules() == null + ? new ArrayList<>() + : baseGitData.getBranchProtectionRules(); + + baseGitData.setBranchProtectionRules(branchNames); + return gitArtifactHelper + .saveArtifact(baseArtifact) + .then(gitArtifactHelper.updateArtifactWithProtectedBranches(baseArtifact.getId(), branchNames)) + .then(sendBranchProtectionAnalytics(baseArtifact, oldProtectedBranches, branchNames)) + .thenReturn(branchNames); + } + /** * Sends one or more analytics events when there's a change in protected branches. * If n number of branches are un-protected and m number of branches are protected, it'll send m+n number of @@ -3598,4 +3417,47 @@ public class CommonGitServiceCEImpl implements CommonGitServiceCE { } return false; } + + /** + * Returns baseArtifact and branchedArtifact + * This operation is quite frequently used, hence providing the right set + * + * @param branchedArtifactId : id of the branchedArtifactId + * @param artifactPermission : permission required for getting artifact. + * @return : A tuple of Artifacts + */ + protected Mono> getBaseAndBranchedArtifacts( + String branchedArtifactId, ArtifactType artifactType, AclPermission artifactPermission) { + if (!hasText(branchedArtifactId)) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID)); + } + + GitArtifactHelper artifactGitHelper = getArtifactGitService(artifactType); + Mono branchedArtifactMono = artifactGitHelper + .getArtifactById(branchedArtifactId, artifactPermission) + .cache(); + + return branchedArtifactMono.flatMap(branchedArtifact -> { + GitArtifactMetadata branchedMetadata = branchedArtifact.getGitArtifactMetadata(); + if (branchedMetadata == null || !hasText(branchedMetadata.getDefaultArtifactId())) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_CONFIG_ERROR)); + } + + String baseArtifactId = branchedMetadata.getDefaultArtifactId(); + Mono baseArtifactMono = Mono.just(branchedArtifact); + + if (!baseArtifactId.equals(branchedArtifactId)) { + baseArtifactMono = artifactGitHelper.getArtifactById(baseArtifactId, artifactPermission); + } + + return baseArtifactMono.zipWith(branchedArtifactMono); + }); + } + + protected Mono> getBaseAndBranchedArtifacts( + String branchedArtifactId, ArtifactType artifactType) { + GitArtifactHelper gitArtifactHelper = getArtifactGitService(artifactType); + AclPermission artifactPermission = gitArtifactHelper.getArtifactEditPermission(); + return getBaseAndBranchedArtifacts(branchedArtifactId, artifactType, artifactPermission); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/DefaultResourcesUtils.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/DefaultResourcesUtils.java deleted file mode 100644 index 1731af079e..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/DefaultResourcesUtils.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.appsmith.server.helpers; - -import com.appsmith.external.dtos.DslExecutableDTO; -import com.appsmith.external.models.ActionDTO; -import com.appsmith.external.models.DefaultResources; -import com.appsmith.server.domains.ActionCollection; -import com.appsmith.server.domains.NewAction; -import com.appsmith.server.domains.NewPage; -import com.appsmith.server.dtos.ActionCollectionDTO; -import com.appsmith.server.dtos.PageDTO; -import org.apache.commons.lang3.StringUtils; - -import java.util.Optional; -import java.util.Set; - -public class DefaultResourcesUtils { - public static T createDefaultIdsOrUpdateWithGivenResourceIds(T resource, String branchName) { - - if (resource instanceof NewAction) { - NewAction action = (NewAction) resource; - DefaultResources actionDefaultResources = action.getDefaultResources(); - - if (Optional.ofNullable(actionDefaultResources).isEmpty()) { - actionDefaultResources = new DefaultResources(); - } - final String defaultApplicationId = StringUtils.isEmpty(actionDefaultResources.getApplicationId()) - ? action.getApplicationId() - : actionDefaultResources.getApplicationId(); - - final String defaultActionId = StringUtils.isEmpty(actionDefaultResources.getActionId()) - ? action.getId() - : actionDefaultResources.getActionId(); - actionDefaultResources.setApplicationId(defaultApplicationId); - actionDefaultResources.setActionId(defaultActionId); - actionDefaultResources.setBranchName(branchName); - - if (Optional.ofNullable(action.getUnpublishedAction()).isPresent()) { - createDefaultIdsOrUpdateWithGivenResourceIds(action.getUnpublishedAction(), branchName); - } - - if (Optional.ofNullable(action.getPublishedAction()).isPresent()) { - createDefaultIdsOrUpdateWithGivenResourceIds(action.getPublishedAction(), branchName); - } - action.setDefaultResources(actionDefaultResources); - } else if (resource instanceof ActionDTO) { - ActionDTO action = (ActionDTO) resource; - DefaultResources actionDefaultResources = action.getDefaultResources(); - if (Optional.ofNullable(actionDefaultResources).isEmpty()) { - actionDefaultResources = new DefaultResources(); - } - final String defaultPageId = StringUtils.isEmpty(actionDefaultResources.getPageId()) - ? action.getPageId() - : actionDefaultResources.getPageId(); - - final String defaultCollectionId = StringUtils.isEmpty(actionDefaultResources.getCollectionId()) - ? action.getCollectionId() - : actionDefaultResources.getCollectionId(); - - actionDefaultResources.setPageId(defaultPageId); - actionDefaultResources.setCollectionId(defaultCollectionId); - action.setDefaultResources(actionDefaultResources); - } else if (resource instanceof NewPage) { - NewPage page = (NewPage) resource; - DefaultResources pageDefaultResources = page.getDefaultResources(); - boolean updateOnLoadAction = false; - if (Optional.ofNullable(pageDefaultResources).isEmpty()) { - pageDefaultResources = new DefaultResources(); - updateOnLoadAction = true; - } - - final String defaultApplicationId = StringUtils.isEmpty(pageDefaultResources.getApplicationId()) - ? page.getApplicationId() - : pageDefaultResources.getApplicationId(); - - final String defaultPageId = StringUtils.isEmpty(pageDefaultResources.getPageId()) - ? page.getId() - : pageDefaultResources.getPageId(); - pageDefaultResources.setApplicationId(defaultApplicationId); - pageDefaultResources.setPageId(defaultPageId); - pageDefaultResources.setBranchName(branchName); - - // Copy layoutOnLoadAction Ids to defaultPageId - updateOnLoadActionAndCollectionIds(page.getUnpublishedPage(), updateOnLoadAction); - - if (page.getPublishedPage() != null - && !CollectionUtils.isNullOrEmpty(page.getPublishedPage().getLayouts())) { - updateOnLoadActionAndCollectionIds(page.getPublishedPage(), updateOnLoadAction); - } - page.setDefaultResources(pageDefaultResources); - } else if (resource instanceof ActionCollection) { - ActionCollection actionCollection = (ActionCollection) resource; - - DefaultResources actionCollectionDefaultResources = actionCollection.getDefaultResources(); - if (Optional.ofNullable(actionCollectionDefaultResources).isEmpty()) { - actionCollectionDefaultResources = new DefaultResources(); - } - - final String defaultApplicationId = StringUtils.isEmpty(actionCollectionDefaultResources.getApplicationId()) - ? actionCollection.getApplicationId() - : actionCollectionDefaultResources.getApplicationId(); - - final String defaultActionCollectionId = - StringUtils.isEmpty(actionCollectionDefaultResources.getCollectionId()) - ? actionCollection.getId() - : actionCollectionDefaultResources.getCollectionId(); - actionCollectionDefaultResources.setApplicationId(defaultApplicationId); - actionCollectionDefaultResources.setCollectionId(defaultActionCollectionId); - actionCollectionDefaultResources.setPageId(null); - actionCollectionDefaultResources.setBranchName(branchName); - - if (Optional.ofNullable(actionCollection.getUnpublishedCollection()).isPresent()) { - createDefaultIdsOrUpdateWithGivenResourceIds(actionCollection.getUnpublishedCollection(), branchName); - } - if (Optional.ofNullable(actionCollection.getPublishedCollection()).isPresent()) { - createDefaultIdsOrUpdateWithGivenResourceIds(actionCollection.getPublishedCollection(), branchName); - } - actionCollection.setDefaultResources(actionCollectionDefaultResources); - } else if (resource instanceof ActionCollectionDTO) { - ActionCollectionDTO collectionDTO = (ActionCollectionDTO) resource; - boolean updateActionIds = false; - DefaultResources collectionDTODefaultResources = collectionDTO.getDefaultResources(); - if (Optional.ofNullable(collectionDTODefaultResources).isEmpty()) { - collectionDTODefaultResources = new DefaultResources(); - updateActionIds = true; - } - final String defaultPageId = StringUtils.isEmpty(collectionDTODefaultResources.getPageId()) - ? collectionDTO.getPageId() - : collectionDTODefaultResources.getPageId(); - - collectionDTODefaultResources.setPageId(defaultPageId); - collectionDTODefaultResources.setApplicationId(null); - collectionDTODefaultResources.setBranchName(null); - collectionDTODefaultResources.setCollectionId(null); - - collectionDTO.setDefaultResources(collectionDTODefaultResources); - } - return resource; - } - - static void updateOnLoadActionAndCollectionIds(PageDTO page, boolean shouldUpdate) { - page.getLayouts().forEach(layout -> { - if (!CollectionUtils.isNullOrEmpty(layout.getLayoutOnLoadActions())) { - for (Set layoutOnLoadAction : layout.getLayoutOnLoadActions()) { - for (DslExecutableDTO dslExecutableDTO : layoutOnLoadAction) { - if (shouldUpdate || StringUtils.isEmpty(dslExecutableDTO.getDefaultActionId())) { - dslExecutableDTO.setDefaultActionId(dslExecutableDTO.getId()); - dslExecutableDTO.setDefaultCollectionId(dslExecutableDTO.getCollectionId()); - } - } - } - } - }); - } -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ResponseUtils.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ResponseUtils.java deleted file mode 100644 index e9f771db2c..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ResponseUtils.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.appsmith.server.helpers; - -import com.appsmith.server.helpers.ce.ResponseUtilsCE; -import com.appsmith.server.migrations.JsonSchemaVersions; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -@Slf4j -@Component -public class ResponseUtils extends ResponseUtilsCE { - - public ResponseUtils(JsonSchemaVersions jsonSchemaVersions) { - super(jsonSchemaVersions); - } -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/UserPermissionUtils.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/UserPermissionUtils.java index dc1115579d..a082e6acf4 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/UserPermissionUtils.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/UserPermissionUtils.java @@ -30,12 +30,12 @@ public class UserPermissionUtils { AppsmithError appsmithError) { return baseDomainFlux .zipWith(permissionGroupIdsMono.repeat()) - .map(tuple -> { + .flatMap(tuple -> { if (!validateDomainObjectPermissionExists(tuple.getT1(), aclPermission, tuple.getT2())) { - throw new AppsmithException( - appsmithError, domainEntity, tuple.getT1().getId()); + return Mono.error(new AppsmithException( + appsmithError, domainEntity, tuple.getT1().getId())); } - return Boolean.TRUE; + return Mono.just(Boolean.TRUE); }) .collectList() .thenReturn(Boolean.TRUE); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/ArtifactGitFileUtilsCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/ArtifactGitFileUtilsCE.java index aa37232625..1844397507 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/ArtifactGitFileUtilsCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/ArtifactGitFileUtilsCE.java @@ -13,7 +13,7 @@ public interface ArtifactGitFileUtilsCE { T createArtifactReferenceObject(); Mono reconstructArtifactExchangeJsonFromFilesInRepository( - String workspaceId, String defaultArtifactId, String repoName, String branchName); + String workspaceId, String baseArtifactId, String repoName, String branchName); void addArtifactReferenceFromExportedJson( ArtifactExchangeJson artifactExchangeJson, ArtifactGitReference artifactGitReference); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/CommonGitFileUtilsCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/CommonGitFileUtilsCE.java index dbaf54e9ee..a648871bb1 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/CommonGitFileUtilsCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/CommonGitFileUtilsCE.java @@ -144,14 +144,14 @@ public class CommonGitFileUtilsCE { public Mono saveArtifactToLocalRepo( String workspaceId, - String defaultArtifactId, + String baseArtifactId, String repoName, ApplicationJson applicationJson, String branchName) throws GitAPIException, IOException { // TODO: Paths are to populated by artifact specific services - Path baseRepoSuffix = Paths.get(workspaceId, defaultArtifactId, repoName); + Path baseRepoSuffix = Paths.get(workspaceId, baseArtifactId, repoName); return saveArtifactToLocalRepo(baseRepoSuffix, applicationJson, branchName); } @@ -191,30 +191,26 @@ public class CommonGitFileUtilsCE { * Method to reconstruct the application from the local git repo * * @param workspaceId To which workspace application needs to be rehydrated - * @param defaultArtifactId Root application for the current branched application + * @param baseArtifactId Root application for the current branched application * @param branchName for which branch the application needs to rehydrate * @param artifactType * @return application reference from which entire application can be rehydrated */ public Mono reconstructArtifactExchangeJsonFromGitRepoWithAnalytics( - String workspaceId, - String defaultArtifactId, - String repoName, - String branchName, - ArtifactType artifactType) { + String workspaceId, String baseArtifactId, String repoName, String branchName, ArtifactType artifactType) { Stopwatch stopwatch = new Stopwatch(AnalyticsEvents.GIT_DESERIALIZE_APP_RESOURCES_FROM_FILE.getEventName()); ArtifactGitFileUtils artifactGitFileUtils = getArtifactBasedFileHelper(artifactType); Map constantsMap = artifactGitFileUtils.getConstantsMap(); return Mono.zip( reconstructArtifactExchangeJsonFromGitRepo( - workspaceId, defaultArtifactId, repoName, branchName, artifactType), + workspaceId, baseArtifactId, repoName, branchName, artifactType), sessionUserService.getCurrentUser()) .flatMap(tuple -> { stopwatch.stopTimer(); final Map data = Map.of( constantsMap.get(FieldName.ID), - defaultArtifactId, + baseArtifactId, FieldName.ORGANIZATION_ID, workspaceId, FieldName.FLOW_NAME, @@ -231,15 +227,11 @@ public class CommonGitFileUtilsCE { } public Mono reconstructArtifactExchangeJsonFromGitRepo( - String workspaceId, - String defaultApplicationId, - String repoName, - String branchName, - ArtifactType artifactType) { + String workspaceId, String baseArtifactId, String repoName, String branchName, ArtifactType artifactType) { ArtifactGitFileUtils artifactGitFileUtils = getArtifactBasedFileHelper(artifactType); return artifactGitFileUtils.reconstructArtifactExchangeJsonFromFilesInRepository( - workspaceId, defaultApplicationId, repoName, branchName); + workspaceId, baseArtifactId, repoName, branchName); } /** diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/ResponseUtilsCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/ResponseUtilsCE.java deleted file mode 100644 index 4480c04dda..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/ResponseUtilsCE.java +++ /dev/null @@ -1,330 +0,0 @@ -package com.appsmith.server.helpers.ce; - -import com.appsmith.external.models.ActionDTO; -import com.appsmith.external.models.DefaultResources; -import com.appsmith.server.domains.ActionCollection; -import com.appsmith.server.domains.Application; -import com.appsmith.server.domains.Layout; -import com.appsmith.server.domains.NewAction; -import com.appsmith.server.domains.NewPage; -import com.appsmith.server.dtos.ActionCollectionDTO; -import com.appsmith.server.dtos.ActionCollectionViewDTO; -import com.appsmith.server.dtos.ActionViewDTO; -import com.appsmith.server.dtos.ApplicationPagesDTO; -import com.appsmith.server.dtos.LayoutDTO; -import com.appsmith.server.dtos.PageDTO; -import com.appsmith.server.dtos.PageNameIdDTO; -import com.appsmith.server.exceptions.AppsmithError; -import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.migrations.JsonSchemaVersions; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang.StringUtils; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.util.List; - -@Slf4j -@Component -@RequiredArgsConstructor -public class ResponseUtilsCE { - - protected final JsonSchemaVersions jsonSchemaVersions; - - public PageDTO updatePageDTOWithDefaultResources(PageDTO page) { - DefaultResources defaultResourceIds = page.getDefaultResources(); - if (defaultResourceIds == null - || StringUtils.isEmpty(defaultResourceIds.getApplicationId()) - || StringUtils.isEmpty(defaultResourceIds.getPageId())) { - - if (defaultResourceIds == null) { - return page; - } - if (StringUtils.isEmpty(defaultResourceIds.getApplicationId())) { - defaultResourceIds.setApplicationId(page.getApplicationId()); - } - if (StringUtils.isEmpty(defaultResourceIds.getPageId())) { - defaultResourceIds.setPageId(page.getId()); - } - } - page.setApplicationId(defaultResourceIds.getApplicationId()); - page.setId(defaultResourceIds.getPageId()); - - page.getLayouts().stream() - .filter(layout -> !CollectionUtils.isEmpty(layout.getLayoutOnLoadActions())) - .forEach(layout -> this.updateLayoutWithDefaultResources(layout)); - return page; - } - - public NewPage updateNewPageWithDefaultResources(NewPage newPage) { - DefaultResources defaultResourceIds = newPage.getDefaultResources(); - if (defaultResourceIds == null - || StringUtils.isEmpty(defaultResourceIds.getApplicationId()) - || StringUtils.isEmpty(defaultResourceIds.getPageId())) { - log.error( - "Unable to find default ids for page: {}", - newPage.getId(), - new AppsmithException(AppsmithError.DEFAULT_RESOURCES_UNAVAILABLE, "page", newPage.getId())); - - if (defaultResourceIds == null) { - return newPage; - } - if (StringUtils.isEmpty(defaultResourceIds.getApplicationId())) { - defaultResourceIds.setApplicationId(newPage.getApplicationId()); - } - if (StringUtils.isEmpty(defaultResourceIds.getPageId())) { - defaultResourceIds.setPageId(newPage.getId()); - } - } - newPage.setId(defaultResourceIds.getPageId()); - newPage.setApplicationId(defaultResourceIds.getApplicationId()); - if (newPage.getUnpublishedPage() != null) { - newPage.setUnpublishedPage(this.updatePageDTOWithDefaultResources(newPage.getUnpublishedPage())); - } - if (newPage.getPublishedPage() != null) { - newPage.setPublishedPage(this.updatePageDTOWithDefaultResources(newPage.getPublishedPage())); - } - return newPage; - } - - public ApplicationPagesDTO updateApplicationPagesDTOWithDefaultResources(ApplicationPagesDTO applicationPages) { - List pageNameIdList = applicationPages.getPages(); - for (PageNameIdDTO page : pageNameIdList) { - if (StringUtils.isEmpty(page.getDefaultPageId())) { - log.error( - "Unable to find default pageId for applicationPage: {}", - page.getId(), - new AppsmithException( - AppsmithError.DEFAULT_RESOURCES_UNAVAILABLE, "applicationPage", page.getId())); - continue; - } - page.setId(page.getDefaultPageId()); - } - // need to update the application also if it's present - if (applicationPages.getApplication() != null) { - applicationPages.setApplication(updateApplicationWithDefaultResources(applicationPages.getApplication())); - } - return applicationPages; - } - - public ActionDTO updateActionDTOWithDefaultResources(ActionDTO action) { - log.debug( - "Updating action DTO with default resources with action id: {} ", - action != null ? action.getId() : null); - DefaultResources defaultResourceIds = action.getDefaultResources(); - if (defaultResourceIds == null) { - return action; - } - if (StringUtils.isEmpty(defaultResourceIds.getApplicationId())) { - defaultResourceIds.setApplicationId(action.getApplicationId()); - } - if (StringUtils.isEmpty(defaultResourceIds.getPageId())) { - defaultResourceIds.setPageId(action.getPageId()); - } - if (StringUtils.isEmpty(defaultResourceIds.getActionId())) { - defaultResourceIds.setActionId(action.getId()); - } - action.setApplicationId(defaultResourceIds.getApplicationId()); - action.setPageId(defaultResourceIds.getPageId()); - action.setId(defaultResourceIds.getActionId()); - if (!StringUtils.isEmpty(defaultResourceIds.getCollectionId())) { - action.setCollectionId(defaultResourceIds.getCollectionId()); - } - return action; - } - - public LayoutDTO updateLayoutDTOWithDefaultResources(LayoutDTO layout) { - if (!CollectionUtils.isEmpty(layout.getActionUpdates())) { - layout.getActionUpdates() - .forEach(updateLayoutAction -> updateLayoutAction.setId(updateLayoutAction.getDefaultActionId())); - } - if (!CollectionUtils.isEmpty(layout.getLayoutOnLoadActions())) { - layout.getLayoutOnLoadActions() - .forEach(layoutOnLoadAction -> layoutOnLoadAction.forEach(onLoadAction -> { - if (!StringUtils.isEmpty(onLoadAction.getDefaultActionId())) { - onLoadAction.setId(onLoadAction.getDefaultActionId()); - } - if (!StringUtils.isEmpty(onLoadAction.getDefaultCollectionId())) { - onLoadAction.setCollectionId(onLoadAction.getDefaultCollectionId()); - } - })); - } - return layout; - } - - public Layout updateLayoutWithDefaultResources(Layout layout) { - if (!CollectionUtils.isEmpty(layout.getLayoutOnLoadActions())) { - layout.getLayoutOnLoadActions() - .forEach(layoutOnLoadAction -> layoutOnLoadAction.forEach(onLoadAction -> { - if (!StringUtils.isEmpty(onLoadAction.getDefaultActionId())) { - onLoadAction.setId(onLoadAction.getDefaultActionId()); - } - if (!StringUtils.isEmpty(onLoadAction.getDefaultCollectionId())) { - onLoadAction.setCollectionId(onLoadAction.getDefaultCollectionId()); - } - })); - } - return layout; - } - - public ActionViewDTO updateActionViewDTOWithDefaultResources(ActionViewDTO viewDTO) { - DefaultResources defaultResourceIds = viewDTO.getDefaultResources(); - - if (defaultResourceIds == null) { - return viewDTO; - } - if (StringUtils.isEmpty(defaultResourceIds.getPageId())) { - defaultResourceIds.setPageId(viewDTO.getPageId()); - } - if (StringUtils.isEmpty(defaultResourceIds.getActionId())) { - defaultResourceIds.setActionId(viewDTO.getId()); - } - - viewDTO.setId(defaultResourceIds.getActionId()); - viewDTO.setPageId(defaultResourceIds.getPageId()); - return viewDTO; - } - - public NewAction updateNewActionWithDefaultResources(NewAction newAction) { - DefaultResources defaultResourceIds = newAction.getDefaultResources(); - if (defaultResourceIds == null - || StringUtils.isEmpty(defaultResourceIds.getApplicationId()) - || StringUtils.isEmpty(defaultResourceIds.getActionId())) { - log.error( - "Unable to find default ids for newAction: {}", - newAction.getId(), - new AppsmithException(AppsmithError.DEFAULT_RESOURCES_UNAVAILABLE, "newAction", newAction.getId())); - - if (defaultResourceIds == null) { - return newAction; - } - if (StringUtils.isEmpty(defaultResourceIds.getApplicationId())) { - defaultResourceIds.setApplicationId(newAction.getApplicationId()); - } - if (StringUtils.isEmpty(defaultResourceIds.getActionId())) { - defaultResourceIds.setActionId(newAction.getId()); - } - } - - newAction.setId(defaultResourceIds.getActionId()); - newAction.setApplicationId(defaultResourceIds.getApplicationId()); - if (newAction.getUnpublishedAction() != null) { - newAction.setUnpublishedAction(this.updateActionDTOWithDefaultResources(newAction.getUnpublishedAction())); - } - if (newAction.getPublishedAction() != null) { - newAction.setPublishedAction(this.updateActionDTOWithDefaultResources(newAction.getPublishedAction())); - } - return newAction; - } - - public ActionCollection updateActionCollectionWithDefaultResources(ActionCollection actionCollection) { - DefaultResources defaultResourceIds = actionCollection.getDefaultResources(); - - if (defaultResourceIds == null) { - return actionCollection; - } - if (StringUtils.isEmpty(defaultResourceIds.getApplicationId())) { - defaultResourceIds.setApplicationId(actionCollection.getApplicationId()); - } - if (StringUtils.isEmpty(defaultResourceIds.getCollectionId())) { - defaultResourceIds.setCollectionId(actionCollection.getId()); - } - - actionCollection.setId(defaultResourceIds.getCollectionId()); - actionCollection.setApplicationId(defaultResourceIds.getApplicationId()); - if (actionCollection.getUnpublishedCollection() != null) { - actionCollection.setUnpublishedCollection( - this.updateCollectionDTOWithDefaultResources(actionCollection.getUnpublishedCollection())); - } - if (actionCollection.getPublishedCollection() != null) { - actionCollection.setPublishedCollection( - this.updateCollectionDTOWithDefaultResources(actionCollection.getPublishedCollection())); - } - return actionCollection; - } - - public ActionCollectionDTO updateCollectionDTOWithDefaultResources(ActionCollectionDTO collection) { - DefaultResources defaultResourceIds = collection.getDefaultResources(); - - if (defaultResourceIds == null) { - return collection; - } - if (StringUtils.isEmpty(defaultResourceIds.getApplicationId())) { - defaultResourceIds.setApplicationId(collection.getApplicationId()); - } - if (StringUtils.isEmpty(defaultResourceIds.getPageId())) { - defaultResourceIds.setPageId(collection.getPageId()); - } - if (StringUtils.isEmpty(defaultResourceIds.getCollectionId())) { - defaultResourceIds.setCollectionId(collection.getId()); - } - - collection.setApplicationId(defaultResourceIds.getApplicationId()); - collection.setPageId(defaultResourceIds.getPageId()); - collection.setId(defaultResourceIds.getCollectionId()); - - // Update actions within the collection - collection.getActions().forEach(actionDto -> { - actionDto.setCollectionId(defaultResourceIds.getCollectionId()); - this.updateActionDTOWithDefaultResources(actionDto); - }); - - return collection; - } - - public ActionCollectionViewDTO updateActionCollectionViewDTOWithDefaultResources(ActionCollectionViewDTO viewDTO) { - DefaultResources defaultResourceIds = viewDTO.getDefaultResources(); - - if (defaultResourceIds == null) { - return viewDTO; - } - if (StringUtils.isEmpty(defaultResourceIds.getApplicationId())) { - defaultResourceIds.setApplicationId(viewDTO.getApplicationId()); - } - if (StringUtils.isEmpty(defaultResourceIds.getPageId())) { - defaultResourceIds.setPageId(viewDTO.getPageId()); - } - if (StringUtils.isEmpty(defaultResourceIds.getCollectionId())) { - defaultResourceIds.setCollectionId(viewDTO.getId()); - } - - viewDTO.setId(defaultResourceIds.getCollectionId()); - viewDTO.setApplicationId(defaultResourceIds.getApplicationId()); - viewDTO.setPageId(defaultResourceIds.getPageId()); - - viewDTO.getActions().forEach(this::updateActionDTOWithDefaultResources); - return viewDTO; - } - - public Application updateApplicationWithDefaultResources(Application application) { - if (application.getGitApplicationMetadata() != null - && !StringUtils.isEmpty(application.getGitApplicationMetadata().getDefaultArtifactId())) { - application.setId(application.getGitApplicationMetadata().getDefaultArtifactId()); - } - if (!CollectionUtils.isEmpty(application.getPages())) { - application.getPages().forEach(page -> { - if (!StringUtils.isEmpty(page.getDefaultPageId())) { - page.setId(page.getDefaultPageId()); - } - }); - } - if (!CollectionUtils.isEmpty(application.getPublishedPages())) { - application.getPublishedPages().forEach(page -> { - if (!StringUtils.isEmpty(page.getDefaultPageId())) { - page.setId(page.getDefaultPageId()); - } - }); - } - - if (application.getClientSchemaVersion() == null - || application.getServerSchemaVersion() == null - || (jsonSchemaVersions.getClientVersion().equals(application.getClientSchemaVersion()) - && jsonSchemaVersions.getServerVersion().equals(application.getServerSchemaVersion()))) { - application.setIsAutoUpdate(false); - } else { - application.setIsAutoUpdate(true); - } - return application; - } -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/importable/artifactbased/ArtifactBasedImportableServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/importable/artifactbased/ArtifactBasedImportableServiceCE.java index ff8f44ab5b..6d62d19a78 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/importable/artifactbased/ArtifactBasedImportableServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/importable/artifactbased/ArtifactBasedImportableServiceCE.java @@ -1,6 +1,8 @@ package com.appsmith.server.imports.importable.artifactbased; import com.appsmith.external.models.BaseDomain; +import com.appsmith.external.models.BranchAwareDomain; +import com.appsmith.external.models.GitSyncedDomain; import com.appsmith.server.domains.Artifact; import com.appsmith.server.domains.Context; import com.appsmith.server.dtos.ImportingMetaDTO; @@ -17,29 +19,45 @@ public interface ArtifactBasedImportableServiceCE getExistingResourcesInCurrentArtifactFlux(Artifact artifact); - Flux getExistingResourcesInOtherBranchesFlux(String defaultArtifactId, String currentArtifactId); + Flux getExistingResourcesInOtherBranchesFlux(List branchedArtifactIds, String currentArtifactId); + + void updateArtifactId(T resource, Artifact artifact); Context updateContextInResource( - Object dtoObject, Map contextMap, String fallbackDefaultContextId); + Object dtoObject, Map contextMap, String fallbackBaseContextId); - void populateDefaultResources( - ImportingMetaDTO importingMetaDTO, - MappedImportableResourcesDTO mappedImportableResourcesDTO, - Artifact artifact, - T branchedResource, - T resource); + default void populateBaseId(ImportingMetaDTO importingMetaDTO, Artifact artifact, T branchedResource, T resource) { + BranchAwareDomain branchAwareResource = (BranchAwareDomain) resource; + BranchAwareDomain branchAwareBranchedResource = (BranchAwareDomain) branchedResource; - void createNewResource(ImportingMetaDTO importingMetaDTO, T actionCollection, Context defaultContext); + branchAwareResource.setBranchName(importingMetaDTO.getBranchName()); + if (artifact.getGitArtifactMetadata() != null && branchedResource != null) { + branchAwareResource.setBaseId(branchAwareBranchedResource.getBaseId()); + + } else { + branchAwareResource.setBaseId(branchAwareResource.getBaseIdOrFallback()); + } + } + + void createNewResource(ImportingMetaDTO importingMetaDTO, T actionCollection, Context baseContext); default T getExistingEntityInCurrentBranchForImportedEntity( MappedImportableResourcesDTO mappedImportableResourcesDTO, Map entityInCurrentArtifact, T entity) { - return entityInCurrentArtifact.get(entity.getGitSyncId()); + if (entity instanceof GitSyncedDomain gitSyncedEntity) { + return entityInCurrentArtifact.get(gitSyncedEntity.getGitSyncId()); + } else { + return entity; + } } default T getExistingEntityInOtherBranchForImportedEntity( MappedImportableResourcesDTO mappedImportableResourcesDTO, Map entityInOtherArtifact, T entity) { - return entityInOtherArtifact.get(entity.getGitSyncId()); + if (entity instanceof GitSyncedDomain gitSyncedEntity) { + return entityInOtherArtifact.get(gitSyncedEntity.getGitSyncId()); + } else { + return entity; + } } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCE.java index 4f6f74d566..7c66c89061 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCE.java @@ -83,11 +83,11 @@ public interface ImportServiceCE { List entitiesToImport); Mono restoreSnapshot( - String workspaceId, String artifactId, String branchName, ArtifactExchangeJson artifactExchangeJson); + String workspaceId, String branchedArtifactId, ArtifactExchangeJson artifactExchangeJson); Mono getArtifactImportDTO( String workspaceId, String artifactId, Artifact importableArtifact, ArtifactType artifactType); Mono> findDatasourceByArtifactId( - String workspaceId, String defaultArtifactId, ArtifactType artifactType); + String workspaceId, String baseArtifactId, ArtifactType artifactType); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java index ca662a3b2d..0f3c5095fe 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java @@ -188,13 +188,7 @@ public class ImportServiceCEImpl implements ImportServiceCE { Set userPermissionGroup = tuple2.getT1(); ImportArtifactPermissionProvider permissionProvider = tuple2.getT2(); return importArtifactInWorkspace( - workspaceId, - artifactExchangeJson, - null, - null, - false, - permissionProvider, - userPermissionGroup); + workspaceId, artifactExchangeJson, null, false, permissionProvider, userPermissionGroup); }); } @@ -242,7 +236,6 @@ public class ImportServiceCEImpl implements ImportServiceCE { workspaceId, artifactExchangeJson, artifactId, - null, false, permissionProvider, userPermissionGroup); @@ -289,7 +282,6 @@ public class ImportServiceCEImpl implements ImportServiceCE { workspaceId, artifactExchangeJson, artifactId, - branchName, false, artifactPermissionProvider, userPermissionGroup); @@ -298,7 +290,7 @@ public class ImportServiceCEImpl implements ImportServiceCE { @Override public Mono restoreSnapshot( - String workspaceId, String artifactId, String branchName, ArtifactExchangeJson artifactExchangeJson) { + String workspaceId, String branchedArtifactId, ArtifactExchangeJson artifactExchangeJson) { /** * Like Git, restore snapshot is a system level operation. So, we're not checking for any permissions here. @@ -318,8 +310,7 @@ public class ImportServiceCEImpl implements ImportServiceCE { return importArtifactInWorkspace( workspaceId, artifactExchangeJson, - artifactId, - branchName, + branchedArtifactId, false, importArtifactPermissionProvider, userPermissionGroup); @@ -365,7 +356,6 @@ public class ImportServiceCEImpl implements ImportServiceCE { workspaceId, artifactExchangeJson, artifactId, - branchName, true, contextPermissionProvider, userPermissionGroup); @@ -401,24 +391,22 @@ public class ImportServiceCEImpl implements ImportServiceCE { * * @param workspaceId The identifier for the destination workspace. * @param artifactExchangeJson The application resource containing necessary information for importing the application. - * @param artifactId The context identifier of the application that needs to be saved with the updated resources. - * @param branchName The name of the branch of the artifact with the specified artifactId. + * @param branchedArtifactId The context identifier of the application that needs to be saved with the updated resources. * @param appendToArtifact Indicates whether artifactExchangeJson will be appended to the existing application or not. * @return The updated artifact stored in MongoDB. */ private Mono importArtifactInWorkspace( String workspaceId, ArtifactExchangeJson artifactExchangeJson, - String artifactId, - String branchName, + String branchedArtifactId, boolean appendToArtifact, ImportArtifactPermissionProvider permissionProvider, Set permissionGroups) { - ArtifactBasedImportService contextBasedImportService = + ArtifactBasedImportService artifactBasedImportService = getArtifactBasedImportService(artifactExchangeJson); - Map artifactSpecificConstantsMap = contextBasedImportService.getArtifactSpecificConstantsMap(); + Map artifactSpecificConstantsMap = artifactBasedImportService.getArtifactSpecificConstantsMap(); String artifactContextString = artifactSpecificConstantsMap.get(FieldName.ARTIFACT_CONTEXT); @@ -444,15 +432,16 @@ public class ImportServiceCEImpl implements ImportServiceCE { ImportingMetaDTO importingMetaDTO = new ImportingMetaDTO( workspaceId, artifactContextString, - artifactId, - branchName, + branchedArtifactId, + null, + new ArrayList<>(), appendToArtifact, false, permissionProvider, permissionGroups); MappedImportableResourcesDTO mappedImportableResourcesDTO = new MappedImportableResourcesDTO(); - contextBasedImportService.syncClientAndSchemaVersion(importedDoc); + artifactBasedImportService.syncClientAndSchemaVersion(importedDoc); Mono workspaceMono = workspaceService .findById(workspaceId, permissionProvider.getRequiredPermissionOnTargetWorkspace()) @@ -471,9 +460,18 @@ public class ImportServiceCEImpl implements ImportServiceCE { // Start the stopwatch to log the execution time Stopwatch stopwatch = new Stopwatch(AnalyticsEvents.IMPORT.getEventName()); + // Get a list of all branched application ids that will be used to find existing synced entities for all + // branch aware resources getting imported + Mono> branchedArtifactIdsMono = Mono.justOrEmpty(branchedArtifactId) + .flatMap(branchedArtifactId1 -> artifactBasedImportService + .getBranchedArtifactIdsByBranchedArtifactId(branchedArtifactId1) + .collectList()) + .switchIfEmpty(Mono.just(List.of())) + .doOnNext(importingMetaDTO::setBranchedArtifactIds); + // this would import customJsLibs for all type of artifacts Mono artifactSpecificImportableEntities = - contextBasedImportService.generateArtifactSpecificImportableEntities( + artifactBasedImportService.generateArtifactSpecificImportableEntities( importedDoc, importingMetaDTO, mappedImportableResourcesDTO); /* @@ -482,8 +480,8 @@ public class ImportServiceCEImpl implements ImportServiceCE { transactions which will lead to NoSuchTransaction exception. */ final Mono importableArtifactMono = workspaceMono - .then(Mono.defer(() -> artifactSpecificImportableEntities)) - .then(Mono.defer(() -> contextBasedImportService.updateAndSaveArtifactInContext( + .then(Mono.defer(() -> Mono.when(branchedArtifactIdsMono, artifactSpecificImportableEntities))) + .then(Mono.defer(() -> artifactBasedImportService.updateAndSaveArtifactInContext( importedDoc.getArtifact(), importingMetaDTO, mappedImportableResourcesDTO, currUserMono))) .cache(); @@ -496,8 +494,8 @@ public class ImportServiceCEImpl implements ImportServiceCE { importedDoc))) .then(importableArtifactMono) .flatMap(importableArtifact -> updateImportableEntities( - contextBasedImportService, importableArtifact, mappedImportableResourcesDTO, importingMetaDTO)) - .flatMap(importableArtifact -> updateImportableArtifact(contextBasedImportService, importableArtifact)) + artifactBasedImportService, importableArtifact, mappedImportableResourcesDTO, importingMetaDTO)) + .flatMap(importableArtifact -> updateImportableArtifact(artifactBasedImportService, importableArtifact)) .onErrorResume(throwable -> { String errorMessage = ImportExportUtils.getErrorMessage(throwable); log.error("Error importing {}. Error: {}", artifactContextString, errorMessage, throwable); @@ -512,7 +510,7 @@ public class ImportServiceCEImpl implements ImportServiceCE { final Mono resultMono = importMono .flatMap(importableArtifact -> sendImportedContextAnalyticsEvent( - contextBasedImportService, importableArtifact, AnalyticsEvents.IMPORT)) + artifactBasedImportService, importableArtifact, AnalyticsEvents.IMPORT)) .zipWith(currUserMono) .flatMap(tuple -> { Artifact importableArtifact = tuple.getT1(); @@ -734,10 +732,10 @@ public class ImportServiceCEImpl implements ImportServiceCE { @Override public Mono> findDatasourceByArtifactId( - String workspaceId, String defaultArtifactId, ArtifactType artifactType) { + String workspaceId, String baseArtifactId, ArtifactType artifactType) { return getArtifactBasedImportService(artifactType) - .getDatasourceIdSetConsumedInArtifact(defaultArtifactId) + .getDatasourceIdSetConsumedInArtifact(baseArtifactId) .flatMap(datasourceIdSet -> { return datasourceImportableService .getEntitiesPresentInWorkspace(workspaceId) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/artifactbased/ArtifactBasedImportServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/artifactbased/ArtifactBasedImportServiceCE.java index 9839bd2f3f..7dfd1560c6 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/artifactbased/ArtifactBasedImportServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/artifactbased/ArtifactBasedImportServiceCE.java @@ -150,5 +150,7 @@ public interface ArtifactBasedImportServiceCE< */ Map getArtifactSpecificConstantsMap(); - Mono> getDatasourceIdSetConsumedInArtifact(String defaultArtifactId); + Mono> getDatasourceIdSetConsumedInArtifact(String baseArtifactId); + + Flux getBranchedArtifactIdsByBranchedArtifactId(String branchedArtifactId); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCE.java index 88635db077..b7daf9cedd 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceCE.java @@ -11,5 +11,5 @@ public interface PartialImportServiceCE { Mono importResourceInPage( String workspaceId, String applicationId, String pageId, String branchName, Part file); - Mono importBuildingBlock(BuildingBlockDTO buildingBlockDTO, String branchName); + Mono importBuildingBlock(BuildingBlockDTO buildingBlockDTO); } 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 5d1ce78d9e..c29638d3f2 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 @@ -19,6 +19,7 @@ import com.appsmith.server.domains.NewPage; import com.appsmith.server.domains.Plugin; import com.appsmith.server.domains.User; import com.appsmith.server.domains.Workspace; +import com.appsmith.server.dtos.ApplicationImportDTO; import com.appsmith.server.dtos.ApplicationJson; import com.appsmith.server.dtos.BuildingBlockDTO; import com.appsmith.server.dtos.BuildingBlockImportDTO; @@ -30,6 +31,7 @@ import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.ImportArtifactPermissionProvider; import com.appsmith.server.imports.importable.ImportableService; import com.appsmith.server.imports.internal.ImportService; +import com.appsmith.server.imports.internal.artifactbased.ArtifactBasedImportService; import com.appsmith.server.jslibs.base.CustomJSLibService; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; @@ -97,6 +99,8 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { private final ApplicationPageService applicationPageService; private final NewActionService newActionService; private final ActionCollectionService actionCollectionService; + private final ArtifactBasedImportService + applicationImportService; private final DatasourceService datasourceService; private final CustomJSLibService customJSLibService; private final UpdateLayoutService updateLayoutService; @@ -111,8 +115,8 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { .flatMap(artifactExchangeJson -> { if (artifactExchangeJson instanceof ApplicationJson && isImportableResource((ApplicationJson) artifactExchangeJson)) { - return importResourceInPage(workspaceId, applicationId, pageId, branchName, (ApplicationJson) - artifactExchangeJson) + return importResourceInPage( + workspaceId, applicationId, pageId, (ApplicationJson) artifactExchangeJson) .zipWith(currUserMono); } else { return Mono.error( @@ -145,16 +149,9 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { } private Mono importResourceInPage( - String workspaceId, - String applicationId, - String pageId, - String branchName, - ApplicationJson applicationJson) { + String workspaceId, String branchedApplicationId, String branchedPageId, ApplicationJson applicationJson) { MappedImportableResourcesDTO mappedImportableResourcesDTO = new MappedImportableResourcesDTO(); - Mono branchedPageIdMono = - newPageService.findBranchedPageId(branchName, pageId, AclPermission.MANAGE_PAGES); - // Extract file and get App Json Mono partiallyImportedAppMono = getImportApplicationPermissions() .flatMap(permissionProvider -> { @@ -178,8 +175,9 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { ImportingMetaDTO importingMetaDTO = new ImportingMetaDTO( workspaceId, FieldName.APPLICATION, - applicationId, - branchName, + branchedApplicationId, + null, + new ArrayList<>(), false, true, permissionProvider, @@ -187,15 +185,22 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { // Get the Application from DB Mono importedApplicationMono = applicationService - .findByBranchNameAndDefaultApplicationId( - branchName, - applicationId, + .findById( + branchedApplicationId, permissionProvider.getRequiredPermissionOnTargetApplication()) .cache(); + // Get a list of all branched application ids that will be used to find existing synced entities for + // all branch aware resources getting imported + Mono> branchedArtifactIdsMono = applicationImportService + .getBranchedArtifactIdsByBranchedArtifactId(branchedApplicationId) + .collectList() + .doOnNext(importingMetaDTO::setBranchedArtifactIds); + return newPageService - .findByBranchNameAndDefaultPageId(branchName, pageId, AclPermission.MANAGE_PAGES) + .findById(branchedPageId, AclPermission.MANAGE_PAGES) .flatMap(page -> { + importingMetaDTO.setBranchName(page.getBranchName()); Layout layout = page.getUnpublishedPage().getLayouts().get(0); return refactoringService.getAllExistingEntitiesMono( @@ -212,6 +217,7 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { applicationJson.setExportedApplication(application); return Mono.just(applicationJson); }) + .then(branchedArtifactIdsMono) // Import Custom Js Lib and Datasource .then(getApplicationImportableEntities( importingMetaDTO, @@ -221,8 +227,8 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { applicationJson)) .thenReturn("done") // Update the pageName map for actions and action collection - .then(paneNameMapForActionAndActionCollectionInAppJson( - branchedPageIdMono, applicationJson, mappedImportableResourcesDTO)) + .then(pageNameMapForActionAndActionCollectionInAppJson( + branchedPageId, applicationJson, mappedImportableResourcesDTO)) .thenReturn("done") // Import Actions and action collection .then(getActionAndActionCollectionImport( @@ -258,7 +264,7 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { FieldName.UNPUBLISHED_JS_LIBS_IDENTIFIER_IN_APPLICATION_CLASS, application.getUnpublishedCustomJSLibs()); return applicationService - .update(applicationId, fieldNameValueMap, branchName) + .updateByBranchedIdAndFieldsMap(branchedApplicationId, fieldNameValueMap) .then(Mono.just(application)); }) // Update the refactored names of the actions and action collections in the DSL bindings @@ -381,73 +387,65 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { return actionMono.then(actionCollectionMono).then(); } - private Mono paneNameMapForActionAndActionCollectionInAppJson( - Mono branchedPageIdMono, - ApplicationJson applicationJson, - MappedImportableResourcesDTO mappedImportableResourcesDTO) { - return branchedPageIdMono.flatMap( - pageId -> newPageService.findById(pageId, null).flatMap(newPage -> { - String pageName = newPage.getUnpublishedPage().getName(); - // update page name reference with newPage - Map pageNameMap = new HashMap<>(); - pageNameMap.put(pageName, newPage); - mappedImportableResourcesDTO.setContextMap(pageNameMap); + private Mono pageNameMapForActionAndActionCollectionInAppJson( + String pageId, ApplicationJson applicationJson, MappedImportableResourcesDTO mappedImportableResourcesDTO) { + return newPageService.findById(pageId, null).flatMap(newPage -> { + String pageName = newPage.getUnpublishedPage().getName(); + // update page name reference with newPage + Map pageNameMap = new HashMap<>(); + pageNameMap.put(pageName, newPage); + mappedImportableResourcesDTO.setContextMap(pageNameMap); - if (applicationJson.getActionList() == null) { - return Mono.just(pageName); - } + if (applicationJson.getActionList() == null) { + return Mono.just(pageName); + } - 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); - } + 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); + } - String actionName = action.getId().split("_")[1]; - action.setId(pageName + "_" + actionName); - action.setGitSyncId(null); - }); + String actionName = action.getId().split("_")[1]; + action.setId(pageName + "_" + actionName); + action.setGitSyncId(null); + }); - if (applicationJson.getActionCollectionList() == null) { - return Mono.just(pageName); - } - applicationJson.getActionCollectionList().forEach(actionCollection -> { - actionCollection.getUnpublishedCollection().setPageId(pageName); - if (actionCollection.getPublishedCollection() != null) { - actionCollection.getPublishedCollection().setPageId(pageName); - } - String collectionName = actionCollection.getId().split("_")[1]; - actionCollection.setId(pageName + "_" + collectionName); - actionCollection.setGitSyncId(null); - }); - return Mono.just(pageName); - })); + if (applicationJson.getActionCollectionList() == null) { + return Mono.just(pageName); + } + applicationJson.getActionCollectionList().forEach(actionCollection -> { + actionCollection.getUnpublishedCollection().setPageId(pageName); + if (actionCollection.getPublishedCollection() != null) { + actionCollection.getPublishedCollection().setPageId(pageName); + } + String collectionName = actionCollection.getId().split("_")[1]; + actionCollection.setId(pageName + "_" + collectionName); + actionCollection.setGitSyncId(null); + }); + return Mono.just(pageName); + }); } @Override - public Mono importBuildingBlock(BuildingBlockDTO buildingBlockDTO, String branchName) { + public Mono importBuildingBlock(BuildingBlockDTO buildingBlockDTO) { Mono applicationJsonMono = applicationTemplateService.getApplicationJsonFromTemplate(buildingBlockDTO.getTemplateId()); - Mono branchedPageIdMono = - newPageService.findBranchedPageId(branchName, buildingBlockDTO.getPageId(), AclPermission.MANAGE_PAGES); - + Stopwatch processStopwatch = new Stopwatch("Download Content from Cloud service"); return applicationJsonMono.flatMap(applicationJson -> { return this.importResourceInPage( buildingBlockDTO.getWorkspaceId(), buildingBlockDTO.getApplicationId(), buildingBlockDTO.getPageId(), - branchName, applicationJson) - .zipWith(branchedPageIdMono) - .flatMap(tuple -> { - BuildingBlockImportDTO buildingBlockImportDTO = tuple.getT1(); - String branchedPageId = tuple.getT2(); + .flatMap(buildingBlockImportDTO -> { + String branchedPageId = buildingBlockDTO.getPageId(); + processStopwatch.stopAndLogTimeInMillis(); // Fetch layout and get new onPageLoadActions // This data is not present in a client, since these are created // after importing the block @@ -462,7 +460,7 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { datasourceService.getAllWithStorages(params).collectList(); Mono> customJSLibs = customJSLibService.getAllJSLibsInContext( - buildingBlockDTO.getApplicationId(), CreatorContextType.APPLICATION, branchName, false); + buildingBlockDTO.getApplicationId(), CreatorContextType.APPLICATION, false); Mono> actionList = newActionService .getUnpublishedActionsByPageId(branchedPageId, AclPermission.MANAGE_ACTIONS) @@ -470,7 +468,6 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { MultiValueMap params1 = new LinkedMultiValueMap<>(); params1.add(FieldName.PAGE_ID, branchedPageId); - newActionService.getUnpublishedActions(params1, branchName); List newActionNames = applicationJson.getActionList().stream() .map(newAction -> @@ -478,8 +475,7 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { .toList(); return newPageService - .findByBranchNameAndDefaultPageId( - branchName, buildingBlockDTO.getPageId(), AclPermission.MANAGE_PAGES) + .findById(buildingBlockDTO.getPageId(), AclPermission.MANAGE_PAGES) .flatMap(newPage -> { String layoutId = newPage.getUnpublishedPage() .getLayouts() diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceImpl.java index 0a45692b6b..ae9e89e9a8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/partial/PartialImportServiceImpl.java @@ -5,12 +5,16 @@ import com.appsmith.server.actioncollections.base.ActionCollectionService; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.datasources.base.DatasourceService; import com.appsmith.server.domains.ActionCollection; +import com.appsmith.server.domains.Application; import com.appsmith.server.domains.CustomJSLib; import com.appsmith.server.domains.NewAction; import com.appsmith.server.domains.NewPage; import com.appsmith.server.domains.Plugin; +import com.appsmith.server.dtos.ApplicationImportDTO; +import com.appsmith.server.dtos.ApplicationJson; import com.appsmith.server.imports.importable.ImportableService; import com.appsmith.server.imports.internal.ImportService; +import com.appsmith.server.imports.internal.artifactbased.ArtifactBasedImportService; import com.appsmith.server.jslibs.base.CustomJSLibService; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; @@ -38,7 +42,6 @@ import org.springframework.transaction.reactive.TransactionalOperator; @Service @Primary public class PartialImportServiceImpl extends PartialImportServiceCEImpl implements PartialImportService { - public PartialImportServiceImpl( ImportService importService, WorkspaceService workspaceService, @@ -65,6 +68,7 @@ public class PartialImportServiceImpl extends PartialImportServiceCEImpl impleme ApplicationPageService applicationPageService, NewActionService newActionService, ActionCollectionService actionCollectionService, + ArtifactBasedImportService applicationImportService, DatasourceService datasourceService, CustomJSLibService customJSLibService, UpdateLayoutService updateLayoutService, @@ -95,6 +99,7 @@ public class PartialImportServiceImpl extends PartialImportServiceCEImpl impleme applicationPageService, newActionService, actionCollectionService, + applicationImportService, datasourceService, customJSLibService, updateLayoutService, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/base/CustomJSLibServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/base/CustomJSLibServiceCE.java index a98baeb87d..70dc3eabb2 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/base/CustomJSLibServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/base/CustomJSLibServiceCE.java @@ -15,21 +15,19 @@ import java.util.Set; public interface CustomJSLibServiceCE extends CrudService { Mono addJSLibsToContext( - @NotNull String contextId, + @NotNull String branchedContextId, CreatorContextType contextType, Set jsLibs, - String branchName, Boolean isForceInstall); Mono removeJSLibFromContext( - @NotNull String contextId, + @NotNull String branchedContextId, CreatorContextType contextType, @NotNull CustomJSLib jsLib, - String branchName, Boolean isForceRemove); Mono> getAllJSLibsInContext( - @NotNull String contextId, CreatorContextType contextType, String branchName, Boolean isViewMode); + @NotNull String branchedContextId, CreatorContextType contextType, Boolean isViewMode); Mono persistCustomJSLibMetaDataIfDoesNotExistAndGetDTO( CustomJSLib jsLib, Boolean isForceInstall); @@ -41,5 +39,5 @@ public interface CustomJSLibServiceCE extends CrudService { boolean isDryOps); Flux getAllVisibleJSLibsInContext( - @NotNull String contextId, CreatorContextType contextType, String branchName, Boolean isViewMode); + @NotNull String branchedContextId, CreatorContextType contextType, String branchName, Boolean isViewMode); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/base/CustomJSLibServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/base/CustomJSLibServiceCEImpl.java index efdb0859bc..d987fae697 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/base/CustomJSLibServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/base/CustomJSLibServiceCEImpl.java @@ -44,10 +44,9 @@ public class CustomJSLibServiceCEImpl extends BaseService addJSLibsToContext( - @NotNull String contextId, + @NotNull String branchedContextId, CreatorContextType contextType, @NotNull Set jsLibs, - String branchName, Boolean isForceInstall) { ContextBasedJsLibService contextBasedService = getContextBasedService(contextType); @@ -55,7 +54,7 @@ public class CustomJSLibServiceCEImpl extends BaseService persistCustomJSLibMetaDataIfDoesNotExistAndGetDTO(jsLib, isForceInstall)) .collect(Collectors.toSet()); return contextBasedService - .getAllVisibleJSLibContextDTOFromContext(contextId, branchName, false) + .getAllVisibleJSLibContextDTOFromContext(branchedContextId, false) .zipWith(persistedJsLibsMono) .map(tuple -> { /* @@ -69,7 +68,7 @@ public class CustomJSLibServiceCEImpl extends BaseService - contextBasedService.updateJsLibsInContext(contextId, branchName, updatedJSLibDTOSet)) + contextBasedService.updateJsLibsInContext(branchedContextId, updatedJSLibDTOSet)) .map(count -> count > 0); } @@ -119,14 +118,13 @@ public class CustomJSLibServiceCEImpl extends BaseService removeJSLibFromContext( - @NotNull String contextId, + @NotNull String branchedContextId, CreatorContextType contextType, @NotNull CustomJSLib jsLib, - String branchName, Boolean isForceRemove) { ContextBasedJsLibService contextBasedService = getContextBasedService(contextType); return contextBasedService - .getAllVisibleJSLibContextDTOFromContext(contextId, branchName, false) + .getAllVisibleJSLibContextDTOFromContext(branchedContextId, false) .map(jsLibDTOSet -> { /* TODO: try to convert it into a single update op where reading of list is not required @@ -138,16 +136,16 @@ public class CustomJSLibServiceCEImpl extends BaseService - contextBasedService.updateJsLibsInContext(contextId, branchName, updatedJSLibDTOList)) + contextBasedService.updateJsLibsInContext(branchedContextId, updatedJSLibDTOList)) .map(count -> count > 0); } @Override public Mono> getAllJSLibsInContext( - @NotNull String contextId, CreatorContextType contextType, String branchName, Boolean isViewMode) { + @NotNull String branchedContextId, CreatorContextType contextType, Boolean isViewMode) { ContextBasedJsLibService contextBasedService = getContextBasedService(contextType); return contextBasedService - .getAllVisibleJSLibContextDTOFromContext(contextId, branchName, isViewMode) + .getAllVisibleJSLibContextDTOFromContext(branchedContextId, isViewMode) .flatMapMany(repository::findCustomJsLibsInContext) .collectList() .map(jsLibList -> { @@ -158,10 +156,10 @@ public class CustomJSLibServiceCEImpl extends BaseService getAllVisibleJSLibsInContext( - @NotNull String contextId, CreatorContextType contextType, String branchName, Boolean isViewMode) { + @NotNull String branchedContextId, CreatorContextType contextType, String branchName, Boolean isViewMode) { ContextBasedJsLibService contextBasedService = getContextBasedService(contextType); return contextBasedService - .getAllVisibleJSLibContextDTOFromContext(contextId, branchName, isViewMode) + .getAllVisibleJSLibContextDTOFromContext(branchedContextId, isViewMode) .flatMapMany(repository::findCustomJsLibsInContext); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/context/ContextBasedJsLibServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/context/ContextBasedJsLibServiceCE.java index 3db07fdef1..67eced8cbf 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/context/ContextBasedJsLibServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/context/ContextBasedJsLibServiceCE.java @@ -11,14 +11,13 @@ public interface ContextBasedJsLibServiceCE { /** * Retrieves all the global JS libs associated with this context - * @param contextId - * @param branchName + * + * @param branchedContextId * @param isViewMode * @return */ Mono> getAllVisibleJSLibContextDTOFromContext( - @NotNull String contextId, String branchName, Boolean isViewMode); + @NotNull String branchedContextId, Boolean isViewMode); - Mono updateJsLibsInContext( - String contextId, String branchName, Set customJSLibContextDTOS); + Mono updateJsLibsInContext(String branchedContextId, Set customJSLibContextDTOS); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCE.java index ed625f2185..e556b792cc 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCE.java @@ -14,11 +14,8 @@ import java.util.Set; public interface UpdateLayoutServiceCE { Mono updateLayout(String pageId, String applicationId, String layoutId, Layout layout); - Mono updateLayout( - String defaultPageId, String defaultApplicationId, String layoutId, Layout layout, String branchName); - Mono updateMultipleLayouts( - String defaultApplicationId, String branchName, UpdateMultiplePageLayoutDTO updateMultiplePageLayoutDTO); + String defaultApplicationId, UpdateMultiplePageLayoutDTO updateMultiplePageLayoutDTO); JSONObject unescapeMongoSpecialCharacters(Layout layout); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java index 15119edadb..fa8747b8b9 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java @@ -17,7 +17,6 @@ import com.appsmith.server.dtos.LayoutDTO; import com.appsmith.server.dtos.UpdateMultiplePageLayoutDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.helpers.WidgetSpecificUtils; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.onload.internal.OnLoadExecutablesUtil; @@ -59,7 +58,6 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { private final SessionUserService sessionUserService; private final NewPageService newPageService; private final AnalyticsService analyticsService; - private final ResponseUtils responseUtils; private final PagePermission pagePermission; private final ApplicationService applicationService; @@ -225,29 +223,16 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { }); } - @Override - public Mono updateLayout( - String defaultPageId, String defaultApplicationId, String layoutId, Layout layout, String branchName) { - if (!StringUtils.hasLength(branchName)) { - return updateLayout(defaultPageId, defaultApplicationId, layoutId, layout); - } - return newPageService - .findByBranchNameAndDefaultPageId(branchName, defaultPageId, pagePermission.getEditPermission()) - .flatMap(branchedPage -> - updateLayout(branchedPage.getId(), branchedPage.getApplicationId(), layoutId, layout)) - .map(responseUtils::updateLayoutDTOWithDefaultResources); - } - @Override public Mono updateMultipleLayouts( - String defaultApplicationId, String branchName, UpdateMultiplePageLayoutDTO updateMultiplePageLayoutDTO) { + String baseApplicationId, UpdateMultiplePageLayoutDTO updateMultiplePageLayoutDTO) { List> monoList = new ArrayList<>(); for (UpdateMultiplePageLayoutDTO.UpdatePageLayoutDTO pageLayout : updateMultiplePageLayoutDTO.getPageLayouts()) { final Layout layout = new Layout(); layout.setDsl(pageLayout.getLayout().dsl()); - Mono updatedLayoutMono = this.updateLayout( - pageLayout.getPageId(), defaultApplicationId, pageLayout.getLayoutId(), layout, branchName); + Mono updatedLayoutMono = + this.updateLayout(pageLayout.getPageId(), baseApplicationId, pageLayout.getLayoutId(), layout); monoList.add(updatedLayoutMono); } return Flux.merge(monoList).then(Mono.just(monoList.size())); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceImpl.java index 1d30144e58..46ab98cc21 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceImpl.java @@ -1,7 +1,6 @@ package com.appsmith.server.layouts; import com.appsmith.server.applications.base.ApplicationService; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.onload.internal.OnLoadExecutablesUtil; import com.appsmith.server.services.AnalyticsService; @@ -18,7 +17,6 @@ public class UpdateLayoutServiceImpl extends UpdateLayoutServiceCEImpl implement SessionUserService sessionUserService, NewPageService newPageService, AnalyticsService analyticsService, - ResponseUtils responseUtils, PagePermission pagePermission, ApplicationService applicationService, ObjectMapper objectMapper) { @@ -27,7 +25,6 @@ public class UpdateLayoutServiceImpl extends UpdateLayoutServiceCEImpl implement sessionUserService, newPageService, analyticsService, - responseUtils, pagePermission, applicationService, objectMapper); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java index db5be15202..a56b849744 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java @@ -2,8 +2,8 @@ package com.appsmith.server.migrations; import com.appsmith.external.converters.ISOStringToInstantConverter; import com.appsmith.external.models.BaseDomain; -import com.appsmith.external.models.BranchAwareDomain; import com.appsmith.external.models.Datasource; +import com.appsmith.external.models.GitSyncedDomain; import com.appsmith.external.models.PluginType; import com.appsmith.external.models.Policy; import com.appsmith.server.acl.AclPermission; @@ -109,13 +109,12 @@ public class DatabaseChangelog2 { } public static void doAddIndexesForGit(MongoTemplate mongoTemplate) { - String defaultResources = BranchAwareDomain.Fields.defaultResources; ensureIndexes( mongoTemplate, ActionCollection.class, makeIndex( - defaultResources + "." + FieldName.APPLICATION_ID, - BaseDomain.Fields.gitSyncId, + "defaultResources." + FieldName.APPLICATION_ID, + GitSyncedDomain.Fields.gitSyncId, FieldName.DELETED) .named("defaultApplicationId_gitSyncId_deleted")); @@ -123,8 +122,8 @@ public class DatabaseChangelog2 { mongoTemplate, NewAction.class, makeIndex( - defaultResources + "." + FieldName.APPLICATION_ID, - BaseDomain.Fields.gitSyncId, + "defaultResources." + FieldName.APPLICATION_ID, + GitSyncedDomain.Fields.gitSyncId, FieldName.DELETED) .named("defaultApplicationId_gitSyncId_deleted")); @@ -132,8 +131,8 @@ public class DatabaseChangelog2 { mongoTemplate, NewPage.class, makeIndex( - defaultResources + "." + FieldName.APPLICATION_ID, - BaseDomain.Fields.gitSyncId, + "defaultResources." + FieldName.APPLICATION_ID, + GitSyncedDomain.Fields.gitSyncId, FieldName.DELETED) .named("defaultApplicationId_gitSyncId_deleted")); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration057MoveDRToBaseIds.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration057MoveDRToBaseIds.java new file mode 100644 index 0000000000..2a926cd261 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration057MoveDRToBaseIds.java @@ -0,0 +1,80 @@ +package com.appsmith.server.migrations.db.ce; + +import com.appsmith.external.models.BaseDomain; +import com.appsmith.external.models.BranchAwareDomain; +import com.appsmith.server.domains.ActionCollection; +import com.appsmith.server.domains.NewAction; +import com.appsmith.server.domains.NewPage; +import com.mongodb.client.result.UpdateResult; +import io.mongock.api.annotations.ChangeUnit; +import io.mongock.api.annotations.Execution; +import io.mongock.api.annotations.RollbackExecution; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.aggregation.AggregationUpdate; +import org.springframework.data.mongodb.core.aggregation.Fields; +import org.springframework.data.mongodb.core.query.Query; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; + +import static org.springframework.data.mongodb.core.query.Criteria.where; +import static org.springframework.data.mongodb.core.query.Query.query; + +@Slf4j +@ChangeUnit(order = "057", id = "move-dr-to-base-ids", author = " ") +public class Migration057MoveDRToBaseIds { + + private final MongoTemplate mongoTemplate; + + public Migration057MoveDRToBaseIds(MongoTemplate mongoTemplate) { + this.mongoTemplate = mongoTemplate; + } + + @RollbackExecution + public void rollbackExecution() {} + + @Execution + public void executeMigration() { + + Query findQuery = query(where(BaseDomain.Fields.deletedAt) + .isNull() + .and(BranchAwareDomain.Fields.branchName) + .exists(false)); + + // NewPage + AggregationUpdate moveNewPageDRUpdateQuery = getUpdateDefinition("defaultResources.pageId"); + Mono newPageMono = Mono.fromCallable(() -> { + log.debug("NewPage"); + return mongoTemplate.updateMulti(findQuery, moveNewPageDRUpdateQuery, NewPage.class); + }) + .subscribeOn(Schedulers.boundedElastic()); + + // NewAction + AggregationUpdate moveNewActionDRUpdateQuery = getUpdateDefinition("defaultResources.actionId"); + Mono newActionMono = Mono.fromCallable(() -> { + log.debug("NewAction"); + return mongoTemplate.updateMulti(findQuery, moveNewActionDRUpdateQuery, NewAction.class); + }) + .subscribeOn(Schedulers.boundedElastic()); + + // ActionCollection + AggregationUpdate moveActionCollectionDRUpdateQuery = getUpdateDefinition("defaultResources.collectionId"); + Mono actionCollectionMono = Mono.fromCallable(() -> { + log.debug("ActionCollection"); + return mongoTemplate.updateMulti( + findQuery, moveActionCollectionDRUpdateQuery, ActionCollection.class); + }) + .subscribeOn(Schedulers.boundedElastic()); + + Mono.zip(newPageMono, newActionMono, actionCollectionMono).block(); + } + + @NotNull private AggregationUpdate getUpdateDefinition(String oldBaseIdPath) { + return AggregationUpdate.update() + .set(BranchAwareDomain.Fields.baseId) + .toValueOf(Fields.field(oldBaseIdPath)) + .set(BranchAwareDomain.Fields.branchName) + .toValueOf(Fields.field("defaultResources.branchName")); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCE.java index ec457dc42f..7b2c4b7138 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCE.java @@ -80,8 +80,6 @@ public interface NewActionServiceCE extends CrudService { Flux getActionsForViewMode(String applicationId); - Flux getActionsForViewMode(String defaultApplicationId, String branchName); - ActionViewDTO generateActionViewDTO(NewAction action, ActionDTO actionDTO, boolean viewMode); Mono deleteUnpublishedAction(String id); @@ -129,13 +127,11 @@ public interface NewActionServiceCE extends CrudService { Flux getUnpublishedActionsExceptJs(MultiValueMap params); - Flux getUnpublishedActionsExceptJs(MultiValueMap params, String branchName); + Mono findByBranchNameAndBaseActionId( + String branchName, String baseActionId, Boolean viewMode, AclPermission permission); - Mono findByBranchNameAndDefaultActionId( - String branchName, String defaultActionId, Boolean viewMode, AclPermission permission); - - Mono findBranchedIdByBranchNameAndDefaultActionId( - String branchName, String defaultActionId, AclPermission permission); + Mono findBranchedIdByBranchNameAndBaseActionId( + String branchName, String baseActionId, AclPermission permission); Mono sanitizeAction(NewAction action); @@ -164,8 +160,6 @@ public interface NewActionServiceCE extends CrudService { NewAction generateActionDomain(ActionDTO action); - void updateDefaultResourcesInAction(NewAction newAction); - Mono saveLastEditInformationInParent(ActionDTO actionDTO); Flux findByCollectionIdAndViewMode(String collectionId, boolean viewMode, AclPermission aclPermission); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java index 07999b8dd8..8019ffb716 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceCEImpl.java @@ -2,14 +2,12 @@ package com.appsmith.server.newactions.base; import com.appsmith.external.dtos.ExecutePluginDTO; import com.appsmith.external.dtos.RemoteDatasourceDTO; -import com.appsmith.external.helpers.AppsmithBeanUtils; import com.appsmith.external.helpers.MustacheHelper; import com.appsmith.external.models.ActionConfiguration; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.CreatorContextType; import com.appsmith.external.models.Datasource; import com.appsmith.external.models.DatasourceConfiguration; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.Executable; import com.appsmith.external.models.MustacheBindingToken; import com.appsmith.external.models.PluginType; @@ -21,7 +19,6 @@ import com.appsmith.server.acl.PolicyGenerator; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.constants.FieldName; import com.appsmith.server.datasources.base.DatasourceService; -import com.appsmith.server.defaultresources.DefaultResourcesService; import com.appsmith.server.domains.ActionCollection; import com.appsmith.server.domains.Application; import com.appsmith.server.domains.ApplicationMode; @@ -37,9 +34,7 @@ import com.appsmith.server.dtos.LayoutExecutableUpdateDTO; import com.appsmith.server.dtos.PluginTypeAndCountDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.DefaultResourcesUtils; import com.appsmith.server.helpers.PluginExecutorHelper; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.newactions.helpers.NewActionHelper; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.plugins.base.PluginService; @@ -84,8 +79,6 @@ import java.util.function.Function; import java.util.stream.Collectors; import static com.appsmith.external.constants.spans.ActionSpan.GET_ACTION_REPOSITORY_CALL; -import static com.appsmith.external.constants.spans.ActionSpan.GET_UNPUBLISHED_ACTION; -import static com.appsmith.external.constants.spans.ActionSpan.GET_VIEW_MODE_ACTION; import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNestedNonNullProperties; import static com.appsmith.external.helpers.PluginUtils.setValueSafelyInFormData; import static com.appsmith.server.acl.AclPermission.EXECUTE_DATASOURCES; @@ -114,8 +107,6 @@ public class NewActionServiceCEImpl extends BaseService defaultPluginMap = new HashMap<>(); private final AtomicReference jsTypePluginReference = new AtomicReference<>(); - private final DefaultResourcesService defaultResourcesService; - private final DefaultResourcesService dtoDefaultResourcesService; public NewActionServiceCEImpl( Validator validator, @@ -141,7 +130,6 @@ public class NewActionServiceCEImpl extends BaseService defaultResourcesService, - DefaultResourcesService dtoDefaultResourcesService) { + ObservationRegistry observationRegistry) { super(validator, repository, analyticsService); this.repository = repository; @@ -166,14 +152,11 @@ public class NewActionServiceCEImpl extends BaseService findByIdAndBranchName(String id, String branchName) { - return this.findByBranchNameAndDefaultActionId(branchName, id, false, actionPermission.getReadPermission()) - .map(responseUtils::updateNewActionWithDefaultResources); + return this.findByBranchNameAndBaseActionId(branchName, id, false, actionPermission.getReadPermission()); } @Override @@ -240,12 +226,7 @@ public class NewActionServiceCEImpl extends BaseService create(validatedAction)) .flatMap(createdAction -> { // If the default action is not set then current action will be the default one - if (!StringUtils.hasLength( - createdAction.getDefaultResources().getActionId())) { - createdAction.getDefaultResources().setActionId(createdAction.getId()); + if (!StringUtils.hasLength(createdAction.getBaseId())) { + createdAction.setBaseId(createdAction.getId()); return repository.save(createdAction); } return Mono.just(createdAction); @@ -296,11 +276,6 @@ public class NewActionServiceCEImpl extends BaseService { - DefaultResources defaults = newAction.getDefaultResources(); - if (defaults == null) { - throw new AppsmithException( - AppsmithError.DEFAULT_RESOURCES_UNAVAILABLE, "action", newAction.getId()); - } - actionDTO.getDefaultResources().setActionId(defaults.getActionId()); - actionDTO.getDefaultResources().setApplicationId(defaults.getApplicationId()); // Added this condition to get a value for updatedAt field since createdAt will always be present if (newAction.getUpdatedAt() != null) { actionDTO.setUpdatedAt(newAction.getUpdatedAt()); @@ -804,16 +772,6 @@ public class NewActionServiceCEImpl extends BaseService getActionsForViewMode(String defaultApplicationId, String branchName) { - return applicationService - .findBranchedApplicationId(branchName, defaultApplicationId, applicationPermission.getReadPermission()) - .flatMapMany(this::getActionsForViewMode) - .map(responseUtils::updateActionViewDTOWithDefaultResources) - .name(GET_VIEW_MODE_ACTION) - .tap(Micrometer.observation(observationRegistry)); - } - @Override public Flux getActionsForViewMode(String applicationId) { @@ -831,21 +789,12 @@ public class NewActionServiceCEImpl extends BaseService jsonPathKeys; jsonPathKeys = new HashSet<>(); @@ -1048,29 +997,27 @@ public class NewActionServiceCEImpl extends BaseService branchedPageMono = !StringUtils.hasLength(params.getFirst(FieldName.PAGE_ID)) ? Mono.just(new NewPage()) - : newPageService.findByBranchNameAndDefaultPageId( + : newPageService.findByBranchNameAndBasePageId( branchName, params.getFirst(FieldName.PAGE_ID), pagePermission.getReadPermission()); Mono branchedApplicationMono = !StringUtils.hasLength(params.getFirst(FieldName.APPLICATION_ID)) ? Mono.just(new Application()) - : applicationService.findByBranchNameAndDefaultApplicationId( + : applicationService.findByBranchNameAndBaseApplicationId( branchName, params.getFirst(FieldName.APPLICATION_ID), applicationPermission.getReadPermission()); - return Mono.zip(branchedApplicationMono, branchedPageMono) - .flatMapMany(tuple -> { - String applicationId = tuple.getT1().getId(); - String pageId = tuple.getT2().getId(); - if (!CollectionUtils.isEmpty(params.get(FieldName.PAGE_ID)) && StringUtils.hasLength(pageId)) { - updatedParams.set(FieldName.PAGE_ID, pageId); - } - if (!CollectionUtils.isEmpty(params.get(FieldName.APPLICATION_ID)) - && StringUtils.hasLength(applicationId)) { - updatedParams.set(FieldName.APPLICATION_ID, applicationId); - } - return getUnpublishedActions(updatedParams, includeJsActions); - }) - .map(responseUtils::updateActionDTOWithDefaultResources); + return Mono.zip(branchedApplicationMono, branchedPageMono).flatMapMany(tuple -> { + String applicationId = tuple.getT1().getId(); + String pageId = tuple.getT2().getId(); + if (!CollectionUtils.isEmpty(params.get(FieldName.PAGE_ID)) && StringUtils.hasLength(pageId)) { + updatedParams.set(FieldName.PAGE_ID, pageId); + } + if (!CollectionUtils.isEmpty(params.get(FieldName.APPLICATION_ID)) + && StringUtils.hasLength(applicationId)) { + updatedParams.set(FieldName.APPLICATION_ID, applicationId); + } + return getUnpublishedActions(updatedParams, includeJsActions); + }); } @Override @@ -1098,14 +1045,6 @@ public class NewActionServiceCEImpl extends BaseService !PluginType.JS.equals(actionDTO.getPluginType())); } - @Override - public Flux getUnpublishedActionsExceptJs(MultiValueMap params, String branchName) { - return this.getUnpublishedActions(params, branchName, FALSE) - .filter(actionDTO -> !PluginType.JS.equals(actionDTO.getPluginType())) - .name(GET_UNPUBLISHED_ACTION) - .tap(Micrometer.observation(observationRegistry)); - } - /** * This method is meant to be used to check for any missing or bad values in NewAction object and attempt to fix it. *

@@ -1427,8 +1366,6 @@ public class NewActionServiceCEImpl extends BaseService findByBranchNameAndDefaultActionId( - String branchName, String defaultActionId, Boolean viewMode, AclPermission permission) { - log.debug("Going to find action based on branchName and defaultActionId with id: {} ", defaultActionId); + public Mono findByBranchNameAndBaseActionId( + String branchName, String baseActionId, Boolean viewMode, AclPermission permission) { + log.debug("Going to find action based on branchName and defaultActionId with id: {} ", baseActionId); if (!StringUtils.hasLength(branchName)) { return repository - .findById(defaultActionId, permission) + .findById(baseActionId, permission) .switchIfEmpty(Mono.error( - new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ACTION, defaultActionId))); + new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ACTION, baseActionId))); } return repository - .findByBranchNameAndDefaultActionId(branchName, defaultActionId, viewMode, permission) + .findByBranchNameAndBaseActionId(branchName, baseActionId, viewMode, permission) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.ACTION, defaultActionId + "," + branchName))) + AppsmithError.NO_RESOURCE_FOUND, FieldName.ACTION, baseActionId + "," + branchName))) .flatMap(this::sanitizeAction); } - public Mono findBranchedIdByBranchNameAndDefaultActionId( - String branchName, String defaultActionId, AclPermission permission) { + public Mono findBranchedIdByBranchNameAndBaseActionId( + String branchName, String baseActionId, AclPermission permission) { if (!StringUtils.hasLength(branchName)) { - return Mono.just(defaultActionId); + return Mono.just(baseActionId); } return repository - .findByBranchNameAndDefaultActionId(branchName, defaultActionId, false, permission) + .findByBranchNameAndBaseActionId(branchName, baseActionId, false, permission) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.ACTION, defaultActionId + "," + branchName))) + AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.ACTION, baseActionId + "," + branchName))) .map(NewAction::getId); } @@ -1631,22 +1568,20 @@ public class NewActionServiceCEImpl extends BaseService collectionIds = List.of(savedActionCollectionId, defaultCollectionId); importActionResultDTO .getUnpublishedCollectionIdToActionIdsMap() .getOrDefault(importedActionCollectionId, Map.of()) .forEach((defaultActionId, actionId) -> { - mapsDTO.getUnpublishedActionIdToCollectionIdMap().putIfAbsent(actionId, collectionIds); + mapsDTO.getUnpublishedActionIdToCollectionIdMap() + .putIfAbsent(actionId, savedActionCollectionId); }); importActionResultDTO .getPublishedCollectionIdToActionIdsMap() .getOrDefault(importedActionCollectionId, Map.of()) .forEach((defaultActionId, actionId) -> { - mapsDTO.getPublishedActionIdToCollectionIdMap().putIfAbsent(actionId, collectionIds); + mapsDTO.getPublishedActionIdToCollectionIdMap().putIfAbsent(actionId, savedActionCollectionId); }); actionIds.addAll(mapsDTO.getUnpublishedActionIdToCollectionIdMap().keySet()); @@ -1664,32 +1599,13 @@ public class NewActionServiceCEImpl extends BaseService saveLastEditInformationInParent(ActionDTO actionDTO) { // Do nothing as this is already taken care for actions in the context of page diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceImpl.java index 337773a644..0ad9ce34f0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/base/NewActionServiceImpl.java @@ -1,13 +1,9 @@ package com.appsmith.server.newactions.base; -import com.appsmith.external.models.ActionDTO; import com.appsmith.server.acl.PolicyGenerator; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.datasources.base.DatasourceService; -import com.appsmith.server.defaultresources.DefaultResourcesService; -import com.appsmith.server.domains.NewAction; import com.appsmith.server.helpers.PluginExecutorHelper; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.newactions.helpers.NewActionHelper; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.plugins.base.PluginService; @@ -42,7 +38,6 @@ public class NewActionServiceImpl extends NewActionServiceCEImpl implements NewA ApplicationService applicationService, PolicySolution policySolution, ConfigService configService, - ResponseUtils responseUtils, PermissionGroupService permissionGroupService, NewActionHelper newActionHelper, DatasourcePermission datasourcePermission, @@ -50,9 +45,7 @@ public class NewActionServiceImpl extends NewActionServiceCEImpl implements NewA PagePermission pagePermission, ActionPermission actionPermission, EntityValidationService entityValidationService, - ObservationRegistry observationRegistry, - DefaultResourcesService defaultResourcesService, - DefaultResourcesService dtoDefaultResourcesService) { + ObservationRegistry observationRegistry) { super( validator, repository, @@ -65,7 +58,6 @@ public class NewActionServiceImpl extends NewActionServiceCEImpl implements NewA applicationService, policySolution, configService, - responseUtils, permissionGroupService, newActionHelper, datasourcePermission, @@ -73,8 +65,6 @@ public class NewActionServiceImpl extends NewActionServiceCEImpl implements NewA pagePermission, actionPermission, entityValidationService, - observationRegistry, - defaultResourcesService, - dtoDefaultResourcesService); + observationRegistry); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/clonepage/ActionClonePageServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/clonepage/ActionClonePageServiceCEImpl.java index 3badc59c7f..b609d992c3 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/clonepage/ActionClonePageServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/clonepage/ActionClonePageServiceCEImpl.java @@ -4,7 +4,6 @@ import com.appsmith.external.constants.ActionCreationSourceTypeEnum; import com.appsmith.external.helpers.AppsmithEventContext; import com.appsmith.external.helpers.AppsmithEventContextType; import com.appsmith.external.models.ActionDTO; -import com.appsmith.external.models.DefaultResources; import com.appsmith.server.clonepage.ClonePageServiceCE; import com.appsmith.server.domains.NewAction; import com.appsmith.server.dtos.ClonePageMetaDTO; @@ -30,22 +29,10 @@ public class ActionClonePageServiceCEImpl implements ClonePageServiceCE { // Set new page id in the actionDTO - final DefaultResources clonedPageDefaultResources = - clonePageMetaDTO.getClonedPageDTO().getDefaultResources(); ActionDTO actionDTO = action.getUnpublishedAction(); - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setPageId(clonedPageDefaultResources.getPageId()); - defaultResources.setBranchName(clonedPageDefaultResources.getBranchName()); - defaultResources.setApplicationId(clonedPageDefaultResources.getApplicationId()); - actionDTO.setDefaultResources(defaultResources); + actionDTO.setBranchName(clonePageMetaDTO.getBranchName()); actionDTO.setPageId(clonePageMetaDTO.getClonedPageDTO().getId()); - if (actionDTO.getCollectionId() != null) { - String clonedActionCollectionId = - clonePageMetaDTO.getOldToNewCollectionIds().get(actionDTO.getCollectionId()); - actionDTO.setCollectionId(clonedActionCollectionId); - actionDTO.getDefaultResources().setCollectionId(clonedActionCollectionId); - } /* * - Now create the new action from the template of the source action. * - Use CLONE_PAGE context to make sure that page / application clone quirks are diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/defaultresources/ActionDTODefaultResourcesServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/defaultresources/ActionDTODefaultResourcesServiceCEImpl.java deleted file mode 100644 index 04a84b1439..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/defaultresources/ActionDTODefaultResourcesServiceCEImpl.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.appsmith.server.newactions.defaultresources; - -import com.appsmith.external.models.ActionDTO; -import com.appsmith.external.models.DefaultResources; -import com.appsmith.server.defaultresources.DefaultResourcesServiceCE; -import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; - -@Service -public class ActionDTODefaultResourcesServiceCEImpl implements DefaultResourcesServiceCE { - - @Override - public ActionDTO initialize(ActionDTO domainObject, String branchName, boolean resetExistingValues) { - DefaultResources existingDefaultResources = domainObject.getDefaultResources(); - DefaultResources defaultResources = new DefaultResources(); - - String defaultPageId = domainObject.getPageId(); - String defaultCollectionId = domainObject.getCollectionId(); - - if (existingDefaultResources != null && !resetExistingValues) { - // Check if there are properties to be copied over from existing - if (StringUtils.hasText(existingDefaultResources.getPageId())) { - defaultPageId = existingDefaultResources.getPageId(); - } - if (StringUtils.hasText(existingDefaultResources.getCollectionId())) { - defaultCollectionId = existingDefaultResources.getCollectionId(); - } - } - - defaultResources.setPageId(defaultPageId); - defaultResources.setCollectionId(defaultCollectionId); - - domainObject.setDefaultResources(defaultResources); - return domainObject; - } - - @Override - public ActionDTO setFromOtherBranch(ActionDTO domainObject, ActionDTO defaultDomainObject, String branchName) { - DefaultResources defaultResources = new DefaultResources(); - - defaultResources.setPageId(defaultDomainObject.getDefaultResources().getPageId()); - defaultResources.setCollectionId( - defaultDomainObject.getDefaultResources().getCollectionId()); - - domainObject.setDefaultResources(defaultResources); - return domainObject; - } -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/defaultresources/ActionDTODefaultResourcesServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/defaultresources/ActionDTODefaultResourcesServiceImpl.java deleted file mode 100644 index d0680bf3ec..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/defaultresources/ActionDTODefaultResourcesServiceImpl.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.appsmith.server.newactions.defaultresources; - -import com.appsmith.external.models.ActionDTO; -import com.appsmith.server.defaultresources.DefaultResourcesService; -import org.springframework.stereotype.Service; - -@Service -public class ActionDTODefaultResourcesServiceImpl extends ActionDTODefaultResourcesServiceCEImpl - implements DefaultResourcesService {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/defaultresources/NewActionDefaultResourcesServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/defaultresources/NewActionDefaultResourcesServiceCEImpl.java deleted file mode 100644 index e81dc33acf..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/defaultresources/NewActionDefaultResourcesServiceCEImpl.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.appsmith.server.newactions.defaultresources; - -import com.appsmith.external.models.DefaultResources; -import com.appsmith.server.defaultresources.DefaultResourcesServiceCE; -import com.appsmith.server.domains.NewAction; -import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; - -@Service -public class NewActionDefaultResourcesServiceCEImpl implements DefaultResourcesServiceCE { - - @Override - public NewAction initialize(NewAction domainObject, String branchName, boolean resetExistingValues) { - DefaultResources existingDefaultResources = domainObject.getDefaultResources(); - DefaultResources defaultResources = new DefaultResources(); - - String defaultApplicationId = domainObject.getApplicationId(); - String defaultActionId = domainObject.getId(); - - if (existingDefaultResources != null && !resetExistingValues) { - // Check if there are properties to be copied over from existing - if (StringUtils.hasText(existingDefaultResources.getApplicationId())) { - defaultApplicationId = existingDefaultResources.getApplicationId(); - } - - if (StringUtils.hasText(existingDefaultResources.getActionId())) { - defaultActionId = existingDefaultResources.getActionId(); - } - } - - defaultResources.setActionId(defaultActionId); - defaultResources.setApplicationId(defaultApplicationId); - defaultResources.setBranchName(branchName); - - domainObject.setDefaultResources(defaultResources); - return domainObject; - } - - @Override - public NewAction setFromOtherBranch(NewAction domainObject, NewAction defaultDomainObject, String branchName) { - DefaultResources defaultResources = new DefaultResources(); - - DefaultResources otherDefaultResources = defaultDomainObject.getDefaultResources(); - - defaultResources.setActionId(otherDefaultResources.getActionId()); - defaultResources.setApplicationId(otherDefaultResources.getApplicationId()); - defaultResources.setBranchName(branchName); - - domainObject.setDefaultResources(defaultResources); - return domainObject; - } -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/defaultresources/NewActionDefaultResourcesServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/defaultresources/NewActionDefaultResourcesServiceImpl.java deleted file mode 100644 index 055db5cca3..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/defaultresources/NewActionDefaultResourcesServiceImpl.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.appsmith.server.newactions.defaultresources; - -import com.appsmith.server.defaultresources.DefaultResourcesService; -import com.appsmith.server.domains.NewAction; -import org.springframework.stereotype.Service; - -@Service -public class NewActionDefaultResourcesServiceImpl extends NewActionDefaultResourcesServiceCEImpl - implements DefaultResourcesService {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/NewActionImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/NewActionImportableServiceCEImpl.java index 589215895b..3d87c2fdcb 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/NewActionImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/NewActionImportableServiceCEImpl.java @@ -289,10 +289,9 @@ public class NewActionImportableServiceCEImpl implements ImportableServiceCE> actionsInOtherBranchesMono; if (artifact.getGitArtifactMetadata() != null) { - final String defaultArtifactId = - artifact.getGitArtifactMetadata().getDefaultArtifactId(); actionsInOtherBranchesMono = artifactBasedImportableService - .getExistingResourcesInOtherBranchesFlux(defaultArtifactId, artifact.getId()) + .getExistingResourcesInOtherBranchesFlux( + importingMetaDTO.getBranchedArtifactIds(), artifact.getId()) .filter(newAction -> newAction.getGitSyncId() != null) .collectMap(NewAction::getGitSyncId); } else { @@ -333,7 +332,7 @@ public class NewActionImportableServiceCEImpl implements ImportableServiceCE actionIds = importActionResultDTO .getPublishedCollectionIdToActionIdsMap() .get(publishedAction.getCollectionId()); - actionIds.put(defaultResourcesActionId, newAction.getId()); + actionIds.put(baseActionId, newAction.getId()); } } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/applications/NewActionApplicationImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/applications/NewActionApplicationImportableServiceCEImpl.java index 7608801c32..19212302fa 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/applications/NewActionApplicationImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/applications/NewActionApplicationImportableServiceCEImpl.java @@ -1,9 +1,7 @@ package com.appsmith.server.newactions.importable.applications; import com.appsmith.external.models.ActionDTO; -import com.appsmith.external.models.DefaultResources; import com.appsmith.server.constants.FieldName; -import com.appsmith.server.defaultresources.DefaultResourcesService; import com.appsmith.server.domains.Application; import com.appsmith.server.domains.Artifact; import com.appsmith.server.domains.Context; @@ -13,7 +11,6 @@ import com.appsmith.server.dtos.ImportingMetaDTO; import com.appsmith.server.dtos.MappedImportableResourcesDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.DefaultResourcesUtils; import com.appsmith.server.imports.importable.artifactbased.ArtifactBasedImportableServiceCE; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.repositories.NewActionRepository; @@ -34,8 +31,6 @@ public class NewActionApplicationImportableServiceCEImpl implements ArtifactBasedImportableServiceCE { private final NewActionRepository repository; - private final DefaultResourcesService defaultResourcesService; - private final DefaultResourcesService dtoDefaultResourcesService; private final NewActionService newActionService; @Override @@ -62,19 +57,25 @@ public class NewActionApplicationImportableServiceCEImpl } @Override - public Flux getExistingResourcesInOtherBranchesFlux(String defaultArtifactId, String currentArtifactId) { + public Flux getExistingResourcesInOtherBranchesFlux( + List branchedArtifactIds, String currentArtifactId) { return repository - .findByDefaultApplicationId(defaultArtifactId, Optional.empty()) + .findAllByApplicationIds(branchedArtifactIds, null) .filter(newAction -> !Objects.equals(newAction.getApplicationId(), currentArtifactId)); } + @Override + public void updateArtifactId(NewAction resource, Artifact artifact) { + resource.setApplicationId(artifact.getId()); + } + @Override public Context updateContextInResource( - Object dtoObject, Map contextMap, String fallbackDefaultContextId) { + Object dtoObject, Map contextMap, String fallbackBaseContextId) { ActionDTO actionDTO = (ActionDTO) dtoObject; if (StringUtils.isEmpty(actionDTO.getPageId())) { - actionDTO.setPageId(fallbackDefaultContextId); + actionDTO.setPageId(fallbackBaseContextId); } NewPage parentPage = (NewPage) contextMap.get(actionDTO.getPageId()); @@ -84,63 +85,24 @@ public class NewActionApplicationImportableServiceCEImpl } actionDTO.setPageId(parentPage.getId()); - // Update defaultResources in actionDTO - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setPageId(parentPage.getDefaultResources().getPageId()); - actionDTO.setDefaultResources(defaultResources); - return parentPage; } @Override - public void populateDefaultResources( - ImportingMetaDTO importingMetaDTO, - MappedImportableResourcesDTO mappedImportableResourcesDTO, - Artifact artifact, - NewAction branchedNewAction, - NewAction newAction) { - newAction.setApplicationId(artifact.getId()); - - if (artifact.getGitArtifactMetadata() != null) { - if (branchedNewAction != null) { - defaultResourcesService.setFromOtherBranch( - newAction, branchedNewAction, importingMetaDTO.getBranchName()); - dtoDefaultResourcesService.setFromOtherBranch( - newAction.getUnpublishedAction(), - branchedNewAction.getUnpublishedAction(), - importingMetaDTO.getBranchName()); - } else { - // This is the first action we are saving with given gitSyncId - // in this instance - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setApplicationId( - artifact.getGitArtifactMetadata().getDefaultArtifactId()); - defaultResources.setActionId(newAction.getId()); - defaultResources.setBranchName(importingMetaDTO.getBranchName()); - newAction.setDefaultResources(defaultResources); - } - } else { - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setApplicationId(artifact.getId()); - defaultResources.setActionId(newAction.getId()); - newAction.setDefaultResources(defaultResources); - } - } - - @Override - public void createNewResource(ImportingMetaDTO importingMetaDTO, NewAction newAction, Context defaultContext) { - if (!importingMetaDTO.getPermissionProvider().canCreateAction((NewPage) defaultContext)) { + public void createNewResource(ImportingMetaDTO importingMetaDTO, NewAction newAction, Context baseContext) { + if (!importingMetaDTO.getPermissionProvider().canCreateAction((NewPage) baseContext)) { throw new AppsmithException( - AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.PAGE, ((NewPage) defaultContext).getId()); + AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.PAGE, ((NewPage) baseContext).getId()); } // this will generate the id and other auto generated fields e.g. createdAt newAction.updateForBulkWriteOperation(); - newActionService.generateAndSetActionPolicies((NewPage) defaultContext, newAction); + newActionService.generateAndSetActionPolicies((NewPage) baseContext, newAction); - // create or update default resources for the action - // values already set to defaultResources are kept unchanged - DefaultResourcesUtils.createDefaultIdsOrUpdateWithGivenResourceIds(newAction, importingMetaDTO.getBranchName()); + // create or update base id for the action + // values already set to base id are kept unchanged + newAction.setBaseId(newAction.getBaseIdOrFallback()); + newAction.setBranchName(importingMetaDTO.getBranchName()); // generate gitSyncId if it's not present if (newAction.getGitSyncId() == null) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/applications/NewActionApplicationImportableServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/applications/NewActionApplicationImportableServiceImpl.java index 44a7b3e0fc..dd8c03cd96 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/applications/NewActionApplicationImportableServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/importable/applications/NewActionApplicationImportableServiceImpl.java @@ -1,7 +1,5 @@ package com.appsmith.server.newactions.importable.applications; -import com.appsmith.external.models.ActionDTO; -import com.appsmith.server.defaultresources.DefaultResourcesService; import com.appsmith.server.domains.Application; import com.appsmith.server.domains.NewAction; import com.appsmith.server.imports.importable.artifactbased.ArtifactBasedImportableService; @@ -12,12 +10,8 @@ import org.springframework.stereotype.Service; @Service public class NewActionApplicationImportableServiceImpl extends NewActionApplicationImportableServiceCEImpl implements ArtifactBasedImportableService { - public NewActionApplicationImportableServiceImpl( - NewActionRepository repository, - DefaultResourcesService defaultResourcesService, - DefaultResourcesService dtoDefaultResourcesService, - NewActionService newActionService) { - super(repository, defaultResourcesService, dtoDefaultResourcesService, newActionService); + NewActionRepository repository, NewActionService newActionService) { + super(repository, newActionService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/refactors/JsActionRefactoringServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/refactors/JsActionRefactoringServiceCEImpl.java index 295dc2e794..cf8dbeeb81 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/refactors/JsActionRefactoringServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/refactors/JsActionRefactoringServiceCEImpl.java @@ -18,7 +18,6 @@ import com.appsmith.server.refactors.utils.RefactoringUtils; import com.appsmith.server.solutions.ActionPermission; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.util.StringUtils; import reactor.core.publisher.Mono; import static com.appsmith.external.constants.AnalyticsEvents.REFACTOR_JSACTION; @@ -50,33 +49,27 @@ public class JsActionRefactoringServiceCEImpl implements EntityRefactoringServic } @Override - public Mono updateRefactoredEntity(RefactorEntityNameDTO refactorEntityNameDTO, String branchName) { - ActionCollectionDTO defaultActionCollection = refactorEntityNameDTO.getActionCollection(); + public Mono updateRefactoredEntity(RefactorEntityNameDTO refactorEntityNameDTO) { + ActionCollectionDTO baseActionCollection = refactorEntityNameDTO.getActionCollection(); // Fetch branched action as client only knows about the default action IDs Mono branchedActionMono = newActionService - .findByBranchNameAndDefaultActionId( - branchName, refactorEntityNameDTO.getActionId(), false, actionPermission.getEditPermission()) + .findById(refactorEntityNameDTO.getActionId(), actionPermission.getEditPermission()) .map(branchedAction -> { refactorEntityNameDTO.setActionId(branchedAction.getId()); - defaultActionCollection.setPageId( + baseActionCollection.setPageId( branchedAction.getUnpublishedAction().getPageId()); - defaultActionCollection.setApplicationId(branchedAction.getApplicationId()); + baseActionCollection.setApplicationId(branchedAction.getApplicationId()); return refactorEntityNameDTO; }); Mono branchedCollectionMono; - if (!StringUtils.hasLength(branchName)) { - branchedCollectionMono = actionCollectionService - .findById(defaultActionCollection.getId(), actionPermission.getEditPermission()) - .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.ACL_NO_RESOURCE_FOUND, - FieldName.ACTION_COLLECTION, - defaultActionCollection.getId()))); - } else { - branchedCollectionMono = actionCollectionService.findByBranchNameAndDefaultCollectionId( - branchName, defaultActionCollection.getId(), actionPermission.getEditPermission()); - } + branchedCollectionMono = actionCollectionService + .findById(baseActionCollection.getId(), actionPermission.getEditPermission()) + .switchIfEmpty(Mono.error(new AppsmithException( + AppsmithError.ACL_NO_RESOURCE_FOUND, + FieldName.ACTION_COLLECTION, + baseActionCollection.getId()))); return Mono.zip(branchedActionMono, branchedCollectionMono).flatMap(tuple -> { ActionCollection dbActionCollection = tuple.getT2(); @@ -88,7 +81,7 @@ public class JsActionRefactoringServiceCEImpl implements EntityRefactoringServic // First perform refactor of the action itself final Mono updatedActionMono = - newActionEntityRefactoringService.updateRefactoredEntity(refactorEntityNameDTO, branchName); + newActionEntityRefactoringService.updateRefactoredEntity(refactorEntityNameDTO); Mono updatedActionCollectionMono = actionCollectionService.update(actionCollectionDTO.getId(), dbActionCollection); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/refactors/NewActionRefactoringServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/refactors/NewActionRefactoringServiceCEImpl.java index 71d7f245a1..be47951274 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/refactors/NewActionRefactoringServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/refactors/NewActionRefactoringServiceCEImpl.java @@ -124,10 +124,9 @@ public class NewActionRefactoringServiceCEImpl implements EntityRefactoringServi } @Override - public Mono updateRefactoredEntity(RefactorEntityNameDTO refactorEntityNameDTO, String branchName) { + public Mono updateRefactoredEntity(RefactorEntityNameDTO refactorEntityNameDTO) { return newActionService - .findByBranchNameAndDefaultActionId( - branchName, refactorEntityNameDTO.getActionId(), false, actionPermission.getEditPermission()) + .findById(refactorEntityNameDTO.getActionId(), actionPermission.getEditPermission()) .map(branchedAction -> newActionService.generateActionByViewMode(branchedAction, false)) .flatMap(action -> { action.setName(refactorEntityNameDTO.getNewName()); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCE.java index 007662a109..071ad9342e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCE.java @@ -7,7 +7,6 @@ import com.appsmith.server.domains.Layout; import com.appsmith.server.domains.NewPage; import com.appsmith.server.dtos.ApplicationPagesDTO; import com.appsmith.server.dtos.PageDTO; -import com.appsmith.server.dtos.PageUpdateDTO; import com.appsmith.server.services.CrudService; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -15,7 +14,6 @@ import reactor.core.publisher.Mono; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Optional; public interface NewPageServiceCE extends CrudService { @@ -41,14 +39,11 @@ public interface NewPageServiceCE extends CrudService { Mono deleteAll(); - Mono findApplicationPagesByApplicationIdViewModeAndBranch( - String applicationId, String branchName, Boolean view, boolean markApplicationAsRecentlyAccessed); - Mono findApplicationPages( - String applicationId, String pageId, String branchName, ApplicationMode mode); + String branchedApplicationId, String branchedPageId, ApplicationMode mode); - Mono findApplicationPagesByApplicationIdViewMode( - String applicationId, Boolean view, boolean markApplicationAsRecentlyAccessed); + Mono findApplicationPagesByBranchedApplicationIdAndViewMode( + String branchedApplicationId, Boolean view, boolean markApplicationAsRecentlyAccessed); Layout createDefaultLayout(); @@ -61,8 +56,6 @@ public interface NewPageServiceCE extends CrudService { Mono updatePage(String pageId, PageDTO page); - Mono updatePageByDefaultPageIdAndBranch(String defaultPageId, PageUpdateDTO page, String branchName); - Mono save(NewPage page); Mono archive(NewPage page); @@ -77,20 +70,17 @@ public interface NewPageServiceCE extends CrudService { Mono getNameByPageId(String pageId, boolean isPublishedName); - Mono findByBranchNameAndDefaultPageId(String branchName, String defaultPageId, AclPermission permission); + Mono findByBranchNameAndBasePageId(String branchName, String defaultPageId, AclPermission permission); - Mono findBranchedPageId(String branchName, String defaultPageId, AclPermission permission); + Mono findByBranchNameAndBasePageIdAndApplicationMode( + String branchName, String basePageId, ApplicationMode mode); - Mono findRootApplicationIdFromNewPage(String branchName, String defaultPageId); - - Mono findByGitSyncIdAndDefaultApplicationId( - String defaultApplicationId, String gitSyncId, AclPermission permission); - - Mono findByGitSyncIdAndDefaultApplicationId( - String defaultApplicationId, String gitSyncId, Optional permission); + Mono findBranchedPageId(String branchName, String basePageId, AclPermission permission); Mono publishPages(Collection pageIds, AclPermission permission); + Flux findAllByApplicationIds(List applicationIds, List includedFields); + ApplicationPagesDTO getApplicationPagesDTO(Application application, List newPages, boolean viewMode); Mono createApplicationPagesDTO( diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCEImpl.java index d6382c9166..bb7707bf36 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceCEImpl.java @@ -1,7 +1,6 @@ package com.appsmith.server.newpages.base; import com.appsmith.external.enums.WorkspaceResourceContext; -import com.appsmith.external.models.DefaultResources; import com.appsmith.server.acl.AclPermission; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.constants.FieldName; @@ -13,10 +12,8 @@ import com.appsmith.server.domains.NewPage; import com.appsmith.server.dtos.ApplicationPagesDTO; import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.dtos.PageNameIdDTO; -import com.appsmith.server.dtos.PageUpdateDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.helpers.TextUtils; import com.appsmith.server.repositories.NewPageRepository; import com.appsmith.server.services.AnalyticsService; @@ -43,7 +40,6 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -56,7 +52,6 @@ public class NewPageServiceCEImpl extends BaseService findByIdAndBranchName(String id, String branchName) { - return this.findByBranchNameAndDefaultPageId(branchName, id, pagePermission.getReadPermission()) - .map(responseUtils::updateNewPageWithDefaultResources); + return this.findByBranchNameAndBasePageId(branchName, id, pagePermission.getReadPermission()); } @Override @@ -160,19 +151,15 @@ public class NewPageServiceCEImpl extends BaseService { - if (defaultResources == null) { - return Mono.error(new AppsmithException( - AppsmithError.DEFAULT_RESOURCES_UNAVAILABLE, "page", savedPage.getId())); - } - if (StringUtils.isEmpty(defaultResources.getPageId())) { + if (StringUtils.isEmpty(newPage.getBaseId())) { NewPage updatePage = new NewPage(); - defaultResources.setPageId(savedPage.getId()); - updatePage.setDefaultResources(defaultResources); + updatePage.setBaseId(savedPage.getId()); return super.update(savedPage.getId(), updatePage); } return Mono.just(savedPage); @@ -214,17 +201,17 @@ public class NewPageServiceCEImpl extends BaseService findApplicationPagesByApplicationIdViewMode( - String applicationId, Boolean view, boolean markApplicationAsRecentlyAccessed) { + public Mono findApplicationPagesByBranchedApplicationIdAndViewMode( + String branchedApplicationId, Boolean view, boolean markApplicationAsRecentlyAccessed) { AclPermission permission = Boolean.TRUE.equals(view) ? applicationPermission.getReadPermission() : applicationPermission.getEditPermission(); Mono applicationMono = applicationService - .findById(applicationId, permission) + .findById(branchedApplicationId, permission) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.APPLICATION, applicationId))) + AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.APPLICATION, branchedApplicationId))) .flatMap(application -> { if (!Boolean.TRUE.equals(view)) { return Mono.just(application); @@ -245,7 +232,7 @@ public class NewPageServiceCEImpl extends BaseService { - log.debug("Fetched application data for id: {}", applicationId); + log.debug("Fetched application data for id: {}", branchedApplicationId); if (markApplicationAsRecentlyAccessed) { // add this application and workspace id to the recently used list in UserData return userDataService @@ -300,9 +287,8 @@ public class NewPageServiceCEImpl extends BaseService getApplicationPagesDTO(branchedApplication, newPages, viewMode))) - .map(responseUtils::updateApplicationPagesDTOWithDefaultResources); + return markedRecentlyAccessedMono.then( + Mono.fromCallable(() -> getApplicationPagesDTO(branchedApplication, newPages, viewMode))); } private List getApplicationPages(Application application, boolean viewMode) { @@ -382,12 +368,8 @@ public class NewPageServiceCEImpl extends BaseService findApplicationPagesByApplicationIdViewModeAndBranch( - String defaultApplicationId, String branchName, Boolean view, boolean markApplicationAsRecentlyAccessed) { - AclPermission permission; - if (view) { - permission = applicationPermission.getReadPermission(); - } else { - permission = applicationPermission.getEditPermission(); - } - - return applicationService - .findBranchedApplicationId(branchName, defaultApplicationId, permission) - .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, defaultApplicationId))) - .flatMap(childApplicationId -> findApplicationPagesByApplicationIdViewMode( - childApplicationId, view, markApplicationAsRecentlyAccessed) - .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, childApplicationId)))) - .map(responseUtils::updateApplicationPagesDTOWithDefaultResources); - } - @Override public Mono findByNameAndApplicationIdAndViewMode( String name, String applicationId, AclPermission permission, Boolean view) { @@ -492,15 +454,6 @@ public class NewPageServiceCEImpl extends BaseService updatePageByDefaultPageIdAndBranch( - String defaultPageId, PageUpdateDTO page, String branchName) { - return repository - .findPageByBranchNameAndDefaultPageId(branchName, defaultPageId, pagePermission.getEditPermission()) - .flatMap(newPage -> updatePage(newPage.getId(), page.toPageDTO())) - .map(responseUtils::updatePageDTOWithDefaultResources); - } - @Override public Mono save(NewPage page) { // gitSyncId will be used to sync resource across instances @@ -553,78 +506,67 @@ public class NewPageServiceCEImpl extends BaseService findByBranchNameAndDefaultPageId( - String branchName, String defaultPageId, AclPermission permission) { + public Mono findByBranchNameAndBasePageId(String branchName, String basePageId, AclPermission permission) { - if (!StringUtils.hasText(defaultPageId)) { + if (!StringUtils.hasText(basePageId)) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.PAGE_ID)); } else if (!StringUtils.hasText(branchName)) { - return this.findById(defaultPageId, permission) + return this.findById(basePageId, permission) .switchIfEmpty(Mono.error( - new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, defaultPageId))); + new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, basePageId))); } return repository - .findPageByBranchNameAndDefaultPageId(branchName, defaultPageId, permission) + .findPageByBranchNameAndBasePageId(branchName, basePageId, permission) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, defaultPageId + ", " + branchName))); + AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, basePageId + ", " + branchName))); } @Override - public Mono findBranchedPageId(String branchName, String defaultPageId, AclPermission permission) { - if (!StringUtils.hasText(branchName)) { - if (!StringUtils.hasText(defaultPageId)) { - return Mono.error( - new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.PAGE_ID, defaultPageId)); - } - return Mono.just(defaultPageId); - } - return repository - .findBranchedPageId(branchName, defaultPageId, permission) - .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE_ID, defaultPageId + ", " + branchName))); - } + public Mono findByBranchNameAndBasePageIdAndApplicationMode( + String branchName, String basePageId, ApplicationMode mode) { - @Override - public Mono findRootApplicationIdFromNewPage(String branchName, String defaultPageId) { - Mono getPageMono; - if (!StringUtils.hasLength(branchName)) { - if (!StringUtils.hasLength(defaultPageId)) { - return Mono.error(new AppsmithException(INVALID_PARAMETER, FieldName.PAGE_ID, defaultPageId)); - } - getPageMono = repository - .queryBuilder() - .byId(defaultPageId) - .fields(FieldName.APPLICATION_ID, FieldName.DEFAULT_RESOURCES) - .permission(pagePermission.getReadPermission()) - .one(); + AclPermission permission; + if (ApplicationMode.EDIT.equals(mode)) { + permission = pagePermission.getEditPermission(); } else { - getPageMono = repository.findPageByBranchNameAndDefaultPageId( - branchName, defaultPageId, pagePermission.getReadPermission()); + permission = pagePermission.getReadPermission(); } - return getPageMono + + return this.findByBranchNameAndBasePageId(branchName, basePageId, permission); + } + + @Override + public Mono findBranchedPageId(String branchName, String basePageId, AclPermission permission) { + if (!StringUtils.hasText(branchName)) { + if (!StringUtils.hasText(basePageId)) { + return Mono.error( + new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.PAGE_ID, basePageId)); + } + return Mono.just(basePageId); + } + return repository + .findPageByBranchNameAndBasePageId(branchName, basePageId, permission) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE_ID, defaultPageId + ", " + branchName))) - .map(newPage -> { - log.debug("Retrieved possible application ids for page, picking the appropriate one now"); - if (newPage.getDefaultResources() != null) { - return newPage.getDefaultResources().getApplicationId(); - } else { - return newPage.getApplicationId(); - } - }); + AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE_ID, basePageId + ", " + branchName))) + .map(NewPage::getId); } - // Remove the code - @Override - public Mono findByGitSyncIdAndDefaultApplicationId( - String defaultApplicationId, String gitSyncId, AclPermission permission) { - return repository.findByGitSyncIdAndDefaultApplicationId(defaultApplicationId, gitSyncId, permission); - } + Mono findBranchedApplicationIdFromNewPageId(String branchedPageId) { + Mono getPageMono; + if (!StringUtils.hasLength(branchedPageId)) { + return Mono.error(new AppsmithException(INVALID_PARAMETER, FieldName.PAGE_ID, branchedPageId)); + } + getPageMono = repository + .queryBuilder() + .byId(branchedPageId) + .fields(FieldName.APPLICATION_ID) + .permission(pagePermission.getReadPermission()) + .one(); - @Override - public Mono findByGitSyncIdAndDefaultApplicationId( - String defaultApplicationId, String gitSyncId, Optional permission) { - return repository.findByGitSyncIdAndDefaultApplicationId(defaultApplicationId, gitSyncId, permission); + return getPageMono + .switchIfEmpty(Mono.error( + new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE_ID, branchedPageId))) + .map(NewPage::getApplicationId); } /** @@ -633,22 +575,21 @@ public class NewPageServiceCEImpl extends BaseService findApplicationPages( - String applicationId, String pageId, String branchName, ApplicationMode mode) { + String branchedApplicationId, String branchedPageId, ApplicationMode mode) { boolean isViewMode = (mode == ApplicationMode.PUBLISHED); - if (StringUtils.hasLength(applicationId)) { - return findApplicationPagesByApplicationIdViewModeAndBranch(applicationId, branchName, isViewMode, true); - } else if (StringUtils.hasLength(pageId)) { - return findRootApplicationIdFromNewPage(branchName, pageId) - .flatMap(rootApplicationId -> findApplicationPagesByApplicationIdViewModeAndBranch( - rootApplicationId, branchName, isViewMode, true)); + if (StringUtils.hasLength(branchedApplicationId)) { + return findApplicationPagesByBranchedApplicationIdAndViewMode(branchedApplicationId, isViewMode, true); + } else if (StringUtils.hasLength(branchedPageId)) { + return findBranchedApplicationIdFromNewPageId(branchedPageId) + .flatMap(rootApplicationId -> findApplicationPagesByBranchedApplicationIdAndViewMode( + rootApplicationId, isViewMode, true)); } else { return Mono.error(new AppsmithException( AppsmithError.INVALID_PARAMETER, FieldName.APPLICATION_ID + " or " + FieldName.PAGE_ID)); @@ -660,6 +601,11 @@ public class NewPageServiceCEImpl extends BaseService findAllByApplicationIds(List applicationIds, List includedFields) { + return repository.findAllByApplicationIds(applicationIds, includedFields); + } + @Override public Mono updateDependencyMap(String pageId, Map> dependencyMap, String branchName) { Mono updateResult; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceImpl.java index dfd2ac191c..db08210d0d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/base/NewPageServiceImpl.java @@ -1,7 +1,6 @@ package com.appsmith.server.newpages.base; import com.appsmith.server.applications.base.ApplicationService; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.repositories.NewPageRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.UserDataService; @@ -21,17 +20,14 @@ public class NewPageServiceImpl extends NewPageServiceCEImpl implements NewPageS AnalyticsService analyticsService, ApplicationService applicationService, UserDataService userDataService, - ResponseUtils responseUtils, ApplicationPermission applicationPermission, PagePermission pagePermission) { - super( validator, repository, analyticsService, applicationService, userDataService, - responseUtils, applicationPermission, pagePermission); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/defaultresources/NewPageDefaultResourcesServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/defaultresources/NewPageDefaultResourcesServiceCEImpl.java deleted file mode 100644 index fda825c906..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/defaultresources/NewPageDefaultResourcesServiceCEImpl.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.appsmith.server.newpages.defaultresources; - -import com.appsmith.external.models.DefaultResources; -import com.appsmith.server.defaultresources.DefaultResourcesServiceCE; -import com.appsmith.server.domains.NewPage; -import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; - -@Service -public class NewPageDefaultResourcesServiceCEImpl implements DefaultResourcesServiceCE { - - @Override - public NewPage initialize(NewPage domainObject, String branchName, boolean resetExistingValues) { - DefaultResources existingDefaultResources = domainObject.getDefaultResources(); - DefaultResources defaultResources = new DefaultResources(); - - String defaultApplicationId = domainObject.getApplicationId(); - String defaultPageId = domainObject.getId(); - - if (existingDefaultResources != null && !resetExistingValues) { - // Check if there are properties to be copied over from existing - if (StringUtils.hasText(existingDefaultResources.getApplicationId())) { - defaultApplicationId = existingDefaultResources.getApplicationId(); - } - - if (StringUtils.hasText(existingDefaultResources.getPageId())) { - defaultPageId = existingDefaultResources.getPageId(); - } - } - - defaultResources.setPageId(defaultPageId); - defaultResources.setApplicationId(defaultApplicationId); - defaultResources.setBranchName(branchName); - - domainObject.setDefaultResources(defaultResources); - return domainObject; - } - - @Override - public NewPage setFromOtherBranch(NewPage domainObject, NewPage defaultDomainObject, String branchName) { - DefaultResources defaultResources = new DefaultResources(); - - defaultResources.setPageId(defaultDomainObject.getId()); - defaultResources.setApplicationId(defaultDomainObject.getApplicationId()); - defaultResources.setBranchName(branchName); - - domainObject.setDefaultResources(defaultResources); - return domainObject; - } -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/defaultresources/NewPageDefaultResourcesServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/defaultresources/NewPageDefaultResourcesServiceImpl.java deleted file mode 100644 index 8d3709d3e5..0000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/defaultresources/NewPageDefaultResourcesServiceImpl.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.appsmith.server.newpages.defaultresources; - -import com.appsmith.server.defaultresources.DefaultResourcesService; -import com.appsmith.server.domains.NewPage; -import org.springframework.stereotype.Service; - -@Service -public class NewPageDefaultResourcesServiceImpl extends NewPageDefaultResourcesServiceCEImpl - implements DefaultResourcesService {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/importable/NewPageImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/importable/NewPageImportableServiceCEImpl.java index f518277496..d49690e2d2 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/importable/NewPageImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/importable/NewPageImportableServiceCEImpl.java @@ -1,6 +1,5 @@ package com.appsmith.server.newpages.importable; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.Policy; import com.appsmith.server.constants.FieldName; import com.appsmith.server.constants.ResourceModes; @@ -17,8 +16,6 @@ import com.appsmith.server.dtos.ImportingMetaDTO; import com.appsmith.server.dtos.MappedImportableResourcesDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.DefaultResourcesUtils; -import com.appsmith.server.helpers.ImportArtifactPermissionProvider; import com.appsmith.server.helpers.TextUtils; import com.appsmith.server.imports.importable.ImportableServiceCE; import com.appsmith.server.imports.importable.artifactbased.ArtifactBasedImportableService; @@ -36,12 +33,12 @@ import reactor.util.function.Tuple2; import reactor.util.function.Tuples; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -92,9 +89,7 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE { - if (newPage.getDefaultResources() != null) { - newPage.getDefaultResources().setBranchName(importingMetaDTO.getBranchName()); - } + newPage.setBranchName(importingMetaDTO.getBranchName()); return mapActionAndCollectionIdWithPageLayout( newPage, importActionResultDTO.getActionIdMap(), @@ -173,9 +166,7 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE importedNewPageList, Mono> existingPagesMono, Mono importableArtifactMono, - boolean appendToApp, - String branchName, - ImportArtifactPermissionProvider permissionProvider, + ImportingMetaDTO importingMetaDTO, MappedImportableResourcesDTO mappedImportableResourcesDTO) { return Mono.just(importedNewPageList) .zipWith(existingPagesMono) @@ -183,7 +174,7 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE importedNewPages = objects.getT1(); List existingPages = objects.getT2(); Map newToOldNameMap; - if (appendToApp) { + if (importingMetaDTO.getAppendToArtifact()) { newToOldNameMap = updateNewPagesBeforeMerge(existingPages, importedNewPages); } else { newToOldNameMap = Map.of(); @@ -197,8 +188,7 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE importedNewPages = objects.getT1().getT1(); Map newToOldNameMap = objects.getT1().getT2(); Application application = (Application) objects.getT2(); - return importAndSavePages( - importedNewPages, application, branchName, existingPagesMono, permissionProvider) + return importAndSavePages(importedNewPages, application, importingMetaDTO, existingPagesMono) .collectList() .zipWith(Mono.just(newToOldNameMap)); }) @@ -287,8 +277,7 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE importAndSavePages( List pages, Application application, - String branchName, - Mono> existingPages, - ImportArtifactPermissionProvider permissionProvider) { + ImportingMetaDTO importingMetaDTO, + Mono> existingPages) { Map oldToNewLayoutIds = new HashMap<>(); pages.forEach(newPage -> { @@ -427,10 +413,23 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE { - Map savedPagesGitIdToPageMap = new HashMap<>(); + Mono> pagesInOtherBranchesMono; + if (application.getGitArtifactMetadata() != null) { + pagesInOtherBranchesMono = newPageService + .findAllByApplicationIds(importingMetaDTO.getBranchedArtifactIds(), null) + .filter(newAction -> newAction.getGitSyncId() != null) + .collectMap(NewPage::getGitSyncId) + .cache(); + } else { + pagesInOtherBranchesMono = Mono.just(Collections.emptyMap()); + } + return existingPages + .zipWith(pagesInOtherBranchesMono) + .flatMapMany(pageTuples -> { + List existingSavedPages = pageTuples.getT1(); + Map pagesFromOtherBranches = pageTuples.getT2(); + Map savedPagesGitIdToPageMap = new HashMap<>(); existingSavedPages.stream() .filter(newPage -> !StringUtils.isEmpty(newPage.getGitSyncId())) .forEach(newPage -> savedPagesGitIdToPageMap.put(newPage.getGitSyncId(), newPage)); @@ -444,7 +443,7 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE existingPagePolicy = existingPage.getPolicies(); copyNestedNonNullProperties(newPage, existingPage); // Update branchName - existingPage.getDefaultResources().setBranchName(branchName); + existingPage.setBranchName(importingMetaDTO.getBranchName()); // Recover the deleted state present in DB from imported page existingPage .getUnpublishedPage() @@ -463,7 +462,7 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE { - // This is the first page we are saving with given gitSyncId in this - // instance - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setApplicationId(defaultApplicationId); - defaultResources.setBranchName(branchName); - newPage.setDefaultResources(defaultResources); - return saveNewPageAndUpdateDefaultResources(newPage, branchName); - })) - .flatMap(branchedPage -> { - DefaultResources defaultResources = branchedPage.getDefaultResources(); - // Create new page but keep defaultApplicationId and defaultPageId same for - // both the - // pages - defaultResources.setBranchName(branchName); - newPage.setDefaultResources(defaultResources); - newPage.getUnpublishedPage() - .setDeletedAt(branchedPage - .getUnpublishedPage() - .getDeletedAt()); - newPage.setDeletedAt(branchedPage.getDeletedAt()); - // Set policies from existing branch object - newPage.setPolicies(branchedPage.getPolicies()); - return newPageService.save(newPage); - }); + + if (!pagesFromOtherBranches.containsKey(newPage.getGitSyncId())) { + return saveNewPageAndUpdateBaseId(newPage, importingMetaDTO.getBranchName()); + } + + NewPage branchedPage = pagesFromOtherBranches.get(newPage.getGitSyncId()); + newPage.setBaseId(branchedPage.getBaseId()); + newPage.setBranchName(importingMetaDTO.getBranchName()); + newPage.getUnpublishedPage() + .setDeletedAt(branchedPage + .getUnpublishedPage() + .getDeletedAt()); + newPage.setDeletedAt(branchedPage.getDeletedAt()); + // Set policies from existing branch object + newPage.setPolicies(branchedPage.getPolicies()); + return newPageService.save(newPage); } - return saveNewPageAndUpdateDefaultResources(newPage, branchName); + return saveNewPageAndUpdateBaseId(newPage, importingMetaDTO.getBranchName()); } }); }) @@ -514,13 +499,16 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE saveNewPageAndUpdateDefaultResources(NewPage newPage, String branchName) { + private Mono saveNewPageAndUpdateBaseId(NewPage newPage, String branchName) { NewPage update = new NewPage(); + newPage.setBranchName(branchName); return newPageService.save(newPage).flatMap(page -> { - update.setDefaultResources( - DefaultResourcesUtils.createDefaultIdsOrUpdateWithGivenResourceIds(page, branchName) - .getDefaultResources()); - return newPageService.update(page.getId(), update); + if (StringUtils.isEmpty(page.getBaseId())) { + update.setBaseId(page.getId()); + return newPageService.update(page.getId(), update); + } else { + return Mono.just(page); + } }); } @@ -595,8 +583,8 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE mapActionAndCollectionIdWithPageLayout( NewPage newPage, Map actionIdMap, - Map> unpublishedActionIdToCollectionIdsMap, - Map> publishedActionIdToCollectionIdsMap) { + Map unpublishedActionIdToCollectionIdsMap, + Map publishedActionIdToCollectionIdsMap) { Set layoutOnLoadActionsForPage = getLayoutOnLoadActionsForPage( newPage, actionIdMap, unpublishedActionIdToCollectionIdsMap, publishedActionIdToCollectionIdsMap); @@ -604,13 +592,7 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE { - final String defaultActionId = - newAction.getDefaultResources().getActionId(); if (newPage.getUnpublishedPage().getLayouts() != null) { - final String defaultCollectionId = newAction - .getUnpublishedAction() - .getDefaultResources() - .getCollectionId(); final String collectionId = newAction.getUnpublishedAction().getCollectionId(); @@ -619,39 +601,11 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE onLoadAction.stream() .filter(actionDTO -> StringUtils.equals(actionDTO.getId(), newAction.getId())) .forEach(actionDTO -> { - actionDTO.setDefaultActionId(defaultActionId); - actionDTO.setDefaultCollectionId(defaultCollectionId); actionDTO.setCollectionId(collectionId); })); } }); } - - if (newPage.getPublishedPage() != null - && newPage.getPublishedPage().getLayouts() != null) { - newPage.getPublishedPage().getLayouts().forEach(layout -> { - if (layout.getLayoutOnLoadActions() != null) { - layout.getLayoutOnLoadActions().forEach(onLoadAction -> onLoadAction.stream() - .filter(actionDTO -> StringUtils.equals(actionDTO.getId(), newAction.getId())) - .forEach(actionDTO -> { - actionDTO.setDefaultActionId(defaultActionId); - if (newAction.getPublishedAction() != null - && newAction - .getPublishedAction() - .getDefaultResources() - != null) { - actionDTO.setDefaultCollectionId(newAction - .getPublishedAction() - .getDefaultResources() - .getCollectionId()); - actionDTO.setCollectionId(newAction - .getPublishedAction() - .getCollectionId()); - } - })); - } - }); - } return newAction; }) .collectList() @@ -665,8 +619,8 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE getLayoutOnLoadActionsForPage( NewPage page, Map actionIdMap, - Map> unpublishedActionIdToCollectionIdsMap, - Map> publishedActionIdToCollectionIdsMap) { + Map unpublishedActionIdToCollectionIdsMap, + Map publishedActionIdToCollectionIdsMap) { Set layoutOnLoadActions = new HashSet<>(); if (page.getUnpublishedPage().getLayouts() != null) { @@ -677,11 +631,9 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE refactorEntityName(RefactorEntityNameDTO refactorEntityNameDTO, String branchName); + Mono refactorEntityName(RefactorEntityNameDTO refactorEntityNameDTO); Mono isNameAllowed(String contextId, CreatorContextType contextType, String layoutId, String newName); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceCEImpl.java index ed1b381624..ddaff144ba 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceCEImpl.java @@ -14,7 +14,6 @@ import com.appsmith.server.dtos.RefactorEntityNameDTO; import com.appsmith.server.dtos.RefactoringMetaDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.refactors.entities.EntityRefactoringService; @@ -24,8 +23,6 @@ import com.appsmith.server.solutions.PagePermission; import com.appsmith.server.validations.EntityValidationService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.transaction.reactive.TransactionalOperator; -import org.springframework.util.StringUtils; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -46,13 +43,11 @@ import static com.appsmith.server.helpers.ContextTypeUtils.getDefaultContextIfNu @RequiredArgsConstructor public class RefactoringServiceCEImpl implements RefactoringServiceCE { private final NewPageService newPageService; - private final ResponseUtils responseUtils; private final UpdateLayoutService updateLayoutService; private final ApplicationService applicationService; private final PagePermission pagePermission; private final AnalyticsService analyticsService; private final SessionUserService sessionUserService; - private final TransactionalOperator transactionalOperator; private final EntityValidationService entityValidationService; protected final EntityRefactoringService jsActionEntityRefactoringService; @@ -154,7 +149,7 @@ public class RefactoringServiceCEImpl implements RefactoringServiceCE { } @Override - public Mono refactorEntityName(RefactorEntityNameDTO refactorEntityNameDTO, String branchName) { + public Mono refactorEntityName(RefactorEntityNameDTO refactorEntityNameDTO) { EntityRefactoringService service = getEntityRefactoringService(refactorEntityNameDTO); @@ -177,38 +172,34 @@ public class RefactoringServiceCEImpl implements RefactoringServiceCE { } // Make sure to retrieve correct page id for branched page - Mono contextIdMono = getBranchedContextIdMono(refactorEntityNameDTO, branchName); + String contextId = getBranchedContextId(refactorEntityNameDTO); final Map analyticsProperties = new HashMap<>(); return isValidNameMono - .then(validateAndPrepareAnalyticsForRefactor(refactorEntityNameDTO, contextIdMono, analyticsProperties)) + .then(validateAndPrepareAnalyticsForRefactor(refactorEntityNameDTO, contextId, analyticsProperties)) .flatMap(updatedAnalyticsProperties -> { - return refactorWithoutContext( - refactorEntityNameDTO, branchName, service, updatedAnalyticsProperties) - .map(responseUtils::updateLayoutDTOWithDefaultResources); + return refactorWithoutContext(refactorEntityNameDTO, service, updatedAnalyticsProperties); }); } protected Mono> validateAndPrepareAnalyticsForRefactor( RefactorEntityNameDTO refactorEntityNameDTO, - Mono contextIdMono, + String branchedContextId, Map analyticsProperties) { - return contextIdMono.flatMap(branchedContextId -> validateEntityName(refactorEntityNameDTO, branchedContextId) - .then(prepareAnalyticsProperties(refactorEntityNameDTO, contextIdMono, analyticsProperties))); + return validateEntityName(refactorEntityNameDTO, branchedContextId) + .then(prepareAnalyticsProperties(refactorEntityNameDTO, branchedContextId, analyticsProperties)); } protected Mono> prepareAnalyticsProperties( RefactorEntityNameDTO refactorEntityNameDTO, - Mono contextIdMono, + String branchedContextId, Map analyticsProperties) { - return contextIdMono.flatMap(branchedPageId -> { - refactorEntityNameDTO.setPageId(branchedPageId); - return newPageService.getByIdWithoutPermissionCheck(branchedPageId).map(page -> { - analyticsProperties.put(FieldName.APPLICATION_ID, page.getApplicationId()); - analyticsProperties.put(FieldName.PAGE_ID, refactorEntityNameDTO.getPageId()); - return analyticsProperties; - }); + refactorEntityNameDTO.setPageId(branchedContextId); + return newPageService.getByIdWithoutPermissionCheck(branchedContextId).map(page -> { + analyticsProperties.put(FieldName.APPLICATION_ID, page.getApplicationId()); + analyticsProperties.put(FieldName.PAGE_ID, refactorEntityNameDTO.getPageId()); + return analyticsProperties; }); } @@ -231,10 +222,9 @@ public class RefactoringServiceCEImpl implements RefactoringServiceCE { protected Mono refactorWithoutContext( RefactorEntityNameDTO refactorEntityNameDTO, - String branchName, EntityRefactoringService service, Map analyticsProperties) { - return service.updateRefactoredEntity(refactorEntityNameDTO, branchName) + return service.updateRefactoredEntity(refactorEntityNameDTO) .then(Mono.defer(() -> this.refactorName(refactorEntityNameDTO))) .flatMap(tuple2 -> { AnalyticsEvents event = service.getRefactorAnalyticsEvent(refactorEntityNameDTO.getEntityType()); @@ -253,14 +243,8 @@ public class RefactoringServiceCEImpl implements RefactoringServiceCE { }; } - protected Mono getBranchedContextIdMono(RefactorEntityNameDTO refactorEntityNameDTO, String branchName) { - if (!StringUtils.hasLength(branchName)) { - return Mono.just(refactorEntityNameDTO.getPageId()); - } - return newPageService - .findByBranchNameAndDefaultPageId( - branchName, refactorEntityNameDTO.getPageId(), pagePermission.getEditPermission()) - .map(newPage -> newPage.getId()); + protected String getBranchedContextId(RefactorEntityNameDTO refactorEntityNameDTO) { + return refactorEntityNameDTO.getPageId(); } private Mono sendRefactorAnalytics( diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceImpl.java index 412f4bf6ca..2de04e3c84 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceImpl.java @@ -4,7 +4,6 @@ import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.domains.ActionCollection; import com.appsmith.server.domains.Layout; import com.appsmith.server.domains.NewAction; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.refactors.entities.EntityRefactoringService; @@ -14,7 +13,6 @@ import com.appsmith.server.solutions.PagePermission; import com.appsmith.server.validations.EntityValidationService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import org.springframework.transaction.reactive.TransactionalOperator; @Service @Slf4j @@ -22,13 +20,11 @@ public class RefactoringServiceImpl extends RefactoringServiceCEImpl implements public RefactoringServiceImpl( NewPageService newPageService, - ResponseUtils responseUtils, UpdateLayoutService updateLayoutService, ApplicationService applicationService, PagePermission pagePermission, AnalyticsService analyticsService, SessionUserService sessionUserService, - TransactionalOperator transactionalOperator, EntityValidationService entityValidationService, EntityRefactoringService jsActionEntityRefactoringService, EntityRefactoringService newActionEntityRefactoringService, @@ -36,13 +32,11 @@ public class RefactoringServiceImpl extends RefactoringServiceCEImpl implements EntityRefactoringService widgetEntityRefactoringService) { super( newPageService, - responseUtils, updateLayoutService, applicationService, pagePermission, analyticsService, sessionUserService, - transactionalOperator, entityValidationService, jsActionEntityRefactoringService, newActionEntityRefactoringService, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/entities/EntityRefactoringServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/entities/EntityRefactoringServiceCE.java index 7a42f55495..cdcc252617 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/entities/EntityRefactoringServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/entities/EntityRefactoringServiceCE.java @@ -20,7 +20,7 @@ public interface EntityRefactoringServiceCE { Mono refactorReferencesInExistingEntities( RefactorEntityNameDTO refactorEntityNameDTO, RefactoringMetaDTO refactoringMetaDTO); - Mono updateRefactoredEntity(RefactorEntityNameDTO refactorEntityNameDTO, String branchName); + Mono updateRefactoredEntity(RefactorEntityNameDTO refactorEntityNameDTO); default Flux getExistingEntityNames( String contextId, CreatorContextType contextType, String layoutId, boolean viewMode) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/BaseAppsmithRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/BaseAppsmithRepositoryCEImpl.java index fef9c8d18e..d67e7340e1 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/BaseAppsmithRepositoryCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/BaseAppsmithRepositoryCEImpl.java @@ -129,16 +129,16 @@ public abstract class BaseAppsmithRepositoryCEImpl { return queryBuilder().byId(id).updateFirst(update); } - public Mono updateFieldByDefaultIdAndBranchName( - String defaultId, - String defaultIdPath, + public Mono updateFieldByBaseIdAndBranchName( + String baseId, + String baseIdPath, Map fieldNameValueMap, String branchName, String branchNamePath, AclPermission permission) { final QueryAllParams builder = queryBuilder(); - builder.criteria(Criteria.where(defaultIdPath).is(defaultId)); + builder.criteria(Criteria.where(baseIdPath).is(baseId)); if (!isBlank(branchName)) { builder.criteria(Criteria.where(branchNamePath).is(branchName)); @@ -150,6 +150,18 @@ public abstract class BaseAppsmithRepositoryCEImpl { return builder.permission(permission).updateFirst(update); } + public Mono updateFieldById( + String id, String idPath, Map fieldNameValueMap, AclPermission permission) { + final QueryAllParams builder = queryBuilder(); + + builder.criteria(Criteria.where(idPath).is(id)); + + Update update = new Update(); + fieldNameValueMap.forEach(update::set); + + return builder.permission(permission).updateFirst(update); + } + protected Mono> getCurrentUserPermissionGroupsIfRequired(AclPermission permission) { return getCurrentUserPermissionGroupsIfRequired(permission, true); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomActionCollectionRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomActionCollectionRepositoryCE.java index a246c399e6..444e8472f9 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomActionCollectionRepositoryCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomActionCollectionRepositoryCE.java @@ -21,22 +21,12 @@ public interface CustomActionCollectionRepositoryCE extends AppsmithRepository findByApplicationIdAndViewMode( String applicationId, boolean viewMode, AclPermission aclPermission); - Flux findAllActionCollectionsByNameDefaultPageIdsViewModeAndBranch( - String name, - List pageIds, - boolean viewMode, - String branchName, - AclPermission aclPermission, - Sort sort); - Flux findByPageId(String pageId, AclPermission permission); Flux findByPageId(String pageId); - Mono findByBranchNameAndDefaultCollectionId( - String branchName, String defaultCollectionId, AclPermission permission); - - Flux findByDefaultApplicationId(String defaultApplicationId, AclPermission permission); + Mono findByBranchNameAndBaseCollectionId( + String branchName, String baseCollectionId, AclPermission permission); Flux findByPageIds(List pageIds, AclPermission permission); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomActionCollectionRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomActionCollectionRepositoryCEImpl.java index 5008d10865..cce3cc3ff8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomActionCollectionRepositoryCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomActionCollectionRepositoryCEImpl.java @@ -1,16 +1,12 @@ package com.appsmith.server.repositories.ce; -import com.appsmith.external.models.BranchAwareDomain; import com.appsmith.external.models.CreatorContextType; -import com.appsmith.external.models.DefaultResources; import com.appsmith.server.acl.AclPermission; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.ActionCollection; -import com.appsmith.server.dtos.ActionCollectionDTO; import com.appsmith.server.helpers.ce.bridge.Bridge; import com.appsmith.server.helpers.ce.bridge.BridgeQuery; import com.appsmith.server.repositories.BaseAppsmithRepositoryImpl; -import org.apache.commons.lang3.StringUtils; import org.springframework.data.domain.Sort; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -18,8 +14,6 @@ import reactor.core.publisher.Mono; import java.util.List; import java.util.Optional; -import static com.appsmith.external.helpers.StringUtils.dotted; - public class CustomActionCollectionRepositoryCEImpl extends BaseAppsmithRepositoryImpl implements CustomActionCollectionRepositoryCE { @@ -74,75 +68,6 @@ public class CustomActionCollectionRepositoryCEImpl extends BaseAppsmithReposito return queryBuilder().criteria(bridgeQuery).permission(aclPermission).all(); } - protected BridgeQuery - getBridgeQueryForFindAllActionCollectionsByNameDefaultPageIdsViewModeAndBranch( - String branchName, boolean viewMode, String name, List pageIds) { - /** - * TODO : This function is called by get(params) to get all actions by params and hence - * only covers criteria of few fields like page id, name, etc. Make this generic to cover - * all possible fields - */ - BridgeQuery bridgeQuery = Bridge.query(); - if (!StringUtils.isEmpty(branchName)) { - bridgeQuery.equal(ActionCollection.Fields.defaultResources_branchName, branchName); - } - - // Fetch published actions - if (Boolean.TRUE.equals(viewMode)) { - - if (name != null) { - bridgeQuery.equal(ActionCollection.Fields.publishedCollection_name, name); - } - - if (pageIds != null && !pageIds.isEmpty()) { - String pageIdFieldPath = dotted( - ActionCollection.Fields.publishedCollection, - ActionCollectionDTO.Fields.defaultResources, - DefaultResources.Fields.pageId); - bridgeQuery.in(pageIdFieldPath, pageIds); - } - } - // Fetch unpublished actions - else { - if (name != null) { - bridgeQuery.equal(ActionCollection.Fields.unpublishedCollection_name, name); - } - - if (pageIds != null && !pageIds.isEmpty()) { - String pageIdFieldPath = dotted( - ActionCollection.Fields.unpublishedCollection, - ActionCollectionDTO.Fields.defaultResources, - DefaultResources.Fields.pageId); - bridgeQuery.in(pageIdFieldPath, pageIds); - } - - // In case an action has been deleted in edit mode, but still exists in deployed mode, NewAction object - // would exist. To handle this, only fetch non-deleted actions - bridgeQuery.isNull(ActionCollection.Fields.unpublishedCollection_deletedAt); - } - - return bridgeQuery; - } - - @Override - public Flux findAllActionCollectionsByNameDefaultPageIdsViewModeAndBranch( - String name, - List pageIds, - boolean viewMode, - String branchName, - AclPermission aclPermission, - Sort sort) { - BridgeQuery criteriaList = - this.getBridgeQueryForFindAllActionCollectionsByNameDefaultPageIdsViewModeAndBranch( - branchName, viewMode, name, pageIds); - - return queryBuilder() - .criteria(criteriaList) - .permission(aclPermission) - .sort(sort) - .all(); - } - @Override public Flux findByPageId(String pageId, AclPermission aclPermission) { String unpublishedPage = ActionCollection.Fields.unpublishedCollection_pageId; @@ -160,24 +85,15 @@ public class CustomActionCollectionRepositoryCEImpl extends BaseAppsmithReposito } @Override - public Mono findByBranchNameAndDefaultCollectionId( - String branchName, String defaultCollectionId, AclPermission permission) { + public Mono findByBranchNameAndBaseCollectionId( + String branchName, String baseCollectionId, AclPermission permission) { final BridgeQuery bq = Bridge.equal( - ActionCollection.Fields.defaultResources_collectionId, defaultCollectionId) - .equal(ActionCollection.Fields.defaultResources_branchName, branchName); + ActionCollection.Fields.baseId, baseCollectionId) + .equal(ActionCollection.Fields.branchName, branchName); return queryBuilder().criteria(bq).permission(permission).one(); } - @Override - public Flux findByDefaultApplicationId(String defaultApplicationId, AclPermission permission) { - BridgeQuery query = Bridge.equal( - BranchAwareDomain.Fields.defaultResources_applicationId, defaultApplicationId) - .isNull(ActionCollection.Fields.unpublishedCollection_deletedAt); - - return queryBuilder().criteria(query).permission(permission).all(); - } - @Override public Flux findByPageIds(List pageIds, AclPermission permission) { BridgeQuery pageIdCriteria = diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomApplicationRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomApplicationRepositoryCE.java index e9f1f3ad38..33d45af9ec 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomApplicationRepositoryCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomApplicationRepositoryCE.java @@ -33,25 +33,25 @@ public interface CustomApplicationRepositoryCE extends AppsmithRepository findByClonedFromApplicationId(String applicationId, AclPermission permission); - Mono addPageToApplication(String applicationId, String pageId, boolean isDefault, String defaultPageId); + Mono addPageToApplication(String applicationId, String pageId, boolean isDefault, String basePageId); Mono setPages(String applicationId, List pages); Mono setDefaultPage(String applicationId, String pageId); - Mono getApplicationByGitBranchAndDefaultApplicationId( - String defaultApplicationId, String branchName, Optional permission); + Mono getApplicationByGitBranchAndBaseApplicationId( + String baseApplicationId, String branchName, Optional permission); - Mono getApplicationByGitBranchAndDefaultApplicationId( - String defaultApplicationId, String branchName, AclPermission aclPermission); + Mono getApplicationByGitBranchAndBaseApplicationId( + String baseApplicationId, String branchName, AclPermission aclPermission); - Mono getApplicationByGitBranchAndDefaultApplicationId( - String defaultApplicationId, + Mono getApplicationByGitBranchAndBaseApplicationId( + String baseApplicationId, List projectionFieldNames, String branchName, AclPermission aclPermission); - Flux getApplicationByGitDefaultApplicationId(String defaultApplicationId, AclPermission permission); + Flux getApplicationByGitBaseApplicationId(String baseApplicationId, AclPermission permission); Mono setAppTheme( String applicationId, String editModeThemeId, String publishedModeThemeId, AclPermission aclPermission); @@ -60,15 +60,10 @@ public interface CustomApplicationRepositoryCE extends AppsmithRepository getGitConnectedApplicationByWorkspaceId(String workspaceId); - Mono getApplicationByDefaultApplicationIdAndDefaultBranch(String defaultApplicationId); + Mono getApplicationByBaseApplicationIdAndDefaultBranch(String baseApplicationId); - Mono updateFieldByDefaultIdAndBranchName( - String defaultId, - String defaultIdPath, - Map fieldNameValueMap, - String branchName, - String branchNamePath, - AclPermission permission); + Mono updateFieldById( + String id, String idPath, Map fieldNameValueMap, AclPermission permission); Mono countByNameAndWorkspaceId(String applicationName, String workspaceId, AclPermission permission); @@ -81,4 +76,9 @@ public interface CustomApplicationRepositoryCE extends AppsmithRepository unprotectAllBranches(String applicationId, AclPermission permission); Mono protectBranchedApplications(String applicationId, List branchNames, AclPermission permission); + + Flux findBranchedApplicationIdsByBaseApplicationId(String baseApplicationId); + + Flux findAllBranchedApplicationIdsByBranchedApplicationId( + String branchedApplicationId, AclPermission permission); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomApplicationRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomApplicationRepositoryCEImpl.java index 240038387c..fa4b56c351 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomApplicationRepositoryCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomApplicationRepositoryCEImpl.java @@ -85,10 +85,10 @@ public class CustomApplicationRepositoryCEImpl extends BaseAppsmithRepositoryImp @Override public Mono addPageToApplication( - String applicationId, String pageId, boolean isDefault, String defaultPageId) { + String applicationId, String pageId, boolean isDefault, String basePageId) { final ApplicationPage applicationPage = new ApplicationPage(); applicationPage.setIsDefault(isDefault); - applicationPage.setDefaultPageId(defaultPageId); + applicationPage.setDefaultPageId(basePageId); applicationPage.setId(pageId); return queryBuilder() .byId(applicationId) @@ -120,14 +120,14 @@ public class CustomApplicationRepositoryCEImpl extends BaseAppsmithRepositoryImp @Override @Deprecated - public Mono getApplicationByGitBranchAndDefaultApplicationId( - String defaultApplicationId, String branchName, AclPermission aclPermission) { - return getApplicationByGitBranchAndDefaultApplicationId(defaultApplicationId, null, branchName, aclPermission); + public Mono getApplicationByGitBranchAndBaseApplicationId( + String baseApplicationId, String branchName, AclPermission aclPermission) { + return getApplicationByGitBranchAndBaseApplicationId(baseApplicationId, null, branchName, aclPermission); } @Override - public Mono getApplicationByGitBranchAndDefaultApplicationId( - String defaultApplicationId, + public Mono getApplicationByGitBranchAndBaseApplicationId( + String baseApplicationId, List projectionFieldNames, String branchName, AclPermission aclPermission) { @@ -136,10 +136,9 @@ public class CustomApplicationRepositoryCEImpl extends BaseAppsmithRepositoryImp .criteria(Bridge.or( Bridge.equal( Application.Fields.gitApplicationMetadata_defaultApplicationId, - defaultApplicationId), + baseApplicationId), Bridge.equal( - Application.Fields.gitApplicationMetadata_defaultArtifactId, - defaultApplicationId)) + Application.Fields.gitApplicationMetadata_defaultArtifactId, baseApplicationId)) .equal(Application.Fields.gitApplicationMetadata_branchName, branchName)) .fields(projectionFieldNames) .permission(aclPermission) @@ -147,24 +146,23 @@ public class CustomApplicationRepositoryCEImpl extends BaseAppsmithRepositoryImp } @Override - public Mono getApplicationByGitBranchAndDefaultApplicationId( - String defaultApplicationId, String branchName, Optional aclPermission) { + public Mono getApplicationByGitBranchAndBaseApplicationId( + String baseApplicationId, String branchName, Optional aclPermission) { return queryBuilder() - .criteria(Bridge.equal( - Application.Fields.gitApplicationMetadata_defaultApplicationId, defaultApplicationId) - .equal(Application.Fields.gitApplicationMetadata_branchName, branchName)) + .criteria( + Bridge.equal(Application.Fields.gitApplicationMetadata_defaultApplicationId, baseApplicationId) + .equal(Application.Fields.gitApplicationMetadata_branchName, branchName)) .permission(aclPermission.orElse(null)) .one(); } @Override - public Flux getApplicationByGitDefaultApplicationId( - String defaultApplicationId, AclPermission permission) { + public Flux getApplicationByGitBaseApplicationId(String baseApplicationId, AclPermission permission) { return queryBuilder() - .criteria(Bridge.equal( - Application.Fields.gitApplicationMetadata_defaultApplicationId, defaultApplicationId)) + .criteria( + Bridge.equal(Application.Fields.gitApplicationMetadata_defaultApplicationId, baseApplicationId)) .permission(permission) .all(); } @@ -192,11 +190,11 @@ public class CustomApplicationRepositoryCEImpl extends BaseAppsmithRepositoryImp } @Override - public Mono getApplicationByDefaultApplicationIdAndDefaultBranch(String defaultApplicationId) { + public Mono getApplicationByBaseApplicationIdAndDefaultBranch(String baseApplicationId) { return queryBuilder() - .criteria(Bridge.equal( - Application.Fields.gitApplicationMetadata_defaultApplicationId, defaultApplicationId)) + .criteria( + Bridge.equal(Application.Fields.gitApplicationMetadata_defaultApplicationId, baseApplicationId)) .one(); } @@ -275,4 +273,29 @@ public class CustomApplicationRepositoryCEImpl extends BaseAppsmithRepositoryImp return queryBuilder().criteria(q).permission(permission).updateAll(setProtected); } + + @Override + public Flux findBranchedApplicationIdsByBaseApplicationId(String baseApplicationId) { + + final BridgeQuery q = + Bridge.equal(Application.Fields.gitApplicationMetadata_defaultApplicationId, baseApplicationId); + + return queryBuilder().criteria(q).fields(Application.Fields.id).all().map(application -> application.getId()); + } + + @Override + public Flux findAllBranchedApplicationIdsByBranchedApplicationId( + String branchedApplicationId, AclPermission permission) { + Mono branchedApplicationMono = this.findById(branchedApplicationId, permission); + + return branchedApplicationMono.flatMapMany(application -> { + if (application.getGitArtifactMetadata() != null + && application.getGitArtifactMetadata().getDefaultArtifactId() != null) { + return this.findBranchedApplicationIdsByBaseApplicationId( + application.getGitArtifactMetadata().getDefaultArtifactId()); + } else { + return Flux.just(application.getId()); + } + }); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCE.java index ea4e8221ec..47957edb54 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCE.java @@ -44,10 +44,8 @@ public interface CustomNewActionRepositoryCE extends AppsmithRepository countByDatasourceId(String datasourceId); - Mono findByBranchNameAndDefaultActionId( - String branchName, String defaultActionId, Boolean viewMode, AclPermission permission); - - Flux findByDefaultApplicationId(String defaultApplicationId, Optional permission); + Mono findByBranchNameAndBaseActionId( + String branchName, String baseActionId, Boolean viewMode, AclPermission permission); Flux findByPageIds(List pageIds, AclPermission permission); @@ -74,4 +72,6 @@ public interface CustomNewActionRepositoryCE extends AppsmithRepository findAllPublishedActionsByContextIdAndContextType( String contextId, CreatorContextType contextType, AclPermission permission, boolean includeJs); + + Flux findAllByApplicationIds(List branchedArtifactIds, List includedFields); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCEImpl.java index e2e432661e..1af3a4e16e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewActionRepositoryCEImpl.java @@ -1,6 +1,5 @@ package com.appsmith.server.repositories.ce; -import com.appsmith.external.models.BranchAwareDomain; import com.appsmith.external.models.CreatorContextType; import com.appsmith.external.models.PluginType; import com.appsmith.server.acl.AclPermission; @@ -232,11 +231,10 @@ public class CustomNewActionRepositoryCEImpl extends BaseAppsmithRepositoryImpl< } @Override - public Mono findByBranchNameAndDefaultActionId( - String branchName, String defaultActionId, Boolean viewMode, AclPermission permission) { - final BridgeQuery q = Bridge.equal( - NewAction.Fields.defaultResources_actionId, defaultActionId) - .equal(NewAction.Fields.defaultResources_branchName, branchName); + public Mono findByBranchNameAndBaseActionId( + String branchName, String baseActionId, Boolean viewMode, AclPermission permission) { + final BridgeQuery q = Bridge.equal(NewAction.Fields.baseId, baseActionId) + .equal(NewAction.Fields.branchName, branchName); if (Boolean.FALSE.equals(viewMode)) { // In case an action has been deleted in edit mode, but still exists in deployed mode, NewAction object @@ -329,16 +327,6 @@ public class CustomNewActionRepositoryCEImpl extends BaseAppsmithRepositoryImpl< return q; } - @Override - public Flux findByDefaultApplicationId(String defaultApplicationId, Optional permission) { - final String defaultResources = BranchAwareDomain.Fields.defaultResources; - return queryBuilder() - .criteria(Bridge.equal(NewAction.Fields.defaultResources_applicationId, defaultApplicationId) - .isNull(NewAction.Fields.unpublishedAction_deletedAt)) - .permission(permission.orElse(null)) - .all(); - } - @Override public Mono publishActions(String applicationId, AclPermission permission) { return copyUnpublishedActionToPublishedAction(getCriterionForFindByApplicationId(applicationId), permission); @@ -448,4 +436,12 @@ public class CustomNewActionRepositoryCEImpl extends BaseAppsmithRepositoryImpl< return queryBuilder().criteria(q).permission(permission).all(); } + + @Override + public Flux findAllByApplicationIds(List applicationIds, List includedFields) { + return queryBuilder() + .criteria(Bridge.in(NewAction.Fields.applicationId, applicationIds)) + .fields(includedFields) + .all(); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCE.java index 767137ce38..96bda4c7b9 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCE.java @@ -9,7 +9,6 @@ import reactor.core.publisher.Mono; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Optional; public interface CustomNewPageRepositoryCE extends AppsmithRepository { @@ -29,20 +28,13 @@ public interface CustomNewPageRepositoryCE extends AppsmithRepository { Mono getNameByPageId(String pageId, boolean isPublishedName); - Mono findPageByBranchNameAndDefaultPageId( - String branchName, String defaultPageId, AclPermission permission); + Mono findPageByBranchNameAndBasePageId(String branchName, String basePageId, AclPermission permission); - Mono findByGitSyncIdAndDefaultApplicationId( - String defaultApplicationId, String gitSyncId, AclPermission permission); - - Mono findByGitSyncIdAndDefaultApplicationId( - String defaultApplicationId, String gitSyncId, Optional permission); + Flux findAllByApplicationIds(List branchedArtifactIds, List includedFields); Mono publishPages(Collection pageIds, AclPermission permission); Flux findAllByApplicationIdsWithoutPermission(List applicationIds, List includeFields); - Mono findBranchedPageId(String branchName, String defaultPageId, AclPermission permission); - Mono updateDependencyMap(String pageId, Map> dependencyMap); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCEImpl.java index 53fd6eac4b..e433f2683a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryCEImpl.java @@ -24,7 +24,6 @@ import reactor.core.scheduler.Schedulers; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import static com.appsmith.external.helpers.StringUtils.dotted; @@ -106,8 +105,9 @@ public class CustomNewPageRepositoryCEImpl extends BaseAppsmithRepositoryImpl findAllPageDTOsByIds(List ids, AclPermission aclPermission) { List includedFields = List.of( - FieldName.APPLICATION_ID, - FieldName.DEFAULT_RESOURCES, + NewPage.Fields.applicationId, + NewPage.Fields.baseId, + NewPage.Fields.branchName, NewPage.Fields.policies, NewPage.Fields.unpublishedPage_name, NewPage.Fields.unpublishedPage_icon, @@ -146,18 +146,18 @@ public class CustomNewPageRepositoryCEImpl extends BaseAppsmithRepositoryImpl findPageByBranchNameAndDefaultPageId( - String branchName, String defaultPageId, AclPermission permission) { + public Mono findPageByBranchNameAndBasePageId( + String branchName, String basePageId, AclPermission permission) { final BridgeQuery q = // defaultPageIdCriteria - Bridge.equal(NewPage.Fields.defaultResources_pageId, defaultPageId); + Bridge.equal(NewPage.Fields.baseId, basePageId); if (branchName != null) { // branchCriteria - q.equal(NewPage.Fields.defaultResources_branchName, branchName); + q.equal(NewPage.Fields.branchName, branchName); } else { - q.isNull(NewPage.Fields.defaultResources_branchName); + q.isNull(NewPage.Fields.branchName); } return queryBuilder().criteria(q).permission(permission).one(); @@ -166,8 +166,8 @@ public class CustomNewPageRepositoryCEImpl extends BaseAppsmithRepositoryImpl findBranchedPageId(String branchName, String defaultPageId, AclPermission permission) { final BridgeQuery q = // defaultPageIdCriteria - Bridge.equal(NewPage.Fields.defaultResources_pageId, defaultPageId); - q.equal(NewPage.Fields.defaultResources_branchName, branchName); + Bridge.equal(NewPage.Fields.baseId, defaultPageId); + q.equal(NewPage.Fields.branchName, branchName); return queryBuilder() .criteria(q) @@ -177,27 +177,11 @@ public class CustomNewPageRepositoryCEImpl extends BaseAppsmithRepositoryImpl findByGitSyncIdAndDefaultApplicationId( - String defaultApplicationId, String gitSyncId, AclPermission permission) { - return findByGitSyncIdAndDefaultApplicationId(defaultApplicationId, gitSyncId, Optional.ofNullable(permission)); - } - - @Override - public Mono findByGitSyncIdAndDefaultApplicationId( - String defaultApplicationId, String gitSyncId, Optional permission) { - - // defaultAppIdCriteria - final BridgeQuery q = - Bridge.equal(NewPage.Fields.defaultResources_applicationId, defaultApplicationId); - - if (gitSyncId != null) { - // gitSyncIdCriteria - q.equal(NewPage.Fields.gitSyncId, gitSyncId); - } else { - q.isNull(NewPage.Fields.gitSyncId); - } - - return queryBuilder().criteria(q).permission(permission.orElse(null)).first(); + public Flux findAllByApplicationIds(List applicationIds, List includedFields) { + return queryBuilder() + .criteria(Bridge.in(NewPage.Fields.applicationId, applicationIds)) + .fields(includedFields) + .all(); } @Override diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/searchentities/SearchEntitySolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/searchentities/SearchEntitySolutionCEImpl.java index 7f969ae88a..1d9f1aba4f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/searchentities/SearchEntitySolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/searchentities/SearchEntitySolutionCEImpl.java @@ -5,7 +5,6 @@ import com.appsmith.server.domains.Application; import com.appsmith.server.domains.Workspace; import com.appsmith.server.dtos.SearchEntityDTO; import com.appsmith.server.helpers.GitUtils; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.services.WorkspaceService; import com.appsmith.server.solutions.ApplicationPermission; import com.appsmith.server.solutions.WorkspacePermission; @@ -33,8 +32,6 @@ public class SearchEntitySolutionCEImpl implements SearchEntitySolutionCE { private final ApplicationPermission applicationPermission; - private final ResponseUtils responseUtils; - /** * This method searches for workspaces and applications based on the searchString provided. * The search is performed with contains operator on the name field of the entities and is case-insensitive. @@ -95,7 +92,6 @@ public class SearchEntitySolutionCEImpl implements SearchEntitySolutionCE { return !GitUtils.isApplicationConnectedToGit(application) || GitUtils.isDefaultBranchedApplication(application); }) - .map(responseUtils::updateApplicationWithDefaultResources) .collectList(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/searchentities/SearchEntitySolutionImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/searchentities/SearchEntitySolutionImpl.java index 8157ca1fed..23803bc762 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/searchentities/SearchEntitySolutionImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/searchentities/SearchEntitySolutionImpl.java @@ -1,7 +1,6 @@ package com.appsmith.server.searchentities; import com.appsmith.server.applications.base.ApplicationService; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.services.WorkspaceService; import com.appsmith.server.solutions.ApplicationPermission; import com.appsmith.server.solutions.WorkspacePermission; @@ -14,8 +13,7 @@ public class SearchEntitySolutionImpl extends SearchEntitySolutionCEImpl impleme WorkspaceService workspaceService, ApplicationService applicationService, WorkspacePermission workspacePermission, - ApplicationPermission applicationPermission, - ResponseUtils responseUtils) { - super(workspaceService, applicationService, workspacePermission, applicationPermission, responseUtils); + ApplicationPermission applicationPermission) { + super(workspaceService, applicationService, workspacePermission, applicationPermission); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationPageServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationPageServiceImpl.java index b594e89d97..0a44c4e365 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationPageServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationPageServiceImpl.java @@ -6,11 +6,8 @@ import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.clonepage.ClonePageService; import com.appsmith.server.domains.ActionCollection; import com.appsmith.server.domains.NewAction; -import com.appsmith.server.git.autocommit.helpers.AutoCommitEligibilityHelper; -import com.appsmith.server.git.autocommit.helpers.GitAutoCommitHelper; import com.appsmith.server.helpers.CommonGitFileUtils; import com.appsmith.server.helpers.DSLMigrationUtils; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; @@ -34,13 +31,11 @@ import org.springframework.transaction.reactive.TransactionalOperator; @Service @Slf4j public class ApplicationPageServiceImpl extends ApplicationPageServiceCEImpl implements ApplicationPageService { - public ApplicationPageServiceImpl( WorkspaceService workspaceService, ApplicationService applicationService, SessionUserService sessionUserService, WorkspaceRepository workspaceRepository, - LayoutActionService layoutActionService, UpdateLayoutService updateLayoutService, AnalyticsService analyticsService, PolicyGenerator policyGenerator, @@ -50,7 +45,6 @@ public class ApplicationPageServiceImpl extends ApplicationPageServiceCEImpl imp ActionCollectionService actionCollectionService, CommonGitFileUtils commonGitFileUtils, ThemeService themeService, - ResponseUtils responseUtils, WorkspacePermission workspacePermission, ApplicationPermission applicationPermission, PagePermission pagePermission, @@ -63,8 +57,6 @@ public class ApplicationPageServiceImpl extends ApplicationPageServiceCEImpl imp DatasourceRepository datasourceRepository, DatasourcePermission datasourcePermission, DSLMigrationUtils dslMigrationUtils, - GitAutoCommitHelper gitAutoCommitHelper, - AutoCommitEligibilityHelper autoCommitEligibilityHelper, ClonePageService actionClonePageService, ClonePageService actionCollectionClonePageService) { super( @@ -72,7 +64,6 @@ public class ApplicationPageServiceImpl extends ApplicationPageServiceCEImpl imp applicationService, sessionUserService, workspaceRepository, - layoutActionService, updateLayoutService, analyticsService, policyGenerator, @@ -82,7 +73,6 @@ public class ApplicationPageServiceImpl extends ApplicationPageServiceCEImpl imp actionCollectionService, commonGitFileUtils, themeService, - responseUtils, workspacePermission, applicationPermission, pagePermission, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationSnapshotServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationSnapshotServiceImpl.java index dc51939b37..2e9de1b6e9 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationSnapshotServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationSnapshotServiceImpl.java @@ -2,7 +2,6 @@ package com.appsmith.server.services; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.exports.internal.ExportService; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.imports.internal.ImportService; import com.appsmith.server.repositories.ApplicationSnapshotRepository; import com.appsmith.server.services.ce.ApplicationSnapshotServiceCEImpl; @@ -15,22 +14,19 @@ import org.springframework.stereotype.Service; @Service public class ApplicationSnapshotServiceImpl extends ApplicationSnapshotServiceCEImpl implements ApplicationSnapshotService { - public ApplicationSnapshotServiceImpl( ApplicationSnapshotRepository applicationSnapshotRepository, ApplicationService applicationService, ImportService importService, ExportService exportService, ApplicationPermission applicationPermission, - Gson gson, - ResponseUtils responseUtils) { + Gson gson) { super( applicationSnapshotRepository, applicationService, importService, exportService, applicationPermission, - gson, - responseUtils); + gson); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationTemplateServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationTemplateServiceImpl.java index 4900d1d057..c8d9239030 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationTemplateServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ApplicationTemplateServiceImpl.java @@ -4,7 +4,6 @@ import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.configurations.CloudServicesConfig; import com.appsmith.server.exports.internal.ExportService; import com.appsmith.server.helpers.CacheableTemplateHelper; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.imports.internal.ImportService; import com.appsmith.server.services.ce.ApplicationTemplateServiceCEImpl; import com.appsmith.server.solutions.ApplicationPermission; @@ -26,7 +25,6 @@ public class ApplicationTemplateServiceImpl extends ApplicationTemplateServiceCE AnalyticsService analyticsService, UserDataService userDataService, ApplicationService applicationService, - ResponseUtils responseUtils, ApplicationPermission applicationPermission, ObjectMapper objectMapper, SessionUserService sessionUserService, @@ -37,9 +35,7 @@ public class ApplicationTemplateServiceImpl extends ApplicationTemplateServiceCE importService, exportService, analyticsService, - userDataService, applicationService, - responseUtils, applicationPermission, objectMapper, sessionUserService, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CurlImporterServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CurlImporterServiceImpl.java index 47ed7001d4..4d5c156ba7 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CurlImporterServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CurlImporterServiceImpl.java @@ -1,6 +1,5 @@ package com.appsmith.server.services; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.plugins.base.PluginService; import com.appsmith.server.services.ce.CurlImporterServiceCEImpl; @@ -12,14 +11,12 @@ import org.springframework.stereotype.Service; @Slf4j @Service public class CurlImporterServiceImpl extends CurlImporterServiceCEImpl implements CurlImporterService { - public CurlImporterServiceImpl( PluginService pluginService, LayoutActionService layoutActionService, NewPageService newPageService, - ResponseUtils responseUtils, ObjectMapper objectMapper, PagePermission pagePermission) { - super(pluginService, layoutActionService, newPageService, responseUtils, objectMapper, pagePermission); + super(pluginService, layoutActionService, newPageService, objectMapper, pagePermission); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java index ea11be60b2..1c0737cbc7 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java @@ -1,7 +1,6 @@ package com.appsmith.server.services; import com.appsmith.server.datasources.base.DatasourceService; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; @@ -23,7 +22,6 @@ public class LayoutActionServiceImpl extends LayoutActionServiceCEImpl implement RefactoringService refactoringService, CollectionService collectionService, UpdateLayoutService updateLayoutService, - ResponseUtils responseUtils, DatasourceService datasourceService, PagePermission pagePermission, ActionPermission actionPermission) { @@ -34,7 +32,6 @@ public class LayoutActionServiceImpl extends LayoutActionServiceCEImpl implement refactoringService, collectionService, updateLayoutService, - responseUtils, datasourceService, pagePermission, actionPermission); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutCollectionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutCollectionServiceImpl.java index 426a0f1484..66ac121333 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutCollectionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutCollectionServiceImpl.java @@ -1,7 +1,6 @@ package com.appsmith.server.services; import com.appsmith.server.actioncollections.base.ActionCollectionService; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; @@ -25,7 +24,6 @@ public class LayoutCollectionServiceImpl extends LayoutCollectionServiceCEImpl i ActionCollectionService actionCollectionService, NewActionService newActionService, AnalyticsService analyticsService, - ResponseUtils responseUtils, ActionCollectionRepository actionCollectionRepository, PagePermission pagePermission, ActionPermission actionPermission) { @@ -37,7 +35,6 @@ public class LayoutCollectionServiceImpl extends LayoutCollectionServiceCEImpl i actionCollectionService, newActionService, analyticsService, - responseUtils, actionCollectionRepository, pagePermission, actionPermission); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutServiceImpl.java index 73b9f920cf..23e816e9de 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutServiceImpl.java @@ -1,6 +1,5 @@ package com.appsmith.server.services; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.services.ce.LayoutServiceCEImpl; import com.appsmith.server.solutions.PagePermission; @@ -11,8 +10,7 @@ import org.springframework.stereotype.Service; @Service public class LayoutServiceImpl extends LayoutServiceCEImpl implements LayoutService { - public LayoutServiceImpl( - NewPageService newPageService, ResponseUtils responseUtils, PagePermission pagePermission) { - super(newPageService, responseUtils, pagePermission); + public LayoutServiceImpl(NewPageService newPageService, PagePermission pagePermission) { + super(newPageService, pagePermission); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApiImporterCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApiImporterCE.java index 82a59b2240..ece688a937 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApiImporterCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApiImporterCE.java @@ -7,10 +7,5 @@ import reactor.core.publisher.Mono; public interface ApiImporterCE { Mono importAction( - Object input, - CreatorContextType contextType, - String contextId, - String name, - String workspaceId, - String branchName); + Object input, CreatorContextType contextType, String branchedContextId, String name, String workspaceId); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCE.java index f92cd9d653..b3ea91f970 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCE.java @@ -6,7 +6,6 @@ import com.appsmith.server.domains.ApplicationMode; import com.appsmith.server.domains.NewPage; import com.appsmith.server.domains.User; import com.appsmith.server.dtos.ApplicationPagesDTO; -import com.appsmith.server.dtos.ClonePageMetaDTO; import com.appsmith.server.dtos.PageDTO; import reactor.core.publisher.Mono; @@ -16,38 +15,32 @@ public interface ApplicationPageServiceCE { Mono createPage(PageDTO page); - Mono createPageWithBranchName(PageDTO page, String branchName); - Mono addPageToApplication(Application application, PageDTO page, Boolean isDefault); Mono getPage(NewPage newPage, boolean viewMode); Mono getPage(String pageId, boolean viewMode); - Mono getPageAndMigrateDslByBranchAndDefaultPageId( + Mono getPageAndMigrateDslByBranchAndBasePageId( String defaultPageId, String branchName, boolean viewMode, boolean migrateDsl); Mono createApplication(Application application); Mono createApplication(Application application, String workspaceId); + Mono getPageAndMigrateDslByBranchedPageId(String branchedPageId, boolean viewMode, boolean migrateDsl); + Mono makePageDefault(PageDTO page); Mono makePageDefault(String applicationId, String pageId); - Mono makePageDefault(String defaultApplicationId, String defaultPageId, String branchName); - Mono setApplicationPolicies(Mono userMono, String workspaceId, Application application); Mono deleteApplication(String id); - Mono clonePage(String pageId, ClonePageMetaDTO clonePageMetaDTO); + Mono clonePage(String pageId); - Mono clonePageByDefaultPageIdAndBranch(String defaultPageId, String branchName); - - Mono cloneApplication(String applicationId, String branchName); - - Mono deleteUnpublishedPageByBranchAndDefaultPageId(String defaultPageId, String branchName); + Mono cloneApplication(String branchedApplicationId); Mono deleteUnpublishedPage( String id, @@ -58,13 +51,13 @@ public interface ApplicationPageServiceCE { Mono deleteUnpublishedPage(String id); - Mono publish(String applicationId, boolean isPublishedManually); + Mono publishWithoutPermissionChecks(String branchedApplicationId, boolean isPublishedManually); - Mono publish(String defaultApplicationId, String branchName, boolean isPublishedManually); + Mono publish(String branchedApplicationId, boolean isPublishedManually); void generateAndSetPagePolicies(Application application, PageDTO page); - Mono reorderPage(String applicationId, String pageId, Integer order, String branchName); + Mono reorderPage(String branchedApplicationId, String branchedPageId, Integer order); Mono deleteApplicationByResource(Application application); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java index 45ba0addfa..64332dd6ce 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationPageServiceCEImpl.java @@ -4,7 +4,6 @@ import com.appsmith.external.constants.AnalyticsEvents; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.BaseDomain; import com.appsmith.external.models.Datasource; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.PluginType; import com.appsmith.external.models.Policy; import com.appsmith.server.acl.AclPermission; @@ -37,7 +36,6 @@ import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.CommonGitFileUtils; import com.appsmith.server.helpers.DSLMigrationUtils; import com.appsmith.server.helpers.GitUtils; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.helpers.UserPermissionUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.migrations.ApplicationVersion; @@ -50,7 +48,6 @@ import com.appsmith.server.repositories.NewActionRepository; import com.appsmith.server.repositories.NewPageRepository; import com.appsmith.server.repositories.WorkspaceRepository; import com.appsmith.server.services.AnalyticsService; -import com.appsmith.server.services.LayoutActionService; import com.appsmith.server.services.PermissionGroupService; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.services.WorkspaceService; @@ -82,7 +79,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -99,7 +95,6 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { private final ApplicationService applicationService; private final SessionUserService sessionUserService; private final WorkspaceRepository workspaceRepository; - private final LayoutActionService layoutActionService; private final UpdateLayoutService updateLayoutService; private final AnalyticsService analyticsService; @@ -111,7 +106,6 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { private final ActionCollectionService actionCollectionService; private final CommonGitFileUtils commonGitFileUtils; private final ThemeService themeService; - private final ResponseUtils responseUtils; private final WorkspacePermission workspacePermission; private final ApplicationPermission applicationPermission; private final PagePermission pagePermission; @@ -162,10 +156,8 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { Mono pageMono = applicationMono.map(application -> { generateAndSetPagePolicies(application, page); - if (page.getDefaultResources() == null) { - DefaultResources defaults = new DefaultResources(); - defaults.setApplicationId(page.getApplicationId()); - page.setDefaultResources(defaults); + if (application.getGitArtifactMetadata() != null) { + page.setBranchName(application.getGitArtifactMetadata().getBranchName()); } return page; }); @@ -182,28 +174,6 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { }); } - public Mono createPageWithBranchName(PageDTO page, String branchName) { - - DefaultResources defaultResources = - page.getDefaultResources() == null ? new DefaultResources() : page.getDefaultResources(); - if (StringUtils.isEmpty(defaultResources.getApplicationId())) { - // Client will be aware of default application Id only so we are safe to assume this - defaultResources.setApplicationId(page.getApplicationId()); - } - defaultResources.setBranchName(branchName); - return applicationService - .findBranchedApplicationId( - branchName, - defaultResources.getApplicationId(), - applicationPermission.getPageCreatePermission()) - .flatMap(branchedApplicationId -> { - page.setApplicationId(branchedApplicationId); - page.setDefaultResources(defaultResources); - return createPage(page); - }) - .map(responseUtils::updatePageDTOWithDefaultResources); - } - /** * This function is called during page create in Page Service. It adds the given page to its ApplicationPages list. * Note: It is assumed here that `application` is already checked for the MANAGE_APPLICATIONS policy. @@ -215,13 +185,10 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { @Override public Mono addPageToApplication(Application application, PageDTO page, Boolean isDefault) { - String defaultPageId = page.getDefaultResources() == null - || StringUtils.isEmpty(page.getDefaultResources().getPageId()) - ? page.getId() - : page.getDefaultResources().getPageId(); + String basePageId = StringUtils.isEmpty(page.getBaseId()) ? page.getId() : page.getBaseId(); if (isDuplicatePage(application, page.getId())) { return applicationRepository - .addPageToApplication(application.getId(), page.getId(), isDefault, defaultPageId) + .addPageToApplication(application.getId(), page.getId(), isDefault, basePageId) .doOnSuccess(count -> { if (count != 1) { log.error( @@ -310,16 +277,24 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { } } return Mono.just(pageDTO); - }) - .map(responseUtils::updatePageDTOWithDefaultResources); + }); } @Override - public Mono getPageAndMigrateDslByBranchAndDefaultPageId( + public Mono getPageAndMigrateDslByBranchAndBasePageId( String defaultPageId, String branchName, boolean viewMode, boolean migrateDsl) { // Fetch the page with read permission in both editor and in viewer. return newPageService - .findByBranchNameAndDefaultPageId(branchName, defaultPageId, pagePermission.getReadPermission()) + .findByBranchNameAndBasePageId(branchName, defaultPageId, pagePermission.getReadPermission()) + .flatMap(newPage -> getPageDTOAfterMigratingDSL(newPage, viewMode, migrateDsl)); + } + + @Override + public Mono getPageAndMigrateDslByBranchedPageId( + String branchedPageId, boolean viewMode, boolean migrateDsl) { + // Fetch the page with read permission in both editor and in viewer. + return newPageService + .findById(branchedPageId, pagePermission.getReadPermission()) .flatMap(newPage -> getPageDTOAfterMigratingDSL(newPage, viewMode, migrateDsl)); } @@ -396,15 +371,6 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { .then(applicationService.getById(applicationId))); } - @Override - public Mono makePageDefault(String defaultApplicationId, String defaultPageId, String branchName) { - // TODO remove the dependency of applicationId as pageId and branch can get the exact resource - return newPageService - .findByBranchNameAndDefaultPageId(branchName, defaultPageId, pagePermission.getEditPermission()) - .flatMap(branchedPage -> makePageDefault(branchedPage.getApplicationId(), branchedPage.getId())) - .map(responseUtils::updateApplicationWithDefaultResources); - } - @Override public Mono createApplication(Application application) { return createApplication(application, application.getWorkspaceId()); @@ -449,7 +415,7 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { application1.setPublishedModeThemeId(themeId); return themeId; }) - .then(applicationService.createDefaultApplication(application1)); + .then(applicationService.createBaseApplication(application1)); }) .flatMap(savedApplication -> { PageDTO page = new PageDTO(); @@ -459,11 +425,6 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { layoutList.add(newPageService.createDefaultLayout()); page.setLayouts(layoutList); - if (page.getDefaultResources() == null) { - DefaultResources defaults = new DefaultResources(); - defaults.setApplicationId(page.getApplicationId()); - page.setDefaultResources(defaults); - } // Set the page policies generateAndSetPagePolicies(savedApplication, page); @@ -472,7 +433,7 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { .flatMap(savedPage -> addPageToApplication(savedApplication, savedPage, true)) // Now publish this newly created app with default states so that // launching of newly created application is possible. - .flatMap(ignored -> publish(savedApplication.getId(), false) + .flatMap(ignored -> publishWithoutPermissionChecks(savedApplication.getId(), false) .then(applicationService.findById( savedApplication.getId(), applicationPermission.getReadPermission()))); }); @@ -527,7 +488,7 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { .flatMapMany(application -> { GitArtifactMetadata gitData = application.getGitApplicationMetadata(); if (GitUtils.isApplicationConnectedToGit(application)) { - return applicationService.findAllApplicationsByDefaultApplicationId( + return applicationService.findAllApplicationsByBaseApplicationId( gitData.getDefaultArtifactId(), applicationPermission.getDeletePermission()); } return Flux.fromIterable(List.of(application)); @@ -579,23 +540,18 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { } @Override - public Mono clonePage(String pageId, ClonePageMetaDTO clonePageMetaDTO) { + public Mono clonePage(String pageId) { return newPageService .findById(pageId, pagePermission.getEditPermission()) .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.ACTION_IS_NOT_AUTHORIZED, "Clone Page"))) - .flatMap(page -> applicationService - .saveLastEditInformation(page.getApplicationId()) - .then(clonePageGivenApplicationId(pageId, page.getApplicationId(), " Copy", clonePageMetaDTO))); - } - - @Override - public Mono clonePageByDefaultPageIdAndBranch(String defaultPageId, String branchName) { - final ClonePageMetaDTO clonePageMetaDTO = new ClonePageMetaDTO(); - clonePageMetaDTO.setBranchName(branchName); - return newPageService - .findByBranchNameAndDefaultPageId(branchName, defaultPageId, pagePermission.getEditPermission()) - .flatMap(newPage -> clonePage(newPage.getId(), clonePageMetaDTO)) - .map(responseUtils::updatePageDTOWithDefaultResources); + .flatMap(page -> { + ClonePageMetaDTO clonePageMetaDTO = new ClonePageMetaDTO(); + clonePageMetaDTO.setBranchName(page.getBranchName()); + return applicationService + .saveLastEditInformation(page.getApplicationId()) + .then(clonePageGivenApplicationId( + pageId, page.getApplicationId(), " Copy", clonePageMetaDTO)); + }); } protected Mono clonePageGivenApplicationId( @@ -628,7 +584,7 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { .flatMap(page -> { clonePageMetaDTO.setBranchedSourcePageId(page.getId()); Mono pageNamesMono = - newPageService.findApplicationPagesByApplicationIdViewMode( + newPageService.findApplicationPagesByBranchedApplicationIdAndViewMode( page.getApplicationId(), false, false); Mono destinationApplicationMono = applicationService @@ -663,15 +619,10 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { // Proceed with creating the copy of the page page.setId(null); page.setApplicationId(applicationId); - DefaultResources defaults = new DefaultResources(); GitArtifactMetadata gitData = application.getGitApplicationMetadata(); if (gitData != null) { - defaults.setApplicationId(gitData.getDefaultArtifactId()); - defaults.setBranchName(gitData.getBranchName()); - } else { - defaults.setApplicationId(applicationId); + page.setBranchName(gitData.getBranchName()); } - page.setDefaultResources(defaults); return newPageService.createDefault(page); }); }) @@ -707,12 +658,11 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { applicationPage.setId(savedPage.getId()); applicationPage.setIsDefault(false); - String defaultPageId = StringUtils.isEmpty( - savedPage.getDefaultResources().getPageId()) + String basePageId = StringUtils.isEmpty(savedPage.getBaseId()) ? savedPage.getId() - : savedPage.getDefaultResources().getPageId(); + : savedPage.getBaseId(); - applicationPage.setDefaultPageId(defaultPageId); + applicationPage.setDefaultPageId(basePageId); application.getPages().add(applicationPage); return applicationService.save(application); @@ -747,30 +697,27 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { } @Override - public Mono cloneApplication(String applicationId, String branchName) { + public Mono cloneApplication(String branchedApplicationId) { // 1. Find valid application to clone, depending on branch Mono applicationMono = applicationService - .findByBranchNameAndDefaultApplicationId( - branchName, applicationId, applicationPermission.getEditPermission()) + .findById(branchedApplicationId, applicationPermission.getEditPermission()) .flatMap(application -> { // For git connected application user can update the default branch // In such cases we should fork the application from the new default branch - if (StringUtils.isEmpty(branchName) - && !Optional.ofNullable(application.getGitApplicationMetadata()) - .isEmpty() - && !application + if (application.getGitApplicationMetadata() == null + || application .getGitApplicationMetadata() .getBranchName() .equals(application .getGitApplicationMetadata() .getDefaultBranchName())) { - return applicationService.findByBranchNameAndDefaultApplicationId( - application.getGitApplicationMetadata().getDefaultBranchName(), - applicationId, - applicationPermission.getEditPermission()); + return Mono.just(application); } - return Mono.just(application); + return applicationService.findByBranchNameAndBaseApplicationId( + application.getGitApplicationMetadata().getDefaultBranchName(), + application.getGitApplicationMetadata().getDefaultArtifactId(), + applicationPermission.getEditPermission()); }) .cache(); @@ -832,7 +779,7 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { // setting modified by to current user application1.setModifiedBy( applicationUserTuple2.getT2().getUsername()); - return applicationService.createDefaultApplication(application1); + return applicationService.createBaseApplication(application1); }) // 4. Now fetch the pages of the source application, clone and add them to this new // application @@ -845,7 +792,7 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { ApplicationPage newApplicationPage = new ApplicationPage(); newApplicationPage.setId(clonedPage.getId()); newApplicationPage.setIsDefault(isDefault); - // Now set defaultPageId to current page itself + // Now set basePageId to current page itself newApplicationPage.setDefaultPageId(clonedPage.getId()); return newApplicationPage; }); @@ -877,7 +824,7 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { .thenReturn(application); })) // 6. Publish copy of application - .flatMap(application -> publish(application.getId(), false)) + .flatMap(application -> publishWithoutPermissionChecks(application.getId(), false)) .flatMap(application -> sendCloneApplicationAnalyticsEvent(sourceApplication, application)); }); @@ -1030,14 +977,6 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { }); } - public Mono deleteUnpublishedPageByBranchAndDefaultPageId(String defaultPageId, String branchName) { - return newPageService - .findByBranchNameAndDefaultPageId(branchName, defaultPageId, pagePermission.getDeletePermission()) - .flatMap(newPage -> deleteUnpublishedPage(newPage.getId())) - .map(responseUtils::updatePageDTOWithDefaultResources) - .as(transactionalOperator::transactional); - } - /** * This function walks through all the pages in the application. In each page, it walks through all the layouts. * In a layout, dsl and publishedDsl JSONObjects exist. Publish function is responsible for copying the dsl into @@ -1047,7 +986,7 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { * @return Publishes a Boolean true, when the application has been published. */ @Override - public Mono publish(String applicationId, boolean isPublishedManually) { + public Mono publishWithoutPermissionChecks(String applicationId, boolean isPublishedManually) { return publishAndGetMetadata(applicationId, isPublishedManually) .flatMap(tuple2 -> { ApplicationPublishingMetaDTO metaDTO = tuple2.getT2(); @@ -1253,38 +1192,34 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { } @Override - public Mono publish(String defaultApplicationId, String branchName, boolean isPublishedManually) { + public Mono publish(String branchedApplicationId, boolean isPublishedManually) { Mono applicationMono = applicationService - .findBranchedApplicationId(branchName, defaultApplicationId, applicationPermission.getEditPermission()) - .flatMap(branchedApplicationId -> - applicationService.findById(branchedApplicationId, applicationPermission.getEditPermission())) + .findById(branchedApplicationId, applicationPermission.getEditPermission()) .cache(); return validateAllObjectsForPermissions(applicationMono, AppsmithError.UNABLE_TO_DEPLOY_MISSING_PERMISSION) .then(applicationMono) - .flatMap(application -> publish(application.getId(), isPublishedManually)) - .map(responseUtils::updateApplicationWithDefaultResources); + .flatMap(application -> publishWithoutPermissionChecks(application.getId(), isPublishedManually)); } /** * This function walks through all the pages and reorders them and updates the order as per the user preference. * A page can be moved up or down from the current position and accordingly the order of the remaining page changes. * - * @param defaultAppId The id of the Application - * @param defaultPageId Targetted page id - * @param order New order for the selected page + * @param branchedApplicationId The id of the Application + * @param branchedPageId Targetted page id + * @param order New order for the selected page * @return Application object with the latest order **/ @Override - public Mono reorderPage( - String defaultAppId, String defaultPageId, Integer order, String branchName) { + public Mono reorderPage(String branchedApplicationId, String branchedPageId, Integer order) { return newPageService - .findByBranchNameAndDefaultPageId(branchName, defaultPageId, pagePermission.getEditPermission()) + .findById(branchedPageId, pagePermission.getEditPermission()) .switchIfEmpty(Mono.error( - new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, defaultPageId))) + new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, branchedPageId))) .zipWhen(branchedPage -> applicationService .findById(branchedPage.getApplicationId(), applicationPermission.getEditPermission()) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, defaultAppId)))) + AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, branchedApplicationId)))) .flatMap(tuple -> { final NewPage branchedPage = tuple.getT1(); Application application = tuple.getT2(); @@ -1305,12 +1240,11 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE { return applicationRepository .setPages(application.getId(), pages) - .flatMap(ignored -> - sendPageOrderAnalyticsEvent(application, defaultPageId, order, branchName)) - .then(newPageService.findApplicationPagesByApplicationIdViewMode( + .flatMap(ignored -> sendPageOrderAnalyticsEvent( + application, branchedPageId, order, branchedPage.getBranchName())) + .then(newPageService.findApplicationPagesByBranchedApplicationIdAndViewMode( application.getId(), Boolean.FALSE, false)); - }) - .map(responseUtils::updateApplicationPagesDTOWithDefaultResources); + }); } /** diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationSnapshotServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationSnapshotServiceCE.java index dcb455f89e..f5f010a753 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationSnapshotServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationSnapshotServiceCE.java @@ -9,15 +9,14 @@ public interface ApplicationSnapshotServiceCE { * This method will create a new snapshot of the provided applicationId and branch name and store in the * ApplicationSnapshot collection. * - * @param applicationId ID of the application, default application ID if application is connected to Git - * @param branchName name of the Git branch, null or empty if not connected to Git + * @param branchedApplicationId ID of the application, default application ID if application is connected to Git * @return Created snapshot ID */ - Mono createApplicationSnapshot(String applicationId, String branchName); + Mono createApplicationSnapshot(String branchedApplicationId); - Mono getWithoutDataByApplicationId(String applicationId, String branchName); + Mono getWithoutDataByBranchedApplicationId(String branchedApplicationId); - Mono restoreSnapshot(String applicationId, String branchName); + Mono restoreSnapshot(String branchedApplicationId); - Mono deleteSnapshot(String applicationId, String branchName); + Mono deleteSnapshot(String branchedApplicationId); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationSnapshotServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationSnapshotServiceCEImpl.java index 9f87c5d446..dfe7de44a7 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationSnapshotServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationSnapshotServiceCEImpl.java @@ -10,7 +10,6 @@ import com.appsmith.server.dtos.ApplicationJson; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.exports.internal.ExportService; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.imports.internal.ImportService; import com.appsmith.server.projections.ApplicationSnapshotResponseDTO; import com.appsmith.server.repositories.ApplicationSnapshotRepository; @@ -34,27 +33,19 @@ public class ApplicationSnapshotServiceCEImpl implements ApplicationSnapshotServ private final ExportService exportService; private final ApplicationPermission applicationPermission; private final Gson gson; - private final ResponseUtils responseUtils; private static final int MAX_SNAPSHOT_SIZE = 15 * 1024 * 1024; // 15 MB @Override - public Mono createApplicationSnapshot(String applicationId, String branchName) { - return applicationService - .findBranchedApplicationId(branchName, applicationId, applicationPermission.getEditPermission()) - /* SerialiseArtifactObjective=VERSION_CONTROL because this API can be invoked from developers. - exportApplicationById method check for MANAGE_PERMISSION if SerialiseArtifactObjective=SHARE. - */ - .flatMap(branchedAppId -> Mono.zip( - exportService.exportByArtifactId( - branchedAppId, SerialiseArtifactObjective.VERSION_CONTROL, ArtifactType.APPLICATION), - Mono.just(branchedAppId))) - .flatMapMany(objects -> { - String branchedAppId = objects.getT2(); - ApplicationJson applicationJson = (ApplicationJson) objects.getT1(); + public Mono createApplicationSnapshot(String branchedApplicationId) { + return exportService + .exportByArtifactId( + branchedApplicationId, SerialiseArtifactObjective.VERSION_CONTROL, ArtifactType.APPLICATION) + .flatMapMany(artifactExchangeJson -> { + ApplicationJson applicationJson = (ApplicationJson) artifactExchangeJson; return applicationSnapshotRepository - .deleteAllByApplicationId(branchedAppId) - .thenMany(createSnapshots(branchedAppId, applicationJson)); + .deleteAllByApplicationId(branchedApplicationId) + .thenMany(createSnapshots(branchedApplicationId, applicationJson)); }) .then(Mono.just(Boolean.TRUE)); } @@ -68,22 +59,19 @@ public class ApplicationSnapshotServiceCEImpl implements ApplicationSnapshotServ } @Override - public Mono getWithoutDataByApplicationId(String applicationId, String branchName) { + public Mono getWithoutDataByBranchedApplicationId(String branchedApplicationId) { // get application first to check the permission and get child aka branched application ID - return applicationService - .findBranchedApplicationId(branchName, applicationId, applicationPermission.getEditPermission()) - .flatMap(branchedApplicationId -> - applicationSnapshotRepository.findByApplicationIdAndChunkOrder(branchedApplicationId, 1)) + return applicationSnapshotRepository + .findByApplicationIdAndChunkOrder(branchedApplicationId, 1) .defaultIfEmpty(new ApplicationSnapshotResponseDTO(null)); } @Override - public Mono restoreSnapshot(String applicationId, String branchName) { + public Mono restoreSnapshot(String branchedApplicationId) { return applicationService - .findByBranchNameAndDefaultApplicationId( - branchName, applicationId, applicationPermission.getEditPermission()) - .switchIfEmpty(Mono.error( - new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, applicationId))) + .findById(branchedApplicationId, applicationPermission.getEditPermission()) + .switchIfEmpty(Mono.error(new AppsmithException( + AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, branchedApplicationId))) .flatMap(application -> getApplicationJsonStringFromSnapShot(application.getId()) .zipWith(Mono.just(application))) .flatMap(objects -> { @@ -91,13 +79,12 @@ public class ApplicationSnapshotServiceCEImpl implements ApplicationSnapshotServ Application application = objects.getT2(); ApplicationJson applicationJson = gson.fromJson(applicationJsonString, ApplicationJson.class); return importService.restoreSnapshot( - application.getWorkspaceId(), application.getId(), branchName, applicationJson); + application.getWorkspaceId(), application.getId(), applicationJson); }) .map(importableArtifact -> (Application) importableArtifact) .flatMap(application -> applicationSnapshotRepository .deleteAllByApplicationId(application.getId()) - .thenReturn(application)) - .map(responseUtils::updateApplicationWithDefaultResources); + .thenReturn(application)); } private Mono getApplicationJsonStringFromSnapShot(String applicationId) { @@ -143,14 +130,9 @@ public class ApplicationSnapshotServiceCEImpl implements ApplicationSnapshotServ } @Override - public Mono deleteSnapshot(String applicationId, String branchName) { - // find root application by applicationId and branchName - return applicationService - .findBranchedApplicationId(branchName, applicationId, applicationPermission.getEditPermission()) - .switchIfEmpty(Mono.error( - new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, applicationId))) - .flatMap(branchedAppId -> applicationSnapshotRepository - .deleteAllByApplicationId(branchedAppId) - .thenReturn(Boolean.TRUE)); + public Mono deleteSnapshot(String branchedApplicationId) { + return applicationSnapshotRepository + .deleteAllByApplicationId(branchedApplicationId) + .thenReturn(Boolean.TRUE); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationTemplateServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationTemplateServiceCE.java index 563702164b..6d2cd25501 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationTemplateServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationTemplateServiceCE.java @@ -22,7 +22,7 @@ public interface ApplicationTemplateServiceCE { Mono importApplicationFromTemplate(String templateId, String workspaceId); Mono mergeTemplateWithApplication( - String templateId, String applicationId, String workspaceId, String branchName, List pagesToImport); + String templateId, String branchedApplicationId, String workspaceId, List pagesToImport); Mono getFilters(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationTemplateServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationTemplateServiceCEImpl.java index f7ede951d9..3f22f26fe0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationTemplateServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ApplicationTemplateServiceCEImpl.java @@ -20,11 +20,9 @@ import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.exports.internal.ExportService; import com.appsmith.server.helpers.CacheableTemplateHelper; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.imports.internal.ImportService; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.UserDataService; import com.appsmith.server.solutions.ApplicationPermission; import com.appsmith.server.solutions.ReleaseNotesService; import com.appsmith.util.WebClientUtils; @@ -55,9 +53,7 @@ public class ApplicationTemplateServiceCEImpl implements ApplicationTemplateServ private final ImportService importService; private final ExportService exportService; private final AnalyticsService analyticsService; - private final UserDataService userDataService; private final ApplicationService applicationService; - private final ResponseUtils responseUtils; private final ApplicationPermission applicationPermission; private final ObjectMapper objectMapper; private final SessionUserService sessionUserService; @@ -70,9 +66,7 @@ public class ApplicationTemplateServiceCEImpl implements ApplicationTemplateServ ImportService importService, ExportService exportService, AnalyticsService analyticsService, - UserDataService userDataService, ApplicationService applicationService, - ResponseUtils responseUtils, ApplicationPermission applicationPermission, ObjectMapper objectMapper, SessionUserService sessionUserService, @@ -82,9 +76,7 @@ public class ApplicationTemplateServiceCEImpl implements ApplicationTemplateServ this.importService = importService; this.exportService = exportService; this.analyticsService = analyticsService; - this.userDataService = userDataService; this.applicationService = applicationService; - this.responseUtils = responseUtils; this.applicationPermission = applicationPermission; this.objectMapper = objectMapper; this.sessionUserService = sessionUserService; @@ -232,11 +224,7 @@ public class ApplicationTemplateServiceCEImpl implements ApplicationTemplateServ */ @Override public Mono mergeTemplateWithApplication( - String templateId, - String applicationId, - String organizationId, - String branchName, - List pagesToImport) { + String templateId, String branchedApplicationId, String organizationId, List pagesToImport) { Mono importedApplicationMono = getApplicationJsonFromTemplate(templateId) .flatMap(applicationJson -> { String templateName = ""; @@ -244,22 +232,10 @@ public class ApplicationTemplateServiceCEImpl implements ApplicationTemplateServ && applicationJson.getExportedApplication().getName() != null) { templateName = applicationJson.getExportedApplication().getName(); } - if (branchName != null) { - return applicationService - .findByBranchNameAndDefaultApplicationId( - branchName, applicationId, applicationPermission.getEditPermission()) - .flatMap(application -> importService.mergeArtifactExchangeJsonWithImportableArtifact( - organizationId, - application.getId(), - branchName, - applicationJson, - pagesToImport)) - .map(importableArtifact -> (Application) importableArtifact) - .zipWith(Mono.just(templateName)); - } + return importService .mergeArtifactExchangeJsonWithImportableArtifact( - organizationId, applicationId, null, applicationJson, pagesToImport) + organizationId, branchedApplicationId, null, applicationJson, pagesToImport) .map(importableArtifact -> (Application) importableArtifact) .zipWith(Mono.just(templateName)); }) @@ -276,8 +252,6 @@ public class ApplicationTemplateServiceCEImpl implements ApplicationTemplateServ .flatMap(importableArtifactDTO -> { ApplicationImportDTO applicationImportDTO = (ApplicationImportDTO) importableArtifactDTO; - responseUtils.updateApplicationWithDefaultResources( - applicationImportDTO.getApplication()); Application application1 = applicationImportDTO.getApplication(); ApplicationTemplate applicationTemplate = new ApplicationTemplate(); applicationTemplate.setId(templateId); @@ -366,7 +340,7 @@ public class ApplicationTemplateServiceCEImpl implements ApplicationTemplateServ application.setForkingEnabled(true); application.setIsCommunityTemplate(isCommunityTemplate); - return applicationService.update(applicationId, application, branchId); + return applicationService.updateApplicationWithPresets(applicationId, application); }); } @@ -408,8 +382,8 @@ public class ApplicationTemplateServiceCEImpl implements ApplicationTemplateServ .flatMap(application -> { ApplicationAccessDTO applicationAccessDTO = new ApplicationAccessDTO(); applicationAccessDTO.setPublicAccess(true); - return applicationService.changeViewAccess( - application.getId(), resource.getBranchName(), applicationAccessDTO); + return applicationService.changeViewAccessForAllBranchesByBranchedApplicationId( + application.getId(), applicationAccessDTO); }); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/AstServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/AstServiceCEImpl.java index a1a7e8a1c8..cd5b32be74 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/AstServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/AstServiceCEImpl.java @@ -160,8 +160,8 @@ public class AstServiceCEImpl implements AstServiceCE { }) .elapsed() .map(tuple -> { - log.debug("Time elapsed since AST refactor call: {} ms", tuple.getT1()); if (tuple.getT1() > MAX_API_RESPONSE_TIME_IN_MS) { + log.debug("Time elapsed since AST refactor call: {} ms", tuple.getT1()); log.debug("This call took longer than expected. The binding was: {}", bindingValue); } return tuple.getT2(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/BaseApiImporterCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/BaseApiImporterCE.java index a6f3c28684..634a031e49 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/BaseApiImporterCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/BaseApiImporterCE.java @@ -7,10 +7,5 @@ import reactor.core.publisher.Mono; public abstract class BaseApiImporterCE implements ApiImporterCE { public abstract Mono importAction( - Object input, - CreatorContextType contextType, - String contextId, - String name, - String workspaceId, - String branchName); + Object input, CreatorContextType contextType, String branchedContextId, String name, String workspaceId); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCEImpl.java index b773e6c6b5..12cc4cafcc 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCEImpl.java @@ -26,7 +26,6 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.reactive.function.BodyInserters; @@ -187,6 +186,7 @@ public class CacheableFeatureFlagHelperCEImpl implements CacheableFeatureFlagHel @Cache(cacheName = "tenantNewFeatures", key = "{#tenantId}") @Override public Mono updateCachedTenantFeatures(String tenantId, CachedFeatures cachedFeatures) { + log.debug("Updating cached tenant features for tenant: {}", tenantId); return Mono.just(cachedFeatures); } @@ -239,12 +239,6 @@ public class CacheableFeatureFlagHelperCEImpl implements CacheableFeatureFlagHel .accept(MediaType.APPLICATION_JSON) .body(BodyInserters.fromValue(featuresRequestDTO)) .retrieve() - .onStatus( - HttpStatusCode::isError, - response -> Mono.error(new AppsmithException( - AppsmithError.CLOUD_SERVICES_ERROR, - "unable to connect to cloud-services with error status ", - response.statusCode()))) .toEntity(new ParameterizedTypeReference<>() {}); return responseEntityMono diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java index a771ca89f6..abc50e012b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java @@ -137,10 +137,10 @@ public class ConsolidatedAPIServiceCEImpl implements ConsolidatedAPIServiceCE { */ @Override public Mono getConsolidatedInfoForPageLoad( - String defaultPageId, String applicationId, String branchName, ApplicationMode mode) { + String basePageId, String baseApplicationId, String branchName, ApplicationMode mode) { - /* if either of pageId or applicationId are provided then application mode must also be provided */ - if (mode == null && (!isBlank(defaultPageId) || !isBlank(applicationId))) { + /* if either of pageId or defaultApplicationId are provided then application mode must also be provided */ + if (mode == null && (!isBlank(basePageId) || !isBlank(baseApplicationId))) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, APP_MODE)); } @@ -191,31 +191,30 @@ public class ConsolidatedAPIServiceCEImpl implements ConsolidatedAPIServiceCE { .name(getQualifiedSpanName(PRODUCT_ALERT_SPAN, mode)) .tap(Micrometer.observation(observationRegistry))); - if (isBlank(defaultPageId) && isBlank(applicationId)) { + if (isBlank(basePageId) && isBlank(baseApplicationId)) { return Mono.when(fetches).thenReturn(consolidatedAPIResponseDTO); } /* Get view mode - EDIT or PUBLISHED */ boolean isViewMode = ApplicationMode.PUBLISHED.equals(mode); - /* Fetch application id if not provided */ - Mono applicationIdMonoCache; - if (isBlank(applicationId)) { - applicationIdMonoCache = newPageService - .findRootApplicationIdFromNewPage(branchName, defaultPageId) + /* Fetch default application id if not provided */ + Mono branchedApplicationMonoCached; + if (isBlank(baseApplicationId)) { + branchedApplicationMonoCached = newPageService + .findByBranchNameAndBasePageIdAndApplicationMode(branchName, basePageId, mode) + .map(NewPage::getApplicationId) + .flatMap(applicationId -> + applicationService.findByBranchedApplicationIdAndApplicationMode(applicationId, mode)) .name(getQualifiedSpanName(APPLICATION_ID_SPAN, mode)) .tap(Micrometer.observation(observationRegistry)) .cache(); } else { - applicationIdMonoCache = Mono.just(applicationId).cache(); + branchedApplicationMonoCached = applicationService + .findByBaseIdBranchNameAndApplicationMode(baseApplicationId, branchName, mode) + .cache(); } - // dslMigration-over-here using the branchName and defaultId - Mono branchedApplicationMonoCached = applicationIdMonoCache - .flatMap(defaultApplicationId -> applicationService.findByDefaultIdBranchNameAndApplicationMode( - defaultApplicationId, branchName, mode)) - .cache(); - Mono> pagesFromCurrentApplicationMonoCached = branchedApplicationMonoCached .flatMap(branchedApplication -> applicationPageService.getPagesBasedOnApplicationMode(branchedApplication, mode)) @@ -238,35 +237,36 @@ public class ConsolidatedAPIServiceCEImpl implements ConsolidatedAPIServiceCE { fetches.add(applicationPagesDTOResponseDTOMonoCache); /* Get current theme */ - fetches.add(applicationIdMonoCache - .flatMap(appId -> themeService.getApplicationTheme(appId, mode, branchName)) + fetches.add(branchedApplicationMonoCached + .flatMap(branchedApplication -> themeService.getApplicationTheme(branchedApplication.getId(), mode)) .as(this::toResponseDTO) .doOnSuccess(consolidatedAPIResponseDTO::setCurrentTheme) .name(getQualifiedSpanName(CURRENT_THEME_SPAN, mode)) .tap(Micrometer.observation(observationRegistry))); /* Get all themes */ - fetches.add(applicationIdMonoCache - .flatMap(appId -> - themeService.getApplicationThemes(appId, branchName).collectList()) + fetches.add(branchedApplicationMonoCached + .flatMap(branchedApplication -> themeService + .getApplicationThemes(branchedApplication.getId()) + .collectList()) .as(this::toResponseDTO) .doOnSuccess(consolidatedAPIResponseDTO::setThemes) .name(getQualifiedSpanName(THEMES_SPAN, mode)) .tap(Micrometer.observation(observationRegistry))); /* Get all custom JS libraries installed in the application */ - fetches.add(applicationIdMonoCache - .flatMap(appId -> customJSLibService.getAllJSLibsInContext( - appId, CreatorContextType.APPLICATION, branchName, isViewMode)) + fetches.add(branchedApplicationMonoCached + .flatMap(branchedApplication -> customJSLibService.getAllJSLibsInContext( + branchedApplication.getId(), CreatorContextType.APPLICATION, isViewMode)) .as(this::toResponseDTO) .doOnSuccess(consolidatedAPIResponseDTO::setCustomJSLibraries) .name(getQualifiedSpanName(CUSTOM_JS_LIB_SPAN, mode)) .tap(Micrometer.observation(observationRegistry))); - if (!isBlank(defaultPageId)) { + if (!isBlank(basePageId)) { /* Get current page */ fetches.add(applicationPageService - .getPageAndMigrateDslByBranchAndDefaultPageId(defaultPageId, branchName, isViewMode, true) + .getPageAndMigrateDslByBranchAndBasePageId(basePageId, branchName, isViewMode, true) .as(this::toResponseDTO) .doOnSuccess(consolidatedAPIResponseDTO::setPageWithMigratedDsl) .name(getQualifiedSpanName(CURRENT_PAGE_SPAN, mode)) @@ -276,9 +276,9 @@ public class ConsolidatedAPIServiceCEImpl implements ConsolidatedAPIServiceCE { /* Fetch view specific data */ if (isViewMode) { /* Get list of all actions in view mode */ - fetches.add(applicationIdMonoCache - .flatMap(appId -> newActionService - .getActionsForViewMode(appId, branchName) + fetches.add(branchedApplicationMonoCached + .flatMap(branchedApplication -> newActionService + .getActionsForViewMode(branchedApplication.getId()) .collectList()) .as(this::toResponseDTO) .doOnSuccess(consolidatedAPIResponseDTO::setPublishedActions) @@ -286,9 +286,9 @@ public class ConsolidatedAPIServiceCEImpl implements ConsolidatedAPIServiceCE { .tap(Micrometer.observation(observationRegistry))); /* Get list of all action collections in view mode */ - fetches.add(applicationIdMonoCache - .flatMap(appId -> actionCollectionService - .getActionCollectionsForViewMode(appId, branchName) + fetches.add(branchedApplicationMonoCached + .flatMap(branchedApplication -> actionCollectionService + .getActionCollectionsForViewMode(branchedApplication.getId()) .collectList()) .as(this::toResponseDTO) .doOnSuccess(consolidatedAPIResponseDTO::setPublishedActionCollections) @@ -296,12 +296,12 @@ public class ConsolidatedAPIServiceCEImpl implements ConsolidatedAPIServiceCE { } else { /* Get all actions in edit mode */ - fetches.add(applicationIdMonoCache - .flatMap(appId -> { + fetches.add(branchedApplicationMonoCached + .flatMap(branchedApplication -> { MultiValueMap params = new LinkedMultiValueMap<>(); - params.add(APPLICATION_ID, appId); + params.add(APPLICATION_ID, branchedApplication.getId()); return newActionService - .getUnpublishedActions(params, branchName, false) + .getUnpublishedActions(params, false) .collectList(); }) .as(this::toResponseDTO) @@ -310,12 +310,11 @@ public class ConsolidatedAPIServiceCEImpl implements ConsolidatedAPIServiceCE { .tap(Micrometer.observation(observationRegistry))); /* Get all action collections in edit mode */ - fetches.add(applicationIdMonoCache - .flatMapMany(appId -> { + fetches.add(branchedApplicationMonoCached + .flatMapMany(branchedApplication -> { MultiValueMap params = new LinkedMultiValueMap<>(); - params.add(APPLICATION_ID, appId); - return actionCollectionService.getPopulatedActionCollectionsByViewMode( - params, false, branchName); + params.add(APPLICATION_ID, branchedApplication.getId()); + return actionCollectionService.getPopulatedActionCollectionsByViewMode(params, false); }) .collectList() .as(this::toResponseDTO) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CurlImporterServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CurlImporterServiceCEImpl.java index d01fcea301..0a75c2f9d7 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CurlImporterServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CurlImporterServiceCEImpl.java @@ -11,7 +11,6 @@ import com.appsmith.server.domains.NewPage; import com.appsmith.server.domains.Plugin; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.plugins.base.PluginService; import com.appsmith.server.services.BaseApiImporter; @@ -54,7 +53,6 @@ public class CurlImporterServiceCEImpl extends BaseApiImporter implements CurlIm private final PluginService pluginService; private final LayoutActionService layoutActionService; - private final ResponseUtils responseUtils; private final NewPageService newPageService; private final ObjectMapper objectMapper; private final PagePermission pagePermission; @@ -63,25 +61,18 @@ public class CurlImporterServiceCEImpl extends BaseApiImporter implements CurlIm PluginService pluginService, LayoutActionService layoutActionService, NewPageService newPageService, - ResponseUtils responseUtils, ObjectMapper objectMapper, PagePermission pagePermission) { this.pluginService = pluginService; this.layoutActionService = layoutActionService; this.newPageService = newPageService; - this.responseUtils = responseUtils; this.objectMapper = objectMapper; this.pagePermission = pagePermission; } @Override public Mono importAction( - Object input, - CreatorContextType contextType, - String contextId, - String name, - String workspaceId, - String branchName) { + Object input, CreatorContextType contextType, String branchedContextId, String name, String workspaceId) { ActionDTO action; try { @@ -109,28 +100,21 @@ public class CurlImporterServiceCEImpl extends BaseApiImporter implements CurlIm datasource.setName(datasourceConfiguration.getUrl()); datasource.setPluginId(plugin.getId()); datasource.setWorkspaceId(workspaceId); - return getBranchedContextId(contextType, contextId, branchName) - .flatMap(branchedContextId -> - associateContextIdToActionDTO(action1, contextType, branchedContextId)); + return associateContextIdToActionDTO(action1, contextType, branchedContextId); }) - .flatMap(action2 -> layoutActionService.createSingleAction(action2, Boolean.FALSE)) - .map(responseUtils::updateActionDTOWithDefaultResources); + .flatMap(action2 -> layoutActionService.createSingleAction(action2)); } protected Mono getBranchedContextId(CreatorContextType contextType, String contextId, String branchName) { return newPageService - .findByBranchNameAndDefaultPageId(branchName, contextId, pagePermission.getActionCreatePermission()) + .findByBranchNameAndBasePageId(branchName, contextId, pagePermission.getActionCreatePermission()) .map(NewPage::getId); } protected Mono associateContextIdToActionDTO( ActionDTO actionDTO, CreatorContextType contextType, String contextId) { actionDTO.setPageId(contextId); - return newPageService.findById(contextId, null).map(newPage -> { - // Set git related resource IDs - actionDTO.setDefaultResources(newPage.getDefaultResources()); - return actionDTO; - }); + return Mono.just(actionDTO); } public ActionDTO curlToAction(String command, String name) throws AppsmithException { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitArtifactHelperCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitArtifactHelperCE.java index 240a61c6e4..7fb4f40c8c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitArtifactHelperCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitArtifactHelperCE.java @@ -27,12 +27,11 @@ public interface GitArtifactHelperCE { Mono getArtifactById(String artifactId, AclPermission aclPermission); - Mono getArtifactByDefaultIdAndBranchName( - String defaultArtifactId, String branchName, AclPermission aclPermission); + Mono getArtifactByBaseIdAndBranchName(String baseArtifactId, String branchName, AclPermission aclPermission); - Flux getAllArtifactByDefaultId(String defaultArtifactId, AclPermission aclPermission); + Flux getAllArtifactByBaseId(String baseArtifactId, AclPermission aclPermission); - Mono getSshKeys(String defaultArtifactId); + Mono getSshKeys(String baseArtifactId); Mono createNewArtifactForCheckout(Artifact sourceArtifact, String branchName); @@ -40,17 +39,15 @@ public interface GitArtifactHelperCE { Mono updateArtifactWithSchemaVersions(Artifact artifact); - Mono updateArtifactWithProtectedBranches(String defaultArtifactId, List branchNames); + Mono updateArtifactWithProtectedBranches(String baseArtifactId, List branchNames); - T updateArtifactWithDefaultReponseUtils(Artifact artifact); - - Flux deleteAllBranches(String defaultArtifactId, List branches); + Flux deleteAllBranches(String baseArtifactId, List branches); Mono deleteArtifactByResource(Artifact artifact); - void resetAttributeInDefaultArtifact(Artifact defaultArtifact); + void resetAttributeInBaseArtifact(Artifact baseArtifact); - Mono disconnectEntitiesOfDefaultArtifact(Artifact artifact); + Mono disconnectEntitiesOfBaseArtifact(Artifact artifact); Path getRepoSuffixPath(String workspaceId, String artifactId, String repoName, String... args); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCE.java index ebb438eb38..c46abdc38a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCE.java @@ -9,27 +9,21 @@ public interface LayoutActionServiceCE { Mono moveAction(ActionMoveDTO actionMoveDTO); - Mono moveAction(ActionMoveDTO actionMoveDTO, String branchName); + Mono updateAction(String id, ActionDTO actionDTO); - Mono updateAction(String id, ActionDTO action); + Mono updateSingleAction(String id, ActionDTO actionDTO); - Mono updateSingleAction(String id, ActionDTO action); - - Mono updateSingleActionWithBranchName(String id, ActionDTO action, String branchName); + Mono updateNewActionByBranchedId(String branchedId, ActionDTO actionDTO); Mono setExecuteOnLoad(String id, Boolean isExecuteOnLoad); - Mono setExecuteOnLoad(String defaultActionId, String branchName, Boolean isExecuteOnLoad); + Mono createAction(ActionDTO actionDTO); - Mono createAction(ActionDTO action); + Mono createSingleAction(ActionDTO actionDTO); - Mono createSingleActionWithBranch(ActionDTO action, String branchName); + Mono createSingleAction(ActionDTO actionDTO, Boolean isJsAction); - Mono createSingleAction(ActionDTO action, Boolean isJsAction); - - Mono createAction(ActionDTO action, AppsmithEventContext eventContext, Boolean isJsAction); + Mono createAction(ActionDTO actionDTO, AppsmithEventContext eventContext, Boolean isJsAction); Mono deleteUnpublishedAction(String id); - - Mono deleteUnpublishedAction(String id, String branchName); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java index 11d738918e..f3d88efa89 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java @@ -5,7 +5,6 @@ import com.appsmith.external.helpers.AppsmithEventContextType; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.CreatorContextType; import com.appsmith.external.models.Datasource; -import com.appsmith.external.models.DefaultResources; import com.appsmith.server.acl.AclPermission; import com.appsmith.server.constants.FieldName; import com.appsmith.server.datasources.base.DatasourceService; @@ -13,9 +12,9 @@ import com.appsmith.server.domains.Layout; import com.appsmith.server.domains.NewAction; import com.appsmith.server.domains.NewPage; import com.appsmith.server.dtos.ActionMoveDTO; +import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; @@ -45,7 +44,6 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { protected final RefactoringService refactoringService; private final CollectionService collectionService; private final UpdateLayoutService updateLayoutService; - private final ResponseUtils responseUtils; private final DatasourceService datasourceService; private final PagePermission pagePermission; private final ActionPermission actionPermission; @@ -54,28 +52,28 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { * Called by Action controller to create Action */ @Override - public Mono createAction(ActionDTO action) { - if (action.getCollectionId() == null) { - return this.createSingleAction(action, Boolean.FALSE); + public Mono createAction(ActionDTO actionDTO) { + if (actionDTO.getCollectionId() == null) { + return this.createSingleAction(actionDTO, Boolean.FALSE); } - return this.createSingleAction(action, Boolean.FALSE) + return this.createSingleAction(actionDTO, Boolean.FALSE) .flatMap(savedAction -> - collectionService.addSingleActionToCollection(action.getCollectionId(), savedAction)); + collectionService.addSingleActionToCollection(actionDTO.getCollectionId(), savedAction)); } @Override - public Mono updateAction(String id, ActionDTO action) { + public Mono updateAction(String id, ActionDTO actionDTO) { // Since the policies are server only concept, we should first set this to null. - action.setPolicies(null); + actionDTO.setPolicies(null); // The change was not in CollectionId, just go ahead and update normally - if (action.getCollectionId() == null) { - return this.updateSingleAction(id, action).flatMap(updatedAction -> updateLayoutService + if (actionDTO.getCollectionId() == null) { + return this.updateSingleAction(id, actionDTO).flatMap(updatedAction -> updateLayoutService .updatePageLayoutsByPageId(updatedAction.getPageId()) .thenReturn(updatedAction)); - } else if (action.getCollectionId().length() == 0) { + } else if (actionDTO.getCollectionId().length() == 0) { // The Action has been removed from existing collection. return newActionService .getByIdWithoutPermissionCheck(id) @@ -83,8 +81,8 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { action1.getUnpublishedAction().getCollectionId(), Mono.just(action1))) .flatMap(action1 -> { log.debug("Action {} has been removed from its collection.", action1.getId()); - action.setCollectionId(null); - return this.updateSingleAction(id, action).flatMap(updatedAction -> updateLayoutService + actionDTO.setCollectionId(null); + return this.updateSingleAction(id, actionDTO).flatMap(updatedAction -> updateLayoutService .updatePageLayoutsByPageId(updatedAction.getPageId()) .thenReturn(updatedAction)); }); @@ -105,14 +103,15 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { .flatMap(action1 -> { ActionDTO unpublishedAction = action1.getUnpublishedAction(); unpublishedAction.setId(action1.getId()); + unpublishedAction.setBaseId(action1.getBaseIdOrFallback()); return collectionService.addSingleActionToCollection( - action.getCollectionId(), unpublishedAction); + actionDTO.getCollectionId(), unpublishedAction); }) .flatMap(action1 -> { log.debug( "Action {} removed from its previous collection and added to the new collection", action1.getId()); - return this.updateSingleAction(id, action).flatMap(updatedAction -> updateLayoutService + return this.updateSingleAction(id, actionDTO).flatMap(updatedAction -> updateLayoutService .updatePageLayoutsByPageId(updatedAction.getPageId()) .thenReturn(updatedAction)); }); @@ -139,26 +138,15 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { * 4. Run updateLayout on the new page. * 5. Return the saved action. */ + Mono updateActionMono = newActionService + .updateUnpublishedAction(action.getId(), action) + .switchIfEmpty(Mono.error(new AppsmithException( + AppsmithError.NO_RESOURCE_FOUND, + actionMoveDTO.getAction().getId()))); return destinationPageMono - .flatMap(destinationPage -> { - // 1. Update and save the action - if (action.getDefaultResources() == null) { - log.debug("Default resource should not be empty for move action: {}", action.getId()); - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setPageId( - destinationPage.getDefaultResources().getPageId()); - action.setDefaultResources(defaultResources); - } else { - action.getDefaultResources() - .setPageId(destinationPage.getDefaultResources().getPageId()); - } - return newActionService - .updateUnpublishedAction(action.getId(), action) - .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, - actionMoveDTO.getAction().getId()))); - }) + .then(Mono.defer(() -> updateActionMono)) .flatMap(savedAction -> + // TODO This can be zipped, they're update layouts on two independent pages // fetch the unpublished source page newPageService .findPageById(oldPageId, pagePermission.getEditPermission(), false) @@ -201,33 +189,6 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { .thenReturn(savedAction)); } - @Override - public Mono moveAction(ActionMoveDTO actionMoveDTO, String branchName) { - - // As client only have default page Id it will be sent under action and not the action.defaultResources - Mono toPageMono = newPageService - .findByBranchNameAndDefaultPageId( - branchName, actionMoveDTO.getDestinationPageId(), pagePermission.getActionCreatePermission()) - .map(NewPage::getId); - - Mono branchedActionMono = newActionService.findByBranchNameAndDefaultActionId( - branchName, actionMoveDTO.getAction().getId(), false, actionPermission.getEditPermission()); - - return Mono.zip(toPageMono, branchedActionMono) - .flatMap(tuple -> { - String toPageId = tuple.getT1(); - NewAction branchedAction = tuple.getT2(); - ActionDTO moveAction = actionMoveDTO.getAction(); - actionMoveDTO.setDestinationPageId(toPageId); - moveAction.setPageId(branchedAction.getUnpublishedAction().getPageId()); - moveAction.setId(branchedAction.getId()); - moveAction.setDefaultResources( - branchedAction.getUnpublishedAction().getDefaultResources()); - return moveAction(actionMoveDTO); - }) - .map(responseUtils::updateActionDTOWithDefaultResources); - } - /** * After updating the action, page layout needs to be updated to update the page load actions with the new json * path keys. @@ -238,24 +199,22 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { * actions on load to change. * * @param id - * @param action + * @param actionDTO * @return */ @Override - public Mono updateSingleAction(String id, ActionDTO action) { + public Mono updateSingleAction(String id, ActionDTO actionDTO) { return newActionService - .updateUnpublishedAction(id, action) + .updateUnpublishedAction(id, actionDTO) .flatMap(newActionService::populateHintMessages) .cache(); } @Override - public Mono updateSingleActionWithBranchName( - String defaultActionId, ActionDTO action, String branchName) { + public Mono updateNewActionByBranchedId(String branchedId, ActionDTO actionDTO) { return newActionService - .findByBranchNameAndDefaultActionId( - branchName, defaultActionId, false, actionPermission.getEditPermission()) - .flatMap(newAction -> updateActionBasedOnContextType(newAction, action)); + .findById(branchedId, actionPermission.getEditPermission()) + .flatMap(newAction -> updateActionBasedOnContextType(newAction, actionDTO)); } /** @@ -264,31 +223,25 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { */ protected Mono updateActionBasedOnContextType(NewAction newAction, ActionDTO action) { log.debug("Updating action based on context type with action id: {}", action != null ? action.getId() : null); - String defaultPageId = - newAction.getUnpublishedAction().getDefaultResources().getPageId(); - String branchName = newAction.getDefaultResources().getBranchName(); + String pageId = newAction.getUnpublishedAction().getPageId(); action.setApplicationId(null); action.setPageId(null); return updateSingleAction(newAction.getId(), action) - .flatMap(updatedAction -> newPageService - .findByBranchNameAndDefaultPageId(branchName, defaultPageId, pagePermission.getEditPermission()) - .flatMap(branchedPage -> updateLayoutService.updatePageLayoutsByPageId(branchedPage.getId())) - .thenReturn(updatedAction)) - .map(responseUtils::updateActionDTOWithDefaultResources) - .flatMap(actionDTO -> newPageService - .findByBranchNameAndDefaultPageId(branchName, defaultPageId, pagePermission.getEditPermission()) - .flatMap(newPage -> newPageService.getPageByViewMode(newPage, false)) - .map(pageDTO -> { - // redundant check - if (pageDTO.getLayouts().size() > 0) { - actionDTO.setErrorReports( - pageDTO.getLayouts().get(0).getLayoutOnLoadActionErrors()); - } - log.debug( - "Update action based on context type completed, returning actionDTO with action id: {}", - actionDTO != null ? actionDTO.getId() : null); - return actionDTO; - })); + .flatMap(updatedAction -> + updateLayoutService.updatePageLayoutsByPageId(pageId).thenReturn(updatedAction)) + .zipWhen(actionDTO -> newPageService.findPageById(pageId, pagePermission.getEditPermission(), false)) + .map(tuple2 -> { + ActionDTO actionDTO = tuple2.getT1(); + PageDTO pageDTO = tuple2.getT2(); + // redundant check + if (pageDTO.getLayouts().size() > 0) { + actionDTO.setErrorReports(pageDTO.getLayouts().get(0).getLayoutOnLoadActionErrors()); + } + log.debug( + "Update action based on context type completed, returning actionDTO with action id: {}", + actionDTO != null ? actionDTO.getId() : null); + return actionDTO; + }); } @Override @@ -311,15 +264,6 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { }); } - @Override - public Mono setExecuteOnLoad(String defaultActionId, String branchName, Boolean isExecuteOnLoad) { - return newActionService - .findByBranchNameAndDefaultActionId( - branchName, defaultActionId, false, actionPermission.getEditPermission()) - .flatMap(branchedAction -> setExecuteOnLoad(branchedAction.getId(), isExecuteOnLoad)) - .map(responseUtils::updateActionDTOWithDefaultResources); - } - /** * - Delete action. * - Update page layout since a deleted action cannot be marked as on page load. @@ -332,60 +276,46 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { .flatMap(tuple -> { ActionDTO actionDTO = tuple.getT1(); return Mono.just(actionDTO); - }); - } - - public Mono deleteUnpublishedAction(String defaultActionId, String branchName) { - return newActionService - .findByBranchNameAndDefaultActionId( - branchName, defaultActionId, false, actionPermission.getDeletePermission()) - .flatMap(branchedAction -> deleteUnpublishedAction(branchedAction.getId())) - .map(responseUtils::updateActionDTOWithDefaultResources) + }) .flatMap(actionDTO -> newActionService .saveLastEditInformationInParent(actionDTO) .thenReturn(actionDTO)); } @Override - public Mono createSingleActionWithBranch(ActionDTO action, String branchName) { - - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setBranchName(branchName); + public Mono createSingleAction(ActionDTO actionDTO) { + return createSingleAction(actionDTO, Boolean.FALSE); + } + @Override + public Mono createSingleAction(ActionDTO actionDTO, Boolean isJsAction) { + if (!StringUtils.hasLength(actionDTO.getPageId())) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.PAGE_ID)); + } return newPageService - .findByBranchNameAndDefaultPageId( - branchName, action.getPageId(), pagePermission.getActionCreatePermission()) + .findById(actionDTO.getPageId(), pagePermission.getActionCreatePermission()) + .switchIfEmpty(Mono.error( + new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, actionDTO.getPageId()))) .flatMap(newPage -> { - // Update the page and application id with branched resource - action.setPageId(newPage.getId()); - action.setApplicationId(newPage.getApplicationId()); - - DefaultResources pageDefaultIds = newPage.getDefaultResources(); - defaultResources.setPageId(pageDefaultIds.getPageId()); - defaultResources.setApplicationId(pageDefaultIds.getApplicationId()); - if (StringUtils.isEmpty(defaultResources.getCollectionId())) { - defaultResources.setCollectionId(action.getCollectionId()); - } - action.setDefaultResources(defaultResources); - return createSingleAction(action, Boolean.FALSE); - }) - .map(responseUtils::updateActionDTOWithDefaultResources); + actionDTO.setBranchName(newPage.getBranchName()); + return createAction(actionDTO, isJsAction); + }); } - @Override - public Mono createSingleAction(ActionDTO action, Boolean isJsAction) { + protected Mono createAction(ActionDTO actionDTO, Boolean isJsAction) { AppsmithEventContext eventContext = new AppsmithEventContext(AppsmithEventContextType.DEFAULT); - return createAction(action, eventContext, isJsAction); + return createAction(actionDTO, eventContext, isJsAction); } @Override - public Mono createAction(ActionDTO action, AppsmithEventContext eventContext, Boolean isJsAction) { + public Mono createAction(ActionDTO actionDTO, AppsmithEventContext eventContext, Boolean isJsAction) { - return validateAndGenerateActionDomainBasedOnContext(action, isJsAction) + return validateAndGenerateActionDomainBasedOnContext(actionDTO, isJsAction) .flatMap(newAction -> { // If the datasource is embedded, check for workspaceId and set it in action - if (action.getDatasource() != null && action.getDatasource().getId() == null) { - Datasource datasource = action.getDatasource(); + if (actionDTO.getDatasource() != null + && actionDTO.getDatasource().getId() == null) { + Datasource datasource = actionDTO.getDatasource(); if (datasource.getWorkspaceId() == null) { return Mono.error( new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.WORKSPACE_ID)); @@ -396,12 +326,10 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE { // New actions will never be set to auto-magical execution, unless it is triggered via a // page or application clone event. if (!AppsmithEventContextType.CLONE_PAGE.equals(eventContext.getAppsmithEventContextType())) { - action.setExecuteOnLoad(false); + actionDTO.setExecuteOnLoad(false); } - newAction.setUnpublishedAction(action); - - newActionService.updateDefaultResourcesInAction(newAction); + newAction.setUnpublishedAction(actionDTO); return Mono.just(newAction); }) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCE.java index 104d2fe4a8..306032d92e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCE.java @@ -9,15 +9,11 @@ public interface LayoutCollectionServiceCE { Mono createCollection(ActionCollection actionCollection); - Mono createCollection(ActionCollectionDTO collection, String branchName); + Mono createCollection(ActionCollectionDTO collection); Mono moveCollection(ActionCollectionMoveDTO actionCollectionMoveDTO); - Mono moveCollection(ActionCollectionMoveDTO actionCollectionMoveDTO, String branchName); + Mono updateUnpublishedActionCollectionBody(String id, ActionCollectionDTO actionCollectionDTO); - Mono updateUnpublishedActionCollectionBody( - String id, ActionCollectionDTO actionCollectionDTO, String branchName); - - Mono updateUnpublishedActionCollection( - String id, ActionCollectionDTO actionCollectionDTO, String branchName); + Mono updateUnpublishedActionCollection(String id, ActionCollectionDTO actionCollectionDTO); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java index b41b1a540a..42a5d1b09a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java @@ -2,7 +2,6 @@ package com.appsmith.server.services.ce; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.CreatorContextType; -import com.appsmith.external.models.DefaultResources; import com.appsmith.server.actioncollections.base.ActionCollectionService; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.ActionCollection; @@ -13,7 +12,6 @@ import com.appsmith.server.dtos.ActionCollectionMoveDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.ContextTypeUtils; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.helpers.ce.bridge.Bridge; import com.appsmith.server.helpers.ce.bridge.BridgeUpdate; import com.appsmith.server.layouts.UpdateLayoutService; @@ -54,14 +52,10 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE protected final ActionCollectionService actionCollectionService; private final NewActionService newActionService; private final AnalyticsService analyticsService; - private final ResponseUtils responseUtils; private final ActionCollectionRepository actionCollectionRepository; private final PagePermission pagePermission; private final ActionPermission actionPermission; - /** - * Called by ActionCollection controller to create ActionCollection - */ @Override public Mono createCollection(ActionCollection actionCollection) { ActionCollectionDTO collectionDTO = actionCollection.getUnpublishedCollection(); @@ -125,21 +119,19 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE } @Override - public Mono createCollection(ActionCollectionDTO collectionDTO, String branchName) { + public Mono createCollection(ActionCollectionDTO collectionDTO) { if (collectionDTO.getId() != null) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID)); } - return validateAndCreateActionCollectionDomain(collectionDTO, branchName) + return validateAndCreateActionCollectionDomain(collectionDTO) .flatMap(actionCollection -> createCollection(actionCollection) .flatMap(actionCollectionDTO -> actionCollectionService .saveLastEditInformationInParent(actionCollectionDTO) - .thenReturn(actionCollectionDTO))) - .map(actionCollectionDTO -> responseUtils.updateCollectionDTOWithDefaultResources(actionCollectionDTO)); + .thenReturn(actionCollectionDTO))); } - protected Mono validateAndCreateActionCollectionDomain( - ActionCollectionDTO collectionDTO, String branchName) { + protected Mono validateAndCreateActionCollectionDomain(ActionCollectionDTO collectionDTO) { if (StringUtils.isEmpty(collectionDTO.getPageId())) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.PAGE_ID)); } @@ -152,14 +144,9 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE actionCollection.setUnpublishedCollection(collectionDTO); return newPageService - .findByBranchNameAndDefaultPageId( - branchName, collectionDTO.getPageId(), pagePermission.getActionCreatePermission()) + .findById(collectionDTO.getPageId(), pagePermission.getActionCreatePermission()) .map(branchedPage -> { - // Insert defaultPageId and defaultAppId from page - DefaultResources defaultResources = branchedPage.getDefaultResources(); - defaultResources.setBranchName(branchName); - collectionDTO.setDefaultResources(defaultResources); - actionCollection.setDefaultResources(defaultResources); + actionCollection.setBranchName(branchedPage.getBranchName()); actionCollectionService.generateAndSetPolicies(branchedPage, actionCollection); actionCollection.setUnpublishedCollection(collectionDTO); @@ -199,12 +186,6 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE .map(newAction -> newActionService.generateActionByViewMode(newAction, false)) .flatMap(actionDTO -> { actionDTO.setPageId(destinationPageId); - // Update default page ID in actions as per destination page object - actionDTO - .getDefaultResources() - .setPageId(destinationPage - .getDefaultResources() - .getPageId()); return newActionService .updateUnpublishedAction(actionDTO.getId(), actionDTO) .onErrorResume(throwable -> { @@ -219,10 +200,6 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE final String oldPageId = actionCollectionDTO.getPageId(); actionCollectionDTO.setPageId(destinationPageId); - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setPageId( - destinationPage.getDefaultResources().getPageId()); - actionCollectionDTO.setDefaultResources(defaultResources); actionCollectionDTO.setName(actionCollectionMoveDTO.getName()); return actionUpdatesFlux @@ -275,35 +252,7 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE } @Override - public Mono moveCollection( - ActionCollectionMoveDTO actionCollectionMoveDTO, String branchName) { - - Mono destinationPageMono = newPageService - .findByBranchNameAndDefaultPageId( - branchName, - actionCollectionMoveDTO.getDestinationPageId(), - pagePermission.getActionCreatePermission()) - .map(NewPage::getId); - - Mono branchedCollectionMono = actionCollectionService - .findByBranchNameAndDefaultCollectionId( - branchName, actionCollectionMoveDTO.getCollectionId(), actionPermission.getEditPermission()) - .map(ActionCollection::getId); - - return Mono.zip(destinationPageMono, branchedCollectionMono) - .flatMap(tuple -> { - String destinationPageId = tuple.getT1(); - String branchedCollectionId = tuple.getT2(); - actionCollectionMoveDTO.setDestinationPageId(destinationPageId); - actionCollectionMoveDTO.setCollectionId(branchedCollectionId); - return this.moveCollection(actionCollectionMoveDTO); - }) - .map(responseUtils::updateCollectionDTOWithDefaultResources); - } - - @Override - public Mono updateUnpublishedActionCollectionBody( - String id, ActionCollectionDTO actionCollectionDTO, String branchName) { + public Mono updateUnpublishedActionCollectionBody(String id, ActionCollectionDTO actionCollectionDTO) { if (id == null) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID)); @@ -318,7 +267,7 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE } Mono branchedActionCollectionMono = actionCollectionService - .findByBranchNameAndDefaultCollectionId(branchName, id, actionPermission.getEditPermission()) + .findById(id, actionPermission.getEditPermission()) .cache(); return branchedActionCollectionMono.flatMap(dbActionCollection -> { @@ -333,7 +282,7 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE @Override public Mono updateUnpublishedActionCollection( - String id, ActionCollectionDTO actionCollectionDTO, String branchName) { + String id, ActionCollectionDTO actionCollectionDTO) { // new actions without ids are to be created // new actions with ids are to be updated and added to collection // old actions that are now missing are to be archived @@ -343,16 +292,17 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE } Mono branchedActionCollectionMono = actionCollectionService - .findByBranchNameAndDefaultCollectionId(branchName, id, actionPermission.getEditPermission()) + .findById(id, actionPermission.getEditPermission()) + .switchIfEmpty(Mono.error( + new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ACTION_COLLECTION, id))) .cache(); - // It is expected that client will be aware of defaultActionIds and not the branched (actual) action ID - final Set validDefaultActionIds = actionCollectionDTO.getActions().stream() - .map(ActionDTO::getId) + final Set validBaseActionIds = actionCollectionDTO.getActions().stream() + .map(ActionDTO::getBaseId) .filter(Objects::nonNull) .collect(Collectors.toUnmodifiableSet()); - final Set defaultActionIds = new HashSet<>(); - defaultActionIds.addAll(validDefaultActionIds); + final Set baseActionIds = new HashSet<>(); + baseActionIds.addAll(validBaseActionIds); final Mono> newValidActionIdsMono = branchedActionCollectionMono.flatMap( branchedActionCollection -> Flux.fromIterable(actionCollectionDTO.getActions()) @@ -373,41 +323,33 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE actionCollectionDTO.getName() + "." + actionDTO.getName()); actionDTO.setPluginType(actionCollectionDTO.getPluginType()); actionDTO.setPluginId(actionCollectionDTO.getPluginId()); - actionDTO.setDefaultResources(branchedActionCollection.getDefaultResources()); - actionDTO.getDefaultResources().setBranchName(branchName); - final String defaultPageId = branchedActionCollection - .getUnpublishedCollection() - .getDefaultResources() - .getPageId(); - actionDTO.getDefaultResources().setPageId(defaultPageId); + actionDTO.setBranchName(branchedActionCollection.getBranchName()); // actionCollectionService is a new action, we need to create one return layoutActionService.createSingleAction(actionDTO, Boolean.TRUE); } else { actionDTO.setCollectionId(null); // Client only knows about the default action ID, fetch branched action id to update the // action - String defaultActionId = actionDTO.getId(); + String branchedActionId = actionDTO.getId(); actionDTO.setId(null); - return layoutActionService.updateSingleActionWithBranchName( - defaultActionId, actionDTO, branchName); + actionDTO.setBaseId(null); + return layoutActionService.updateNewActionByBranchedId(branchedActionId, actionDTO); } }) - .collect(toMap( - actionDTO -> actionDTO.getDefaultResources().getActionId(), ActionDTO::getId))); + .collect(toMap(actionDTO -> actionDTO.getBaseId(), ActionDTO::getId))); // First collect all valid action ids from before, and diff against incoming action ids Mono> deleteNonExistingActionMono = newActionService .findByCollectionIdAndViewMode(id, false, actionPermission.getEditPermission()) - .filter(newAction -> !defaultActionIds.contains( - newAction.getDefaultResources().getActionId())) + .filter(newAction -> !baseActionIds.contains(newAction.getBaseId())) .flatMap(x -> newActionService .deleteGivenNewAction(x) // return an empty action so that the filter can remove it from the list .onErrorResume(throwable -> { log.debug( "Failed to delete action with id {}, branch {} for collection: {}", - x.getDefaultResources().getActionId(), - branchName, + x.getBaseId(), + x.getBranchName(), actionCollectionDTO.getName()); log.error(throwable.getMessage()); return Mono.empty(); @@ -419,6 +361,7 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE .flatMap(tuple -> { return branchedActionCollectionMono.map(dbActionCollection -> { actionCollectionDTO.setId(null); + actionCollectionDTO.setBaseId(null); resetContextId(actionCollectionDTO); // Since we have a different endpoint to update the body, we need to remove it from the DTO actionCollectionDTO.setBody(null); @@ -442,8 +385,7 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE .flatMap(actionCollectionDTO2 -> actionCollectionService .saveLastEditInformationInParent(actionCollectionDTO2) .thenReturn(actionCollectionDTO2)))) - .flatMap(branchedActionCollection -> sendErrorReportsFromPageToCollection(branchedActionCollection)) - .map(responseUtils::updateCollectionDTOWithDefaultResources); + .flatMap(branchedActionCollection -> sendErrorReportsFromPageToCollection(branchedActionCollection)); } private Mono sendErrorReportsFromPageToCollection( diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCE.java index 63d3e38999..7b128e49b8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCE.java @@ -6,6 +6,4 @@ import reactor.core.publisher.Mono; public interface LayoutServiceCE { Mono getLayout(String pageId, String layoutId, Boolean viewMode); - - Mono getLayout(String defaultPageId, String layoutId, Boolean viewMode, String branchName); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCEImpl.java index 80b7f16367..c298798dba 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCEImpl.java @@ -4,12 +4,10 @@ import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.Layout; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.solutions.PagePermission; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import reactor.core.publisher.Mono; import java.util.List; @@ -19,7 +17,6 @@ import java.util.List; public class LayoutServiceCEImpl implements LayoutServiceCE { private final NewPageService newPageService; - private final ResponseUtils responseUtils; private final PagePermission pagePermission; @Override @@ -40,15 +37,4 @@ public class LayoutServiceCEImpl implements LayoutServiceCE { return matchedLayout; }); } - - @Override - public Mono getLayout(String defaultPageId, String layoutId, Boolean viewMode, String branchName) { - if (StringUtils.isEmpty(branchName)) { - return getLayout(defaultPageId, layoutId, viewMode); - } - return newPageService - .findByBranchNameAndDefaultPageId(branchName, defaultPageId, pagePermission.getEditPermission()) - .flatMap(branchedPage -> getLayout(branchedPage.getId(), layoutId, viewMode)) - .map(responseUtils::updateLayoutWithDefaultResources); - } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/PermissionGroupServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/PermissionGroupServiceCEImpl.java index 9b7ec6d0a5..34976f8fa6 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/PermissionGroupServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/PermissionGroupServiceCEImpl.java @@ -23,6 +23,7 @@ import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.PermissionGroupPermission; import com.appsmith.server.solutions.PolicySolution; import jakarta.validation.Validator; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.springframework.util.StringUtils; import reactor.core.publisher.Flux; @@ -39,6 +40,7 @@ import static com.appsmith.server.constants.FieldName.PERMISSION_GROUP_ID; import static com.appsmith.server.constants.FieldName.PUBLIC_PERMISSION_GROUP; import static java.lang.Boolean.TRUE; +@Slf4j public class PermissionGroupServiceCEImpl extends BaseService implements PermissionGroupServiceCE { @@ -150,12 +152,18 @@ public class PermissionGroupServiceCEImpl extends BaseService()); } } + protected void ensureAssignedToUserGroups(PermissionGroup permissionGroup) { + if (permissionGroup.getAssignedToGroupIds() == null) { + permissionGroup.setAssignedToUserIds(new HashSet<>()); + } + } + @Override public Mono bulkAssignToUsers(PermissionGroup pg, List users) { ensureAssignedToUserIds(pg); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/SessionUserServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/SessionUserServiceCEImpl.java index 082a22c507..e004fc9497 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/SessionUserServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/SessionUserServiceCEImpl.java @@ -60,6 +60,7 @@ public class SessionUserServiceCEImpl implements SessionUserServiceCE { user, currentToken.getAuthorities(), ((OAuth2AuthenticationToken) currentToken).getAuthorizedClientRegistrationId()); + // Here also update the userdata to contain the new access token. } else { log.error( "Unrecognized session token type when updating user in session: {}.", diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ApplicationServiceCECompatibleImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ApplicationServiceCECompatibleImpl.java index 2a1ae6cfd0..47158228e8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ApplicationServiceCECompatibleImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ApplicationServiceCECompatibleImpl.java @@ -1,7 +1,6 @@ package com.appsmith.server.services.ce_compatible; import com.appsmith.server.applications.base.ApplicationServiceCEImpl; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.repositories.ApplicationRepository; import com.appsmith.server.repositories.NewActionRepository; import com.appsmith.server.services.AnalyticsService; @@ -25,7 +24,6 @@ public class ApplicationServiceCECompatibleImpl extends ApplicationServiceCEImpl ApplicationRepository repository, AnalyticsService analyticsService, PolicySolution policySolution, - ResponseUtils responseUtils, PermissionGroupService permissionGroupService, NewActionRepository newActionRepository, AssetService assetService, @@ -40,7 +38,6 @@ public class ApplicationServiceCECompatibleImpl extends ApplicationServiceCEImpl repository, analyticsService, policySolution, - responseUtils, permissionGroupService, newActionRepository, assetService, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/CreateDBTablePageSolutionImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/CreateDBTablePageSolutionImpl.java index 69956e2ebe..de21fb2774 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/CreateDBTablePageSolutionImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/CreateDBTablePageSolutionImpl.java @@ -4,7 +4,6 @@ import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.datasources.base.DatasourceService; import com.appsmith.server.datasourcestorages.base.DatasourceStorageService; import com.appsmith.server.helpers.PluginExecutorHelper; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.migrations.JsonSchemaMigration; import com.appsmith.server.newpages.base.NewPageService; @@ -21,7 +20,6 @@ import org.springframework.stereotype.Service; @Slf4j public class CreateDBTablePageSolutionImpl extends CreateDBTablePageSolutionCEImpl implements CreateDBTablePageSolution { - public CreateDBTablePageSolutionImpl( DatasourceService datasourceService, DatasourceStorageService datasourceStorageService, @@ -33,7 +31,6 @@ public class CreateDBTablePageSolutionImpl extends CreateDBTablePageSolutionCEIm PluginService pluginService, AnalyticsService analyticsService, SessionUserService sessionUserService, - ResponseUtils responseUtils, PluginExecutorHelper pluginExecutorHelper, DatasourcePermission datasourcePermission, ApplicationPermission applicationPermission, @@ -52,7 +49,6 @@ public class CreateDBTablePageSolutionImpl extends CreateDBTablePageSolutionCEIm pluginService, analyticsService, sessionUserService, - responseUtils, pluginExecutorHelper, datasourcePermission, applicationPermission, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCE.java index 74b988eeb2..9c86491eb7 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCE.java @@ -13,11 +13,7 @@ import java.util.Map; public interface ActionExecutionSolutionCE { Mono executeAction( - Flux partFlux, - String branchName, - String environmentId, - HttpHeaders httpHeaders, - Boolean operateWithoutPermission); + Flux partFlux, String environmentId, HttpHeaders httpHeaders, Boolean operateWithoutPermission); Mono executeAction( ExecuteActionDTO executeActionDTO, ExecuteActionMetaDTO executeActionMetaDTO); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java index 47d1918bdb..6b31319f34 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java @@ -185,11 +185,7 @@ public class ActionExecutionSolutionCEImpl implements ActionExecutionSolutionCE ExecuteActionDTO executeActionDTO, ExecuteActionMetaDTO executeActionMetaDTO) { AclPermission executePermission = getPermission(executeActionMetaDTO, actionPermission.getExecutePermission()); Mono newActionMono = newActionService - .findByBranchNameAndDefaultActionId( - executeActionMetaDTO.getBranchName(), - executeActionDTO.getActionId(), - executeActionDTO.getViewMode(), - executePermission) + .findById(executeActionDTO.getActionId(), executePermission) .cache(); Mono populatedExecuteActionDTOMono = @@ -259,21 +255,15 @@ public class ActionExecutionSolutionCEImpl implements ActionExecutionSolutionCE * Executes the action(queries) by creating executeActionDTO and sending it to the plugin for further execution * * @param partFlux - * @param branchName * @param environmentId * @return Mono of actionExecutionResult if the query succeeds, error messages otherwise */ @Override public Mono executeAction( - Flux partFlux, - String branchName, - String environmentId, - HttpHeaders httpHeaders, - Boolean operateWithoutPermission) { + Flux partFlux, String environmentId, HttpHeaders httpHeaders, Boolean operateWithoutPermission) { ExecuteActionMetaDTO executeActionMetaDTO = ExecuteActionMetaDTO.builder() .headers(httpHeaders) .operateWithoutPermission(operateWithoutPermission) - .branchName(branchName) .environmentId(environmentId) .build(); Mono executeActionDTOMono = createExecuteActionDTO(partFlux); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/AuthenticationServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/AuthenticationServiceCE.java index 5cbea161ef..ef00e16667 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/AuthenticationServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/AuthenticationServiceCE.java @@ -21,7 +21,7 @@ public interface AuthenticationServiceCE { * @return a url String to continue the authorization flow */ Mono getAuthorizationCodeURLForGenericOAuth2( - String datasourceId, String environmentId, String pageId, String branchName, ServerHttpRequest httpRequest); + String datasourceId, String environmentId, String pageId, ServerHttpRequest httpRequest); /** * This is the method that handles callback for generic OAuth2. We will be retrieving and storing token information here @@ -36,7 +36,6 @@ public interface AuthenticationServiceCE { String datasourceId, String environmentId, RequestAppsmithTokenDTO requestAppsmithTokenDTO, - String branchName, HttpHeaders headers, String importForGit); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/AuthenticationServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/AuthenticationServiceCEImpl.java index 8259190b65..b78a629923 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/AuthenticationServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/AuthenticationServiceCEImpl.java @@ -12,7 +12,6 @@ import com.appsmith.external.models.BaseDomain; import com.appsmith.external.models.CreatorContextType; import com.appsmith.external.models.Datasource; import com.appsmith.external.models.DatasourceStorage; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.OAuth2; import com.appsmith.external.models.OAuth2ResponseDTO; import com.appsmith.external.models.PluginType; @@ -81,6 +80,7 @@ import static com.appsmith.external.constants.Authentication.RESPONSE_TYPE; import static com.appsmith.external.constants.Authentication.SCOPE; import static com.appsmith.external.constants.Authentication.STATE; import static com.appsmith.external.constants.Authentication.SUCCESS; +import static org.springframework.util.StringUtils.hasText; @RequiredArgsConstructor @Slf4j @@ -105,27 +105,30 @@ public class AuthenticationServiceCEImpl implements AuthenticationServiceCE { * when hitting the authorization url and redirect to it from the controller. * * @param datasourceId required to validate the details in the request and populate redirect url - * @param environmentId - * @param pageId Required to populate redirect url - * @param httpRequest Used to find the redirect domain + * @param environmentId environment from which the datasource authentication has started. + * @param branchedPageId required to populate redirect url + * @param httpRequest used to find the redirect domain * @return a url String to continue the authorization flow */ public Mono getAuthorizationCodeURLForGenericOAuth2( - String datasourceId, - String environmentId, - String pageId, - String branchName, - ServerHttpRequest httpRequest) { + String datasourceId, String environmentId, String branchedPageId, ServerHttpRequest httpRequest) { // This is the only database access that is controlled by ACL // The rest of the queries in this flow will not have context information Mono datasourceMonoCached = datasourceService .findById(datasourceId, datasourcePermission.getEditPermission()) .cache(); + Mono trueEnvironmentIdCached = datasourceMonoCached .flatMap(datasource -> datasourceService.getTrueEnvironmentId( datasource.getWorkspaceId(), environmentId, datasource.getPluginId(), null)) .cache(); + + Mono newPageMono = newPageService + .findById(branchedPageId, pagePermission.getReadPermission()) + .switchIfEmpty(Mono.error( + new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, branchedPageId))); + Mono workspaceIdMono = datasourceMonoCached.map(Datasource::getWorkspaceId); return datasourceMonoCached @@ -138,18 +141,32 @@ public class AuthenticationServiceCEImpl implements AuthenticationServiceCE { .switchIfEmpty(Mono.error( new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.DATASOURCE, datasourceId))) .flatMap(this::validateRequiredFieldsForGenericOAuth2) - .zipWith(Mono.zip(workspaceIdMono, trueEnvironmentIdCached)) + .zipWith(Mono.zip(workspaceIdMono, trueEnvironmentIdCached, newPageMono)) .flatMap(tuple2 -> { DatasourceStorage datasourceStorage = tuple2.getT1(); String workspaceId = tuple2.getT2().getT1(); String trueEnvironmentId = tuple2.getT2().getT2(); + NewPage branchedPage = tuple2.getT2().getT3(); + String branchName = null; + + if (hasText(branchedPage.getBranchName())) { + branchName = branchedPage.getBranchName(); + } + String basePageId = branchedPage.getBaseIdOrFallback(); + OAuth2 oAuth2 = (OAuth2) datasourceStorage.getDatasourceConfiguration().getAuthentication(); final String redirectUri = redirectHelper.getRedirectDomain(httpRequest.getHeaders()); final String state = StringUtils.hasText(branchName) ? String.join( - ",", pageId, datasourceId, trueEnvironmentId, redirectUri, workspaceId, branchName) - : String.join(",", pageId, datasourceId, trueEnvironmentId, redirectUri, workspaceId); + ",", + basePageId, + datasourceId, + trueEnvironmentId, + redirectUri, + workspaceId, + branchName) + : String.join(",", basePageId, datasourceId, trueEnvironmentId, redirectUri, workspaceId); // Adding basic uri components UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString( oAuth2.getAuthorizationUrl()) @@ -332,7 +349,7 @@ public class AuthenticationServiceCEImpl implements AuthenticationServiceCE { private Mono getPageRedirectUrl(String state, String error) { final String[] splitState = state.split(","); - final String pageId = splitState[0]; + final String basePageId = splitState[0]; final String datasourceId = splitState[1]; final String environmentId = splitState[2]; final String redirectOrigin = splitState[3]; @@ -344,19 +361,21 @@ public class AuthenticationServiceCEImpl implements AuthenticationServiceCE { } final String responseStatus = response; return newPageService - .findByIdAndBranchName(pageId, branchName) - .map(newPage -> redirectOrigin + Entity.SLASH + Entity.APPLICATIONS - + Entity.SLASH + newPage.getApplicationId() - + Entity.SLASH + Entity.PAGES - + Entity.SLASH + newPage.getId() - + Entity.SLASH + "edit" - + Entity.SLASH + Entity.DATASOURCE - + Entity.SLASH + datasourceId - + "?response_status=" - + responseStatus - + "&view_mode=true" - + (StringUtils.hasText(workspaceId) ? "&workspaceId=" + workspaceId : "") - + (StringUtils.hasText(branchName) ? "&branch=" + branchName : "")) + .findById(basePageId, pagePermission.getReadPermission()) + .map(basePage -> { + return redirectOrigin + Entity.SLASH + Entity.APPLICATIONS + + Entity.SLASH + basePage.getApplicationId() + + Entity.SLASH + Entity.PAGES + + Entity.SLASH + basePage.getId() + + Entity.SLASH + "edit" + + Entity.SLASH + Entity.DATASOURCE + + Entity.SLASH + datasourceId + + "?response_status=" + + responseStatus + + "&view_mode=true" + + (StringUtils.hasText(workspaceId) ? "&workspaceId=" + workspaceId : "") + + (StringUtils.hasText(branchName) ? "&branch=" + branchName : ""); + }) .onErrorResume(e -> Mono.just(redirectOrigin + Entity.SLASH + Entity.APPLICATIONS + "?response_status=" + responseStatus + "&view_mode=true")); @@ -367,7 +386,6 @@ public class AuthenticationServiceCEImpl implements AuthenticationServiceCE { String datasourceId, String environmentId, RequestAppsmithTokenDTO requestAppsmithTokenDTO, - String branchName, HttpHeaders headers, String importForGit) { // Check whether user has access to manage the datasource @@ -406,8 +424,6 @@ public class AuthenticationServiceCEImpl implements AuthenticationServiceCE { Plugin plugin = tuple.getT2(); IntegrationDTO integrationDTO = new IntegrationDTO(); integrationDTO.setInstallationKey(instanceId); - - integrationDTO.setBranch(branchName); integrationDTO.setImportForGit(importForGit); integrationDTO.setWorkspaceId(datasource.getWorkspaceId()); integrationDTO.setPluginName(plugin.getPluginName()); @@ -510,23 +526,45 @@ public class AuthenticationServiceCEImpl implements AuthenticationServiceCE { })); } - protected Mono getContext(String contextId, CreatorContextType contextType) { - return newPageService.findById(contextId, pagePermission.getReadPermission()); + /** + * Finds the new page from which the appsmith token request has been made + * @param branchedContextId : id of the branched Context, only applicable for git, else base id is used. + * @param contextType : context type of the request, in this case it's NewPage + * @return : An newPage for which the id is provided + */ + protected Mono getContext(String branchedContextId, CreatorContextType contextType) { + return newPageService + .findById(branchedContextId, pagePermission.getReadPermission()) + .flatMap(branchedPage -> { + // this would be the case for non git connected apps or base branch of a + // git connected app + if (branchedPage.getId().equals(branchedPage.getBaseIdOrFallback())) { + return Mono.just(branchedPage); + } + + return newPageService + .findById(branchedPage.getBaseIdOrFallback(), pagePermission.getReadPermission()) + .map(basePage -> { + NewPage pageRedirectionDTO = new NewPage(); + pageRedirectionDTO.setId(basePage.getId()); + pageRedirectionDTO.setBaseId(basePage.getBaseId()); + pageRedirectionDTO.setApplicationId(basePage.getApplicationId()); + // the branch name should come from the branched page as it is required for redirecting + pageRedirectionDTO.setBranchName(branchedPage.getBranchName()); + return pageRedirectionDTO; + }); + }); } protected IntegrationDTO associateIntegrationDTOWithContext( IntegrationDTO integrationDTO, BaseDomain baseDomain, CreatorContextType contextType) { - NewPage newPage = (NewPage) baseDomain; - DefaultResources defaultResources = newPage.getDefaultResources(); - String defaultPageId = - StringUtils.hasLength(defaultResources.getPageId()) ? defaultResources.getPageId() : newPage.getId(); + NewPage pageRedirectionDTO = (NewPage) baseDomain; + integrationDTO.setPageId(pageRedirectionDTO.getBaseIdOrFallback()); + integrationDTO.setApplicationId(pageRedirectionDTO.getApplicationId()); - String defaultApplicationId = StringUtils.hasLength(defaultResources.getApplicationId()) - ? defaultResources.getApplicationId() - : newPage.getApplicationId(); - - integrationDTO.setPageId(defaultPageId); - integrationDTO.setApplicationId(defaultApplicationId); + if (hasText(pageRedirectionDTO.getBranchName())) { + integrationDTO.setBranch(pageRedirectionDTO.getBranchName()); + } return integrationDTO; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/CreateDBTablePageSolutionCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/CreateDBTablePageSolutionCE.java index 8cf22dea92..e7cbec40de 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/CreateDBTablePageSolutionCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/CreateDBTablePageSolutionCE.java @@ -10,17 +10,17 @@ public interface CreateDBTablePageSolutionCE { * This function will clone template page along with the actions. DatasourceStructure is used to map the * templateColumns with the datasource under consideration * - * @param defaultPageId for which the template page needs to be replicated + * @param branchedPageId for which the template page needs to be replicated * @param pageResourceDTO * @param environmentId * @return generated pageDTO from the template resource */ Mono createPageFromDBTable( - String defaultPageId, CRUDPageResourceDTO pageResourceDTO, String environmentId, String branchName); + String branchedPageId, CRUDPageResourceDTO pageResourceDTO, String environmentId); // TODO Remove this interface, once the client handles environmentId changes Mono createPageFromDBTable( - String defaultPageId, + String basePageId, CRUDPageResourceDTO pageResourceDTO, String environmentId, String branchName, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/CreateDBTablePageSolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/CreateDBTablePageSolutionCEImpl.java index 159aafd1d0..6f26851a12 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/CreateDBTablePageSolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/CreateDBTablePageSolutionCEImpl.java @@ -13,7 +13,6 @@ import com.appsmith.external.models.DatasourceStructure; import com.appsmith.external.models.DatasourceStructure.Column; import com.appsmith.external.models.DatasourceStructure.PrimaryKey; import com.appsmith.external.models.DatasourceStructure.Table; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.Property; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.constants.Assets; @@ -32,7 +31,6 @@ import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.PluginExecutorHelper; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.migrations.JsonSchemaMigration; import com.appsmith.server.newpages.base.NewPageService; @@ -88,7 +86,6 @@ public class CreateDBTablePageSolutionCEImpl implements CreateDBTablePageSolutio private final PluginService pluginService; private final AnalyticsService analyticsService; private final SessionUserService sessionUserService; - private final ResponseUtils responseUtils; private final PluginExecutorHelper pluginExecutorHelper; private final DatasourcePermission datasourcePermission; private final ApplicationPermission applicationPermission; @@ -162,7 +159,7 @@ public class CreateDBTablePageSolutionCEImpl implements CreateDBTablePageSolutio .create(); public Mono createPageFromDBTable( - String defaultPageId, + String branchedPageId, CRUDPageResourceDTO pageResourceDTO, String environmentId, String branchName, @@ -178,23 +175,23 @@ public class CreateDBTablePageSolutionCEImpl implements CreateDBTablePageSolutio environmentPermission.getExecutePermission()); }) .flatMap(trueEnvironmentId -> - createPageFromDBTable(defaultPageId, pageResourceDTO, trueEnvironmentId, branchName)); + createPageFromDBTable(branchedPageId, pageResourceDTO, trueEnvironmentId)); } - return createPageFromDBTable(defaultPageId, pageResourceDTO, environmentId, branchName); + return createPageFromDBTable(branchedPageId, pageResourceDTO, environmentId); } /** * This function will clone template page along with the actions. DatasourceStructure is used to map the * templateColumns with the datasource under consideration * - * @param defaultPageId for which the template page needs to be replicated + * @param branchedPageId for which the template page needs to be replicated * @param pageResourceDTO * @param environmentId * @return generated pageDTO from the template resource */ public Mono createPageFromDBTable( - String defaultPageId, CRUDPageResourceDTO pageResourceDTO, String environmentId, String branchName) { + String branchedPageId, CRUDPageResourceDTO pageResourceDTO, String environmentId) { /* 1. Fetch page from the application @@ -218,7 +215,7 @@ public class CreateDBTablePageSolutionCEImpl implements CreateDBTablePageSolutio final String tableName = pageResourceDTO.getTableName(); final String datasourceId = pageResourceDTO.getDatasourceId(); - final String defaultApplicationId = pageResourceDTO.getApplicationId(); + final String branchedApplicationId = pageResourceDTO.getApplicationId(); final String searchColumn = pageResourceDTO.getSearchColumn(); final Set columns = pageResourceDTO.getColumns(); final Map pluginSpecificParams = pageResourceDTO.getPluginSpecificParams(); @@ -227,7 +224,7 @@ public class CreateDBTablePageSolutionCEImpl implements CreateDBTablePageSolutio Map mappedColumnsAndTableName = new HashMap<>(); // Fetch branched applicationId if connected to git - Mono pageMono = getOrCreatePage(defaultApplicationId, defaultPageId, tableName, branchName); + Mono pageMono = getOrCreatePage(branchedApplicationId, branchedPageId, tableName); Mono datasourceStorageMono = datasourceService .findById(datasourceId, datasourcePermission.getActionCreatePermission()) @@ -388,7 +385,7 @@ public class CreateDBTablePageSolutionCEImpl implements CreateDBTablePageSolutio .filter(newAction -> StringUtils.equalsIgnoreCase( newAction.getUnpublishedAction().getPageId(), plugin.getGenerateCRUDPageComponent())) - .peek(newAction -> newAction.setDefaultResources(page.getDefaultResources())) + .peek(newAction -> newAction.setBranchName(page.getBranchName())) .collect(Collectors.toList()); List templateUnpublishedActionConfigList = templateActionList.stream() @@ -448,27 +445,18 @@ public class CreateDBTablePageSolutionCEImpl implements CreateDBTablePageSolutio crudPage.setPage(pageDTO); createSuccessMessageAndSetAsset(plugin, crudPage); return sendGenerateCRUDPageAnalyticsEvent( - crudPage, datasourceStorage, plugin.getName()) - .map(res -> { - PageDTO sanitisedResponse = - responseUtils.updatePageDTOWithDefaultResources( - res.getPage()); - crudPage.setPage(sanitisedResponse); - return crudPage; - }); + crudPage, datasourceStorage, plugin.getName()); })); }); } /** - * @param defaultApplicationId application from which the page should be fetched - * @param defaultPageId default page for which equivalent branched page is going to be fetched + * @param branchedApplicationId application from which the page should be fetched + * @param branchedPageId default page for which equivalent branched page is going to be fetched * @param tableName if page is not present then name of the page name should include tableName - * @param branchName branch of which the page needs to be fetched * @return NewPage if not present already with the incremental suffix number to avoid duplicate application names */ - private Mono getOrCreatePage( - String defaultApplicationId, String defaultPageId, String tableName, String branchName) { + private Mono getOrCreatePage(String branchedApplicationId, String branchedPageId, String tableName) { /* 1. Check if the page is already available @@ -477,15 +465,14 @@ public class CreateDBTablePageSolutionCEImpl implements CreateDBTablePageSolutio */ log.debug( - "Fetching page from application {}, defaultPageId {}, branchName {}", - defaultApplicationId, - defaultPageId, - branchName); - if (defaultPageId != null) { + "Fetching page from branchedApplicationId {}, branchedPageId {}", + branchedApplicationId, + branchedPageId); + if (branchedPageId != null) { return newPageService - .findByBranchNameAndDefaultPageId(branchName, defaultPageId, pagePermission.getEditPermission()) + .findById(branchedPageId, pagePermission.getEditPermission()) .switchIfEmpty(Mono.error( - new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, defaultPageId))) + new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.PAGE, branchedPageId))) .map(newPage -> { Layout layout = newPage.getUnpublishedPage().getLayouts().get(0); @@ -499,38 +486,38 @@ public class CreateDBTablePageSolutionCEImpl implements CreateDBTablePageSolutio } return applicationService - .findBranchedApplicationId( - branchName, defaultApplicationId, applicationPermission.getPageCreatePermission()) + .findById(branchedApplicationId, applicationPermission.getPageCreatePermission()) .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, defaultApplicationId))) - .flatMapMany(childApplicationId -> newPageService.findByApplicationId( - childApplicationId, pagePermission.getEditPermission(), false)) - .collectList() - .flatMap(pages -> { - // Avoid duplicating page names - String applicationId = pages.get(0).getApplicationId(); - String pageName = WordUtils.capitalize(tableName); - long maxCount = 0L; - for (PageDTO pageDTO : pages) { - if (pageDTO.getName().matches("^" + Pattern.quote(pageName) + "\\d*$")) { - long count = 1L; - String pageCount = pageDTO.getName().substring(pageName.length()); - if (!pageCount.isEmpty()) { - count = Long.parseLong(pageCount); + AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, branchedApplicationId))) + .flatMap(branchedApplication -> newPageService + .findByApplicationId(branchedApplicationId, pagePermission.getEditPermission(), false) + .collectList() + .flatMap(pages -> { + // Avoid duplicating page names + String applicationId = pages.get(0).getApplicationId(); + String pageName = WordUtils.capitalize(tableName); + long maxCount = 0L; + for (PageDTO pageDTO : pages) { + if (pageDTO.getName().matches("^" + Pattern.quote(pageName) + "\\d*$")) { + long count = 1L; + String pageCount = pageDTO.getName().substring(pageName.length()); + if (!pageCount.isEmpty()) { + count = Long.parseLong(pageCount); + } + maxCount = maxCount <= count ? count + 1 : maxCount; + } } - maxCount = maxCount <= count ? count + 1 : maxCount; - } - } - pageName = maxCount != 0 ? pageName + maxCount : pageName; - PageDTO page = new PageDTO(); - page.setApplicationId(applicationId); - page.setName(pageName); - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setBranchName(branchName); - defaultResources.setApplicationId(defaultApplicationId); - page.setDefaultResources(defaultResources); - return applicationPageService.createPage(page); - }) + pageName = maxCount != 0 ? pageName + maxCount : pageName; + PageDTO page = new PageDTO(); + page.setApplicationId(applicationId); + page.setName(pageName); + if (branchedApplication.getGitArtifactMetadata() != null) { + page.setBranchName(branchedApplication + .getGitArtifactMetadata() + .getBranchName()); + } + return applicationPageService.createPage(page); + })) .flatMap(pageDTO -> newPageService.findById(pageDTO.getId(), pagePermission.getEditPermission())); } @@ -609,10 +596,11 @@ public class CreateDBTablePageSolutionCEImpl implements CreateDBTablePageSolutio templateAction.getUnpublishedAction().getActionConfiguration(); actionDTO.setPluginId(datasourceStorage.getPluginId()); actionDTO.setId(null); + actionDTO.setBaseId(null); actionDTO.setDatasource(datasourceService.createDatasourceFromDatasourceStorage(datasourceStorage)); actionDTO.setPageId(pageId); actionDTO.setName(templateAction.getUnpublishedAction().getName()); - actionDTO.setDefaultResources(templateAction.getDefaultResources()); + actionDTO.setBranchName(templateAction.getBranchName()); // Indicates that source of action creation is generate-crud-page actionDTO.setSource(ActionCreationSourceTypeEnum.GENERATE_PAGE); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceStructureSolutionCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceStructureSolutionCE.java index 79f78f948e..79f7c67fa8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceStructureSolutionCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceStructureSolutionCE.java @@ -8,7 +8,7 @@ import reactor.core.publisher.Mono; public interface DatasourceStructureSolutionCE { - Mono getStructure(String datasourceId, boolean ignoreCache, String environmentName); + Mono getStructure(String datasourceId, boolean ignoreCache, String environmentId); Mono getStructure(DatasourceStorage datasourceStorage, boolean ignoreCache); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/themes/base/ThemeServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/themes/base/ThemeServiceCE.java index a9c7719737..683a1b6a23 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/themes/base/ThemeServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/themes/base/ThemeServiceCE.java @@ -11,17 +11,21 @@ import reactor.core.publisher.Mono; public interface ThemeServiceCE extends CrudService { Mono getApplicationTheme(String applicationId, ApplicationMode applicationMode, String branchName); + Mono getApplicationTheme(String branchedApplicationId, ApplicationMode applicationMode); + Flux getApplicationThemes(String applicationId, String branchName); + Flux getApplicationThemes(String branchedApplicationId); + Flux getSystemThemes(); Mono archiveById(String themeId); Mono getSystemTheme(String themeName); - Mono updateTheme(String applicationId, String branchName, Theme resource); + Mono updateTheme(String branchedApplicationId, Theme resource); - Mono changeCurrentTheme(String themeId, String applicationId, String branchName); + Mono changeCurrentTheme(String themeId, String branchedApplicationId); /** * Returns a themeId that was fetched earlier and stored to cache. diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/themes/base/ThemeServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/themes/base/ThemeServiceCEImpl.java index e0ff971cc7..97b3215c32 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/themes/base/ThemeServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/themes/base/ThemeServiceCEImpl.java @@ -69,7 +69,7 @@ public class ThemeServiceCEImpl extends BaseService getApplicationTheme(String applicationId, ApplicationMode applicationMode, String branchName) { return applicationService - .findByBranchNameAndDefaultApplicationId( + .findByBranchNameAndBaseApplicationId( branchName, applicationId, applicationPermission.getReadPermission()) .switchIfEmpty(Mono.error( new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, applicationId))) @@ -88,40 +88,66 @@ public class ThemeServiceCEImpl extends BaseService getApplicationTheme(String branchedApplicationId, ApplicationMode applicationMode) { + return applicationService + .findById(branchedApplicationId, applicationPermission.getReadPermission()) + .switchIfEmpty(Mono.error(new AppsmithException( + AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.APPLICATION, branchedApplicationId))) + .flatMap(application -> { + String themeId = application.getEditModeThemeId(); + if (applicationMode == ApplicationMode.PUBLISHED) { + themeId = application.getPublishedModeThemeId(); + } + if (StringUtils.hasLength(themeId)) { + return repository + .findById(themeId, READ_THEMES) + .switchIfEmpty(repository.getSystemThemeByName(Theme.DEFAULT_THEME_NAME, READ_THEMES)); + } else { // theme id is not present, return default theme + return repository.getSystemThemeByName(Theme.DEFAULT_THEME_NAME, READ_THEMES); + } + }); + } + @Override public Flux getApplicationThemes(String applicationId, String branchName) { return applicationService - .findByBranchNameAndDefaultApplicationId( + .findByBranchNameAndBaseApplicationId( branchName, applicationId, applicationPermission.getReadPermission()) .flatMapMany(application -> repository.getApplicationThemes(application.getId(), READ_THEMES)); } + @Override + public Flux getApplicationThemes(String branchedApplicationId) { + return applicationService + .findById(branchedApplicationId, applicationPermission.getReadPermission()) + .flatMapMany(application -> repository.getApplicationThemes(application.getId(), READ_THEMES)); + } + @Override public Flux getSystemThemes() { return repository.getSystemThemes(READ_THEMES); } @Override - public Mono updateTheme(String applicationId, String branchName, Theme resource) { + public Mono updateTheme(String branchedApplicationId, Theme resource) { return applicationService - .findByBranchNameAndDefaultApplicationId( - branchName, applicationId, applicationPermission.getEditPermission()) + .findById(branchedApplicationId, applicationPermission.getEditPermission()) .flatMap(application -> { // makes sure user has permission to edit application and an application exists by this // applicationId - // check if this application has already a customized them + // check if this application has already a customized theme return saveThemeForApplication( application.getEditModeThemeId(), resource, application, ApplicationMode.EDIT); }); } @Override - public Mono changeCurrentTheme(String newThemeId, String applicationId, String branchName) { + public Mono changeCurrentTheme(String newThemeId, String branchedApplicationId) { return applicationService - .findByBranchNameAndDefaultApplicationId( - branchName, applicationId, applicationPermission.getEditPermission()) - .switchIfEmpty(Mono.error( - new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, applicationId))) + .findById(branchedApplicationId, applicationPermission.getEditPermission()) + .switchIfEmpty(Mono.error(new AppsmithException( + AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, branchedApplicationId))) .flatMap(application -> repository .findById(application.getEditModeThemeId(), READ_THEMES) .defaultIfEmpty(new Theme()) @@ -322,7 +348,7 @@ public class ThemeServiceCEImpl extends BaseService persistCurrentTheme(String applicationId, String branchName, Theme resource) { return applicationService - .findByBranchNameAndDefaultApplicationId( + .findByBranchNameAndBaseApplicationId( branchName, applicationId, applicationPermission.getEditPermission()) .switchIfEmpty(Mono.error( new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.APPLICATION, applicationId))) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/widgets/refactors/WidgetRefactoringServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/widgets/refactors/WidgetRefactoringServiceCEImpl.java index f6cb1d59a5..43535467c6 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/widgets/refactors/WidgetRefactoringServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/widgets/refactors/WidgetRefactoringServiceCEImpl.java @@ -95,7 +95,7 @@ public class WidgetRefactoringServiceCEImpl implements EntityRefactoringServiceC } @Override - public Mono updateRefactoredEntity(RefactorEntityNameDTO refactorEntityNameDTO, String branchName) { + public Mono updateRefactoredEntity(RefactorEntityNameDTO refactorEntityNameDTO) { // Do nothing, DSL refactor will take care of this return Mono.empty().then(); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/controllers/PageControllerTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/controllers/PageControllerTest.java index 17af15ff68..642288dec3 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/controllers/PageControllerTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/controllers/PageControllerTest.java @@ -218,9 +218,7 @@ public class PageControllerTest { @Test @WithMockUser void emptyCustomSlugShouldBeOkay() { - doReturn(Mono.just(new PageDTO())) - .when(newPageService) - .updatePageByDefaultPageIdAndBranch(anyString(), any(), anyString()); + doReturn(Mono.just(new PageDTO())).when(newPageService).updatePage(anyString(), any()); client.put() .uri("/api/v1/pages/abcdef") @@ -228,6 +226,6 @@ public class PageControllerTest { .body(BodyInserters.fromValue(Map.of("customSlug", ""))) .exchange(); - verify(newPageService, times(1)).updatePageByDefaultPageIdAndBranch(eq("abcdef"), any(), eq(null)); + verify(newPageService, times(1)).updatePage(eq("abcdef"), any()); } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/exports/internal/ExportServiceTests.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/exports/internal/ExportServiceTests.java index fec54983fa..025e3d11f9 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/exports/internal/ExportServiceTests.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/exports/internal/ExportServiceTests.java @@ -309,7 +309,8 @@ public class ExportServiceTests { // Make the application public applicationService - .changeViewAccess(createdApplication.getId(), applicationAccessDTO) + .changeViewAccessForSingleBranchByBranchedApplicationId( + createdApplication.getId(), applicationAccessDTO) .block(); Mono resultMono = exportService @@ -489,7 +490,7 @@ public class ExportServiceTests { actionCollectionDTO1.setPluginType(PluginType.JS); return layoutCollectionService - .createCollection(actionCollectionDTO1, null) + .createCollection(actionCollectionDTO1) .then(layoutActionService.createSingleAction(action, Boolean.FALSE)) .then(layoutActionService.createSingleAction(action2, Boolean.FALSE)) .then(updateLayoutService.updateLayout( @@ -887,13 +888,11 @@ public class ExportServiceTests { final String branchName = application.getGitApplicationMetadata().getBranchName(); pageList.forEach(page -> { - assertThat(page.getDefaultResources()).isNotNull(); - assertThat(page.getDefaultResources().getBranchName()).isEqualTo(branchName); + assertThat(page.getBranchName()).isEqualTo(branchName); }); actionList.forEach(action -> { - assertThat(action.getDefaultResources()).isNotNull(); - assertThat(action.getDefaultResources().getBranchName()).isEqualTo(branchName); + assertThat(action.getBranchName()).isEqualTo(branchName); }); }) .verifyComplete(); @@ -953,7 +952,7 @@ public class ExportServiceTests { ApplicationAccessDTO applicationAccessDTO = new ApplicationAccessDTO(); applicationAccessDTO.setPublicAccess(true); Application newApplication = applicationService - .changeViewAccess(application.getId(), "master", applicationAccessDTO) + .changeViewAccessForAllBranchesByBranchedApplicationId(application.getId(), applicationAccessDTO) .block(); PermissionGroup anonymousPermissionGroup = @@ -1022,7 +1021,7 @@ public class ExportServiceTests { ApplicationAccessDTO accessDTO = new ApplicationAccessDTO(); accessDTO.setPublicAccess(true); applicationService - .changeViewAccess(exportWithConfigurationAppId, accessDTO) + .changeViewAccessForSingleBranchByBranchedApplicationId(exportWithConfigurationAppId, accessDTO) .block(); final String appName = testApplication.getName(); final Mono resultMono = Mono.zip( @@ -1089,7 +1088,7 @@ public class ExportServiceTests { actionCollectionDTO1.setPluginType(PluginType.JS); return layoutCollectionService - .createCollection(actionCollectionDTO1, null) + .createCollection(actionCollectionDTO1) .then(layoutActionService.createSingleAction(action, Boolean.FALSE)) .then(layoutActionService.createSingleAction(action2, Boolean.FALSE)) .then(updateLayoutService.updateLayout( @@ -1317,10 +1316,10 @@ public class ExportServiceTests { // Set order for the newly created pages applicationPageService - .reorderPage(testApplication.getId(), testPage1.getId(), 0, null) + .reorderPage(testApplication.getId(), testPage1.getId(), 0) .block(); applicationPageService - .reorderPage(testApplication.getId(), testPage2.getId(), 1, null) + .reorderPage(testApplication.getId(), testPage2.getId(), 1) .block(); // Deploy the current application applicationPageService.publish(testApplication.getId(), true).block(); @@ -1549,10 +1548,10 @@ public class ExportServiceTests { // Set order for the newly created pages applicationPageService - .reorderPage(testApplication.getId(), testPage1.getId(), 0, null) + .reorderPage(testApplication.getId(), testPage1.getId(), 0) .block(); applicationPageService - .reorderPage(testApplication.getId(), testPage2.getId(), 1, null) + .reorderPage(testApplication.getId(), testPage2.getId(), 1) .block(); Mono applicationJsonMono = exportService @@ -1689,7 +1688,7 @@ public class ExportServiceTests { ApplicationAccessDTO accessDTO = new ApplicationAccessDTO(); accessDTO.setPublicAccess(true); return applicationService - .changeViewAccess(application.getId(), accessDTO) + .changeViewAccessForSingleBranchByBranchedApplicationId(application.getId(), accessDTO) .thenReturn(application); }); @@ -1837,7 +1836,7 @@ public class ExportServiceTests { public void createExportAppJsonWithCustomJSLibTest() { CustomJSLib jsLib = new CustomJSLib("TestLib", Set.of("accessor1"), "url", "docsUrl", "1.0", "defs_string"); Mono addJSLibMonoCached = customJSLibService - .addJSLibsToContext(testAppId, CreatorContextType.APPLICATION, Set.of(jsLib), null, false) + .addJSLibsToContext(testAppId, CreatorContextType.APPLICATION, Set.of(jsLib), false) .flatMap(isJSLibAdded -> Mono.zip(Mono.just(isJSLibAdded), applicationPageService.publish(testAppId, true))) .map(tuple2 -> { @@ -1910,7 +1909,7 @@ public class ExportServiceTests { action1.getActionConfiguration().setBody("mockBody"); actionCollectionDTO1.setActions(List.of(action1)); actionCollectionDTO1.setPluginType(PluginType.JS); - return layoutCollectionService.createCollection(actionCollectionDTO1, null); + return layoutCollectionService.createCollection(actionCollectionDTO1); } @Test diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/fork/ApplicationForkingServiceTests.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/fork/ApplicationForkingServiceTests.java index 6c85210be5..e303be7d49 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/fork/ApplicationForkingServiceTests.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/fork/ApplicationForkingServiceTests.java @@ -70,7 +70,6 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; -import org.apache.commons.lang.StringUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; @@ -316,7 +315,7 @@ public class ApplicationForkingServiceTests { actionCollectionDTO.setActions(List.of(action1)); actionCollectionDTO.setPluginType(PluginType.JS); - layoutCollectionService.createCollection(actionCollectionDTO, null).block(); + layoutCollectionService.createCollection(actionCollectionDTO).block(); ObjectMapper objectMapper = new ObjectMapper(); JSONObject parentDsl = new JSONObject( @@ -394,57 +393,17 @@ public class ApplicationForkingServiceTests { assertThat(pageList).isNotEmpty(); pageList.forEach(newPage -> { - assertThat(newPage.getDefaultResources()).isNotNull(); - assertThat(newPage.getDefaultResources().getPageId()).isEqualTo(newPage.getId()); - assertThat(newPage.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); - - newPage.getUnpublishedPage().getLayouts().forEach(layout -> { - assertThat(layout.getLayoutOnLoadActions()).hasSize(2); - layout.getLayoutOnLoadActions().forEach(dslActionDTOS -> { - assertThat(dslActionDTOS).hasSize(1); - dslActionDTOS.forEach(actionDTO -> { - assertThat(actionDTO.getId()).isEqualTo(actionDTO.getDefaultActionId()); - if (!StringUtils.isEmpty(actionDTO.getCollectionId())) { - assertThat(actionDTO.getCollectionId()) - .isEqualTo(actionDTO.getDefaultCollectionId()); - } - }); - }); - }); + assertThat(newPage.getBaseId()).isEqualTo(newPage.getId()); }); assertThat(actionList).hasSize(2); actionList.forEach(newAction -> { - assertThat(newAction.getDefaultResources()).isNotNull(); - assertThat(newAction.getDefaultResources().getActionId()) - .isEqualTo(newAction.getId()); - assertThat(newAction.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); - - ActionDTO action = newAction.getUnpublishedAction(); - assertThat(action.getDefaultResources()).isNotNull(); - assertThat(action.getDefaultResources().getPageId()) - .isEqualTo(application.getPages().get(0).getId()); - if (!StringUtils.isEmpty(action.getDefaultResources().getCollectionId())) { - assertThat(action.getDefaultResources().getCollectionId()) - .isEqualTo(action.getCollectionId()); - } + assertThat(newAction.getBaseId()).isEqualTo(newAction.getId()); }); assertThat(actionCollectionList).hasSize(1); actionCollectionList.forEach(actionCollection -> { - assertThat(actionCollection.getDefaultResources()).isNotNull(); - assertThat(actionCollection.getDefaultResources().getCollectionId()) - .isEqualTo(actionCollection.getId()); - assertThat(actionCollection.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); - - ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - - assertThat(unpublishedCollection.getDefaultResources()).isNotNull(); - assertThat(unpublishedCollection.getDefaultResources().getPageId()) - .isEqualTo(application.getPages().get(0).getId()); + assertThat(actionCollection.getBaseId()).isEqualTo(actionCollection.getId()); }); }) .verifyComplete(); @@ -573,50 +532,17 @@ public class ApplicationForkingServiceTests { assertThat(pageList).isNotEmpty(); pageList.forEach(newPage -> { - assertThat(newPage.getDefaultResources()).isNotNull(); - assertThat(newPage.getDefaultResources().getPageId()).isEqualTo(newPage.getId()); - assertThat(newPage.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); - - newPage.getUnpublishedPage().getLayouts().forEach(layout -> layout.getLayoutOnLoadActions() - .forEach(dslActionDTOS -> { - dslActionDTOS.forEach(actionDTO -> { - assertThat(actionDTO.getId()).isEqualTo(actionDTO.getDefaultActionId()); - }); - })); + assertThat(newPage.getBaseId()).isEqualTo(newPage.getId()); }); assertThat(actionList).hasSize(2); actionList.forEach(newAction -> { - assertThat(newAction.getDefaultResources()).isNotNull(); - assertThat(newAction.getDefaultResources().getActionId()) - .isEqualTo(newAction.getId()); - assertThat(newAction.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); - - ActionDTO action = newAction.getUnpublishedAction(); - assertThat(action.getDefaultResources()).isNotNull(); - assertThat(action.getDefaultResources().getPageId()) - .isEqualTo(application.getPages().get(0).getId()); - if (!StringUtils.isEmpty(action.getDefaultResources().getCollectionId())) { - assertThat(action.getDefaultResources().getCollectionId()) - .isEqualTo(action.getCollectionId()); - } + assertThat(newAction.getBaseId()).isEqualTo(newAction.getId()); }); assertThat(actionCollectionList).hasSize(1); actionCollectionList.forEach(actionCollection -> { - assertThat(actionCollection.getDefaultResources()).isNotNull(); - assertThat(actionCollection.getDefaultResources().getCollectionId()) - .isEqualTo(actionCollection.getId()); - assertThat(actionCollection.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); - - ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - - assertThat(unpublishedCollection.getDefaultResources()).isNotNull(); - assertThat(unpublishedCollection.getDefaultResources().getPageId()) - .isEqualTo(application.getPages().get(0).getId()); + assertThat(actionCollection.getBaseId()).isEqualTo(actionCollection.getId()); }); }) .verifyComplete(); @@ -645,7 +571,7 @@ public class ApplicationForkingServiceTests { NewPage updatedGitAppPage = newPageRepository.save(appPage).block(); final Mono resultMono = - applicationForkingService.forkApplicationToWorkspace(sourceAppId, targetWorkspace.getId(), null); + applicationForkingService.forkApplicationToWorkspace(sourceAppId, targetWorkspace.getId()); StepVerifier.create(resultMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -691,7 +617,7 @@ public class ApplicationForkingServiceTests { workspaceRepository.save(targetWorkspace).block(); final Mono resultMono = - applicationForkingService.forkApplicationToWorkspace(sourceAppId, targetWorkspace.getId(), null); + applicationForkingService.forkApplicationToWorkspace(sourceAppId, targetWorkspace.getId()); StepVerifier.create(resultMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -743,7 +669,7 @@ public class ApplicationForkingServiceTests { Theme theme = new Theme(); theme.setDisplayName("theme_" + uniqueString); - themeService.updateTheme(createdSrcApplication.getId(), null, theme).block(); + themeService.updateTheme(createdSrcApplication.getId(), theme).block(); createdSrcApplication = applicationService.findById(srcApplication.getId()).block(); @@ -898,7 +824,7 @@ public class ApplicationForkingServiceTests { Theme theme = new Theme(); theme.setDisplayName("theme_" + uniqueString); - themeService.updateTheme(createdSrcApplication.getId(), null, theme).block(); + themeService.updateTheme(createdSrcApplication.getId(), theme).block(); themeService .persistCurrentTheme(createdSrcApplication.getId(), null, theme) .block(); @@ -1085,7 +1011,7 @@ public class ApplicationForkingServiceTests { gitArtifactMetadata.setGitAuth(gitAuth); createdSrcApplication.setGitApplicationMetadata(gitArtifactMetadata); - themeService.updateTheme(createdSrcApplication.getId(), null, theme).block(); + themeService.updateTheme(createdSrcApplication.getId(), theme).block(); createdSrcApplication = applicationService.save(createdSrcApplication).block(); // Create a branch application @@ -1874,9 +1800,9 @@ public class ApplicationForkingServiceTests { return applicationService .findByWorkspaceId(workspace.getId(), READ_APPLICATIONS) // fetch the unpublished pages - .flatMap(application -> newPageService.findByApplicationId(application.getId(), READ_PAGES, false)) - .flatMap(page -> actionCollectionService.getPopulatedActionCollectionsByViewMode( - new LinkedMultiValueMap<>(Map.of(FieldName.PAGE_ID, Collections.singletonList(page.getId()))), + .flatMap(application -> actionCollectionService.getPopulatedActionCollectionsByViewMode( + new LinkedMultiValueMap<>( + Map.of(FieldName.APPLICATION_ID, Collections.singletonList(application.getId()))), false)); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/git/CommonGitServiceCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/git/CommonGitServiceCETest.java index 8f60bce8a2..570f86e28b 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/git/CommonGitServiceCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/git/CommonGitServiceCETest.java @@ -9,7 +9,6 @@ import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.Datasource; import com.appsmith.external.models.DatasourceConfiguration; import com.appsmith.external.models.DatasourceStorageDTO; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.JSValue; import com.appsmith.external.models.PluginType; import com.appsmith.external.models.Policy; @@ -46,7 +45,6 @@ import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.git.common.CommonGitServiceCE; -import com.appsmith.server.helpers.CollectionUtils; import com.appsmith.server.helpers.CommonGitFileUtils; import com.appsmith.server.helpers.GitCloudServicesUtils; import com.appsmith.server.helpers.MockPluginExecutor; @@ -1224,13 +1222,8 @@ public class CommonGitServiceCETest { action.setActionConfiguration(actionConfiguration); action.setDatasource(datasource); - DefaultResources branchedResources = new DefaultResources(); - branchedResources.setActionId("branchedActionId"); - branchedResources.setApplicationId("branchedAppId"); - branchedResources.setPageId("branchedPageId"); - branchedResources.setCollectionId("branchedCollectionId"); - branchedResources.setBranchName("testBranch"); - action.setDefaultResources(branchedResources); + action.setBaseId("branchedActionId"); + action.setBranchName("testBranch"); ObjectMapper objectMapper = new ObjectMapper(); JSONObject parentDsl = null; @@ -1268,7 +1261,6 @@ public class CommonGitServiceCETest { action1.getActionConfiguration().setBody("mockBody"); actionCollectionDTO.setActions(List.of(action1)); actionCollectionDTO.setPluginType(PluginType.JS); - actionCollectionDTO.setDefaultResources(branchedResources); return Mono.zip( layoutActionService @@ -1278,9 +1270,12 @@ public class CommonGitServiceCETest { testPage.getApplicationId(), layout.getId(), layout)), - layoutCollectionService.createCollection(actionCollectionDTO, null)) + layoutCollectionService.createCollection(actionCollectionDTO)) .map(tuple2 -> application); - }); + }) + .cache(); + + Mockito.doReturn(applicationMono).when(applicationService).findById(eq("TestId"), any(AclPermission.class)); Mono resultMono = applicationMono.flatMap(application -> commonGitServiceCE .detachRemote(application.getId(), ArtifactType.APPLICATION) @@ -1310,56 +1305,20 @@ public class CommonGitServiceCETest { assertThat(pageList).isNotNull(); pageList.forEach(newPage -> { - assertThat(newPage.getDefaultResources()).isNotNull(); - assertThat(newPage.getDefaultResources().getPageId()).isEqualTo(newPage.getId()); - assertThat(newPage.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); - assertThat(newPage.getDefaultResources().getBranchName()) - .isNullOrEmpty(); - - newPage.getUnpublishedPage().getLayouts().forEach(layout -> layout.getLayoutOnLoadActions() - .forEach(dslActionDTOS -> { - dslActionDTOS.forEach(actionDTO -> { - assertThat(actionDTO.getId()).isEqualTo(actionDTO.getDefaultActionId()); - }); - })); + assertThat(newPage.getBaseId()).isEqualTo(newPage.getId()); + assertThat(newPage.getBranchName()).isNullOrEmpty(); }); assertThat(actionList).hasSize(2); actionList.forEach(newAction -> { - assertThat(newAction.getDefaultResources()).isNotNull(); - assertThat(newAction.getDefaultResources().getActionId()) - .isEqualTo(newAction.getId()); - assertThat(newAction.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); - assertThat(newAction.getDefaultResources().getBranchName()) - .isNullOrEmpty(); - - ActionDTO action = newAction.getUnpublishedAction(); - assertThat(action.getDefaultResources()).isNotNull(); - assertThat(action.getDefaultResources().getPageId()) - .isEqualTo(application.getPages().get(0).getId()); - if (!StringUtils.isEmpty(action.getDefaultResources().getCollectionId())) { - assertThat(action.getDefaultResources().getCollectionId()) - .isEqualTo(action.getCollectionId()); - } + assertThat(newAction.getBaseId()).isEqualTo(newAction.getId()); + assertThat(newAction.getBranchName()).isNullOrEmpty(); }); assertThat(actionCollectionList).hasSize(1); actionCollectionList.forEach(actionCollection -> { - assertThat(actionCollection.getDefaultResources()).isNotNull(); - assertThat(actionCollection.getDefaultResources().getCollectionId()) - .isEqualTo(actionCollection.getId()); - assertThat(actionCollection.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); - assertThat(actionCollection.getDefaultResources().getBranchName()) - .isNullOrEmpty(); - - ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - - assertThat(unpublishedCollection.getDefaultResources()).isNotNull(); - assertThat(unpublishedCollection.getDefaultResources().getPageId()) - .isEqualTo(application.getPages().get(0).getId()); + assertThat(actionCollection.getBaseId()).isEqualTo(actionCollection.getId()); + assertThat(actionCollection.getBranchName()).isNullOrEmpty(); }); }) .verifyComplete(); @@ -1396,8 +1355,8 @@ public class CommonGitServiceCETest { Application application1 = applicationPageService.createApplication(testApplication).block(); - Mono> listMono = commonGitServiceCE.listBranchForArtifact( - application1.getId(), false, "defaultBranch", ArtifactType.APPLICATION); + Mono> listMono = + commonGitServiceCE.listBranchForArtifact(application1.getId(), false, ArtifactType.APPLICATION); StepVerifier.create(listMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -1424,8 +1383,8 @@ public class CommonGitServiceCETest { Application application1 = applicationPageService.createApplication(testApplication).block(); - Mono> listMono = commonGitServiceCE.listBranchForArtifact( - application1.getId(), false, "defaultBranch", ArtifactType.APPLICATION); + Mono> listMono = + commonGitServiceCE.listBranchForArtifact(application1.getId(), false, ArtifactType.APPLICATION); StepVerifier.create(listMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -1469,8 +1428,8 @@ public class CommonGitServiceCETest { Application application1 = createApplicationConnectedToGit( "listBranchForArtifact_pruneBranchNoChangesInRemote_Success", "defaultBranch"); - Mono> listMono = commonGitServiceCE.listBranchForArtifact( - application1.getId(), true, "defaultBranch", ArtifactType.APPLICATION); + Mono> listMono = + commonGitServiceCE.listBranchForArtifact(application1.getId(), true, ArtifactType.APPLICATION); StepVerifier.create(listMono) .assertNext(listBranch -> { @@ -1522,7 +1481,7 @@ public class CommonGitServiceCETest { applicationService.save(application2).block(); Mono applicationUpdatedMono = commonGitServiceCE - .listBranchForArtifact(application1.getId(), true, "defaultBranch", ArtifactType.APPLICATION) + .listBranchForArtifact(application1.getId(), true, ArtifactType.APPLICATION) .then(applicationService.findById(application1.getId())); StepVerifier.create(applicationUpdatedMono) @@ -1588,7 +1547,7 @@ public class CommonGitServiceCETest { "listBranchForArtifact_defaultBranchChangesInRemoteDoesNotExistsInDB_Success", "defaultBranch"); Mono applicationUpdatedMono = commonGitServiceCE - .listBranchForArtifact(application1.getId(), true, "defaultBranch", ArtifactType.APPLICATION) + .listBranchForArtifact(application1.getId(), true, ArtifactType.APPLICATION) .then(Mono.defer(() -> applicationService.findById(application1.getId()))); StepVerifier.create(applicationUpdatedMono) @@ -1648,8 +1607,8 @@ public class CommonGitServiceCETest { Mockito.when(gitExecutor.resetToLastCommit(any(Path.class), Mockito.anyString())) .thenReturn(Mono.just(true)); - Mono applicationMono = commonGitServiceCE.pullArtifact( - application.getId(), application.getGitApplicationMetadata().getBranchName(), ArtifactType.APPLICATION); + Mono applicationMono = + commonGitServiceCE.pullArtifact(application.getId(), ArtifactType.APPLICATION); StepVerifier.create(applicationMono) .assertNext(gitPullDTO -> { @@ -1693,8 +1652,8 @@ public class CommonGitServiceCETest { Mockito.anyString())) .thenReturn(Mono.just(mergeStatusDTO)); - Mono applicationMono = commonGitServiceCE.pullArtifact( - application.getId(), application.getGitApplicationMetadata().getBranchName(), ArtifactType.APPLICATION); + Mono applicationMono = + commonGitServiceCE.pullArtifact(application.getId(), ArtifactType.APPLICATION); StepVerifier.create(applicationMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -1744,8 +1703,8 @@ public class CommonGitServiceCETest { Mockito.when(gitExecutor.resetToLastCommit(any(Path.class), Mockito.anyString())) .thenReturn(Mono.just(true)); - Mono applicationMono = commonGitServiceCE.pullArtifact( - application.getId(), application.getGitApplicationMetadata().getBranchName(), ArtifactType.APPLICATION); + Mono applicationMono = + commonGitServiceCE.pullArtifact(application.getId(), ArtifactType.APPLICATION); StepVerifier.create(applicationMono) .assertNext(gitPullDTO -> { @@ -1789,7 +1748,7 @@ public class CommonGitServiceCETest { Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyString(), - Mockito.anyBoolean())) + Mockito.anyString())) .thenReturn(Mono.just("fetchResult")); Mockito.when(gitExecutor.resetToLastCommit(any(Path.class), Mockito.anyString())) .thenReturn(Mono.just(TRUE)); @@ -1833,7 +1792,7 @@ public class CommonGitServiceCETest { Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyString(), - Mockito.anyBoolean())) + Mockito.anyString())) .thenReturn(Mono.just("fetchResult")); Mockito.when(gitExecutor.resetToLastCommit(any(Path.class), Mockito.anyString())) .thenReturn(Mono.just(Boolean.FALSE)); @@ -1883,7 +1842,7 @@ public class CommonGitServiceCETest { Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyString(), - Mockito.anyBoolean())) + Mockito.anyString())) .thenReturn(Mono.just("fetchResult")); Mockito.when(gitExecutor.resetToLastCommit(any(Path.class), Mockito.anyString())) .thenReturn(Mono.just(Boolean.FALSE)); @@ -1955,7 +1914,7 @@ public class CommonGitServiceCETest { Mono applicationMono = commonGitServiceCE .checkoutBranch( gitConnectedApplication.getId(), "origin/branchNotInLocal", true, ArtifactType.APPLICATION) - .flatMap(application1 -> applicationService.findByBranchNameAndDefaultApplicationId( + .flatMap(application1 -> applicationService.findByBranchNameAndBaseApplicationId( "branchNotInLocal", gitConnectedApplication.getId(), READ_APPLICATIONS)); StepVerifier.create(applicationMono) @@ -2035,7 +1994,7 @@ public class CommonGitServiceCETest { Mono> resultMono = commonGitServiceCE .checkoutBranch( gitConnectedApplication.getId(), "origin/branchNotInLocal2", true, ArtifactType.APPLICATION) - .flatMap(checkedOutArtifact -> applicationService.findByBranchNameAndDefaultApplicationId( + .flatMap(checkedOutArtifact -> applicationService.findByBranchNameAndBaseApplicationId( "branchNotInLocal2", gitConnectedApplication.getId(), READ_APPLICATIONS)) .flatMap(application -> { Mono defaultAppTheme = Mono.just(customTheme); @@ -2141,8 +2100,8 @@ public class CommonGitServiceCETest { Mockito.anyBoolean())) .thenReturn(Mono.error(new EmptyCommitException("nothing to commit"))); - Mono commitMono = commonGitServiceCE.commitArtifact( - commitDTO, gitConnectedApplication.getId(), DEFAULT_BRANCH, ArtifactType.APPLICATION); + Mono commitMono = + commonGitServiceCE.commitArtifact(commitDTO, gitConnectedApplication.getId(), ArtifactType.APPLICATION); StepVerifier.create(commitMono) .assertNext(commitMsg -> { @@ -2165,8 +2124,8 @@ public class CommonGitServiceCETest { commitDTO.setDoPush(false); commitDTO.setCommitMessage("empty commit"); - Mono commitMono = commonGitServiceCE.commitArtifact( - commitDTO, application.getId(), DEFAULT_BRANCH, ArtifactType.APPLICATION); + Mono commitMono = + commonGitServiceCE.commitArtifact(commitDTO, application.getId(), ArtifactType.APPLICATION); StepVerifier.create(commitMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -2184,8 +2143,8 @@ public class CommonGitServiceCETest { commitDTO.setDoPush(false); commitDTO.setCommitMessage("empty commit"); - Mono commitMono = commonGitServiceCE.commitArtifact( - commitDTO, gitConnectedApplication.getId(), DEFAULT_BRANCH, ArtifactType.APPLICATION); + Mono commitMono = + commonGitServiceCE.commitArtifact(commitDTO, gitConnectedApplication.getId(), ArtifactType.APPLICATION); Mockito.when(commonGitFileUtils.saveArtifactToLocalRepoWithAnalytics( any(Path.class), any(), Mockito.anyString())) @@ -2221,8 +2180,8 @@ public class CommonGitServiceCETest { Mockito.anyBoolean())) .thenReturn(Mono.just("sample response for commit")); - Mono commitMono = commonGitServiceCE.commitArtifact( - commitDTO, gitConnectedApplication.getId(), DEFAULT_BRANCH, ArtifactType.APPLICATION); + Mono commitMono = + commonGitServiceCE.commitArtifact(commitDTO, gitConnectedApplication.getId(), ArtifactType.APPLICATION); StepVerifier.create(commitMono) .assertNext(commitMsg -> { @@ -2254,7 +2213,7 @@ public class CommonGitServiceCETest { .updateProtectedBranches( gitConnectedApplication.getId(), List.of(DEFAULT_BRANCH), ArtifactType.APPLICATION) .then(commonGitServiceCE.commitArtifact( - commitDTO, gitConnectedApplication.getId(), DEFAULT_BRANCH, ArtifactType.APPLICATION)); + commitDTO, gitConnectedApplication.getId(), ArtifactType.APPLICATION)); StepVerifier.create(commitMono).verifyError(); } @@ -2288,11 +2247,11 @@ public class CommonGitServiceCETest { Mockito.anyString())) .thenReturn(Mono.just("pushed successfully")); - Mono commitAndPushMono = commonGitServiceCE.commitArtifact( - commitDTO, gitConnectedApplication.getId(), DEFAULT_BRANCH, ArtifactType.APPLICATION); + Mono commitAndPushMono = + commonGitServiceCE.commitArtifact(commitDTO, gitConnectedApplication.getId(), ArtifactType.APPLICATION); - StepVerifier.create(commitAndPushMono.zipWhen(status -> - applicationService.findByIdAndBranchName(gitConnectedApplication.getId(), DEFAULT_BRANCH))) + StepVerifier.create(commitAndPushMono.zipWhen( + status -> applicationService.findByBranchedId(gitConnectedApplication.getId(), null))) .assertNext(tuple -> { String commitMsg = tuple.getT1(); Application application = tuple.getT2(); @@ -2335,8 +2294,8 @@ public class CommonGitServiceCETest { Mockito.anyString())) .thenReturn(Mono.just("pushed successfully")); - Mono commitAndPushMono = commonGitServiceCE.commitArtifact( - commitDTO, gitConnectedApplication.getId(), DEFAULT_BRANCH, ArtifactType.APPLICATION); + Mono commitAndPushMono = + commonGitServiceCE.commitArtifact(commitDTO, gitConnectedApplication.getId(), ArtifactType.APPLICATION); StepVerifier.create(commitAndPushMono) .assertNext(commitAndPushMsg -> { @@ -2357,24 +2316,24 @@ public class CommonGitServiceCETest { // Create and fetch the application state before adding new page Application testApplication = createApplicationConnectedToGit("gitConnectedPushFailApplication", DEFAULT_BRANCH); - Application precommitArtifact = applicationService - .getApplicationByDefaultApplicationIdAndDefaultBranch(testApplication.getId()) + Application preCommitApplication = applicationService + .getApplicationByBaseApplicationIdAndDefaultBranch(testApplication.getId()) .block(); // Creating a new page to commit to git PageDTO testPage = new PageDTO(); testPage.setName("GitServiceTestPageGitPushFail"); - testPage.setApplicationId(precommitArtifact.getId()); + testPage.setApplicationId(preCommitApplication.getId()); PageDTO createdPage = applicationPageService.createPage(testPage).block(); GitCommitDTO commitDTO = new GitCommitDTO(); commitDTO.setDoPush(true); commitDTO.setCommitMessage("New page added"); - Mono commitMono = commonGitServiceCE.commitArtifact( - commitDTO, precommitArtifact.getId(), DEFAULT_BRANCH, ArtifactType.APPLICATION); + Mono commitMono = + commonGitServiceCE.commitArtifact(commitDTO, preCommitApplication.getId(), ArtifactType.APPLICATION); Mono committedApplicationMono = - applicationService.getApplicationByDefaultApplicationIdAndDefaultBranch(precommitArtifact.getId()); + applicationService.getApplicationByBaseApplicationIdAndDefaultBranch(preCommitApplication.getId()); // Mocking a git push failure Mockito.when(gitExecutor.pushApplication(any(), any(), any(), any(), any())) @@ -2395,7 +2354,7 @@ public class CommonGitServiceCETest { .assertNext(application -> { List publishedPages = application.getPublishedPages(); assertThat(application.getPublishedPages()) - .hasSize(precommitArtifact.getPublishedPages().size()); + .hasSize(preCommitApplication.getPublishedPages().size()); publishedPages.forEach(publishedPage -> { assertThat(publishedPage.getId().equals(createdPage.getId())) .isFalse(); @@ -2409,22 +2368,22 @@ public class CommonGitServiceCETest { public void commitArtifact_protectedBranch_pushFails() throws GitAPIException, IOException { // Create and fetch the application state before adding new page Application testApplication = - createApplicationConnectedToGit("commitArtifact_protectedBranch_pushFails", DEFAULT_BRANCH); - Application precommitArtifact = applicationService - .getApplicationByDefaultApplicationIdAndDefaultBranch(testApplication.getId()) + createApplicationConnectedToGit("commitApplication_protectedBranch_pushFails", DEFAULT_BRANCH); + Application preCommitApplication = applicationService + .getApplicationByBaseApplicationIdAndDefaultBranch(testApplication.getId()) .block(); // Creating a new page to commit to git PageDTO testPage = new PageDTO(); testPage.setName("GitServiceTestPageGitPushFail"); - testPage.setApplicationId(precommitArtifact.getId()); + testPage.setApplicationId(preCommitApplication.getId()); PageDTO createdPage = applicationPageService.createPage(testPage).block(); GitCommitDTO commitDTO = new GitCommitDTO(); commitDTO.setDoPush(true); commitDTO.setCommitMessage("New page added"); - Mono commitMono = commonGitServiceCE.commitArtifact( - commitDTO, precommitArtifact.getId(), DEFAULT_BRANCH, ArtifactType.APPLICATION); + Mono commitMono = + commonGitServiceCE.commitArtifact(commitDTO, preCommitApplication.getId(), ArtifactType.APPLICATION); // Mocking a git push failure Mockito.when(gitExecutor.pushApplication(any(), any(), any(), any(), any())) @@ -2452,12 +2411,8 @@ public class CommonGitServiceCETest { createGitBranchDTO.setBranchName("origin/createNewBranch"); Mono createBranchMono = commonGitServiceCE - .createBranch( - gitConnectedApplication.getId(), - createGitBranchDTO, - gitConnectedApplication.getGitApplicationMetadata().getBranchName(), - ArtifactType.APPLICATION) - .map(artifact -> (Application) artifact); + .createBranch(gitConnectedApplication.getId(), createGitBranchDTO, ArtifactType.APPLICATION) + .map(baseArtifact -> (Application) baseArtifact); StepVerifier.create(createBranchMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -2491,11 +2446,7 @@ public class CommonGitServiceCETest { .thenReturn(Mono.just("fetchResult")); Mockito.when(gitExecutor.listBranches(any())).thenReturn(Mono.just(branchList)); Mono createBranchMono = commonGitServiceCE - .createBranch( - gitConnectedApplication.getId(), - createGitBranchDTO, - gitConnectedApplication.getGitApplicationMetadata().getBranchName(), - ArtifactType.APPLICATION) + .createBranch(gitConnectedApplication.getId(), createGitBranchDTO, ArtifactType.APPLICATION) .map(artifact -> (Application) artifact); StepVerifier.create(createBranchMono) @@ -2634,24 +2585,20 @@ public class CommonGitServiceCETest { return Mono.zip( layoutActionService - .createSingleActionWithBranch(action, null) + .createSingleAction(action) .then(updateLayoutService.updateLayout( testPage.getId(), testPage.getApplicationId(), layout.getId(), layout)), - layoutCollectionService.createCollection(actionCollectionDTO, null)) + layoutCollectionService.createCollection(actionCollectionDTO)) .then(commonGitServiceCE.connectArtifactToGit( application.getId(), gitConnectDTO, "origin", ArtifactType.APPLICATION)) .map(artifact -> (Application) artifact); }) .flatMap(application -> commonGitServiceCE - .createBranch( - application.getId(), - createGitBranchDTO, - application.getGitApplicationMetadata().getBranchName(), - ArtifactType.APPLICATION) - .then(applicationService.findByBranchNameAndDefaultApplicationId( + .createBranch(application.getId(), createGitBranchDTO, ArtifactType.APPLICATION) + .then(applicationService.findByBranchNameAndBaseApplicationId( createGitBranchDTO.getBranchName(), application.getId(), READ_APPLICATIONS))); StepVerifier.create(createBranchMono.zipWhen(application -> Mono.zip( @@ -2692,59 +2639,20 @@ public class CommonGitServiceCETest { assertThat(pageList).isNotNull(); pageList.forEach(newPage -> { - assertThat(newPage.getDefaultResources()).isNotNull(); - assertThat(newPage.getDefaultResources().getPageId()).isNotEqualTo(newPage.getId()); - assertThat(newPage.getDefaultResources().getApplicationId()) - .isEqualTo(parentApplication.getId()); - assertThat(newPage.getDefaultResources().getBranchName()) - .isEqualTo(createGitBranchDTO.getBranchName()); - - newPage.getUnpublishedPage().getLayouts().stream() - .filter(layout -> !CollectionUtils.isNullOrEmpty(layout.getLayoutOnLoadActions())) - .forEach(layout -> layout.getLayoutOnLoadActions() - .forEach(dslActionDTOS -> { - dslActionDTOS.forEach(actionDTO -> { - assertThat(actionDTO.getId()) - .isNotEqualTo(actionDTO.getDefaultActionId()); - }); - })); + assertThat(newPage.getBaseId()).isNotEqualTo(newPage.getId()); + assertThat(newPage.getBranchName()).isEqualTo(createGitBranchDTO.getBranchName()); }); assertThat(actionList).hasSize(2); actionList.forEach(newAction -> { - assertThat(newAction.getDefaultResources()).isNotNull(); - assertThat(newAction.getDefaultResources().getActionId()) - .isNotEqualTo(newAction.getId()); - assertThat(newAction.getDefaultResources().getApplicationId()) - .isEqualTo(parentApplication.getId()); - assertThat(newAction.getDefaultResources().getBranchName()) - .isEqualTo(createGitBranchDTO.getBranchName()); - - ActionDTO action = newAction.getUnpublishedAction(); - assertThat(action.getDefaultResources()).isNotNull(); - assertThat(action.getDefaultResources().getPageId()) - .isEqualTo(parentApplication.getPages().get(0).getId()); - if (!StringUtils.isEmpty(action.getDefaultResources().getCollectionId())) { - assertThat(action.getDefaultResources().getCollectionId()) - .isNotEqualTo(action.getCollectionId()); - } + assertThat(newAction.getBaseId()).isNotEqualTo(newAction.getId()); + assertThat(newAction.getBranchName()).isEqualTo(createGitBranchDTO.getBranchName()); }); assertThat(actionCollectionList).hasSize(1); actionCollectionList.forEach(actionCollection -> { - assertThat(actionCollection.getDefaultResources()).isNotNull(); - assertThat(actionCollection.getDefaultResources().getCollectionId()) - .isNotEqualTo(actionCollection.getId()); - assertThat(actionCollection.getDefaultResources().getApplicationId()) - .isEqualTo(parentApplication.getId()); - assertThat(actionCollection.getDefaultResources().getBranchName()) - .isEqualTo(createGitBranchDTO.getBranchName()); - - ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - - assertThat(unpublishedCollection.getDefaultResources()).isNotNull(); - assertThat(unpublishedCollection.getDefaultResources().getPageId()) - .isEqualTo(parentApplication.getPages().get(0).getId()); + assertThat(actionCollection.getBaseId()).isNotEqualTo(actionCollection.getId()); + assertThat(actionCollection.getBranchName()).isEqualTo(createGitBranchDTO.getBranchName()); }); }) .verifyComplete(); @@ -2827,19 +2735,15 @@ public class CommonGitServiceCETest { .flatMap(theme -> { theme.setId(null); theme.setName("Custom theme"); - return themeService.updateTheme(application.getId(), null, theme); + return themeService.updateTheme(application.getId(), theme); }) .then(commonGitServiceCE.connectArtifactToGit( application.getId(), gitConnectDTO, "origin", ArtifactType.APPLICATION)) .map(artifact -> (Application) artifact); }) .flatMap(application -> commonGitServiceCE - .createBranch( - application.getId(), - createGitBranchDTO, - application.getGitApplicationMetadata().getBranchName(), - ArtifactType.APPLICATION) - .then(applicationService.findByBranchNameAndDefaultApplicationId( + .createBranch(application.getId(), createGitBranchDTO, ArtifactType.APPLICATION) + .then(applicationService.findByBranchNameAndBaseApplicationId( createGitBranchDTO.getBranchName(), application.getId(), READ_APPLICATIONS))) .zipWhen(application -> applicationService.findById( application.getGitApplicationMetadata().getDefaultArtifactId())); @@ -2922,14 +2826,9 @@ public class CommonGitServiceCETest { .createApplication(testApplication) .flatMap(application -> commonGitServiceCE.connectArtifactToGit( application.getId(), gitConnectDTO, "origin", ArtifactType.APPLICATION)) - .map(artifact -> (Application) artifact) .flatMap(application -> commonGitServiceCE - .createBranch( - application.getId(), - createGitBranchDTO, - application.getGitApplicationMetadata().getBranchName(), - ArtifactType.APPLICATION) - .then(applicationService.findByBranchNameAndDefaultApplicationId( + .createBranch(application.getId(), createGitBranchDTO, ArtifactType.APPLICATION) + .then(applicationService.findByBranchNameAndBaseApplicationId( createGitBranchDTO.getBranchName(), application.getId(), READ_APPLICATIONS))) .flatMap(branchedApplication -> { Application.NavigationSetting appNavigationSetting = new Application.NavigationSetting(); @@ -2949,10 +2848,8 @@ public class CommonGitServiceCETest { branchedApplication.getUnpublishedApplicationDetail().setThemeSetting(themeSettings); return Mono.just(branchedApplication); }) - .flatMap(branchedApplication -> applicationService.update( - branchedApplication.getGitApplicationMetadata().getDefaultArtifactId(), - branchedApplication, - branchedApplication.getGitApplicationMetadata().getBranchName())) + .flatMap(branchedApplication -> applicationService.updateApplicationWithPresets( + branchedApplication.getId(), branchedApplication)) .zipWhen(application -> applicationService.findById( application.getGitApplicationMetadata().getDefaultArtifactId())); @@ -3015,26 +2912,17 @@ public class CommonGitServiceCETest { .createApplication(testApplication) .flatMap(application -> commonGitServiceCE.connectArtifactToGit( application.getId(), gitConnectDTO, "origin", ArtifactType.APPLICATION)) - .map(artifact -> (Application) artifact) .flatMap(application -> commonGitServiceCE - .createBranch( - application.getId(), - createGitBranchDTO, - application.getGitApplicationMetadata().getBranchName(), - ArtifactType.APPLICATION) - .then(applicationService.findByBranchNameAndDefaultApplicationId( + .createBranch(application.getId(), createGitBranchDTO, ArtifactType.APPLICATION) + .map(artifact -> { + return artifact; + }) + .then(applicationService.findByBranchNameAndBaseApplicationId( createGitBranchDTO.getBranchName(), application.getId(), READ_APPLICATIONS))) .flatMap(branchedApplication -> { FilePart filepart = createMockFilePart(); return applicationService - .saveAppNavigationLogo( - branchedApplication - .getGitApplicationMetadata() - .getBranchName(), - branchedApplication - .getGitApplicationMetadata() - .getDefaultArtifactId(), - filepart) + .saveAppNavigationLogo(branchedApplication.getId(), filepart) .cache(); }) .zipWhen(application -> applicationService.findById( @@ -3082,12 +2970,8 @@ public class CommonGitServiceCETest { .map(artifact -> (Application) artifact) .flatMap(application -> Mono.zip( commonGitServiceCE - .createBranch( - application.getId(), - createGitBranchDTO, - application.getGitApplicationMetadata().getBranchName(), - ArtifactType.APPLICATION) - .then(applicationService.findByBranchNameAndDefaultApplicationId( + .createBranch(application.getId(), createGitBranchDTO, ArtifactType.APPLICATION) + .then(applicationService.findByBranchNameAndBaseApplicationId( createGitBranchDTO.getBranchName(), application.getId(), READ_APPLICATIONS)), Mono.just(application))) .flatMap(applicationTuple -> { @@ -3103,10 +2987,10 @@ public class CommonGitServiceCETest { FilePart filepart = createMockFilePart(); return Mono.zip( applicationService - .saveAppNavigationLogo(otherBranchName, defaultApplicationId, filepart) + .saveAppNavigationLogo(branchedApplication.getId(), filepart) .cache(), applicationService - .saveAppNavigationLogo(srcBranchName, defaultApplicationId, filepart) + .saveAppNavigationLogo(defaultApplicationId, filepart) .cache()); }) .flatMap(appTuple -> { @@ -3114,20 +2998,8 @@ public class CommonGitServiceCETest { Application application = appTuple.getT2(); return applicationService - .deleteAppNavigationLogo( - branchedApplication - .getGitApplicationMetadata() - .getBranchName(), - branchedApplication - .getGitApplicationMetadata() - .getDefaultArtifactId()) - .then(applicationService.findByIdAndBranchName( - branchedApplication - .getGitApplicationMetadata() - .getDefaultArtifactId(), - branchedApplication - .getGitApplicationMetadata() - .getBranchName())); + .deleteAppNavigationLogo(branchedApplication.getId()) + .then(applicationService.findByBranchedId(branchedApplication.getId(), null)); }) .zipWhen(application -> applicationService.findById( application.getGitApplicationMetadata().getDefaultArtifactId())); @@ -3179,12 +3051,8 @@ public class CommonGitServiceCETest { .map(artifact -> (Application) artifact) .flatMap(application -> Mono.zip( commonGitServiceCE - .createBranch( - application.getId(), - createGitBranchDTO, - application.getGitApplicationMetadata().getBranchName(), - ArtifactType.APPLICATION) - .then(applicationService.findByBranchNameAndDefaultApplicationId( + .createBranch(application.getId(), createGitBranchDTO, ArtifactType.APPLICATION) + .then(applicationService.findByBranchNameAndBaseApplicationId( createGitBranchDTO.getBranchName(), application.getId(), READ_APPLICATIONS)), Mono.just(application))) .flatMap(applicationTuple -> { @@ -3207,8 +3075,8 @@ public class CommonGitServiceCETest { newBranchPage.setApplicationId(defaultApplicationId); return Mono.zip( - applicationPageService.createPageWithBranchName(newBranchPage, otherBranchName), - applicationPageService.createPageWithBranchName(newSrcPage, srcBranchName)); + applicationPageService.createPage(newBranchPage), + applicationPageService.createPage(newSrcPage)); }); StepVerifier.create(createBranchMono) @@ -3329,7 +3197,7 @@ public class CommonGitServiceCETest { .thenReturn(Mono.just("pushed successfully")); commonGitServiceCE - .commitArtifact(commitDTO, gitConnectedApplication.getId(), DEFAULT_BRANCH, ArtifactType.APPLICATION) + .commitArtifact(commitDTO, gitConnectedApplication.getId(), ArtifactType.APPLICATION) .timeout(Duration.ofMillis(10)) .subscribe(); @@ -3396,11 +3264,7 @@ public class CommonGitServiceCETest { Application application1 = createApplicationConnectedToGit("createBranch_cancelledMidway_newApplicationCreated", "master"); commonGitServiceCE - .createBranch( - application1.getId(), - createGitBranchDTO, - application1.getGitApplicationMetadata().getBranchName(), - ArtifactType.APPLICATION) + .createBranch(application1.getId(), createGitBranchDTO, ArtifactType.APPLICATION) .timeout(Duration.ofMillis(10)) .subscribe(); @@ -3412,7 +3276,7 @@ public class CommonGitServiceCETest { } catch (InterruptedException e) { e.printStackTrace(); } - return applicationService.findByBranchNameAndDefaultApplicationId( + return applicationService.findByBranchNameAndBaseApplicationId( createGitBranchDTO.getBranchName(), application.getId(), MANAGE_APPLICATIONS); }); @@ -3914,22 +3778,19 @@ public class CommonGitServiceCETest { @Test @WithUserDetails(value = "api_user") - public void deleteBranch_staleBranchNotInDB_Success() throws IOException, GitAPIException { + public void deleteBranch_staleBranchNotInDB_NotFoundError() throws IOException, GitAPIException { Application application = createApplicationConnectedToGit("deleteBranch_staleBranchNotInDB_Success", "master"); application.getGitApplicationMetadata().setDefaultBranchName("master"); applicationService.save(application).block(); - Mockito.when(gitExecutor.deleteBranch(any(Path.class), Mockito.anyString())) - .thenReturn(Mono.just(true)); - Mono applicationMono = commonGitServiceCE - .deleteBranch(application.getId(), "test", ArtifactType.APPLICATION) - .map(artifact -> (Application) artifact); + Mono applicationMono = + commonGitServiceCE.deleteBranch(application.getId(), "test", ArtifactType.APPLICATION); - StepVerifier.create(applicationMono) - .assertNext(application1 -> { - assertThat(application1.getId()).isEqualTo(application.getId()); - }) - .verifyComplete(); + StepVerifier.create(applicationMono).verifyErrorSatisfies(error -> { + assertThat(error).isInstanceOf(AppsmithException.class); + assertThat(((AppsmithException) error).getAppErrorCode()) + .isEqualTo(AppsmithError.NO_RESOURCE_FOUND.getAppErrorCode()); + }); } @Test @@ -3979,11 +3840,17 @@ public class CommonGitServiceCETest { createApplicationConnectedToGit("deleteBranch_branchDoesNotExist_ThrowError", "master"); application.getGitApplicationMetadata().setDefaultBranchName("test"); applicationService.save(application).block(); + Mockito.when(gitExecutor.deleteBranch(any(Path.class), Mockito.anyString())) .thenReturn(Mono.just(false)); + application.getGitApplicationMetadata().setBranchName("not-present-branch"); + Mockito.doReturn(Mono.just(application)) + .when(applicationService) + .findByBranchNameAndBaseApplicationId(anyString(), anyString(), any(AclPermission.class)); + Mono applicationMono = commonGitServiceCE - .deleteBranch(application.getId(), "master", ArtifactType.APPLICATION) + .deleteBranch(application.getId(), "not-present-branch", ArtifactType.APPLICATION) .map(artifact -> (Application) artifact); StepVerifier.create(applicationMono) @@ -4073,10 +3940,7 @@ public class CommonGitServiceCETest { .thenReturn(Mono.just(true)); Mono applicationMono = commonGitServiceCE - .discardChanges( - application.getId(), - application.getGitApplicationMetadata().getBranchName(), - ArtifactType.APPLICATION) + .discardChanges(application.getId(), ArtifactType.APPLICATION) .map(artifact -> (Application) artifact); StepVerifier.create(applicationMono) @@ -4132,10 +3996,7 @@ public class CommonGitServiceCETest { .thenReturn(Mono.just("fetched")); commonGitServiceCE - .discardChanges( - application.getId(), - application.getGitApplicationMetadata().getBranchName(), - ArtifactType.APPLICATION) + .discardChanges(application.getId(), ArtifactType.APPLICATION) .map(artifact -> (Application) artifact) .timeout(Duration.ofNanos(100)) .subscribe(); @@ -4194,7 +4055,7 @@ public class CommonGitServiceCETest { } catch (InterruptedException e) { e.printStackTrace(); } - return applicationService.findAllApplicationsByDefaultApplicationId( + return applicationService.findAllApplicationsByBaseApplicationId( DBApplication.getId(), MANAGE_APPLICATIONS); }) .collectList(); @@ -4243,11 +4104,11 @@ public class CommonGitServiceCETest { .thenReturn(Mono.just("pushed successfully")); // First request for commit operation - Mono commitMonoReq1 = commonGitServiceCE.commitArtifact( - commitDTO, gitConnectedApplication.getId(), DEFAULT_BRANCH, ArtifactType.APPLICATION); + Mono commitMonoReq1 = + commonGitServiceCE.commitArtifact(commitDTO, gitConnectedApplication.getId(), ArtifactType.APPLICATION); // Second request for commit operation - Mono commitMonoReq2 = commonGitServiceCE.commitArtifact( - commitDTO, gitConnectedApplication.getId(), DEFAULT_BRANCH, ArtifactType.APPLICATION); + Mono commitMonoReq2 = + commonGitServiceCE.commitArtifact(commitDTO, gitConnectedApplication.getId(), ArtifactType.APPLICATION); // Both the request to execute completely without the file lock error from jgit. StepVerifier.create(Mono.zip(commitMonoReq1, commitMonoReq2)) @@ -4304,7 +4165,7 @@ public class CommonGitServiceCETest { Mockito.when(gitExecutor.getBranchTrackingStatus(repoPath, branch)).thenReturn(Mono.just(branchTrackingStatus)); StepVerifier.create(commonGitServiceCE.fetchRemoteChanges( - gitData.getDefaultArtifactId(), branch, false, ArtifactType.APPLICATION)) + gitData.getDefaultArtifactId(), false, ArtifactType.APPLICATION)) .assertNext(response -> { assertThat(response.getAheadCount()).isEqualTo(1); assertThat(response.getBehindCount()).isEqualTo(2); @@ -4540,7 +4401,7 @@ public class CommonGitServiceCETest { String defaultAppId = createBranchedApplication(branchList); Flux applicationFlux = commonGitServiceCE .updateProtectedBranches(defaultAppId, List.of("master"), ArtifactType.APPLICATION) - .thenMany(applicationService.findAllApplicationsByDefaultApplicationId( + .thenMany(applicationService.findAllApplicationsByBaseApplicationId( defaultAppId, applicationPermission.getEditPermission())); StepVerifier.create(applicationFlux.collectList()) @@ -4570,7 +4431,7 @@ public class CommonGitServiceCETest { .updateProtectedBranches(defaultAppId, List.of("master"), ArtifactType.APPLICATION) .then(commonGitServiceCE.updateProtectedBranches( defaultAppId, List.of(), ArtifactType.APPLICATION)) // unset the protected branch list - .thenMany(applicationService.findAllApplicationsByDefaultApplicationId( + .thenMany(applicationService.findAllApplicationsByBaseApplicationId( defaultAppId, applicationPermission.getEditPermission())); StepVerifier.create(applicationFlux.collectList()) @@ -4805,8 +4666,8 @@ public class CommonGitServiceCETest { Application application1 = createApplicationConnectedToGit( "listBranchForArtifact_pruneBranchNoChangesInRemote_Success", "defaultBranch"); - Mono> listMono = commonGitServiceCE.listBranchForArtifact( - application1.getId(), false, "defaultBranch", ArtifactType.APPLICATION); + Mono> listMono = + commonGitServiceCE.listBranchForArtifact(application1.getId(), false, ArtifactType.APPLICATION); StepVerifier.create(listMono) .assertNext(listBranch -> { diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/AutoCommitServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/AutoCommitServiceTest.java index 455fac3cff..070b7d525b 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/AutoCommitServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/AutoCommitServiceTest.java @@ -217,10 +217,13 @@ public class AutoCommitServiceTest { baseRepoSuffix = Paths.get(WORKSPACE_ID, DEFAULT_APP_ID, REPO_NAME); // used for fetching application on autocommit service and gitAutoCommitHelper.autocommit - Mockito.when(applicationService.findByBranchNameAndDefaultApplicationId( + Mockito.when(applicationService.findByBranchNameAndBaseApplicationId( anyString(), anyString(), any(AclPermission.class))) .thenReturn(Mono.just(testApplication)); + Mockito.when(applicationService.findById(anyString(), any(AclPermission.class))) + .thenReturn(Mono.just(testApplication)); + // create page-dto PageDTO pageDTO = createPageDTO(); @@ -240,8 +243,7 @@ public class AutoCommitServiceTest { Mockito.when(featureFlagService.check(FeatureFlagEnum.release_git_autocommit_feature_enabled)) .thenReturn(Mono.just(TRUE)); - Mockito.when(commonGitService.fetchRemoteChanges( - any(Application.class), any(Application.class), anyString(), anyBoolean())) + Mockito.when(commonGitService.fetchRemoteChanges(any(Application.class), any(Application.class), anyBoolean())) .thenReturn(Mono.just(branchTrackingStatus)); Mockito.when(branchTrackingStatus.getBehindCount()).thenReturn(0); @@ -300,7 +302,7 @@ public class AutoCommitServiceTest { Mockito.when(redisUtils.getAutoCommitProgress(DEFAULT_APP_ID)).thenReturn(Mono.empty()); Mono autoCommitResponseDTOMono = - autoCommitService.autoCommitApplication(testApplication.getId(), BRANCH_NAME); + autoCommitService.autoCommitApplication(testApplication.getId()); StepVerifier.create(autoCommitResponseDTOMono) .assertNext(autoCommitResponseDTO -> { @@ -374,7 +376,7 @@ public class AutoCommitServiceTest { // this would trigger autocommit Mono autoCommitResponseDTOMono = - autoCommitService.autoCommitApplication(testApplication.getId(), BRANCH_NAME); + autoCommitService.autoCommitApplication(testApplication.getId()); StepVerifier.create(autoCommitResponseDTOMono) .assertNext(autoCommitResponseDTO -> { @@ -430,7 +432,7 @@ public class AutoCommitServiceTest { // this would not trigger autocommit Mono autoCommitResponseDTOMono = - autoCommitService.autoCommitApplication(testApplication.getId(), BRANCH_NAME); + autoCommitService.autoCommitApplication(testApplication.getId()); StepVerifier.create(autoCommitResponseDTOMono) .assertNext(autoCommitResponseDTO -> { @@ -465,7 +467,7 @@ public class AutoCommitServiceTest { // this would not trigger autocommit Mono autoCommitResponseDTOMono = - autoCommitService.autoCommitApplication(testApplication.getId(), BRANCH_NAME); + autoCommitService.autoCommitApplication(testApplication.getId()); StepVerifier.create(autoCommitResponseDTOMono) .assertNext(autoCommitResponseDTO -> { @@ -486,7 +488,7 @@ public class AutoCommitServiceTest { // this would not trigger autocommit Mono autoCommitResponseDTOMono = - autoCommitService.autoCommitApplication(testApplication.getId(), BRANCH_NAME); + autoCommitService.autoCommitApplication(testApplication.getId()); StepVerifier.create(autoCommitResponseDTOMono) .assertNext(autoCommitResponseDTO -> { @@ -502,13 +504,16 @@ public class AutoCommitServiceTest { public void testAutoCommit_whenNoGitMetadata_returnsNonGitApp() { testApplication.setGitApplicationMetadata(null); // used for fetching application on autocommit service and gitAutoCommitHelper.autocommit - Mockito.when(applicationService.findByBranchNameAndDefaultApplicationId( + Mockito.when(applicationService.findById(anyString(), any(AclPermission.class))) + .thenReturn(Mono.just(testApplication)); + + Mockito.when(applicationService.findByBranchNameAndBaseApplicationId( anyString(), anyString(), any(AclPermission.class))) .thenReturn(Mono.just(testApplication)); // this would not trigger autocommit Mono autoCommitResponseDTOMono = - autoCommitService.autoCommitApplication(testApplication.getId(), BRANCH_NAME); + autoCommitService.autoCommitApplication(testApplication.getId()); StepVerifier.create(autoCommitResponseDTOMono) .assertNext(autoCommitResponseDTO -> { @@ -533,7 +538,7 @@ public class AutoCommitServiceTest { // this would not trigger autocommit Mono autoCommitResponseDTOMono = - autoCommitService.autoCommitApplication(testApplication.getId(), BRANCH_NAME); + autoCommitService.autoCommitApplication(testApplication.getId()); StepVerifier.create(autoCommitResponseDTOMono) .assertNext(autoCommitResponseDTO -> { @@ -581,7 +586,7 @@ public class AutoCommitServiceTest { Mockito.when(redisUtils.getAutoCommitProgress(DEFAULT_APP_ID)).thenReturn(Mono.empty()); Mono autoCommitResponseDTOMono = - autoCommitService.autoCommitApplication(testApplication.getId(), BRANCH_NAME); + autoCommitService.autoCommitApplication(testApplication.getId()); StepVerifier.create(autoCommitResponseDTOMono) .assertNext(autoCommitResponseDTO -> assertThat(autoCommitResponseDTO.getAutoCommitResponse()) @@ -592,7 +597,7 @@ public class AutoCommitServiceTest { Mockito.when(redisUtils.getRunningAutoCommitBranchName(DEFAULT_APP_ID)).thenReturn(Mono.just(BRANCH_NAME)); Mockito.when(redisUtils.getAutoCommitProgress(DEFAULT_APP_ID)).thenReturn(Mono.just(20)); - StepVerifier.create(autoCommitService.autoCommitApplication(testApplication.getId(), BRANCH_NAME)) + StepVerifier.create(autoCommitService.autoCommitApplication(testApplication.getId())) .assertNext(autoCommitResponseDTO -> { assertThat(autoCommitResponseDTO.getAutoCommitResponse()) .isEqualTo(AutoCommitResponseDTO.AutoCommitResponse.IN_PROGRESS); @@ -651,23 +656,23 @@ public class AutoCommitServiceTest { // redis-utils fixing Mockito.when(redisUtils.getRunningAutoCommitBranchName(DEFAULT_APP_ID)).thenReturn(Mono.empty()); - Mockito.when(redisUtils.getAutoCommitProgress(DEFAULT_APP_ID)).thenReturn(Mono.empty()); Mono autoCommitResponseDTOMono = - autoCommitService.autoCommitApplication(testApplication.getId(), BRANCH_NAME); + autoCommitService.autoCommitApplication(testApplication.getId()); StepVerifier.create(autoCommitResponseDTOMono) .assertNext(autoCommitResponseDTO -> assertThat(autoCommitResponseDTO.getAutoCommitResponse()) .isEqualTo(AutoCommitResponseDTO.AutoCommitResponse.PUBLISHED)) .verifyComplete(); + testApplication.getGitApplicationMetadata().setBranchName("another-branch-name"); + // redis-utils fixing Mockito.when(redisUtils.getRunningAutoCommitBranchName(DEFAULT_APP_ID)).thenReturn(Mono.just(BRANCH_NAME)); - Mockito.when(redisUtils.getAutoCommitProgress(DEFAULT_APP_ID)).thenReturn(Mono.just(20)); - StepVerifier.create(autoCommitService.autoCommitApplication(testApplication.getId(), DEFAULT_BRANCH_NAME)) + StepVerifier.create(autoCommitService.autoCommitApplication(testApplication.getId())) .assertNext(autoCommitResponseDTO -> { assertThat(autoCommitResponseDTO.getAutoCommitResponse()) .isEqualTo(AutoCommitResponseDTO.AutoCommitResponse.LOCKED); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/helpers/GitAutoCommitHelperImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/helpers/GitAutoCommitHelperImplTest.java index fd12c38181..6e4707db2f 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/helpers/GitAutoCommitHelperImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/git/autocommit/helpers/GitAutoCommitHelperImplTest.java @@ -91,7 +91,7 @@ public class GitAutoCommitHelperImplTest { .thenReturn(Mono.just(application)); Mockito.when(gitPrivateRepoHelper.isBranchProtected(any(GitArtifactMetadata.class), anyString())) .thenReturn(Mono.just(Boolean.FALSE)); - Mockito.when(applicationService.findByBranchNameAndDefaultApplicationId( + Mockito.when(applicationService.findByBranchNameAndBaseApplicationId( anyString(), anyString(), any(AclPermission.class))) .thenReturn(Mono.just(application)); @@ -114,7 +114,7 @@ public class GitAutoCommitHelperImplTest { .thenReturn(Mono.just(application)); Mockito.when(gitPrivateRepoHelper.isBranchProtected(any(GitArtifactMetadata.class), eq(branchName))) .thenReturn(Mono.just(Boolean.TRUE)); - Mockito.when(applicationService.findByBranchNameAndDefaultApplicationId( + Mockito.when(applicationService.findByBranchNameAndBaseApplicationId( anyString(), anyString(), any(AclPermission.class))) .thenReturn(Mono.just(application)); @@ -139,7 +139,7 @@ public class GitAutoCommitHelperImplTest { .thenReturn(Mono.just(Boolean.TRUE)); Mockito.when(applicationService.findById(defaultApplicationId, applicationPermission.getEditPermission())) .thenReturn(Mono.just(application)); - Mockito.when(applicationService.findByBranchNameAndDefaultApplicationId( + Mockito.when(applicationService.findByBranchNameAndBaseApplicationId( anyString(), anyString(), any(AclPermission.class))) .thenReturn(Mono.just(application)); Mockito.when(gitPrivateRepoHelper.isBranchProtected(any(GitArtifactMetadata.class), eq(branchName))) @@ -164,7 +164,7 @@ public class GitAutoCommitHelperImplTest { .thenReturn(Mono.just(Boolean.FALSE)); Mockito.when(featureFlagService.check(FeatureFlagEnum.release_git_autocommit_feature_enabled)) .thenReturn(Mono.just(Boolean.TRUE)); - Mockito.when(applicationService.findByBranchNameAndDefaultApplicationId( + Mockito.when(applicationService.findByBranchNameAndBaseApplicationId( anyString(), anyString(), any(AclPermission.class))) .thenReturn(Mono.just(application)); @@ -197,12 +197,11 @@ public class GitAutoCommitHelperImplTest { .thenReturn(Mono.just(Boolean.TRUE)); Mockito.when(applicationService.findById(defaultApplicationId, applicationPermission.getEditPermission())) .thenReturn(Mono.just(application)); - Mockito.when(applicationService.findByBranchNameAndDefaultApplicationId( + Mockito.when(applicationService.findByBranchNameAndBaseApplicationId( anyString(), anyString(), any(AclPermission.class))) .thenReturn(Mono.just(application)); - Mockito.when(commonGitService.fetchRemoteChanges( - any(Application.class), any(Application.class), anyString(), anyBoolean())) + Mockito.when(commonGitService.fetchRemoteChanges(any(Application.class), any(Application.class), anyBoolean())) .thenReturn(Mono.just(branchTrackingStatus)); Mockito.when(branchTrackingStatus.getBehindCount()).thenReturn(0); @@ -299,11 +298,10 @@ public class GitAutoCommitHelperImplTest { .thenReturn(Mono.just(Boolean.TRUE)); Mockito.when(applicationService.findById(defaultApplicationId, applicationPermission.getEditPermission())) .thenReturn(Mono.just(application)); - Mockito.when(applicationService.findByBranchNameAndDefaultApplicationId( + Mockito.when(applicationService.findByBranchNameAndBaseApplicationId( anyString(), anyString(), any(AclPermission.class))) .thenReturn(Mono.just(application)); - Mockito.when(commonGitService.fetchRemoteChanges( - any(Application.class), any(Application.class), anyString(), anyBoolean())) + Mockito.when(commonGitService.fetchRemoteChanges(any(Application.class), any(Application.class), anyBoolean())) .thenReturn(Mono.just(branchTrackingStatus)); Mockito.when(branchTrackingStatus.getBehindCount()).thenReturn(1); @@ -364,20 +362,30 @@ public class GitAutoCommitHelperImplTest { Mockito.when(applicationService.findById(anyString(), any(AclPermission.class))) .thenReturn(Mono.just(application)); - Mockito.when(applicationService.findByBranchNameAndDefaultApplicationId( + Mockito.when(applicationService.findByBranchNameAndBaseApplicationId( anyString(), anyString(), any(AclPermission.class))) .thenReturn(Mono.just(application)); - Mockito.when(commonGitService.fetchRemoteChanges( - any(Application.class), any(Application.class), anyString(), anyBoolean())) + Mockito.when(commonGitService.fetchRemoteChanges(any(Application.class), any(Application.class), anyBoolean())) .thenReturn(Mono.just(branchTrackingStatus)); Mockito.when(branchTrackingStatus.getBehindCount()).thenReturn(0); + Mockito.when(gitPrivateRepoHelper.isBranchProtected(any(GitArtifactMetadata.class), eq(branchName))) + .thenReturn(Mono.just(Boolean.FALSE)); + + GitProfile gitProfile = new GitProfile(); + gitProfile.setAuthorEmail("user@example.com"); + gitProfile.setAuthorName("test user name"); + + Mockito.when(userDataService.getGitProfileForCurrentUser(defaultApplicationId)) + .thenReturn(Mono.just(gitProfile)); + StepVerifier.create(gitAutoCommitHelper.autoCommitServerMigration(defaultApplicationId, branchName)) .assertNext(isAutoCommitPublished -> { assertThat(isAutoCommitPublished).isTrue(); - }); + }) + .verifyComplete(); } @Test @@ -402,9 +410,14 @@ public class GitAutoCommitHelperImplTest { Mockito.when(applicationService.findById(anyString(), any(AclPermission.class))) .thenReturn(Mono.just(application)); + Mockito.when(applicationService.findByBranchNameAndBaseApplicationId( + anyString(), anyString(), any(AclPermission.class))) + .thenReturn(Mono.just(application)); + StepVerifier.create(gitAutoCommitHelper.autoCommitServerMigration(defaultApplicationId, branchName)) .assertNext(isAutoCommitPublished -> { assertThat(isAutoCommitPublished).isFalse(); - }); + }) + .verifyComplete(); } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/ResponseUtilsTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/ResponseUtilsTest.java deleted file mode 100644 index f771243f3e..0000000000 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/ResponseUtilsTest.java +++ /dev/null @@ -1,197 +0,0 @@ -package com.appsmith.server.helpers; - -import com.appsmith.external.helpers.AppsmithBeanUtils; -import com.appsmith.server.domains.ActionCollection; -import com.appsmith.server.domains.Application; -import com.appsmith.server.domains.ApplicationPage; -import com.appsmith.server.domains.NewAction; -import com.appsmith.server.domains.NewPage; -import com.appsmith.server.migrations.JsonSchemaVersions; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.Gson; -import lombok.SneakyThrows; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; - -import java.io.File; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - -@SpringBootTest -@DirtiesContext -public class ResponseUtilsTest { - - private static final File mockObjects = - new File("src/test/resources/test_assets/ResponseUtilsTest/mockObjects.json"); - private static final ObjectMapper objectMapper = new ObjectMapper(); - private static JsonNode jsonNode; - - @Autowired - ResponseUtils responseUtils; - - @Autowired - JsonSchemaVersions jsonSchemaVersions; - - Gson gson = new Gson(); - - @SneakyThrows - @BeforeEach - public void setup() { - jsonNode = objectMapper.readValue(mockObjects, JsonNode.class); - } - - @Test - public void getPage_whenDefaultIdsNull_returnsSamePage() { - final NewPage newPage = objectMapper.convertValue(jsonNode.get("newPage"), NewPage.class); - newPage.setDefaultResources(null); - assertEquals(newPage, responseUtils.updateNewPageWithDefaultResources(newPage)); - } - - @Test - public void getPage_withDefaultIdsPresent_returnsUpdatedPage() { - NewPage newPage = gson.fromJson(String.valueOf(jsonNode.get("newPage")), NewPage.class); - - final NewPage newPageCopy = new NewPage(); - AppsmithBeanUtils.copyNestedNonNullProperties(newPage, newPageCopy); - responseUtils.updateNewPageWithDefaultResources(newPage); - assertNotEquals(newPageCopy, newPage); - assertEquals(newPageCopy.getDefaultResources().getPageId(), newPage.getId()); - assertEquals(newPageCopy.getDefaultResources().getApplicationId(), newPage.getApplicationId()); - } - - @Test - public void getAction_whenDefaultIdsNull_returnsSameAction() { - final NewAction newAction = objectMapper.convertValue(jsonNode.get("newAction"), NewAction.class); - newAction.setDefaultResources(null); - assertEquals(newAction, responseUtils.updateNewActionWithDefaultResources(newAction)); - } - - @Test - public void getAction_withDefaultIdsPresent_returnsUpdatedAction() { - NewAction newAction = gson.fromJson(String.valueOf(jsonNode.get("newAction")), NewAction.class); - - final NewAction newActionCopy = new NewAction(); - AppsmithBeanUtils.copyNestedNonNullProperties(newAction, newActionCopy); - responseUtils.updateNewActionWithDefaultResources(newAction); - assertNotEquals(newActionCopy, newAction); - assertEquals(newActionCopy.getDefaultResources().getActionId(), newAction.getId()); - assertEquals(newActionCopy.getDefaultResources().getApplicationId(), newAction.getApplicationId()); - - assertEquals( - newActionCopy.getUnpublishedAction().getDefaultResources().getPageId(), - newAction.getUnpublishedAction().getPageId()); - assertEquals( - newActionCopy.getUnpublishedAction().getDefaultResources().getCollectionId(), - newAction.getUnpublishedAction().getCollectionId()); - - assertEquals( - newActionCopy.getPublishedAction().getDefaultResources().getPageId(), - newAction.getPublishedAction().getPageId()); - assertEquals( - newActionCopy.getPublishedAction().getDefaultResources().getCollectionId(), - newAction.getPublishedAction().getCollectionId()); - } - - @Test - public void getActionCollection_whenDefaultIdsNull_returnsSameActionCollection() { - final ActionCollection actionCollection = - objectMapper.convertValue(jsonNode.get("actionCollection"), ActionCollection.class); - actionCollection.setDefaultResources(null); - assertEquals(actionCollection, responseUtils.updateActionCollectionWithDefaultResources(actionCollection)); - } - - @Test - public void getActionCollection_withDefaultIdsPresent_returnsUpdatedActionCollection() { - ActionCollection actionCollection = - gson.fromJson(String.valueOf(jsonNode.get("actionCollection")), ActionCollection.class); - - final ActionCollection actionCollectionCopy = new ActionCollection(); - AppsmithBeanUtils.copyNestedNonNullProperties(actionCollection, actionCollectionCopy); - responseUtils.updateActionCollectionWithDefaultResources(actionCollection); - assertNotEquals(actionCollectionCopy, actionCollection); - assertEquals(actionCollectionCopy.getDefaultResources().getCollectionId(), actionCollection.getId()); - assertEquals( - actionCollectionCopy.getDefaultResources().getApplicationId(), actionCollection.getApplicationId()); - - assertEquals( - actionCollectionCopy - .getUnpublishedCollection() - .getDefaultResources() - .getPageId(), - actionCollection.getUnpublishedCollection().getPageId()); - assertEquals( - actionCollectionCopy - .getPublishedCollection() - .getDefaultResources() - .getPageId(), - actionCollection.getPublishedCollection().getPageId()); - } - - @Test - public void getApplication_withDefaultIdsPresent_returnsUpdatedApplication() { - Application application = gson.fromJson(String.valueOf(jsonNode.get("application")), Application.class); - - final Application applicationCopy = new Application(); - AppsmithBeanUtils.copyNestedNonNullProperties(application, applicationCopy); - - // Check if the id and defaultPage ids for pages are not same before we update the application using - // responseUtils - for (ApplicationPage applicationPage : application.getPages()) { - assertNotEquals(applicationPage.getId(), applicationPage.getDefaultPageId()); - } - for (ApplicationPage applicationPage : application.getPublishedPages()) { - assertNotEquals(applicationPage.getId(), applicationPage.getDefaultPageId()); - } - responseUtils.updateApplicationWithDefaultResources(application); - assertNotEquals(applicationCopy, application); - // Check if the id and defaultPage ids for pages are same after we update the application from responseUtils - for (ApplicationPage applicationPage : application.getPages()) { - assertEquals(applicationPage.getId(), applicationPage.getDefaultPageId()); - } - for (ApplicationPage applicationPage : application.getPublishedPages()) { - assertEquals(applicationPage.getId(), applicationPage.getDefaultPageId()); - } - } - - @Test - public void getApplication_withMultipleSchemaVersions_returnsCorrectManualUpdate() { - Application application = gson.fromJson(String.valueOf(jsonNode.get("application")), Application.class); - - final Application applicationCopy = new Application(); - AppsmithBeanUtils.copyNestedNonNullProperties(application, applicationCopy); - - application.setServerSchemaVersion(null); - assertNull(application.getIsAutoUpdate()); - responseUtils.updateApplicationWithDefaultResources(application); - assertEquals(application.getIsAutoUpdate(), false); - - application.setClientSchemaVersion(null); - application.setIsAutoUpdate(null); - responseUtils.updateApplicationWithDefaultResources(application); - assertEquals(application.getIsAutoUpdate(), false); - - application.setIsAutoUpdate(null); - application.setServerSchemaVersion(1000); - application.setClientSchemaVersion(JsonSchemaVersions.clientVersion); - responseUtils.updateApplicationWithDefaultResources(application); - assertEquals(application.getIsAutoUpdate(), true); - - application.setIsAutoUpdate(null); - application.setClientSchemaVersion(1000); - application.setServerSchemaVersion(jsonSchemaVersions.getServerVersion()); - responseUtils.updateApplicationWithDefaultResources(application); - assertEquals(application.getIsAutoUpdate(), true); - - application.setIsAutoUpdate(null); - application.setClientSchemaVersion(jsonSchemaVersions.getClientVersion()); - application.setServerSchemaVersion(jsonSchemaVersions.getServerVersion()); - responseUtils.updateApplicationWithDefaultResources(application); - assertEquals(application.getIsAutoUpdate(), false); - } -} diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/ce/ResponseUtilsCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/ce/ResponseUtilsCETest.java deleted file mode 100644 index dca75e558e..0000000000 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/ce/ResponseUtilsCETest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.appsmith.server.helpers.ce; - -import com.appsmith.external.models.ActionDTO; -import com.appsmith.external.models.DefaultResources; -import com.appsmith.server.dtos.ActionCollectionDTO; -import com.appsmith.server.helpers.ResponseUtils; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest -public class ResponseUtilsCETest { - - @Autowired - private ResponseUtils responseUtils; - - @Test - public void updateCollectionDTOWithDefaultResources() { - ActionCollectionDTO actionCollectionDTO = new ActionCollectionDTO(); - actionCollectionDTO.setId("child-id"); - - DefaultResources defaultResourceIds = new DefaultResources(); - defaultResourceIds.setCollectionId("default-collection-id"); - actionCollectionDTO.setDefaultResources(defaultResourceIds); - - ActionDTO actionDTO = new ActionDTO(); - actionCollectionDTO.setActions(List.of(actionDTO)); - - ActionCollectionDTO updatedActionCollectionDTO = - responseUtils.updateCollectionDTOWithDefaultResources(actionCollectionDTO); - assertThat(updatedActionCollectionDTO).isNotNull(); - assertThat(updatedActionCollectionDTO.getId()).isEqualTo("default-collection-id"); - updatedActionCollectionDTO.getActions().forEach(actionDTO1 -> { - assertThat(actionDTO1.getCollectionId()).isEqualTo("default-collection-id"); - }); - } -} diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/imports/internal/ImportServiceTests.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/imports/internal/ImportServiceTests.java index e44c86ba6b..e222dfbaa8 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/imports/internal/ImportServiceTests.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/imports/internal/ImportServiceTests.java @@ -514,7 +514,7 @@ public class ImportServiceTests { actionCollectionDTO1.setPluginType(PluginType.JS); return layoutCollectionService - .createCollection(actionCollectionDTO1, null) + .createCollection(actionCollectionDTO1) .then(layoutActionService.createSingleAction(action, Boolean.FALSE)) .then(layoutActionService.createSingleAction(action2, Boolean.FALSE)) .then(updateLayoutService.updateLayout( @@ -975,7 +975,7 @@ public class ImportServiceTests { .findAllByApplicationIdAndViewMode(application.getId(), false, MANAGE_ACTIONS, null) .collectList(), customJSLibService.getAllJSLibsInContext( - application.getId(), CreatorContextType.APPLICATION, null, false), + application.getId(), CreatorContextType.APPLICATION, false), applicationService.findById( applicationImportDTO.getApplication().getId(), MANAGE_APPLICATIONS)); })) @@ -1046,8 +1046,6 @@ public class ImportServiceTests { if (!StringUtils.isEmpty(actionDTO.getCollectionId())) { collectionIdInAction.add(actionDTO.getCollectionId()); - assertThat(actionDTO.getDefaultResources().getCollectionId()) - .isEqualTo(actionDTO.getCollectionId()); } }); @@ -1422,13 +1420,11 @@ public class ImportServiceTests { final String branchName = application.getGitApplicationMetadata().getBranchName(); pageList.forEach(page -> { - assertThat(page.getDefaultResources()).isNotNull(); - assertThat(page.getDefaultResources().getBranchName()).isEqualTo(branchName); + assertThat(page.getBranchName()).isEqualTo(branchName); }); actionList.forEach(action -> { - assertThat(action.getDefaultResources()).isNotNull(); - assertThat(action.getDefaultResources().getBranchName()).isEqualTo(branchName); + assertThat(action.getBranchName()).isEqualTo(branchName); }); }) .verifyComplete(); @@ -1771,7 +1767,7 @@ public class ImportServiceTests { ApplicationAccessDTO applicationAccessDTO = new ApplicationAccessDTO(); applicationAccessDTO.setPublicAccess(true); Application newApplication = applicationService - .changeViewAccess(application.getId(), "master", applicationAccessDTO) + .changeViewAccessForAllBranchesByBranchedApplicationId(application.getId(), applicationAccessDTO) .block(); PermissionGroup anonymousPermissionGroup = @@ -2065,7 +2061,7 @@ public class ImportServiceTests { actionCollectionDTO1.setActions(List.of(action1)); actionCollectionDTO1.setPluginType(PluginType.JS); - return layoutCollectionService.createCollection(actionCollectionDTO1, null); + return layoutCollectionService.createCollection(actionCollectionDTO1); }) .flatMap(actionCollectionDTO -> actionCollectionService.getByIdWithoutPermissionCheck(actionCollectionDTO.getId())) @@ -2767,7 +2763,7 @@ public class ImportServiceTests { ApplicationAccessDTO accessDTO = new ApplicationAccessDTO(); accessDTO.setPublicAccess(true); applicationService - .changeViewAccess(exportWithConfigurationAppId, accessDTO) + .changeViewAccessForSingleBranchByBranchedApplicationId(exportWithConfigurationAppId, accessDTO) .block(); final String appName = testApplication.getName(); final Mono resultMono = Mono.zip( @@ -2834,7 +2830,7 @@ public class ImportServiceTests { actionCollectionDTO1.setPluginType(PluginType.JS); return layoutCollectionService - .createCollection(actionCollectionDTO1, null) + .createCollection(actionCollectionDTO1) .then(layoutActionService.createSingleAction(action, Boolean.FALSE)) .then(layoutActionService.createSingleAction(action2, Boolean.FALSE)) .then(updateLayoutService.updateLayout( @@ -3172,10 +3168,10 @@ public class ImportServiceTests { // Set order for the newly created pages applicationPageService - .reorderPage(testApplication.getId(), testPage1.getId(), 0, null) + .reorderPage(testApplication.getId(), testPage1.getId(), 0) .block(); applicationPageService - .reorderPage(testApplication.getId(), testPage2.getId(), 1, null) + .reorderPage(testApplication.getId(), testPage2.getId(), 1) .block(); // Deploy the current application applicationPageService.publish(testApplication.getId(), true).block(); @@ -3402,10 +3398,10 @@ public class ImportServiceTests { // Set order for the newly created pages applicationPageService - .reorderPage(testApplication.getId(), testPage1.getId(), 0, null) + .reorderPage(testApplication.getId(), testPage1.getId(), 0) .block(); applicationPageService - .reorderPage(testApplication.getId(), testPage2.getId(), 1, null) + .reorderPage(testApplication.getId(), testPage2.getId(), 1) .block(); Mono applicationJsonMono = exportService @@ -3581,8 +3577,7 @@ public class ImportServiceTests { .flatMap(application -> // fetch the application pages, this should contain pages from application json Mono.zip( - newPageService.findApplicationPages( - application.getId(), null, null, ApplicationMode.EDIT), + newPageService.findApplicationPages(application.getId(), null, ApplicationMode.EDIT), newActionService .findAllByApplicationIdAndViewMode( application.getId(), false, MANAGE_ACTIONS, null) @@ -3648,7 +3643,7 @@ public class ImportServiceTests { .thenReturn(application)) .flatMap(application -> // fetch the application pages, this should contain pages from application json - newPageService.findApplicationPages(application.getId(), null, null, ApplicationMode.EDIT)); + newPageService.findApplicationPages(application.getId(), null, ApplicationMode.EDIT)); StepVerifier.create(applicationPagesDTOMono) .assertNext(applicationPagesDTO -> { @@ -4474,7 +4469,7 @@ public class ImportServiceTests { ApplicationAccessDTO accessDTO = new ApplicationAccessDTO(); accessDTO.setPublicAccess(true); return applicationService - .changeViewAccess(application.getId(), accessDTO) + .changeViewAccessForSingleBranchByBranchedApplicationId(application.getId(), accessDTO) .thenReturn(application); }); @@ -4640,7 +4635,7 @@ public class ImportServiceTests { }) .zipWith(applicationJson) .flatMap(objects -> importService - .restoreSnapshot(workspaceId, objects.getT1().getId(), null, objects.getT2()) + .restoreSnapshot(workspaceId, objects.getT1().getId(), objects.getT2()) .map(importableArtifact -> (Application) importableArtifact) .zipWith(Mono.just(objects.getT1()))) .flatMap(objects -> { @@ -4847,7 +4842,7 @@ public class ImportServiceTests { public void createExportAppJsonWithCustomJSLibTest() { CustomJSLib jsLib = new CustomJSLib("TestLib", Set.of("accessor1"), "url", "docsUrl", "1.0", "defs_string"); Mono addJSLibMonoCached = customJSLibService - .addJSLibsToContext(testAppId, CreatorContextType.APPLICATION, Set.of(jsLib), null, false) + .addJSLibsToContext(testAppId, CreatorContextType.APPLICATION, Set.of(jsLib), false) .flatMap(isJSLibAdded -> Mono.zip(Mono.just(isJSLibAdded), applicationPageService.publish(testAppId, true))) .map(tuple2 -> { @@ -5020,7 +5015,7 @@ public class ImportServiceTests { action1.getActionConfiguration().setBody("mockBody"); actionCollectionDTO1.setActions(List.of(action1)); actionCollectionDTO1.setPluginType(PluginType.JS); - return layoutCollectionService.createCollection(actionCollectionDTO1, null); + return layoutCollectionService.createCollection(actionCollectionDTO1); } @Test diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCEImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCEImplTest.java index a8f3ae63dd..61d74b6a91 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCEImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCEImplTest.java @@ -1,7 +1,6 @@ package com.appsmith.server.refactors.ce; import com.appsmith.external.models.ActionDTO; -import com.appsmith.external.models.DefaultResources; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.ActionCollection; @@ -16,7 +15,6 @@ import com.appsmith.server.dtos.LayoutDTO; import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.dtos.RefactorEntityNameDTO; import com.appsmith.server.exceptions.AppsmithError; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; @@ -37,7 +35,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.transaction.reactive.TransactionalOperator; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -66,9 +63,6 @@ class RefactoringServiceCEImplTest { @SpyBean private NewActionService newActionService; - @MockBean - private ResponseUtils responseUtils; - @MockBean private UpdateLayoutService updateLayoutService; @@ -96,9 +90,6 @@ class RefactoringServiceCEImplTest { @SpyBean private EntityRefactoringService widgetEntityRefactoringService; - @Autowired - private TransactionalOperator transactionalOperator; - @Autowired private EntityValidationService entityValidationService; @@ -109,13 +100,11 @@ class RefactoringServiceCEImplTest { refactoringServiceCE = new RefactoringServiceCEImpl( newPageService, - responseUtils, updateLayoutService, applicationService, pagePermission, analyticsService, sessionUserService, - transactionalOperator, entityValidationService, jsActionEntityRefactoringService, newActionEntityRefactoringService, @@ -139,20 +128,16 @@ class RefactoringServiceCEImplTest { oldUnpublishedCollection.setPageId("testPageId"); oldUnpublishedCollection.setName("oldName"); oldActionCollection.setUnpublishedCollection(oldUnpublishedCollection); - oldUnpublishedCollection.setDefaultResources(setDefaultResources(oldUnpublishedCollection)); - oldActionCollection.setDefaultResources(setDefaultResources(oldActionCollection)); + oldActionCollection.setBaseId("testCollectionId"); LayoutDTO layout = new LayoutDTO(); final JSONObject jsonObject = new JSONObject(); jsonObject.put("key", "value"); layout.setDsl(jsonObject); - Mockito.when(responseUtils.updateLayoutDTOWithDefaultResources(Mockito.any())) - .thenReturn(layout); - Mockito.doReturn(Mono.empty()) .when(actionCollectionEntityRefactoringService) - .updateRefactoredEntity(Mockito.any(), Mockito.isNull()); + .updateRefactoredEntity(Mockito.any()); NewPage newPage = new NewPage(); newPage.setId("testPageId"); @@ -189,8 +174,7 @@ class RefactoringServiceCEImplTest { .when(actionCollectionEntityRefactoringService) .getExistingEntityNames(Mockito.anyString(), Mockito.any(), Mockito.anyString(), Mockito.eq(false)); - final Mono layoutDTOMono = - refactoringServiceCE.refactorEntityName(refactorActionCollectionNameDTO, null); + final Mono layoutDTOMono = refactoringServiceCE.refactorEntityName(refactorActionCollectionNameDTO); StepVerifier.create(layoutDTOMono) .assertNext(layoutDTO -> { @@ -243,8 +227,7 @@ class RefactoringServiceCEImplTest { Mockito.when(newPageService.getByIdWithoutPermissionCheck(Mockito.anyString())) .thenReturn(Mono.just(newPage)); - final Mono layoutDTOMono = - refactoringServiceCE.refactorEntityName(refactorActionCollectionNameDTO, null); + final Mono layoutDTOMono = refactoringServiceCE.refactorEntityName(refactorActionCollectionNameDTO); StepVerifier.create(layoutDTOMono) .expectErrorMatches(e -> AppsmithError.NAME_CLASH_NOT_ALLOWED_IN_REFACTOR @@ -269,8 +252,7 @@ class RefactoringServiceCEImplTest { oldUnpublishedCollection.setPageId("testPageId"); oldUnpublishedCollection.setName("oldName"); oldActionCollection.setUnpublishedCollection(oldUnpublishedCollection); - oldActionCollection.setDefaultResources(setDefaultResources(oldActionCollection)); - oldUnpublishedCollection.setDefaultResources(setDefaultResources(oldUnpublishedCollection)); + oldActionCollection.setBaseId("testCollectionId"); Mockito.when(newActionService.findActionDTObyIdAndViewMode( Mockito.anyString(), Mockito.anyBoolean(), Mockito.any())) @@ -281,7 +263,7 @@ class RefactoringServiceCEImplTest { Mockito.doReturn(Mono.empty()) .when(actionCollectionEntityRefactoringService) - .updateRefactoredEntity(Mockito.any(), Mockito.isNull()); + .updateRefactoredEntity(Mockito.any()); NewPage newPage = new NewPage(); newPage.setId("testPageId"); @@ -322,9 +304,6 @@ class RefactoringServiceCEImplTest { layout.setActionUpdates(new ArrayList<>()); layout.setLayoutOnLoadActions(new ArrayList<>()); - Mockito.when(responseUtils.updateLayoutDTOWithDefaultResources(Mockito.any())) - .thenReturn(layout); - Mockito.when(updateLayoutService.updateLayout( Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.any())) .thenReturn(Mono.just(layout)); @@ -333,8 +312,7 @@ class RefactoringServiceCEImplTest { .when(actionCollectionEntityRefactoringService) .getExistingEntityNames(Mockito.anyString(), Mockito.any(), Mockito.anyString(), Mockito.eq(false)); - final Mono layoutDTOMono = - refactoringServiceCE.refactorEntityName(refactorActionCollectionNameDTO, null); + final Mono layoutDTOMono = refactoringServiceCE.refactorEntityName(refactorActionCollectionNameDTO); StepVerifier.create(layoutDTOMono) .assertNext(layoutDTO -> { @@ -343,15 +321,4 @@ class RefactoringServiceCEImplTest { }) .verifyComplete(); } - - DefaultResources setDefaultResources(T collection) { - DefaultResources defaultResources = new DefaultResources(); - if (collection instanceof ActionCollection) { - defaultResources.setApplicationId("testApplicationId"); - defaultResources.setCollectionId("testCollectionId"); - } else if (collection instanceof ActionCollectionDTO) { - defaultResources.setPageId("testPageId"); - } - return defaultResources; - } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCETest.java index 52208f9a10..739c4b997d 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCETest.java @@ -4,7 +4,6 @@ import com.appsmith.external.dtos.DslExecutableDTO; import com.appsmith.external.models.ActionConfiguration; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.Datasource; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.PluginType; import com.appsmith.external.models.Property; import com.appsmith.server.actioncollections.base.ActionCollectionService; @@ -308,9 +307,8 @@ class RefactoringServiceCETest { refactorActionNameDTO.setNewName("PostNameChange"); refactorActionNameDTO.setActionId(createdAction.getId()); - LayoutDTO postNameChangeLayout = refactoringService - .refactorEntityName(refactorActionNameDTO, null) - .block(); + LayoutDTO postNameChangeLayout = + refactoringService.refactorEntityName(refactorActionNameDTO).block(); Mono postNameChangeActionMono = newActionService.findById(createdAction.getId(), READ_ACTIONS); @@ -373,7 +371,7 @@ class RefactoringServiceCETest { layoutActionService.createSingleAction(action, Boolean.FALSE).block(); LayoutDTO firstLayout = updateLayoutService - .updateLayout(gitConnectedPage.getId(), testApp.getId(), layout.getId(), layout, null) + .updateLayout(gitConnectedPage.getId(), testApp.getId(), layout.getId(), layout) .block(); RefactorEntityNameDTO refactorActionNameDTO = new RefactorEntityNameDTO(); @@ -384,9 +382,8 @@ class RefactoringServiceCETest { refactorActionNameDTO.setNewName("PostNameChange"); refactorActionNameDTO.setActionId(createdAction.getId()); - LayoutDTO postNameChangeLayout = refactoringService - .refactorEntityName(refactorActionNameDTO, null) - .block(); + LayoutDTO postNameChangeLayout = + refactoringService.refactorEntityName(refactorActionNameDTO).block(); Mono postNameChangeActionMono = newActionService.findById(createdAction.getId(), READ_ACTIONS); @@ -406,16 +403,7 @@ class RefactoringServiceCETest { innerArrayReference.clear(); innerArrayReference.add(new JSONObject(Map.of("innerK", "{{\tPostNameChange.data}}"))); assertThat(postNameChangeLayout.getDsl()).isEqualTo(dsl); - assertThat(updatedAction.getDefaultResources()).isNotNull(); - assertThat(updatedAction.getDefaultResources().getActionId()) - .isEqualTo(updatedAction.getId()); - assertThat(updatedAction.getDefaultResources().getApplicationId()) - .isEqualTo(gitConnectedApp.getId()); - assertThat(updatedAction - .getUnpublishedAction() - .getDefaultResources() - .getPageId()) - .isEqualTo(gitConnectedPage.getId()); + assertThat(updatedAction.getBaseId()).isEqualTo(updatedAction.getId()); }) .verifyComplete(); } @@ -461,7 +449,7 @@ class RefactoringServiceCETest { refactorActionNameDTO.setNewName("NewActionName"); refactorActionNameDTO.setActionId(firstAction.getId()); - refactoringService.refactorEntityName(refactorActionNameDTO, null).block(); + refactoringService.refactorEntityName(refactorActionNameDTO).block(); Mono postNameChangeActionMono = newActionService.findById(secondAction.getId(), READ_ACTIONS); @@ -514,7 +502,7 @@ class RefactoringServiceCETest { assert createdAction != null; refactorActionNameDTO.setActionId(createdAction.getId()); - final Mono layoutDTOMono = refactoringService.refactorEntityName(refactorActionNameDTO, null); + final Mono layoutDTOMono = refactoringService.refactorEntityName(refactorActionNameDTO); StepVerifier.create(layoutDTOMono) .expectErrorMatches(e -> e instanceof AppsmithException @@ -568,7 +556,6 @@ class RefactoringServiceCETest { duplicateNameCompleteAction.setPluginId(duplicateName.getPluginId()); duplicateNameCompleteAction.setDocumentation(duplicateName.getDocumentation()); duplicateNameCompleteAction.setApplicationId(duplicateName.getApplicationId()); - duplicateNameCompleteAction.setDefaultResources(new DefaultResources()); // Now save this action directly in the repo to create a duplicate action name scenario newActionService @@ -588,9 +575,8 @@ class RefactoringServiceCETest { refactorActionNameDTO.setNewName("newName"); refactorActionNameDTO.setActionId(firstAction.getId()); - LayoutDTO postNameChangeLayout = refactoringService - .refactorEntityName(refactorActionNameDTO, null) - .block(); + LayoutDTO postNameChangeLayout = + refactoringService.refactorEntityName(refactorActionNameDTO).block(); Mono postNameChangeActionMono = newActionService.findById(firstAction.getId(), READ_ACTIONS); @@ -641,7 +627,7 @@ class RefactoringServiceCETest { refactorNameDTO.setNewName("NewNameTable1"); Mono widgetRenameMono = - refactoringService.refactorEntityName(refactorNameDTO, null).cache(); + refactoringService.refactorEntityName(refactorNameDTO).cache(); Mono pageFromRepoMono = widgetRenameMono.then(newPageService.findPageById(testPage.getId(), READ_PAGES, false)); @@ -691,7 +677,7 @@ class RefactoringServiceCETest { refactorNameDTO.setNewName("NewNameTable1"); Mono widgetRenameMono = - refactoringService.refactorEntityName(refactorNameDTO, null).cache(); + refactoringService.refactorEntityName(refactorNameDTO).cache(); Mono pageFromRepoMono = widgetRenameMono.then(newPageService.findPageById(testPage.getId(), READ_PAGES, false)); @@ -743,7 +729,7 @@ class RefactoringServiceCETest { refactorNameDTO.setOldName("oldWidgetName"); refactorNameDTO.setNewName("newWidgetName"); - Mono widgetRenameMono = refactoringService.refactorEntityName(refactorNameDTO, null); + Mono widgetRenameMono = refactoringService.refactorEntityName(refactorNameDTO); StepVerifier.create(widgetRenameMono) .assertNext(updatedLayout -> { @@ -793,9 +779,8 @@ class RefactoringServiceCETest { actionCollectionDTO1.setActions(List.of(action1)); actionCollectionDTO1.setPluginType(PluginType.JS); - final ActionCollectionDTO createdActionCollectionDTO1 = layoutCollectionService - .createCollection(actionCollectionDTO1, null) - .block(); + final ActionCollectionDTO createdActionCollectionDTO1 = + layoutCollectionService.createCollection(actionCollectionDTO1).block(); RefactorEntityNameDTO refactorNameDTO = new RefactorEntityNameDTO(); refactorNameDTO.setEntityType(EntityType.WIDGET); @@ -805,7 +790,7 @@ class RefactoringServiceCETest { refactorNameDTO.setNewName("NewNameTable1"); LayoutDTO updatedLayout = - refactoringService.refactorEntityName(refactorNameDTO, null).block(); + refactoringService.refactorEntityName(refactorNameDTO).block(); assert createdActionCollectionDTO1 != null; final Mono actionCollectionMono = @@ -855,7 +840,7 @@ class RefactoringServiceCETest { originalActionCollectionDTO.setActions(List.of(action1)); final ActionCollectionDTO dto = layoutCollectionService - .createCollection(originalActionCollectionDTO, null) + .createCollection(originalActionCollectionDTO) .block(); ActionCollectionDTO actionCollectionDTO = new ActionCollectionDTO(); @@ -876,7 +861,7 @@ class RefactoringServiceCETest { refactorActionNameInCollectionDTO.setCollectionName("originalName"); final Mono> tuple2Mono = refactoringService - .refactorEntityName(refactorActionNameInCollectionDTO, null) + .refactorEntityName(refactorActionNameInCollectionDTO) .then(actionCollectionService .getByIdWithoutPermissionCheck(dto.getId()) .zipWith(newActionService.findById( diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/repositories/ce/CustomActionCollectionRepositoryCEImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/repositories/ce/CustomActionCollectionRepositoryCEImplTest.java index 887bd8e6f8..a5d1270b56 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/repositories/ce/CustomActionCollectionRepositoryCEImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/repositories/ce/CustomActionCollectionRepositoryCEImplTest.java @@ -1,8 +1,6 @@ package com.appsmith.server.repositories.ce; -import com.appsmith.external.models.DefaultResources; import com.appsmith.server.domains.ActionCollection; -import com.appsmith.server.dtos.ActionCollectionDTO; import com.appsmith.server.repositories.ActionCollectionRepository; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -100,69 +98,4 @@ public class CustomActionCollectionRepositoryCEImplTest { }) .verifyComplete(); } - - private void testFindAllActionCollectionsByNamePageIdsViewModeAndBranch(boolean isViewMode) { - String defaultPageId = "default-page-id", branchName = "main", childPageId = "child-page-id"; - - // create action collection that has different values in pageId and defaultResources.pageId - ActionCollection actionCollection = new ActionCollection(); - ActionCollectionDTO actionCollectionDTO = new ActionCollectionDTO(); - actionCollectionDTO.setPageId(childPageId); - actionCollectionDTO.setDefaultResources(new DefaultResources()); - actionCollectionDTO.getDefaultResources().setPageId(defaultPageId); - - if (isViewMode) { - actionCollection.setPublishedCollection(actionCollectionDTO); - } else { - actionCollection.setUnpublishedCollection(actionCollectionDTO); - } - - actionCollection.setDefaultResources(new DefaultResources()); - actionCollection.getDefaultResources().setBranchName(branchName); - - Mono createActionCollectionMono = - actionCollectionRepository.save(actionCollection).cache(); - - // check whether action collection is found when branch and default page id matches - Mono> actionCollectionListMono = createActionCollectionMono - .thenMany(actionCollectionRepository.findAllActionCollectionsByNameDefaultPageIdsViewModeAndBranch( - null, List.of(defaultPageId), isViewMode, branchName, null, null)) - .collectList(); - - StepVerifier.create(actionCollectionListMono) - .assertNext(actionCollectionList -> { - assertThat(actionCollectionList).hasSize(1); - }) - .verifyComplete(); - - // check whether action collection is not found when branch name does not match - Mono> actionCollectionListMono2 = createActionCollectionMono - .thenMany(actionCollectionRepository.findAllActionCollectionsByNameDefaultPageIdsViewModeAndBranch( - null, List.of(defaultPageId), isViewMode, "feature", null, null)) - .collectList(); - - StepVerifier.create(actionCollectionListMono2) - .assertNext(actionCollectionList -> { - assertThat(actionCollectionList).hasSize(0); - }) - .verifyComplete(); - - // check whether action collection is not found when default page id does not match - Mono> actionCollectionListMono3 = createActionCollectionMono - .thenMany(actionCollectionRepository.findAllActionCollectionsByNameDefaultPageIdsViewModeAndBranch( - null, List.of(childPageId), isViewMode, branchName, null, null)) - .collectList(); - - StepVerifier.create(actionCollectionListMono3) - .assertNext(actionCollectionList -> { - assertThat(actionCollectionList).hasSize(0); - }) - .verifyComplete(); - } - - @Test - public void findAllActionCollectionsByNamePageIdsViewModeAndBranch_ForChildBranch_Successful() { - testFindAllActionCollectionsByNamePageIdsViewModeAndBranch(false); - testFindAllActionCollectionsByNamePageIdsViewModeAndBranch(true); - } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryTest.java index 271b8c9607..6cff70087a 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/repositories/ce/CustomNewPageRepositoryTest.java @@ -100,7 +100,7 @@ class CustomNewPageRepositoryTest { @Test void findPageWithoutBranchName() { - StepVerifier.create(newPageRepository.findPageByBranchNameAndDefaultPageId( + StepVerifier.create(newPageRepository.findPageByBranchNameAndBasePageId( null, "pageId", AclPermission.PAGE_CREATE_PAGE_ACTIONS)) .verifyComplete(); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java index 8fc8ae95f7..1f90c776f2 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceImplTest.java @@ -1,7 +1,6 @@ package com.appsmith.server.services; import com.appsmith.external.models.ActionDTO; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.PluginType; import com.appsmith.external.views.Views; import com.appsmith.server.acl.AclPermission; @@ -10,14 +9,12 @@ import com.appsmith.server.actioncollections.base.ActionCollectionService; import com.appsmith.server.actioncollections.base.ActionCollectionServiceImpl; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.constants.FieldName; -import com.appsmith.server.defaultresources.DefaultResourcesService; import com.appsmith.server.domains.ActionCollection; import com.appsmith.server.domains.NewAction; import com.appsmith.server.domains.NewPage; import com.appsmith.server.dtos.ActionCollectionDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; @@ -85,9 +82,6 @@ public class ActionCollectionServiceImplTest { @MockBean ApplicationService applicationService; - @MockBean - ResponseUtils responseUtils; - ApplicationPermission applicationPermission; PagePermission pagePermission; ActionPermission actionPermission; @@ -101,18 +95,6 @@ public class ActionCollectionServiceImplTest { @MockBean private PolicyGenerator policyGenerator; - @MockBean - private DefaultResourcesService actionCollectionDefaultResourcesService; - - @MockBean - private DefaultResourcesService actionCollectionDtoDefaultResourcesService; - - @MockBean - private DefaultResourcesService newActionDefaultResourcesService; - - @MockBean - private DefaultResourcesService actionDTODefaultResourcesService; - @BeforeEach public void setUp() { applicationPermission = new ApplicationPermissionImpl(); @@ -125,13 +107,8 @@ public class ActionCollectionServiceImplTest { newActionService, policyGenerator, applicationService, - responseUtils, applicationPermission, - actionPermission, - actionCollectionDefaultResourcesService, - actionCollectionDtoDefaultResourcesService, - newActionDefaultResourcesService, - actionDTODefaultResourcesService); + actionPermission); layoutCollectionService = new LayoutCollectionServiceImpl( newPageService, @@ -141,7 +118,6 @@ public class ActionCollectionServiceImplTest { actionCollectionService, newActionService, analyticsService, - responseUtils, actionCollectionRepository, pagePermission, actionPermission); @@ -175,23 +151,12 @@ public class ActionCollectionServiceImplTest { invocationOnMock -> Mono.justOrEmpty(invocationOnMock.getArguments()[0])); } - DefaultResources setDefaultResources(T collection) { - DefaultResources defaultResources = new DefaultResources(); - if (collection instanceof ActionCollection) { - defaultResources.setApplicationId("testApplicationId"); - defaultResources.setCollectionId("testCollectionId"); - } else if (collection instanceof ActionCollectionDTO) { - defaultResources.setPageId("testPageId"); - } - return defaultResources; - } - @Test public void testCreateCollection_withId_throwsError() { ActionCollectionDTO actionCollectionDTO = new ActionCollectionDTO(); actionCollectionDTO.setId("testId"); final Mono actionCollectionDTOMono = - layoutCollectionService.createCollection(actionCollectionDTO, null); + layoutCollectionService.createCollection(actionCollectionDTO); StepVerifier.create(actionCollectionDTOMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -203,7 +168,7 @@ public class ActionCollectionServiceImplTest { public void testCreateCollection_withoutOrgPageApplicationPluginIds_throwsError() { ActionCollectionDTO actionCollectionDTO = new ActionCollectionDTO(); final Mono actionCollectionDTOMono = - layoutCollectionService.createCollection(actionCollectionDTO, null); + layoutCollectionService.createCollection(actionCollectionDTO); StepVerifier.create(actionCollectionDTOMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException) @@ -225,22 +190,13 @@ public class ActionCollectionServiceImplTest { final NewPage newPage = objectMapper.convertValue(jsonNode.get("newPage"), NewPage.class); Mockito.when(newPageService.findById(Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); - Mockito.when(newPageService.findByBranchNameAndDefaultPageId(Mockito.any(), Mockito.any(), Mockito.any())) + Mockito.when(newPageService.findByBranchNameAndBasePageId(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); Mockito.when(refactoringService.isNameAllowed(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(false)); - Mockito.when(actionCollectionRepository.findAllActionCollectionsByNameDefaultPageIdsViewModeAndBranch( - Mockito.any(), - Mockito.any(), - Mockito.anyBoolean(), - Mockito.any(), - Mockito.any(), - Mockito.any())) - .thenReturn(Flux.empty()); - final Mono actionCollectionDTOMono = - layoutCollectionService.createCollection(actionCollectionDTO, null); + layoutCollectionService.createCollection(actionCollectionDTO); StepVerifier.create(actionCollectionDTOMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -260,7 +216,6 @@ public class ActionCollectionServiceImplTest { actionCollectionDTO.setWorkspaceId("testWorkspaceId"); actionCollectionDTO.setPluginId("testPluginId"); actionCollectionDTO.setPluginType(PluginType.JS); - actionCollectionDTO.setDefaultResources(setDefaultResources(actionCollectionDTO)); ObjectMapper objectMapper = new ObjectMapper(); final JsonNode jsonNode = objectMapper.readValue(mockObjects, JsonNode.class); @@ -268,20 +223,11 @@ public class ActionCollectionServiceImplTest { Mockito.when(newPageService.findById(Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); - Mockito.when(newPageService.findByBranchNameAndDefaultPageId(Mockito.any(), Mockito.any(), Mockito.any())) + Mockito.when(newPageService.findByBranchNameAndBasePageId(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); Mockito.when(refactoringService.isNameAllowed(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(true)); - Mockito.when(actionCollectionRepository.findAllActionCollectionsByNameDefaultPageIdsViewModeAndBranch( - Mockito.any(), - Mockito.any(), - Mockito.anyBoolean(), - Mockito.any(), - Mockito.any(), - Mockito.any())) - .thenReturn(Flux.empty()); - Mockito.when(layoutActionService.createAction(Mockito.any())).thenReturn(Mono.just(new ActionDTO())); Mockito.when(updateLayoutService.updatePageLayoutsByPageId(Mockito.anyString())) @@ -303,16 +249,8 @@ public class ActionCollectionServiceImplTest { return Mono.just(argument); }); - Mockito.when(responseUtils.updateCollectionDTOWithDefaultResources(Mockito.any())) - .thenAnswer(invocation -> { - final ActionCollectionDTO argument = - (ActionCollectionDTO) invocation.getArguments()[0]; - argument.setDefaultResources(setDefaultResources(argument)); - return argument; - }); - final Mono actionCollectionDTOMono = - layoutCollectionService.createCollection(actionCollectionDTO, null); + layoutCollectionService.createCollection(actionCollectionDTO); StepVerifier.create(actionCollectionDTOMono) .assertNext(actionCollectionDTO1 -> { @@ -335,7 +273,6 @@ public class ActionCollectionServiceImplTest { action.setClientSideExecution(true); actionCollectionDTO.setActions(List.of(action)); actionCollectionDTO.setPluginType(PluginType.JS); - actionCollectionDTO.setDefaultResources(setDefaultResources(actionCollectionDTO)); ObjectMapper objectMapper = new ObjectMapper(); final JsonNode jsonNode = objectMapper.readValue(mockObjects, JsonNode.class); @@ -343,20 +280,11 @@ public class ActionCollectionServiceImplTest { Mockito.when(newPageService.findById(Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); - Mockito.when(newPageService.findByBranchNameAndDefaultPageId(Mockito.any(), Mockito.any(), Mockito.any())) + Mockito.when(newPageService.findByBranchNameAndBasePageId(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); Mockito.when(refactoringService.isNameAllowed(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(true)); - Mockito.when(actionCollectionRepository.findAllActionCollectionsByNameDefaultPageIdsViewModeAndBranch( - Mockito.any(), - Mockito.any(), - Mockito.anyBoolean(), - Mockito.any(), - Mockito.any(), - Mockito.any())) - .thenReturn(Flux.empty()); - Mockito.when(layoutActionService.createSingleAction(Mockito.any(), Mockito.any())) .thenAnswer(invocation -> { final ActionDTO argument = (ActionDTO) invocation.getArguments()[0]; @@ -404,16 +332,8 @@ public class ActionCollectionServiceImplTest { return Mono.just(argument); }); - Mockito.when(responseUtils.updateCollectionDTOWithDefaultResources(Mockito.any())) - .thenAnswer(invocation -> { - final ActionCollectionDTO argument = - (ActionCollectionDTO) invocation.getArguments()[0]; - argument.setDefaultResources(setDefaultResources(argument)); - return argument; - }); - final Mono actionCollectionDTOMono = - layoutCollectionService.createCollection(actionCollectionDTO, null); + layoutCollectionService.createCollection(actionCollectionDTO); StepVerifier.create(actionCollectionDTOMono) .assertNext(actionCollectionDTO1 -> { @@ -424,9 +344,6 @@ public class ActionCollectionServiceImplTest { assertEquals("testAction", actionDTO.getName()); assertEquals("testActionId", actionDTO.getId()); assertEquals("testCollection.testAction", actionDTO.getFullyQualifiedName()); - assertEquals( - "testActionCollectionId", - actionDTO.getDefaultResources().getCollectionId()); assertTrue(actionDTO.getClientSideExecution()); }) .verifyComplete(); @@ -437,7 +354,7 @@ public class ActionCollectionServiceImplTest { ActionCollectionDTO actionCollectionDTO = new ActionCollectionDTO(); actionCollectionDTO.setId("testId"); final Mono actionCollectionDTOMono = - layoutCollectionService.updateUnpublishedActionCollection(null, actionCollectionDTO, null); + layoutCollectionService.updateUnpublishedActionCollection(null, actionCollectionDTO); StepVerifier.create(actionCollectionDTOMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -449,7 +366,6 @@ public class ActionCollectionServiceImplTest { public void testUpdateUnpublishedActionCollection_withInvalidId_throwsError() throws IOException { ActionCollectionDTO actionCollectionDTO = new ActionCollectionDTO(); actionCollectionDTO.setId("testId"); - actionCollectionDTO.setDefaultResources(setDefaultResources(actionCollectionDTO)); actionCollectionDTO.setPageId("testPageId"); ObjectMapper objectMapper = new ObjectMapper(); @@ -459,7 +375,7 @@ public class ActionCollectionServiceImplTest { Mockito.when(actionCollectionRepository.findById(Mockito.anyString(), Mockito.any())) .thenReturn(Mono.empty()); - Mockito.when(newPageService.findByBranchNameAndDefaultPageId(Mockito.any(), Mockito.any(), Mockito.any())) + Mockito.when(newPageService.findByBranchNameAndBasePageId(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(newPage)); Mockito.when(newPageService.findById(Mockito.any(), Mockito.any())) @@ -470,7 +386,7 @@ public class ActionCollectionServiceImplTest { .thenReturn(Flux.empty()); final Mono actionCollectionDTOMono = - layoutCollectionService.updateUnpublishedActionCollection("testId", actionCollectionDTO, null); + layoutCollectionService.updateUnpublishedActionCollection("testId", actionCollectionDTO); StepVerifier.create(actionCollectionDTOMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -508,8 +424,6 @@ public class ActionCollectionServiceImplTest { .readValue(jsonNode.get("actionCollectionWithAction"), ActionCollection.class); final ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); unpublishedCollection.setActions(List.of()); - actionCollection.setDefaultResources(setDefaultResources(actionCollection)); - unpublishedCollection.setDefaultResources(setDefaultResources(unpublishedCollection)); Instant deletedAt = Instant.now(); @@ -551,8 +465,6 @@ public class ActionCollectionServiceImplTest { .writeValueAsString(jsonNode.get("actionCollectionWithAction")), ActionCollection.class); ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - actionCollection.setDefaultResources(setDefaultResources(actionCollection)); - unpublishedCollection.setDefaultResources(setDefaultResources(unpublishedCollection)); Instant deletedAt = Instant.now(); Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.any())) @@ -601,10 +513,6 @@ public class ActionCollectionServiceImplTest { ActionCollection.class); actionCollection.setPublishedCollection(null); - actionCollection.setDefaultResources(setDefaultResources(actionCollection)); - actionCollection - .getUnpublishedCollection() - .setDefaultResources(setDefaultResources(actionCollection.getUnpublishedCollection())); Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.any())) .thenReturn(Mono.just(actionCollection)); @@ -646,13 +554,6 @@ public class ActionCollectionServiceImplTest { .writeValueAsString(jsonNode.get("actionCollectionWithAction")), ActionCollection.class); actionCollection.setPublishedCollection(null); - DefaultResources resources = new DefaultResources(); - resources.setApplicationId("testApplicationId"); - resources.setApplicationId("testCollectionId"); - actionCollection.setDefaultResources(setDefaultResources(actionCollection)); - actionCollection - .getUnpublishedCollection() - .setDefaultResources(setDefaultResources(actionCollection.getUnpublishedCollection())); Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.any())) .thenReturn(Mono.just(actionCollection)); @@ -688,17 +589,14 @@ public class ActionCollectionServiceImplTest { String mockAppId = "mock-app-id"; String mockWorkspaceId = "mock-workspace-id"; Set mockPermissions = Set.of("mock-permission-1", "mock-permission-2", "mock-permission-3"); - DefaultResources mockDefaultResources = new DefaultResources(); - mockDefaultResources.setApplicationId(mockAppId); ActionCollectionDTO mockApplicationCollectionDTO = new ActionCollectionDTO(); - mockApplicationCollectionDTO.setDefaultResources(mockDefaultResources); + actionCollection.setId(mockId); actionCollection.setApplicationId(mockAppId); actionCollection.setWorkspaceId(mockWorkspaceId); actionCollection.setUserPermissions(mockPermissions); actionCollection.setPublishedCollection(mockApplicationCollectionDTO); actionCollection.setUnpublishedCollection(mockApplicationCollectionDTO); - actionCollection.setDefaultResources(mockDefaultResources); Mono unpublishedActionCollectionDTOMono = actionCollectionService.generateActionCollectionByViewMode(actionCollection, false); @@ -714,18 +612,12 @@ public class ActionCollectionServiceImplTest { assertEquals(mockAppId, publishedActionCollectionDTO.getApplicationId()); assertEquals(mockWorkspaceId, publishedActionCollectionDTO.getWorkspaceId()); assertEquals(mockPermissions, publishedActionCollectionDTO.getUserPermissions()); - assertEquals( - mockAppId, - publishedActionCollectionDTO.getDefaultResources().getApplicationId()); assertNotNull(unpublishedActionCollectionDTO); assertEquals(mockId, unpublishedActionCollectionDTO.getId()); assertEquals(mockAppId, unpublishedActionCollectionDTO.getApplicationId()); assertEquals(mockWorkspaceId, unpublishedActionCollectionDTO.getWorkspaceId()); assertEquals(mockPermissions, unpublishedActionCollectionDTO.getUserPermissions()); - assertEquals( - mockAppId, - unpublishedActionCollectionDTO.getDefaultResources().getApplicationId()); }) .verifyComplete(); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceTest.java index 9ff1f2b903..b13dd94a39 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceTest.java @@ -224,7 +224,7 @@ public class ActionCollectionServiceTest { actionCollectionDTO.setPluginId(datasource.getPluginId()); actionCollectionDTO.setPluginType(PluginType.JS); - StepVerifier.create(layoutCollectionService.createCollection(actionCollectionDTO, null)) + StepVerifier.create(layoutCollectionService.createCollection(actionCollectionDTO)) .assertNext(actionCollectionDTO1 -> { assertThat(actionCollectionDTO1.getApplicationId()).isEqualTo(testApp.getId()); assertThat(actionCollectionDTO1.getWorkspaceId()).isEqualTo(testApp.getWorkspaceId()); @@ -263,7 +263,7 @@ public class ActionCollectionServiceTest { actionCollectionDTO.setPluginId(datasource.getPluginId()); actionCollectionDTO.setPluginType(PluginType.JS); actionCollectionDTO.setDeletedAt(Instant.now()); - layoutCollectionService.createCollection(actionCollectionDTO, null).block(); + layoutCollectionService.createCollection(actionCollectionDTO).block(); ActionCollection createdActionCollection = actionCollectionRepository .findByApplicationId(createdApplication.getId(), READ_ACTIONS, null) .blockFirst(); @@ -302,7 +302,7 @@ public class ActionCollectionServiceTest { actionCollectionDTO.setPluginId(datasource.getPluginId()); actionCollectionDTO.setPluginType(PluginType.JS); actionCollectionDTO.setDeletedAt(Instant.now()); - layoutCollectionService.createCollection(actionCollectionDTO, null).block(); + layoutCollectionService.createCollection(actionCollectionDTO).block(); ActionCollection createdActionCollection = actionCollectionRepository .findByApplicationId(createdApplication.getId(), READ_ACTIONS, null) .blockFirst(); @@ -345,7 +345,7 @@ public class ActionCollectionServiceTest { actionCollectionDTO.setPluginType(PluginType.JS); Mono actionCollectionMono = layoutCollectionService - .createCollection(actionCollectionDTO, null) + .createCollection(actionCollectionDTO) .flatMap( createdCollection -> actionCollectionService.findById(createdCollection.getId(), READ_ACTIONS)); @@ -422,9 +422,8 @@ public class ActionCollectionServiceTest { actionCollectionDTO1.setPluginType(PluginType.JS); actionCollectionDTO1.setBody("export default { x: 1 }"); - final ActionCollectionDTO createdActionCollectionDTO1 = layoutCollectionService - .createCollection(actionCollectionDTO1, null) - .block(); + final ActionCollectionDTO createdActionCollectionDTO1 = + layoutCollectionService.createCollection(actionCollectionDTO1).block(); ActionCollectionDTO actionCollectionDTO2 = new ActionCollectionDTO(); actionCollectionDTO2.setName("testCollection2"); @@ -440,9 +439,8 @@ public class ActionCollectionServiceTest { actionCollectionDTO2.setPluginType(PluginType.JS); actionCollectionDTO2.setBody("export default { x: testCollection1.testAction1() }"); - final ActionCollectionDTO createdActionCollectionDTO2 = layoutCollectionService - .createCollection(actionCollectionDTO2, null) - .block(); + final ActionCollectionDTO createdActionCollectionDTO2 = + layoutCollectionService.createCollection(actionCollectionDTO2).block(); RefactorEntityNameDTO refactorActionNameDTO = new RefactorEntityNameDTO(); refactorActionNameDTO.setEntityType(EntityType.JS_ACTION); @@ -458,9 +456,8 @@ public class ActionCollectionServiceTest { refactorActionNameDTO.setOldName("testAction1"); refactorActionNameDTO.setNewName("newTestAction1"); - final LayoutDTO layoutDTO = refactoringService - .refactorEntityName(refactorActionNameDTO, null) - .block(); + final LayoutDTO layoutDTO = + refactoringService.refactorEntityName(refactorActionNameDTO).block(); assert createdActionCollectionDTO2 != null; final Mono actionCollectionMono = @@ -517,9 +514,8 @@ public class ActionCollectionServiceTest { actionCollectionDTO1.setPluginType(PluginType.JS); actionCollectionDTO1.setBody("export default { x: 1 }"); - final ActionCollectionDTO createdActionCollectionDTO1 = layoutCollectionService - .createCollection(actionCollectionDTO1, null) - .block(); + final ActionCollectionDTO createdActionCollectionDTO1 = + layoutCollectionService.createCollection(actionCollectionDTO1).block(); ActionCollectionDTO actionCollectionDTO2 = new ActionCollectionDTO(); actionCollectionDTO2.setName("testCollection2"); @@ -535,9 +531,8 @@ public class ActionCollectionServiceTest { actionCollectionDTO2.setPluginType(PluginType.JS); actionCollectionDTO2.setBody("export default { x: Api1.run() }"); - final ActionCollectionDTO createdActionCollectionDTO2 = layoutCollectionService - .createCollection(actionCollectionDTO2, null) - .block(); + final ActionCollectionDTO createdActionCollectionDTO2 = + layoutCollectionService.createCollection(actionCollectionDTO2).block(); RefactorEntityNameDTO refactorActionNameDTO = new RefactorEntityNameDTO(); refactorActionNameDTO.setEntityType(EntityType.JS_ACTION); @@ -553,9 +548,8 @@ public class ActionCollectionServiceTest { refactorActionNameDTO.setOldName("run"); refactorActionNameDTO.setNewName("newRun"); - final LayoutDTO layoutDTO = refactoringService - .refactorEntityName(refactorActionNameDTO, null) - .block(); + final LayoutDTO layoutDTO = + refactoringService.refactorEntityName(refactorActionNameDTO).block(); assert createdActionCollectionDTO2 != null; final Mono actionCollectionMono = @@ -614,9 +608,8 @@ public class ActionCollectionServiceTest { actionCollectionDTO.setActions(List.of(action1)); actionCollectionDTO.setPluginType(PluginType.JS); - ActionCollectionDTO createdActionCollectionDTO = layoutCollectionService - .createCollection(actionCollectionDTO, null) - .block(); + ActionCollectionDTO createdActionCollectionDTO = + layoutCollectionService.createCollection(actionCollectionDTO).block(); assert createdActionCollectionDTO != null; assert createdActionCollectionDTO.getId() != null; String createdActionCollectionId = createdActionCollectionDTO.getId(); @@ -626,7 +619,7 @@ public class ActionCollectionServiceTest { actionCollectionDTO.getActions().get(0).getActionConfiguration().setBody("updatedBody"); ActionCollectionDTO updatedActionCollectionDTO = layoutCollectionService - .updateUnpublishedActionCollection(createdActionCollectionId, actionCollectionDTO, null) + .updateUnpublishedActionCollection(createdActionCollectionId, actionCollectionDTO) .block(); assert updatedActionCollectionDTO != null; assert updatedActionCollectionDTO.getId() != null; @@ -690,9 +683,8 @@ public class ActionCollectionServiceTest { actionCollectionDTO.setActions(List.of(action1)); actionCollectionDTO.setPluginType(PluginType.JS); - final ActionCollectionDTO createdActionCollectionDTO = layoutCollectionService - .createCollection(actionCollectionDTO, null) - .block(); + final ActionCollectionDTO createdActionCollectionDTO = + layoutCollectionService.createCollection(actionCollectionDTO).block(); assert createdActionCollectionDTO != null; final Mono> viewModeCollectionsMono = applicationPageService diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ApplicationPageServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ApplicationPageServiceTest.java index 9d86fbdeb6..4082dfce51 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ApplicationPageServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ApplicationPageServiceTest.java @@ -140,7 +140,7 @@ public class ApplicationPageServiceTest { @WithUserDetails("api_user") public void cloneApplication_WhenClonedSuccessfully_ApplicationIsPublished() { Mono applicationMono = createPageMono(UUID.randomUUID().toString()) - .flatMap(pageDTO -> applicationPageService.cloneApplication(pageDTO.getApplicationId(), null)); + .flatMap(pageDTO -> applicationPageService.cloneApplication(pageDTO.getApplicationId())); StepVerifier.create(applicationMono) .assertNext(application -> { @@ -197,7 +197,7 @@ public class ApplicationPageServiceTest { int currentDslVersion = layout.getDsl().getAsNumber("version").intValue(); Mockito.when(dslMigrationUtils.getLatestDslVersion()).thenReturn(Mono.just(currentDslVersion)); - StepVerifier.create(applicationPageService.getPageAndMigrateDslByBranchAndDefaultPageId( + StepVerifier.create(applicationPageService.getPageAndMigrateDslByBranchAndBasePageId( newPage.getId(), null, false, true)) .assertNext(pageDTO -> { Layout layout2 = pageDTO.getLayouts().get(0); @@ -242,7 +242,7 @@ public class ApplicationPageServiceTest { Mockito.when(dslMigrationUtils.migratePageDsl(any(JSONObject.class))).thenReturn(Mono.just(dslAfterMigration)); Mono newPageMono = applicationPageService - .getPageAndMigrateDslByBranchAndDefaultPageId(newPage.getId(), null, false, true) + .getPageAndMigrateDslByBranchAndBasePageId(newPage.getId(), null, false, true) .then(newPageService.getByIdWithoutPermissionCheck(newPage.getId())); StepVerifier.create(newPageMono) @@ -302,7 +302,7 @@ public class ApplicationPageServiceTest { Mockito.when(dslMigrationUtils.migratePageDsl(any(JSONObject.class))).thenReturn(Mono.just(dslAfterMigration)); Mono newPageMono = applicationPageService - .getPageAndMigrateDslByBranchAndDefaultPageId(newPage.getId(), null, false, true) + .getPageAndMigrateDslByBranchAndBasePageId(newPage.getId(), null, false, true) .then(newPageService.getByIdWithoutPermissionCheck(newPage.getId())); StepVerifier.create(newPageMono) @@ -350,7 +350,7 @@ public class ApplicationPageServiceTest { Mockito.when(dslMigrationUtils.migratePageDsl(any(JSONObject.class))).thenReturn(Mono.just(dslAfterMigration)); Mono newPageMono = applicationPageService - .getPageAndMigrateDslByBranchAndDefaultPageId(newPage.getId(), null, true, true) + .getPageAndMigrateDslByBranchAndBasePageId(newPage.getId(), null, true, true) .then(newPageService.getByIdWithoutPermissionCheck(newPage.getId())); StepVerifier.create(newPageMono) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ApplicationSnapshotServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ApplicationSnapshotServiceTest.java index 08dd28a190..99aaf6bba8 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ApplicationSnapshotServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ApplicationSnapshotServiceTest.java @@ -97,11 +97,11 @@ public class ApplicationSnapshotServiceTest { .flatMap(application -> { assert application.getId() != null; return applicationSnapshotService - .createApplicationSnapshot(application.getId(), "") + .createApplicationSnapshot(application.getId()) .thenReturn(application.getId()); }) - .flatMap( - applicationId -> applicationSnapshotService.getWithoutDataByApplicationId(applicationId, null)); + .flatMap(applicationId -> + applicationSnapshotService.getWithoutDataByBranchedApplicationId(applicationId)); StepVerifier.create(snapshotMono) .assertNext(snapshot -> { @@ -122,12 +122,12 @@ public class ApplicationSnapshotServiceTest { assert application.getId() != null; // create snapshot twice return applicationSnapshotService - .createApplicationSnapshot(application.getId(), "") - .then(applicationSnapshotService.createApplicationSnapshot(application.getId(), "")) + .createApplicationSnapshot(application.getId()) + .then(applicationSnapshotService.createApplicationSnapshot(application.getId())) .thenReturn(application.getId()); }) - .flatMap( - applicationId -> applicationSnapshotService.getWithoutDataByApplicationId(applicationId, null)); + .flatMap(applicationId -> + applicationSnapshotService.getWithoutDataByBranchedApplicationId(applicationId)); StepVerifier.create(snapshotMono) .assertNext(snapshot -> { @@ -154,9 +154,8 @@ public class ApplicationSnapshotServiceTest { Mono> tuple2Mono = applicationPageService .createApplication(testApplication) .flatMap(application -> applicationSnapshotService - .createApplicationSnapshot(testDefaultAppId, testBranchName) - .then(applicationSnapshotService.getWithoutDataByApplicationId( - testDefaultAppId, testBranchName)) + .createApplicationSnapshot(application.getId()) + .then(applicationSnapshotService.getWithoutDataByBranchedApplicationId(application.getId())) .zipWith(Mono.just(application))); StepVerifier.create(tuple2Mono) @@ -190,7 +189,7 @@ public class ApplicationSnapshotServiceTest { .thenReturn(application); }) .flatMapMany(application -> applicationSnapshotService - .createApplicationSnapshot(application.getId(), null) + .createApplicationSnapshot(application.getId()) .thenMany(applicationSnapshotRepository.findByApplicationId(application.getId()))); StepVerifier.create(applicationSnapshotFlux) @@ -220,14 +219,14 @@ public class ApplicationSnapshotServiceTest { pageDTO.setApplicationId(createdApp.getId()); return applicationPageService .createPage(pageDTO) - .then(newPageService.findApplicationPages(createdApp.getId(), null, null, ApplicationMode.EDIT)); + .then(newPageService.findApplicationPages(createdApp.getId(), null, ApplicationMode.EDIT)); }); Mono pagesAfterSnapshot = applicationMono .flatMap( application -> { // create a snapshot return applicationSnapshotService - .createApplicationSnapshot(application.getId(), null) + .createApplicationSnapshot(application.getId()) .thenReturn(application); }) .flatMap( @@ -237,9 +236,9 @@ public class ApplicationSnapshotServiceTest { pageDTO.setApplicationId(application.getId()); return applicationPageService .createPage(pageDTO) - .then(applicationSnapshotService.restoreSnapshot(application.getId(), null)) + .then(applicationSnapshotService.restoreSnapshot(application.getId())) .then(newPageService.findApplicationPages( - application.getId(), null, null, ApplicationMode.EDIT)); + application.getId(), null, ApplicationMode.EDIT)); }); // not using Mono.zip because we want pagesBeforeSnapshot to finish first @@ -266,11 +265,11 @@ public class ApplicationSnapshotServiceTest { .flatMap( application -> { // create a snapshot return applicationSnapshotService - .createApplicationSnapshot(application.getId(), null) + .createApplicationSnapshot(application.getId()) .thenReturn(application); }) .flatMapMany(application -> applicationSnapshotService - .restoreSnapshot(application.getId(), null) + .restoreSnapshot(application.getId()) .thenMany(applicationSnapshotRepository.findByApplicationId(application.getId()))); StepVerifier.create(snapshotFlux).verifyComplete(); @@ -289,7 +288,7 @@ public class ApplicationSnapshotServiceTest { Flux snapshotFlux = applicationSnapshotRepository .saveAll(List.of(snapshot1, snapshot2)) - .then(applicationSnapshotService.deleteSnapshot(testAppId, null)) + .then(applicationSnapshotService.deleteSnapshot(testAppId)) .thenMany(applicationSnapshotRepository.findByApplicationId(testAppId)); StepVerifier.create(snapshotFlux).verifyComplete(); @@ -304,7 +303,7 @@ public class ApplicationSnapshotServiceTest { Mono applicationSnapshotMono = applicationPageService .createApplication(testApplication) .flatMap(application1 -> { - return applicationSnapshotService.getWithoutDataByApplicationId(application1.getId(), null); + return applicationSnapshotService.getWithoutDataByBranchedApplicationId(application1.getId()); }); StepVerifier.create(applicationSnapshotMono) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ApplicationTemplateServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ApplicationTemplateServiceTest.java index 68bd4b06d4..a2f22e82c3 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ApplicationTemplateServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ApplicationTemplateServiceTest.java @@ -2,7 +2,6 @@ package com.appsmith.server.services; import com.appsmith.server.configurations.CloudServicesConfig; import com.appsmith.server.domains.Application; -import com.appsmith.server.domains.GitArtifactMetadata; import com.appsmith.server.domains.Workspace; import com.appsmith.server.dtos.TemplateDTO; import lombok.extern.slf4j.Slf4j; @@ -58,7 +57,7 @@ public class ApplicationTemplateServiceTest { testApplication.setUpdatedAt(Instant.now()); testApplication.setLastDeployedAt(Instant.now()); testApplication.setModifiedBy("some-user"); - testApplication.setGitApplicationMetadata(new GitArtifactMetadata()); + // testApplication.setGitApplicationMetadata(new GitArtifactMetadata()); cloudServicesConfig.setBaseUrl(String.format("http://localhost:%s", mockCloudServices.getPort())); mockCloudServices.enqueue( diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ConsolidatedAPIServiceImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ConsolidatedAPIServiceImplTest.java index 619dcfae7f..00d38a0eeb 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ConsolidatedAPIServiceImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ConsolidatedAPIServiceImplTest.java @@ -214,50 +214,60 @@ public class ConsolidatedAPIServiceImplTest { ApplicationPagesDTO sampleApplicationPagesDTO = new ApplicationPagesDTO(); sampleApplicationPagesDTO.setWorkspaceId("sampleWorkspaceId"); - doReturn(Mono.just(new Application())) + Application mockApplication = new Application(); + mockApplication.setId("mockApplicationId"); + doReturn(Mono.just(mockApplication)) .when(spyApplicationService) - .findByDefaultIdBranchNameAndApplicationMode(anyString(), anyString(), any()); + .findByBranchedApplicationIdAndApplicationMode(anyString(), any()); - doReturn(Mono.just(List.of(new NewPage()))) + NewPage mockNewPage = new NewPage(); + mockNewPage.setApplicationId("mockApplicationId"); + doReturn(Mono.just(mockNewPage)) + .when(spyNewPageService) + .findByBranchNameAndBasePageId(anyString(), anyString(), any()); + + doReturn(Mono.just(List.of(mockNewPage))) .when(spyApplicationPageService) .getPagesBasedOnApplicationMode(any(), any()); + doReturn(Mono.just(new PageDTO())) + .when(spyApplicationPageService) + .getPageAndMigrateDslByBranchAndBasePageId(anyString(), anyString(), anyBoolean(), anyBoolean()); + doReturn(Mono.just(sampleApplicationPagesDTO)) .when(spyNewPageService) .createApplicationPagesDTO(any(), any(), anyBoolean(), anyBoolean()); Theme sampleTheme = new Theme(); sampleTheme.setName("sampleTheme"); - doReturn(Mono.just(sampleTheme)).when(spyThemeService).getApplicationTheme(anyString(), any(), anyString()); - doReturn(Flux.just(sampleTheme)).when(spyThemeService).getApplicationThemes(anyString(), anyString()); + doReturn(Mono.just(sampleTheme)).when(spyThemeService).getApplicationTheme(anyString(), any()); + doReturn(Flux.just(sampleTheme)).when(spyThemeService).getApplicationThemes(anyString()); CustomJSLib sampleCustomJSLib = new CustomJSLib(); sampleCustomJSLib.setName("sampleJSLib"); doReturn(Mono.just(List.of(sampleCustomJSLib))) .when(spyCustomJSLibService) - .getAllJSLibsInContext(anyString(), any(), anyString(), anyBoolean()); + .getAllJSLibsInContext(anyString(), any(), anyBoolean()); PageDTO samplePageDTO = new PageDTO(); samplePageDTO.setName("samplePageDTO"); doReturn(Mono.just(samplePageDTO)) .when(spyApplicationPageService) - .getPageAndMigrateDslByBranchAndDefaultPageId(anyString(), anyString(), anyBoolean(), anyBoolean()); + .getPageAndMigrateDslByBranchAndBasePageId(anyString(), anyString(), anyBoolean(), anyBoolean()); ActionViewDTO sampleActionViewDTO = new ActionViewDTO(); sampleActionViewDTO.setName("sampleActionViewDTO"); - doReturn(Flux.just(sampleActionViewDTO)) - .when(spyNewActionService) - .getActionsForViewMode(anyString(), anyString()); + doReturn(Flux.just(sampleActionViewDTO)).when(spyNewActionService).getActionsForViewMode(anyString()); ActionCollectionViewDTO sampleActionCollectionViewDTO = new ActionCollectionViewDTO(); sampleActionCollectionViewDTO.setName("sampleActionCollectionViewDTO"); doReturn(Flux.just(sampleActionCollectionViewDTO)) .when(spyActionCollectionService) - .getActionCollectionsForViewMode(anyString(), anyString()); + .getActionCollectionsForViewMode(anyString()); Mono consolidatedInfoForPageLoad = consolidatedAPIService.getConsolidatedInfoForPageLoad( - "pageId", "appId", "branch", ApplicationMode.PUBLISHED); + "pageId", null, "branch", ApplicationMode.PUBLISHED); StepVerifier.create(consolidatedInfoForPageLoad) .assertNext(consolidatedAPIResponseDTO -> { assertNotNull(consolidatedAPIResponseDTO.getPublishedActions()); @@ -395,35 +405,52 @@ public class ConsolidatedAPIServiceImplTest { ApplicationPagesDTO sampleApplicationPagesDTO = new ApplicationPagesDTO(); sampleApplicationPagesDTO.setWorkspaceId("sampleWorkspaceId"); - doReturn(Mono.just(new Application())) + Application mockApplication = new Application(); + mockApplication.setId("mockApplicationId"); + doReturn(Mono.just(mockApplication)) .when(spyApplicationService) - .findByDefaultIdBranchNameAndApplicationMode(anyString(), anyString(), any()); + .findByBranchedApplicationIdAndApplicationMode(anyString(), any()); - doReturn(Mono.just(List.of(new NewPage()))) + NewPage mockNewPage = new NewPage(); + mockNewPage.setApplicationId("mockApplicationId"); + doReturn(Mono.just(mockNewPage)) + .when(spyNewPageService) + .findByBranchNameAndBasePageId(anyString(), anyString(), any()); + + doReturn(Mono.just(List.of(mockNewPage))) .when(spyApplicationPageService) .getPagesBasedOnApplicationMode(any(), any()); + doReturn(Mono.just(new PageDTO())) + .when(spyApplicationPageService) + .getPageAndMigrateDslByBranchAndBasePageId(anyString(), anyString(), anyBoolean(), anyBoolean()); + doReturn(Mono.just(sampleApplicationPagesDTO)) .when(spyNewPageService) .createApplicationPagesDTO(any(), any(), anyBoolean(), anyBoolean()); Theme sampleTheme = new Theme(); sampleTheme.setName("sampleTheme"); - doReturn(Mono.just(sampleTheme)).when(spyThemeService).getApplicationTheme(anyString(), any(), anyString()); - doReturn(Flux.just(sampleTheme)).when(spyThemeService).getApplicationThemes(anyString(), anyString()); + doReturn(Mono.just(sampleTheme)).when(spyThemeService).getApplicationTheme(anyString(), any()); + doReturn(Flux.just(sampleTheme)).when(spyThemeService).getApplicationThemes(anyString()); CustomJSLib sampleCustomJSLib = new CustomJSLib(); sampleCustomJSLib.setName("sampleJSLib"); doReturn(Mono.just(List.of(sampleCustomJSLib))) .when(spyCustomJSLibService) - .getAllJSLibsInContext(anyString(), any(), anyString(), anyBoolean()); + .getAllJSLibsInContext(anyString(), any(), anyBoolean()); PageDTO samplePageDTO = new PageDTO(); samplePageDTO.setName("samplePageDTO"); doReturn(Mono.just(samplePageDTO)) .doReturn(Mono.just(samplePageDTO)) .when(spyApplicationPageService) - .getPageAndMigrateDslByBranchAndDefaultPageId(anyString(), anyString(), anyBoolean(), anyBoolean()); + .getPageAndMigrateDslByBranchAndBasePageId(anyString(), anyString(), anyBoolean(), anyBoolean()); + + doReturn(Mono.just(samplePageDTO)) + .doReturn(Mono.just(samplePageDTO)) + .when(spyApplicationPageService) + .getPageDTOAfterMigratingDSL(any(), anyBoolean(), anyBoolean()); doReturn(Mono.just(samplePageDTO)) .doReturn(Mono.just(samplePageDTO)) @@ -433,19 +460,16 @@ public class ConsolidatedAPIServiceImplTest { ActionDTO sampleActionDTO = new ActionDTO(); sampleActionDTO.setName("sampleActionDTO"); sampleActionDTO.setUpdatedAt(Instant.now()); - doReturn(Flux.just(sampleActionDTO)) - .when(spyNewActionService) - .getUnpublishedActions(any(), anyString(), anyBoolean()); + doReturn(Flux.just(sampleActionDTO)).when(spyNewActionService).getUnpublishedActions(any(), anyBoolean()); ActionCollectionDTO sampleActionCollectionDTO = new ActionCollectionDTO(); sampleActionCollectionDTO.setName("sampleActionCollectionDTO"); doReturn(Flux.just(sampleActionCollectionDTO)) .when(spyActionCollectionService) - .getPopulatedActionCollectionsByViewMode(any(), anyBoolean(), anyString()); + .getPopulatedActionCollectionsByViewMode(any(), anyBoolean()); PageNameIdDTO samplePageNameIdDTO = new PageNameIdDTO(); samplePageNameIdDTO.setName("samplePageNameIdDTO"); - samplePageNameIdDTO.setDefaultPageId("pageId"); sampleApplicationPagesDTO.setPages(List.of(samplePageNameIdDTO)); Plugin samplePlugin = new Plugin(); @@ -483,8 +507,7 @@ public class ConsolidatedAPIServiceImplTest { when(mockMockDataService.getMockDataSet()).thenReturn(Mono.just(sampleMockDataDTO)); Mono consolidatedInfoForPageLoad = - consolidatedAPIService.getConsolidatedInfoForPageLoad( - "pageId", "appId", "branch", ApplicationMode.EDIT); + consolidatedAPIService.getConsolidatedInfoForPageLoad("pageId", null, "branch", ApplicationMode.EDIT); StepVerifier.create(consolidatedInfoForPageLoad) .assertNext(consolidatedAPIResponseDTO -> { assertNotNull(consolidatedAPIResponseDTO.getUserProfile()); @@ -697,11 +720,11 @@ public class ConsolidatedAPIServiceImplTest { when(mockProductAlertService.getSingleApplicableMessage()) .thenReturn(Mono.just(List.of(sampleProductAlertResponseDTO))); - when(mockNewPageRepository.findPageByBranchNameAndDefaultPageId(anyString(), anyString(), any())) + when(mockNewPageRepository.findPageByBranchNameAndBasePageId(anyString(), anyString(), any())) .thenReturn(Mono.empty()); doReturn(Mono.empty()) .when(spyApplicationRepository) - .getApplicationByGitBranchAndDefaultApplicationId(anyString(), anyString(), any(AclPermission.class)); + .getApplicationByGitBranchAndBaseApplicationId(anyString(), anyString(), any(AclPermission.class)); Mono consolidatedInfoForPageLoad = consolidatedAPIService.getConsolidatedInfoForPageLoad( diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/CurlImporterServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/CurlImporterServiceTest.java index 8560f4bd89..cf8fdec1cc 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/CurlImporterServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/CurlImporterServiceTest.java @@ -314,7 +314,7 @@ public class CurlImporterServiceTest { public void testImportActionOnInvalidInput() { // Set up the application & page for which this import curl action would be added Application app = new Application(); - app.setName("curlTest Incorrect Command"); + app.setName("curlTest testImportActionOnInvalidInput"); Application application = applicationPageService.createApplication(app, workspaceId).block(); @@ -324,8 +324,7 @@ public class CurlImporterServiceTest { .block(); assert page != null; - Mono action = - curlImporterService.importAction("'", null, page.getId(), "actionName", workspaceId, null); + Mono action = curlImporterService.importAction("'", null, page.getId(), "actionName", workspaceId); StepVerifier.create(action) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -338,7 +337,7 @@ public class CurlImporterServiceTest { public void testImportActionOnNullInput() { // Set up the application & page for which this import curl action would be added Application app = new Application(); - app.setName("curlTest Incorrect Command"); + app.setName("curlTest testImportActionOnNullInput"); Application application = applicationPageService.createApplication(app, workspaceId).block(); @@ -348,8 +347,7 @@ public class CurlImporterServiceTest { .block(); assert page != null; - Mono action = - curlImporterService.importAction(null, null, page.getId(), "actionName", workspaceId, null); + Mono action = curlImporterService.importAction(null, null, page.getId(), "actionName", workspaceId); StepVerifier.create(action) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -362,7 +360,7 @@ public class CurlImporterServiceTest { public void testImportActionOnEmptyInput() { // Set up the application & page for which this import curl action would be added Application app = new Application(); - app.setName("curlTest Incorrect Command"); + app.setName("curlTest testImportActionOnEmptyInput"); Application application = applicationPageService.createApplication(app, workspaceId).block(); @@ -372,8 +370,7 @@ public class CurlImporterServiceTest { .block(); assert page != null; - Mono action = - curlImporterService.importAction("", null, page.getId(), "actionName", workspaceId, null); + Mono action = curlImporterService.importAction("", null, page.getId(), "actionName", workspaceId); StepVerifier.create(action) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -390,7 +387,7 @@ public class CurlImporterServiceTest { // Set up the application & page for which this import curl action would be added Application app = new Application(); - app.setName("curlTest App"); + app.setName("curlTest importValidCurlCommand"); Mono applicationMono = applicationPageService .createApplication(app, workspaceId) @@ -399,7 +396,7 @@ public class CurlImporterServiceTest { return newPageService .findById(pageId, AclPermission.MANAGE_PAGES) .flatMap(newPage -> { - newPage.getDefaultResources().setBranchName("main"); + newPage.setBranchName("main"); return newPageService.update(pageId, newPage); }) .thenReturn(application1); @@ -415,8 +412,8 @@ public class CurlImporterServiceTest { "curl -X GET http://localhost:8080/api/v1/actions?name=something -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: Basic YXBpX3VzZXI6OHVBQDsmbUI6Y252Tn57Iw==' -H 'Cache-Control: no-cache' -H 'Connection: keep-alive' -H 'Content-Type: application/json' -H 'Cookie: SESSION=97c5def4-4f72-45aa-96fe-e8a9f5ade0b5,SESSION=97c5def4-4f72-45aa-96fe-e8a9f5ade0b5; SESSION=' -H 'Host: localhost:8080' -H 'Postman-Token: 16e4b6bc-2c7a-4ab1-a127-bca382dfc0f0,a6655daa-db07-4c5e-aca3-3fd505bd230d' -H 'User-Agent: PostmanRuntime/7.20.1' -H 'cache-control: no-cache' -d '{someJson}'"; Mono resultMono = defaultPageMono - .flatMap(page -> curlImporterService.importAction( - command, null, page.getId(), "actionName", workspaceId, "main")) + .flatMap(page -> + curlImporterService.importAction(command, null, page.getId(), "actionName", workspaceId)) .cache(); Mono savedActionMono = @@ -443,14 +440,8 @@ public class CurlImporterServiceTest { assertThat(action1.getActionConfiguration().getHttpMethod()).isEqualTo(HttpMethod.GET); assertThat(action1.getActionConfiguration().getBody()).isEqualTo("{someJson}"); - assertThat(newAction.getDefaultResources().getActionId()).isEqualTo(newAction.getId()); - assertThat(action1.getDefaultResources().getPageId()) - .isEqualTo(newPage.getDefaultResources().getPageId()); - assertThat(newAction.getDefaultResources().getBranchName()).isNotEmpty(); - assertThat(newAction.getDefaultResources().getBranchName()) - .isEqualTo(newPage.getDefaultResources().getBranchName()); - assertThat(newAction.getDefaultResources().getApplicationId()) - .isEqualTo(newPage.getDefaultResources().getApplicationId()); + assertThat(newAction.getBaseId()).isEqualTo(newAction.getId()); + assertThat(newAction.getBranchName()).isEqualTo(newPage.getBranchName()); }) .verifyComplete(); @@ -465,21 +456,21 @@ public class CurlImporterServiceTest { .flatMap(defaultPage -> newPageService .findById(branchedPageId, AclPermission.MANAGE_PAGES) .flatMap(newPage -> { - newPage.setDefaultResources(defaultPage.getDefaultResources()); - newPage.getDefaultResources().setBranchName("testBranch"); + newPage.setBaseId(defaultPage.getId()); + newPage.setBranchName("testBranch"); return newPageService.save(newPage); })) .cache(); Mono branchedResultMono = branchedPageMono - .flatMap(page -> curlImporterService.importAction( - command, null, page.getDefaultResources().getPageId(), "actionName", workspaceId, "testBranch")) + .flatMap(page -> + curlImporterService.importAction(command, null, page.getId(), "actionName", workspaceId)) .cache(); // As importAction updates the ids with the defaultIds before sending the response to client we have to again // fetch branched action Mono branchedSavedActionMono = - branchedResultMono.flatMap(actionDTO -> newActionService.findByBranchNameAndDefaultActionId( + branchedResultMono.flatMap(actionDTO -> newActionService.findByBranchNameAndBaseActionId( "testBranch", actionDTO.getId(), false, AclPermission.MANAGE_ACTIONS)); StepVerifier.create(Mono.zip(branchedResultMono, branchedPageMono, branchedSavedActionMono)) @@ -503,15 +494,9 @@ public class CurlImporterServiceTest { assertThat(action1.getActionConfiguration().getHttpMethod()).isEqualTo(HttpMethod.GET); assertThat(action1.getActionConfiguration().getBody()).isEqualTo("{someJson}"); - assertThat(newAction.getDefaultResources().getActionId()).isEqualTo(newAction.getId()); - assertThat(action1.getDefaultResources().getPageId()) - .isEqualTo(newPage.getDefaultResources().getPageId()); - assertThat(action1.getDefaultResources().getPageId()).isNotEqualTo(newPage.getId()); + assertThat(newAction.getBaseId()).isEqualTo(newAction.getId()); - assertThat(newAction.getDefaultResources().getBranchName()).isNotEmpty(); - assertThat(newAction.getDefaultResources().getBranchName()).isEqualTo("testBranch"); - assertThat(newAction.getDefaultResources().getApplicationId()) - .isEqualTo(newPage.getDefaultResources().getApplicationId()); + assertThat(newAction.getBranchName()).isEqualTo("testBranch"); }) .verifyComplete(); } @@ -1048,7 +1033,7 @@ public class CurlImporterServiceTest { String command = "invalid curl command here"; Mono actionMono = - curlImporterService.importAction(command, null, "pageId", "actionName", workspaceId, null); + curlImporterService.importAction(command, null, "pageId", "actionName", workspaceId); StepVerifier.create(actionMono).verifyError(); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutActionServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutActionServiceTest.java index a70490538a..ecda5e353f 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutActionServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutActionServiceTest.java @@ -20,7 +20,6 @@ import com.appsmith.server.domains.Plugin; import com.appsmith.server.domains.User; import com.appsmith.server.domains.Workspace; import com.appsmith.server.dtos.ApplicationJson; -import com.appsmith.server.dtos.ClonePageMetaDTO; import com.appsmith.server.dtos.EntityType; import com.appsmith.server.dtos.LayoutDTO; import com.appsmith.server.dtos.PageDTO; @@ -83,7 +82,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @SpringBootTest @Slf4j @DirtiesContext -public class LayoutActionServiceTest { +class LayoutActionServiceTest { @SpyBean NewActionService newActionService; @@ -255,7 +254,7 @@ public class LayoutActionServiceTest { } @AfterEach - public void cleanup() { + void cleanup() { List deletedApplications = applicationService .findByWorkspaceId(workspaceId, applicationPermission.getDeletePermission()) .flatMap(remainingApplication -> applicationPageService.deleteApplication(remainingApplication.getId())) @@ -266,7 +265,7 @@ public class LayoutActionServiceTest { @Test @WithUserDetails(value = "api_user") - public void deleteUnpublishedAction_WhenActionDeleted_OnPageLoadActionsIsEmpty() { + void deleteUnpublishedAction_WhenActionDeleted_OnPageLoadActionsIsEmpty() { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); @@ -309,14 +308,14 @@ public class LayoutActionServiceTest { // Verify that no action is marked to run on page load. assertThat(page.getLayouts().get(0).getLayoutOnLoadActions()) - .hasSize(0); + .isEmpty(); }) .verifyComplete(); } @Test @WithUserDetails(value = "api_user") - public void updateActionUpdatesLayout() { + void updateActionUpdatesLayout() { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); @@ -423,7 +422,7 @@ public class LayoutActionServiceTest { @Test @WithUserDetails(value = "api_user") - public void updateLayout_WhenOnLoadChanged_ActionExecuted() { + void updateLayout_WhenOnLoadChanged_ActionExecuted() { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); @@ -537,7 +536,7 @@ public class LayoutActionServiceTest { @Test @WithUserDetails(value = "api_user") - public void testHintMessageOnLocalhostUrlOnUpdateActionEvent() { + void testHintMessageOnLocalhostUrlOnUpdateActionEvent() { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); @@ -588,7 +587,7 @@ public class LayoutActionServiceTest { @Test @WithUserDetails(value = "api_user") - public void tableWidgetKeyEscape() { + void tableWidgetKeyEscape() { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); @@ -629,7 +628,7 @@ public class LayoutActionServiceTest { @Test @WithUserDetails(value = "api_user") - public void duplicateActionNameCreation() { + void duplicateActionNameCreation() { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); @@ -664,7 +663,7 @@ public class LayoutActionServiceTest { @SneakyThrows @Test @WithUserDetails(value = "api_user") - public void OnLoadActionsWhenActionDependentOnActionViaWidget() { + void OnLoadActionsWhenActionDependentOnActionViaWidget() { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); @@ -768,7 +767,7 @@ public class LayoutActionServiceTest { @Test @WithUserDetails(value = "api_user") - public void simpleOnPageLoadActionCreationTest() throws JsonProcessingException { + void simpleOnPageLoadActionCreationTest() throws JsonProcessingException { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); @@ -866,9 +865,10 @@ public class LayoutActionServiceTest { .assertNext(updatedLayout -> { assertThat(updatedLayout.getLayoutOnLoadActions()).hasSize(2); - // Assert that all three the actions dont belong to the same set + // Assert that all three the actions don't belong to the same set final Set firstSet = updatedLayout.getLayoutOnLoadActions().get(0); + assertThat(firstSet).isNotEmpty(); assertThat(firstSet).allMatch(actionDTO -> Set.of("firstAction", "thirdAction") .contains(actionDTO.getName())); final DslExecutableDTO secondSetAction = updatedLayout @@ -884,7 +884,7 @@ public class LayoutActionServiceTest { @SneakyThrows @Test @WithUserDetails(value = "api_user") - public void OnLoadActionsWhenActionDependentOnWidgetButNotPageLoadCandidate() { + void OnLoadActionsWhenActionDependentOnWidgetButNotPageLoadCandidate() { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); @@ -972,7 +972,7 @@ public class LayoutActionServiceTest { @SneakyThrows(JsonProcessingException.class) @Test @WithUserDetails(value = "api_user") - public void updateLayout_withSelfReferencingWidget_updatesLayout() { + void updateLayout_withSelfReferencingWidget_updatesLayout() { JSONObject parentDsl = new JSONObject( objectMapper.readValue(DEFAULT_PAGE_LAYOUT, new TypeReference>() {})); @@ -1008,11 +1008,9 @@ public class LayoutActionServiceTest { @SneakyThrows(JsonProcessingException.class) @Test @WithUserDetails(value = "api_user") - public void updateMultipleLayouts_MultipleLayouts_LayoutsUpdated() { + void updateMultipleLayouts_MultipleLayouts_LayoutsUpdated() { // clone the current page to create another page for testing - PageDTO secondPage = applicationPageService - .clonePage(testPage.getId(), new ClonePageMetaDTO()) - .block(); + PageDTO secondPage = applicationPageService.clonePage(testPage.getId()).block(); List testPages = List.of(testPage, secondPage); UpdateMultiplePageLayoutDTO multiplePageLayoutDTO = new UpdateMultiplePageLayoutDTO(); @@ -1035,7 +1033,7 @@ public class LayoutActionServiceTest { newPageService.findPageById(secondPage.getId(), READ_PAGES, false)); Mono> updateAndGetPagesMono = updateLayoutService - .updateMultipleLayouts(testApp.getId(), null, multiplePageLayoutDTO) + .updateMultipleLayouts(testApp.getId(), multiplePageLayoutDTO) .then(pagesMono); StepVerifier.create(updateAndGetPagesMono) @@ -1046,8 +1044,8 @@ public class LayoutActionServiceTest { ArrayList childArray1 = (ArrayList) dsl1.get("children"); ArrayList childArray2 = (ArrayList) dsl2.get("children"); - assertEquals(childArray1.size(), 1); - assertEquals(childArray2.size(), 1); + assertEquals(1, childArray1.size()); + assertEquals(1, childArray2.size()); LinkedHashMap widget1 = childArray1.get(0); LinkedHashMap widget2 = childArray2.get(0); @@ -1068,7 +1066,7 @@ public class LayoutActionServiceTest { */ @Test @WithUserDetails(value = "api_user") - public void testExecuteOnPageLoadOrderWhenAllActionsAreOnlyExplicitlySetToExecute() throws JsonProcessingException { + void testExecuteOnPageLoadOrderWhenAllActionsAreOnlyExplicitlySetToExecute() throws JsonProcessingException { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); @@ -1105,7 +1103,8 @@ public class LayoutActionServiceTest { createdAction1.setExecuteOnLoad(true); // this can only be set to true post action creation. NewAction newAction1 = new NewAction(); newAction1.setUnpublishedAction(createdAction1); - newAction1.setDefaultResources(createdAction1.getDefaultResources()); + newAction1.setBranchName(createdAction1.getBranchName()); + newAction1.setBaseId(createdAction1.getBaseId()); newAction1.setPluginId(installed_plugin.getId()); newAction1.setPluginType(installed_plugin.getType()); @@ -1115,7 +1114,8 @@ public class LayoutActionServiceTest { createdAction2.setExecuteOnLoad(true); // this can only be set to true post action creation. NewAction newAction2 = new NewAction(); newAction2.setUnpublishedAction(createdAction2); - newAction2.setDefaultResources(createdAction2.getDefaultResources()); + newAction2.setBranchName(createdAction2.getBranchName()); + newAction2.setBaseId(createdAction2.getBaseId()); newAction2.setPluginId(installed_plugin.getId()); newAction2.setPluginType(installed_plugin.getType()); @@ -1159,7 +1159,7 @@ public class LayoutActionServiceTest { */ @Test @WithUserDetails(value = "api_user") - public void updateLayout_WhenPageLoadActionSetBothWaysExplicitlyAndImplicitlyViaWidget_ActionsSaved() { + void updateLayout_WhenPageLoadActionSetBothWaysExplicitlyAndImplicitlyViaWidget_ActionsSaved() { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); @@ -1188,7 +1188,8 @@ public class LayoutActionServiceTest { createdAction1.setUserSetOnLoad(true); NewAction newAction1 = new NewAction(); newAction1.setUnpublishedAction(createdAction1); - newAction1.setDefaultResources(createdAction1.getDefaultResources()); + newAction1.setBranchName(createdAction1.getBranchName()); + newAction1.setBaseId(createdAction1.getBaseId()); newAction1.setPluginId(installed_plugin.getId()); newAction1.setPluginType(installed_plugin.getType()); @@ -1218,7 +1219,7 @@ public class LayoutActionServiceTest { @Test @WithUserDetails(value = "api_user") - public void introduceCyclicDependencyAndRemoveLater() { + void introduceCyclicDependencyAndRemoveLater() { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); @@ -1291,7 +1292,7 @@ public class LayoutActionServiceTest { refactorActionNameDTO.setPageId(testPage.getId()); refactorActionNameDTO.setActionId(createdAction.getId()); - Mono layoutDTOMono = refactoringService.refactorEntityName(refactorActionNameDTO, null); + Mono layoutDTOMono = refactoringService.refactorEntityName(refactorActionNameDTO); StepVerifier.create(layoutDTOMono.map( layoutDTO -> layoutDTO.getLayoutOnLoadActionErrors().size())) .expectNext(1) @@ -1300,7 +1301,7 @@ public class LayoutActionServiceTest { // updateAction to see if the error persists actionDTO.setName("finalActionName"); Mono actionDTOMono = - layoutActionService.updateSingleActionWithBranchName(createdAction.getId(), actionDTO, null); + layoutActionService.updateNewActionByBranchedId(createdAction.getId(), actionDTO); StepVerifier.create(actionDTOMono.map( actionDTO1 -> actionDTO1.getErrorReports().size())) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/NewPageServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/NewPageServiceTest.java index 555f1bd6fd..49b5eb7b31 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/NewPageServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/NewPageServiceTest.java @@ -95,7 +95,7 @@ public class NewPageServiceTest { @Test @WithUserDetails("api_user") public void findApplicationPages_WhenApplicationIdAndPageIdNotPresent_ThrowsException() { - StepVerifier.create(newPageService.findApplicationPages(null, null, "master", ApplicationMode.EDIT)) + StepVerifier.create(newPageService.findApplicationPages(null, null, ApplicationMode.EDIT)) .expectError(AppsmithException.class) .verify(); } @@ -114,8 +114,8 @@ public class NewPageServiceTest { pageDTO.setApplicationId(application1.getId()); return applicationPageService.createPage(pageDTO); }) - .flatMap(pageDTO -> newPageService.findApplicationPages( - pageDTO.getApplicationId(), null, null, ApplicationMode.EDIT)); + .flatMap(pageDTO -> + newPageService.findApplicationPages(pageDTO.getApplicationId(), null, ApplicationMode.EDIT)); StepVerifier.create(applicationPagesDTOMono) .assertNext(applicationPagesDTO -> { @@ -150,7 +150,7 @@ public class NewPageServiceTest { .then(pageDTOMono); }) .flatMap(pageDTO -> newPageService.findApplicationPages( - pageDTO.getApplicationId(), null, null, ApplicationMode.PUBLISHED)); + pageDTO.getApplicationId(), null, ApplicationMode.PUBLISHED)); StepVerifier.create(applicationPagesDTOMono) .assertNext(applicationPagesDTO -> { @@ -180,8 +180,7 @@ public class NewPageServiceTest { pageDTO.setApplicationId(application1.getId()); return applicationPageService.createPage(pageDTO); }) - .flatMap(pageDTO -> - newPageService.findApplicationPages(null, pageDTO.getId(), null, ApplicationMode.EDIT)); + .flatMap(pageDTO -> newPageService.findApplicationPages(null, pageDTO.getId(), ApplicationMode.EDIT)); StepVerifier.create(applicationPagesDTOMono) .assertNext(applicationPagesDTO -> { @@ -210,7 +209,7 @@ public class NewPageServiceTest { return applicationService .save(application1) .then(newPageService.findApplicationPages( - null, applicationPage.getId(), null, ApplicationMode.EDIT)); + null, applicationPage.getId(), ApplicationMode.EDIT)); }); StepVerifier.create(applicationPagesDTOMono) @@ -236,7 +235,7 @@ public class NewPageServiceTest { pageDTO.setApplicationId(application1.getId()); return applicationPageService.createPage(pageDTO); }) - .flatMap(pageDTO -> applicationPageService.getPageAndMigrateDslByBranchAndDefaultPageId( + .flatMap(pageDTO -> applicationPageService.getPageAndMigrateDslByBranchAndBasePageId( pageDTO.getId(), null, false, false)); StepVerifier.create(applicationPageDTOMono) @@ -463,7 +462,7 @@ public class NewPageServiceTest { dependencyMap.put("key3", List.of("val1", "val2")); return newPageService .updateDependencyMap(pageDTO.getId(), dependencyMap, null) - .flatMap(page -> applicationPageService.publish(application.getId(), null, false)) + .flatMap(page -> applicationPageService.publish(application.getId(), false)) .then(newPageService.findById(pageDTO.getId(), null)); }); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/PageServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/PageServiceTest.java index f1f610c71a..f6f0bf00cd 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/PageServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/PageServiceTest.java @@ -3,7 +3,6 @@ package com.appsmith.server.services; import com.appsmith.external.models.ActionConfiguration; import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.Datasource; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.JSValue; import com.appsmith.external.models.PluginType; import com.appsmith.external.models.Policy; @@ -27,7 +26,6 @@ import com.appsmith.server.domains.Workspace; import com.appsmith.server.dtos.ActionCollectionDTO; import com.appsmith.server.dtos.ApplicationJson; import com.appsmith.server.dtos.ApplicationPagesDTO; -import com.appsmith.server.dtos.ClonePageMetaDTO; import com.appsmith.server.dtos.LayoutDTO; import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.dtos.PageNameIdDTO; @@ -293,7 +291,7 @@ public class PageServiceTest { .build(); assertThat(page.getPolicies()) - .containsOnly(managePagePolicy, readPagePolicy, deletePagePolicy, createPageActionsPolicy); + .contains(managePagePolicy, readPagePolicy, deletePagePolicy, createPageActionsPolicy); assertThat(page.getLayouts()).isNotEmpty(); assertThat(page.getLayouts().get(0).getDsl()).isEqualTo(parsedJson); @@ -306,9 +304,7 @@ public class PageServiceTest { pageMono.flatMap(pageDTO -> newPageService.getByIdWithoutPermissionCheck(pageDTO.getId())); StepVerifier.create(newPageMono) .assertNext(newPage -> { - assertThat(newPage.getDefaultResources()).isNotNull(); - assertThat(newPage.getDefaultResources().getPageId()).isEqualTo(newPage.getId()); - assertThat(newPage.getDefaultResources().getApplicationId()).isEqualTo(newPage.getApplicationId()); + assertThat(newPage.getBaseId()).isEqualTo(newPage.getId()); }) .verifyComplete(); } @@ -392,7 +388,7 @@ public class PageServiceTest { .build(); assertThat(page.getPolicies()) - .containsOnly(managePagePolicy, readPagePolicy, deletePagePolicy, createPageActionsPolicy); + .contains(managePagePolicy, readPagePolicy, deletePagePolicy, createPageActionsPolicy); }) .verifyComplete(); } @@ -476,7 +472,7 @@ public class PageServiceTest { .build(); assertThat(page.getPolicies()) - .containsOnly(managePagePolicy, readPagePolicy, deletePagePolicy, createPageActionsPolicy); + .contains(managePagePolicy, readPagePolicy, deletePagePolicy, createPageActionsPolicy); }) .verifyComplete(); } @@ -559,7 +555,7 @@ public class PageServiceTest { .build(); assertThat(page.getPolicies()) - .containsOnly(managePagePolicy, readPagePolicy, deletePagePolicy, createPageActionsPolicy); + .contains(managePagePolicy, readPagePolicy, deletePagePolicy, createPageActionsPolicy); }) .verifyComplete(); } @@ -644,13 +640,12 @@ public class PageServiceTest { actionCollectionDTO.setActions(List.of(action1)); actionCollectionDTO.setPluginType(PluginType.JS); - layoutCollectionService.createCollection(actionCollectionDTO, null).block(); + layoutCollectionService.createCollection(actionCollectionDTO).block(); applicationPageService.publish(applicationId, true).block(); - final Mono pageMono = applicationPageService - .clonePage(page.getId(), new ClonePageMetaDTO()) - .cache(); + final Mono pageMono = + applicationPageService.clonePage(page.getId()).cache(); Mono> actionsMono = pageMono.flatMapMany( page1 -> newActionService.findByPageId(page1.getId(), READ_ACTIONS)) @@ -717,7 +712,7 @@ public class PageServiceTest { .build(); assertThat(clonedPage.getPolicies()) - .containsOnly(managePagePolicy, readPagePolicy, deletePagePolicy, createPageActionsPolicy); + .contains(managePagePolicy, readPagePolicy, deletePagePolicy, createPageActionsPolicy); assertThat(clonedPage.getLayouts()).isNotEmpty(); assertThat(clonedPage.getLayouts().get(0).getDsl().get("widgetName")) @@ -853,12 +848,12 @@ public class PageServiceTest { actionCollectionDTO.setActions(List.of(action1)); actionCollectionDTO.setPluginType(PluginType.JS); - layoutCollectionService.createCollection(actionCollectionDTO, null).block(); + layoutCollectionService.createCollection(actionCollectionDTO).block(); final Mono pageMono = applicationPageService - .clonePageByDefaultPageIdAndBranch(page.getId(), branchName) + .clonePage(page.getId()) .flatMap(pageDTO -> - newPageService.findByBranchNameAndDefaultPageId(branchName, pageDTO.getId(), MANAGE_PAGES)) + newPageService.findByBranchNameAndBasePageId(branchName, pageDTO.getId(), MANAGE_PAGES)) .cache(); Mono> actionsMono = pageMono.flatMapMany( @@ -930,7 +925,7 @@ public class PageServiceTest { .build(); assertThat(clonedPage.getPolicies()) - .containsOnly(managePagePolicy, readPagePolicy, deletePagePolicy, createPageActionsPolicy); + .contains(managePagePolicy, readPagePolicy, deletePagePolicy, createPageActionsPolicy); assertThat(unpublishedPage.getLayouts()).isNotEmpty(); assertThat(unpublishedPage.getLayouts().get(0).getDsl().get("widgetName")) @@ -941,13 +936,8 @@ public class PageServiceTest { .isNotEmpty(); assertThat(unpublishedPage.getLayouts().get(0).getPublishedDsl()) .isNullOrEmpty(); - DefaultResources clonedPageDefaultRes = clonedPage.getDefaultResources(); - assertThat(clonedPageDefaultRes).isNotNull(); - assertThat(clonedPageDefaultRes.getPageId()) - .isNotEqualTo(page.getDefaultResources().getPageId()); - assertThat(clonedPageDefaultRes.getApplicationId()) - .isEqualTo(page.getDefaultResources().getApplicationId()); - assertThat(clonedPageDefaultRes.getBranchName()).isEqualTo(branchName); + assertThat(clonedPage.getBaseId()).isNotEqualTo(page.getBaseId()); + assertThat(clonedPage.getBranchName()).isEqualTo(branchName); // Confirm that the page action got copied as well List actions = tuple.getT2(); @@ -958,20 +948,10 @@ public class PageServiceTest { .findFirst() .orElse(null); - DefaultResources clonedActionDefaultRes = actionWithoutCollection.getDefaultResources(); assertThat(actionWithoutCollection.getUnpublishedAction().getName()) .isEqualTo("PageAction"); - assertThat(clonedActionDefaultRes).isNotNull(); - assertThat(clonedActionDefaultRes.getActionId()).isEqualTo(actionWithoutCollection.getId()); - assertThat(clonedActionDefaultRes.getApplicationId()) - .isEqualTo(actionWithoutCollection.getApplicationId()); - assertThat(clonedActionDefaultRes.getPageId()).isNull(); - assertThat(clonedActionDefaultRes.getBranchName()).isEqualTo(branchName); - assertThat(actionWithoutCollection - .getUnpublishedAction() - .getDefaultResources() - .getPageId()) - .isEqualTo(clonedPage.getDefaultResources().getPageId()); + assertThat(actionWithoutCollection.getBaseId()).isEqualTo(actionWithoutCollection.getId()); + assertThat(actionWithoutCollection.getBranchName()).isEqualTo(branchName); // Confirm that executeOnLoad is cloned as well. assertThat(actions.stream() @@ -993,15 +973,7 @@ public class PageServiceTest { assertThat(collection.getUnpublishedCollection()).isNotNull(); assertThat(collection.getUnpublishedCollection().getPageId()) .isEqualTo(clonedPage.getId()); - DefaultResources collectionDefaultResource = collection.getDefaultResources(); - assertThat(collectionDefaultResource.getPageId()).isNull(); - assertThat(collectionDefaultResource.getApplicationId()).isEqualTo(collection.getApplicationId()); - assertThat(collectionDefaultResource.getBranchName()).isEqualTo(branchName); - assertThat(collection - .getUnpublishedCollection() - .getDefaultResources() - .getPageId()) - .isEqualTo(clonedPage.getDefaultResources().getPageId()); + assertThat(collection.getBranchName()).isEqualTo(branchName); // Check if the parent page collections are not altered List parentPageCollections = tuple.getT4(); @@ -1096,7 +1068,7 @@ public class PageServiceTest { pageIds[2] = application.getPages().get(2).getId(); pageIds[3] = application.getPages().get(3).getId(); return applicationPageService.reorderPage( - application.getId(), application.getPages().get(3).getId(), 1, null); + application.getId(), application.getPages().get(3).getId(), 1); }); StepVerifier.create(applicationPageReOrdered) @@ -1147,7 +1119,7 @@ public class PageServiceTest { pageIds[2] = application.getPages().get(2).getId(); pageIds[3] = application.getPages().get(3).getId(); return applicationPageService.reorderPage( - application.getId(), application.getPages().get(0).getId(), 3, null); + application.getId(), application.getPages().get(0).getId(), 3); }); StepVerifier.create(applicationPageReOrdered) @@ -1175,18 +1147,18 @@ public class PageServiceTest { testPage1.setName("Page2"); testPage1.setApplicationId(gitConnectedApplication.getId()); Mono applicationPageReOrdered = applicationPageService - .createPageWithBranchName(testPage1, branchName) + .createPage(testPage1) .flatMap(pageDTO -> { PageDTO testPage = new PageDTO(); testPage.setName("Page3"); testPage.setApplicationId(gitConnectedApplication.getId()); - return applicationPageService.createPageWithBranchName(testPage, branchName); + return applicationPageService.createPage(testPage); }) .flatMap(pageDTO -> { PageDTO testPage = new PageDTO(); testPage.setName("Page4"); testPage.setApplicationId(gitConnectedApplication.getId()); - return applicationPageService.createPageWithBranchName(testPage, branchName); + return applicationPageService.createPage(testPage); }) .flatMap(pageDTO -> applicationService.getById(pageDTO.getApplicationId())) .flatMap(application -> { @@ -1195,7 +1167,7 @@ public class PageServiceTest { pageIds[2] = application.getPages().get(2); pageIds[3] = application.getPages().get(3); return applicationPageService.reorderPage( - application.getId(), application.getPages().get(0).getId(), 3, null); + application.getId(), application.getPages().get(0).getId(), 3); }); StepVerifier.create(applicationPageReOrdered) @@ -1206,9 +1178,6 @@ public class PageServiceTest { assertThat(pages.get(0).getId()).isEqualTo(pageIds[1].getId()); assertThat(pages.get(1).getId()).isEqualTo(pageIds[2].getId()); assertThat(pages.get(2).getId()).isEqualTo(pageIds[3].getId()); - - // Check if the defaultIds are intact - assertThat(pages.get(3).getDefaultPageId()).isEqualTo(pageIds[0].getDefaultPageId()); }) .verifyComplete(); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ThemeServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ThemeServiceTest.java index 5ef0dcd0de..0e7e7ce8bb 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ThemeServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ThemeServiceTest.java @@ -196,13 +196,11 @@ public class ThemeServiceTest { Application savedApplication = createApplication(); // Apply Sharp theme to the application - Mono applySharpTheme = - themeService.changeCurrentTheme(sharpTheme.getId(), savedApplication.getId(), null); + Mono applySharpTheme = themeService.changeCurrentTheme(sharpTheme.getId(), savedApplication.getId()); // Publish app Mono publishApp = applicationPageService.publish(savedApplication.getId(), TRUE); // apply classic theme to the application - Mono applyClassicTheme = - themeService.changeCurrentTheme(classicTheme.getId(), savedApplication.getId(), null); + Mono applyClassicTheme = themeService.changeCurrentTheme(classicTheme.getId(), savedApplication.getId()); Mono> applicationThemesMono = applySharpTheme .then(publishApp) @@ -230,13 +228,11 @@ public class ThemeServiceTest { Theme sharpTheme = themeService.getSystemTheme("Sharp").block(); Theme classicTheme = themeService.getSystemTheme("Classic").block(); // Apply Sharp theme to the application - Mono applySharpTheme = - themeService.changeCurrentTheme(sharpTheme.getId(), savedApplication.getId(), null); + Mono applySharpTheme = themeService.changeCurrentTheme(sharpTheme.getId(), savedApplication.getId()); // Publish app Mono publishApp = applicationPageService.publish(savedApplication.getId(), TRUE); // apply classic theme to the application - Mono applyClassicTheme = - themeService.changeCurrentTheme(classicTheme.getId(), savedApplication.getId(), null); + Mono applyClassicTheme = themeService.changeCurrentTheme(classicTheme.getId(), savedApplication.getId()); // Set the themes in edit and published mode before the user is removed from the workspace applySharpTheme.then(publishApp).then(applyClassicTheme).block(); @@ -285,11 +281,9 @@ public class ThemeServiceTest { applicationPageService.publish(savedApplication.getId(), TRUE).block(); // apply classic theme to the application - Mono applyClassicTheme = - themeService.changeCurrentTheme(classicTheme.getId(), savedApplication.getId(), null); + Mono applyClassicTheme = themeService.changeCurrentTheme(classicTheme.getId(), savedApplication.getId()); // apply rounded theme to the application - Mono applyRoundedTheme = - themeService.changeCurrentTheme(roundedTheme.getId(), savedApplication.getId(), null); + Mono applyRoundedTheme = themeService.changeCurrentTheme(roundedTheme.getId(), savedApplication.getId()); Mono applicationPostThemeUpdatesMono = applyClassicTheme .then(applyRoundedTheme) @@ -326,8 +320,7 @@ public class ThemeServiceTest { // Publish app Mono publishApp = applicationPageService.publish(savedApplication.getId(), TRUE); // apply classic theme to the application - Mono applyClassicTheme = - themeService.changeCurrentTheme(classicTheme.getId(), savedApplication.getId(), null); + Mono applyClassicTheme = themeService.changeCurrentTheme(classicTheme.getId(), savedApplication.getId()); // Set the themes in edit and published mode before the user is removed from the workspace applyClassicTheme.then(publishApp).block(); @@ -336,7 +329,7 @@ public class ThemeServiceTest { // Change the app theme as api_user (after api_user has been removed from the workspace) Mono changeCurrentThemeMono = - themeService.changeCurrentTheme(savedApplication.getEditModeThemeId(), savedApplication.getId(), null); + themeService.changeCurrentTheme(savedApplication.getEditModeThemeId(), savedApplication.getId()); StepVerifier.create(changeCurrentThemeMono) .expectError(AppsmithException.class) @@ -354,7 +347,7 @@ public class ThemeServiceTest { Application savedApplication = createApplication(); Mono applicationThemeMono = defaultThemeIdMono.flatMap(themeId -> themeService - .changeCurrentTheme(themeId, savedApplication.getId(), null) + .changeCurrentTheme(themeId, savedApplication.getId()) .then(themeService.getApplicationTheme(savedApplication.getId(), ApplicationMode.EDIT, null))); StepVerifier.create(applicationThemeMono) @@ -377,7 +370,7 @@ public class ThemeServiceTest { Mono createAndApplyCustomThemeMono = themeService .persistCurrentTheme(savedApplication.getId(), null, customTheme) // Apply the newly created custom theme to the application - .flatMap(theme -> themeService.changeCurrentTheme(theme.getId(), savedApplication.getId(), null)) + .flatMap(theme -> themeService.changeCurrentTheme(theme.getId(), savedApplication.getId())) .flatMap(theme -> { // Mark this custom theme as not an application theme // Don't know why a theme will not be associated with an application if it is not a system theme @@ -387,7 +380,7 @@ public class ThemeServiceTest { Mono applyDefaultThemeMono = themeService .getDefaultThemeId() - .flatMap(themeId -> themeService.changeCurrentTheme(themeId, savedApplication.getId(), null)); + .flatMap(themeId -> themeService.changeCurrentTheme(themeId, savedApplication.getId())); Mono newApplicationThemeMono = createAndApplyCustomThemeMono .then(applyDefaultThemeMono) @@ -507,7 +500,7 @@ public class ThemeServiceTest { Mono classicThemeMono = themeService.getSystemTheme("classic").cache(); Mono> appAndThemeTuple = classicThemeMono - .flatMap(theme -> themeService.changeCurrentTheme(theme.getId(), savedApplication.getId(), null)) + .flatMap(theme -> themeService.changeCurrentTheme(theme.getId(), savedApplication.getId())) .then(themeService.publishTheme(savedApplication.getId())) .then(applicationRepository.findById(savedApplication.getId())) .zipWith(classicThemeMono); @@ -534,7 +527,7 @@ public class ThemeServiceTest { customTheme.setName("my-custom-theme"); Mono createAndApplyCustomThemeMono = themeService .persistCurrentTheme(application.getId(), null, customTheme) - .flatMap(theme -> themeService.changeCurrentTheme(theme.getId(), application.getId(), null)); + .flatMap(theme -> themeService.changeCurrentTheme(theme.getId(), application.getId())); // publish the theme Mono publishThemeMono = themeService.publishTheme(application.getId()); @@ -570,7 +563,7 @@ public class ThemeServiceTest { updatesToSystemTheme.setDisplayName("My updates to existing system theme"); Mono> appThemesMono = themeService - .updateTheme(application.getId(), null, updatesToSystemTheme) + .updateTheme(application.getId(), updatesToSystemTheme) .then(Mono.zip( themeService.getApplicationTheme(application.getId(), ApplicationMode.EDIT, null), themeService.getApplicationTheme(application.getId(), ApplicationMode.PUBLISHED, null))); @@ -607,14 +600,14 @@ public class ThemeServiceTest { customTheme.setDisplayName("My custom theme"); themeService .persistCurrentTheme(application.getId(), null, customTheme) - .flatMap(theme -> themeService.changeCurrentTheme(theme.getId(), applicationId, null)) + .flatMap(theme -> themeService.changeCurrentTheme(theme.getId(), applicationId)) .block(); application = applicationRepository.findById(applicationId).block(); // Apply theme customization. Theme themeCustomization = new Theme(); themeCustomization.setDisplayName("Updated name"); - Mono updateThemeMono = themeService.updateTheme(application.getId(), null, themeCustomization); + Mono updateThemeMono = themeService.updateTheme(application.getId(), themeCustomization); Mono> appThemesMono = updateThemeMono.then(Mono.zip( themeService.getApplicationTheme(application.getId(), ApplicationMode.EDIT, null), @@ -686,7 +679,7 @@ public class ThemeServiceTest { customTheme.setName("my-custom-theme"); Mono createAndApplyCustomThemeMono = themeService .persistCurrentTheme(savedApplication.getId(), null, customTheme) - .flatMap(theme -> themeService.changeCurrentTheme(theme.getId(), savedApplication.getId(), null)); + .flatMap(theme -> themeService.changeCurrentTheme(theme.getId(), savedApplication.getId())); // Make the app public. Mono makeAppPublicMono = applicationPageService.publish(savedApplication.getId(), TRUE); @@ -812,7 +805,7 @@ public class ThemeServiceTest { Theme themeCustomization = new Theme(); themeCustomization.setDisplayName("Updated name"); Mono deleteThemeMono = themeService - .updateTheme(savedApplication.getId(), null, themeCustomization) + .updateTheme(savedApplication.getId(), themeCustomization) .flatMap(customizedTheme -> themeService.archiveById(customizedTheme.getId())); StepVerifier.create(deleteThemeMono) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserWorkspaceServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserWorkspaceServiceTest.java index 375e1e40e2..6ee7c1659e 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserWorkspaceServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserWorkspaceServiceTest.java @@ -12,6 +12,7 @@ import com.appsmith.server.dtos.RecentlyUsedEntityDTO; import com.appsmith.server.dtos.UpdatePermissionGroupDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; +import com.appsmith.server.helpers.UserUtils; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.repositories.PermissionGroupRepository; import com.appsmith.server.repositories.UserRepository; @@ -60,6 +61,9 @@ public class UserWorkspaceServiceTest { @Autowired UserService userService; + @Autowired + UserUtils userUtils; + @Autowired private UserWorkspaceService userWorkspaceService; @@ -127,7 +131,7 @@ public class UserWorkspaceServiceTest { // Add application and workspace to the recently used list by accessing the application pages. newPageService - .findApplicationPagesByApplicationIdViewModeAndBranch(savedApplication.getId(), null, false, true) + .findApplicationPagesByBranchedApplicationIdAndViewMode(savedApplication.getId(), false, true) .block(); Set uniqueUsersInWorkspaceBefore = userWorkspaceService diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ActionServiceCE_Test.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ActionServiceCE_Test.java index b40319fcda..86d94f1b5f 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ActionServiceCE_Test.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ActionServiceCE_Test.java @@ -1,7 +1,6 @@ package com.appsmith.server.services.ce; import com.appsmith.external.dtos.DslExecutableDTO; -import com.appsmith.external.helpers.AppsmithBeanUtils; import com.appsmith.external.helpers.AppsmithEventContext; import com.appsmith.external.helpers.AppsmithEventContextType; import com.appsmith.external.models.ActionConfiguration; @@ -9,7 +8,6 @@ import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.Datasource; import com.appsmith.external.models.DatasourceConfiguration; import com.appsmith.external.models.DatasourceStorageDTO; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.PaginationType; import com.appsmith.external.models.Policy; import com.appsmith.external.models.Property; @@ -309,16 +307,14 @@ public class ActionServiceCE_Test { action.setDatasource(datasource); Mono actionMono = layoutActionService - .createSingleActionWithBranch(action, branchName) - .flatMap(createdAction -> newActionService.findByBranchNameAndDefaultActionId( + .createSingleAction(action) + .flatMap(createdAction -> newActionService.findByBranchNameAndBaseActionId( branchName, createdAction.getId(), false, READ_ACTIONS)); StepVerifier.create(actionMono) .assertNext(newAction -> { assertThat(newAction.getUnpublishedAction().getPageId()).isEqualTo(gitConnectedPage.getId()); - assertThat(newAction.getDefaultResources().getActionId()).isEqualTo(newAction.getId()); - assertThat(newAction.getDefaultResources().getApplicationId()) - .isEqualTo(gitConnectedApp.getId()); + assertThat(newAction.getBaseId()).isEqualTo(newAction.getId()); }) .verifyComplete(); } @@ -419,19 +415,14 @@ public class ActionServiceCE_Test { action.setActionConfiguration(actionConfiguration); action.setDatasource(datasource); - Mono actionMono = layoutActionService.createSingleActionWithBranch(action, branchName); + Mono actionMono = layoutActionService.createSingleAction(action); StepVerifier.create(Mono.zip(actionMono, defaultPermissionGroupsMono)) .assertNext(tuple -> { ActionDTO createdAction = tuple.getT1(); assertThat(createdAction.getExecuteOnLoad()).isFalse(); - assertThat(createdAction.getDefaultResources()).isNotNull(); assertThat(createdAction.getUserPermissions()).isNotEmpty(); - assertThat(createdAction.getDefaultResources().getActionId()) - .isEqualTo(createdAction.getId()); - assertThat(createdAction.getDefaultResources().getPageId()).isEqualTo(gitConnectedPage.getId()); - assertThat(createdAction.getDefaultResources().getApplicationId()) - .isEqualTo(gitConnectedPage.getApplicationId()); + assertThat(createdAction.getBaseId()).isEqualTo(createdAction.getId()); List permissionGroups = tuple.getT2(); PermissionGroup adminPermissionGroup = permissionGroups.stream() @@ -523,9 +514,7 @@ public class ActionServiceCE_Test { PageDTO newPage = new PageDTO(); newPage.setName("Destination Page"); newPage.setApplicationId(gitConnectedApp.getId()); - PageDTO destinationPage = applicationPageService - .createPageWithBranchName(newPage, branchName) - .block(); + PageDTO destinationPage = applicationPageService.createPage(newPage).block(); ActionDTO action = new ActionDTO(); action.setName("validAction"); @@ -535,17 +524,14 @@ public class ActionServiceCE_Test { action.setActionConfiguration(actionConfiguration); action.setDatasource(datasource); - Mono createActionMono = layoutActionService - .createSingleActionWithBranch(action, branchName) - .cache(); - DefaultResources sourceActionDefaultRes = new DefaultResources(); + Mono createActionMono = + layoutActionService.createSingleAction(action).cache(); Mono movedActionMono = createActionMono.flatMap(savedAction -> { ActionMoveDTO actionMoveDTO = new ActionMoveDTO(); actionMoveDTO.setAction(savedAction); actionMoveDTO.setDestinationPageId(destinationPage.getId()); - AppsmithBeanUtils.copyNestedNonNullProperties(savedAction.getDefaultResources(), sourceActionDefaultRes); - return layoutActionService.moveAction(actionMoveDTO, branchName); + return layoutActionService.moveAction(actionMoveDTO); }); StepVerifier.create(Mono.zip(createActionMono, movedActionMono)) @@ -557,13 +543,6 @@ public class ActionServiceCE_Test { assertThat(movedAction.getName()).isEqualTo(originalAction.getName()); assertThat(movedAction.getPolicies()).containsAll(originalAction.getPolicies()); assertThat(movedAction.getPageId()).isEqualTo(destinationPage.getId()); - - // Check if the defaultIds are updated as per destination page default Id - assertThat(movedAction.getDefaultResources()).isNotNull(); - assertThat(movedAction.getDefaultResources().getPageId()) - .isEqualTo(destinationPage.getDefaultResources().getPageId()); - assertThat(sourceActionDefaultRes.getPageId()) - .isEqualTo(gitConnectedPage.getDefaultResources().getPageId()); }) .verifyComplete(); } @@ -655,7 +634,7 @@ public class ActionServiceCE_Test { ActionConfiguration actionConfiguration = new ActionConfiguration(); actionConfiguration.setHttpMethod(HttpMethod.GET); action.setActionConfiguration(actionConfiguration); - Mono actionMono = layoutActionService.createSingleActionWithBranch(action, branchName); + Mono actionMono = layoutActionService.createSingleAction(action); StepVerifier.create(actionMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -682,25 +661,6 @@ public class ActionServiceCE_Test { .verify(); } - @Test - @WithUserDetails(value = "api_user") - public void createAction_forGitConnectedAppWithInvalidBranchName_throwException() { - ActionDTO action = new ActionDTO(); - action.setName("randomActionName"); - action.setPageId(gitConnectedPage.getId()); - ActionConfiguration actionConfiguration = new ActionConfiguration(); - actionConfiguration.setHttpMethod(HttpMethod.GET); - action.setActionConfiguration(actionConfiguration); - Mono actionMono = layoutActionService.createSingleActionWithBranch(action, "randomTestBranch"); - StepVerifier.create(actionMono) - .expectErrorMatches(throwable -> throwable instanceof AppsmithException - && throwable - .getMessage() - .equals(AppsmithError.NO_RESOURCE_FOUND.getMessage( - FieldName.PAGE, action.getPageId() + ", randomTestBranch"))) - .verify(); - } - @Test @WithUserDetails(value = "api_user") public void checkActionInViewMode() { @@ -1072,7 +1032,8 @@ public class ActionServiceCE_Test { applicationAccessDTO.setPublicAccess(true); Mono publicAppMono = applicationService - .changeViewAccess(createdApplication.getId(), applicationAccessDTO) + .changeViewAccessForSingleBranchByBranchedApplicationId( + createdApplication.getId(), applicationAccessDTO) .cache(); Datasource datasource = new Datasource(); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationServiceCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationServiceCETest.java index b919e99ec1..001452bb05 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationServiceCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationServiceCETest.java @@ -656,8 +656,8 @@ public class ApplicationServiceCETest { @Test @WithUserDetails(value = "api_user") public void getApplicationByDefaultIdAndBranchName_emptyBranchName_success() { - Mono applicationMono = applicationService.findByBranchNameAndDefaultApplicationId( - "", gitConnectedApp.getId(), READ_APPLICATIONS); + Mono applicationMono = + applicationService.findByBranchNameAndBaseApplicationId("", gitConnectedApp.getId(), READ_APPLICATIONS); StepVerifier.create(applicationMono) .assertNext(application -> { assertThat(application.getId()).isEqualTo(gitConnectedApp.getId()); @@ -668,7 +668,7 @@ public class ApplicationServiceCETest { @Test @WithUserDetails(value = "api_user") public void getApplicationByDefaultIdAndBranchName_invalidBranchName_throwException() { - Mono applicationMono = applicationService.findByBranchNameAndDefaultApplicationId( + Mono applicationMono = applicationService.findByBranchNameAndBaseApplicationId( "randomBranch", gitConnectedApp.getId(), READ_APPLICATIONS); StepVerifier.create(applicationMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -682,7 +682,7 @@ public class ApplicationServiceCETest { @Test @WithUserDetails(value = "api_user") public void getApplicationByDefaultIdAndBranchName_validBranchName_success() { - Mono applicationMono = applicationService.findByBranchNameAndDefaultApplicationId( + Mono applicationMono = applicationService.findByBranchNameAndBaseApplicationId( "testBranch", gitConnectedApp.getId(), READ_APPLICATIONS); StepVerifier.create(applicationMono) .assertNext(application -> { @@ -695,9 +695,7 @@ public class ApplicationServiceCETest { @Test @WithUserDetails(value = "api_user") public void getApplicationsByBranchName_validBranchName_success() { - Mono getApplication = applicationService.findByIdAndBranchName( - gitConnectedApp.getId(), - gitConnectedApp.getGitApplicationMetadata().getBranchName()); + Mono getApplication = applicationService.findByBranchedId(gitConnectedApp.getId(), null); StepVerifier.create(getApplication) .assertNext(t -> { assertThat(t).isNotNull(); @@ -826,7 +824,7 @@ public class ApplicationServiceCETest { .update(gitConnectedApp.getId(), gitConnectedApp) .flatMap(t -> { GitArtifactMetadata gitData = t.getGitApplicationMetadata(); - return applicationService.findByBranchNameAndDefaultApplicationId( + return applicationService.findByBranchNameAndBaseApplicationId( gitData.getBranchName(), gitData.getDefaultApplicationId(), READ_APPLICATIONS); }); @@ -908,7 +906,8 @@ public class ApplicationServiceCETest { applicationAccessDTO.setPublicAccess(true); Mono publicAppMono = applicationService - .changeViewAccess(createdApplication.getId(), applicationAccessDTO) + .changeViewAccessForSingleBranchByBranchedApplicationId( + createdApplication.getId(), applicationAccessDTO) .cache(); Mono pageMono = publicAppMono.flatMap(app -> { @@ -1004,11 +1003,13 @@ public class ApplicationServiceCETest { Mono privateAppMono = createApplication .flatMap(application1 -> { applicationAccessDTO.setPublicAccess(true); - return applicationService.changeViewAccess(application1.getId(), applicationAccessDTO); + return applicationService.changeViewAccessForSingleBranchByBranchedApplicationId( + application1.getId(), applicationAccessDTO); }) .flatMap(application1 -> { applicationAccessDTO.setPublicAccess(false); - return applicationService.changeViewAccess(application1.getId(), applicationAccessDTO); + return applicationService.changeViewAccessForSingleBranchByBranchedApplicationId( + application1.getId(), applicationAccessDTO); }) .cache(); @@ -1100,7 +1101,7 @@ public class ApplicationServiceCETest { applicationPageService.createApplication(testApplication).block(); Mono publicAppMono = applicationService - .changeViewAccess(gitConnectedApp.getId(), "testBranch", applicationAccessDTO) + .changeViewAccessForAllBranchesByBranchedApplicationId(gitConnectedApp.getId(), applicationAccessDTO) .cache(); Mono pageMono = publicAppMono.flatMap(app -> { @@ -1251,12 +1252,13 @@ public class ApplicationServiceCETest { Mono> privateAppAndPageTupleMono = // First make the git connected app public applicationService - .changeViewAccess(gitConnectedApp.getId(), "testBranch", applicationAccessDTO) + .changeViewAccessForAllBranchesByBranchedApplicationId( + gitConnectedApp.getId(), applicationAccessDTO) .flatMap(application1 -> { applicationAccessDTO.setPublicAccess(false); // Then make the test branch private - return applicationService.changeViewAccess( - application1.getId(), "testBranch", applicationAccessDTO); + return applicationService.changeViewAccessForAllBranchesByBranchedApplicationId( + application1.getId(), applicationAccessDTO); }) .flatMap(app -> { String pageId = app.getPages().get(0).getId(); @@ -1365,12 +1367,12 @@ public class ApplicationServiceCETest { actionCollectionDTO.setPluginId(installedJsPlugin.getId()); actionCollectionDTO.setPluginType(PluginType.JS); - ActionCollectionDTO savedActionCollection = layoutCollectionService - .createCollection(actionCollectionDTO, null) - .block(); + ActionCollectionDTO savedActionCollection = + layoutCollectionService.createCollection(actionCollectionDTO).block(); Mono publicAppMono = applicationService - .changeViewAccess(createdApplication.getId(), applicationAccessDTO) + .changeViewAccessForSingleBranchByBranchedApplicationId( + createdApplication.getId(), applicationAccessDTO) .cache(); Mono publicPermissionGroupMono = permissionGroupService.getPublicPermissionGroup(); @@ -1509,7 +1511,8 @@ public class ApplicationServiceCETest { ApplicationAccessDTO applicationAccessDTO = new ApplicationAccessDTO(); applicationAccessDTO.setPublicAccess(true); applicationService - .changeViewAccess(createdApplication.getId(), applicationAccessDTO) + .changeViewAccessForSingleBranchByBranchedApplicationId( + createdApplication.getId(), applicationAccessDTO) .block(); Datasource datasourceAfterPublicShare = @@ -1545,13 +1548,15 @@ public class ApplicationServiceCETest { ApplicationAccessDTO applicationAccessDTO2 = new ApplicationAccessDTO(); applicationAccessDTO2.setPublicAccess(true); applicationService - .changeViewAccess(createdApplication2.getId(), applicationAccessDTO2) + .changeViewAccessForSingleBranchByBranchedApplicationId( + createdApplication2.getId(), applicationAccessDTO2) .block(); // Now revoke public access from first app applicationAccessDTO.setPublicAccess(false); applicationService - .changeViewAccess(createdApplication.getId(), applicationAccessDTO) + .changeViewAccessForSingleBranchByBranchedApplicationId( + createdApplication.getId(), applicationAccessDTO) .block(); // Check that datasource still has execute access @@ -1569,7 +1574,8 @@ public class ApplicationServiceCETest { // Now revoke public access from second app applicationAccessDTO2.setPublicAccess(false); applicationService - .changeViewAccess(createdApplication2.getId(), applicationAccessDTO2) + .changeViewAccessForSingleBranchByBranchedApplicationId( + createdApplication2.getId(), applicationAccessDTO2) .block(); // Check that datasource now does NOT have execute access @@ -1590,9 +1596,8 @@ public class ApplicationServiceCETest { public void cloneApplication_applicationWithGitMetadata_success() { final String branchName = gitConnectedApp.getGitApplicationMetadata().getBranchName(); - Mono clonedApplicationMono = applicationPageService - .cloneApplication(gitConnectedApp.getId(), branchName) - .cache(); + Mono clonedApplicationMono = + applicationPageService.cloneApplication(gitConnectedApp.getId()).cache(); Mono workspaceResponse = workspaceService.findById(workspaceId, READ_WORKSPACES); @@ -1685,9 +1690,6 @@ public class ApplicationServiceCETest { Set srcPageIdsFromDb = srcPageList.stream().map(page -> page.getId()).collect(Collectors.toSet()); - Set defaultSrcPageIdsFromDb = srcPageList.stream() - .map(page -> page.getDefaultResources().getPageId()) - .collect(Collectors.toSet()); assertThat(Collections.disjoint(srcPageIdsFromDb, clonedPageIdsFromDb)) .isTrue(); @@ -1707,7 +1709,7 @@ public class ApplicationServiceCETest { .collectList(); Mono> srcNewPageListMono = Flux.fromIterable(gitConnectedApp.getPages()) - .flatMap(applicationPage -> newPageService.findByBranchNameAndDefaultPageId( + .flatMap(applicationPage -> newPageService.findByBranchNameAndBasePageId( branchName, applicationPage.getDefaultPageId(), READ_PAGES)) .collectList(); @@ -1720,21 +1722,16 @@ public class ApplicationServiceCETest { List clonedDefaultPageIdList = new ArrayList<>(); clonedNewPageList.forEach(newPage -> { clonedPageIdList.add(newPage.getId()); - clonedDefaultPageIdList.add( - newPage.getDefaultResources().getPageId()); - assertThat(newPage.getDefaultResources().getApplicationId()) - .isEqualTo(newPage.getApplicationId()); - assertThat(newPage.getDefaultResources().getPageId()).isEqualTo(newPage.getId()); + clonedDefaultPageIdList.add(newPage.getBaseId()); + assertThat(newPage.getBaseId()).isEqualTo(newPage.getId()); }); List srcPageIdList = new ArrayList<>(); List srcDefaultPageIdList = new ArrayList<>(); srcNewPageList.forEach(newPage -> { srcPageIdList.add(newPage.getId()); - srcDefaultPageIdList.add(newPage.getDefaultResources().getPageId()); - assertThat(newPage.getDefaultResources().getApplicationId()) - .isEqualTo(newPage.getApplicationId()); - assertThat(newPage.getDefaultResources().getPageId()).isEqualTo(newPage.getId()); + srcDefaultPageIdList.add(newPage.getBaseId()); + assertThat(newPage.getBaseId()).isEqualTo(newPage.getId()); }); assertThat(clonedPageIdList).doesNotContainAnyElementsOf(srcPageIdList); @@ -1792,9 +1789,8 @@ public class ApplicationServiceCETest { ActionDTO savedAction = layoutActionService.createSingleAction(action, Boolean.FALSE).block(); - Mono clonedApplicationMono = applicationPageService - .cloneApplication(gitConnectedApp.getId(), branchName) - .cache(); + Mono clonedApplicationMono = + applicationPageService.cloneApplication(gitConnectedApp.getId()).cache(); Mono> clonedActionListMono = clonedApplicationMono .flatMapMany(application -> newActionService.findAllByApplicationIdAndViewMode( @@ -1871,13 +1867,8 @@ public class ApplicationServiceCETest { Set clonedPageIdsInActionFromDb = clonedActionList.stream() .map(action1 -> action1.getUnpublishedAction().getPageId()) .collect(Collectors.toSet()); - Set defaultPageIdsInClonedActionFromDb = clonedActionList.stream() - .map(action1 -> action1.getUnpublishedAction() - .getDefaultResources() - .getPageId()) - .collect(Collectors.toSet()); Set defaultClonedActionIdsFromDb = clonedActionList.stream() - .map(newAction -> newAction.getDefaultResources().getActionId()) + .map(newAction -> newAction.getBaseId()) .collect(Collectors.toSet()); Set srcActionIdsFromDb = srcActionList.stream() @@ -1886,13 +1877,8 @@ public class ApplicationServiceCETest { Set srcPageIdsInActionFromDb = srcActionList.stream() .map(action1 -> action1.getUnpublishedAction().getPageId()) .collect(Collectors.toSet()); - Set defaultPageIdsInSrcActionFromDb = srcActionList.stream() - .map(action1 -> action1.getUnpublishedAction() - .getDefaultResources() - .getPageId()) - .collect(Collectors.toSet()); Set defaultSrcActionIdsFromDb = srcActionList.stream() - .map(newAction -> newAction.getDefaultResources().getActionId()) + .map(newAction -> newAction.getBaseId()) .collect(Collectors.toSet()); assertThat(Collections.disjoint(clonedActionIdsFromDb, srcActionIdsFromDb)) @@ -1902,10 +1888,6 @@ public class ApplicationServiceCETest { .isTrue(); assertThat(Collections.disjoint(clonedPageIdsInActionFromDb, srcPageIdsInActionFromDb)) .isTrue(); - assertThat(Collections.disjoint( - defaultPageIdsInClonedActionFromDb, defaultPageIdsInSrcActionFromDb)) - .isTrue(); - assertThat(defaultPageIdsInClonedActionFromDb).isNotEmpty(); assertThat(clonedActionList).isNotEmpty(); assertThat(defaultClonedActionIdsFromDb).isNotEmpty(); @@ -1913,11 +1895,6 @@ public class ApplicationServiceCETest { assertThat(newAction.getPolicies()) .containsAll(Set.of(readActionPolicy, executeActionPolicy, manageActionPolicy)); assertThat(newAction.getApplicationId()).isEqualTo(clonedApplication.getId()); - assertThat(newAction.getUnpublishedAction().getPageId()) - .isEqualTo(newAction - .getUnpublishedAction() - .getDefaultResources() - .getPageId()); } }) .verifyComplete(); @@ -2024,7 +2001,7 @@ public class ApplicationServiceCETest { actionCollectionDTO.setPluginType(PluginType.JS); return Mono.zip( - layoutCollectionService.createCollection(actionCollectionDTO, null), + layoutCollectionService.createCollection(actionCollectionDTO), layoutActionService.createSingleAction(action, Boolean.FALSE), updateLayoutService.updateLayout( testPage.getId(), testPage.getApplicationId(), layout.getId(), layout), @@ -2046,7 +2023,7 @@ public class ApplicationServiceCETest { .collect(Collectors.toList()); originalResourceIds.put("actionIds", actionIds); return applicationPageService.cloneApplication( - tuple.getT4().getId(), null); + tuple.getT4().getId()); }); }) .cache(); @@ -2133,57 +2110,17 @@ public class ApplicationServiceCETest { assertThat(pageList).isNotEmpty(); pageList.forEach(newPage -> { - assertThat(newPage.getDefaultResources()).isNotNull(); - assertThat(newPage.getDefaultResources().getPageId()).isEqualTo(newPage.getId()); - assertThat(newPage.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); - - newPage.getUnpublishedPage().getLayouts().forEach(layout -> { - assertThat(layout.getLayoutOnLoadActions()).hasSize(1); - layout.getLayoutOnLoadActions().forEach(dslActionDTOS -> { - assertThat(dslActionDTOS).hasSize(2); - dslActionDTOS.forEach(actionDTO -> { - assertThat(actionDTO.getId()).isEqualTo(actionDTO.getDefaultActionId()); - if (StringUtils.hasLength(actionDTO.getCollectionId())) { - assertThat(actionDTO.getDefaultCollectionId()) - .isEqualTo(actionDTO.getCollectionId()); - } - }); - }); - }); + assertThat(newPage.getBaseId()).isEqualTo(newPage.getId()); }); assertThat(actionList).hasSize(3); actionList.forEach(newAction -> { - assertThat(newAction.getDefaultResources()).isNotNull(); - assertThat(newAction.getDefaultResources().getActionId()) - .isEqualTo(newAction.getId()); - assertThat(newAction.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); - - ActionDTO action = newAction.getUnpublishedAction(); - assertThat(action.getDefaultResources()).isNotNull(); - assertThat(action.getDefaultResources().getPageId()) - .isEqualTo(application.getPages().get(0).getId()); - if (StringUtils.hasLength(action.getDefaultResources().getCollectionId())) { - assertThat(action.getDefaultResources().getCollectionId()) - .isEqualTo(action.getCollectionId()); - } + assertThat(newAction.getBaseId()).isEqualTo(newAction.getId()); }); assertThat(actionCollectionList).hasSize(1); actionCollectionList.forEach(actionCollection -> { - assertThat(actionCollection.getDefaultResources()).isNotNull(); - assertThat(actionCollection.getDefaultResources().getCollectionId()) - .isEqualTo(actionCollection.getId()); - assertThat(actionCollection.getDefaultResources().getApplicationId()) - .isEqualTo(application.getId()); - - ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - - assertThat(unpublishedCollection.getDefaultResources()).isNotNull(); - assertThat(unpublishedCollection.getDefaultResources().getPageId()) - .isEqualTo(application.getPages().get(0).getId()); + assertThat(actionCollection.getBaseId()).isEqualTo(actionCollection.getId()); }); }) .verifyComplete(); @@ -2375,7 +2312,7 @@ public class ApplicationServiceCETest { layout.setDsl(parentDsl); return Mono.zip( - layoutCollectionService.createCollection(actionCollectionDTO, null), + layoutCollectionService.createCollection(actionCollectionDTO), layoutActionService.createSingleAction(action, Boolean.FALSE), Mono.just(application), Mono.just(testPage), @@ -2416,7 +2353,7 @@ public class ApplicationServiceCETest { actionList.stream().map(BaseDomain::getId).collect(Collectors.toList()); originalResourceIds.put("actionIds", actionIds); return applicationPageService.cloneApplication( - tuple4.getT4().getId(), null); + tuple4.getT4().getId()); }) .block(); @@ -2503,57 +2440,17 @@ public class ApplicationServiceCETest { assertThat(pageList).isNotEmpty(); pageList.forEach(newPage -> { - assertThat(newPage.getDefaultResources()).isNotNull(); - assertThat(newPage.getDefaultResources().getPageId()).isEqualTo(newPage.getId()); - assertThat(newPage.getDefaultResources().getApplicationId()) - .isEqualTo(application1.getId()); - - newPage.getUnpublishedPage().getLayouts().forEach(layout -> { - assertThat(layout.getLayoutOnLoadActions()).hasSize(1); - layout.getLayoutOnLoadActions().forEach(dslActionDTOS -> { - assertThat(dslActionDTOS).hasSize(2); - dslActionDTOS.forEach(actionDTO -> { - assertThat(actionDTO.getId()).isEqualTo(actionDTO.getDefaultActionId()); - if (StringUtils.hasLength(actionDTO.getCollectionId())) { - assertThat(actionDTO.getDefaultCollectionId()) - .isEqualTo(actionDTO.getCollectionId()); - } - }); - }); - }); + assertThat(newPage.getBaseId()).isEqualTo(newPage.getId()); }); assertThat(actionList).hasSize(2); actionList.forEach(newAction -> { - assertThat(newAction.getDefaultResources()).isNotNull(); - assertThat(newAction.getDefaultResources().getActionId()) - .isEqualTo(newAction.getId()); - assertThat(newAction.getDefaultResources().getApplicationId()) - .isEqualTo(application1.getId()); - - ActionDTO action = newAction.getUnpublishedAction(); - assertThat(action.getDefaultResources()).isNotNull(); - assertThat(action.getDefaultResources().getPageId()) - .isEqualTo(application1.getPages().get(0).getId()); - if (StringUtils.hasLength(action.getDefaultResources().getCollectionId())) { - assertThat(action.getDefaultResources().getCollectionId()) - .isEqualTo(action.getCollectionId()); - } + assertThat(newAction.getBaseId()).isEqualTo(newAction.getId()); }); assertThat(actionCollectionList).hasSize(1); actionCollectionList.forEach(actionCollection -> { - assertThat(actionCollection.getDefaultResources()).isNotNull(); - assertThat(actionCollection.getDefaultResources().getCollectionId()) - .isEqualTo(actionCollection.getId()); - assertThat(actionCollection.getDefaultResources().getApplicationId()) - .isEqualTo(application1.getId()); - - ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection(); - - assertThat(unpublishedCollection.getDefaultResources()).isNotNull(); - assertThat(unpublishedCollection.getDefaultResources().getPageId()) - .isEqualTo(application1.getPages().get(0).getId()); + assertThat(actionCollection.getBaseId()).isEqualTo(actionCollection.getId()); }); }) .verifyComplete(); @@ -2610,7 +2507,7 @@ public class ApplicationServiceCETest { return applicationPageService.createPage(pageDTO).then(Mono.just(application1)); }) .flatMap(application1 -> applicationPageService.cloneApplication( - application1.getGitApplicationMetadata().getDefaultApplicationId(), null)); + application1.getGitApplicationMetadata().getDefaultApplicationId())); StepVerifier.create(forkedApp) .assertNext(application1 -> { @@ -2774,7 +2671,7 @@ public class ApplicationServiceCETest { return layoutActionService .createSingleAction(action, Boolean.FALSE) - .zipWith(layoutCollectionService.createCollection(actionCollectionDTO, null)) + .zipWith(layoutCollectionService.createCollection(actionCollectionDTO)) .flatMap(tuple1 -> { ActionDTO savedAction = tuple1.getT1(); ActionCollectionDTO savedActionCollection = tuple1.getT2(); @@ -2832,9 +2729,8 @@ public class ApplicationServiceCETest { Mono applicationMono = applicationService .update(gitConnectedApp.getId(), gitConnectedApp) - .flatMap( - updatedApp -> applicationPageService.publish(updatedApp.getId(), gitData.getBranchName(), true)) - .flatMap(application -> applicationService.findByBranchNameAndDefaultApplicationId( + .flatMap(updatedApp -> applicationPageService.publish(updatedApp.getId(), true)) + .flatMap(application -> applicationService.findByBranchNameAndBaseApplicationId( gitData.getBranchName(), gitData.getDefaultApplicationId(), MANAGE_APPLICATIONS)) .cache(); @@ -2867,7 +2763,7 @@ public class ApplicationServiceCETest { .getLayouts() .get(0) .getDsl()); - assertThat(newPage.getDefaultResources()).isNotNull(); + assertThat(newPage.getBaseId()).isNotNull(); assertThat(application.getPublishedAppLayout()).isEqualTo(application.getUnpublishedAppLayout()); assertThat(application.getPublishedApplicationDetail().getAppPositioning()) @@ -2996,8 +2892,8 @@ public class ApplicationServiceCETest { page.setLayouts(layouts); Mono applicationMono = applicationPageService - .createPageWithBranchName(page, branchName) - .flatMap(pageDTO -> applicationPageService.publish(pageDTO.getApplicationId(), branchName, true)) + .createPage(page) + .flatMap(pageDTO -> applicationPageService.publish(pageDTO.getApplicationId(), true)) .cache(); PageDTO newPage = applicationMono @@ -3109,7 +3005,7 @@ public class ApplicationServiceCETest { new CustomJSLib("name1", Set.of("accessor"), "url", "docsUrl", "version", "defs"); return customJSLibService .addJSLibsToContext( - application.getId(), CreatorContextType.APPLICATION, Set.of(jsLib), null, false) + application.getId(), CreatorContextType.APPLICATION, Set.of(jsLib), false) .then(applicationService.getById(application.getId())); }) .flatMap(application -> { @@ -3239,13 +3135,12 @@ public class ApplicationServiceCETest { actionCollectionDTO1.setActions(List.of(jsAction)); actionCollectionDTO1.setPluginType(PluginType.JS); - final ActionCollectionDTO createdActionCollectionDTO1 = layoutCollectionService - .createCollection(actionCollectionDTO1, null) - .block(); + final ActionCollectionDTO createdActionCollectionDTO1 = + layoutCollectionService.createCollection(actionCollectionDTO1).block(); // Trigger the clone of application now. applicationPageService - .cloneApplication(originalApplication.getId(), null) + .cloneApplication(originalApplication.getId()) .timeout(Duration.ofMillis(50)) .subscribe(); @@ -3379,8 +3274,8 @@ public class ApplicationServiceCETest { Mono applicationPagesDTOMono = createApplicationMono .map(application -> application.getId()) - .flatMap(applicationId -> - newPageService.findApplicationPagesByApplicationIdViewMode(applicationId, false, false)); + .flatMap(applicationId -> newPageService.findApplicationPagesByBranchedApplicationIdAndViewMode( + applicationId, false, false)); StepVerifier.create(applicationPagesDTOMono) .assertNext(applicationPagesDTO -> { @@ -3464,7 +3359,8 @@ public class ApplicationServiceCETest { // Trigger the change view access of application now. applicationService - .changeViewAccess(originalApplication.getId(), applicationAccessDTO) + .changeViewAccessForSingleBranchByBranchedApplicationId( + originalApplication.getId(), applicationAccessDTO) .timeout(Duration.ofMillis(10)) .subscribe(); @@ -3588,7 +3484,8 @@ public class ApplicationServiceCETest { .flatMap(application -> { ApplicationAccessDTO applicationAccessDTO = new ApplicationAccessDTO(); applicationAccessDTO.setPublicAccess(TRUE); - return applicationService.changeViewAccess(application.getId(), applicationAccessDTO); + return applicationService.changeViewAccessForSingleBranchByBranchedApplicationId( + application.getId(), applicationAccessDTO); }) .flatMap(application -> applicationService.saveLastEditInformation(application.getId())); StepVerifier.create(updatedApplication) @@ -3748,7 +3645,7 @@ public class ApplicationServiceCETest { return layoutActionService .createSingleAction(action, Boolean.FALSE) - .zipWith(layoutCollectionService.createCollection(actionCollectionDTO, null)) + .zipWith(layoutCollectionService.createCollection(actionCollectionDTO)) .flatMap(tuple1 -> { ActionDTO savedAction = tuple1.getT1(); ActionCollectionDTO savedActionCollection = tuple1.getT2(); @@ -3853,11 +3750,11 @@ public class ApplicationServiceCETest { Mono>> tuple2Application = createTheme .then(applicationPageService.createApplication(testApplication, workspaceId)) .flatMap(application -> themeService - .updateTheme(application.getId(), null, theme) + .updateTheme(application.getId(), theme) .then(themeService .persistCurrentTheme(application.getId(), null, new Theme()) .flatMap(theme1 -> Mono.zip( - applicationPageService.cloneApplication(application.getId(), null), + applicationPageService.cloneApplication(application.getId()), Mono.just(application))))) .flatMap(objects -> themeService .getThemeById(objects.getT1().getEditModeThemeId(), MANAGE_THEMES) @@ -3878,7 +3775,7 @@ public class ApplicationServiceCETest { @Test @WithUserDetails(value = "api_user") public void getApplicationConnectedToGit_defaultBranchUpdated_returnBranchSpecificApplication() { - // Update the default Branch for the gitConected App + // Update the default Branch for the gitConnected App gitConnectedApp.getGitApplicationMetadata().setDefaultBranchName("release"); applicationService.save(gitConnectedApp).block(); @@ -3899,7 +3796,7 @@ public class ApplicationServiceCETest { .map(importableArtifact -> (Application) importableArtifact) .block(); - Mono getApplication = applicationService.findByIdAndBranchName(gitConnectedApp.getId(), "release"); + Mono getApplication = applicationService.findByBranchedId(application.getId(), null); StepVerifier.create(getApplication) .assertNext(application1 -> { assertThat(application1).isNotNull(); @@ -3908,7 +3805,8 @@ public class ApplicationServiceCETest { gitConnectedApp.getGitApplicationMetadata().getBranchName()); assertThat(application1.getGitApplicationMetadata().getBranchName()) .isEqualTo(application.getGitApplicationMetadata().getBranchName()); - assertThat(application1.getId()).isEqualTo(gitConnectedApp.getId()); + assertThat(application1.getGitArtifactMetadata().getDefaultArtifactId()) + .isEqualTo(gitConnectedApp.getId()); assertThat(application1.getName()).isEqualTo(application.getName()); }) .verifyComplete(); @@ -3938,7 +3836,8 @@ public class ApplicationServiceCETest { ApplicationAccessDTO applicationAccessDTO = new ApplicationAccessDTO(); applicationAccessDTO.setPublicAccess(true); Application publicAccessApplication = applicationService - .changeViewAccess(createdApplication.getId(), applicationAccessDTO) + .changeViewAccessForSingleBranchByBranchedApplicationId( + createdApplication.getId(), applicationAccessDTO) .block(); /** @@ -3987,7 +3886,8 @@ public class ApplicationServiceCETest { applicationAccessDTO.setPublicAccess(false); Application privateAccessApplication = applicationService - .changeViewAccess(createdApplication.getId(), applicationAccessDTO) + .changeViewAccessForSingleBranchByBranchedApplicationId( + createdApplication.getId(), applicationAccessDTO) .block(); /** @@ -4039,7 +3939,7 @@ public class ApplicationServiceCETest { String createdApplicationId = createTestApplication("ApplicationServiceTest Upload/Delete Nav Logo"); final Mono saveMono = applicationService - .saveAppNavigationLogo(null, createdApplicationId, filepart) + .saveAppNavigationLogo(createdApplicationId, filepart) .cache(); Mono> loadLogoImageMono = applicationService @@ -4061,7 +3961,7 @@ public class ApplicationServiceCETest { final Mono> saveAndGetMono = saveMono.then(loadLogoImageMono); final Mono> deleteAndGetMono = saveMono.then( - applicationService.deleteAppNavigationLogo(null, createdApplicationId)) + applicationService.deleteAppNavigationLogo(createdApplicationId)) .then(loadLogoImageMono); StepVerifier.create(saveAndGetMono) @@ -4107,7 +4007,7 @@ public class ApplicationServiceCETest { String createdApplicationId = createTestApplication("ApplicationServiceTest Upload Invalid Nav Logo"); final Mono saveMono = applicationService - .saveAppNavigationLogo(null, createdApplicationId, filepart) + .saveAppNavigationLogo(createdApplicationId, filepart) .cache(); StepVerifier.create(saveMono) .expectErrorMatches(error -> error instanceof AppsmithException) @@ -4131,7 +4031,7 @@ public class ApplicationServiceCETest { String createdApplicationId = createTestApplication("ApplicationServiceTest Upload Invalid Nav Logo Size"); final Mono saveMono = applicationService - .saveAppNavigationLogo(null, createdApplicationId, filepart) + .saveAppNavigationLogo(createdApplicationId, filepart) .cache(); StepVerifier.create(saveMono) .expectErrorMatches(error -> error instanceof AppsmithException) @@ -4151,7 +4051,7 @@ public class ApplicationServiceCETest { Application application = applicationPageService .createApplication(testApplication, workspaceId) .block(); - Mono clonedApplicationMono = applicationPageService.cloneApplication(application.getId(), null); + Mono clonedApplicationMono = applicationPageService.cloneApplication(application.getId()); StepVerifier.create(clonedApplicationMono) .assertNext(clonedApplication -> { @@ -4179,7 +4079,7 @@ public class ApplicationServiceCETest { .collect(Collectors.toSet()); gitAppPage.setPolicies(newPoliciesWithoutEdit); NewPage updatedGitAppPage = newPageRepository.save(gitAppPage).block(); - StepVerifier.create(applicationPageService.publish(gitConnectedApp.getId(), null, true)) + StepVerifier.create(applicationPageService.publish(gitConnectedApp.getId(), true)) .expectErrorMatches(throwable -> throwable instanceof AppsmithException && throwable .getMessage() @@ -4212,7 +4112,7 @@ public class ApplicationServiceCETest { .collect(Collectors.toSet()); gitAppPage.setPolicies(newPoliciesWithoutEdit); NewPage updatedGitAppPage = newPageRepository.save(gitAppPage).block(); - StepVerifier.create(applicationPageService.cloneApplication(gitConnectedApp.getId(), null)) + StepVerifier.create(applicationPageService.cloneApplication(gitConnectedApp.getId())) .expectErrorMatches(throwable -> throwable instanceof AppsmithException && throwable .getMessage() @@ -4264,7 +4164,7 @@ public class ApplicationServiceCETest { testDatasource1.setPolicies(newPoliciesWithoutEdit); Datasource updatedTestDatasource = datasourceRepository.save(testDatasource1).block(); - StepVerifier.create(applicationPageService.cloneApplication(gitConnectedApp.getId(), null)) + StepVerifier.create(applicationPageService.cloneApplication(gitConnectedApp.getId())) .expectErrorMatches(throwable -> throwable instanceof AppsmithException && throwable .getMessage() @@ -4387,7 +4287,7 @@ public class ApplicationServiceCETest { assert workspace != null; Flux allApplicationsWithinWorkspace = - applicationService.findByWorkspaceIdAndDefaultApplicationsInRecentlyUsedOrder(workspace.getId()); + applicationService.findByWorkspaceIdAndBaseApplicationsInRecentlyUsedOrder(workspace.getId()); StepVerifier.create(allApplicationsWithinWorkspace.collectList()) .assertNext(applications -> { @@ -4419,7 +4319,7 @@ public class ApplicationServiceCETest { doReturn(Mono.just(userData)).when(userDataService).getForCurrentUser(); Flux allApplicationsWithinWorkspace = - applicationService.findByWorkspaceIdAndDefaultApplicationsInRecentlyUsedOrder(workspace.getId()); + applicationService.findByWorkspaceIdAndBaseApplicationsInRecentlyUsedOrder(workspace.getId()); StepVerifier.create(allApplicationsWithinWorkspace.collectList()) .assertNext(applications -> { @@ -4456,7 +4356,7 @@ public class ApplicationServiceCETest { doReturn(Mono.just(userData)).when(userDataService).getForCurrentUser(); Flux allApplicationsWithinWorkspace = - applicationService.findByWorkspaceIdAndDefaultApplicationsInRecentlyUsedOrder(workspace.getId()); + applicationService.findByWorkspaceIdAndBaseApplicationsInRecentlyUsedOrder(workspace.getId()); StepVerifier.create(allApplicationsWithinWorkspace.collectList()) .assertNext(applications -> { @@ -4482,7 +4382,7 @@ public class ApplicationServiceCETest { String invalidWorkspaceId = UUID.randomUUID().toString(); Flux allApplicationsWithinWorkspace = - applicationService.findByWorkspaceIdAndDefaultApplicationsInRecentlyUsedOrder(invalidWorkspaceId); + applicationService.findByWorkspaceIdAndBaseApplicationsInRecentlyUsedOrder(invalidWorkspaceId); StepVerifier.create(allApplicationsWithinWorkspace.collectList()) .expectErrorSatisfies(throwable -> { diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationSnapshotServiceUnitTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationSnapshotServiceUnitTest.java index cb4c7dfc11..f278c9f114 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationSnapshotServiceUnitTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ApplicationSnapshotServiceUnitTest.java @@ -5,9 +5,7 @@ import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.constants.ArtifactType; import com.appsmith.server.constants.SerialiseArtifactObjective; import com.appsmith.server.domains.Application; -import com.appsmith.server.domains.ApplicationPage; import com.appsmith.server.domains.ApplicationSnapshot; -import com.appsmith.server.domains.GitArtifactMetadata; import com.appsmith.server.domains.Layout; import com.appsmith.server.domains.NewPage; import com.appsmith.server.dtos.ApplicationJson; @@ -37,7 +35,6 @@ import java.util.Random; import static java.util.Arrays.copyOfRange; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; @@ -103,7 +100,7 @@ public class ApplicationSnapshotServiceUnitTest { Mockito.when(applicationSnapshotRepository.saveAll(argThat(snapshotListHasTwoSnapshot))) .thenReturn(Flux.just(new ApplicationSnapshot(), new ApplicationSnapshot())); - StepVerifier.create(applicationSnapshotService.createApplicationSnapshot(defaultAppId, branchName)) + StepVerifier.create(applicationSnapshotService.createApplicationSnapshot(branchedAppId)) .assertNext(aBoolean -> { assertThat(aBoolean).isTrue(); }) @@ -122,8 +119,7 @@ public class ApplicationSnapshotServiceUnitTest { application.setWorkspaceId(workspaceId); application.setId(branchedAppId); - Mockito.when(applicationService.findByBranchNameAndDefaultApplicationId( - branch, defaultAppId, AclPermission.MANAGE_APPLICATIONS)) + Mockito.when(applicationService.findById(branchedAppId, AclPermission.MANAGE_APPLICATIONS)) .thenReturn(Mono.just(application)); ApplicationJson applicationJson = new ApplicationJson(); @@ -148,71 +144,19 @@ public class ApplicationSnapshotServiceUnitTest { applicationJson1.getExportedApplication().getName().equals(application.getName()); Mockito.when(importService.restoreSnapshot( - eq(application.getWorkspaceId()), eq(branchedAppId), eq(branch), argThat(matchApplicationJson))) + eq(application.getWorkspaceId()), eq(branchedAppId), argThat(matchApplicationJson))) .thenAnswer(getTypeSafeMockAnswer(application)); Mockito.when(applicationSnapshotRepository.deleteAllByApplicationId(branchedAppId)) .thenReturn(Mono.just("application").then()); - StepVerifier.create(applicationSnapshotService.restoreSnapshot(defaultAppId, branch)) + StepVerifier.create(applicationSnapshotService.restoreSnapshot(branchedAppId)) .assertNext(application1 -> { assertThat(application1.getName()).isEqualTo(application.getName()); }) .verifyComplete(); } - @Test - public void restoreSnapshot_WhenApplicationHasDefaultPageIds_IdReplacedWithDefaultPageId() { - String defaultAppId = "default-app-id", - branchedAppId = "branched-app-id", - workspaceId = "workspace-id", - branch = "development"; - - Application application = new Application(); - application.setName("Snapshot test"); - application.setWorkspaceId(workspaceId); - application.setId(branchedAppId); - - ApplicationPage applicationPage = new ApplicationPage(); - applicationPage.setId("original-page-id"); - applicationPage.setDefaultPageId("default-page-id"); - applicationPage.setSlug("original-page-slug"); - applicationPage.setIsDefault(true); - - application.setPages(List.of(applicationPage)); - - Mockito.when(applicationService.findByBranchNameAndDefaultApplicationId( - branch, defaultAppId, AclPermission.MANAGE_APPLICATIONS)) - .thenReturn(Mono.just(application)); - - ApplicationJson applicationJson = new ApplicationJson(); - applicationJson.setExportedApplication(application); - - String jsonString = gson.toJson(applicationJson); - byte[] jsonStringBytes = jsonString.getBytes(StandardCharsets.UTF_8); - - List snapshots = List.of(createSnapshot(branchedAppId, jsonStringBytes, 1)); - - Mockito.when(applicationSnapshotRepository.findByApplicationId(branchedAppId)) - .thenReturn(Flux.fromIterable(snapshots)); - - Mockito.when(importService.restoreSnapshot( - eq(application.getWorkspaceId()), eq(branchedAppId), eq(branch), any())) - .thenAnswer(getTypeSafeMockAnswer(application)); - - Mockito.when(applicationSnapshotRepository.deleteAllByApplicationId(branchedAppId)) - .thenReturn(Mono.just("application").then()); - - StepVerifier.create(applicationSnapshotService.restoreSnapshot(defaultAppId, branch)) - .assertNext(application1 -> { - assertThat(application1.getName()).isEqualTo(application.getName()); - application1.getPages().forEach(page -> { - assertThat(page.getId()).isEqualTo(page.getDefaultPageId()); - }); - }) - .verifyComplete(); - } - private ApplicationSnapshot createSnapshot(String applicationId, byte[] data, int chunkOrder) { ApplicationSnapshot applicationSnapshot = new ApplicationSnapshot(); applicationSnapshot.setApplicationId(applicationId); @@ -236,65 +180,6 @@ public class ApplicationSnapshotServiceUnitTest { return generatedString; } - @Test - public void restoreSnapshot_WhenApplicationConnectedToGit_ReturnApplicationWithDefaultIds() { - // create an application object that has git related fields populated - Application application = new Application(); - application.setId("branched-app-id"); - application.setName("Snapshot test"); - application.setWorkspaceId("workspace-id"); - application.setGitApplicationMetadata(new GitArtifactMetadata()); - application.getGitApplicationMetadata().setDefaultApplicationId("default-app-id"); - application.getGitApplicationMetadata().setBranchName("development"); - - // create pages for the application that have git related fields populated - List pages = new ArrayList<>(); - ApplicationPage page = new ApplicationPage(); - page.setDefaultPageId("default-page-id"); - page.setId("branched-page-id"); - pages.add(page); - application.setPages(pages); - - // create the application json because we need to mock the snapshot with a byte array of this json - ApplicationJson applicationJson = new ApplicationJson(); - applicationJson.setExportedApplication(application); - String jsonString = gson.toJson(applicationJson); - byte[] jsonStringBytes = jsonString.getBytes(StandardCharsets.UTF_8); - ApplicationSnapshot applicationSnapshot = createSnapshot("branched-app-id", jsonStringBytes, 1); - - // mock so that this application is returned - Mockito.when(applicationService.findByBranchNameAndDefaultApplicationId( - "development", "default-app-id", applicationPermission.getEditPermission())) - .thenReturn(Mono.just(application)); - - // mock so that this application snapshot is returned when queried with branched application id - Mockito.when(applicationSnapshotRepository.findByApplicationId("branched-app-id")) - .thenReturn(Flux.just(applicationSnapshot)); - - // mock the import application service to return the application that was passed to it - Mockito.when(importService.restoreSnapshot( - eq(application.getWorkspaceId()), - eq("branched-app-id"), - eq("development"), - argThat(applicationJson1 -> - applicationJson1.getArtifact().getName().equals(application.getName())))) - .thenAnswer(getTypeSafeMockAnswer(application)); - - // mock the delete spanshot to return an empty mono - Mockito.when(applicationSnapshotRepository.deleteAllByApplicationId("branched-app-id")) - .thenReturn(Mono.empty()); - - StepVerifier.create(applicationSnapshotService.restoreSnapshot("default-app-id", "development")) - .assertNext(application1 -> { - assertThat(application1.getName()).isEqualTo(application.getName()); - assertThat(application1.getId()) - .isEqualTo(application.getGitApplicationMetadata().getDefaultApplicationId()); - assertThat(application1.getPages().get(0).getId()) - .isEqualTo(application.getPages().get(0).getDefaultPageId()); - }) - .verifyComplete(); - } - @Test public void test() { Mono mono = Mono.just(1) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/NewActionServiceUnitTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/NewActionServiceUnitTest.java index b88aae1647..02fe5af4de 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/NewActionServiceUnitTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/NewActionServiceUnitTest.java @@ -6,11 +6,9 @@ import com.appsmith.external.models.PluginType; import com.appsmith.server.acl.PolicyGenerator; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.datasources.base.DatasourceService; -import com.appsmith.server.defaultresources.DefaultResourcesService; import com.appsmith.server.domains.NewAction; import com.appsmith.server.domains.Plugin; import com.appsmith.server.helpers.PluginExecutorHelper; -import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.newactions.base.NewActionServiceCEImpl; import com.appsmith.server.newactions.helpers.NewActionHelper; import com.appsmith.server.newpages.base.NewPageService; @@ -77,9 +75,6 @@ public class NewActionServiceUnitTest { @MockBean ConfigService configService; - @MockBean - ResponseUtils responseUtils; - @MockBean PermissionGroupService permissionGroupService; @@ -106,12 +101,6 @@ public class NewActionServiceUnitTest { @MockBean ObservationRegistry observationRegistry; - @MockBean - DefaultResourcesService defaultResourcesService; - - @MockBean - DefaultResourcesService dtoDefaultResourcesService; - @BeforeEach public void setup() { newActionService = new NewActionServiceCEImpl( @@ -126,7 +115,6 @@ public class NewActionServiceUnitTest { applicationService, policySolution, configService, - responseUtils, permissionGroupService, newActionHelper, datasourcePermission, @@ -134,9 +122,7 @@ public class NewActionServiceUnitTest { pagePermission, actionPermission, entityValidationService, - observationRegistry, - defaultResourcesService, - dtoDefaultResourcesService); + observationRegistry); ObservationRegistry.ObservationConfig mockObservationConfig = Mockito.mock(ObservationRegistry.ObservationConfig.class); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/TenantServiceCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/TenantServiceCETest.java index 14bc90dfbc..f82b882de9 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/TenantServiceCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/TenantServiceCETest.java @@ -13,6 +13,7 @@ import com.appsmith.server.helpers.ce.bridge.Bridge; import com.appsmith.server.repositories.CacheableRepositoryHelper; import com.appsmith.server.repositories.TenantRepository; import com.appsmith.server.repositories.UserRepository; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.EnvManager; import org.junit.jupiter.api.AfterEach; @@ -65,6 +66,9 @@ class TenantServiceCETest { @Autowired UserUtils userUtils; + @SpyBean + FeatureFlagService featureFlagService; + @Autowired ReactiveRedisTemplate reactiveRedisTemplate; diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/AuthenticationServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/AuthenticationServiceTest.java index be51dc5b5d..2538f7925d 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/AuthenticationServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/AuthenticationServiceTest.java @@ -6,10 +6,12 @@ import com.appsmith.external.models.DatasourceConfiguration; import com.appsmith.external.models.DatasourceStorageDTO; import com.appsmith.external.models.OAuth2; import com.appsmith.external.models.Property; +import com.appsmith.server.acl.AclPermission; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.constants.FieldName; import com.appsmith.server.datasources.base.DatasourceService; import com.appsmith.server.domains.Application; +import com.appsmith.server.domains.NewPage; import com.appsmith.server.domains.Plugin; import com.appsmith.server.domains.Workspace; import com.appsmith.server.dtos.PageDTO; @@ -19,6 +21,7 @@ import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.MockPluginExecutor; import com.appsmith.server.helpers.PluginExecutorHelper; +import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.plugins.base.PluginService; import com.appsmith.server.repositories.WorkspaceRepository; import com.appsmith.server.services.ApplicationPageService; @@ -31,6 +34,7 @@ import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.http.HttpHeaders; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; import org.springframework.security.test.context.support.WithUserDetails; @@ -82,6 +86,9 @@ public class AuthenticationServiceTest { @Autowired ApplicationService applicationService; + @SpyBean + NewPageService newPageService; + Workspace workspace; @BeforeEach @@ -106,7 +113,7 @@ public class AuthenticationServiceTest { @WithUserDetails(value = "api_user") public void testGetAuthorizationCodeURL_missingDatasource() { Mono authorizationCodeUrlMono = authenticationService.getAuthorizationCodeURLForGenericOAuth2( - "invalidId", FieldName.UNUSED_ENVIRONMENT_ID, "irrelevantPageId", null, null); + "invalidId", FieldName.UNUSED_ENVIRONMENT_ID, "irrelevantPageId", null); StepVerifier.create(authorizationCodeUrlMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -125,6 +132,16 @@ public class AuthenticationServiceTest { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); + String pageId = "irrelevantPageId"; + String branchName = "irrelevantBranchName"; + NewPage newPage = new NewPage(); + newPage.setId(pageId); + newPage.setBranchName(branchName); + + Mockito.doReturn(Mono.just(newPage)) + .when(newPageService) + .findById(Mockito.any(), Mockito.any(AclPermission.class)); + Mono pluginMono = pluginService.findByName("Installed Plugin Name"); Datasource datasource = new Datasource(); datasource.setName("Missing OAuth2 datasource"); @@ -147,7 +164,7 @@ public class AuthenticationServiceTest { Mono authorizationCodeUrlMono = datasourceMono .map(BaseDomain::getId) .flatMap(datasourceId -> authenticationService.getAuthorizationCodeURLForGenericOAuth2( - datasourceId, defaultEnvironmentId, "irrelevantPageId", null, null)); + datasourceId, defaultEnvironmentId, pageId, null)); StepVerifier.create(authorizationCodeUrlMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -225,7 +242,7 @@ public class AuthenticationServiceTest { final String datasourceId1 = datasourceMono.map(BaseDomain::getId).block(); Mono authorizationCodeUrlMono = authenticationService.getAuthorizationCodeURLForGenericOAuth2( - datasourceId1, defaultEnvironmentId, pageDto.getId(), null, httpRequest); + datasourceId1, defaultEnvironmentId, pageDto.getId(), httpRequest); StepVerifier.create(authorizationCodeUrlMono) .assertNext(url -> { @@ -267,8 +284,11 @@ public class AuthenticationServiceTest { .getDefaultEnvironmentId(workspaceId, environmentPermission.getExecutePermission()) .block(); + String branchName = "testBranch"; + PageDTO testPage = new PageDTO(); testPage.setName("Test-Page-oauth2-git-redirection"); + testPage.setBranchName(branchName); Application newApp = new Application(); newApp.setName(UUID.randomUUID().toString()); @@ -319,7 +339,7 @@ public class AuthenticationServiceTest { final String datasourceId = datasourceMono.map(BaseDomain::getId).block(); Mono authorizationCodeUrlMono = authenticationService.getAuthorizationCodeURLForGenericOAuth2( - datasourceId, null, pageDTO.getId(), "testBranch", httpRequest); + datasourceId, null, pageDTO.getId(), httpRequest); StepVerifier.create(authorizationCodeUrlMono) .assertNext(url -> { @@ -335,7 +355,7 @@ public class AuthenticationServiceTest { defaultEnvironmentId, "https://mock.origin.com", workspaceId, - "testBranch") + branchName) + "&scope=Scope\\d%20Scope\\d" + "&key=value")); }) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/CreateDBTablePageSolutionTests.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/CreateDBTablePageSolutionTests.java index e98a53e6b1..ae1af27a46 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/CreateDBTablePageSolutionTests.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/CreateDBTablePageSolutionTests.java @@ -11,7 +11,6 @@ import com.appsmith.external.models.DatasourceStructure.Column; import com.appsmith.external.models.DatasourceStructure.Key; import com.appsmith.external.models.DatasourceStructure.Table; import com.appsmith.external.models.DatasourceStructure.TableType; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.Property; import com.appsmith.external.plugins.PluginExecutor; import com.appsmith.server.applications.base.ApplicationService; @@ -258,8 +257,8 @@ public class CreateDBTablePageSolutionTests { @WithUserDetails(value = "api_user") public void createPageWithInvalidApplicationIdTest() { - Mono resultMono = solution.createPageFromDBTable( - testApp.getPages().get(0).getId(), resource, testDefaultEnvironmentId, ""); + Mono resultMono = + solution.createPageFromDBTable(testApp.getPages().get(0).getId(), resource, testDefaultEnvironmentId); StepVerifier.create(resultMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -285,7 +284,7 @@ public class CreateDBTablePageSolutionTests { resource.setApplicationId(testApp.getId()); resource.setDatasourceId(datasource.getId()); return solution.createPageFromDBTable( - testApp.getPages().get(0).getId(), resource, testDefaultEnvironmentId, null); + testApp.getPages().get(0).getId(), resource, testDefaultEnvironmentId); }); StepVerifier.create(resultMono) @@ -300,7 +299,7 @@ public class CreateDBTablePageSolutionTests { @WithUserDetails(value = "api_user") public void createPageWithInvalidRequestBodyTest() { Mono resultMono = solution.createPageFromDBTable( - testApp.getPages().get(0).getId(), new CRUDPageResourceDTO(), testDefaultEnvironmentId, ""); + testApp.getPages().get(0).getId(), new CRUDPageResourceDTO(), testDefaultEnvironmentId); StepVerifier.create(resultMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -310,30 +309,12 @@ public class CreateDBTablePageSolutionTests { .verify(); } - @Test - @WithUserDetails(value = "api_user") - public void createPage_withInvalidBranchName_throwException() { - final String pageId = testApp.getPages().get(0).getId(); - resource.setApplicationId(testApp.getId()); - Mono resultMono = - solution.createPageFromDBTable(pageId, resource, testDefaultEnvironmentId, "invalidBranch"); - - StepVerifier.create(resultMono) - .expectErrorMatches(throwable -> throwable instanceof AppsmithException - && throwable - .getMessage() - .equals(AppsmithError.NO_RESOURCE_FOUND.getMessage( - FieldName.PAGE, pageId + ", " + "invalidBranch"))) - .verify(); - } - @Test @WithUserDetails(value = "api_user") public void createPageWithNullPageId() { resource.setApplicationId(testApp.getId()); - Mono resultMono = - solution.createPageFromDBTable(null, resource, testDefaultEnvironmentId, null); + Mono resultMono = solution.createPageFromDBTable(null, resource, testDefaultEnvironmentId); StepVerifier.create(resultMono) .assertNext(crudPage -> { @@ -382,10 +363,10 @@ public class CreateDBTablePageSolutionTests { newPage.setName("crud-admin-page-with-git-connected-app"); Mono resultMono = applicationPageService - .createPageWithBranchName(newPage, gitData.getBranchName()) - .flatMap(savedPage -> solution.createPageFromDBTable( - savedPage.getId(), resource, testDefaultEnvironmentId, gitData.getBranchName())) - .flatMap(crudPageResponseDTO -> newPageService.findByBranchNameAndDefaultPageId( + .createPage(newPage) + .flatMap(savedPage -> + solution.createPageFromDBTable(savedPage.getId(), resource, testDefaultEnvironmentId)) + .flatMap(crudPageResponseDTO -> newPageService.findByBranchNameAndBasePageId( gitData.getBranchName(), crudPageResponseDTO.getPage().getId(), READ_PAGES)); StepVerifier.create(resultMono.zipWhen(newPage1 -> getActions(newPage1.getId()))) @@ -397,24 +378,14 @@ public class CreateDBTablePageSolutionTests { Layout layout = page.getLayouts().get(0); assertThat(page.getName()).isEqualTo("crud-admin-page-with-git-connected-app"); - assertThat(newPage1.getDefaultResources()).isNotNull(); - assertThat(newPage1.getDefaultResources().getBranchName()).isEqualTo(gitData.getBranchName()); - assertThat(newPage1.getDefaultResources().getPageId()).isEqualTo(newPage1.getId()); - assertThat(newPage1.getDefaultResources().getApplicationId()) - .isEqualTo(newPage1.getApplicationId()); + assertThat(newPage1.getBranchName()).isEqualTo(gitData.getBranchName()); + assertThat(newPage1.getBaseId()).isEqualTo(newPage1.getId()); assertThat(actionList).hasSize(4); - DefaultResources newActionResources = actionList.get(0).getDefaultResources(); - DefaultResources actionDTOResources = - actionList.get(0).getUnpublishedAction().getDefaultResources(); - assertThat(newActionResources.getActionId()) + NewAction newAction = actionList.get(0); + assertThat(newAction.getBaseId()) .isEqualTo(actionList.get(0).getId()); - assertThat(newActionResources.getApplicationId()) - .isEqualTo(newPage1.getDefaultResources().getApplicationId()); - assertThat(newActionResources.getPageId()).isNull(); - assertThat(newActionResources.getBranchName()).isEqualTo(gitData.getBranchName()); - assertThat(actionDTOResources.getPageId()) - .isEqualTo(newPage1.getDefaultResources().getPageId()); + assertThat(newAction.getBranchName()).isEqualTo(gitData.getBranchName()); }) .verifyComplete(); } @@ -431,7 +402,7 @@ public class CreateDBTablePageSolutionTests { Mono resultMono = applicationPageService .createPage(newPage) .flatMap(savedPage -> - solution.createPageFromDBTable(savedPage.getId(), resource, testDefaultEnvironmentId, "")) + solution.createPageFromDBTable(savedPage.getId(), resource, testDefaultEnvironmentId)) .map(crudPageResponseDTO -> crudPageResponseDTO.getPage()); StepVerifier.create(resultMono.zipWhen(pageDTO -> getActions(pageDTO.getId()))) @@ -488,7 +459,7 @@ public class CreateDBTablePageSolutionTests { Mono resultMono = applicationPageService .createPage(newPage) .flatMap(savedPage -> - solution.createPageFromDBTable(savedPage.getId(), resourceDTO, testDefaultEnvironmentId, "")); + solution.createPageFromDBTable(savedPage.getId(), resourceDTO, testDefaultEnvironmentId)); StepVerifier.create(resultMono.zipWhen(crudPageResponseDTO -> getActions(crudPageResponseDTO.getPage().getId()))) @@ -584,7 +555,7 @@ public class CreateDBTablePageSolutionTests { return applicationPageService.createPage(newPage); }) .flatMap(savedPage -> - solution.createPageFromDBTable(savedPage.getId(), resourceDTO, testDefaultEnvironmentId, null)); + solution.createPageFromDBTable(savedPage.getId(), resourceDTO, testDefaultEnvironmentId)); StepVerifier.create(resultMono.zipWhen(crudPageResponseDTO -> getActions(crudPageResponseDTO.getPage().getId()))) @@ -673,7 +644,7 @@ public class CreateDBTablePageSolutionTests { return applicationPageService.createPage(newPage); }) .flatMap(savedPage -> - solution.createPageFromDBTable(savedPage.getId(), resource, testDefaultEnvironmentId, null)); + solution.createPageFromDBTable(savedPage.getId(), resource, testDefaultEnvironmentId)); StepVerifier.create(resultMono.zipWhen(crudPageResponseDTO -> getActions(crudPageResponseDTO.getPage().getId()))) @@ -757,7 +728,7 @@ public class CreateDBTablePageSolutionTests { return applicationPageService.createPage(newPage); }) .flatMap(savedPage -> - solution.createPageFromDBTable(savedPage.getId(), resource, testDefaultEnvironmentId, "")) + solution.createPageFromDBTable(savedPage.getId(), resource, testDefaultEnvironmentId)) .map(crudPageResponseDTO -> crudPageResponseDTO.getPage()); StepVerifier.create(resultMono.zipWhen(pageDTO -> getActions(pageDTO.getId()))) @@ -885,7 +856,7 @@ public class CreateDBTablePageSolutionTests { Mono resultMono = datasourceMono .flatMap(datasource1 -> { resource.setDatasourceId(datasource1.getId()); - return solution.createPageFromDBTable(null, resource, testDefaultEnvironmentId, ""); + return solution.createPageFromDBTable(null, resource, testDefaultEnvironmentId); }) .map(crudPageResponseDTO -> crudPageResponseDTO.getPage()); @@ -969,7 +940,7 @@ public class CreateDBTablePageSolutionTests { Mono resultMono = datasourceMono.flatMap(datasource1 -> { resource.setDatasourceId(datasource1.getId()); - return solution.createPageFromDBTable(null, resource, testDefaultEnvironmentId, ""); + return solution.createPageFromDBTable(null, resource, testDefaultEnvironmentId); }); StepVerifier.create(resultMono.zipWhen(crudPageResponseDTO -> @@ -1059,7 +1030,7 @@ public class CreateDBTablePageSolutionTests { return applicationPageService.createPage(newPage); }) .flatMap(savedPage -> - solution.createPageFromDBTable(savedPage.getId(), resource, testDefaultEnvironmentId, null)) + solution.createPageFromDBTable(savedPage.getId(), resource, testDefaultEnvironmentId)) .map(crudPageResponseDTO -> crudPageResponseDTO.getPage()); StepVerifier.create(resultMono.zipWhen(pageDTO -> getActions(pageDTO.getId()))) @@ -1136,7 +1107,7 @@ public class CreateDBTablePageSolutionTests { return applicationPageService.createPage(newPage); }) .flatMap(savedPage -> - solution.createPageFromDBTable(savedPage.getId(), resource, testDefaultEnvironmentId, null)) + solution.createPageFromDBTable(savedPage.getId(), resource, testDefaultEnvironmentId)) .map(crudPageResponseDTO -> crudPageResponseDTO.getPage()); StepVerifier.create(resultMono.zipWhen(pageDTO -> getActions(pageDTO.getId()))) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/DatasourceTriggerSolutionTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/DatasourceTriggerSolutionTest.java index 4e1c3a3b08..1304acc687 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/DatasourceTriggerSolutionTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/DatasourceTriggerSolutionTest.java @@ -93,6 +93,7 @@ public class DatasourceTriggerSolutionTest { public void setup() { Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) .thenReturn(Mono.just(new MockPluginExecutor())); + Mockito.doReturn(Mono.just(Boolean.TRUE)).when(featureFlagService).check(Mockito.any()); Workspace workspace = new Workspace(); workspace.setName("Datasource Trigger Test Workspace"); Workspace savedWorkspace = workspaceService.create(workspace).block(); @@ -170,7 +171,6 @@ public class DatasourceTriggerSolutionTest { datasourceService .findById(datasourceId, datasourcePermission.getReadPermission()) .block(); - Mockito.doReturn(Mono.just(Boolean.TRUE)).when(featureFlagService).check(Mockito.any()); Mono tableNameMono = datasourceTriggerSolution.trigger( datasourceId, diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/EnvManagerTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/EnvManagerTest.java index ad829c97a6..de9bb7eebe 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/EnvManagerTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/EnvManagerTest.java @@ -11,6 +11,7 @@ import com.appsmith.server.helpers.UserUtils; import com.appsmith.server.notifications.EmailSender; import com.appsmith.server.repositories.UserRepository; import com.appsmith.server.services.AnalyticsService; +import com.appsmith.server.services.AssetService; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.EmailService; import com.appsmith.server.services.PermissionGroupService; @@ -85,6 +86,9 @@ public class EnvManagerTest { @MockBean private ObjectMapper objectMapper; + @MockBean + private AssetService assetService; + @MockBean private EmailService emailService; diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialExportServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialExportServiceTest.java index 9ee328ab6d..2ff253c451 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialExportServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialExportServiceTest.java @@ -7,7 +7,6 @@ import com.appsmith.external.models.Datasource; import com.appsmith.external.models.DatasourceConfiguration; import com.appsmith.external.models.DatasourceStorage; import com.appsmith.external.models.DatasourceStorageDTO; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.Property; import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.datasources.base.DatasourceService; @@ -261,7 +260,7 @@ public class PartialExportServiceTest { // Get the partial export resources Mono partialExportFileDTOMono = partialExportService.getPartialExportResources( - testApplication.getId(), savedPage.getId(), null, partialExportFileDTO); + testApplication.getId(), savedPage.getId(), partialExportFileDTO); StepVerifier.create(partialExportFileDTOMono) .assertNext(applicationJson -> { @@ -290,13 +289,8 @@ public class PartialExportServiceTest { PageDTO savedPage = new PageDTO(); savedPage.setName("Page 2"); savedPage.setApplicationId(application.getId()); - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setApplicationId(application.getId()); - defaultResources.setBranchName("master"); - savedPage.setDefaultResources(defaultResources); - savedPage = applicationPageService - .createPageWithBranchName(savedPage, "master") - .block(); + savedPage.setBranchName("master"); + savedPage = applicationPageService.createPage(savedPage).block(); // Create Action ActionDTO action = new ActionDTO(); @@ -319,7 +313,7 @@ public class PartialExportServiceTest { // Get the partial export resources Mono partialExportFileDTOMono = partialExportService.getPartialExportResources( - application.getId(), savedPage.getId(), "master", partialExportFileDTO); + application.getId(), savedPage.getId(), partialExportFileDTO); StepVerifier.create(partialExportFileDTOMono) .assertNext(applicationJson -> { @@ -355,13 +349,8 @@ public class PartialExportServiceTest { PageDTO savedPage = new PageDTO(); savedPage.setName("Page 2"); savedPage.setApplicationId(application.getId()); - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setApplicationId(application.getId()); - defaultResources.setBranchName("master"); - savedPage.setDefaultResources(defaultResources); - savedPage = applicationPageService - .createPageWithBranchName(savedPage, "master") - .block(); + savedPage.setBranchName("master"); + savedPage = applicationPageService.createPage(savedPage).block(); // Create Action ActionDTO action = new ActionDTO(); @@ -373,11 +362,7 @@ public class PartialExportServiceTest { actionConfiguration.setTimeoutInMillisecond("6000"); action.setActionConfiguration(actionConfiguration); action.setDatasource(datasourceMap.get("DS1")); - DefaultResources defaultResource = new DefaultResources(); - defaultResource.setApplicationId(application.getId()); - defaultResource.setBranchName("master"); - defaultResource.setActionId("testActionId"); - action.setDefaultResources(defaultResource); + action.setBranchName("master"); ActionDTO savedAction = layoutActionService.createSingleAction(action, Boolean.FALSE).block(); @@ -386,11 +371,11 @@ public class PartialExportServiceTest { partialExportFileDTO.setDatasourceList(List.of( datasourceMap.get("DS1").getId(), datasourceMap.get("DS2").getId())); // For a feature branch the resources in the client always get the default resource id - partialExportFileDTO.setActionList(List.of("testActionId")); + partialExportFileDTO.setActionList(List.of(savedAction.getId())); // Get the partial export resources Mono partialExportFileDTOMono = partialExportService.getPartialExportResources( - application.getId(), savedPage.getId(), "master", partialExportFileDTO); + application.getId(), savedPage.getId(), partialExportFileDTO); StepVerifier.create(partialExportFileDTOMono) .assertNext(applicationJson -> { diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialImportServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialImportServiceTest.java index 1efad0723b..218269a72e 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialImportServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialImportServiceTest.java @@ -4,7 +4,6 @@ import com.appsmith.external.models.DBAuth; import com.appsmith.external.models.Datasource; import com.appsmith.external.models.DatasourceConfiguration; import com.appsmith.external.models.DatasourceStorageDTO; -import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.Property; import com.appsmith.server.actioncollections.base.ActionCollectionService; import com.appsmith.server.applications.base.ApplicationService; @@ -332,13 +331,8 @@ public class PartialImportServiceTest { PageDTO savedPage = new PageDTO(); savedPage.setName("Page 2"); savedPage.setApplicationId(application.getId()); - DefaultResources defaultResources = new DefaultResources(); - defaultResources.setApplicationId(application.getId()); - defaultResources.setBranchName("master"); - savedPage.setDefaultResources(defaultResources); - savedPage = applicationPageService - .createPageWithBranchName(savedPage, "master") - .block(); + savedPage.setBranchName("master"); + savedPage = applicationPageService.createPage(savedPage).block(); Part filePart = createFilePart("test_assets/ImportExportServiceTest/partial-export-valid-without-widget.json"); @@ -494,8 +488,8 @@ public class PartialImportServiceTest { buildingBlockDTO1.setTemplateId("templatedId1"); Mono, List>> result = partialImportService - .importBuildingBlock(buildingBlockDTO, null) - .flatMap(s -> partialImportService.importBuildingBlock(buildingBlockDTO1, null)) + .importBuildingBlock(buildingBlockDTO) + .flatMap(s -> partialImportService.importBuildingBlock(buildingBlockDTO1)) .flatMap(buildingBlockResponseDTO -> { return Mono.zip( Mono.just(buildingBlockResponseDTO), diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java index baa2bdc81c..4f0a20df1a 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java @@ -69,6 +69,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; @@ -197,7 +198,7 @@ class ActionExecutionSolutionCEImplTest { @Test public void testExecuteAction_withoutExecuteActionDTOPart_failsValidation() { final Mono actionExecutionResultMono = actionExecutionSolution.executeAction( - Flux.empty(), null, FieldName.UNUSED_ENVIRONMENT_ID, null, Boolean.FALSE); + Flux.empty(), FieldName.UNUSED_ENVIRONMENT_ID, null, Boolean.FALSE); StepVerifier.create(actionExecutionResultMono) .expectErrorMatches(e -> e instanceof AppsmithException @@ -211,17 +212,17 @@ class ActionExecutionSolutionCEImplTest { .contentType(new MediaType("multipart", "form-data", Map.of("boundary", "boundary"))) .body( """ - --boundary\r - Content-Disposition: form-data; name="executeActionDTO"\r - \r - irrelevant content\r - --boundary--\r - """); + --boundary\r + Content-Disposition: form-data; name="executeActionDTO"\r + \r + irrelevant content\r + --boundary--\r + """); final Flux partsFlux = BodyExtractors.toParts().extract(mock, this.context); - final Mono actionExecutionResultMono = actionExecutionSolution.executeAction( - partsFlux, null, FieldName.UNUSED_ENVIRONMENT_ID, null, Boolean.FALSE); + final Mono actionExecutionResultMono = + actionExecutionSolution.executeAction(partsFlux, FieldName.UNUSED_ENVIRONMENT_ID, null, Boolean.FALSE); StepVerifier.create(actionExecutionResultMono) .expectErrorMatches(e -> e instanceof AppsmithException @@ -235,17 +236,17 @@ class ActionExecutionSolutionCEImplTest { .contentType(new MediaType("multipart", "form-data", Map.of("boundary", "boundary"))) .body( """ - --boundary\r - Content-Disposition: form-data; name="executeActionDTO"\r - \r - {"viewMode":false}\r - --boundary--\r - """); + --boundary\r + Content-Disposition: form-data; name="executeActionDTO"\r + \r + {"viewMode":false}\r + --boundary--\r + """); final Flux partsFlux = BodyExtractors.toParts().extract(mock, this.context); final Mono actionExecutionResultMono = - actionExecutionSolution.executeAction(partsFlux, null, null, null, Boolean.FALSE); + actionExecutionSolution.executeAction(partsFlux, null, null, Boolean.FALSE); StepVerifier.create(actionExecutionResultMono) .expectErrorMatches(e -> e instanceof AppsmithException @@ -296,12 +297,10 @@ class ActionExecutionSolutionCEImplTest { .getTrueEnvironmentId( any(), any(), any(), Mockito.eq(environmentPermission.getExecutePermission()), anyBoolean()); doReturn(Mono.just(mockResult)).when(executionSolutionSpy).executeAction(any(), any()); - doReturn(Mono.just(newAction)) - .when(newActionService) - .findByBranchNameAndDefaultActionId(any(), any(), Mockito.anyBoolean(), any()); + doReturn(Mono.just(newAction)).when(newActionService).findById(anyString(), any()); Mono actionExecutionResultMono = - executionSolutionSpy.executeAction(partsFlux, null, null, null, Boolean.FALSE); + executionSolutionSpy.executeAction(partsFlux, null, null, Boolean.FALSE); StepVerifier.create(actionExecutionResultMono) .assertNext(response -> { @@ -356,12 +355,10 @@ class ActionExecutionSolutionCEImplTest { .getTrueEnvironmentId( any(), any(), any(), Mockito.eq(environmentPermission.getExecutePermission()), anyBoolean()); doReturn(Mono.just(mockResult)).when(executionSolutionSpy).executeAction(any(), any()); - doReturn(Mono.just(newAction)) - .when(newActionService) - .findByBranchNameAndDefaultActionId(any(), any(), Mockito.anyBoolean(), any()); + doReturn(Mono.just(newAction)).when(newActionService).findById(anyString(), any()); Mono actionExecutionResultMono = - executionSolutionSpy.executeAction(partsFlux, null, null, null, Boolean.FALSE); + executionSolutionSpy.executeAction(partsFlux, null, null, Boolean.FALSE); StepVerifier.create(actionExecutionResultMono) .assertNext(response -> { diff --git a/app/server/appsmith-server/src/test/resources/test_assets/ActionCollectionServiceTest/mockObjects.json b/app/server/appsmith-server/src/test/resources/test_assets/ActionCollectionServiceTest/mockObjects.json index 4ebfccf806..bbfcf8faba 100644 --- a/app/server/appsmith-server/src/test/resources/test_assets/ActionCollectionServiceTest/mockObjects.json +++ b/app/server/appsmith-server/src/test/resources/test_assets/ActionCollectionServiceTest/mockObjects.json @@ -2,9 +2,6 @@ "newPage": { "id": "testPageId", "applicationId": "testApplicationId", - "defaultResources": { - "pageId" : "testPageId" - }, "unpublishedPage": { "name": "TestPage", "layouts": [ diff --git a/app/server/appsmith-server/src/test/resources/test_assets/ResponseUtilsTest/mockObjects.json b/app/server/appsmith-server/src/test/resources/test_assets/ResponseUtilsTest/mockObjects.json deleted file mode 100644 index 98a7791836..0000000000 --- a/app/server/appsmith-server/src/test/resources/test_assets/ResponseUtilsTest/mockObjects.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "newPage": { - "id": "testPageId", - "applicationId": "testApplicationId", - "defaultResources": { - "pageId" : "defaultTestPageId", - "applicationId": "defaultApplicationId" - } - }, - "newAction": { - "id": "testActionId", - "applicationId": "testApplicationId", - "unpublishedAction": { - "pageId": "testPageId", - "collectionId": "testCollectionId", - "defaultResources": { - "pageId": "defaultTestPageIdUnpublished", - "collectionId": "defaultTestCollectionIdUnpublished" - } - }, - "publishedAction": { - "pageId": "testPageId", - "collectionId": "testCollectionId", - "defaultResources": { - "pageId": "defaultTestPageIdPublished", - "collectionId": "defaultTestCollectionIdPublished" - } - }, - "defaultResources": { - "actionId": "defaultTestActionId", - "applicationId": "defaultApplicationId" - } - }, - "actionCollection": { - "id": "testCollectionId", - "applicationId": "testApplicationId", - "unpublishedCollection": { - "pageId": "testPageIdUnpublished", - "defaultResources": { - "pageId": "defaultTestPageIdUnpublished" - } - }, - "publishedCollection": { - "pageId": "testPageIdPublished", - "defaultResources": { - "pageId": "defaultTestPageIdPublished" - } - }, - "defaultResources": { - "collectionId": "defaultTestCollectionId", - "applicationId": "defaultApplicationId" - } - }, - "application": { - "id": "testApplicationId", - "pages": [ - { - "id" : "testPageId1", - "isDefault": true, - "defaultPageId": "defaultTestPageId1" - }, - { - "id" : "testPageId2", - "isDefault": false, - "defaultPageId": "defaultTestPageId2" - } - ], - "publishedPages": [ - { - "id" : "testPageId1", - "isDefault": false, - "defaultPageId": "defaultTestPageId1" - }, - { - "id" : "testPageId2", - "isDefault": true, - "defaultPageId": "defaultTestPageId2" - } - ] - } -}