Skip to content

Commit 26fe7c1

Browse files
authored
Merge pull request #41946 from appsmithorg/release
06/07 - Daily Promotion
2 parents b58a464 + 477e66c commit 26fe7c1

65 files changed

Lines changed: 2346 additions & 147 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test-storybook.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ jobs:
4444
4545
- name: Storybook Tests
4646
working-directory: ./app/client/packages/storybook
47+
env:
48+
# The Storybook test-runner (Jest + Playwright over every story) exceeds
49+
# Node's ~2GB default old-space heap on the runner and OOMs (exit 129).
50+
# Raise the limit; the runner has ample RAM.
51+
NODE_OPTIONS: --max-old-space-size=8192
4752
run: |
4853
yarn build-storybook
4954
yarn test-storybook:ci

app/client/cypress/support/Objects/FeatureFlags.ts

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,50 @@ const defaultFlags = {
1111
export const featureFlagIntercept = (
1212
flags: Record<string, boolean> = {},
1313
reload = true,
14+
// When true, the requested flags are OVERLAID on the real feature flags from the
15+
// backend instead of REPLACING them. The replace behavior drops every flag the test
16+
// didn't list — including editor-infrastructure flags (e.g. release_app_sidebar_enabled)
17+
// that the IDE needs to render at all. Tests that open the full editor (Anvil/AI) must
18+
// preserve those, or the editor never mounts (.t--sidebar-Editor never appears).
19+
preserveOtherFlags = false,
1420
) => {
15-
getConsolidatedDataApi({ ...flags, ...defaultFlags }, false);
16-
const response = {
17-
responseMeta: {
18-
status: 200,
19-
success: true,
20-
},
21-
data: {
22-
...flags,
23-
...defaultFlags,
24-
},
25-
errorDisplay: "",
26-
};
27-
cy.intercept("GET", "/api/v1/users/features", response);
21+
getConsolidatedDataApi(
22+
{ ...flags, ...defaultFlags },
23+
false,
24+
preserveOtherFlags,
25+
);
26+
if (preserveOtherFlags) {
27+
cy.intercept("GET", "/api/v1/users/features", (req) => {
28+
req.reply((res: any) => {
29+
const original = res?.body?.data ?? {};
30+
res.send({
31+
responseMeta: { status: 200, success: true },
32+
data: { ...original, ...flags, ...defaultFlags },
33+
errorDisplay: "",
34+
});
35+
});
36+
});
37+
} else {
38+
const response = {
39+
responseMeta: {
40+
status: 200,
41+
success: true,
42+
},
43+
data: {
44+
...flags,
45+
...defaultFlags,
46+
},
47+
errorDisplay: "",
48+
};
49+
cy.intercept("GET", "/api/v1/users/features", response);
50+
}
2851
if (reload) ObjectsRegistry.AggregateHelper.CypressReload();
2952
};
3053

3154
export const getConsolidatedDataApi = (
3255
flags: Record<string, boolean> = {},
3356
reload = true,
57+
preserveOtherFlags = false,
3458
) => {
3559
cy.intercept("GET", "/api/v1/consolidated-api/*?*", (req) => {
3660
delete req.headers["if-none-match"];
@@ -43,7 +67,9 @@ export const getConsolidatedDataApi = (
4367
const originalResponse = res?.body;
4468
try {
4569
const updatedResponse = JSON.parse(JSON.stringify(originalResponse));
46-
updatedResponse.data.featureFlags.data = { ...flags };
70+
updatedResponse.data.featureFlags.data = preserveOtherFlags
71+
? { ...updatedResponse.data.featureFlags.data, ...flags }
72+
: { ...flags };
4773
return res.send(updatedResponse);
4874
} catch (e) {
4975
cy.log(`Featureflags.ts error `, e);

app/client/package.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,14 @@
417417
"fast-csv": "4.3.6",
418418
"json-schema": "0.4.0",
419419
"node-fetch": "2.6.7",
420-
"minimatch": "^5.1.8",
420+
"minimatch@^3.0.3": "^5.1.8",
421+
"minimatch@^3.0.4": "^5.1.8",
422+
"minimatch@^3.0.5": "^5.1.8",
423+
"minimatch@^3.1.1": "^5.1.8",
424+
"minimatch@^3.1.2": "^5.1.8",
425+
"minimatch@~3.0.2": "^5.1.8",
426+
"minimatch@~3.0.4": "^5.1.8",
427+
"minimatch@3.0.4": "^5.1.8",
421428
"loader-utils": "^2.0.4",
422429
"json5": "2.2.3",
423430
"dns-packet": "5.4.0",
@@ -480,6 +487,7 @@
480487
"joi": "^18.2.1",
481488
"ws@^6.1.0": "6.2.4",
482489
"launch-editor": "2.14.1",
483-
"@babel/core": "7.29.6"
490+
"@babel/core": "7.29.6",
491+
"http-proxy-middleware": "2.0.10"
484492
}
485493
}

app/client/src/PluginActionEditor/components/PluginActionResponse/components/BindDataButton.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,9 @@ function getWidgetProps(
160160
parentRowSpace: 10,
161161
};
162162
case "TABLE_WIDGET_V2":
163+
case "WDS_TABLE_WIDGET":
163164
return {
164-
type: "TABLE_WIDGET_V2",
165+
type: suggestedWidget.type,
165166
props: {
166167
[fieldName]: `{{${actionName}.${suggestedWidget.bindingQuery}}}`,
167168
dynamicBindingPathList: [{ key: "tableData" }],
@@ -276,11 +277,16 @@ function BindDataButton(props: BindDataButtonProps) {
276277
const isAnvilLayout = useSelector(getIsAnvilLayout);
277278
// The purpose of this filter is to make sure that if Anvil is enabled
278279
// only those widgets which have an alternative in Anvil are listed
279-
// for selection for adding a new suggested widget
280+
// for selection for adding a new suggested widget. A suggestion survives
281+
// the filter if it is a legacy type with a WDS counterpart (a map key,
282+
// e.g. TABLE_WIDGET_V2) or already a WDS type (a map value, e.g.
283+
// WDS_TABLE_WIDGET).
280284
const filteredSuggestedWidgets =
281285
isAnvilLayout && suggestedWidgets
282-
? suggestedWidgets.filter((each) =>
283-
Object.keys(WDS_V2_WIDGET_MAP).includes(each.type),
286+
? suggestedWidgets.filter(
287+
(each) =>
288+
Object.keys(WDS_V2_WIDGET_MAP).includes(each.type) ||
289+
Object.values(WDS_V2_WIDGET_MAP).includes(each.type),
284290
)
285291
: suggestedWidgets;
286292

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
2+
import type {
3+
CopyEntityToAppPayload,
4+
CopyToAppModalEntity,
5+
} from "pages/Editor/Explorer/CopyToApp/types";
6+
7+
export const openCopyToAppModal = (payload: CopyToAppModalEntity) => ({
8+
type: ReduxActionTypes.OPEN_COPY_ENTITY_TO_APP_MODAL,
9+
payload,
10+
});
11+
12+
export const closeCopyToAppModal = () => ({
13+
type: ReduxActionTypes.CLOSE_COPY_ENTITY_TO_APP_MODAL,
14+
});
15+
16+
export const copyActionToApp = (payload: CopyEntityToAppPayload) => ({
17+
type: ReduxActionTypes.COPY_ACTION_TO_APP_INIT,
18+
payload,
19+
});
20+
21+
export const copyJSActionToApp = (payload: CopyEntityToAppPayload) => ({
22+
type: ReduxActionTypes.COPY_JS_ACTION_TO_APP_INIT,
23+
payload,
24+
});
25+
26+
export const fetchAppsForCopyTarget = (workspaceId: string) => ({
27+
type: ReduxActionTypes.FETCH_COPY_TARGET_APPLICATIONS_INIT,
28+
payload: { workspaceId },
29+
});
30+
31+
export const fetchPagesForCopyTarget = (applicationId: string) => ({
32+
type: ReduxActionTypes.FETCH_COPY_TARGET_PAGES_INIT,
33+
payload: { applicationId },
34+
});

app/client/src/ce/constants/ReduxActionConstants.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,17 @@ const ImportExportActionTypes = {
223223
PARTIAL_EXPORT_MODAL_OPEN: "PARTIAL_EXPORT_MODAL_OPEN",
224224
PARTIAL_EXPORT_INIT: "PARTIAL_EXPORT_INIT",
225225
PARTIAL_EXPORT_SUCCESS: "PARTIAL_EXPORT_SUCCESS",
226+
OPEN_COPY_ENTITY_TO_APP_MODAL: "OPEN_COPY_ENTITY_TO_APP_MODAL",
227+
CLOSE_COPY_ENTITY_TO_APP_MODAL: "CLOSE_COPY_ENTITY_TO_APP_MODAL",
228+
COPY_ACTION_TO_APP_INIT: "COPY_ACTION_TO_APP_INIT",
229+
COPY_ACTION_TO_APP_SUCCESS: "COPY_ACTION_TO_APP_SUCCESS",
230+
COPY_JS_ACTION_TO_APP_INIT: "COPY_JS_ACTION_TO_APP_INIT",
231+
COPY_JS_ACTION_TO_APP_SUCCESS: "COPY_JS_ACTION_TO_APP_SUCCESS",
232+
FETCH_COPY_TARGET_APPLICATIONS_INIT: "FETCH_COPY_TARGET_APPLICATIONS_INIT",
233+
FETCH_COPY_TARGET_APPLICATIONS_SUCCESS:
234+
"FETCH_COPY_TARGET_APPLICATIONS_SUCCESS",
235+
FETCH_COPY_TARGET_PAGES_INIT: "FETCH_COPY_TARGET_PAGES_INIT",
236+
FETCH_COPY_TARGET_PAGES_SUCCESS: "FETCH_COPY_TARGET_PAGES_SUCCESS",
226237
IMPORT_APPLICATION_INIT: "IMPORT_APPLICATION_INIT",
227238
IMPORT_APPLICATION_FROM_GIT_INIT: "IMPORT_APPLICATION_FROM_GIT_INIT",
228239
IMPORT_APPLICATION_SUCCESS: "IMPORT_APPLICATION_SUCCESS",
@@ -233,6 +244,10 @@ const ImportExportActionErrorTypes = {
233244
IMPORT_APPLICATION_ERROR: "IMPORT_APPLICATION_ERROR",
234245
PARTIAL_IMPORT_ERROR: "PARTIAL_IMPORT_ERROR",
235246
PARTIAL_EXPORT_ERROR: "PARTIAL_EXPORT_ERROR",
247+
COPY_ACTION_TO_APP_ERROR: "COPY_ACTION_TO_APP_ERROR",
248+
COPY_JS_ACTION_TO_APP_ERROR: "COPY_JS_ACTION_TO_APP_ERROR",
249+
FETCH_COPY_TARGET_APPLICATIONS_ERROR: "FETCH_COPY_TARGET_APPLICATIONS_ERROR",
250+
FETCH_COPY_TARGET_PAGES_ERROR: "FETCH_COPY_TARGET_PAGES_ERROR",
236251
};
237252

238253
const ImportGitActionTypes = {

app/client/src/ce/constants/messages.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ export const FIXED_APPLICATIONS = () => `Classic Applications`;
219219
export const AI_AGENTS_APPLICATIONS = () => `AI Agents`;
220220
export const AI_APPLICATION_CARD_LIST_ZERO_STATE = () =>
221221
`There are no AI Agents in this workspace.`;
222+
export const ANVIL_APPLICATIONS = () => `Anvil apps`;
223+
export const ANVIL_APPLICATION_CARD_LIST_ZERO_STATE = () =>
224+
`There are no Anvil apps in this workspace yet.`;
225+
export const NEW_ANVIL_APP = () => `Anvil app`;
222226
export const AI_AGENT_AUTH_SUBTITLE = () =>
223227
`Sign up with any Google account.\n Support for email will be available soon.`;
224228

@@ -1841,6 +1845,7 @@ export const CONTEXT_RENAME = () => "Rename";
18411845
export const CONTEXT_SHOW_BINDING = () => "Show bindings";
18421846
export const CONTEXT_MOVE = () => "Move to page";
18431847
export const CONTEXT_COPY = () => "Copy to page";
1848+
export const CONTEXT_COPY_TO_APP = () => "Copy to application";
18441849
export const CONTEXT_DUPLICATE = () => "Duplicate";
18451850
export const CONTEXT_DELETE = () => "Delete";
18461851
export const CONFIRM_CONTEXT_DELETE = () => "Are you sure?";
@@ -1924,6 +1929,32 @@ export const FORK_APP_MODAL_SUCCESS_TITLE = () =>
19241929
"Choose where to fork the app";
19251930
export const FORK = () => `Fork`;
19261931

1932+
export const COPY_ENTITY_TO_APP_MODAL_TITLE = () => "Copy to application";
1933+
export const COPY_ENTITY_TO_APP_WORKSPACE_LABEL = () => "Workspace";
1934+
export const COPY_ENTITY_TO_APP_APPLICATION_LABEL = () => "Application";
1935+
export const COPY_ENTITY_TO_APP_PAGE_LABEL = () => "Page";
1936+
export const COPY_ENTITY_TO_APP_WORKSPACE_PLACEHOLDER = () =>
1937+
"Select a workspace";
1938+
export const COPY_ENTITY_TO_APP_APPLICATION_PLACEHOLDER = () =>
1939+
"Select an application";
1940+
export const COPY_ENTITY_TO_APP_PAGE_PLACEHOLDER = () => "Select a page";
1941+
export const COPY_ENTITY_TO_APP_CONFIRM = () => "Copy";
1942+
export const COPY_ENTITY_TO_APP_NO_WORKSPACES = () =>
1943+
"No workspaces available to copy to";
1944+
export const COPY_ENTITY_TO_APP_NO_APPS = () =>
1945+
"No applications available in this workspace";
1946+
export const COPY_ENTITY_TO_APP_NO_PAGES = () =>
1947+
"No pages available in this application";
1948+
export const COPY_ENTITY_TO_APP_SUCCESS = (
1949+
entityName: string,
1950+
appName: string,
1951+
pageName: string,
1952+
) => `Copied ${entityName} to ${appName} / ${pageName}`;
1953+
export const COPY_ENTITY_TO_APP_ERROR = () =>
1954+
"Failed to copy to the selected application";
1955+
export const COPY_ENTITY_TO_APP_NOTE = () =>
1956+
"Datasource credentials and any referenced queries aren't copied. Datasources are set up during import, but you may need to re-enter credentials and recreate any referenced queries before the copied item will work in the target application.";
1957+
19271958
export const CLEAN_URL_UPDATE = {
19281959
name: () => "Update URLs",
19291960
shortDesc: () =>

app/client/src/ce/entities/FeatureFlag.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const FEATURE_FLAG = {
1717
"release_show_publish_app_to_community_enabled",
1818
license_gac_enabled: "license_gac_enabled",
1919
release_anvil_enabled: "release_anvil_enabled",
20+
license_anvil_enabled: "license_anvil_enabled",
2021
license_ai_agent_enabled: "license_ai_agent_enabled",
2122
license_git_branch_protection_enabled:
2223
"license_git_branch_protection_enabled",
@@ -87,6 +88,7 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = {
8788
release_show_publish_app_to_community_enabled: false,
8889
license_gac_enabled: false,
8990
release_anvil_enabled: false,
91+
license_anvil_enabled: false,
9092
license_ai_agent_enabled: false,
9193
release_drag_drop_building_blocks_enabled: false,
9294
license_git_branch_protection_enabled: false,

app/client/src/ce/pages/AppIDE/components/AppIDEModals.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { PartialExportModal } from "components/editorComponents/PartialImportExp
88
import { PartialImportModal } from "components/editorComponents/PartialImportExport/PartialImportModal";
99
import { AppCURLImportModal } from "ee/pages/Editor/CurlImport";
1010
import GeneratePageModal from "pages/Editor/GeneratePage";
11+
import CopyEntityToAppModal from "pages/Editor/Explorer/CopyToApp/CopyEntityToAppModal";
1112

1213
export function AppIDEModals() {
1314
return (
@@ -21,6 +22,7 @@ export function AppIDEModals() {
2122
<PartialImportModal />
2223
<AppCURLImportModal />
2324
<GeneratePageModal />
25+
<CopyEntityToAppModal />
2426
</>
2527
);
2628
}

app/client/src/ce/pages/Applications/WorkspaceAction.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
createMessage,
1818
} from "ee/constants/messages";
1919
import type { Workspace } from "ee/constants/workspaceConstants";
20+
import type { LayoutSystemTypes } from "layoutSystems/types";
2021
import { getIsCreatingApplicationByWorkspaceId } from "ee/selectors/applicationSelectors";
2122
import { getIsFetchingApplications } from "ee/selectors/selectedWorkspaceSelectors";
2223
import { hasCreateNewAppPermission } from "ee/utils/permissionHelpers";
@@ -27,7 +28,10 @@ export interface WorkspaceActionProps {
2728
isMobile: boolean;
2829
enableImportExport: boolean;
2930
workspaceId: string;
30-
onCreateNewApplication: (workspaceId: string) => void;
31+
onCreateNewApplication: (
32+
workspaceId: string,
33+
layoutSystemType?: LayoutSystemTypes,
34+
) => void;
3135
onStartFromTemplate: (workspaceId: string) => void;
3236
setSelectedWorkspaceIdForImportApplication: (workspaceId?: string) => void;
3337
}

0 commit comments

Comments
 (0)