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/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..43289f02a98 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)); @@ -133,7 +132,7 @@ export const SidebarHelpSection: React.FC = observer( leaveTo="transform opacity-0 scale-95" >
{ + 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); +}