From 4298b0500eeadeaa171b8bc0329c5dae4e8b151b Mon Sep 17 00:00:00 2001 From: Palanikannan1437 <73993394+Palanikannan1437@users.noreply.github.com> Date: Thu, 28 Sep 2023 16:05:52 +0530 Subject: [PATCH] refactored editor to not require workspace slug --- package.json | 5 +- .../editor/core/src/types/upload-image.ts | 2 +- .../editor/core/src/ui/extensions/index.tsx | 3 +- .../core/src/ui/extensions/slash-command.tsx | 6 +- packages/editor/core/src/ui/index.tsx | 6 +- .../core/src/ui/plugins/upload-image.tsx | 18 +----- packages/editor/core/src/ui/props.tsx | 5 +- packages/editor/core/src/useEditor.tsx | 58 +++++++++---------- web/components/issues/description-form.tsx | 3 +- web/services/file.service.ts | 19 +++++- 10 files changed, 63 insertions(+), 62 deletions(-) diff --git a/package.json b/package.json index 23ec38b79..a0e58018a 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,10 @@ "web", "space", "packages/editor/*", - "packages/*" + "packages/eslint-config-custom", + "packages/tailwind-config-custom", + "packages/tsconfig", + "packages/ui" ], "scripts": { "build": "turbo run build", diff --git a/packages/editor/core/src/types/upload-image.ts b/packages/editor/core/src/types/upload-image.ts index e9d35ad48..3cf1408d2 100644 --- a/packages/editor/core/src/types/upload-image.ts +++ b/packages/editor/core/src/types/upload-image.ts @@ -1 +1 @@ -export type UploadImage = (workspaceSlug: string, formData: FormData) => Promise; +export type UploadImage = (file: File) => Promise; diff --git a/packages/editor/core/src/ui/extensions/index.tsx b/packages/editor/core/src/ui/extensions/index.tsx index f018fab49..1c1132444 100644 --- a/packages/editor/core/src/ui/extensions/index.tsx +++ b/packages/editor/core/src/ui/extensions/index.tsx @@ -32,7 +32,6 @@ import "highlight.js/styles/github-dark.css"; lowlight.registerLanguage("ts", ts); export const TiptapExtensions = ( - workspaceSlug: string, uploadFile: UploadImage, deleteFile: DeleteImage, setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void @@ -126,7 +125,7 @@ export const TiptapExtensions = ( }, includeChildren: true, }), - SlashCommand(workspaceSlug, uploadFile, setIsSubmitting), + SlashCommand(uploadFile, setIsSubmitting), TiptapUnderline, TextStyle, Color, diff --git a/packages/editor/core/src/ui/extensions/slash-command.tsx b/packages/editor/core/src/ui/extensions/slash-command.tsx index 3813c1def..844d4c55a 100644 --- a/packages/editor/core/src/ui/extensions/slash-command.tsx +++ b/packages/editor/core/src/ui/extensions/slash-command.tsx @@ -59,7 +59,6 @@ const Command = Extension.create({ const getSuggestionItems = ( - workspaceSlug: string, uploadFile: UploadImage, setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void ) => @@ -185,7 +184,7 @@ const getSuggestionItems = if (input.files?.length) { const file = input.files[0]; const pos = editor.view.state.selection.from; - startImageUpload(file, editor.view, pos, workspaceSlug, uploadFile, setIsSubmitting); + startImageUpload(file, editor.view, pos, uploadFile, setIsSubmitting); } }; input.click(); @@ -351,13 +350,12 @@ const renderItems = () => { }; export const SlashCommand = ( - workspaceSlug: string, uploadFile: UploadImage, setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void ) => Command.configure({ suggestion: { - items: getSuggestionItems(workspaceSlug, uploadFile, setIsSubmitting), + items: getSuggestionItems(uploadFile, setIsSubmitting), render: renderItems, }, }); diff --git a/packages/editor/core/src/ui/index.tsx b/packages/editor/core/src/ui/index.tsx index 7eb332a43..fc870f309 100644 --- a/packages/editor/core/src/ui/index.tsx +++ b/packages/editor/core/src/ui/index.tsx @@ -24,7 +24,6 @@ interface ITiptapEditor { onChange?: (json: any, html: string) => void; setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void; setShouldShowAlert?: (showAlert: boolean) => void; - workspaceSlug: string; editable?: boolean; forwardedRef?: any; debouncedUpdatesEnabled?: boolean; @@ -59,7 +58,6 @@ const TiptapEditor = ({ uploadFile, deleteFile, noBorder, - workspaceSlug, borderOnFocus, customClassName, forwardedRef, @@ -69,9 +67,9 @@ const TiptapEditor = ({ }: TiptapProps) => { const editor = useEditor({ editable: editable ?? true, - editorProps: TiptapEditorProps(workspaceSlug, uploadFile, setIsSubmitting), + editorProps: TiptapEditorProps(uploadFile, setIsSubmitting), // @ts-expect-err - extensions: TiptapExtensions(workspaceSlug, uploadFile, deleteFile, setIsSubmitting), + extensions: TiptapExtensions(uploadFile, deleteFile, setIsSubmitting), content: (typeof value === "string" && value.trim() !== "") ? value : "

", onUpdate: async ({ editor }) => { // for instant feedback loop diff --git a/packages/editor/core/src/ui/plugins/upload-image.tsx b/packages/editor/core/src/ui/plugins/upload-image.tsx index 4c3bbf9a8..976c4968b 100644 --- a/packages/editor/core/src/ui/plugins/upload-image.tsx +++ b/packages/editor/core/src/ui/plugins/upload-image.tsx @@ -57,7 +57,6 @@ export async function startImageUpload( file: File, view: EditorView, pos: number, - workspaceSlug: string, uploadFile: UploadImage, setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void ) { @@ -83,11 +82,8 @@ export async function startImageUpload( view.dispatch(tr); }; - if (!workspaceSlug) { - return; - } setIsSubmitting?.("submitting"); - const src = await UploadImageHandler(file, workspaceSlug, uploadFile); + const src = await UploadImageHandler(file, uploadFile); const { schema } = view.state; pos = findPlaceholder(view.state, id); @@ -101,21 +97,13 @@ export async function startImageUpload( view.dispatch(transaction); } -const UploadImageHandler = (file: File, workspaceSlug: string, +const UploadImageHandler = (file: File, uploadFile: UploadImage ): Promise => { - if (!workspaceSlug) { - return Promise.reject("Workspace slug is missing"); - } try { - const formData = new FormData(); - formData.append("asset", file); - formData.append("attributes", JSON.stringify({})); - return new Promise(async (resolve, reject) => { try { - const imageUrl = await uploadFile(workspaceSlug, formData) - .then((response: { asset: string }) => response.asset); + const imageUrl = await uploadFile(file) const image = new Image(); image.src = imageUrl; diff --git a/packages/editor/core/src/ui/props.tsx b/packages/editor/core/src/ui/props.tsx index 9dfc8fd0f..528f664ea 100644 --- a/packages/editor/core/src/ui/props.tsx +++ b/packages/editor/core/src/ui/props.tsx @@ -4,7 +4,6 @@ import { startImageUpload } from "@/ui/plugins/upload-image"; import { UploadImage } from "@/types/upload-image"; export function TiptapEditorProps( - workspaceSlug: string, uploadFile: UploadImage, setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void ): EditorProps { @@ -37,7 +36,7 @@ export function TiptapEditorProps( event.preventDefault(); const file = event.clipboardData.files[0]; const pos = view.state.selection.from; - startImageUpload(file, view, pos, workspaceSlug, uploadFile, setIsSubmitting); + startImageUpload(file, view, pos, uploadFile, setIsSubmitting); return true; } return false; @@ -61,7 +60,7 @@ export function TiptapEditorProps( }); // here we deduct 1 from the pos or else the image will create an extra node if (coordinates) { - startImageUpload(file, view, coordinates.pos - 1, workspaceSlug, uploadFile, setIsSubmitting); + startImageUpload(file, view, coordinates.pos - 1, uploadFile, setIsSubmitting); } return true; } diff --git a/packages/editor/core/src/useEditor.tsx b/packages/editor/core/src/useEditor.tsx index 94559acb0..552c0ca21 100644 --- a/packages/editor/core/src/useEditor.tsx +++ b/packages/editor/core/src/useEditor.tsx @@ -1,35 +1,35 @@ import { - useEditor as useEditorCore, - } from "@tiptap/react"; + useEditor as useEditorCore, +} from "@tiptap/react"; import { findTableAncestor } from "@/lib/utils"; export const useEditor = (props: any) => useEditorCore({ - editorProps: { - attributes: { - class: `prose prose-brand max-w-full prose-headings:font-display font-default focus:outline-none`, - }, - handleDOMEvents: { - keydown: (_view, event) => { - // prevent default event listeners from firing when slash command is active - if (["ArrowUp", "ArrowDown", "Enter"].includes(event.key)) { - const slashCommand = document.querySelector("#slash-command"); - if (slashCommand) { - return true; - } - } - }, - }, - handlePaste: () => { - if (typeof window !== "undefined") { - const selection: any = window?.getSelection(); - if (selection.rangeCount !== 0) { - const range = selection.getRangeAt(0); - if (findTableAncestor(range.startContainer)) { - return; - } - } + editorProps: { + attributes: { + class: `prose prose-brand max-w-full prose-headings:font-display font-default focus:outline-none`, + }, + handleDOMEvents: { + keydown: (_view, event) => { + // prevent default event listeners from firing when slash command is active + if (["ArrowUp", "ArrowDown", "Enter"].includes(event.key)) { + const slashCommand = document.querySelector("#slash-command"); + if (slashCommand) { + return true; } - }, + } }, - ...props, -}); \ No newline at end of file + }, + handlePaste: () => { + if (typeof window !== "undefined") { + const selection: any = window?.getSelection(); + if (selection.rangeCount !== 0) { + const range = selection.getRangeAt(0); + if (findTableAncestor(range.startContainer)) { + return; + } + } + } + }, + }, + ...props, +}); diff --git a/web/components/issues/description-form.tsx b/web/components/issues/description-form.tsx index dc140af1d..eb26a7805 100644 --- a/web/components/issues/description-form.tsx +++ b/web/components/issues/description-form.tsx @@ -135,10 +135,9 @@ export const IssueDescriptionForm: FC = ({ return ( { - return this.mediaUpload(`/api/workspaces/${workspaceSlug}/file-assets/`, file) + return this.post(`/api/workspaces/${workspaceSlug}/file-assets/`, file, { + headers: { + ...this.getHeaders(), + "Content-Type": "multipart/form-data", + }, + }) .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } + getUploadFileFunction(workspaceSlug: string): (file: File) => Promise { + return async (file: File) => { + const formData = new FormData(); + formData.append("asset", file); + formData.append("attributes", JSON.stringify({})); + + const data = await this.uploadFile(workspaceSlug, formData); + return data.asset; + }; + } + async deleteImage(assetUrlWithWorkspaceId: string): Promise { return this.delete(`/api/workspaces/file-assets/${assetUrlWithWorkspaceId}/`) .then((response) => response?.status) @@ -59,6 +75,7 @@ class FileService extends APIService { throw error?.response?.data; }); } + async uploadUserFile(file: FormData): Promise { return this.mediaUpload(`/api/users/file-assets/`, file) .then((response) => response?.data)