[WEB-462] refactor: editor props structure (#7233)
* refactor: editor props structure * chore: add missing prop * fix: space app build * chore: export ce types
This commit is contained in:
parent
eb5ffebcc6
commit
8988cf9a85
41 changed files with 348 additions and 347 deletions
|
|
@ -1,13 +1,13 @@
|
||||||
import { Extensions } from "@tiptap/core";
|
import type { Extensions } from "@tiptap/core";
|
||||||
// types
|
// types
|
||||||
import { TExtensions, TFileHandler } from "@/types";
|
import type { IEditorProps } from "@/types";
|
||||||
|
|
||||||
type Props = {
|
export type TCoreAdditionalExtensionsProps = Pick<
|
||||||
disabledExtensions: TExtensions[];
|
IEditorProps,
|
||||||
fileHandler: TFileHandler;
|
"disabledExtensions" | "flaggedExtensions" | "fileHandler"
|
||||||
};
|
>;
|
||||||
|
|
||||||
export const CoreEditorAdditionalExtensions = (props: Props): Extensions => {
|
export const CoreEditorAdditionalExtensions = (props: TCoreAdditionalExtensionsProps): Extensions => {
|
||||||
const {} = props;
|
const {} = props;
|
||||||
return [];
|
return [];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
import { Extensions } from "@tiptap/core";
|
import type { Extensions } from "@tiptap/core";
|
||||||
// types
|
// types
|
||||||
import { TExtensions } from "@/types";
|
import type { IReadOnlyEditorProps } from "@/types";
|
||||||
|
|
||||||
type Props = {
|
export type TCoreReadOnlyEditorAdditionalExtensionsProps = Pick<
|
||||||
disabledExtensions: TExtensions[];
|
IReadOnlyEditorProps,
|
||||||
};
|
"disabledExtensions" | "flaggedExtensions"
|
||||||
|
>;
|
||||||
|
|
||||||
export const CoreReadOnlyEditorAdditionalExtensions = (props: Props): Extensions => {
|
export const CoreReadOnlyEditorAdditionalExtensions = (
|
||||||
|
props: TCoreReadOnlyEditorAdditionalExtensionsProps
|
||||||
|
): Extensions => {
|
||||||
const {} = props;
|
const {} = props;
|
||||||
return [];
|
return [];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,39 @@
|
||||||
import { HocuspocusProvider } from "@hocuspocus/provider";
|
import type { HocuspocusProvider } from "@hocuspocus/provider";
|
||||||
import { AnyExtension } from "@tiptap/core";
|
import type { AnyExtension } from "@tiptap/core";
|
||||||
import { SlashCommands } from "@/extensions";
|
import { SlashCommands } from "@/extensions";
|
||||||
// plane editor types
|
// plane editor types
|
||||||
import { TEmbedConfig } from "@/plane-editor/types";
|
import type { TEmbedConfig } from "@/plane-editor/types";
|
||||||
// types
|
// types
|
||||||
import { TExtensions, TFileHandler, TUserDetails } from "@/types";
|
import type { IEditorProps, TExtensions, TUserDetails } from "@/types";
|
||||||
|
|
||||||
export type TDocumentEditorAdditionalExtensionsProps = {
|
export type TDocumentEditorAdditionalExtensionsProps = Pick<
|
||||||
disabledExtensions: TExtensions[];
|
IEditorProps,
|
||||||
|
"disabledExtensions" | "flaggedExtensions" | "fileHandler"
|
||||||
|
> & {
|
||||||
embedConfig: TEmbedConfig | undefined;
|
embedConfig: TEmbedConfig | undefined;
|
||||||
fileHandler: TFileHandler;
|
|
||||||
provider?: HocuspocusProvider;
|
provider?: HocuspocusProvider;
|
||||||
userDetails: TUserDetails;
|
userDetails: TUserDetails;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TDocumentEditorAdditionalExtensionsRegistry = {
|
export type TDocumentEditorAdditionalExtensionsRegistry = {
|
||||||
isEnabled: (disabledExtensions: TExtensions[]) => boolean;
|
isEnabled: (disabledExtensions: TExtensions[], flaggedExtensions: TExtensions[]) => boolean;
|
||||||
getExtension: (props: TDocumentEditorAdditionalExtensionsProps) => AnyExtension;
|
getExtension: (props: TDocumentEditorAdditionalExtensionsProps) => AnyExtension;
|
||||||
};
|
};
|
||||||
|
|
||||||
const extensionRegistry: TDocumentEditorAdditionalExtensionsRegistry[] = [
|
const extensionRegistry: TDocumentEditorAdditionalExtensionsRegistry[] = [
|
||||||
{
|
{
|
||||||
isEnabled: (disabledExtensions) => !disabledExtensions.includes("slash-commands"),
|
isEnabled: (disabledExtensions) => !disabledExtensions.includes("slash-commands"),
|
||||||
getExtension: ({ disabledExtensions }) => SlashCommands({ disabledExtensions }),
|
getExtension: ({ disabledExtensions, flaggedExtensions }) =>
|
||||||
|
SlashCommands({ disabledExtensions, flaggedExtensions }),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const DocumentEditorAdditionalExtensions = (_props: TDocumentEditorAdditionalExtensionsProps) => {
|
export const DocumentEditorAdditionalExtensions = (props: TDocumentEditorAdditionalExtensionsProps) => {
|
||||||
const { disabledExtensions = [] } = _props;
|
const { disabledExtensions, flaggedExtensions } = props;
|
||||||
|
|
||||||
const documentExtensions = extensionRegistry
|
const documentExtensions = extensionRegistry
|
||||||
.filter((config) => config.isEnabled(disabledExtensions))
|
.filter((config) => config.isEnabled(disabledExtensions, flaggedExtensions))
|
||||||
.map((config) => config.getExtension(_props));
|
.map((config) => config.getExtension(props));
|
||||||
|
|
||||||
return documentExtensions;
|
return documentExtensions;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,19 @@ import { AnyExtension, Extensions } from "@tiptap/core";
|
||||||
// extensions
|
// extensions
|
||||||
import { SlashCommands } from "@/extensions/slash-commands/root";
|
import { SlashCommands } from "@/extensions/slash-commands/root";
|
||||||
// types
|
// types
|
||||||
import { TExtensions, TFileHandler } from "@/types";
|
import { IEditorProps, TExtensions } from "@/types";
|
||||||
|
|
||||||
export type TRichTextEditorAdditionalExtensionsProps = {
|
export type TRichTextEditorAdditionalExtensionsProps = Pick<
|
||||||
disabledExtensions: TExtensions[];
|
IEditorProps,
|
||||||
fileHandler: TFileHandler;
|
"disabledExtensions" | "flaggedExtensions" | "fileHandler"
|
||||||
};
|
>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registry entry configuration for extensions
|
* Registry entry configuration for extensions
|
||||||
*/
|
*/
|
||||||
export type TRichTextEditorAdditionalExtensionsRegistry = {
|
export type TRichTextEditorAdditionalExtensionsRegistry = {
|
||||||
/** Determines if the extension should be enabled based on disabled extensions */
|
/** Determines if the extension should be enabled based on disabled extensions */
|
||||||
isEnabled: (disabledExtensions: TExtensions[]) => boolean;
|
isEnabled: (disabledExtensions: TExtensions[], flaggedExtensions: TExtensions[]) => boolean;
|
||||||
/** Returns the extension instance(s) when enabled */
|
/** Returns the extension instance(s) when enabled */
|
||||||
getExtension: (props: TRichTextEditorAdditionalExtensionsProps) => AnyExtension | undefined;
|
getExtension: (props: TRichTextEditorAdditionalExtensionsProps) => AnyExtension | undefined;
|
||||||
};
|
};
|
||||||
|
|
@ -22,18 +22,19 @@ export type TRichTextEditorAdditionalExtensionsRegistry = {
|
||||||
const extensionRegistry: TRichTextEditorAdditionalExtensionsRegistry[] = [
|
const extensionRegistry: TRichTextEditorAdditionalExtensionsRegistry[] = [
|
||||||
{
|
{
|
||||||
isEnabled: (disabledExtensions) => !disabledExtensions.includes("slash-commands"),
|
isEnabled: (disabledExtensions) => !disabledExtensions.includes("slash-commands"),
|
||||||
getExtension: ({ disabledExtensions }) =>
|
getExtension: ({ disabledExtensions, flaggedExtensions }) =>
|
||||||
SlashCommands({
|
SlashCommands({
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
|
flaggedExtensions,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const RichTextEditorAdditionalExtensions = (props: TRichTextEditorAdditionalExtensionsProps) => {
|
export const RichTextEditorAdditionalExtensions = (props: TRichTextEditorAdditionalExtensionsProps) => {
|
||||||
const { disabledExtensions } = props;
|
const { disabledExtensions, flaggedExtensions } = props;
|
||||||
|
|
||||||
const extensions: Extensions = extensionRegistry
|
const extensions: Extensions = extensionRegistry
|
||||||
.filter((config) => config.isEnabled(disabledExtensions))
|
.filter((config) => config.isEnabled(disabledExtensions, flaggedExtensions))
|
||||||
.map((config) => config.getExtension(props))
|
.map((config) => config.getExtension(props))
|
||||||
.filter((extension): extension is AnyExtension => extension !== undefined);
|
.filter((extension): extension is AnyExtension => extension !== undefined);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import { AnyExtension, Extensions } from "@tiptap/core";
|
import { AnyExtension, Extensions } from "@tiptap/core";
|
||||||
// types
|
// types
|
||||||
import { TExtensions, TReadOnlyFileHandler } from "@/types";
|
import { IReadOnlyEditorProps, TExtensions } from "@/types";
|
||||||
|
|
||||||
export type TRichTextReadOnlyEditorAdditionalExtensionsProps = {
|
export type TRichTextReadOnlyEditorAdditionalExtensionsProps = Pick<
|
||||||
disabledExtensions: TExtensions[];
|
IReadOnlyEditorProps,
|
||||||
fileHandler: TReadOnlyFileHandler;
|
"disabledExtensions" | "flaggedExtensions" | "fileHandler"
|
||||||
};
|
>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registry entry configuration for extensions
|
* Registry entry configuration for extensions
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
// extensions
|
// extensions
|
||||||
import { TSlashCommandAdditionalOption } from "@/extensions";
|
import type { TSlashCommandAdditionalOption } from "@/extensions";
|
||||||
// types
|
// types
|
||||||
import { TExtensions } from "@/types";
|
import type { IEditorProps } from "@/types";
|
||||||
|
|
||||||
type Props = {
|
type Props = Pick<IEditorProps, "disabledExtensions" | "flaggedExtensions">;
|
||||||
disabledExtensions?: TExtensions[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const coreEditorAdditionalSlashCommandOptions = (props: Props): TSlashCommandAdditionalOption[] => {
|
export const coreEditorAdditionalSlashCommandOptions = (props: Props): TSlashCommandAdditionalOption[] => {
|
||||||
const {} = props;
|
const {} = props;
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,11 @@ import { getEditorClassNames } from "@/helpers/common";
|
||||||
// hooks
|
// hooks
|
||||||
import { useCollaborativeEditor } from "@/hooks/use-collaborative-editor";
|
import { useCollaborativeEditor } from "@/hooks/use-collaborative-editor";
|
||||||
// types
|
// types
|
||||||
import { EditorRefApi, ICollaborativeDocumentEditor } from "@/types";
|
import { EditorRefApi, ICollaborativeDocumentEditorProps } from "@/types";
|
||||||
|
|
||||||
const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => {
|
const CollaborativeDocumentEditor: React.FC<ICollaborativeDocumentEditorProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
|
onChange,
|
||||||
onTransaction,
|
onTransaction,
|
||||||
aiHandler,
|
aiHandler,
|
||||||
bubbleMenuEnabled = true,
|
bubbleMenuEnabled = true,
|
||||||
|
|
@ -27,6 +28,7 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => {
|
||||||
editorClassName = "",
|
editorClassName = "",
|
||||||
embedHandler,
|
embedHandler,
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
forwardedRef,
|
forwardedRef,
|
||||||
handleEditorReady,
|
handleEditorReady,
|
||||||
id,
|
id,
|
||||||
|
|
@ -56,10 +58,12 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => {
|
||||||
embedHandler,
|
embedHandler,
|
||||||
extensions,
|
extensions,
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
forwardedRef,
|
forwardedRef,
|
||||||
handleEditorReady,
|
handleEditorReady,
|
||||||
id,
|
id,
|
||||||
mentionHandler,
|
mentionHandler,
|
||||||
|
onChange,
|
||||||
onTransaction,
|
onTransaction,
|
||||||
placeholder,
|
placeholder,
|
||||||
realtimeConfig,
|
realtimeConfig,
|
||||||
|
|
@ -95,7 +99,7 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const CollaborativeDocumentEditorWithRef = React.forwardRef<EditorRefApi, ICollaborativeDocumentEditor>(
|
const CollaborativeDocumentEditorWithRef = React.forwardRef<EditorRefApi, ICollaborativeDocumentEditorProps>(
|
||||||
(props, ref) => (
|
(props, ref) => (
|
||||||
<CollaborativeDocumentEditor {...props} forwardedRef={ref as React.MutableRefObject<EditorRefApi | null>} />
|
<CollaborativeDocumentEditor {...props} forwardedRef={ref as React.MutableRefObject<EditorRefApi | null>} />
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { AIFeaturesMenu, BlockMenu, EditorBubbleMenu } from "@/components/menus"
|
||||||
// types
|
// types
|
||||||
import { TAIHandler, TDisplayConfig } from "@/types";
|
import { TAIHandler, TDisplayConfig } from "@/types";
|
||||||
|
|
||||||
type IPageRenderer = {
|
type Props = {
|
||||||
aiHandler?: TAIHandler;
|
aiHandler?: TAIHandler;
|
||||||
bubbleMenuEnabled: boolean;
|
bubbleMenuEnabled: boolean;
|
||||||
displayConfig: TDisplayConfig;
|
displayConfig: TDisplayConfig;
|
||||||
|
|
@ -15,7 +15,7 @@ type IPageRenderer = {
|
||||||
tabIndex?: number;
|
tabIndex?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PageRenderer = (props: IPageRenderer) => {
|
export const PageRenderer = (props: Props) => {
|
||||||
const { aiHandler, bubbleMenuEnabled, displayConfig, editor, editorContainerClassName, id, tabIndex } = props;
|
const { aiHandler, bubbleMenuEnabled, displayConfig, editor, editorContainerClassName, id, tabIndex } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Extensions } from "@tiptap/core";
|
import { Extensions } from "@tiptap/core";
|
||||||
import { forwardRef, MutableRefObject } from "react";
|
import React, { forwardRef, MutableRefObject } from "react";
|
||||||
// plane imports
|
// plane imports
|
||||||
import { cn } from "@plane/utils";
|
import { cn } from "@plane/utils";
|
||||||
// components
|
// components
|
||||||
|
|
@ -13,30 +13,9 @@ import { getEditorClassNames } from "@/helpers/common";
|
||||||
// hooks
|
// hooks
|
||||||
import { useReadOnlyEditor } from "@/hooks/use-read-only-editor";
|
import { useReadOnlyEditor } from "@/hooks/use-read-only-editor";
|
||||||
// types
|
// types
|
||||||
import {
|
import { EditorReadOnlyRefApi, IDocumentReadOnlyEditorProps } from "@/types";
|
||||||
EditorReadOnlyRefApi,
|
|
||||||
TDisplayConfig,
|
|
||||||
TExtensions,
|
|
||||||
TReadOnlyFileHandler,
|
|
||||||
TReadOnlyMentionHandler,
|
|
||||||
} from "@/types";
|
|
||||||
|
|
||||||
interface IDocumentReadOnlyEditor {
|
const DocumentReadOnlyEditor: React.FC<IDocumentReadOnlyEditorProps> = (props) => {
|
||||||
disabledExtensions: TExtensions[];
|
|
||||||
id: string;
|
|
||||||
initialValue: string;
|
|
||||||
containerClassName: string;
|
|
||||||
displayConfig?: TDisplayConfig;
|
|
||||||
editorClassName?: string;
|
|
||||||
embedHandler: any;
|
|
||||||
fileHandler: TReadOnlyFileHandler;
|
|
||||||
tabIndex?: number;
|
|
||||||
handleEditorReady?: (value: boolean) => void;
|
|
||||||
mentionHandler: TReadOnlyMentionHandler;
|
|
||||||
forwardedRef?: React.MutableRefObject<EditorReadOnlyRefApi | null>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DocumentReadOnlyEditor = (props: IDocumentReadOnlyEditor) => {
|
|
||||||
const {
|
const {
|
||||||
containerClassName,
|
containerClassName,
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
|
|
@ -44,6 +23,7 @@ const DocumentReadOnlyEditor = (props: IDocumentReadOnlyEditor) => {
|
||||||
editorClassName = "",
|
editorClassName = "",
|
||||||
embedHandler,
|
embedHandler,
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
id,
|
id,
|
||||||
forwardedRef,
|
forwardedRef,
|
||||||
handleEditorReady,
|
handleEditorReady,
|
||||||
|
|
@ -64,6 +44,7 @@ const DocumentReadOnlyEditor = (props: IDocumentReadOnlyEditor) => {
|
||||||
editorClassName,
|
editorClassName,
|
||||||
extensions,
|
extensions,
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
forwardedRef,
|
forwardedRef,
|
||||||
handleEditorReady,
|
handleEditorReady,
|
||||||
initialValue,
|
initialValue,
|
||||||
|
|
@ -87,7 +68,7 @@ const DocumentReadOnlyEditor = (props: IDocumentReadOnlyEditor) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const DocumentReadOnlyEditorWithRef = forwardRef<EditorReadOnlyRefApi, IDocumentReadOnlyEditor>((props, ref) => (
|
const DocumentReadOnlyEditorWithRef = forwardRef<EditorReadOnlyRefApi, IDocumentReadOnlyEditorProps>((props, ref) => (
|
||||||
<DocumentReadOnlyEditor {...props} forwardedRef={ref as MutableRefObject<EditorReadOnlyRefApi | null>} />
|
<DocumentReadOnlyEditor {...props} forwardedRef={ref as MutableRefObject<EditorReadOnlyRefApi | null>} />
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ export const EditorWrapper: React.FC<Props> = (props) => {
|
||||||
id,
|
id,
|
||||||
initialValue,
|
initialValue,
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
forwardedRef,
|
forwardedRef,
|
||||||
mentionHandler,
|
mentionHandler,
|
||||||
onChange,
|
onChange,
|
||||||
|
|
@ -44,6 +45,7 @@ export const EditorWrapper: React.FC<Props> = (props) => {
|
||||||
enableHistory: true,
|
enableHistory: true,
|
||||||
extensions,
|
extensions,
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
forwardedRef,
|
forwardedRef,
|
||||||
id,
|
id,
|
||||||
initialValue,
|
initialValue,
|
||||||
|
|
|
||||||
|
|
@ -4,23 +4,25 @@ import { EditorWrapper } from "@/components/editors/editor-wrapper";
|
||||||
// extensions
|
// extensions
|
||||||
import { EnterKeyExtension } from "@/extensions";
|
import { EnterKeyExtension } from "@/extensions";
|
||||||
// types
|
// types
|
||||||
import { EditorRefApi, ILiteTextEditor } from "@/types";
|
import { EditorRefApi, ILiteTextEditorProps } from "@/types";
|
||||||
|
|
||||||
const LiteTextEditor = (props: ILiteTextEditor) => {
|
const LiteTextEditor: React.FC<ILiteTextEditorProps> = (props) => {
|
||||||
const { onEnterKeyPress, disabledExtensions, extensions: externalExtensions = [] } = props;
|
const { onEnterKeyPress, disabledExtensions, extensions: externalExtensions = [] } = props;
|
||||||
|
|
||||||
const extensions = useMemo(
|
const extensions = useMemo(() => {
|
||||||
() => [
|
const resolvedExtensions = [...externalExtensions];
|
||||||
...externalExtensions,
|
|
||||||
...(disabledExtensions?.includes("enter-key") ? [] : [EnterKeyExtension(onEnterKeyPress)]),
|
if (!disabledExtensions?.includes("enter-key")) {
|
||||||
],
|
resolvedExtensions.push(EnterKeyExtension(onEnterKeyPress));
|
||||||
[externalExtensions, disabledExtensions, onEnterKeyPress]
|
}
|
||||||
);
|
|
||||||
|
return resolvedExtensions;
|
||||||
|
}, [externalExtensions, disabledExtensions, onEnterKeyPress]);
|
||||||
|
|
||||||
return <EditorWrapper {...props} extensions={extensions} />;
|
return <EditorWrapper {...props} extensions={extensions} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
const LiteTextEditorWithRef = forwardRef<EditorRefApi, ILiteTextEditor>((props, ref) => (
|
const LiteTextEditorWithRef = forwardRef<EditorRefApi, ILiteTextEditorProps>((props, ref) => (
|
||||||
<LiteTextEditor {...props} forwardedRef={ref as React.MutableRefObject<EditorRefApi | null>} />
|
<LiteTextEditor {...props} forwardedRef={ref as React.MutableRefObject<EditorRefApi | null>} />
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@ import { forwardRef } from "react";
|
||||||
// components
|
// components
|
||||||
import { ReadOnlyEditorWrapper } from "@/components/editors";
|
import { ReadOnlyEditorWrapper } from "@/components/editors";
|
||||||
// types
|
// types
|
||||||
import { EditorReadOnlyRefApi, ILiteTextReadOnlyEditor } from "@/types";
|
import { EditorReadOnlyRefApi, ILiteTextReadOnlyEditorProps } from "@/types";
|
||||||
|
|
||||||
const LiteTextReadOnlyEditorWithRef = forwardRef<EditorReadOnlyRefApi, ILiteTextReadOnlyEditor>((props, ref) => (
|
const LiteTextReadOnlyEditorWithRef = forwardRef<EditorReadOnlyRefApi, ILiteTextReadOnlyEditorProps>((props, ref) => (
|
||||||
<ReadOnlyEditorWrapper {...props} forwardedRef={ref as React.MutableRefObject<EditorReadOnlyRefApi | null>} />
|
<ReadOnlyEditorWrapper {...props} forwardedRef={ref as React.MutableRefObject<EditorReadOnlyRefApi | null>} />
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ export const ReadOnlyEditorWrapper = (props: IReadOnlyEditorProps) => {
|
||||||
editorClassName = "",
|
editorClassName = "",
|
||||||
extensions,
|
extensions,
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
forwardedRef,
|
forwardedRef,
|
||||||
id,
|
id,
|
||||||
initialValue,
|
initialValue,
|
||||||
|
|
@ -28,6 +29,7 @@ export const ReadOnlyEditorWrapper = (props: IReadOnlyEditorProps) => {
|
||||||
editorClassName,
|
editorClassName,
|
||||||
extensions,
|
extensions,
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
forwardedRef,
|
forwardedRef,
|
||||||
initialValue,
|
initialValue,
|
||||||
mentionHandler,
|
mentionHandler,
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,16 @@ import { SideMenuExtension } from "@/extensions";
|
||||||
// plane editor imports
|
// plane editor imports
|
||||||
import { RichTextEditorAdditionalExtensions } from "@/plane-editor/extensions/rich-text/extensions";
|
import { RichTextEditorAdditionalExtensions } from "@/plane-editor/extensions/rich-text/extensions";
|
||||||
// types
|
// types
|
||||||
import { EditorRefApi, IRichTextEditor } from "@/types";
|
import { EditorRefApi, IRichTextEditorProps } from "@/types";
|
||||||
|
|
||||||
const RichTextEditor = (props: IRichTextEditor) => {
|
const RichTextEditor: React.FC<IRichTextEditorProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
|
bubbleMenuEnabled = true,
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
dragDropEnabled,
|
dragDropEnabled,
|
||||||
fileHandler,
|
|
||||||
bubbleMenuEnabled = true,
|
|
||||||
extensions: externalExtensions = [],
|
extensions: externalExtensions = [],
|
||||||
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const getExtensions = useCallback(() => {
|
const getExtensions = useCallback(() => {
|
||||||
|
|
@ -28,11 +29,12 @@ const RichTextEditor = (props: IRichTextEditor) => {
|
||||||
...RichTextEditorAdditionalExtensions({
|
...RichTextEditorAdditionalExtensions({
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
return extensions;
|
return extensions;
|
||||||
}, [dragDropEnabled, disabledExtensions, externalExtensions, fileHandler]);
|
}, [dragDropEnabled, disabledExtensions, externalExtensions, fileHandler, flaggedExtensions]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EditorWrapper {...props} extensions={getExtensions()}>
|
<EditorWrapper {...props} extensions={getExtensions()}>
|
||||||
|
|
@ -41,7 +43,7 @@ const RichTextEditor = (props: IRichTextEditor) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const RichTextEditorWithRef = forwardRef<EditorRefApi, IRichTextEditor>((props, ref) => (
|
const RichTextEditorWithRef = forwardRef<EditorRefApi, IRichTextEditorProps>((props, ref) => (
|
||||||
<RichTextEditor {...props} forwardedRef={ref as React.MutableRefObject<EditorRefApi | null>} />
|
<RichTextEditor {...props} forwardedRef={ref as React.MutableRefObject<EditorRefApi | null>} />
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,23 +2,22 @@ import { forwardRef, useCallback } from "react";
|
||||||
// plane editor extensions
|
// plane editor extensions
|
||||||
import { RichTextReadOnlyEditorAdditionalExtensions } from "@/plane-editor/extensions/rich-text/read-only-extensions";
|
import { RichTextReadOnlyEditorAdditionalExtensions } from "@/plane-editor/extensions/rich-text/read-only-extensions";
|
||||||
// types
|
// types
|
||||||
import { EditorReadOnlyRefApi, IRichTextReadOnlyEditor } from "@/types";
|
import { EditorReadOnlyRefApi, IRichTextReadOnlyEditorProps } from "@/types";
|
||||||
// local imports
|
// local imports
|
||||||
import { ReadOnlyEditorWrapper } from "../read-only-editor-wrapper";
|
import { ReadOnlyEditorWrapper } from "../read-only-editor-wrapper";
|
||||||
|
|
||||||
const RichTextReadOnlyEditorWithRef = forwardRef<EditorReadOnlyRefApi, IRichTextReadOnlyEditor>((props, ref) => {
|
const RichTextReadOnlyEditorWithRef = forwardRef<EditorReadOnlyRefApi, IRichTextReadOnlyEditorProps>((props, ref) => {
|
||||||
const { disabledExtensions, fileHandler } = props;
|
const { disabledExtensions, fileHandler, flaggedExtensions } = props;
|
||||||
|
|
||||||
const getExtensions = useCallback(() => {
|
const getExtensions = useCallback(() => {
|
||||||
const extensions = [
|
const extensions = RichTextReadOnlyEditorAdditionalExtensions({
|
||||||
...RichTextReadOnlyEditorAdditionalExtensions({
|
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
fileHandler,
|
fileHandler,
|
||||||
}),
|
flaggedExtensions,
|
||||||
];
|
});
|
||||||
|
|
||||||
return extensions;
|
return extensions;
|
||||||
}, [disabledExtensions, fileHandler]);
|
}, [disabledExtensions, fileHandler, flaggedExtensions]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ReadOnlyEditorWrapper
|
<ReadOnlyEditorWrapper
|
||||||
|
|
|
||||||
|
|
@ -37,20 +37,27 @@ import { getExtensionStorage } from "@/helpers/get-extension-storage";
|
||||||
// plane editor extensions
|
// plane editor extensions
|
||||||
import { CoreEditorAdditionalExtensions } from "@/plane-editor/extensions";
|
import { CoreEditorAdditionalExtensions } from "@/plane-editor/extensions";
|
||||||
// types
|
// types
|
||||||
import { TExtensions, TFileHandler, TMentionHandler } from "@/types";
|
import type { IEditorProps } from "@/types";
|
||||||
|
|
||||||
type TArguments = {
|
type TArguments = Pick<
|
||||||
disabledExtensions: TExtensions[];
|
IEditorProps,
|
||||||
|
"disabledExtensions" | "flaggedExtensions" | "fileHandler" | "mentionHandler" | "placeholder" | "tabIndex"
|
||||||
|
> & {
|
||||||
enableHistory: boolean;
|
enableHistory: boolean;
|
||||||
fileHandler: TFileHandler;
|
|
||||||
mentionHandler: TMentionHandler;
|
|
||||||
placeholder?: string | ((isFocused: boolean, value: string) => string);
|
|
||||||
tabIndex?: number;
|
|
||||||
editable: boolean;
|
editable: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CoreEditorExtensions = (args: TArguments): Extensions => {
|
export const CoreEditorExtensions = (args: TArguments): Extensions => {
|
||||||
const { disabledExtensions, enableHistory, fileHandler, mentionHandler, placeholder, tabIndex, editable } = args;
|
const {
|
||||||
|
disabledExtensions,
|
||||||
|
enableHistory,
|
||||||
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
|
mentionHandler,
|
||||||
|
placeholder,
|
||||||
|
tabIndex,
|
||||||
|
editable,
|
||||||
|
} = args;
|
||||||
|
|
||||||
const extensions = [
|
const extensions = [
|
||||||
StarterKit.configure({
|
StarterKit.configure({
|
||||||
|
|
@ -177,6 +184,7 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => {
|
||||||
CustomColorExtension,
|
CustomColorExtension,
|
||||||
...CoreEditorAdditionalExtensions({
|
...CoreEditorAdditionalExtensions({
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
|
flaggedExtensions,
|
||||||
fileHandler,
|
fileHandler,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -31,16 +31,12 @@ import { isValidHttpUrl } from "@/helpers/common";
|
||||||
// plane editor extensions
|
// plane editor extensions
|
||||||
import { CoreReadOnlyEditorAdditionalExtensions } from "@/plane-editor/extensions";
|
import { CoreReadOnlyEditorAdditionalExtensions } from "@/plane-editor/extensions";
|
||||||
// types
|
// types
|
||||||
import { TExtensions, TReadOnlyFileHandler, TReadOnlyMentionHandler } from "@/types";
|
import type { IReadOnlyEditorProps } from "@/types";
|
||||||
|
|
||||||
type Props = {
|
type Props = Pick<IReadOnlyEditorProps, "disabledExtensions" | "flaggedExtensions" | "fileHandler" | "mentionHandler">;
|
||||||
disabledExtensions: TExtensions[];
|
|
||||||
fileHandler: TReadOnlyFileHandler;
|
|
||||||
mentionHandler: TReadOnlyMentionHandler;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const CoreReadOnlyEditorExtensions = (props: Props): Extensions => {
|
export const CoreReadOnlyEditorExtensions = (props: Props): Extensions => {
|
||||||
const { disabledExtensions, fileHandler, mentionHandler } = props;
|
const { disabledExtensions, fileHandler, flaggedExtensions, mentionHandler } = props;
|
||||||
|
|
||||||
const extensions = [
|
const extensions = [
|
||||||
StarterKit.configure({
|
StarterKit.configure({
|
||||||
|
|
@ -133,6 +129,7 @@ export const CoreReadOnlyEditorExtensions = (props: Props): Extensions => {
|
||||||
}),
|
}),
|
||||||
...CoreReadOnlyEditorAdditionalExtensions({
|
...CoreReadOnlyEditorAdditionalExtensions({
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
|
flaggedExtensions,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ export type TSlashCommandSection = {
|
||||||
export const getSlashCommandFilteredSections =
|
export const getSlashCommandFilteredSections =
|
||||||
(args: TExtensionProps) =>
|
(args: TExtensionProps) =>
|
||||||
({ query }: { query: string }): TSlashCommandSection[] => {
|
({ query }: { query: string }): TSlashCommandSection[] => {
|
||||||
const { additionalOptions: externalAdditionalOptions, disabledExtensions } = args;
|
const { additionalOptions: externalAdditionalOptions, disabledExtensions, flaggedExtensions } = args;
|
||||||
const SLASH_COMMAND_SECTIONS: TSlashCommandSection[] = [
|
const SLASH_COMMAND_SECTIONS: TSlashCommandSection[] = [
|
||||||
{
|
{
|
||||||
key: "general",
|
key: "general",
|
||||||
|
|
@ -290,6 +290,7 @@ export const getSlashCommandFilteredSections =
|
||||||
...(externalAdditionalOptions ?? []),
|
...(externalAdditionalOptions ?? []),
|
||||||
...coreEditorAdditionalSlashCommandOptions({
|
...coreEditorAdditionalSlashCommandOptions({
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
|
flaggedExtensions,
|
||||||
}),
|
}),
|
||||||
]?.forEach((item) => {
|
]?.forEach((item) => {
|
||||||
const sectionToPushTo = SLASH_COMMAND_SECTIONS.find((s) => s.key === item.section) ?? SLASH_COMMAND_SECTIONS[0];
|
const sectionToPushTo = SLASH_COMMAND_SECTIONS.find((s) => s.key === item.section) ?? SLASH_COMMAND_SECTIONS[0];
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { CORE_EXTENSIONS } from "@/constants/extension";
|
||||||
// helpers
|
// helpers
|
||||||
import { CommandListInstance } from "@/helpers/tippy";
|
import { CommandListInstance } from "@/helpers/tippy";
|
||||||
// types
|
// types
|
||||||
import { ISlashCommandItem, TEditorCommands, TExtensions, TSlashCommandSectionKeys } from "@/types";
|
import { IEditorProps, ISlashCommandItem, TEditorCommands, TSlashCommandSectionKeys } from "@/types";
|
||||||
// components
|
// components
|
||||||
import { getSlashCommandFilteredSections } from "./command-items-list";
|
import { getSlashCommandFilteredSections } from "./command-items-list";
|
||||||
import { SlashCommandsMenu, SlashCommandsMenuProps } from "./command-menu";
|
import { SlashCommandsMenu, SlashCommandsMenuProps } from "./command-menu";
|
||||||
|
|
@ -106,9 +106,8 @@ const renderItems = () => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TExtensionProps = {
|
export type TExtensionProps = Pick<IEditorProps, "disabledExtensions" | "flaggedExtensions"> & {
|
||||||
additionalOptions?: TSlashCommandAdditionalOption[];
|
additionalOptions?: TSlashCommandAdditionalOption[];
|
||||||
disabledExtensions?: TExtensions[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SlashCommands = (props: TExtensionProps) =>
|
export const SlashCommands = (props: TExtensionProps) =>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import { DropHandlerPlugin } from "@/plugins/drop";
|
||||||
import { FilePlugins } from "@/plugins/file/root";
|
import { FilePlugins } from "@/plugins/file/root";
|
||||||
import { MarkdownClipboardPlugin } from "@/plugins/markdown-clipboard";
|
import { MarkdownClipboardPlugin } from "@/plugins/markdown-clipboard";
|
||||||
// types
|
// types
|
||||||
import { TExtensions, TFileHandler, TReadOnlyFileHandler } from "@/types";
|
import type { IEditorProps, TFileHandler, TReadOnlyFileHandler } from "@/types";
|
||||||
|
|
||||||
declare module "@tiptap/core" {
|
declare module "@tiptap/core" {
|
||||||
interface Commands {
|
interface Commands {
|
||||||
|
|
@ -23,8 +23,7 @@ export interface UtilityExtensionStorage {
|
||||||
uploadInProgress: boolean;
|
uploadInProgress: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = Pick<IEditorProps, "disabledExtensions"> & {
|
||||||
disabledExtensions: TExtensions[];
|
|
||||||
fileHandler: TFileHandler | TReadOnlyFileHandler;
|
fileHandler: TFileHandler | TReadOnlyFileHandler;
|
||||||
isEditable: boolean;
|
isEditable: boolean;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,19 @@ import { useEditor } from "@/hooks/use-editor";
|
||||||
// plane editor extensions
|
// plane editor extensions
|
||||||
import { DocumentEditorAdditionalExtensions } from "@/plane-editor/extensions";
|
import { DocumentEditorAdditionalExtensions } from "@/plane-editor/extensions";
|
||||||
// types
|
// types
|
||||||
import { TCollaborativeEditorProps } from "@/types";
|
import { TCollaborativeEditorHookProps } from "@/types";
|
||||||
|
|
||||||
export const useCollaborativeEditor = (props: TCollaborativeEditorProps) => {
|
export const useCollaborativeEditor = (props: TCollaborativeEditorHookProps) => {
|
||||||
const {
|
const {
|
||||||
onTransaction,
|
onTransaction,
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
editable,
|
editable,
|
||||||
editorClassName,
|
editorClassName = "",
|
||||||
editorProps = {},
|
editorProps = {},
|
||||||
embedHandler,
|
embedHandler,
|
||||||
extensions,
|
extensions = [],
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
forwardedRef,
|
forwardedRef,
|
||||||
handleEditorReady,
|
handleEditorReady,
|
||||||
id,
|
id,
|
||||||
|
|
@ -89,16 +90,18 @@ export const useCollaborativeEditor = (props: TCollaborativeEditorProps) => {
|
||||||
Collaboration.configure({
|
Collaboration.configure({
|
||||||
document: provider.document,
|
document: provider.document,
|
||||||
}),
|
}),
|
||||||
...(extensions ?? []),
|
...extensions,
|
||||||
...DocumentEditorAdditionalExtensions({
|
...DocumentEditorAdditionalExtensions({
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
embedConfig: embedHandler,
|
embedConfig: embedHandler,
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
provider,
|
provider,
|
||||||
userDetails: user,
|
userDetails: user,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
forwardedRef,
|
forwardedRef,
|
||||||
handleEditorReady,
|
handleEditorReady,
|
||||||
mentionHandler,
|
mentionHandler,
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
import { HocuspocusProvider } from "@hocuspocus/provider";
|
|
||||||
import { DOMSerializer } from "@tiptap/pm/model";
|
import { DOMSerializer } from "@tiptap/pm/model";
|
||||||
import { EditorProps } from "@tiptap/pm/view";
|
import { useEditor as useTiptapEditor } from "@tiptap/react";
|
||||||
import { useEditor as useTiptapEditor, Extensions } from "@tiptap/react";
|
import { useImperativeHandle, useEffect } from "react";
|
||||||
import { useImperativeHandle, MutableRefObject, useEffect } from "react";
|
|
||||||
import * as Y from "yjs";
|
import * as Y from "yjs";
|
||||||
// components
|
// components
|
||||||
import { getEditorMenuItems } from "@/components/menus";
|
import { getEditorMenuItems } from "@/components/menus";
|
||||||
// constants
|
// constants
|
||||||
import { CORE_EXTENSIONS } from "@/constants/extension";
|
import { CORE_EXTENSIONS } from "@/constants/extension";
|
||||||
|
import { CORE_EDITOR_META } from "@/constants/meta";
|
||||||
// extensions
|
// extensions
|
||||||
import { CoreEditorExtensions } from "@/extensions";
|
import { CoreEditorExtensions } from "@/extensions";
|
||||||
// helpers
|
// helpers
|
||||||
|
|
@ -18,49 +17,19 @@ import { IMarking, scrollSummary, scrollToNodeViaDOMCoordinates } from "@/helper
|
||||||
// props
|
// props
|
||||||
import { CoreEditorProps } from "@/props";
|
import { CoreEditorProps } from "@/props";
|
||||||
// types
|
// types
|
||||||
import type {
|
import type { TDocumentEventsServer, TEditorCommands, TEditorHookProps } from "@/types";
|
||||||
TDocumentEventsServer,
|
|
||||||
EditorRefApi,
|
|
||||||
TEditorCommands,
|
|
||||||
TFileHandler,
|
|
||||||
TExtensions,
|
|
||||||
TMentionHandler,
|
|
||||||
} from "@/types";
|
|
||||||
import { CORE_EDITOR_META } from "@/constants/meta";
|
|
||||||
|
|
||||||
export interface CustomEditorProps {
|
export const useEditor = (props: TEditorHookProps) => {
|
||||||
editable: boolean;
|
|
||||||
editorClassName: string;
|
|
||||||
editorProps?: EditorProps;
|
|
||||||
enableHistory: boolean;
|
|
||||||
disabledExtensions: TExtensions[];
|
|
||||||
extensions?: Extensions;
|
|
||||||
fileHandler: TFileHandler;
|
|
||||||
forwardedRef?: MutableRefObject<EditorRefApi | null>;
|
|
||||||
handleEditorReady?: (value: boolean) => void;
|
|
||||||
id?: string;
|
|
||||||
initialValue?: string;
|
|
||||||
mentionHandler: TMentionHandler;
|
|
||||||
onChange?: (json: object, html: string) => void;
|
|
||||||
onTransaction?: () => void;
|
|
||||||
autofocus?: boolean;
|
|
||||||
placeholder?: string | ((isFocused: boolean, value: string) => string);
|
|
||||||
provider?: HocuspocusProvider;
|
|
||||||
tabIndex?: number;
|
|
||||||
// undefined when prop is not passed, null if intentionally passed to stop
|
|
||||||
// swr syncing
|
|
||||||
value?: string | null | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useEditor = (props: CustomEditorProps) => {
|
|
||||||
const {
|
const {
|
||||||
|
autofocus = false,
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
editable = true,
|
editable = true,
|
||||||
editorClassName,
|
editorClassName = "",
|
||||||
editorProps = {},
|
editorProps = {},
|
||||||
enableHistory,
|
enableHistory,
|
||||||
extensions = [],
|
extensions = [],
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
forwardedRef,
|
forwardedRef,
|
||||||
handleEditorReady,
|
handleEditorReady,
|
||||||
id = "",
|
id = "",
|
||||||
|
|
@ -69,10 +38,9 @@ export const useEditor = (props: CustomEditorProps) => {
|
||||||
onChange,
|
onChange,
|
||||||
onTransaction,
|
onTransaction,
|
||||||
placeholder,
|
placeholder,
|
||||||
|
provider,
|
||||||
tabIndex,
|
tabIndex,
|
||||||
value,
|
value,
|
||||||
provider,
|
|
||||||
autofocus = false,
|
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const editor = useTiptapEditor(
|
const editor = useTiptapEditor(
|
||||||
|
|
@ -94,6 +62,7 @@ export const useEditor = (props: CustomEditorProps) => {
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
enableHistory,
|
enableHistory,
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
mentionHandler,
|
mentionHandler,
|
||||||
placeholder,
|
placeholder,
|
||||||
tabIndex,
|
tabIndex,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { HocuspocusProvider } from "@hocuspocus/provider";
|
import { useEditor as useTiptapEditor } from "@tiptap/react";
|
||||||
import { EditorProps } from "@tiptap/pm/view";
|
import { useImperativeHandle, useEffect } from "react";
|
||||||
import { useEditor as useTiptapEditor, Extensions } from "@tiptap/react";
|
|
||||||
import { useImperativeHandle, MutableRefObject, useEffect } from "react";
|
|
||||||
import * as Y from "yjs";
|
import * as Y from "yjs";
|
||||||
|
// constants
|
||||||
|
import { CORE_EDITOR_META } from "@/constants/meta";
|
||||||
// extensions
|
// extensions
|
||||||
import { CoreReadOnlyEditorExtensions } from "@/extensions";
|
import { CoreReadOnlyEditorExtensions } from "@/extensions";
|
||||||
// helpers
|
// helpers
|
||||||
|
|
@ -11,32 +11,19 @@ import { IMarking, scrollSummary } from "@/helpers/scroll-to-node";
|
||||||
// props
|
// props
|
||||||
import { CoreReadOnlyEditorProps } from "@/props";
|
import { CoreReadOnlyEditorProps } from "@/props";
|
||||||
// types
|
// types
|
||||||
import type { EditorReadOnlyRefApi, TExtensions, TReadOnlyFileHandler, TReadOnlyMentionHandler } from "@/types";
|
import type { TReadOnlyEditorHookProps } from "@/types";
|
||||||
import { CORE_EDITOR_META } from "@/constants/meta";
|
|
||||||
|
|
||||||
interface CustomReadOnlyEditorProps {
|
export const useReadOnlyEditor = (props: TReadOnlyEditorHookProps) => {
|
||||||
disabledExtensions: TExtensions[];
|
|
||||||
editorClassName: string;
|
|
||||||
editorProps?: EditorProps;
|
|
||||||
extensions?: Extensions;
|
|
||||||
forwardedRef?: MutableRefObject<EditorReadOnlyRefApi | null>;
|
|
||||||
initialValue?: string;
|
|
||||||
fileHandler: TReadOnlyFileHandler;
|
|
||||||
handleEditorReady?: (value: boolean) => void;
|
|
||||||
mentionHandler: TReadOnlyMentionHandler;
|
|
||||||
provider?: HocuspocusProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useReadOnlyEditor = (props: CustomReadOnlyEditorProps) => {
|
|
||||||
const {
|
const {
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
initialValue,
|
editorClassName = "",
|
||||||
editorClassName,
|
|
||||||
forwardedRef,
|
|
||||||
extensions = [],
|
|
||||||
editorProps = {},
|
editorProps = {},
|
||||||
|
extensions = [],
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
|
forwardedRef,
|
||||||
handleEditorReady,
|
handleEditorReady,
|
||||||
|
initialValue,
|
||||||
mentionHandler,
|
mentionHandler,
|
||||||
provider,
|
provider,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
@ -59,8 +46,9 @@ export const useReadOnlyEditor = (props: CustomReadOnlyEditorProps) => {
|
||||||
extensions: [
|
extensions: [
|
||||||
...CoreReadOnlyEditorExtensions({
|
...CoreReadOnlyEditorExtensions({
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
mentionHandler,
|
|
||||||
fileHandler,
|
fileHandler,
|
||||||
|
flaggedExtensions,
|
||||||
|
mentionHandler,
|
||||||
}),
|
}),
|
||||||
...extensions,
|
...extensions,
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -1,50 +1,4 @@
|
||||||
import { Extensions } from "@tiptap/core";
|
|
||||||
import { EditorProps } from "@tiptap/pm/view";
|
|
||||||
// plane editor types
|
|
||||||
import { TEmbedConfig } from "@/plane-editor/types";
|
|
||||||
// types
|
|
||||||
import {
|
|
||||||
EditorReadOnlyRefApi,
|
|
||||||
EditorRefApi,
|
|
||||||
TExtensions,
|
|
||||||
TFileHandler,
|
|
||||||
TMentionHandler,
|
|
||||||
TReadOnlyFileHandler,
|
|
||||||
TReadOnlyMentionHandler,
|
|
||||||
TRealtimeConfig,
|
|
||||||
TUserDetails,
|
|
||||||
} from "@/types";
|
|
||||||
|
|
||||||
export type TServerHandler = {
|
export type TServerHandler = {
|
||||||
onConnect?: () => void;
|
onConnect?: () => void;
|
||||||
onServerError?: () => void;
|
onServerError?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type TCollaborativeEditorHookProps = {
|
|
||||||
disabledExtensions: TExtensions[];
|
|
||||||
editable: boolean;
|
|
||||||
editorClassName: string;
|
|
||||||
editorProps?: EditorProps;
|
|
||||||
extensions?: Extensions;
|
|
||||||
handleEditorReady?: (value: boolean) => void;
|
|
||||||
id: string;
|
|
||||||
realtimeConfig: TRealtimeConfig;
|
|
||||||
serverHandler?: TServerHandler;
|
|
||||||
user: TUserDetails;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TCollaborativeEditorProps = TCollaborativeEditorHookProps & {
|
|
||||||
onTransaction?: () => void;
|
|
||||||
embedHandler?: TEmbedConfig;
|
|
||||||
fileHandler: TFileHandler;
|
|
||||||
forwardedRef?: React.MutableRefObject<EditorRefApi | null>;
|
|
||||||
mentionHandler: TMentionHandler;
|
|
||||||
placeholder?: string | ((isFocused: boolean, value: string) => string);
|
|
||||||
tabIndex?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TReadOnlyCollaborativeEditorProps = TCollaborativeEditorHookProps & {
|
|
||||||
fileHandler: TReadOnlyFileHandler;
|
|
||||||
forwardedRef?: React.MutableRefObject<EditorReadOnlyRefApi | null>;
|
|
||||||
mentionHandler: TReadOnlyMentionHandler;
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// plane imports
|
||||||
|
import { TWebhookConnectionQueryParams } from "@plane/types";
|
||||||
|
|
||||||
export type TReadOnlyFileHandler = {
|
export type TReadOnlyFileHandler = {
|
||||||
checkIfAssetExists: (assetId: string) => Promise<boolean>;
|
checkIfAssetExists: (assetId: string) => Promise<boolean>;
|
||||||
getAssetSrc: (path: string) => Promise<string>;
|
getAssetSrc: (path: string) => Promise<string>;
|
||||||
|
|
@ -30,3 +33,15 @@ export type TDisplayConfig = {
|
||||||
lineSpacing?: TEditorLineSpacing;
|
lineSpacing?: TEditorLineSpacing;
|
||||||
wideLayout?: boolean;
|
wideLayout?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TUserDetails = {
|
||||||
|
color: string;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
cookie?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TRealtimeConfig = {
|
||||||
|
url: string;
|
||||||
|
queryParams: TWebhookConnectionQueryParams;
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
import { Extensions, JSONContent } from "@tiptap/core";
|
import type { Extensions, JSONContent } from "@tiptap/core";
|
||||||
import { Selection } from "@tiptap/pm/state";
|
import type { Selection } from "@tiptap/pm/state";
|
||||||
// plane types
|
|
||||||
import { TWebhookConnectionQueryParams } from "@plane/types";
|
|
||||||
// extension types
|
// extension types
|
||||||
import { TTextAlign } from "@/extensions";
|
import type { TTextAlign } from "@/extensions";
|
||||||
// helpers
|
// helpers
|
||||||
import { IMarking } from "@/helpers/scroll-to-node";
|
import type { IMarking } from "@/helpers/scroll-to-node";
|
||||||
// types
|
// types
|
||||||
import {
|
import type {
|
||||||
TAIHandler,
|
TAIHandler,
|
||||||
TDisplayConfig,
|
TDisplayConfig,
|
||||||
TDocumentEventEmitter,
|
TDocumentEventEmitter,
|
||||||
|
|
@ -18,7 +16,9 @@ import {
|
||||||
TMentionHandler,
|
TMentionHandler,
|
||||||
TReadOnlyFileHandler,
|
TReadOnlyFileHandler,
|
||||||
TReadOnlyMentionHandler,
|
TReadOnlyMentionHandler,
|
||||||
|
TRealtimeConfig,
|
||||||
TServerHandler,
|
TServerHandler,
|
||||||
|
TUserDetails,
|
||||||
} from "@/types";
|
} from "@/types";
|
||||||
|
|
||||||
export type TEditorCommands =
|
export type TEditorCommands =
|
||||||
|
|
@ -114,90 +114,70 @@ export interface EditorRefApi extends EditorReadOnlyRefApi {
|
||||||
|
|
||||||
// editor props
|
// editor props
|
||||||
export interface IEditorProps {
|
export interface IEditorProps {
|
||||||
|
autofocus?: boolean;
|
||||||
|
bubbleMenuEnabled?: boolean;
|
||||||
containerClassName?: string;
|
containerClassName?: string;
|
||||||
displayConfig?: TDisplayConfig;
|
displayConfig?: TDisplayConfig;
|
||||||
disabledExtensions: TExtensions[];
|
disabledExtensions: TExtensions[];
|
||||||
editorClassName?: string;
|
editorClassName?: string;
|
||||||
|
extensions?: Extensions;
|
||||||
|
flaggedExtensions: TExtensions[];
|
||||||
fileHandler: TFileHandler;
|
fileHandler: TFileHandler;
|
||||||
forwardedRef?: React.MutableRefObject<EditorRefApi | null>;
|
forwardedRef?: React.MutableRefObject<EditorRefApi | null>;
|
||||||
|
handleEditorReady?: (value: boolean) => void;
|
||||||
id: string;
|
id: string;
|
||||||
initialValue: string;
|
initialValue: string;
|
||||||
mentionHandler: TMentionHandler;
|
mentionHandler: TMentionHandler;
|
||||||
onChange?: (json: object, html: string) => void;
|
onChange?: (json: object, html: string) => void;
|
||||||
onTransaction?: () => void;
|
|
||||||
handleEditorReady?: (value: boolean) => void;
|
|
||||||
autofocus?: boolean;
|
|
||||||
onEnterKeyPress?: (e?: any) => void;
|
onEnterKeyPress?: (e?: any) => void;
|
||||||
|
onTransaction?: () => void;
|
||||||
placeholder?: string | ((isFocused: boolean, value: string) => string);
|
placeholder?: string | ((isFocused: boolean, value: string) => string);
|
||||||
tabIndex?: number;
|
tabIndex?: number;
|
||||||
value?: string | null;
|
value?: string | null;
|
||||||
bubbleMenuEnabled?: boolean;
|
|
||||||
}
|
}
|
||||||
export interface ILiteTextEditor extends IEditorProps {
|
|
||||||
extensions?: Extensions;
|
export type ILiteTextEditorProps = IEditorProps;
|
||||||
}
|
export interface IRichTextEditorProps extends IEditorProps {
|
||||||
export interface IRichTextEditor extends IEditorProps {
|
|
||||||
extensions?: Extensions;
|
|
||||||
dragDropEnabled?: boolean;
|
dragDropEnabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICollaborativeDocumentEditor
|
export interface ICollaborativeDocumentEditorProps
|
||||||
extends Omit<IEditorProps, "initialValue" | "onChange" | "onEnterKeyPress" | "value"> {
|
extends Omit<IEditorProps, "extensions" | "initialValue" | "onEnterKeyPress" | "value"> {
|
||||||
aiHandler?: TAIHandler;
|
aiHandler?: TAIHandler;
|
||||||
bubbleMenuEnabled?: boolean;
|
|
||||||
editable: boolean;
|
editable: boolean;
|
||||||
embedHandler: TEmbedConfig;
|
embedHandler: TEmbedConfig;
|
||||||
handleEditorReady?: (value: boolean) => void;
|
|
||||||
id: string;
|
|
||||||
realtimeConfig: TRealtimeConfig;
|
realtimeConfig: TRealtimeConfig;
|
||||||
serverHandler?: TServerHandler;
|
serverHandler?: TServerHandler;
|
||||||
user: TUserDetails;
|
user: TUserDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read only editor props
|
// read only editor props
|
||||||
export interface IReadOnlyEditorProps {
|
export interface IReadOnlyEditorProps
|
||||||
containerClassName?: string;
|
extends Pick<
|
||||||
disabledExtensions: TExtensions[];
|
IEditorProps,
|
||||||
displayConfig?: TDisplayConfig;
|
| "containerClassName"
|
||||||
editorClassName?: string;
|
| "disabledExtensions"
|
||||||
extensions?: Extensions;
|
| "flaggedExtensions"
|
||||||
|
| "displayConfig"
|
||||||
|
| "editorClassName"
|
||||||
|
| "extensions"
|
||||||
|
| "handleEditorReady"
|
||||||
|
| "id"
|
||||||
|
| "initialValue"
|
||||||
|
> {
|
||||||
fileHandler: TReadOnlyFileHandler;
|
fileHandler: TReadOnlyFileHandler;
|
||||||
forwardedRef?: React.MutableRefObject<EditorReadOnlyRefApi | null>;
|
forwardedRef?: React.MutableRefObject<EditorReadOnlyRefApi | null>;
|
||||||
id: string;
|
|
||||||
initialValue: string;
|
|
||||||
mentionHandler: TReadOnlyMentionHandler;
|
mentionHandler: TReadOnlyMentionHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ILiteTextReadOnlyEditor = IReadOnlyEditorProps;
|
export type ILiteTextReadOnlyEditorProps = IReadOnlyEditorProps;
|
||||||
|
|
||||||
export type IRichTextReadOnlyEditor = IReadOnlyEditorProps;
|
export type IRichTextReadOnlyEditorProps = IReadOnlyEditorProps;
|
||||||
|
|
||||||
export interface ICollaborativeDocumentReadOnlyEditor extends Omit<IReadOnlyEditorProps, "initialValue"> {
|
export interface IDocumentReadOnlyEditorProps extends IReadOnlyEditorProps {
|
||||||
embedHandler: TEmbedConfig;
|
embedHandler: TEmbedConfig;
|
||||||
handleEditorReady?: (value: boolean) => void;
|
|
||||||
id: string;
|
|
||||||
realtimeConfig: TRealtimeConfig;
|
|
||||||
serverHandler?: TServerHandler;
|
|
||||||
user: TUserDetails;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDocumentReadOnlyEditor extends IReadOnlyEditorProps {
|
|
||||||
embedHandler: TEmbedConfig;
|
|
||||||
handleEditorReady?: (value: boolean) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TUserDetails = {
|
|
||||||
color: string;
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
cookie?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TRealtimeConfig = {
|
|
||||||
url: string;
|
|
||||||
queryParams: TWebhookConnectionQueryParams;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface EditorEvents {
|
export interface EditorEvents {
|
||||||
beforeCreate: never;
|
beforeCreate: never;
|
||||||
create: never;
|
create: never;
|
||||||
|
|
|
||||||
50
packages/editor/src/core/types/hook.ts
Normal file
50
packages/editor/src/core/types/hook.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
import type { HocuspocusProvider } from "@hocuspocus/provider";
|
||||||
|
import type { EditorProps } from "@tiptap/pm/view";
|
||||||
|
// local imports
|
||||||
|
import type { ICollaborativeDocumentEditorProps, IEditorProps, IReadOnlyEditorProps } from "./editor";
|
||||||
|
|
||||||
|
type TCoreHookProps = Pick<
|
||||||
|
IEditorProps,
|
||||||
|
"disabledExtensions" | "editorClassName" | "extensions" | "flaggedExtensions" | "handleEditorReady"
|
||||||
|
> & {
|
||||||
|
editorProps?: EditorProps;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TEditorHookProps = TCoreHookProps &
|
||||||
|
Pick<
|
||||||
|
IEditorProps,
|
||||||
|
| "autofocus"
|
||||||
|
| "fileHandler"
|
||||||
|
| "forwardedRef"
|
||||||
|
| "id"
|
||||||
|
| "mentionHandler"
|
||||||
|
| "onChange"
|
||||||
|
| "onTransaction"
|
||||||
|
| "placeholder"
|
||||||
|
| "tabIndex"
|
||||||
|
| "value"
|
||||||
|
> & {
|
||||||
|
editable: boolean;
|
||||||
|
enableHistory: boolean;
|
||||||
|
initialValue?: string;
|
||||||
|
provider?: HocuspocusProvider;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TCollaborativeEditorHookProps = TCoreHookProps &
|
||||||
|
Pick<
|
||||||
|
TEditorHookProps,
|
||||||
|
| "editable"
|
||||||
|
| "fileHandler"
|
||||||
|
| "forwardedRef"
|
||||||
|
| "id"
|
||||||
|
| "mentionHandler"
|
||||||
|
| "onChange"
|
||||||
|
| "onTransaction"
|
||||||
|
| "placeholder"
|
||||||
|
| "tabIndex"
|
||||||
|
> &
|
||||||
|
Pick<ICollaborativeDocumentEditorProps, "embedHandler" | "realtimeConfig" | "serverHandler" | "user">;
|
||||||
|
|
||||||
|
export type TReadOnlyEditorHookProps = TCoreHookProps &
|
||||||
|
Pick<TEditorHookProps, "initialValue" | "provider"> &
|
||||||
|
Pick<IReadOnlyEditorProps, "fileHandler" | "forwardedRef" | "mentionHandler">;
|
||||||
|
|
@ -4,6 +4,7 @@ export * from "./config";
|
||||||
export * from "./editor";
|
export * from "./editor";
|
||||||
export * from "./embed";
|
export * from "./embed";
|
||||||
export * from "./extensions";
|
export * from "./extensions";
|
||||||
|
export * from "./hook";
|
||||||
export * from "./mention";
|
export * from "./mention";
|
||||||
export * from "./slash-commands-suggestion";
|
export * from "./slash-commands-suggestion";
|
||||||
export * from "@/plane-editor/types";
|
export * from "@/plane-editor/types";
|
||||||
|
|
|
||||||
|
|
@ -36,5 +36,4 @@ export { type IMarking, useEditorMarkings } from "@/hooks/use-editor-markings";
|
||||||
export { useReadOnlyEditor } from "@/hooks/use-read-only-editor";
|
export { useReadOnlyEditor } from "@/hooks/use-read-only-editor";
|
||||||
|
|
||||||
// types
|
// types
|
||||||
export type { CustomEditorProps } from "@/hooks/use-editor";
|
|
||||||
export * from "@/types";
|
export * from "@/types";
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
// plane imports
|
// plane imports
|
||||||
import { EditorRefApi, ILiteTextEditor, LiteTextEditorWithRef, TFileHandler } from "@plane/editor";
|
import { EditorRefApi, ILiteTextEditorProps, LiteTextEditorWithRef, TFileHandler } from "@plane/editor";
|
||||||
import { MakeOptional } from "@plane/types";
|
import { MakeOptional } from "@plane/types";
|
||||||
import { cn } from "@plane/utils";
|
import { cn } from "@plane/utils";
|
||||||
// components
|
// components
|
||||||
|
|
@ -10,7 +10,10 @@ import { getEditorFileHandlers } from "@/helpers/editor.helper";
|
||||||
import { isCommentEmpty } from "@/helpers/string.helper";
|
import { isCommentEmpty } from "@/helpers/string.helper";
|
||||||
|
|
||||||
interface LiteTextEditorWrapperProps
|
interface LiteTextEditorWrapperProps
|
||||||
extends MakeOptional<Omit<ILiteTextEditor, "fileHandler" | "mentionHandler">, "disabledExtensions"> {
|
extends MakeOptional<
|
||||||
|
Omit<ILiteTextEditorProps, "fileHandler" | "mentionHandler">,
|
||||||
|
"disabledExtensions" | "flaggedExtensions"
|
||||||
|
> {
|
||||||
anchor: string;
|
anchor: string;
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
isSubmitting?: boolean;
|
isSubmitting?: boolean;
|
||||||
|
|
@ -27,6 +30,7 @@ export const LiteTextEditor = React.forwardRef<EditorRefApi, LiteTextEditorWrapp
|
||||||
showSubmitButton = true,
|
showSubmitButton = true,
|
||||||
uploadFile,
|
uploadFile,
|
||||||
disabledExtensions,
|
disabledExtensions,
|
||||||
|
flaggedExtensions,
|
||||||
...rest
|
...rest
|
||||||
} = props;
|
} = props;
|
||||||
function isMutableRefObject<T>(ref: React.ForwardedRef<T>): ref is React.MutableRefObject<T | null> {
|
function isMutableRefObject<T>(ref: React.ForwardedRef<T>): ref is React.MutableRefObject<T | null> {
|
||||||
|
|
@ -41,6 +45,7 @@ export const LiteTextEditor = React.forwardRef<EditorRefApi, LiteTextEditorWrapp
|
||||||
<LiteTextEditorWithRef
|
<LiteTextEditorWithRef
|
||||||
ref={ref}
|
ref={ref}
|
||||||
disabledExtensions={disabledExtensions ?? []}
|
disabledExtensions={disabledExtensions ?? []}
|
||||||
|
flaggedExtensions={flaggedExtensions ?? []}
|
||||||
fileHandler={getEditorFileHandlers({
|
fileHandler={getEditorFileHandlers({
|
||||||
anchor,
|
anchor,
|
||||||
uploadFile,
|
uploadFile,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
// plane imports
|
// plane imports
|
||||||
import { EditorReadOnlyRefApi, ILiteTextReadOnlyEditor, LiteTextReadOnlyEditorWithRef } from "@plane/editor";
|
import { EditorReadOnlyRefApi, ILiteTextReadOnlyEditorProps, LiteTextReadOnlyEditorWithRef } from "@plane/editor";
|
||||||
import { MakeOptional } from "@plane/types";
|
import { MakeOptional } from "@plane/types";
|
||||||
import { cn } from "@plane/utils";
|
import { cn } from "@plane/utils";
|
||||||
// components
|
// components
|
||||||
|
|
@ -11,21 +11,22 @@ import { getReadOnlyEditorFileHandlers } from "@/helpers/editor.helper";
|
||||||
import { useMember } from "@/hooks/store";
|
import { useMember } from "@/hooks/store";
|
||||||
|
|
||||||
type LiteTextReadOnlyEditorWrapperProps = MakeOptional<
|
type LiteTextReadOnlyEditorWrapperProps = MakeOptional<
|
||||||
Omit<ILiteTextReadOnlyEditor, "fileHandler" | "mentionHandler">,
|
Omit<ILiteTextReadOnlyEditorProps, "fileHandler" | "mentionHandler">,
|
||||||
"disabledExtensions"
|
"disabledExtensions" | "flaggedExtensions"
|
||||||
> & {
|
> & {
|
||||||
anchor: string;
|
anchor: string;
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LiteTextReadOnlyEditor = React.forwardRef<EditorReadOnlyRefApi, LiteTextReadOnlyEditorWrapperProps>(
|
export const LiteTextReadOnlyEditor = React.forwardRef<EditorReadOnlyRefApi, LiteTextReadOnlyEditorWrapperProps>(
|
||||||
({ anchor, workspaceId, disabledExtensions, ...props }, ref) => {
|
({ anchor, workspaceId, disabledExtensions, flaggedExtensions, ...props }, ref) => {
|
||||||
const { getMemberById } = useMember();
|
const { getMemberById } = useMember();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LiteTextReadOnlyEditorWithRef
|
<LiteTextReadOnlyEditorWithRef
|
||||||
ref={ref}
|
ref={ref}
|
||||||
disabledExtensions={disabledExtensions ?? []}
|
disabledExtensions={disabledExtensions ?? []}
|
||||||
|
flaggedExtensions={flaggedExtensions ?? []}
|
||||||
fileHandler={getReadOnlyEditorFileHandlers({
|
fileHandler={getReadOnlyEditorFileHandlers({
|
||||||
anchor,
|
anchor,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { forwardRef } from "react";
|
import React, { forwardRef } from "react";
|
||||||
// plane imports
|
// plane imports
|
||||||
import { EditorRefApi, IRichTextEditor, RichTextEditorWithRef, TFileHandler } from "@plane/editor";
|
import { EditorRefApi, IRichTextEditorProps, RichTextEditorWithRef, TFileHandler } from "@plane/editor";
|
||||||
import { MakeOptional } from "@plane/types";
|
import { MakeOptional } from "@plane/types";
|
||||||
// components
|
// components
|
||||||
import { EditorMentionsRoot } from "@/components/editor";
|
import { EditorMentionsRoot } from "@/components/editor";
|
||||||
|
|
@ -10,14 +10,17 @@ import { getEditorFileHandlers } from "@/helpers/editor.helper";
|
||||||
import { useMember } from "@/hooks/store";
|
import { useMember } from "@/hooks/store";
|
||||||
|
|
||||||
interface RichTextEditorWrapperProps
|
interface RichTextEditorWrapperProps
|
||||||
extends MakeOptional<Omit<IRichTextEditor, "fileHandler" | "mentionHandler">, "disabledExtensions"> {
|
extends MakeOptional<
|
||||||
|
Omit<IRichTextEditorProps, "fileHandler" | "mentionHandler">,
|
||||||
|
"disabledExtensions" | "flaggedExtensions"
|
||||||
|
> {
|
||||||
anchor: string;
|
anchor: string;
|
||||||
uploadFile: TFileHandler["upload"];
|
uploadFile: TFileHandler["upload"];
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RichTextEditor = forwardRef<EditorRefApi, RichTextEditorWrapperProps>((props, ref) => {
|
export const RichTextEditor = forwardRef<EditorRefApi, RichTextEditorWrapperProps>((props, ref) => {
|
||||||
const { anchor, containerClassName, uploadFile, workspaceId, disabledExtensions, ...rest } = props;
|
const { anchor, containerClassName, uploadFile, workspaceId, disabledExtensions, flaggedExtensions, ...rest } = props;
|
||||||
const { getMemberById } = useMember();
|
const { getMemberById } = useMember();
|
||||||
return (
|
return (
|
||||||
<RichTextEditorWithRef
|
<RichTextEditorWithRef
|
||||||
|
|
@ -34,6 +37,7 @@ export const RichTextEditor = forwardRef<EditorRefApi, RichTextEditorWrapperProp
|
||||||
uploadFile,
|
uploadFile,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
})}
|
})}
|
||||||
|
flaggedExtensions={flaggedExtensions ?? []}
|
||||||
{...rest}
|
{...rest}
|
||||||
containerClassName={containerClassName}
|
containerClassName={containerClassName}
|
||||||
editorClassName="min-h-[100px] max-h-[200px] border-[0.5px] border-custom-border-300 rounded-md pl-3 py-2 overflow-hidden"
|
editorClassName="min-h-[100px] max-h-[200px] border-[0.5px] border-custom-border-300 rounded-md pl-3 py-2 overflow-hidden"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
// plane imports
|
// plane imports
|
||||||
import { EditorReadOnlyRefApi, IRichTextReadOnlyEditor, RichTextReadOnlyEditorWithRef } from "@plane/editor";
|
import { EditorReadOnlyRefApi, IRichTextReadOnlyEditorProps, RichTextReadOnlyEditorWithRef } from "@plane/editor";
|
||||||
import { MakeOptional } from "@plane/types";
|
import { MakeOptional } from "@plane/types";
|
||||||
import { cn } from "@plane/utils";
|
import { cn } from "@plane/utils";
|
||||||
// components
|
// components
|
||||||
|
|
@ -11,21 +11,22 @@ import { getReadOnlyEditorFileHandlers } from "@/helpers/editor.helper";
|
||||||
import { useMember } from "@/hooks/store";
|
import { useMember } from "@/hooks/store";
|
||||||
|
|
||||||
type RichTextReadOnlyEditorWrapperProps = MakeOptional<
|
type RichTextReadOnlyEditorWrapperProps = MakeOptional<
|
||||||
Omit<IRichTextReadOnlyEditor, "fileHandler" | "mentionHandler">,
|
Omit<IRichTextReadOnlyEditorProps, "fileHandler" | "mentionHandler">,
|
||||||
"disabledExtensions"
|
"disabledExtensions" | "flaggedExtensions"
|
||||||
> & {
|
> & {
|
||||||
anchor: string;
|
anchor: string;
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RichTextReadOnlyEditor = React.forwardRef<EditorReadOnlyRefApi, RichTextReadOnlyEditorWrapperProps>(
|
export const RichTextReadOnlyEditor = React.forwardRef<EditorReadOnlyRefApi, RichTextReadOnlyEditorWrapperProps>(
|
||||||
({ anchor, workspaceId, disabledExtensions, ...props }, ref) => {
|
({ anchor, workspaceId, disabledExtensions, flaggedExtensions, ...props }, ref) => {
|
||||||
const { getMemberById } = useMember();
|
const { getMemberById } = useMember();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RichTextReadOnlyEditorWithRef
|
<RichTextReadOnlyEditorWithRef
|
||||||
ref={ref}
|
ref={ref}
|
||||||
disabledExtensions={disabledExtensions ?? []}
|
disabledExtensions={disabledExtensions ?? []}
|
||||||
|
flaggedExtensions={flaggedExtensions ?? []}
|
||||||
fileHandler={getReadOnlyEditorFileHandlers({
|
fileHandler={getReadOnlyEditorFileHandlers({
|
||||||
anchor,
|
anchor,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,35 @@
|
||||||
// editor
|
// editor
|
||||||
import { TExtensions } from "@plane/editor";
|
import { TExtensions } from "@plane/editor";
|
||||||
|
|
||||||
|
export type TEditorFlaggingHookReturnType = {
|
||||||
|
document: {
|
||||||
|
disabled: TExtensions[];
|
||||||
|
flagged: TExtensions[];
|
||||||
|
};
|
||||||
|
liteText: {
|
||||||
|
disabled: TExtensions[];
|
||||||
|
flagged: TExtensions[];
|
||||||
|
};
|
||||||
|
richText: {
|
||||||
|
disabled: TExtensions[];
|
||||||
|
flagged: TExtensions[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description extensions disabled in various editors
|
* @description extensions disabled in various editors
|
||||||
*/
|
*/
|
||||||
export const useEditorFlagging = (
|
export const useEditorFlagging = (workspaceSlug: string): TEditorFlaggingHookReturnType => ({
|
||||||
workspaceSlug: string
|
document: {
|
||||||
): {
|
disabled: ["ai", "collaboration-cursor"],
|
||||||
documentEditor: TExtensions[];
|
flagged: [],
|
||||||
liteTextEditor: TExtensions[];
|
},
|
||||||
richTextEditor: TExtensions[];
|
liteText: {
|
||||||
} => ({
|
disabled: ["ai", "collaboration-cursor"],
|
||||||
documentEditor: ["ai", "collaboration-cursor"],
|
flagged: [],
|
||||||
liteTextEditor: ["ai", "collaboration-cursor"],
|
},
|
||||||
richTextEditor: ["ai", "collaboration-cursor"],
|
richText: {
|
||||||
|
disabled: ["ai", "collaboration-cursor"],
|
||||||
|
flagged: [],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import React, { useState } from "react";
|
||||||
// plane constants
|
// plane constants
|
||||||
import { EIssueCommentAccessSpecifier } from "@plane/constants";
|
import { EIssueCommentAccessSpecifier } from "@plane/constants";
|
||||||
// plane editor
|
// plane editor
|
||||||
import { EditorRefApi, ILiteTextEditor, LiteTextEditorWithRef, TFileHandler } from "@plane/editor";
|
import { EditorRefApi, ILiteTextEditorProps, LiteTextEditorWithRef, TFileHandler } from "@plane/editor";
|
||||||
// i18n
|
// i18n
|
||||||
import { useTranslation } from "@plane/i18n";
|
import { useTranslation } from "@plane/i18n";
|
||||||
// components
|
// components
|
||||||
|
|
@ -21,7 +21,10 @@ import { WorkspaceService } from "@/plane-web/services";
|
||||||
const workspaceService = new WorkspaceService();
|
const workspaceService = new WorkspaceService();
|
||||||
|
|
||||||
interface LiteTextEditorWrapperProps
|
interface LiteTextEditorWrapperProps
|
||||||
extends MakeOptional<Omit<ILiteTextEditor, "fileHandler" | "mentionHandler">, "disabledExtensions"> {
|
extends MakeOptional<
|
||||||
|
Omit<ILiteTextEditorProps, "fileHandler" | "mentionHandler">,
|
||||||
|
"disabledExtensions" | "flaggedExtensions"
|
||||||
|
> {
|
||||||
workspaceSlug: string;
|
workspaceSlug: string;
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
projectId?: string;
|
projectId?: string;
|
||||||
|
|
@ -55,13 +58,13 @@ export const LiteTextEditor = React.forwardRef<EditorRefApi, LiteTextEditorWrapp
|
||||||
parentClassName = "",
|
parentClassName = "",
|
||||||
placeholder = t("issue.comments.placeholder"),
|
placeholder = t("issue.comments.placeholder"),
|
||||||
uploadFile,
|
uploadFile,
|
||||||
disabledExtensions: additionalDisabledExtensions,
|
disabledExtensions: additionalDisabledExtensions = [],
|
||||||
...rest
|
...rest
|
||||||
} = props;
|
} = props;
|
||||||
// states
|
// states
|
||||||
const [isFocused, setIsFocused] = useState(showToolbarInitially);
|
const [isFocused, setIsFocused] = useState(showToolbarInitially);
|
||||||
// editor flaggings
|
// editor flaggings
|
||||||
const { liteTextEditor: disabledExtensions } = useEditorFlagging(workspaceSlug?.toString());
|
const { liteText: liteTextEditorExtensions } = useEditorFlagging(workspaceSlug?.toString());
|
||||||
// store hooks
|
// store hooks
|
||||||
const { getUserDetails } = useMember();
|
const { getUserDetails } = useMember();
|
||||||
// use editor mention
|
// use editor mention
|
||||||
|
|
@ -90,7 +93,8 @@ export const LiteTextEditor = React.forwardRef<EditorRefApi, LiteTextEditorWrapp
|
||||||
>
|
>
|
||||||
<LiteTextEditorWithRef
|
<LiteTextEditorWithRef
|
||||||
ref={ref}
|
ref={ref}
|
||||||
disabledExtensions={[...disabledExtensions, ...(additionalDisabledExtensions ?? [])]}
|
disabledExtensions={[...liteTextEditorExtensions.disabled, ...additionalDisabledExtensions]}
|
||||||
|
flaggedExtensions={liteTextEditorExtensions.flagged}
|
||||||
fileHandler={getEditorFileHandlers({
|
fileHandler={getEditorFileHandlers({
|
||||||
projectId,
|
projectId,
|
||||||
uploadFile,
|
uploadFile,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
// plane imports
|
// plane imports
|
||||||
import { EditorReadOnlyRefApi, ILiteTextReadOnlyEditor, LiteTextReadOnlyEditorWithRef } from "@plane/editor";
|
import { EditorReadOnlyRefApi, ILiteTextReadOnlyEditorProps, LiteTextReadOnlyEditorWithRef } from "@plane/editor";
|
||||||
import { MakeOptional } from "@plane/types";
|
import { MakeOptional } from "@plane/types";
|
||||||
// components
|
// components
|
||||||
import { cn } from "@plane/utils";
|
import { cn } from "@plane/utils";
|
||||||
|
|
@ -14,8 +14,8 @@ import { useMember } from "@/hooks/store";
|
||||||
import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
|
import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
|
||||||
|
|
||||||
type LiteTextReadOnlyEditorWrapperProps = MakeOptional<
|
type LiteTextReadOnlyEditorWrapperProps = MakeOptional<
|
||||||
Omit<ILiteTextReadOnlyEditor, "fileHandler" | "mentionHandler">,
|
Omit<ILiteTextReadOnlyEditorProps, "fileHandler" | "mentionHandler">,
|
||||||
"disabledExtensions"
|
"disabledExtensions" | "flaggedExtensions"
|
||||||
> & {
|
> & {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
workspaceSlug: string;
|
workspaceSlug: string;
|
||||||
|
|
@ -28,14 +28,15 @@ export const LiteTextReadOnlyEditor = React.forwardRef<EditorReadOnlyRefApi, Lit
|
||||||
const { getUserDetails } = useMember();
|
const { getUserDetails } = useMember();
|
||||||
|
|
||||||
// editor flaggings
|
// editor flaggings
|
||||||
const { liteTextEditor: disabledExtensions } = useEditorFlagging(workspaceSlug?.toString());
|
const { liteText: liteTextEditorExtensions } = useEditorFlagging(workspaceSlug?.toString());
|
||||||
// editor config
|
// editor config
|
||||||
const { getReadOnlyEditorFileHandlers } = useEditorConfig();
|
const { getReadOnlyEditorFileHandlers } = useEditorConfig();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LiteTextReadOnlyEditorWithRef
|
<LiteTextReadOnlyEditorWithRef
|
||||||
ref={ref}
|
ref={ref}
|
||||||
disabledExtensions={[...disabledExtensions, ...(additionalDisabledExtensions ?? [])]}
|
disabledExtensions={[...liteTextEditorExtensions.disabled, ...(additionalDisabledExtensions ?? [])]}
|
||||||
|
flaggedExtensions={liteTextEditorExtensions.flagged}
|
||||||
fileHandler={getReadOnlyEditorFileHandlers({
|
fileHandler={getReadOnlyEditorFileHandlers({
|
||||||
projectId,
|
projectId,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { forwardRef } from "react";
|
import React, { forwardRef } from "react";
|
||||||
// plane imports
|
// plane imports
|
||||||
import { EditorRefApi, IRichTextEditor, RichTextEditorWithRef, TFileHandler } from "@plane/editor";
|
import { EditorRefApi, IRichTextEditorProps, RichTextEditorWithRef, TFileHandler } from "@plane/editor";
|
||||||
import { MakeOptional, TSearchEntityRequestPayload, TSearchResponse } from "@plane/types";
|
import { MakeOptional, TSearchEntityRequestPayload, TSearchResponse } from "@plane/types";
|
||||||
// components
|
// components
|
||||||
import { cn } from "@plane/utils";
|
import { cn } from "@plane/utils";
|
||||||
|
|
@ -14,7 +14,10 @@ import { useMember } from "@/hooks/store";
|
||||||
import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
|
import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
|
||||||
|
|
||||||
interface RichTextEditorWrapperProps
|
interface RichTextEditorWrapperProps
|
||||||
extends MakeOptional<Omit<IRichTextEditor, "fileHandler" | "mentionHandler">, "disabledExtensions"> {
|
extends MakeOptional<
|
||||||
|
Omit<IRichTextEditorProps, "fileHandler" | "mentionHandler">,
|
||||||
|
"disabledExtensions" | "flaggedExtensions"
|
||||||
|
> {
|
||||||
searchMentionCallback: (payload: TSearchEntityRequestPayload) => Promise<TSearchResponse>;
|
searchMentionCallback: (payload: TSearchEntityRequestPayload) => Promise<TSearchResponse>;
|
||||||
workspaceSlug: string;
|
workspaceSlug: string;
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
|
|
@ -36,7 +39,7 @@ export const RichTextEditor = forwardRef<EditorRefApi, RichTextEditorWrapperProp
|
||||||
// store hooks
|
// store hooks
|
||||||
const { getUserDetails } = useMember();
|
const { getUserDetails } = useMember();
|
||||||
// editor flaggings
|
// editor flaggings
|
||||||
const { richTextEditor: disabledExtensions } = useEditorFlagging(workspaceSlug?.toString());
|
const { richText: richTextEditorExtensions } = useEditorFlagging(workspaceSlug?.toString());
|
||||||
// use editor mention
|
// use editor mention
|
||||||
const { fetchMentions } = useEditorMention({
|
const { fetchMentions } = useEditorMention({
|
||||||
searchEntity: async (payload) => await searchMentionCallback(payload),
|
searchEntity: async (payload) => await searchMentionCallback(payload),
|
||||||
|
|
@ -47,7 +50,8 @@ export const RichTextEditor = forwardRef<EditorRefApi, RichTextEditorWrapperProp
|
||||||
return (
|
return (
|
||||||
<RichTextEditorWithRef
|
<RichTextEditorWithRef
|
||||||
ref={ref}
|
ref={ref}
|
||||||
disabledExtensions={[...disabledExtensions, ...(additionalDisabledExtensions ?? [])]}
|
disabledExtensions={[...richTextEditorExtensions.disabled, ...(additionalDisabledExtensions ?? [])]}
|
||||||
|
flaggedExtensions={richTextEditorExtensions.flagged}
|
||||||
fileHandler={getEditorFileHandlers({
|
fileHandler={getEditorFileHandlers({
|
||||||
projectId,
|
projectId,
|
||||||
uploadFile,
|
uploadFile,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
// plane imports
|
// plane imports
|
||||||
import { EditorReadOnlyRefApi, IRichTextReadOnlyEditor, RichTextReadOnlyEditorWithRef } from "@plane/editor";
|
import { EditorReadOnlyRefApi, IRichTextReadOnlyEditorProps, RichTextReadOnlyEditorWithRef } from "@plane/editor";
|
||||||
import { MakeOptional } from "@plane/types";
|
import { MakeOptional } from "@plane/types";
|
||||||
// components
|
// components
|
||||||
import { cn } from "@plane/utils";
|
import { cn } from "@plane/utils";
|
||||||
|
|
@ -16,8 +16,8 @@ import { useMember } from "@/hooks/store";
|
||||||
import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
|
import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
|
||||||
|
|
||||||
type RichTextReadOnlyEditorWrapperProps = MakeOptional<
|
type RichTextReadOnlyEditorWrapperProps = MakeOptional<
|
||||||
Omit<IRichTextReadOnlyEditor, "fileHandler" | "mentionHandler">,
|
Omit<IRichTextReadOnlyEditorProps, "fileHandler" | "mentionHandler">,
|
||||||
"disabledExtensions"
|
"disabledExtensions" | "flaggedExtensions"
|
||||||
> & {
|
> & {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
workspaceSlug: string;
|
workspaceSlug: string;
|
||||||
|
|
@ -30,14 +30,15 @@ export const RichTextReadOnlyEditor = React.forwardRef<EditorReadOnlyRefApi, Ric
|
||||||
const { getUserDetails } = useMember();
|
const { getUserDetails } = useMember();
|
||||||
|
|
||||||
// editor flaggings
|
// editor flaggings
|
||||||
const { richTextEditor: disabledExtensions } = useEditorFlagging(workspaceSlug?.toString());
|
const { richText: richTextEditorExtensions } = useEditorFlagging(workspaceSlug?.toString());
|
||||||
// editor config
|
// editor config
|
||||||
const { getReadOnlyEditorFileHandlers } = useEditorConfig();
|
const { getReadOnlyEditorFileHandlers } = useEditorConfig();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RichTextReadOnlyEditorWithRef
|
<RichTextReadOnlyEditorWithRef
|
||||||
ref={ref}
|
ref={ref}
|
||||||
disabledExtensions={[...disabledExtensions, ...(additionalDisabledExtensions ?? [])]}
|
disabledExtensions={[...richTextEditorExtensions.disabled, ...(additionalDisabledExtensions ?? [])]}
|
||||||
|
flaggedExtensions={richTextEditorExtensions.flagged}
|
||||||
fileHandler={getReadOnlyEditorFileHandlers({
|
fileHandler={getReadOnlyEditorFileHandlers({
|
||||||
projectId,
|
projectId,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import React, { useState } from "react";
|
||||||
// plane constants
|
// plane constants
|
||||||
import { EIssueCommentAccessSpecifier } from "@plane/constants";
|
import { EIssueCommentAccessSpecifier } from "@plane/constants";
|
||||||
// plane editor
|
// plane editor
|
||||||
import { EditorRefApi, ILiteTextEditor, LiteTextEditorWithRef, TFileHandler } from "@plane/editor";
|
import { EditorRefApi, ILiteTextEditorProps, LiteTextEditorWithRef, TFileHandler } from "@plane/editor";
|
||||||
// components
|
// components
|
||||||
import { TSticky } from "@plane/types";
|
import { TSticky } from "@plane/types";
|
||||||
// helpers
|
// helpers
|
||||||
|
|
@ -14,7 +14,7 @@ import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
|
||||||
import { StickyEditorToolbar } from "./toolbar";
|
import { StickyEditorToolbar } from "./toolbar";
|
||||||
|
|
||||||
interface StickyEditorWrapperProps
|
interface StickyEditorWrapperProps
|
||||||
extends Omit<ILiteTextEditor, "disabledExtensions" | "fileHandler" | "mentionHandler"> {
|
extends Omit<ILiteTextEditorProps, "disabledExtensions" | "flaggedExtensions" | "fileHandler" | "mentionHandler"> {
|
||||||
workspaceSlug: string;
|
workspaceSlug: string;
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
projectId?: string;
|
projectId?: string;
|
||||||
|
|
@ -48,7 +48,7 @@ export const StickyEditor = React.forwardRef<EditorRefApi, StickyEditorWrapperPr
|
||||||
// states
|
// states
|
||||||
const [isFocused, setIsFocused] = useState(showToolbarInitially);
|
const [isFocused, setIsFocused] = useState(showToolbarInitially);
|
||||||
// editor flaggings
|
// editor flaggings
|
||||||
const { liteTextEditor: disabledExtensions } = useEditorFlagging(workspaceSlug?.toString());
|
const { liteText: liteTextEditorExtensions } = useEditorFlagging(workspaceSlug?.toString());
|
||||||
// editor config
|
// editor config
|
||||||
const { getEditorFileHandlers } = useEditorConfig();
|
const { getEditorFileHandlers } = useEditorConfig();
|
||||||
function isMutableRefObject<T>(ref: React.ForwardedRef<T>): ref is React.MutableRefObject<T | null> {
|
function isMutableRefObject<T>(ref: React.ForwardedRef<T>): ref is React.MutableRefObject<T | null> {
|
||||||
|
|
@ -65,7 +65,8 @@ export const StickyEditor = React.forwardRef<EditorRefApi, StickyEditorWrapperPr
|
||||||
>
|
>
|
||||||
<LiteTextEditorWithRef
|
<LiteTextEditorWithRef
|
||||||
ref={ref}
|
ref={ref}
|
||||||
disabledExtensions={[...disabledExtensions, "enter-key"]}
|
disabledExtensions={[...liteTextEditorExtensions.disabled, "enter-key"]}
|
||||||
|
flaggedExtensions={liteTextEditorExtensions.flagged}
|
||||||
fileHandler={getEditorFileHandlers({
|
fileHandler={getEditorFileHandlers({
|
||||||
projectId,
|
projectId,
|
||||||
uploadFile,
|
uploadFile,
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ export const PageEditorBody: React.FC<Props> = observer((props) => {
|
||||||
searchEntity: handlers.fetchEntity,
|
searchEntity: handlers.fetchEntity,
|
||||||
});
|
});
|
||||||
// editor flaggings
|
// editor flaggings
|
||||||
const { documentEditor: disabledExtensions } = useEditorFlagging(workspaceSlug);
|
const { document: documentEditorExtensions } = useEditorFlagging(workspaceSlug);
|
||||||
// page filters
|
// page filters
|
||||||
const { fontSize, fontStyle, isFullWidth } = usePageFilters();
|
const { fontSize, fontStyle, isFullWidth } = usePageFilters();
|
||||||
// derived values
|
// derived values
|
||||||
|
|
@ -213,7 +213,8 @@ export const PageEditorBody: React.FC<Props> = observer((props) => {
|
||||||
realtimeConfig={realtimeConfig}
|
realtimeConfig={realtimeConfig}
|
||||||
serverHandler={serverHandler}
|
serverHandler={serverHandler}
|
||||||
user={userConfig}
|
user={userConfig}
|
||||||
disabledExtensions={disabledExtensions}
|
disabledExtensions={documentEditorExtensions.disabled}
|
||||||
|
flaggedExtensions={documentEditorExtensions.flagged}
|
||||||
aiHandler={{
|
aiHandler={{
|
||||||
menu: getAIMenu,
|
menu: getAIMenu,
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export const PagesVersionEditor: React.FC<TVersionEditorProps> = observer((props
|
||||||
// derived values
|
// derived values
|
||||||
const workspaceDetails = getWorkspaceBySlug(workspaceSlug?.toString() ?? "");
|
const workspaceDetails = getWorkspaceBySlug(workspaceSlug?.toString() ?? "");
|
||||||
// editor flaggings
|
// editor flaggings
|
||||||
const { documentEditor: disabledExtensions } = useEditorFlagging(workspaceSlug?.toString() ?? "");
|
const { document: documentEditorExtensions } = useEditorFlagging(workspaceSlug?.toString() ?? "");
|
||||||
// editor config
|
// editor config
|
||||||
const { getReadOnlyEditorFileHandlers } = useEditorConfig();
|
const { getReadOnlyEditorFileHandlers } = useEditorConfig();
|
||||||
// issue-embed
|
// issue-embed
|
||||||
|
|
@ -99,7 +99,8 @@ export const PagesVersionEditor: React.FC<TVersionEditorProps> = observer((props
|
||||||
id={activeVersion ?? ""}
|
id={activeVersion ?? ""}
|
||||||
initialValue={description ?? "<p></p>"}
|
initialValue={description ?? "<p></p>"}
|
||||||
containerClassName="p-0 pb-64 border-none"
|
containerClassName="p-0 pb-64 border-none"
|
||||||
disabledExtensions={disabledExtensions}
|
disabledExtensions={documentEditorExtensions.disabled}
|
||||||
|
flaggedExtensions={documentEditorExtensions.flagged}
|
||||||
displayConfig={displayConfig}
|
displayConfig={displayConfig}
|
||||||
editorClassName="pl-10"
|
editorClassName="pl-10"
|
||||||
fileHandler={getReadOnlyEditorFileHandlers({
|
fileHandler={getReadOnlyEditorFileHandlers({
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue