diff --git a/apps/web/ce/hooks/pages/use-pages-pane-extensions.ts b/apps/web/ce/hooks/pages/use-pages-pane-extensions.ts index cd405c1ca4e..b73ffc58b01 100644 --- a/apps/web/ce/hooks/pages/use-pages-pane-extensions.ts +++ b/apps/web/ce/hooks/pages/use-pages-pane-extensions.ts @@ -4,6 +4,7 @@ import type { EditorRefApi } from "@plane/editor"; import { PAGE_NAVIGATION_PANE_TAB_KEYS, PAGE_NAVIGATION_PANE_TABS_QUERY_PARAM, + PAGE_NAVIGATION_PANE_VERSION_QUERY_PARAM, } from "@/components/pages/navigation-pane"; import { useAppRouter } from "@/hooks/use-app-router"; import { useQueryParams } from "@/hooks/use-query-params"; @@ -43,10 +44,18 @@ export const usePagesPaneExtensions = (_params: TPageExtensionHookParams) => { const navigationPaneExtensions: INavigationPaneExtension[] = []; + const handleCloseNavigationPane = useCallback(() => { + const updatedRoute = updateQueryParams({ + paramsToRemove: [PAGE_NAVIGATION_PANE_TABS_QUERY_PARAM, PAGE_NAVIGATION_PANE_VERSION_QUERY_PARAM], + }); + router.push(updatedRoute); + }, [router, updateQueryParams]); + return { editorExtensionHandlers, navigationPaneExtensions, handleOpenNavigationPane, isNavigationPaneOpen, + handleCloseNavigationPane, }; }; diff --git a/apps/web/core/components/editor/lite-text/editor.tsx b/apps/web/core/components/editor/lite-text/editor.tsx index 42d6f0bd95c..7e1cf4f7617 100644 --- a/apps/web/core/components/editor/lite-text/editor.tsx +++ b/apps/web/core/components/editor/lite-text/editor.tsx @@ -14,8 +14,9 @@ import { useEditorConfig, useEditorMention } from "@/hooks/editor"; import { useMember } from "@/hooks/store/use-member"; // plane web hooks import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging"; -// plane web services +// plane web service import { WorkspaceService } from "@/plane-web/services"; +import { LiteToolbar } from "./lite-toolbar"; const workspaceService = new WorkspaceService(); type LiteTextEditorWrapperProps = MakeOptional< @@ -31,9 +32,10 @@ type LiteTextEditorWrapperProps = MakeOptional< showSubmitButton?: boolean; isSubmitting?: boolean; showToolbarInitially?: boolean; - showToolbar?: boolean; + variant?: "full" | "lite" | "none"; issue_id?: string; parentClassName?: string; + editorClassName?: string; } & ( | { editable: false; @@ -59,14 +61,17 @@ export const LiteTextEditor = React.forwardRef !showToolbarInitially && setIsFocused(true)} - onBlur={() => !showToolbarInitially && setIsFocused(false)} + onFocus={() => isFullVariant && !showToolbarInitially && setIsFocused(true)} + onBlur={() => isFullVariant && !showToolbarInitially && setIsFocused(false)} > - "", - workspaceId, - workspaceSlug, - })} - mentionHandler={{ - searchCallback: async (query) => { - const res = await fetchMentions(query); - if (!res) throw new Error("Failed in fetching mentions"); - return res; - }, - renderComponent: EditorMentionsRoot, - getMentionedEntityDetails: (id) => ({ - display_name: getUserDetails(id)?.display_name ?? "", - }), - }} - placeholder={placeholder} - containerClassName={cn(containerClassName, "relative", { - "p-2": !editable, - })} - extendedEditorProps={{}} - {...rest} - /> - {showToolbar && editable && ( + {/* Wrapper for lite toolbar layout */} +
+ {/* Main Editor - always rendered once */} +
+ "", + workspaceId, + workspaceSlug, + })} + mentionHandler={{ + searchCallback: async (query) => { + const res = await fetchMentions(query); + if (!res) throw new Error("Failed in fetching mentions"); + return res; + }, + renderComponent: EditorMentionsRoot, + getMentionedEntityDetails: (id) => ({ + display_name: getUserDetails(id)?.display_name ?? "", + }), + }} + placeholder={placeholder} + containerClassName={cn(containerClassName, "relative", { + "p-2": !editable, + })} + extendedEditorProps={{}} + editorClassName={editorClassName} + {...rest} + /> +
+ + {/* Lite Toolbar - conditionally rendered */} + {isLiteVariant && editable && ( + { + // TODO: update this while toolbar homogenization + // @ts-expect-error type mismatch here + editorRef?.executeMenuItemCommand({ + itemKey: item.itemKey, + ...item.extraProps, + }); + }} + onSubmit={(e) => rest.onEnterKeyPress?.(e)} + isSubmitting={isSubmitting} + isEmpty={isEmpty} + /> + )} +
+ + {/* Full Toolbar - conditionally rendered */} + {isFullVariant && editable && (
| React.MouseEvent) => void; + isSubmitting: boolean; + isEmpty: boolean; + executeCommand: (item: ToolbarMenuItem) => void; +}; + +export const LiteToolbar = ({ onSubmit, isSubmitting, isEmpty, executeCommand }: LiteToolbarProps) => ( +
+ + +
+); + +export type { LiteToolbarProps }; diff --git a/apps/web/core/components/pages/editor/page-root.tsx b/apps/web/core/components/pages/editor/page-root.tsx index 3159691e136..487592b0195 100644 --- a/apps/web/core/components/pages/editor/page-root.tsx +++ b/apps/web/core/components/pages/editor/page-root.tsx @@ -6,7 +6,6 @@ import type { TDocumentPayload, TPage, TPageVersion, TWebhookConnectionQueryPara // hooks import { useAppRouter } from "@/hooks/use-app-router"; import { usePageFallback } from "@/hooks/use-page-fallback"; -import { useQueryParams } from "@/hooks/use-query-params"; // plane web import import { PageModals } from "@/plane-web/components/pages"; import { usePagesPaneExtensions, useExtendedEditorProps } from "@/plane-web/hooks/pages"; @@ -14,11 +13,7 @@ import { EPageStoreType } from "@/plane-web/hooks/store"; // store import type { TPageInstance } from "@/store/pages/base-page"; // local imports -import { - PAGE_NAVIGATION_PANE_TABS_QUERY_PARAM, - PAGE_NAVIGATION_PANE_VERSION_QUERY_PARAM, - PageNavigationPaneRoot, -} from "../navigation-pane"; +import { PageNavigationPaneRoot } from "../navigation-pane"; import { PageVersionsOverlay } from "../version"; import { PagesVersionEditor } from "../version/editor"; import { PageEditorBody, type TEditorBodyConfig, type TEditorBodyHandlers } from "./editor-body"; @@ -66,7 +61,6 @@ export const PageRoot = observer((props: TPageRootProps) => { hasConnectionFailed, updatePageDescription: handlers.updateDescription, }); - const { updateQueryParams } = useQueryParams(); const handleEditorReady = useCallback( (status: boolean) => { @@ -85,11 +79,16 @@ export const PageRoot = observer((props: TPageRootProps) => { }, [isContentEditable, setEditorRef]); // Get extensions and navigation logic from hook - const { editorExtensionHandlers, navigationPaneExtensions, handleOpenNavigationPane, isNavigationPaneOpen } = - usePagesPaneExtensions({ - page, - editorRef, - }); + const { + editorExtensionHandlers, + navigationPaneExtensions, + handleOpenNavigationPane, + handleCloseNavigationPane, + isNavigationPaneOpen, + } = usePagesPaneExtensions({ + page, + editorRef, + }); // Get extended editor extensions configuration const extendedEditorProps = useExtendedEditorProps({ @@ -118,13 +117,6 @@ export const PageRoot = observer((props: TPageRootProps) => { [setEditorRef] ); - const handleCloseNavigationPane = useCallback(() => { - const updatedRoute = updateQueryParams({ - paramsToRemove: [PAGE_NAVIGATION_PANE_TABS_QUERY_PARAM, PAGE_NAVIGATION_PANE_VERSION_QUERY_PARAM], - }); - router.push(updatedRoute); - }, [router, updateQueryParams]); - return (
diff --git a/apps/web/core/constants/editor.ts b/apps/web/core/constants/editor.ts index ff046b917df..c6bc2fef400 100644 --- a/apps/web/core/constants/editor.ts +++ b/apps/web/core/constants/editor.ts @@ -158,9 +158,18 @@ const USER_ACTION_ITEMS: ToolbarMenuItem<"quote" | "code">[] = [ { itemKey: "code", renderKey: "code", name: "Code", icon: Code2, editors: ["lite", "document"] }, ]; +export const IMAGE_ITEM = { + itemKey: "image", + renderKey: "image", + name: "Image", + icon: Image, + editors: ["lite", "document"], + extraProps: {}, +} as ToolbarMenuItem<"image">; + const COMPLEX_ITEMS: ToolbarMenuItem<"table" | "image">[] = [ { itemKey: "table", renderKey: "table", name: "Table", icon: Table, editors: ["document"] }, - { itemKey: "image", renderKey: "image", name: "Image", icon: Image, editors: ["lite", "document"], extraProps: {} }, + IMAGE_ITEM, ]; export const TOOLBAR_ITEMS: { diff --git a/packages/editor/tsdown.config.ts b/packages/editor/tsdown.config.ts index 348f1fd7a7e..5e9a7b960ad 100644 --- a/packages/editor/tsdown.config.ts +++ b/packages/editor/tsdown.config.ts @@ -5,7 +5,7 @@ export default defineConfig({ outDir: "dist", format: ["esm", "cjs"], dts: true, - clean: true, + clean: false, sourcemap: true, copy: ["src/styles"], });