name !== "createReactComponent")
- .filter((name) => !name.endsWith("Filled"))
.map((name) => {
content += `\n "${kebabCase(name).replace("icon-", "")}": "${name}",`;
});
diff --git a/app/client/packages/storybook/.storybook/addons/theming/ThemingPopup.tsx b/app/client/packages/storybook/.storybook/addons/theming/ThemingPopup.tsx
index 390763d83558..f7ebfb17dde9 100644
--- a/app/client/packages/storybook/.storybook/addons/theming/ThemingPopup.tsx
+++ b/app/client/packages/storybook/.storybook/addons/theming/ThemingPopup.tsx
@@ -61,8 +61,6 @@ export const ThemingPopup: React.FC
= ({ leftShift, onClose }) => {
setBorderRadius={(value) => updateGlobal("borderRadius", value)}
seedColor={globals.seedColor}
setSeedColor={(value) => updateGlobal("seedColor", value)}
- fontFamily={globals.fontFamily}
- setFontFamily={(value) => updateGlobal("fontFamily", value)}
userDensity={globals.userDensity}
userSizing={globals.userSizing}
setUserDensity={(value) => updateGlobal("userDensity", value)}
diff --git a/app/client/packages/storybook/.storybook/decorators/theming.tsx b/app/client/packages/storybook/.storybook/decorators/theming.tsx
index 23b58e53a837..9efe5e3cd2ec 100644
--- a/app/client/packages/storybook/.storybook/decorators/theming.tsx
+++ b/app/client/packages/storybook/.storybook/decorators/theming.tsx
@@ -18,7 +18,6 @@ export const theming = (Story, args) => {
seedColor: args.globals.seedColor,
colorMode: args.parameters.colorMode || args.globals.colorMode,
borderRadius: args.globals.borderRadius,
- fontFamily: args.globals.fontFamily,
userDensity: args.globals.userDensity,
userSizing: args.globals.userSizing,
});
diff --git a/app/client/packages/storybook/src/components/ThemeSettings.tsx b/app/client/packages/storybook/src/components/ThemeSettings.tsx
index f9b227934de0..b3d77aa3b3db 100644
--- a/app/client/packages/storybook/src/components/ThemeSettings.tsx
+++ b/app/client/packages/storybook/src/components/ThemeSettings.tsx
@@ -2,7 +2,6 @@ import { Form } from "@storybook/components";
import React, { useCallback } from "react";
import { Flex, Text } from "@appsmith/wds";
import { ColorControl, BooleanControl, RangeControl } from "@storybook/blocks";
-import { FONT_METRICS } from "@appsmith/wds-theming";
import styled from "styled-components";
import { debounce } from "lodash";
import { AddonPanel } from "@storybook/components";
@@ -42,12 +41,10 @@ interface ThemeSettingsProps {
export const ThemeSettings = ({
borderRadius,
direction = "column",
- fontFamily,
isDarkMode,
seedColor,
setBorderRadius,
setDarkMode,
- setFontFamily,
setSeedColor,
setUserDensity,
setUserSizing,
@@ -106,36 +103,6 @@ export const ThemeSettings = ({
)}
- {setFontFamily && (
-
- Font Family
- setFontFamily(e.target.value)}
- size="100%"
- title="Font Family"
- >
-
- {Object.keys(FONT_METRICS)
- .filter((item) => {
- return (
- [
- "-apple-system",
- "BlinkMacSystemFont",
- "Segoe UI",
- ].includes(item) === false
- );
- })
- .map((font) => (
-
- ))}
-
-
- )}
-
{setUserDensity && (
Density
diff --git a/app/client/src/PluginActionEditor/PluginActionContext.tsx b/app/client/src/PluginActionEditor/PluginActionContext.tsx
index 0b99f9dc363d..21c76f6c8985 100644
--- a/app/client/src/PluginActionEditor/PluginActionContext.tsx
+++ b/app/client/src/PluginActionEditor/PluginActionContext.tsx
@@ -20,7 +20,7 @@ interface PluginActionContextType {
const PluginActionContext = createContext(null);
interface ChildrenProps {
- children: ReactNode[];
+ children: ReactNode | ReactNode[];
}
export const PluginActionContextProvider = (
diff --git a/app/client/src/PluginActionEditor/PluginActionEditor.tsx b/app/client/src/PluginActionEditor/PluginActionEditor.tsx
index d8e480403064..bfdad62b30b7 100644
--- a/app/client/src/PluginActionEditor/PluginActionEditor.tsx
+++ b/app/client/src/PluginActionEditor/PluginActionEditor.tsx
@@ -18,7 +18,7 @@ import CenteredWrapper from "components/designSystems/appsmith/CenteredWrapper";
import { Text } from "@appsmith/ads";
interface ChildrenProps {
- children: React.ReactNode[];
+ children: React.ReactNode | React.ReactNode[];
}
const PluginActionEditor = (props: ChildrenProps) => {
diff --git a/app/client/src/PluginActionEditor/components/PluginActionToolbar.tsx b/app/client/src/PluginActionEditor/components/PluginActionToolbar.tsx
index ee90ecc960ba..75ee4dc86bd2 100644
--- a/app/client/src/PluginActionEditor/components/PluginActionToolbar.tsx
+++ b/app/client/src/PluginActionEditor/components/PluginActionToolbar.tsx
@@ -1,11 +1,12 @@
import React from "react";
import { IDEToolbar } from "IDE";
-import { Button, Tooltip } from "@appsmith/ads";
-import { modText } from "../../utils/helpers";
+import { Button, Menu, MenuContent, MenuTrigger, Tooltip } from "@appsmith/ads";
+import { modText } from "utils/helpers";
interface PluginActionToolbarProps {
runOptions?: React.ReactNode;
children?: React.ReactNode[] | React.ReactNode;
+ menuContent?: React.ReactNode[] | React.ReactNode;
}
const PluginActionToolbar = (props: PluginActionToolbarProps) => {
@@ -29,12 +30,19 @@ const PluginActionToolbar = (props: PluginActionToolbarProps) => {
size="sm"
startIcon="settings-2-line"
/>
-
+
);
diff --git a/app/client/src/actions/widgetSelectionActions.ts b/app/client/src/actions/widgetSelectionActions.ts
index 092400d49bb8..940a48863746 100644
--- a/app/client/src/actions/widgetSelectionActions.ts
+++ b/app/client/src/actions/widgetSelectionActions.ts
@@ -8,6 +8,7 @@ export interface WidgetSelectionRequestPayload {
payload?: string[];
invokedBy?: NavigationMethod;
basePageId?: string;
+ parentId?: string;
}
export type WidgetSelectionRequest = (
@@ -15,6 +16,7 @@ export type WidgetSelectionRequest = (
payload?: string[],
invokedBy?: NavigationMethod,
basePageId?: string,
+ parentId?: string,
) => ReduxAction;
// Use to select a widget programmatically via platform action
@@ -23,9 +25,10 @@ export const selectWidgetInitAction: WidgetSelectionRequest = (
payload,
invokedBy?: NavigationMethod,
basePageId?: string,
+ parentId?: string,
) => ({
type: ReduxActionTypes.SELECT_WIDGET_INIT,
- payload: { selectionRequestType, payload, basePageId, invokedBy },
+ payload: { selectionRequestType, payload, basePageId, invokedBy, parentId },
});
export interface SetSelectedWidgetsPayload {
diff --git a/app/client/src/ce/pages/Editor/AppPluginActionEditor/AppPluginActionEditor.tsx b/app/client/src/ce/pages/Editor/AppPluginActionEditor/AppPluginActionEditor.tsx
index 6ed514390c08..e5f9366c05c5 100644
--- a/app/client/src/ce/pages/Editor/AppPluginActionEditor/AppPluginActionEditor.tsx
+++ b/app/client/src/ce/pages/Editor/AppPluginActionEditor/AppPluginActionEditor.tsx
@@ -1,17 +1,24 @@
import React from "react";
import {
PluginActionEditor,
- PluginActionToolbar,
PluginActionForm,
PluginActionResponsePane,
} from "PluginActionEditor";
+import {
+ ConvertToModuleDisabler,
+ ConvertToModuleCallout,
+} from "./components/ConvertToModule";
+import AppPluginActionToolbar from "./components/AppPluginActionToolbar";
const AppPluginActionEditor = () => {
return (
-
-
-
+
+
+
+
+
+
);
};
diff --git a/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/AppPluginActionToolbar.tsx b/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/AppPluginActionToolbar.tsx
new file mode 100644
index 000000000000..ab44ba573b3d
--- /dev/null
+++ b/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/AppPluginActionToolbar.tsx
@@ -0,0 +1,9 @@
+import React from "react";
+import { PluginActionToolbar } from "PluginActionEditor";
+import { ConvertToModuleCTA } from "./ConvertToModule";
+
+const AppPluginActionToolbar = () => {
+ return } />;
+};
+
+export default AppPluginActionToolbar;
diff --git a/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/ConvertToModule/ConvertToModuleCTA.tsx b/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/ConvertToModule/ConvertToModuleCTA.tsx
new file mode 100644
index 000000000000..83aac04d90e5
--- /dev/null
+++ b/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/ConvertToModule/ConvertToModuleCTA.tsx
@@ -0,0 +1,35 @@
+import React from "react";
+import { usePluginActionContext } from "PluginActionEditor";
+import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
+import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
+import { useSelector } from "react-redux";
+import { getPagePermissions } from "selectors/editorSelectors";
+import {
+ getHasCreateActionPermission,
+ getHasDeleteActionPermission,
+} from "ee/utils/BusinessFeatures/permissionPageHelpers";
+import { MODULE_TYPE } from "ee/constants/ModuleConstants";
+import ConvertToModuleInstanceCTA from "ee/pages/Editor/EntityEditor/ConvertToModuleInstanceCTA";
+
+const ConvertToModuleCTA = () => {
+ const { action } = usePluginActionContext();
+ const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled);
+ const pagePermissions = useSelector(getPagePermissions);
+ const isCreatePermitted = getHasCreateActionPermission(
+ isFeatureEnabled,
+ pagePermissions,
+ );
+ const isDeletePermitted = getHasDeleteActionPermission(
+ isFeatureEnabled,
+ action.userPermissions,
+ );
+ const convertToModuleProps = {
+ canCreateModuleInstance: isCreatePermitted,
+ canDeleteEntity: isDeletePermitted,
+ entityId: action.id,
+ moduleType: MODULE_TYPE.QUERY,
+ };
+ return ;
+};
+
+export default ConvertToModuleCTA;
diff --git a/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/ConvertToModule/ConvertToModuleCallout.tsx b/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/ConvertToModule/ConvertToModuleCallout.tsx
new file mode 100644
index 000000000000..a58ebc069dd3
--- /dev/null
+++ b/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/ConvertToModule/ConvertToModuleCallout.tsx
@@ -0,0 +1,40 @@
+import React from "react";
+import { Flex, Icon } from "@appsmith/ads";
+import { useSelector } from "react-redux";
+import { getIsActionConverting } from "ee/selectors/entitiesSelector";
+import { usePluginActionContext } from "PluginActionEditor";
+import {
+ ENTITY_ICON_SIZE,
+ EntityIcon,
+} from "pages/Editor/Explorer/ExplorerIcons";
+import ConvertEntityNotification from "ee/pages/common/ConvertEntityNotification";
+import { resolveIcon } from "pages/Editor/utils";
+
+const ConvertToModuleCallout = () => {
+ const { action, plugin } = usePluginActionContext();
+ const isConverting = useSelector((state) =>
+ getIsActionConverting(state, action.id),
+ );
+
+ const PluginIcon = resolveIcon({
+ iconLocation: plugin.iconLocation || "",
+ pluginType: plugin.type,
+ moduleType: action.actionConfiguration?.body?.moduleType,
+ }) || (
+
+
+
+ );
+
+ if (!isConverting) return null;
+ return (
+
+
+
+ );
+};
+
+export default ConvertToModuleCallout;
diff --git a/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/ConvertToModule/ConvertToModuleDisabler.tsx b/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/ConvertToModule/ConvertToModuleDisabler.tsx
new file mode 100644
index 000000000000..26cace30fc06
--- /dev/null
+++ b/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/ConvertToModule/ConvertToModuleDisabler.tsx
@@ -0,0 +1,19 @@
+import React from "react";
+import Disabler from "pages/common/Disabler";
+import { usePluginActionContext } from "PluginActionEditor";
+import { useSelector } from "react-redux";
+import { getIsActionConverting } from "ee/selectors/entitiesSelector";
+
+interface Props {
+ children: React.ReactNode | React.ReactNode[];
+}
+
+const ConvertToModuleDisabler = (props: Props) => {
+ const { action } = usePluginActionContext();
+ const isConverting = useSelector((state) =>
+ getIsActionConverting(state, action.id),
+ );
+ return {props.children};
+};
+
+export default ConvertToModuleDisabler;
diff --git a/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/ConvertToModule/index.tsx b/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/ConvertToModule/index.tsx
new file mode 100644
index 000000000000..c390c4a5dd63
--- /dev/null
+++ b/app/client/src/ce/pages/Editor/AppPluginActionEditor/components/ConvertToModule/index.tsx
@@ -0,0 +1,3 @@
+export { default as ConvertToModuleCTA } from "./ConvertToModuleCTA";
+export { default as ConvertToModuleDisabler } from "./ConvertToModuleDisabler";
+export { default as ConvertToModuleCallout } from "./ConvertToModuleCallout";
diff --git a/app/client/src/constants/AppConstants.ts b/app/client/src/constants/AppConstants.ts
index 8af037a86a97..25bda3ec55eb 100644
--- a/app/client/src/constants/AppConstants.ts
+++ b/app/client/src/constants/AppConstants.ts
@@ -89,7 +89,6 @@ export interface ThemeSetting {
density: number;
sizing: number;
fontFamily: string;
- iconStyle: "FILLED" | "OUTLINED";
appMaxWidth: AppMaxWidth;
}
@@ -129,7 +128,6 @@ export const defaultThemeSetting: ThemeSetting = {
borderRadius: "6px",
density: 1,
sizing: 1,
- iconStyle: "OUTLINED",
appMaxWidth: APP_MAX_WIDTH.Large,
};
diff --git a/app/client/src/pages/AppViewer/index.tsx b/app/client/src/pages/AppViewer/index.tsx
index 8ac8d38e651f..93c87a3e8353 100644
--- a/app/client/src/pages/AppViewer/index.tsx
+++ b/app/client/src/pages/AppViewer/index.tsx
@@ -46,7 +46,6 @@ import {
} from "ee/selectors/applicationSelectors";
import { editorInitializer } from "../../utils/editor/EditorUtils";
import { widgetInitialisationSuccess } from "../../actions/widgetActions";
-import type { FontFamily } from "@appsmith/wds-theming";
import {
ThemeProvider as WDSThemeProvider,
useTheme,
@@ -110,21 +109,15 @@ function AppViewer(props: Props) {
);
const isAnvilLayout = useSelector(getIsAnvilLayout);
const themeSetting = useSelector(getAppThemeSettings);
- const themeProps = {
- borderRadius: selectedTheme.properties.borderRadius.appBorderRadius,
- seedColor: selectedTheme.properties.colors.primaryColor,
- fontFamily: selectedTheme.properties.fontFamily.appFont as FontFamily,
- };
const wdsThemeProps = {
borderRadius: themeSetting.borderRadius,
seedColor: themeSetting.accentColor,
colorMode: themeSetting.colorMode.toLowerCase(),
- fontFamily: themeSetting.fontFamily as FontFamily,
userSizing: themeSetting.sizing,
userDensity: themeSetting.density,
- iconStyle: themeSetting.iconStyle.toLowerCase(),
- };
- const { theme } = useTheme(isAnvilLayout ? wdsThemeProps : themeProps);
+ } as Parameters[0];
+ const { theme } = useTheme(isAnvilLayout ? wdsThemeProps : {});
+
const focusRef = useWidgetFocus();
const isAutoLayout = useSelector(getIsAutoLayout);
diff --git a/app/client/src/pages/Editor/Canvas.tsx b/app/client/src/pages/Editor/Canvas.tsx
index 5d310f366b66..2a25d73b1d5d 100644
--- a/app/client/src/pages/Editor/Canvas.tsx
+++ b/app/client/src/pages/Editor/Canvas.tsx
@@ -56,10 +56,8 @@ const Canvas = (props: CanvasProps) => {
borderRadius: themeSetting.borderRadius,
seedColor: themeSetting.accentColor,
colorMode: themeSetting.colorMode.toLowerCase(),
- fontFamily: themeSetting.fontFamily,
userSizing: themeSetting.sizing,
userDensity: themeSetting.density,
- iconStyle: themeSetting.iconStyle.toLowerCase(),
} as Parameters[0];
// in case of non-WDS theme, we will pass an empty object to useTheme hook
// so that fixedLayout theme does not break because of calculations done in useTheme
diff --git a/app/client/src/pages/Editor/EditorName/components.ts b/app/client/src/pages/Editor/EditorName/components.ts
index b9fb3c7177da..8aaa930f461f 100644
--- a/app/client/src/pages/Editor/EditorName/components.ts
+++ b/app/client/src/pages/Editor/EditorName/components.ts
@@ -7,25 +7,30 @@ import { IDE_HEADER_HEIGHT } from "IDE";
export const Container = styled.div`
display: flex;
cursor: pointer;
+
&:hover {
background-color: var(--ads-v2-color-bg-subtle);
}
+
& .${Classes.EDITABLE_TEXT} {
- height: ${IDE_HEADER_HEIGHT} !important;
+ height: ${IDE_HEADER_HEIGHT}px !important;
display: block;
cursor: pointer;
}
+
&&&& .${Classes.EDITABLE_TEXT}, &&&& .${Classes.EDITABLE_TEXT_EDITING} {
padding: 0;
width: 100%;
}
+
&&&& .${Classes.EDITABLE_TEXT_CONTENT}, &&&& .${Classes.EDITABLE_TEXT_INPUT} {
display: block;
${getTypographyByKey("h5")};
- line-height: ${IDE_HEADER_HEIGHT} !important;
+ line-height: ${IDE_HEADER_HEIGHT}px !important;
padding: 0 ${(props) => props.theme.spaces[2]}px;
- height: ${IDE_HEADER_HEIGHT} !important;
+ height: ${IDE_HEADER_HEIGHT}px !important;
}
+
&&&& .${Classes.EDITABLE_TEXT_INPUT} {
margin-right: 20px;
}
diff --git a/app/client/src/pages/Editor/WDSThemePropertyPane/constants.ts b/app/client/src/pages/Editor/WDSThemePropertyPane/constants.ts
index 87947c97ddaa..06da8ef2964b 100644
--- a/app/client/src/pages/Editor/WDSThemePropertyPane/constants.ts
+++ b/app/client/src/pages/Editor/WDSThemePropertyPane/constants.ts
@@ -45,11 +45,6 @@ export const THEME_SETTINGS_BORDER_RADIUS_OPTIONS = [
{ label: "Pill", value: "20px" },
];
-export const THEME_SETTINGS_ICON_STYLE_OPTIONS = [
- { label: "Filled", value: "FILLED" },
- { label: "Outlined", value: "OUTLINED" },
-];
-
export const THEME_SETTING_COLOR_PRESETS = {
LIGHT: ["#0080ff", "#6b35ff", "#d54137", "#f09326", "#02925c"],
DARK: ["#0080ff", "#5b02ea", "#c12c26", "#e98b11", "#03854e"],
diff --git a/app/client/src/pages/Editor/WDSThemePropertyPane/index.tsx b/app/client/src/pages/Editor/WDSThemePropertyPane/index.tsx
index 5d64737db88a..6143acb5a1b7 100644
--- a/app/client/src/pages/Editor/WDSThemePropertyPane/index.tsx
+++ b/app/client/src/pages/Editor/WDSThemePropertyPane/index.tsx
@@ -1,7 +1,6 @@
import { debounce } from "lodash";
import styled from "styled-components";
import { isValidColor } from "utils/helpers";
-import { FONT_METRICS } from "@appsmith/wds-theming";
import { useDispatch, useSelector } from "react-redux";
import React, { useCallback, useRef, useState } from "react";
import type { ThemeSetting } from "constants/AppConstants";
@@ -13,14 +12,13 @@ import {
LeftIcon,
StyledInputGroup,
} from "components/propertyControls/ColorPickerComponentV2";
-import { SegmentedControl, Tooltip, Select, Option, Icon } from "@appsmith/ads";
+import { SegmentedControl, Tooltip, Icon } from "@appsmith/ads";
import styles from "./styles.module.css";
import {
THEME_SETTINGS_BORDER_RADIUS_OPTIONS,
THEME_SETTINGS_DENSITY_OPTIONS,
- THEME_SETTINGS_ICON_STYLE_OPTIONS,
THEME_SETTINGS_SIZING_OPTIONS,
THEME_SETTINGS_COLOR_MODE_OPTIONS,
THEME_SETTING_COLOR_PRESETS,
@@ -35,14 +33,6 @@ const SubText = styled.p`
color: var(--ads-v2-color-fg);
`;
-const FontText = styled.div`
- border-radius: var(--ads-v2-border-radius);
- border: 1px solid var(--ads-v2-color-border);
- font-size: 11px;
- height: 18px;
- width: 18px;
-`;
-
const buttonGroupOptions = THEME_SETTINGS_BORDER_RADIUS_OPTIONS.map(
(optionKey) => ({
label: (
@@ -185,49 +175,6 @@ function WDSThemePropertyPane() {
-
-
-
-
-
-
{/* Dimensions */}
- {/* Icon Style */}
-
-
- Icon Style
- {
- updateTheme({
- ...theme,
- iconStyle: value as ThemeSetting["iconStyle"],
- });
- }}
- options={THEME_SETTINGS_ICON_STYLE_OPTIONS}
- value={theme.iconStyle}
- />
-
-
-
{/* Layout Style */}
) {
if (!disallowUndo) {
// close property pane after delete
yield put(closePropertyPane());
- yield put(
- selectWidgetInitAction(SelectionRequestType.Unselect, [widgetId]),
- );
+
+ if (isAnvilLayout) {
+ yield put(
+ selectWidgetInitAction(
+ SelectionRequestType.Unselect,
+ [widgetId],
+ undefined,
+ undefined,
+ parentId,
+ ),
+ );
+ } else {
+ yield put(
+ selectWidgetInitAction(SelectionRequestType.Unselect, [widgetId]),
+ );
+ }
+
yield call(postDelete, widgetId, widgetName, otherWidgetsToDelete);
}
}
diff --git a/app/client/src/sagas/WidgetSelectionSagas.ts b/app/client/src/sagas/WidgetSelectionSagas.ts
index 0398c4be37de..48078f270454 100644
--- a/app/client/src/sagas/WidgetSelectionSagas.ts
+++ b/app/client/src/sagas/WidgetSelectionSagas.ts
@@ -66,6 +66,7 @@ function* selectWidgetSaga(action: ReduxAction) {
const {
basePageId,
invokedBy,
+ parentId,
payload = [],
selectionRequestType,
} = action.payload;
@@ -93,8 +94,9 @@ function* selectWidgetSaga(action: ReduxAction) {
// It is possible that the payload is empty.
// These properties can be used for a finding sibling widgets for certain types of selections
const widgetId = payload[0];
- const parentId: string | undefined =
- widgetId in allWidgets ? allWidgets[widgetId].parentId : undefined;
+ const finalParentId: string | undefined =
+ parentId ||
+ (widgetId in allWidgets ? allWidgets[widgetId].parentId : undefined);
if (
widgetId &&
@@ -115,7 +117,7 @@ function* selectWidgetSaga(action: ReduxAction) {
}
case SelectionRequestType.One:
case SelectionRequestType.Create: {
- assertParentId(parentId);
+ assertParentId(finalParentId);
newSelection = selectOneWidget(payload);
break;
}
@@ -124,10 +126,10 @@ function* selectWidgetSaga(action: ReduxAction) {
break;
}
case SelectionRequestType.ShiftSelect: {
- assertParentId(parentId);
+ assertParentId(finalParentId);
const siblingWidgets: string[] = yield select(
getWidgetImmediateChildren,
- parentId,
+ finalParentId,
);
newSelection = shiftSelectWidgets(
payload,
@@ -138,10 +140,10 @@ function* selectWidgetSaga(action: ReduxAction) {
break;
}
case SelectionRequestType.PushPop: {
- assertParentId(parentId);
+ assertParentId(finalParentId);
const siblingWidgets: string[] = yield select(
getWidgetImmediateChildren,
- parentId,
+ finalParentId,
);
newSelection = pushPopWidgetSelection(
payload,
@@ -151,7 +153,16 @@ function* selectWidgetSaga(action: ReduxAction) {
break;
}
case SelectionRequestType.Unselect: {
- newSelection = unselectWidget(payload, selectedWidgets);
+ const isParentExists = finalParentId
+ ? finalParentId in allWidgets
+ : false;
+
+ if (isParentExists) {
+ assertParentId(finalParentId);
+ newSelection = [finalParentId];
+ } else {
+ newSelection = unselectWidget(payload, selectedWidgets);
+ }
break;
}
case SelectionRequestType.All: {
diff --git a/deploy/docker/fs/opt/appsmith/JFR-recording-24-hours.sh b/deploy/docker/fs/opt/appsmith/JFR-recording-24-hours.sh
new file mode 100644
index 000000000000..ea26f0247a51
--- /dev/null
+++ b/deploy/docker/fs/opt/appsmith/JFR-recording-24-hours.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+set -o errexit
+set -o pipefail
+set -o nounset
+set -o noglob
+
+# Define the log file path
+log_dir=$1
+log_file=$log_dir/loop.log
+
+# Ensure the log directory exists
+mkdir -p $log_dir
+
+# Start logging
+echo "Script started at $(date)" > $log_file
+
+echo "Sleep 180 seconds to wait for backend to be ready at $(date)" >> $log_file
+sleep 180
+
+# Run the loop for 24 hours (or 24 attempts)
+for i in {1..24}; do
+ echo "Attempt $i at $(date)" >> $log_file
+
+ location=$log_dir/heap_dumps/ad-hoc-24-hours/${HOSTNAME}/thread-profile/profile-$(date "+%Y_%m_%d_%H_%M_%S")
+ mkdir -p $location
+ echo "Created directory $location" >> $log_file
+
+ # Get the PID of the Java process
+ pid=$(pgrep -f -- "-jar\sserver.jar")
+ echo "Found java process at $pid...." >> $log_file
+ if [ -z "$pid" ]; then
+ echo "Java process not found, skipping this attempt." >> $log_file
+ continue
+ fi
+
+ echo "Found Java PID: $pid" >> $log_file
+
+ # Stop any ongoing JFR recording
+ jcmd $pid JFR.stop name=profile || true
+ echo "Stopped previous JFR recording (if any)" >> $log_file
+
+ # Start a new JFR recording
+ jcmd $pid JFR.start name=profile filename=$location.jfr
+ echo "Started new JFR recording: $location.jfr" >> $log_file
+
+ # Wait for an hour before taking the next thread dump
+ echo "Sleeping for 1 hour..." >> $log_file
+ sleep 3600
+ jcmd $pid JFR.stop name=profile || true
+done >> $log_file 2>&1 &
+
+# Detach the process from the terminal
+echo "Script disowned, running in background." >> $log_file
\ No newline at end of file
diff --git a/deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs b/deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs
index c3a9fd51741b..4e6eeddc25c9 100644
--- a/deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs
+++ b/deploy/docker/fs/opt/appsmith/caddy-reconfigure.mjs
@@ -43,7 +43,7 @@ const parts = []
parts.push(`
{
debug
- admin 127.0.0.1:2019
+ admin 0.0.0.0:2019
persist_config off
acme_ca_root /etc/ssl/certs/ca-certificates.crt
servers {
diff --git a/deploy/docker/fs/opt/appsmith/entrypoint.sh b/deploy/docker/fs/opt/appsmith/entrypoint.sh
index 17eaf3a72dd6..1d5bd59fde6d 100644
--- a/deploy/docker/fs/opt/appsmith/entrypoint.sh
+++ b/deploy/docker/fs/opt/appsmith/entrypoint.sh
@@ -477,6 +477,14 @@ function setup_auto_heal(){
fi
}
+function setup_monitoring(){
+ if [[ ${APPSMITH_MONITORING-} = 1 ]]; then
+ # By default APPSMITH_MONITORING=0
+ # To enable auto heal set APPSMITH_MONITORING=1
+ bash /opt/appsmith/JFR-recording-24-hours.sh $APPSMITH_LOG_DIR 2>&1 &
+ fi
+}
+
print_appsmith_info(){
tr '\n' ' ' < /opt/appsmith/info.json
}
@@ -530,6 +538,7 @@ mkdir -p "$APPSMITH_LOG_DIR"/{supervisor,backend,cron,editor,rts,mongodb,redis,p
setup_auto_heal
capture_infra_details
+setup_monitoring || echo true
# Handle CMD command
exec "$@"
diff --git a/deploy/docker/fs/opt/appsmith/utils/bin/utils.js b/deploy/docker/fs/opt/appsmith/utils/bin/utils.js
index 997ab2fbaf6a..8b70980adc0c 100644
--- a/deploy/docker/fs/opt/appsmith/utils/bin/utils.js
+++ b/deploy/docker/fs/opt/appsmith/utils/bin/utils.js
@@ -38,7 +38,7 @@ function getDburl() {
let env_array = fs.readFileSync(Constants.ENV_PATH, 'utf8').toString().split("\n");
for (let i in env_array) {
if (env_array[i].startsWith("APPSMITH_MONGODB_URI") || env_array[i].startsWith("APPSMITH_DB_URL")) {
- dbUrl = env_array[i].toString().split("=")[1];
+ dbUrl = env_array[i].toString().split("=")[1].trim();
break; // Break early when the desired line is found
}
}
@@ -48,7 +48,7 @@ function getDburl() {
let dbEnvUrl = process.env.APPSMITH_DB_URL || process.env.APPSMITH_MONGO_DB_URI;
// Make sure dbEnvUrl takes precedence over dbUrl
if (dbEnvUrl && dbEnvUrl !== "undefined") {
- dbUrl = dbEnvUrl;
+ dbUrl = dbEnvUrl.trim();
}
return dbUrl;
}