chore: Side by Side exits beta phase (#38347)

This commit is contained in:
Hetu Nandu 2024-12-30 10:41:52 +05:30 committed by GitHub
parent cf534946b6
commit aaabb154f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 228 additions and 12 deletions

View File

@ -35,6 +35,7 @@ import { AnvilSnapshot } from "../Pages/Anvil/AnvilSnapshot";
export class ObjectsRegistry { export class ObjectsRegistry {
private static aggregateHelper__: AggregateHelper; private static aggregateHelper__: AggregateHelper;
static get AggregateHelper(): AggregateHelper { static get AggregateHelper(): AggregateHelper {
if (ObjectsRegistry.aggregateHelper__ === undefined) { if (ObjectsRegistry.aggregateHelper__ === undefined) {
ObjectsRegistry.aggregateHelper__ = new AggregateHelper(); ObjectsRegistry.aggregateHelper__ = new AggregateHelper();
@ -43,6 +44,7 @@ export class ObjectsRegistry {
} }
private static assertHelper__: AssertHelper; private static assertHelper__: AssertHelper;
static get AssertHelper(): AssertHelper { static get AssertHelper(): AssertHelper {
if (ObjectsRegistry.assertHelper__ === undefined) { if (ObjectsRegistry.assertHelper__ === undefined) {
ObjectsRegistry.assertHelper__ = new AssertHelper(); ObjectsRegistry.assertHelper__ = new AssertHelper();
@ -51,6 +53,7 @@ export class ObjectsRegistry {
} }
private static jsEditor__: JSEditor; private static jsEditor__: JSEditor;
static get JSEditor(): JSEditor { static get JSEditor(): JSEditor {
if (ObjectsRegistry.jsEditor__ === undefined) { if (ObjectsRegistry.jsEditor__ === undefined) {
ObjectsRegistry.jsEditor__ = new JSEditor(); ObjectsRegistry.jsEditor__ = new JSEditor();
@ -59,6 +62,7 @@ export class ObjectsRegistry {
} }
private static commonLocators__: CommonLocators; private static commonLocators__: CommonLocators;
static get CommonLocators(): CommonLocators { static get CommonLocators(): CommonLocators {
if (ObjectsRegistry.commonLocators__ === undefined) { if (ObjectsRegistry.commonLocators__ === undefined) {
ObjectsRegistry.commonLocators__ = new CommonLocators(); ObjectsRegistry.commonLocators__ = new CommonLocators();
@ -67,6 +71,7 @@ export class ObjectsRegistry {
} }
private static entityExplorer__: EntityExplorer; private static entityExplorer__: EntityExplorer;
static get EntityExplorer(): EntityExplorer { static get EntityExplorer(): EntityExplorer {
if (ObjectsRegistry.entityExplorer__ === undefined) { if (ObjectsRegistry.entityExplorer__ === undefined) {
ObjectsRegistry.entityExplorer__ = new EntityExplorer(); ObjectsRegistry.entityExplorer__ = new EntityExplorer();
@ -75,6 +80,7 @@ export class ObjectsRegistry {
} }
private static apiPage__: ApiPage; private static apiPage__: ApiPage;
static get ApiPage(): ApiPage { static get ApiPage(): ApiPage {
if (ObjectsRegistry.apiPage__ === undefined) { if (ObjectsRegistry.apiPage__ === undefined) {
ObjectsRegistry.apiPage__ = new ApiPage(); ObjectsRegistry.apiPage__ = new ApiPage();
@ -83,6 +89,7 @@ export class ObjectsRegistry {
} }
private static adminSettings__: AdminSettings; private static adminSettings__: AdminSettings;
static get AdminSettings(): AdminSettings { static get AdminSettings(): AdminSettings {
if (ObjectsRegistry.adminSettings__ === undefined) { if (ObjectsRegistry.adminSettings__ === undefined) {
ObjectsRegistry.adminSettings__ = new AdminSettings(); ObjectsRegistry.adminSettings__ = new AdminSettings();
@ -91,6 +98,7 @@ export class ObjectsRegistry {
} }
private static homePage__: HomePage; private static homePage__: HomePage;
static get HomePage(): HomePage { static get HomePage(): HomePage {
if (ObjectsRegistry.homePage__ === undefined) { if (ObjectsRegistry.homePage__ === undefined) {
ObjectsRegistry.homePage__ = new HomePage(); ObjectsRegistry.homePage__ = new HomePage();
@ -99,6 +107,7 @@ export class ObjectsRegistry {
} }
private static dataSources__: DataSources; private static dataSources__: DataSources;
static get DataSources(): DataSources { static get DataSources(): DataSources {
if (ObjectsRegistry.dataSources__ === undefined) { if (ObjectsRegistry.dataSources__ === undefined) {
ObjectsRegistry.dataSources__ = new DataSources(); ObjectsRegistry.dataSources__ = new DataSources();
@ -107,6 +116,7 @@ export class ObjectsRegistry {
} }
private static table__: Table; private static table__: Table;
static get Table(): Table { static get Table(): Table {
if (ObjectsRegistry.table__ === undefined) { if (ObjectsRegistry.table__ === undefined) {
ObjectsRegistry.table__ = new Table(); ObjectsRegistry.table__ = new Table();
@ -115,6 +125,7 @@ export class ObjectsRegistry {
} }
private static tabs__: Tabs; private static tabs__: Tabs;
static get Tabs(): Tabs { static get Tabs(): Tabs {
if (ObjectsRegistry.tabs__ === undefined) { if (ObjectsRegistry.tabs__ === undefined) {
ObjectsRegistry.tabs__ = new Tabs(); ObjectsRegistry.tabs__ = new Tabs();
@ -123,6 +134,7 @@ export class ObjectsRegistry {
} }
private static propertyPane__: PropertyPane; private static propertyPane__: PropertyPane;
static get PropertyPane(): PropertyPane { static get PropertyPane(): PropertyPane {
if (ObjectsRegistry.propertyPane__ === undefined) { if (ObjectsRegistry.propertyPane__ === undefined) {
ObjectsRegistry.propertyPane__ = new PropertyPane(); ObjectsRegistry.propertyPane__ = new PropertyPane();
@ -131,6 +143,7 @@ export class ObjectsRegistry {
} }
private static deployMode__: DeployMode; private static deployMode__: DeployMode;
static get DeployMode(): DeployMode { static get DeployMode(): DeployMode {
if (ObjectsRegistry.deployMode__ === undefined) { if (ObjectsRegistry.deployMode__ === undefined) {
ObjectsRegistry.deployMode__ = new DeployMode(); ObjectsRegistry.deployMode__ = new DeployMode();
@ -139,6 +152,7 @@ export class ObjectsRegistry {
} }
private static gitSync__: GitSync; private static gitSync__: GitSync;
static get GitSync(): GitSync { static get GitSync(): GitSync {
if (ObjectsRegistry.gitSync__ === undefined) { if (ObjectsRegistry.gitSync__ === undefined) {
ObjectsRegistry.gitSync__ = new GitSync(); ObjectsRegistry.gitSync__ = new GitSync();
@ -147,6 +161,7 @@ export class ObjectsRegistry {
} }
private static fakerHelper__: FakerHelper; private static fakerHelper__: FakerHelper;
static get FakerHelper(): FakerHelper { static get FakerHelper(): FakerHelper {
if (ObjectsRegistry.fakerHelper__ === undefined) { if (ObjectsRegistry.fakerHelper__ === undefined) {
ObjectsRegistry.fakerHelper__ = new FakerHelper(); ObjectsRegistry.fakerHelper__ = new FakerHelper();
@ -155,6 +170,7 @@ export class ObjectsRegistry {
} }
private static debuggerHelper__: DebuggerHelper; private static debuggerHelper__: DebuggerHelper;
static get DebuggerHelper(): DebuggerHelper { static get DebuggerHelper(): DebuggerHelper {
if (ObjectsRegistry.debuggerHelper__ === undefined) { if (ObjectsRegistry.debuggerHelper__ === undefined) {
ObjectsRegistry.debuggerHelper__ = new DebuggerHelper(); ObjectsRegistry.debuggerHelper__ = new DebuggerHelper();
@ -163,6 +179,7 @@ export class ObjectsRegistry {
} }
private static appSettings__: AppSettings; private static appSettings__: AppSettings;
static get AppSettings(): AppSettings { static get AppSettings(): AppSettings {
if (ObjectsRegistry.appSettings__ === undefined) { if (ObjectsRegistry.appSettings__ === undefined) {
ObjectsRegistry.appSettings__ = new AppSettings(); ObjectsRegistry.appSettings__ = new AppSettings();
@ -171,6 +188,7 @@ export class ObjectsRegistry {
} }
private static generalSettings__: GeneralSettings; private static generalSettings__: GeneralSettings;
static get GeneralSettings(): GeneralSettings { static get GeneralSettings(): GeneralSettings {
if (ObjectsRegistry.generalSettings__ === undefined) { if (ObjectsRegistry.generalSettings__ === undefined) {
ObjectsRegistry.generalSettings__ = new GeneralSettings(); ObjectsRegistry.generalSettings__ = new GeneralSettings();
@ -179,6 +197,7 @@ export class ObjectsRegistry {
} }
private static pageSettings__: PageSettings; private static pageSettings__: PageSettings;
static get PageSettings(): PageSettings { static get PageSettings(): PageSettings {
if (ObjectsRegistry.pageSettings__ === undefined) { if (ObjectsRegistry.pageSettings__ === undefined) {
ObjectsRegistry.pageSettings__ = new PageSettings(); ObjectsRegistry.pageSettings__ = new PageSettings();
@ -187,6 +206,7 @@ export class ObjectsRegistry {
} }
private static themeSettings__: ThemeSettings; private static themeSettings__: ThemeSettings;
static get ThemeSettings(): ThemeSettings { static get ThemeSettings(): ThemeSettings {
if (ObjectsRegistry.themeSettings__ === undefined) { if (ObjectsRegistry.themeSettings__ === undefined) {
ObjectsRegistry.themeSettings__ = new ThemeSettings(); ObjectsRegistry.themeSettings__ = new ThemeSettings();
@ -195,6 +215,7 @@ export class ObjectsRegistry {
} }
private static embedSettings__: EmbedSettings; private static embedSettings__: EmbedSettings;
static get EmbedSettings(): EmbedSettings { static get EmbedSettings(): EmbedSettings {
if (ObjectsRegistry.embedSettings__ === undefined) { if (ObjectsRegistry.embedSettings__ === undefined) {
ObjectsRegistry.embedSettings__ = new EmbedSettings(); ObjectsRegistry.embedSettings__ = new EmbedSettings();
@ -203,6 +224,7 @@ export class ObjectsRegistry {
} }
private static LibraryInstaller__: LibraryInstaller; private static LibraryInstaller__: LibraryInstaller;
static get LibraryInstaller(): LibraryInstaller { static get LibraryInstaller(): LibraryInstaller {
if (ObjectsRegistry.LibraryInstaller__ === undefined) { if (ObjectsRegistry.LibraryInstaller__ === undefined) {
ObjectsRegistry.LibraryInstaller__ = new LibraryInstaller(); ObjectsRegistry.LibraryInstaller__ = new LibraryInstaller();
@ -211,6 +233,7 @@ export class ObjectsRegistry {
} }
private static peekOverlay__: PeekOverlay; private static peekOverlay__: PeekOverlay;
static get PeekOverlay(): PeekOverlay { static get PeekOverlay(): PeekOverlay {
if (ObjectsRegistry.peekOverlay__ === undefined) { if (ObjectsRegistry.peekOverlay__ === undefined) {
ObjectsRegistry.peekOverlay__ = new PeekOverlay(); ObjectsRegistry.peekOverlay__ = new PeekOverlay();
@ -219,6 +242,7 @@ export class ObjectsRegistry {
} }
private static inviteModal__: InviteModal; private static inviteModal__: InviteModal;
static get InviteModal(): InviteModal { static get InviteModal(): InviteModal {
if (ObjectsRegistry.inviteModal__ === undefined) { if (ObjectsRegistry.inviteModal__ === undefined) {
ObjectsRegistry.inviteModal__ = new InviteModal(); ObjectsRegistry.inviteModal__ = new InviteModal();
@ -227,6 +251,7 @@ export class ObjectsRegistry {
} }
private static templates__: Templates; private static templates__: Templates;
static get Templates(): Templates { static get Templates(): Templates {
if (ObjectsRegistry.templates__ === undefined) { if (ObjectsRegistry.templates__ === undefined) {
ObjectsRegistry.templates__ = new Templates(); ObjectsRegistry.templates__ = new Templates();
@ -235,6 +260,7 @@ export class ObjectsRegistry {
} }
private static onboarding__: Onboarding; private static onboarding__: Onboarding;
static get Onboarding(): Onboarding { static get Onboarding(): Onboarding {
if (ObjectsRegistry.onboarding__ === undefined) { if (ObjectsRegistry.onboarding__ === undefined) {
ObjectsRegistry.onboarding__ = new Onboarding(); ObjectsRegistry.onboarding__ = new Onboarding();
@ -243,6 +269,7 @@ export class ObjectsRegistry {
} }
private static autoLayout__: AutoLayout; private static autoLayout__: AutoLayout;
static get AutoLayout(): AutoLayout { static get AutoLayout(): AutoLayout {
if (ObjectsRegistry.autoLayout__ === undefined) { if (ObjectsRegistry.autoLayout__ === undefined) {
ObjectsRegistry.autoLayout__ = new AutoLayout(); ObjectsRegistry.autoLayout__ = new AutoLayout();
@ -251,6 +278,7 @@ export class ObjectsRegistry {
} }
private static anvilLayout__: AnvilLayout; private static anvilLayout__: AnvilLayout;
static get AnvilLayout(): AnvilLayout { static get AnvilLayout(): AnvilLayout {
if (ObjectsRegistry.anvilLayout__ === undefined) { if (ObjectsRegistry.anvilLayout__ === undefined) {
ObjectsRegistry.anvilLayout__ = new AnvilLayout(); ObjectsRegistry.anvilLayout__ = new AnvilLayout();
@ -259,6 +287,7 @@ export class ObjectsRegistry {
} }
private static wdsWidgets__: WDSWidgets; private static wdsWidgets__: WDSWidgets;
static get WDSWidgets(): WDSWidgets { static get WDSWidgets(): WDSWidgets {
if (ObjectsRegistry.wdsWidgets__ === undefined) { if (ObjectsRegistry.wdsWidgets__ === undefined) {
ObjectsRegistry.wdsWidgets__ = new WDSWidgets(); ObjectsRegistry.wdsWidgets__ = new WDSWidgets();
@ -267,6 +296,7 @@ export class ObjectsRegistry {
} }
private static anvilSnapshot__: AnvilSnapshot; private static anvilSnapshot__: AnvilSnapshot;
static get AnvilSnapshot(): AnvilSnapshot { static get AnvilSnapshot(): AnvilSnapshot {
if (ObjectsRegistry.anvilSnapshot__ === undefined) { if (ObjectsRegistry.anvilSnapshot__ === undefined) {
ObjectsRegistry.anvilSnapshot__ = new AnvilSnapshot(); ObjectsRegistry.anvilSnapshot__ = new AnvilSnapshot();
@ -275,6 +305,7 @@ export class ObjectsRegistry {
} }
private static dataManager__: DataManager; private static dataManager__: DataManager;
static get DataManager(): DataManager { static get DataManager(): DataManager {
if (ObjectsRegistry.dataManager__ === undefined) { if (ObjectsRegistry.dataManager__ === undefined) {
ObjectsRegistry.dataManager__ = new DataManager(); ObjectsRegistry.dataManager__ = new DataManager();
@ -283,6 +314,7 @@ export class ObjectsRegistry {
} }
private static gsheetHelper__: GsheetHelper; private static gsheetHelper__: GsheetHelper;
static get GSheetHelper(): GsheetHelper { static get GSheetHelper(): GsheetHelper {
if (ObjectsRegistry.gsheetHelper__ === undefined) { if (ObjectsRegistry.gsheetHelper__ === undefined) {
ObjectsRegistry.gsheetHelper__ = new GsheetHelper(); ObjectsRegistry.gsheetHelper__ = new GsheetHelper();
@ -291,6 +323,7 @@ export class ObjectsRegistry {
} }
private static communityTemplates__: CommunityTemplates; private static communityTemplates__: CommunityTemplates;
static get CommunityTemplates(): CommunityTemplates { static get CommunityTemplates(): CommunityTemplates {
if (ObjectsRegistry.communityTemplates__ === undefined) { if (ObjectsRegistry.communityTemplates__ === undefined) {
ObjectsRegistry.communityTemplates__ = new CommunityTemplates(); ObjectsRegistry.communityTemplates__ = new CommunityTemplates();
@ -299,6 +332,7 @@ export class ObjectsRegistry {
} }
private static partialImportExport__: PartialImportExport; private static partialImportExport__: PartialImportExport;
static get PartialImportExport(): PartialImportExport { static get PartialImportExport(): PartialImportExport {
if (ObjectsRegistry.partialImportExport__ === undefined) { if (ObjectsRegistry.partialImportExport__ === undefined) {
ObjectsRegistry.partialImportExport__ = new PartialImportExport(); ObjectsRegistry.partialImportExport__ = new PartialImportExport();
@ -311,6 +345,7 @@ export const initLocalstorageRegistry = () => {
cy.window().then((window) => { cy.window().then((window) => {
window.localStorage.setItem("ShowCommentsButtonToolTip", ""); window.localStorage.setItem("ShowCommentsButtonToolTip", "");
window.localStorage.setItem("updateDismissed", "true"); window.localStorage.setItem("updateDismissed", "true");
window.localStorage.setItem("NUDGE_SHOWN_SPLIT_PANE", "true");
}); });
localStorage.setItem("inDeployedMode", "false"); localStorage.setItem("inDeployedMode", "false");
}; };

View File

@ -19,6 +19,7 @@ import { v4 as uuidv4 } from "uuid";
const dayjs = require("dayjs"); const dayjs = require("dayjs");
const loginPage = require("../locators/LoginPage.json"); const loginPage = require("../locators/LoginPage.json");
import homePage from "../locators/HomePage"; import homePage from "../locators/HomePage";
dayjs.extend(advancedFormat); dayjs.extend(advancedFormat);
const commonlocators = require("../locators/commonlocators.json"); const commonlocators = require("../locators/commonlocators.json");
@ -54,6 +55,7 @@ export const initLocalstorage = () => {
cy.window().then((window) => { cy.window().then((window) => {
window.localStorage.setItem("ShowCommentsButtonToolTip", ""); window.localStorage.setItem("ShowCommentsButtonToolTip", "");
window.localStorage.setItem("updateDismissed", "true"); window.localStorage.setItem("updateDismissed", "true");
window.localStorage.setItem("NUDGE_SHOWN_SPLIT_PANE", "true");
}); });
}; };

View File

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import type { PopoverTriggerProps } from "@radix-ui/react-popover"; import type { PopoverTriggerProps } from "@radix-ui/react-popover";
import { Close, Root, Trigger, Portal } from "@radix-ui/react-popover"; import { Close, Root, Trigger, Portal, Arrow } from "@radix-ui/react-popover";
import type { PopoverHeaderProps, PopoverContentProps } from "./Popover.types"; import type { PopoverHeaderProps, PopoverContentProps } from "./Popover.types";
import { import {
@ -60,6 +60,7 @@ function PopoverContent({ size = "sm", ...props }: PopoverContentProps) {
sideOffset={4} sideOffset={4}
{...props} {...props}
> >
{props.showArrow ? <Arrow /> : null}
{props.children} {props.children}
</StyledContent> </StyledContent>
</Portal> </Portal>

View File

@ -20,4 +20,6 @@ export type PopoverContentProps = {
className?: string; className?: string;
/** the minimum size of the popover */ /** the minimum size of the popover */
size?: PopoverSize; size?: PopoverSize;
/** render an arrow pointing to the trigger */
showArrow?: boolean;
} & RadixPopoverContentProps; } & RadixPopoverContentProps;

View File

@ -0,0 +1,57 @@
import React, { useEffect, useState } from "react";
import { Flex, Popover, Text } from "@appsmith/ads";
import * as Styled from "./styles";
import type { Align, Side } from "@radix-ui/react-popper";
interface Props {
trigger: React.ReactNode;
onDismissClick: () => void;
message: string;
align?: Align;
side?: Side;
delayOpen?: number;
}
export const Nudge = (props: Props) => {
const [open, setOpen] = useState(false);
useEffect(
function handleDelayOpenOnMount() {
const timer = setTimeout(() => {
setOpen(true);
}, props.delayOpen || 0);
return () => clearTimeout(timer);
},
[props.delayOpen],
);
return (
<Popover open={open}>
<Styled.PopoverTrigger data-active={open}>
{props.trigger}
</Styled.PopoverTrigger>
<Styled.PopoverContent
align={props.align}
showArrow
side={props.side}
size="sm"
>
<Flex
alignItems="flex-start"
backgroundColor="var(--ads-v2-color-bg-emphasis-max)"
gap="spaces-2"
>
<Text color="var(--ads-v2-color-bg)" kind="heading-xs">
{props.message}
</Text>
<Styled.CloseIcon
name="close-line"
onClick={props.onDismissClick}
size="md"
/>
</Flex>
</Styled.PopoverContent>
</Popover>
);
};

View File

@ -0,0 +1 @@
export { Nudge } from "./Nudge";

View File

@ -0,0 +1,49 @@
import styled from "styled-components";
import {
Icon,
PopoverContent as ADSPopoverContent,
PopoverTrigger as ADSPopoverTrigger,
} from "@appsmith/ads";
export const PopoverContent = styled(ADSPopoverContent)`
background: var(--ads-v2-color-bg-emphasis-max);
box-shadow: 0 1px 20px 0 #4c56641c;
border: none;
transform-origin: var(--radix-popover-content-transform-origin);
animation: fadeIn 0.2s cubic-bezier(0, 0, 0.58, 1);
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
`;
export const PopoverTrigger = styled(ADSPopoverTrigger)`
border: 2px solid transparent !important;
&[data-active="true"] {
border: 2px solid var(--ads-v2-color-blue-300) !important;
}
transition: border 0.2s cubic-bezier(0, 0, 0.58, 1);
`;
export const CloseIcon = styled(Icon)`
svg {
path {
fill: var(--ads-v2-color-bg);
}
}
padding: var(--ads-v2-spaces-2);
cursor: pointer;
border-radius: var(--ads-v2-border-radius);
&:hover {
background-color: #ffffff33;
}
`;

View File

@ -4,6 +4,8 @@ import localStorage, { LOCAL_STORAGE_KEYS } from "utils/localStorage";
import { SPLITPANE_ANNOUNCEMENT, createMessage } from "ee/constants/messages"; import { SPLITPANE_ANNOUNCEMENT, createMessage } from "ee/constants/messages";
import { getAssetUrl } from "ee/utils/airgapHelpers"; import { getAssetUrl } from "ee/utils/airgapHelpers";
import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants"; import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
const Announcement = () => { const Announcement = () => {
const localStorageFlag = const localStorageFlag =
@ -22,6 +24,10 @@ const Announcement = () => {
); );
}; };
const featureIsOutOfBeta = useFeatureFlag(
FEATURE_FLAG.release_actions_redesign_enabled,
);
const modalFooter = () => ( const modalFooter = () => (
<> <>
<Button <Button
@ -38,6 +44,11 @@ const Announcement = () => {
</> </>
); );
// If the feature is out of beta, don't show the announcement
if (featureIsOutOfBeta) {
return null;
}
return ( return (
<AnnouncementModal <AnnouncementModal
banner={getAssetUrl(`${ASSETS_CDN_URL}/splitpane-banner.svg`)} banner={getAssetUrl(`${ASSETS_CDN_URL}/splitpane-banner.svg`)}

View File

@ -1,4 +1,4 @@
import React, { useCallback } from "react"; import React, { useCallback, useMemo } from "react";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { Button, Tooltip } from "@appsmith/ads"; import { Button, Tooltip } from "@appsmith/ads";
@ -14,6 +14,8 @@ import { setIdeEditorViewMode } from "actions/ideActions";
import type { AppState } from "ee/reducers"; import type { AppState } from "ee/reducers";
import { selectFeatureFlagCheck } from "ee/selectors/featureFlagsSelectors"; import { selectFeatureFlagCheck } from "ee/selectors/featureFlagsSelectors";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import { Nudge } from "IDE/Components/Nudge";
import { useShowSideBySideNudge } from "../hooks";
export const ScreenModeToggle = () => { export const ScreenModeToggle = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -41,11 +43,15 @@ export const ScreenModeToggle = () => {
} }
}, [dispatch, isAnimatedIDEEnabled]); }, [dispatch, isAnimatedIDEEnabled]);
const [showNudge, dismissNudge] = useShowSideBySideNudge();
const switchToSplitScreen = useCallback(() => { const switchToSplitScreen = useCallback(() => {
AnalyticsUtil.logEvent("EDITOR_MODE_CHANGE", { AnalyticsUtil.logEvent("EDITOR_MODE_CHANGE", {
to: EditorViewMode.SplitScreen, to: EditorViewMode.SplitScreen,
}); });
dismissNudge();
if ("startViewTransition" in document && isAnimatedIDEEnabled) { if ("startViewTransition" in document && isAnimatedIDEEnabled) {
document.startViewTransition(() => { document.startViewTransition(() => {
dispatch(setIdeEditorViewMode(EditorViewMode.SplitScreen)); dispatch(setIdeEditorViewMode(EditorViewMode.SplitScreen));
@ -53,7 +59,22 @@ export const ScreenModeToggle = () => {
} else { } else {
dispatch(setIdeEditorViewMode(EditorViewMode.SplitScreen)); dispatch(setIdeEditorViewMode(EditorViewMode.SplitScreen));
} }
}, [dispatch, isAnimatedIDEEnabled]); }, [dispatch, dismissNudge, isAnimatedIDEEnabled]);
const minimiseButton = useMemo(
() => (
<Button
className="ml-auto !min-w-[24px]"
data-testid={"t--ide-minimize"}
id={"editor-mode-minimize"}
isIconButton
kind="tertiary"
onClick={switchToSplitScreen}
startIcon={"minimize-v3"}
/>
),
[switchToSplitScreen],
);
if (ideViewMode === EditorViewMode.SplitScreen) { if (ideViewMode === EditorViewMode.SplitScreen) {
return ( return (
@ -74,20 +95,26 @@ export const ScreenModeToggle = () => {
); );
} }
if (showNudge) {
return (
<Nudge
align="center"
delayOpen={500}
message="Write code and configure UI elements side by side"
onDismissClick={dismissNudge}
side="left"
trigger={minimiseButton}
/>
);
}
return ( return (
<Tooltip <Tooltip
content={createMessage(MINIMIZE_BUTTON_TOOLTIP)} content={createMessage(MINIMIZE_BUTTON_TOOLTIP)}
key={createMessage(MINIMIZE_BUTTON_TOOLTIP)} key={createMessage(MINIMIZE_BUTTON_TOOLTIP)}
placement="left"
> >
<Button {minimiseButton}
className="ml-auto !min-w-[24px]"
data-testid={"t--ide-minimize"}
id={"editor-mode-minimize"}
isIconButton
kind="tertiary"
onClick={switchToSplitScreen}
startIcon={"minimize-v3"}
/>
</Tooltip> </Tooltip>
); );
}; };

View File

@ -29,6 +29,11 @@ import { getCurrentBasePageId } from "selectors/editorSelectors";
import { getCurrentEntityInfo } from "../utils"; import { getCurrentEntityInfo } from "../utils";
import { useEditorType } from "ee/hooks"; import { useEditorType } from "ee/hooks";
import { useParentEntityInfo } from "ee/hooks/datasourceEditorHooks"; import { useParentEntityInfo } from "ee/hooks/datasourceEditorHooks";
import { useBoolean } from "usehooks-ts";
import { isWidgetActionConnectionPresent } from "selectors/onboardingSelectors";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import localStorage, { LOCAL_STORAGE_KEYS } from "utils/localStorage";
export const useCurrentEditorState = () => { export const useCurrentEditorState = () => {
const [selectedSegment, setSelectedSegment] = useState<EditorEntityTab>( const [selectedSegment, setSelectedSegment] = useState<EditorEntityTab>(
@ -198,3 +203,26 @@ export const useIDETabClickHandlers = () => {
return { addClickHandler, tabClickHandler, closeClickHandler }; return { addClickHandler, tabClickHandler, closeClickHandler };
}; };
export const useShowSideBySideNudge: () => [boolean, () => void] = () => {
const widgetBindingsExist = useSelector(isWidgetActionConnectionPresent);
const localStorageFlag = localStorage.getItem(
LOCAL_STORAGE_KEYS.NUDGE_SHOWN_SPLIT_PANE,
);
const isActionRedesignEnabled = useFeatureFlag(
FEATURE_FLAG.release_actions_redesign_enabled,
);
const { setFalse, value } = useBoolean(
widgetBindingsExist && isActionRedesignEnabled && !localStorageFlag,
);
const dismissNudge = useCallback(() => {
setFalse();
localStorage.setItem(LOCAL_STORAGE_KEYS.NUDGE_SHOWN_SPLIT_PANE, "true");
}, [setFalse]);
return [value, dismissNudge];
};

View File

@ -10,10 +10,12 @@ import { toast } from "@appsmith/ads";
export const LOCAL_STORAGE_KEYS = { export const LOCAL_STORAGE_KEYS = {
CANVAS_CARDS_STATE: "CANVAS_CARDS_STATE", CANVAS_CARDS_STATE: "CANVAS_CARDS_STATE",
SPLITPANE_ANNOUNCEMENT: "SPLITPANE_ANNOUNCEMENT", SPLITPANE_ANNOUNCEMENT: "SPLITPANE_ANNOUNCEMENT",
NUDGE_SHOWN_SPLIT_PANE: "NUDGE_SHOWN_SPLIT_PANE",
}; };
class LocalStorageNotSupportedError extends Error { class LocalStorageNotSupportedError extends Error {
name: string; name: string;
constructor() { constructor() {
super(); super();
this.name = "LOCAL_STORAGE_NOT_SUPPORTED"; this.name = "LOCAL_STORAGE_NOT_SUPPORTED";
@ -29,6 +31,7 @@ class WebStorage {
this._isSupported = this.isSupported(); this._isSupported = this.isSupported();
} }
// ref: https://github.com/Modernizr/Modernizr/blob/94592f279a410436530c7c06acc42a6e90c20150/feature-detects/storage/localstorage.js // ref: https://github.com/Modernizr/Modernizr/blob/94592f279a410436530c7c06acc42a6e90c20150/feature-detects/storage/localstorage.js
isSupported = () => { isSupported = () => {
try { try {