From b75b11957c5892a37b32428c8039758289543fea Mon Sep 17 00:00:00 2001 From: gurusainath Date: Tue, 6 Aug 2024 14:33:58 +0530 Subject: [PATCH 1/2] chore: handled intercom operations programatically. --- .../command-palette/actions/help-actions.tsx | 12 ++++---- .../workspace/sidebar/help-section.tsx | 7 ++--- web/core/hooks/store/index.ts | 1 + web/core/hooks/store/use-transient.ts | 11 ++++++++ web/core/lib/intercom-provider.tsx | 17 +++++++++-- web/core/store/root.store.ts | 5 ++++ web/core/store/transient.store.ts | 28 +++++++++++++++++++ 7 files changed, 68 insertions(+), 13 deletions(-) create mode 100644 web/core/hooks/store/use-transient.ts create mode 100644 web/core/store/transient.store.ts diff --git a/web/core/components/command-palette/actions/help-actions.tsx b/web/core/components/command-palette/actions/help-actions.tsx index ad54c542bfe..49a8887981f 100644 --- a/web/core/components/command-palette/actions/help-actions.tsx +++ b/web/core/components/command-palette/actions/help-actions.tsx @@ -1,19 +1,21 @@ "use client"; import { Command } from "cmdk"; +import { observer } from "mobx-react"; import { FileText, GithubIcon, MessageSquare, Rocket } from "lucide-react"; // ui import { DiscordIcon } from "@plane/ui"; // hooks -import { useCommandPalette } from "@/hooks/store"; +import { useCommandPalette, useTransient } from "@/hooks/store"; type Props = { closePalette: () => void; }; -export const CommandPaletteHelpActions: React.FC = (props) => { +export const CommandPaletteHelpActions: React.FC = observer((props) => { const { closePalette } = props; // hooks const { toggleShortcutModal } = useCommandPalette(); + const { toggleIntercom } = useTransient(); return ( @@ -68,9 +70,7 @@ export const CommandPaletteHelpActions: React.FC = (props) => { { closePalette(); - if (window) { - window.$crisp.push(["do", "chat:show"]); - } + toggleIntercom(true); }} className="focus:outline-none" > @@ -81,4 +81,4 @@ export const CommandPaletteHelpActions: React.FC = (props) => { ); -}; +}); diff --git a/web/core/components/workspace/sidebar/help-section.tsx b/web/core/components/workspace/sidebar/help-section.tsx index e2c94e85566..0921cf5e49e 100644 --- a/web/core/components/workspace/sidebar/help-section.tsx +++ b/web/core/components/workspace/sidebar/help-section.tsx @@ -10,7 +10,7 @@ import { DiscordIcon, GithubIcon, Tooltip } from "@plane/ui"; // helpers import { cn } from "@/helpers/common.helper"; // hooks -import { useAppTheme, useCommandPalette, useInstance } from "@/hooks/store"; +import { useAppTheme, useCommandPalette, useInstance, useTransient } from "@/hooks/store"; import useOutsideClickDetector from "@/hooks/use-outside-click-detector"; import { usePlatformOS } from "@/hooks/use-platform-os"; // components @@ -45,15 +45,14 @@ export const SidebarHelpSection: React.FC = observer( const { toggleShortcutModal } = useCommandPalette(); const { isMobile } = usePlatformOS(); const { config } = useInstance(); + const { isIntercomToggle, toggleIntercom } = useTransient(); // states const [isNeedHelpOpen, setIsNeedHelpOpen] = useState(false); // refs const helpOptionsRef = useRef(null); const handleCrispWindowShow = () => { - if (window) { - window.$crisp.push(["do", "chat:show"]); - } + toggleIntercom(!isIntercomToggle); }; useOutsideClickDetector(helpOptionsRef, () => setIsNeedHelpOpen(false)); diff --git a/web/core/hooks/store/index.ts b/web/core/hooks/store/index.ts index a19c269be24..1be070cb89b 100644 --- a/web/core/hooks/store/index.ts +++ b/web/core/hooks/store/index.ts @@ -30,3 +30,4 @@ export * from "./use-router-params"; export * from "./use-webhook"; export * from "./use-workspace"; export * from "./user"; +export * from "./use-transient"; diff --git a/web/core/hooks/store/use-transient.ts b/web/core/hooks/store/use-transient.ts new file mode 100644 index 00000000000..4bca56be938 --- /dev/null +++ b/web/core/hooks/store/use-transient.ts @@ -0,0 +1,11 @@ +import { useContext } from "react"; +// mobx store +import { StoreContext } from "@/lib/store-context"; +// types +import { ITransientStore } from "@/store/transient.store"; + +export const useTransient = (): ITransientStore => { + const context = useContext(StoreContext); + if (context === undefined) throw new Error("useTransient must be used within StoreProvider"); + return context.transient; +}; diff --git a/web/core/lib/intercom-provider.tsx b/web/core/lib/intercom-provider.tsx index 0140e4a2074..b483c6da2d0 100644 --- a/web/core/lib/intercom-provider.tsx +++ b/web/core/lib/intercom-provider.tsx @@ -1,10 +1,10 @@ "use client"; import React, { FC, useEffect } from "react"; -import Intercom from "@intercom/messenger-js-sdk"; +import { Intercom, show, hide, onHide } from "@intercom/messenger-js-sdk"; import { observer } from "mobx-react"; // store hooks -import { useUser, useInstance } from "@/hooks/store"; +import { useUser, useInstance, useTransient } from "@/hooks/store"; export type IntercomProviderProps = { children: React.ReactNode; @@ -15,6 +15,16 @@ const IntercomProvider: FC = observer((props) => { // hooks const { data: user } = useUser(); const { config } = useInstance(); + const { isIntercomToggle, toggleIntercom } = useTransient(); + + useEffect(() => { + if (isIntercomToggle) show(); + else hide(); + }, [isIntercomToggle]); + + onHide(() => { + toggleIntercom(false); + }); useEffect(() => { if (user && config?.is_intercom_enabled && config.intercom_app_id) { @@ -23,9 +33,10 @@ const IntercomProvider: FC = observer((props) => { user_id: user.id, name: `${user.first_name} ${user.last_name}`, email: user.email, + hide_default_launcher: true, }); } - }, [user, config]); + }, [user, config, toggleIntercom]); return <>{children}; }); diff --git a/web/core/store/root.store.ts b/web/core/store/root.store.ts index 709076ceb97..af38f51b28c 100644 --- a/web/core/store/root.store.ts +++ b/web/core/store/root.store.ts @@ -23,6 +23,7 @@ import { IProjectViewStore, ProjectViewStore } from "./project-view.store"; import { RouterStore, IRouterStore } from "./router.store"; import { IStateStore, StateStore } from "./state.store"; import { ThemeStore, IThemeStore } from "./theme.store"; +import { ITransientStore, TransientStore } from "./transient.store"; import { IUserStore, UserStore } from "./user"; import { IWorkspaceRootStore, WorkspaceRootStore } from "./workspace"; @@ -54,6 +55,7 @@ export class CoreRootStore { multipleSelect: IMultipleSelectStore; workspaceNotification: IWorkspaceNotificationStore; favorite: IFavoriteStore; + transient: ITransientStore; constructor() { this.router = new RouterStore(); @@ -81,6 +83,7 @@ export class CoreRootStore { this.projectEstimate = new ProjectEstimateStore(this); this.workspaceNotification = new WorkspaceNotificationStore(this); this.favorite = new FavoriteStore(this); + this.transient = new TransientStore(); } resetOnSignOut() { @@ -110,5 +113,7 @@ export class CoreRootStore { this.multipleSelect = new MultipleSelectStore(); this.projectEstimate = new ProjectEstimateStore(this); this.workspaceNotification = new WorkspaceNotificationStore(this); + this.favorite = new FavoriteStore(this); + this.transient = new TransientStore(); } } diff --git a/web/core/store/transient.store.ts b/web/core/store/transient.store.ts new file mode 100644 index 00000000000..c7bacce616a --- /dev/null +++ b/web/core/store/transient.store.ts @@ -0,0 +1,28 @@ +import { action, observable, makeObservable } from "mobx"; + +export interface ITransientStore { + // observables + isIntercomToggle: boolean; + // actions + toggleIntercom: (intercomToggle: boolean) => void; +} + +export class TransientStore implements ITransientStore { + // observables + isIntercomToggle: boolean = false; + + constructor() { + makeObservable(this, { + // observable + isIntercomToggle: observable.ref, + // action + toggleIntercom: action, + }); + } + + /** + * @description Toggle the intercom collapsed state + * @param { boolean } intercomToggle + */ + toggleIntercom = (intercomToggle: boolean) => (this.isIntercomToggle = intercomToggle); +} From d41daab97ee02ed3fb38bb9f64439cd74c4558d0 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia Date: Tue, 6 Aug 2024 15:50:04 +0530 Subject: [PATCH 2/2] fix: app sidebar improvement --- admin/core/components/admin-sidebar/help-section.tsx | 2 +- web/app/[workspaceSlug]/(projects)/sidebar.tsx | 12 ++++++++---- .../components/workspace/sidebar/help-section.tsx | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/admin/core/components/admin-sidebar/help-section.tsx b/admin/core/components/admin-sidebar/help-section.tsx index 4b516dff0bb..abba68e3eae 100644 --- a/admin/core/components/admin-sidebar/help-section.tsx +++ b/admin/core/components/admin-sidebar/help-section.tsx @@ -96,7 +96,7 @@ export const HelpSection: FC = observer(() => { leaveTo="transform opacity-0 scale-95" >
= observer(() => {
-
+
@@ -69,8 +73,8 @@ export const AppSidebar: FC = observer(() => { })} />
diff --git a/web/core/components/workspace/sidebar/help-section.tsx b/web/core/components/workspace/sidebar/help-section.tsx index 0921cf5e49e..43289f02a98 100644 --- a/web/core/components/workspace/sidebar/help-section.tsx +++ b/web/core/components/workspace/sidebar/help-section.tsx @@ -132,7 +132,7 @@ export const SidebarHelpSection: React.FC = observer( leaveTo="transform opacity-0 scale-95" >