diff --git a/app/client/packages/design-system/theming/src/color/src/LightModeTheme.ts b/app/client/packages/design-system/theming/src/color/src/LightModeTheme.ts index 6b480526ea..5840db599d 100644 --- a/app/client/packages/design-system/theming/src/color/src/LightModeTheme.ts +++ b/app/client/packages/design-system/theming/src/color/src/LightModeTheme.ts @@ -1063,7 +1063,7 @@ export class LightModeTheme implements ColorModeTheme { // Slightly subtler version of neutral border, used in outlined buttons const color = this.bdNeutral.clone(); - color.oklch.l += 0.47; + color.oklch.l += 0.35; return color; } diff --git a/app/client/src/ce/components/formControls/AIChatIntegrationsControl.tsx b/app/client/src/ce/components/formControls/AIChatIntegrationsControl.tsx new file mode 100644 index 0000000000..39a0550f3f --- /dev/null +++ b/app/client/src/ce/components/formControls/AIChatIntegrationsControl.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import BaseControl, { + type ControlProps, +} from "components/formControls/BaseControl"; +import type { ControlType } from "constants/PropertyControlConstants"; + +interface AIChatIntegrationsControlProps extends ControlProps {} + +class AIChatIntegrationsControl extends BaseControl { + getControlType(): ControlType { + return "AI_CHAT_INTEGRATIONS_FORM"; + } + public render() { + return
AIChatIntegrationsControl
; + } +} + +export default AIChatIntegrationsControl; diff --git a/app/client/src/ce/components/formControls/index.ts b/app/client/src/ce/components/formControls/index.ts new file mode 100644 index 0000000000..977f194275 --- /dev/null +++ b/app/client/src/ce/components/formControls/index.ts @@ -0,0 +1 @@ +export { default } from "./AIChatIntegrationsControl"; diff --git a/app/client/src/ce/constants/messages.ts b/app/client/src/ce/constants/messages.ts index 2f7ab65da9..29e43ab5dd 100644 --- a/app/client/src/ce/constants/messages.ts +++ b/app/client/src/ce/constants/messages.ts @@ -1627,6 +1627,8 @@ export const PROPERTY_PANE_EMPTY_SEARCH_RESULT_MESSAGE = "No properties found based on your search"; export const PROPERTY_SEARCH_INPUT_PLACEHOLDER = "Search for controls, labels etc"; +export const PROPERTY_PANE_TITLE_RENAME_DISABLED = () => + "This widget cannot be renamed"; export const EXPLORER_BETA_ENTITY = () => "BETA"; export const BINDING_WIDGET_WALKTHROUGH_TITLE = () => "Widget properties"; export const BINDING_WIDGET_WALKTHROUGH_DESC = () => diff --git a/app/client/src/ce/entities/FeatureFlag.ts b/app/client/src/ce/entities/FeatureFlag.ts index c9ed5ba670..63f151e0e7 100644 --- a/app/client/src/ce/entities/FeatureFlag.ts +++ b/app/client/src/ce/entities/FeatureFlag.ts @@ -58,6 +58,8 @@ export const FEATURE_FLAG = { release_git_package_enabled: "release_git_package_enabled", license_external_saas_plugins_enabled: "license_external_saas_plugins_enabled", + release_computation_cache_enabled: "release_computation_cache_enabled", + release_ai_chat_integrations_enabled: "release_ai_chat_integrations_enabled", } as const; export type FeatureFlag = keyof typeof FEATURE_FLAG; @@ -106,6 +108,8 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = { release_table_custom_sort_function_enabled: false, release_git_package_enabled: false, license_external_saas_plugins_enabled: false, + release_computation_cache_enabled: false, + release_ai_chat_integrations_enabled: false, }; export const AB_TESTING_EVENT_KEYS = { diff --git a/app/client/src/ee/components/formControls/AIChatIntegrationsControl/index.ts b/app/client/src/ee/components/formControls/AIChatIntegrationsControl/index.ts new file mode 100644 index 0000000000..eb7d8e90e0 --- /dev/null +++ b/app/client/src/ee/components/formControls/AIChatIntegrationsControl/index.ts @@ -0,0 +1 @@ +export { default } from "ce/components/formControls/AIChatIntegrationsControl"; diff --git a/app/client/src/pages/Editor/PropertyPane/PropertyPaneTitle.tsx b/app/client/src/pages/Editor/PropertyPane/PropertyPaneTitle.tsx index 21ee25646f..8b059c69f3 100644 --- a/app/client/src/pages/Editor/PropertyPane/PropertyPaneTitle.tsx +++ b/app/client/src/pages/Editor/PropertyPane/PropertyPaneTitle.tsx @@ -23,6 +23,10 @@ import { getIsCurrentWidgetRecentlyAdded, getPropertyPaneWidth, } from "selectors/propertyPaneSelectors"; +import { + createMessage, + PROPERTY_PANE_TITLE_RENAME_DISABLED, +} from "ee/constants/messages"; interface PropertyPaneTitleProps { title: string; @@ -31,6 +35,7 @@ interface PropertyPaneTitleProps { updatePropertyTitle?: (title: string) => void; onBackClick?: () => void; isPanelTitle?: boolean; + isRenameDisabled?: boolean; actions: Array<{ tooltipContent: string; icon: ReactElement; @@ -186,22 +191,36 @@ const PropertyPaneTitle = memo(function PropertyPaneTitle( className="flex-grow" onKeyDown={handleTabKeyDown} > - + {props.isRenameDisabled ? ( +
+ +
{name}
+
+
+ ) : ( + + )} {/* ACTIONS */} diff --git a/app/client/src/pages/Editor/PropertyPane/PropertyPaneView.tsx b/app/client/src/pages/Editor/PropertyPane/PropertyPaneView.tsx index c6143c68bb..f1663bc579 100644 --- a/app/client/src/pages/Editor/PropertyPane/PropertyPaneView.tsx +++ b/app/client/src/pages/Editor/PropertyPane/PropertyPaneView.tsx @@ -287,6 +287,7 @@ function PropertyPaneView( > [string], +) => config.type.startsWith("MODULE_WIDGET_"); + export const getWidgetCards = createSelector( getIsAutoLayout, getIsAnvilLayout, @@ -357,7 +361,7 @@ export const getWidgetCards = createSelector( return config.widgetName !== "Map" && !config.hideCard; } - return !config.hideCard; + return !config.hideCard && !isModuleWidget(config); }); const _cards: WidgetCardProps[] = cards.map((config) => { diff --git a/app/client/src/utils/formControl/FormControlRegistry.tsx b/app/client/src/utils/formControl/FormControlRegistry.tsx index 06ae0c609c..0dc64d91a7 100644 --- a/app/client/src/utils/formControl/FormControlRegistry.tsx +++ b/app/client/src/utils/formControl/FormControlRegistry.tsx @@ -56,6 +56,7 @@ import { AiChatSystemInstructionsControl, type AiChatSystemInstructionsControlProps, } from "components/formControls/AIChatSystemInstructionsControl"; +import AIChatIntegrationsControl from "ee/components/formControls/AIChatIntegrationsControl"; /** * NOTE: If you are adding a component that uses FormControl @@ -253,6 +254,14 @@ class FormControlRegistry { }, }, ); + FormControlFactory.registerControlBuilder( + formControlTypes.AI_CHAT_INTEGRATIONS_FORM, + { + buildPropertyControl(controlProps): JSX.Element { + return ; + }, + }, + ); FormControlFactory.registerControlBuilder( formControlTypes.DATASOURCE_LINK, { diff --git a/app/client/src/utils/formControl/formControlTypes.ts b/app/client/src/utils/formControl/formControlTypes.ts index 7564fd922d..c5f9468aff 100644 --- a/app/client/src/utils/formControl/formControlTypes.ts +++ b/app/client/src/utils/formControl/formControlTypes.ts @@ -27,4 +27,5 @@ export default { DATASOURCE_LINK: "DATASOURCE_LINK", CUSTOM_ACTIONS_CONFIG_FORM: "CUSTOM_ACTIONS_CONFIG_FORM", AI_CHAT_SYSTEM_INSTRUCTIONS: "AI_CHAT_SYSTEM_INSTRUCTIONS", + AI_CHAT_INTEGRATIONS_FORM: "AI_CHAT_INTEGRATIONS_FORM", }; diff --git a/app/client/src/utils/hooks/useFeatureFlagOverride.ts b/app/client/src/utils/hooks/useFeatureFlagOverride.ts index ab30f18f42..03dbe071a0 100644 --- a/app/client/src/utils/hooks/useFeatureFlagOverride.ts +++ b/app/client/src/utils/hooks/useFeatureFlagOverride.ts @@ -16,6 +16,7 @@ export const AvailableFeaturesToOverride: FeatureFlag[] = [ "release_anvil_enabled", "release_layout_conversion_enabled", "license_ai_agent_enabled", + "release_ai_chat_integrations_enabled", ]; export type OverriddenFeatureFlags = Partial>; diff --git a/app/client/src/workers/common/AppComputationCache/AppComputationCache.test.ts b/app/client/src/workers/common/AppComputationCache/AppComputationCache.test.ts index 223097799c..5f6369dc74 100644 --- a/app/client/src/workers/common/AppComputationCache/AppComputationCache.test.ts +++ b/app/client/src/workers/common/AppComputationCache/AppComputationCache.test.ts @@ -7,6 +7,8 @@ import { APP_MODE } from "entities/App"; import localforage from "localforage"; import loglevel from "loglevel"; import { AppComputationCache } from "./index"; +import { WorkerEnv } from "workers/Evaluation/handlers/workerEnv"; +import type { FeatureFlags } from "ee/entities/FeatureFlag"; jest.useFakeTimers(); @@ -68,6 +70,9 @@ describe("AppComputationCache", () => { beforeEach(() => { jest.clearAllMocks(); AppComputationCache.resetInstance(); + WorkerEnv.setFeatureFlags({ + release_computation_cache_enabled: true, + } as FeatureFlags); // Now instantiate the singleton after mocks are set up appComputationCache = AppComputationCache.getInstance(); diff --git a/app/client/src/workers/common/AppComputationCache/index.ts b/app/client/src/workers/common/AppComputationCache/index.ts index f872a6b6c8..7b1a2b926b 100644 --- a/app/client/src/workers/common/AppComputationCache/index.ts +++ b/app/client/src/workers/common/AppComputationCache/index.ts @@ -9,6 +9,7 @@ import { } from "./types"; import debounce from "lodash/debounce"; import { isFinite, isNumber, isString } from "lodash"; +import { WorkerEnv } from "workers/Evaluation/handlers/workerEnv"; interface ICachedData { value: T; @@ -82,6 +83,12 @@ export class AppComputationCache { 5000, ); + isComputationCacheFeatureEnabled() { + const featureFlags = WorkerEnv.getFeatureFlags(); + + return featureFlags["release_computation_cache_enabled"] || false; + } + /** * Check if the computation result should be cached based on the app mode configuration * @returns - A boolean indicating whether the cache should be enabled for the given app mode @@ -95,7 +102,8 @@ export class AppComputationCache { if ( !this.isAppModeValid(appMode) || !this.isTimestampValid(timestamp) || - !this.isDSLVersionValid(dslVersion) + !this.isDSLVersionValid(dslVersion) || + !this.isComputationCacheFeatureEnabled() ) { return false; } 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 e36eea10f8..2aa964d5c4 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 @@ -1268,7 +1268,12 @@ public class FileUtilsCEImpl implements FileInterface { @Override public Mono reconstructPageFromGitRepo( - String pageName, String branchName, Path baseRepoSuffixPath, Boolean resetToLastCommitRequired) { + String pageName, + String branchName, + Path baseRepoSuffixPath, + Boolean resetToLastCommitRequired, + Boolean useFSGitHandler, + Boolean keepWorkingDirChanges) { Mono pageObjectMono; try { Mono resetToLastCommit = Mono.just(Boolean.TRUE); @@ -1276,7 +1281,12 @@ public class FileUtilsCEImpl implements FileInterface { if (Boolean.TRUE.equals(resetToLastCommitRequired)) { // instead of checking out to last branch we are first cleaning the git repo, // then checking out to the desired branch - resetToLastCommit = gitExecutor.resetToLastCommit(baseRepoSuffixPath, branchName, false); + if (Boolean.TRUE.equals(useFSGitHandler)) { + resetToLastCommit = + fsGitHandler.resetToLastCommit(baseRepoSuffixPath, branchName, keepWorkingDirChanges); + } else { + resetToLastCommit = gitExecutor.resetToLastCommit(baseRepoSuffixPath, branchName, true); + } } pageObjectMono = resetToLastCommit.map(isSwitched -> { diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java index fcb8ab2c15..5aa764d353 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java @@ -24,6 +24,7 @@ public enum FeatureFlagEnum { * Feature flag to detect if the RTS git reset is enabled */ ab_rts_git_reset_enabled, + release_git_api_contracts_enabled, // Deprecated CE flags over here release_git_autocommit_feature_enabled, 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 7d4443f9a2..9203832403 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 @@ -80,7 +80,12 @@ public interface FileInterface { Mono reconstructPackageJsonFromGitRepository(Path repoSuffix); Mono reconstructPageFromGitRepo( - String pageName, String branchName, Path repoSuffixPath, Boolean checkoutRequired); + String pageName, + String branchName, + Path repoSuffixPath, + Boolean checkoutRequired, + Boolean useFSGitHandler, + Boolean keepWorkingDirChanges); /** * Once the user connects the existing application to a remote repo, we will initialize the repo with Readme.md - diff --git a/app/server/appsmith-plugins/snowflakePlugin/pom.xml b/app/server/appsmith-plugins/snowflakePlugin/pom.xml index 30c9245c3a..b91626e575 100644 --- a/app/server/appsmith-plugins/snowflakePlugin/pom.xml +++ b/app/server/appsmith-plugins/snowflakePlugin/pom.xml @@ -18,7 +18,7 @@ net.snowflake snowflake-jdbc - 3.22.0 + 3.23.1 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 fdeae3e1ba..3d52dd1239 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 @@ -933,6 +933,9 @@ public class CommonGitFileUtilsCE { String defaultArtifactId = gitArtifactMetadata.getDefaultArtifactId(); String refName = gitArtifactMetadata.getRefName(); String repoName = gitArtifactMetadata.getRepoName(); + Mono useFSGitHandlerMono = featureFlagService.check(FeatureFlagEnum.release_git_api_contracts_enabled); + Mono keepWorkingDirChangesMono = + featureFlagService.check(FeatureFlagEnum.release_git_reset_optimization_enabled); if (!hasText(workspaceId)) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.WORKSPACE_ID)); @@ -957,8 +960,14 @@ public class CommonGitFileUtilsCE { ArtifactGitFileUtils artifactGitFileUtils = getArtifactBasedFileHelper(artifactType); Path baseRepoSuffix = artifactGitFileUtils.getRepoSuffixPath(workspaceId, defaultArtifactId, repoName); - Mono jsonObjectMono = fileUtils - .reconstructPageFromGitRepo(pageDTO.getName(), refName, baseRepoSuffix, isResetToLastCommitRequired) + Mono jsonObjectMono = Mono.zip(useFSGitHandlerMono, keepWorkingDirChangesMono) + .flatMap(tuple -> fileUtils.reconstructPageFromGitRepo( + pageDTO.getName(), + refName, + baseRepoSuffix, + isResetToLastCommitRequired, + tuple.getT1(), + tuple.getT2())) .onErrorResume(error -> Mono.error( new AppsmithException(AppsmithError.GIT_ACTION_FAILED, RECONSTRUCT_PAGE, error.getMessage()))) .map(pageJson -> {