ultisuite-client/components/drive/richtext/docs-graphic-draw-modal.tsx
R3D347HR4Y 303b2b1074
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
wow
2026-06-11 01:22:40 +02:00

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)