118 lines
3.4 KiB
TypeScript
118 lines
3.4 KiB
TypeScript
"use client"
|
|
|
|
import { memo, useState } from "react"
|
|
import type { Editor } from "@tiptap/react"
|
|
import type { ExcalidrawImperativeAPI } from "@excalidraw/excalidraw/types"
|
|
import { Shapes } from "lucide-react"
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from "@/components/ui/dialog"
|
|
import { Button } from "@/components/ui/button"
|
|
import { cn } from "@/lib/utils"
|
|
import {
|
|
DocsExcalidrawEditor,
|
|
docsExcalidrawEditorKey,
|
|
useDocsExcalidrawSave,
|
|
} from "@/components/drive/richtext/docs-excalidraw-editor"
|
|
import {
|
|
DOCS_GRAPHIC_DRAW_EVENT,
|
|
notifyDocsGraphicDrawSaved,
|
|
openDocsGraphicDrawModal,
|
|
readSelectedGraphicAttrs,
|
|
} from "@/lib/drive/docs-graphic-draw-bridge"
|
|
import {
|
|
DOCS_GRAPHIC_DRAW_DIALOG_CONTENT,
|
|
DOCS_GRAPHIC_DRAW_DIALOG_OVERLAY,
|
|
} from "@/lib/drive/drive-dialog-styles"
|
|
|
|
export { openDocsGraphicDrawModal, DOCS_GRAPHIC_DRAW_EVENT }
|
|
|
|
function DocsGraphicDrawModalInner({
|
|
open,
|
|
editor,
|
|
onClose,
|
|
}: {
|
|
open: boolean
|
|
editor: Editor | null
|
|
onClose: () => void
|
|
}) {
|
|
const [api, setApi] = useState<ExcalidrawImperativeAPI | null>(null)
|
|
const { exportDrawing, saving } = useDocsExcalidrawSave(api)
|
|
|
|
const selectedAttrs = open ? readSelectedGraphicAttrs(editor) : null
|
|
const drawScene = selectedAttrs?.drawScene ?? null
|
|
const editorKey = docsExcalidrawEditorKey(drawScene)
|
|
|
|
const handleValidate = async () => {
|
|
const payload = await exportDrawing()
|
|
if (!payload || !editor) return
|
|
editor
|
|
.chain()
|
|
.focus()
|
|
.updateDocsGraphic({
|
|
graphicType: "draw",
|
|
drawScene: payload.drawScene,
|
|
src: payload.src,
|
|
width: payload.width,
|
|
height: payload.height,
|
|
lockAspectRatio: true,
|
|
})
|
|
.run()
|
|
notifyDocsGraphicDrawSaved()
|
|
handleClose()
|
|
}
|
|
|
|
const handleClose = () => {
|
|
setApi(null)
|
|
onClose()
|
|
}
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={(next) => !next && handleClose()}>
|
|
<DialogContent
|
|
overlayClassName={DOCS_GRAPHIC_DRAW_DIALOG_OVERLAY}
|
|
className={cn(
|
|
DOCS_GRAPHIC_DRAW_DIALOG_CONTENT,
|
|
"flex h-[min(88vh,900px)] max-w-[min(96vw,1200px)] flex-col gap-0 overflow-hidden p-0"
|
|
)}
|
|
>
|
|
<DialogHeader className="shrink-0 border-b border-border px-4 py-3">
|
|
<DialogTitle className="flex items-center gap-2 text-base">
|
|
<Shapes className="size-4" />
|
|
Modifier le dessin
|
|
</DialogTitle>
|
|
<DialogDescription className="sr-only">
|
|
Éditeur vectoriel pour créer et modifier un dessin dans le document.
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<div className="min-h-0 flex-1 overflow-hidden">
|
|
{open ? (
|
|
<DocsExcalidrawEditor
|
|
key={editorKey}
|
|
drawScene={drawScene}
|
|
onReady={setApi}
|
|
/>
|
|
) : null}
|
|
</div>
|
|
|
|
<DialogFooter className="shrink-0 border-t border-border px-4 py-3 sm:justify-end">
|
|
<Button type="button" variant="outline" onClick={handleClose} disabled={saving}>
|
|
Annuler
|
|
</Button>
|
|
<Button type="button" onClick={() => void handleValidate()} disabled={saving || !api}>
|
|
{saving ? "Export…" : "Valider"}
|
|
</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|
|
|
|
export const DocsGraphicDrawModal = memo(DocsGraphicDrawModalInner)
|