From aaabb154f88ba2c8e7890c1fff18cfef916fdc9c Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Mon, 30 Dec 2024 10:41:52 +0530 Subject: [PATCH] chore: Side by Side exits beta phase (#38347) --- .../cypress/support/Objects/Registry.ts | 35 ++++++++++++ app/client/cypress/support/commands.js | 2 + .../design-system/ads/src/Popover/Popover.tsx | 3 +- .../ads/src/Popover/Popover.types.ts | 2 + app/client/src/IDE/Components/Nudge/Nudge.tsx | 57 +++++++++++++++++++ app/client/src/IDE/Components/Nudge/index.ts | 1 + app/client/src/IDE/Components/Nudge/styles.ts | 49 ++++++++++++++++ .../EditorPane/components/Announcement.tsx | 11 ++++ .../IDE/EditorTabs/ScreenModeToggle.tsx | 49 ++++++++++++---- app/client/src/pages/Editor/IDE/hooks.ts | 28 +++++++++ app/client/src/utils/localStorage.tsx | 3 + 11 files changed, 228 insertions(+), 12 deletions(-) create mode 100644 app/client/src/IDE/Components/Nudge/Nudge.tsx create mode 100644 app/client/src/IDE/Components/Nudge/index.ts create mode 100644 app/client/src/IDE/Components/Nudge/styles.ts diff --git a/app/client/cypress/support/Objects/Registry.ts b/app/client/cypress/support/Objects/Registry.ts index ebc61b8413..3b43cf5c8c 100644 --- a/app/client/cypress/support/Objects/Registry.ts +++ b/app/client/cypress/support/Objects/Registry.ts @@ -35,6 +35,7 @@ import { AnvilSnapshot } from "../Pages/Anvil/AnvilSnapshot"; export class ObjectsRegistry { private static aggregateHelper__: AggregateHelper; + static get AggregateHelper(): AggregateHelper { if (ObjectsRegistry.aggregateHelper__ === undefined) { ObjectsRegistry.aggregateHelper__ = new AggregateHelper(); @@ -43,6 +44,7 @@ export class ObjectsRegistry { } private static assertHelper__: AssertHelper; + static get AssertHelper(): AssertHelper { if (ObjectsRegistry.assertHelper__ === undefined) { ObjectsRegistry.assertHelper__ = new AssertHelper(); @@ -51,6 +53,7 @@ export class ObjectsRegistry { } private static jsEditor__: JSEditor; + static get JSEditor(): JSEditor { if (ObjectsRegistry.jsEditor__ === undefined) { ObjectsRegistry.jsEditor__ = new JSEditor(); @@ -59,6 +62,7 @@ export class ObjectsRegistry { } private static commonLocators__: CommonLocators; + static get CommonLocators(): CommonLocators { if (ObjectsRegistry.commonLocators__ === undefined) { ObjectsRegistry.commonLocators__ = new CommonLocators(); @@ -67,6 +71,7 @@ export class ObjectsRegistry { } private static entityExplorer__: EntityExplorer; + static get EntityExplorer(): EntityExplorer { if (ObjectsRegistry.entityExplorer__ === undefined) { ObjectsRegistry.entityExplorer__ = new EntityExplorer(); @@ -75,6 +80,7 @@ export class ObjectsRegistry { } private static apiPage__: ApiPage; + static get ApiPage(): ApiPage { if (ObjectsRegistry.apiPage__ === undefined) { ObjectsRegistry.apiPage__ = new ApiPage(); @@ -83,6 +89,7 @@ export class ObjectsRegistry { } private static adminSettings__: AdminSettings; + static get AdminSettings(): AdminSettings { if (ObjectsRegistry.adminSettings__ === undefined) { ObjectsRegistry.adminSettings__ = new AdminSettings(); @@ -91,6 +98,7 @@ export class ObjectsRegistry { } private static homePage__: HomePage; + static get HomePage(): HomePage { if (ObjectsRegistry.homePage__ === undefined) { ObjectsRegistry.homePage__ = new HomePage(); @@ -99,6 +107,7 @@ export class ObjectsRegistry { } private static dataSources__: DataSources; + static get DataSources(): DataSources { if (ObjectsRegistry.dataSources__ === undefined) { ObjectsRegistry.dataSources__ = new DataSources(); @@ -107,6 +116,7 @@ export class ObjectsRegistry { } private static table__: Table; + static get Table(): Table { if (ObjectsRegistry.table__ === undefined) { ObjectsRegistry.table__ = new Table(); @@ -115,6 +125,7 @@ export class ObjectsRegistry { } private static tabs__: Tabs; + static get Tabs(): Tabs { if (ObjectsRegistry.tabs__ === undefined) { ObjectsRegistry.tabs__ = new Tabs(); @@ -123,6 +134,7 @@ export class ObjectsRegistry { } private static propertyPane__: PropertyPane; + static get PropertyPane(): PropertyPane { if (ObjectsRegistry.propertyPane__ === undefined) { ObjectsRegistry.propertyPane__ = new PropertyPane(); @@ -131,6 +143,7 @@ export class ObjectsRegistry { } private static deployMode__: DeployMode; + static get DeployMode(): DeployMode { if (ObjectsRegistry.deployMode__ === undefined) { ObjectsRegistry.deployMode__ = new DeployMode(); @@ -139,6 +152,7 @@ export class ObjectsRegistry { } private static gitSync__: GitSync; + static get GitSync(): GitSync { if (ObjectsRegistry.gitSync__ === undefined) { ObjectsRegistry.gitSync__ = new GitSync(); @@ -147,6 +161,7 @@ export class ObjectsRegistry { } private static fakerHelper__: FakerHelper; + static get FakerHelper(): FakerHelper { if (ObjectsRegistry.fakerHelper__ === undefined) { ObjectsRegistry.fakerHelper__ = new FakerHelper(); @@ -155,6 +170,7 @@ export class ObjectsRegistry { } private static debuggerHelper__: DebuggerHelper; + static get DebuggerHelper(): DebuggerHelper { if (ObjectsRegistry.debuggerHelper__ === undefined) { ObjectsRegistry.debuggerHelper__ = new DebuggerHelper(); @@ -163,6 +179,7 @@ export class ObjectsRegistry { } private static appSettings__: AppSettings; + static get AppSettings(): AppSettings { if (ObjectsRegistry.appSettings__ === undefined) { ObjectsRegistry.appSettings__ = new AppSettings(); @@ -171,6 +188,7 @@ export class ObjectsRegistry { } private static generalSettings__: GeneralSettings; + static get GeneralSettings(): GeneralSettings { if (ObjectsRegistry.generalSettings__ === undefined) { ObjectsRegistry.generalSettings__ = new GeneralSettings(); @@ -179,6 +197,7 @@ export class ObjectsRegistry { } private static pageSettings__: PageSettings; + static get PageSettings(): PageSettings { if (ObjectsRegistry.pageSettings__ === undefined) { ObjectsRegistry.pageSettings__ = new PageSettings(); @@ -187,6 +206,7 @@ export class ObjectsRegistry { } private static themeSettings__: ThemeSettings; + static get ThemeSettings(): ThemeSettings { if (ObjectsRegistry.themeSettings__ === undefined) { ObjectsRegistry.themeSettings__ = new ThemeSettings(); @@ -195,6 +215,7 @@ export class ObjectsRegistry { } private static embedSettings__: EmbedSettings; + static get EmbedSettings(): EmbedSettings { if (ObjectsRegistry.embedSettings__ === undefined) { ObjectsRegistry.embedSettings__ = new EmbedSettings(); @@ -203,6 +224,7 @@ export class ObjectsRegistry { } private static LibraryInstaller__: LibraryInstaller; + static get LibraryInstaller(): LibraryInstaller { if (ObjectsRegistry.LibraryInstaller__ === undefined) { ObjectsRegistry.LibraryInstaller__ = new LibraryInstaller(); @@ -211,6 +233,7 @@ export class ObjectsRegistry { } private static peekOverlay__: PeekOverlay; + static get PeekOverlay(): PeekOverlay { if (ObjectsRegistry.peekOverlay__ === undefined) { ObjectsRegistry.peekOverlay__ = new PeekOverlay(); @@ -219,6 +242,7 @@ export class ObjectsRegistry { } private static inviteModal__: InviteModal; + static get InviteModal(): InviteModal { if (ObjectsRegistry.inviteModal__ === undefined) { ObjectsRegistry.inviteModal__ = new InviteModal(); @@ -227,6 +251,7 @@ export class ObjectsRegistry { } private static templates__: Templates; + static get Templates(): Templates { if (ObjectsRegistry.templates__ === undefined) { ObjectsRegistry.templates__ = new Templates(); @@ -235,6 +260,7 @@ export class ObjectsRegistry { } private static onboarding__: Onboarding; + static get Onboarding(): Onboarding { if (ObjectsRegistry.onboarding__ === undefined) { ObjectsRegistry.onboarding__ = new Onboarding(); @@ -243,6 +269,7 @@ export class ObjectsRegistry { } private static autoLayout__: AutoLayout; + static get AutoLayout(): AutoLayout { if (ObjectsRegistry.autoLayout__ === undefined) { ObjectsRegistry.autoLayout__ = new AutoLayout(); @@ -251,6 +278,7 @@ export class ObjectsRegistry { } private static anvilLayout__: AnvilLayout; + static get AnvilLayout(): AnvilLayout { if (ObjectsRegistry.anvilLayout__ === undefined) { ObjectsRegistry.anvilLayout__ = new AnvilLayout(); @@ -259,6 +287,7 @@ export class ObjectsRegistry { } private static wdsWidgets__: WDSWidgets; + static get WDSWidgets(): WDSWidgets { if (ObjectsRegistry.wdsWidgets__ === undefined) { ObjectsRegistry.wdsWidgets__ = new WDSWidgets(); @@ -267,6 +296,7 @@ export class ObjectsRegistry { } private static anvilSnapshot__: AnvilSnapshot; + static get AnvilSnapshot(): AnvilSnapshot { if (ObjectsRegistry.anvilSnapshot__ === undefined) { ObjectsRegistry.anvilSnapshot__ = new AnvilSnapshot(); @@ -275,6 +305,7 @@ export class ObjectsRegistry { } private static dataManager__: DataManager; + static get DataManager(): DataManager { if (ObjectsRegistry.dataManager__ === undefined) { ObjectsRegistry.dataManager__ = new DataManager(); @@ -283,6 +314,7 @@ export class ObjectsRegistry { } private static gsheetHelper__: GsheetHelper; + static get GSheetHelper(): GsheetHelper { if (ObjectsRegistry.gsheetHelper__ === undefined) { ObjectsRegistry.gsheetHelper__ = new GsheetHelper(); @@ -291,6 +323,7 @@ export class ObjectsRegistry { } private static communityTemplates__: CommunityTemplates; + static get CommunityTemplates(): CommunityTemplates { if (ObjectsRegistry.communityTemplates__ === undefined) { ObjectsRegistry.communityTemplates__ = new CommunityTemplates(); @@ -299,6 +332,7 @@ export class ObjectsRegistry { } private static partialImportExport__: PartialImportExport; + static get PartialImportExport(): PartialImportExport { if (ObjectsRegistry.partialImportExport__ === undefined) { ObjectsRegistry.partialImportExport__ = new PartialImportExport(); @@ -311,6 +345,7 @@ export const initLocalstorageRegistry = () => { cy.window().then((window) => { window.localStorage.setItem("ShowCommentsButtonToolTip", ""); window.localStorage.setItem("updateDismissed", "true"); + window.localStorage.setItem("NUDGE_SHOWN_SPLIT_PANE", "true"); }); localStorage.setItem("inDeployedMode", "false"); }; diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index 75dab16115..74294b336c 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -19,6 +19,7 @@ import { v4 as uuidv4 } from "uuid"; const dayjs = require("dayjs"); const loginPage = require("../locators/LoginPage.json"); import homePage from "../locators/HomePage"; + dayjs.extend(advancedFormat); const commonlocators = require("../locators/commonlocators.json"); @@ -54,6 +55,7 @@ export const initLocalstorage = () => { cy.window().then((window) => { window.localStorage.setItem("ShowCommentsButtonToolTip", ""); window.localStorage.setItem("updateDismissed", "true"); + window.localStorage.setItem("NUDGE_SHOWN_SPLIT_PANE", "true"); }); }; diff --git a/app/client/packages/design-system/ads/src/Popover/Popover.tsx b/app/client/packages/design-system/ads/src/Popover/Popover.tsx index 34fc8d7ef2..44270713da 100644 --- a/app/client/packages/design-system/ads/src/Popover/Popover.tsx +++ b/app/client/packages/design-system/ads/src/Popover/Popover.tsx @@ -1,6 +1,6 @@ import React from "react"; 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 { @@ -60,6 +60,7 @@ function PopoverContent({ size = "sm", ...props }: PopoverContentProps) { sideOffset={4} {...props} > + {props.showArrow ? : null} {props.children} diff --git a/app/client/packages/design-system/ads/src/Popover/Popover.types.ts b/app/client/packages/design-system/ads/src/Popover/Popover.types.ts index c3e61cd2ce..f78414b2f5 100644 --- a/app/client/packages/design-system/ads/src/Popover/Popover.types.ts +++ b/app/client/packages/design-system/ads/src/Popover/Popover.types.ts @@ -20,4 +20,6 @@ export type PopoverContentProps = { className?: string; /** the minimum size of the popover */ size?: PopoverSize; + /** render an arrow pointing to the trigger */ + showArrow?: boolean; } & RadixPopoverContentProps; diff --git a/app/client/src/IDE/Components/Nudge/Nudge.tsx b/app/client/src/IDE/Components/Nudge/Nudge.tsx new file mode 100644 index 0000000000..d32eb14adf --- /dev/null +++ b/app/client/src/IDE/Components/Nudge/Nudge.tsx @@ -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 ( + + + {props.trigger} + + + + + {props.message} + + + + + + ); +}; diff --git a/app/client/src/IDE/Components/Nudge/index.ts b/app/client/src/IDE/Components/Nudge/index.ts new file mode 100644 index 0000000000..166ded472e --- /dev/null +++ b/app/client/src/IDE/Components/Nudge/index.ts @@ -0,0 +1 @@ +export { Nudge } from "./Nudge"; diff --git a/app/client/src/IDE/Components/Nudge/styles.ts b/app/client/src/IDE/Components/Nudge/styles.ts new file mode 100644 index 0000000000..081c6ed10c --- /dev/null +++ b/app/client/src/IDE/Components/Nudge/styles.ts @@ -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; + } +`; diff --git a/app/client/src/pages/Editor/IDE/EditorPane/components/Announcement.tsx b/app/client/src/pages/Editor/IDE/EditorPane/components/Announcement.tsx index 354a70a481..54181cab50 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/components/Announcement.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/components/Announcement.tsx @@ -4,6 +4,8 @@ import localStorage, { LOCAL_STORAGE_KEYS } from "utils/localStorage"; import { SPLITPANE_ANNOUNCEMENT, createMessage } from "ee/constants/messages"; import { getAssetUrl } from "ee/utils/airgapHelpers"; import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants"; +import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; +import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; const Announcement = () => { const localStorageFlag = @@ -22,6 +24,10 @@ const Announcement = () => { ); }; + const featureIsOutOfBeta = useFeatureFlag( + FEATURE_FLAG.release_actions_redesign_enabled, + ); + const modalFooter = () => ( <>