Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/api/plane/app/views/asset/v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ def get_entity_id_field(self, entity_type, entity_id):

return {}

@allow_permission([ROLE.ADMIN, ROLE.MEMBER], level="WORKSPACE")
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST], level="WORKSPACE")
def post(self, request, slug, asset_id):
project_id = request.data.get("project_id", None)
entity_id = request.data.get("entity_id", None)
Expand All @@ -792,7 +792,7 @@ def post(self, request, slug, asset_id):

storage = S3Storage(request=request)
original_asset = FileAsset.objects.filter(
workspace=workspace, id=asset_id, is_uploaded=True
id=asset_id, is_uploaded=True
).first()

if not original_asset:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const DescriptionVersionsModal = observer(function DescriptionVersionsMod

const handleCopyMarkdown = useCallback(() => {
if (!editorRef.current) return;
copyTextToClipboard(editorRef.current.getMarkDown()).then(() =>
editorRef.current.copyMarkdownToClipboard().then(() =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this a promise?

setToast({
type: TOAST_TYPE.SUCCESS,
title: t("toast.success"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const PageOptionsDropdown = observer(function PageOptionsDropdown(props:
key: "copy-markdown",
action: () => {
if (!editorRef) return;
copyTextToClipboard(editorRef.getMarkDown()).then(() =>
editorRef.copyMarkdownToClipboard().then(() =>
setToast({
type: TOAST_TYPE.SUCCESS,
title: "Success!",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,24 @@ export function CustomImageNodeView(props: CustomImageNodeViewProps) {
return;
}

setResolvedSrc(undefined);
setResolvedDownloadSrc(undefined);
setFailedToLoadImage(false);

const getImageSource = async () => {
const url = await extension.options.getImageSource?.(imgNodeSrc);
setResolvedSrc(url);
const downloadUrl = await extension.options.getImageDownloadSource?.(imgNodeSrc);
setResolvedDownloadSrc(downloadUrl);
try {
const url = await extension.options.getImageSource?.(imgNodeSrc);
setResolvedSrc(url);
const downloadUrl = await extension.options.getImageDownloadSource?.(imgNodeSrc);
setResolvedDownloadSrc(downloadUrl);
} catch (error) {
console.error("Error fetching image source:", error);
setFailedToLoadImage(true);
}
};
getImageSource();
}, [imgNodeSrc, extension.options]);

// Handle image duplication when status is duplicating
useEffect(() => {
const handleDuplication = async () => {
if (status !== ECustomImageStatus.DUPLICATING || !extension.options.duplicateImage || !imgNodeSrc) {
Expand All @@ -87,11 +95,8 @@ export function CustomImageNodeView(props: CustomImageNodeViewProps) {
throw new Error("Duplication returned invalid asset ID");
}

// Update node with new source and success status
updateAttributes({
src: newAssetId,
status: ECustomImageStatus.UPLOADED,
});
setFailedToLoadImage(false);
updateAttributes({ src: newAssetId, status: ECustomImageStatus.UPLOADED });
} catch (error: unknown) {
console.error("Failed to duplicate image:", error);
// Update status to failed
Expand All @@ -115,11 +120,13 @@ export function CustomImageNodeView(props: CustomImageNodeViewProps) {
useEffect(() => {
if (status === ECustomImageStatus.UPLOADED) {
hasRetriedOnMount.current = false;
setFailedToLoadImage(false);
}
}, [status]);

const hasDuplicationFailed = hasImageDuplicationFailed(status);
const shouldShowBlock = (isUploaded || imageFromFileSystem) && !failedToLoadImage;
const hasValidImageSource = imageFromFileSystem || (isUploaded && resolvedSrc);
const shouldShowBlock = hasValidImageSource && !failedToLoadImage && !hasDuplicationFailed;

return (
<NodeViewWrapper>
Expand Down
21 changes: 21 additions & 0 deletions packages/editor/src/core/helpers/editor-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,27 @@ export const getEditorRefHelpers = (args: TArgs): EditorRefApi => {
});
return markdown;
},
copyMarkdownToClipboard: async () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this async

if (!editor) return;

const html = editor.getHTML();
const metaData = getEditorMetaData(html);
const markdown = convertHTMLToMarkdown({
description_html: html,
metaData,
});

const copyHandler = (event: ClipboardEvent) => {
event.preventDefault();
event.clipboardData?.setData("text/plain", markdown);
event.clipboardData?.setData("text/html", html);
event.clipboardData?.setData("text/plane-editor-html", html);
document.removeEventListener("copy", copyHandler);
};

document.addEventListener("copy", copyHandler);
document.execCommand("copy");
},
isAnyDropbarOpen: () => {
if (!editor) return false;
const utilityStorage = editor.storage.utility;
Expand Down
1 change: 1 addition & 0 deletions packages/editor/src/core/plugins/markdown-clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const MarkdownClipboardPlugin = (args: TArgs): Plugin => {
});
event.clipboardData?.setData("text/plain", markdown);
event.clipboardData?.setData("text/html", clipboardHTML);
event.clipboardData?.setData("text/plane-editor-html", clipboardHTML);
return true;
} catch (error) {
console.error("Failed to copy markdown content to clipboard:", error);
Expand Down
11 changes: 10 additions & 1 deletion packages/editor/src/core/plugins/paste-asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@ export const PasteAssetPlugin = (): Plugin =>
handlePaste: (view, event) => {
if (!event.clipboardData) return false;

const htmlContent = event.clipboardData.getData("text/html");
let htmlContent = event.clipboardData.getData("text/plane-editor-html");
if (htmlContent) {
const metaTag = document.createElement("meta");
metaTag.setAttribute("charset", "utf-8");
htmlContent = metaTag.outerHTML + htmlContent;
} else {
return false;
}

if (!htmlContent || htmlContent.includes('data-uploaded="true"')) return false;

// Process the HTML content using the registry
Expand All @@ -30,6 +38,7 @@ export const PasteAssetPlugin = (): Plugin =>

const newDataTransfer = new DataTransfer();
newDataTransfer.setData("text/html", finalHtml);
newDataTransfer.setData("text/plane-editor-html", finalHtml);
if (event.clipboardData) {
newDataTransfer.setData("text/plain", event.clipboardData.getData("text/plain"));
}
Expand Down
1 change: 1 addition & 0 deletions packages/editor/src/core/types/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export type EditorRefApi = {
getDocumentInfo: () => TDocumentInfo;
getHeadings: () => IMarking[];
getMarkDown: () => string;
copyMarkdownToClipboard: () => Promise<void>;
getSelectedText: () => string | null;
insertText: (contentHTML: string, insertOnNextLine?: boolean) => void;
isAnyDropbarOpen: () => boolean;
Expand Down
Loading