upload inserted images as attachments

This commit is contained in:
Alex Turchyn authored and Pete Matsyburka committed 2026-10-03 14:05:38 +03:00
1 parent 2189c2e9fe
commit 9b267d4a07
4 files changed
+34 -14

No files matched your search

@@ -50,6 +50,7 @@
@draw="$emit('draw', $event)" @draw="$emit('draw', $event)"
@add-custom-field="$emit('add-custom-field', $event)" @add-custom-field="$emit('add-custom-field', $event)"
@set-draw="$emit('set-draw', $event)" @set-draw="$emit('set-draw', $event)"
@add-attachment="document.attachments.push($event)"
/> />
</Teleport> </Teleport>
</div> </div>
@@ -1470,7 +1470,7 @@ const VariableHighlight = Extension.create({
} }
}) })
export function buildEditor ({ dynamicAreaProps, attachmentsIndex, renderHtmlForSaveRef, onFieldDrop, onFieldDestroy, editorOptions }) { export function buildEditor ({ dynamicAreaProps, getAttachmentsIndex, renderHtmlForSaveRef, onFieldDrop, onFieldDestroy, editorOptions }) {
const FieldNode = Node.create({ const FieldNode = Node.create({
name: 'fieldNode', name: 'fieldNode',
inline: true, inline: true,
@@ -1777,9 +1777,10 @@ export function buildEditor ({ dynamicAreaProps, attachmentsIndex, renderHtmlFor
const attrs = { ...node.attrs.htmlAttrs } const attrs = { ...node.attrs.htmlAttrs }
const blobUuid = attrs.src?.startsWith('blob:') && attrs.src.slice(5) const blobUuid = attrs.src?.startsWith('blob:') && attrs.src.slice(5)
const attachmentUrl = blobUuid && getAttachmentsIndex()[blobUuid]
if (blobUuid && attachmentsIndex[blobUuid]) { if (attachmentUrl) {
attrs.src = attachmentsIndex[blobUuid] attrs.src = attachmentUrl
} }
img.setAttribute('loading', 'lazy') img.setAttribute('loading', 'lazy')
@@ -107,7 +107,7 @@ export default {
FieldContextMenu, FieldContextMenu,
AreaTitle AreaTitle
}, },
inject: ['template', 'save', 't', 'fieldsDragFieldRef', 'customDragFieldRef', 'selectedAreasRef', 'getFieldTypeIndex', 'fieldTypes', 'withPhone', 'withPayment', 'withVerification', 'withKba', 'backgroundColor'], inject: ['template', 'save', 'baseFetch', 't', 'fieldsDragFieldRef', 'customDragFieldRef', 'selectedAreasRef', 'getFieldTypeIndex', 'fieldTypes', 'withPhone', 'withPayment', 'withVerification', 'withKba', 'backgroundColor'],
props: { props: {
section: { section: {
type: Object, type: Object,
@@ -177,7 +177,7 @@ export default {
default: null default: null
} }
}, },
emits: ['update', 'draw', 'set-draw', 'add-custom-field'], emits: ['update', 'draw', 'set-draw', 'add-custom-field', 'add-attachment'],
data () { data () {
return { return {
isAreaDrag: false, isAreaDrag: false,
@@ -290,7 +290,7 @@ export default {
onAreaResize: this.onAreaResize, onAreaResize: this.onAreaResize,
onAreaDragStart: this.onAreaDragStart onAreaDragStart: this.onAreaDragStart
}, },
attachmentsIndex: this.attachmentsIndex, getAttachmentsIndex: () => this.attachmentsIndex,
onFieldDrop: this.onFieldDrop, onFieldDrop: this.onFieldDrop,
onFieldDestroy: this.onFieldDestroy, onFieldDestroy: this.onFieldDestroy,
renderHtmlForSaveRef: this.renderHtmlForSaveRef, renderHtmlForSaveRef: this.renderHtmlForSaveRef,
@@ -569,7 +569,7 @@ export default {
.setTextSelection(from + 4) .setTextSelection(from + 4)
.run() .run()
}, },
onImageSelected (event) { async onImageSelected (event) {
const file = event.target.files[0] const file = event.target.files[0]
const pos = this.editor.state.selection.head const pos = this.editor.state.selection.head
@@ -577,15 +577,26 @@ export default {
if (!file) return if (!file) return
const reader = new FileReader() const formData = new FormData()
reader.onload = () => { formData.append('file', file)
this.editor.chain().focus()
.insertContentAt(pos, { type: 'image', attrs: { htmlAttrs: { src: reader.result, style: 'max-width: 100%' } } })
.run()
}
reader.readAsDataURL(file) const response = await this.baseFetch(`/templates/${this.template.id}/dynamic_documents/${this.attachmentUuid}/attachments`, {
method: 'POST',
body: formData
})
const data = await response.json()
if (!response.ok) return alert(data.error)
this.$emit('add-attachment', data)
await this.$nextTick()
this.editor.chain().focus()
.insertContentAt(pos, { type: 'image', attrs: { htmlAttrs: { src: `blob:${data.uuid}`, style: 'max-width: 100%' } } })
.run()
}, },
setDynamicMenuCoords (editor) { setDynamicMenuCoords (editor) {
const { from, to } = editor.state.selection const { from, to } = editor.state.selection
+7
View File
@@ -624,6 +624,7 @@ en: &en
form_has_been_declined: Form has been declined. form_has_been_declined: Form has been declined.
form_is_view_only: Form is view only. form_is_view_only: Form is view only.
file_is_missing: File is missing file_is_missing: File is missing
file_is_not_an_image: File is not an image
folder_name_has_been_updated: Folder name has been updated. folder_name_has_been_updated: Folder name has been updated.
unable_to_rename_folder: Unable to rename folder. unable_to_rename_folder: Unable to rename folder.
template_has_been_removed: Template has been removed. template_has_been_removed: Template has been removed.
@@ -1781,6 +1782,7 @@ es: &es
form_has_been_declined: El formulario ha sido rechazado. form_has_been_declined: El formulario ha sido rechazado.
form_is_view_only: El formulario es de solo lectura. form_is_view_only: El formulario es de solo lectura.
file_is_missing: Falta el archivo file_is_missing: Falta el archivo
file_is_not_an_image: El archivo no es una imagen
folder_name_has_been_updated: El nombre de la carpeta ha sido actualizado. folder_name_has_been_updated: El nombre de la carpeta ha sido actualizado.
unable_to_rename_folder: No se pudo renombrar la carpeta. unable_to_rename_folder: No se pudo renombrar la carpeta.
template_has_been_removed: La plantilla ha sido eliminada. template_has_been_removed: La plantilla ha sido eliminada.
@@ -2941,6 +2943,7 @@ it: &it
form_has_been_declined: Il modulo è stato rifiutato. form_has_been_declined: Il modulo è stato rifiutato.
form_is_view_only: Il modulo è di sola lettura. form_is_view_only: Il modulo è di sola lettura.
file_is_missing: File mancante file_is_missing: File mancante
file_is_not_an_image: Il file non è un'immagine
folder_name_has_been_updated: Il nome della cartella è stato aggiornato. folder_name_has_been_updated: Il nome della cartella è stato aggiornato.
unable_to_rename_folder: Impossibile rinominare la cartella. unable_to_rename_folder: Impossibile rinominare la cartella.
template_has_been_removed: Il modello è stato rimosso. template_has_been_removed: Il modello è stato rimosso.
@@ -4087,6 +4090,7 @@ fr: &fr
form_has_been_declined: Le formulaire a été refusé. form_has_been_declined: Le formulaire a été refusé.
form_is_view_only: Le formulaire est en lecture seule. form_is_view_only: Le formulaire est en lecture seule.
file_is_missing: Fichier manquant file_is_missing: Fichier manquant
file_is_not_an_image: Le fichier n'est pas une image
folder_name_has_been_updated: Le nom du dossier a été mis à jour. folder_name_has_been_updated: Le nom du dossier a été mis à jour.
unable_to_rename_folder: Impossible de renommer le dossier. unable_to_rename_folder: Impossible de renommer le dossier.
template_has_been_removed: Le modèle a été supprimé. template_has_been_removed: Le modèle a été supprimé.
@@ -5243,6 +5247,7 @@ pt: &pt
form_has_been_declined: O formulário foi recusado. form_has_been_declined: O formulário foi recusado.
form_is_view_only: O formulário é somente leitura. form_is_view_only: O formulário é somente leitura.
file_is_missing: O arquivo está ausente file_is_missing: O arquivo está ausente
file_is_not_an_image: O arquivo não é uma imagem
folder_name_has_been_updated: O nome da pasta foi atualizado. folder_name_has_been_updated: O nome da pasta foi atualizado.
unable_to_rename_folder: Não foi possível renomear a pasta. unable_to_rename_folder: Não foi possível renomear a pasta.
template_has_been_removed: O modelo foi removido. template_has_been_removed: O modelo foi removido.
@@ -6402,6 +6407,7 @@ de: &de
form_has_been_declined: Das Formular wurde abgelehnt. form_has_been_declined: Das Formular wurde abgelehnt.
form_is_view_only: Das Formular ist schreibgeschützt. form_is_view_only: Das Formular ist schreibgeschützt.
file_is_missing: Datei fehlt file_is_missing: Datei fehlt
file_is_not_an_image: Datei ist kein Bild
folder_name_has_been_updated: Der Ordnername wurde aktualisiert. folder_name_has_been_updated: Der Ordnername wurde aktualisiert.
unable_to_rename_folder: Der Ordner konnte nicht umbenannt werden. unable_to_rename_folder: Der Ordner konnte nicht umbenannt werden.
template_has_been_removed: Die Vorlage wurde entfernt. template_has_been_removed: Die Vorlage wurde entfernt.
@@ -8089,6 +8095,7 @@ nl: &nl
form_has_been_declined: Formulier is geweigerd. form_has_been_declined: Formulier is geweigerd.
form_is_view_only: Formulier is alleen-lezen. form_is_view_only: Formulier is alleen-lezen.
file_is_missing: Bestand ontbreekt file_is_missing: Bestand ontbreekt
file_is_not_an_image: Bestand is geen afbeelding
folder_name_has_been_updated: Mapnaam is bijgewerkt. folder_name_has_been_updated: Mapnaam is bijgewerkt.
unable_to_rename_folder: Kan map niet hernoemen. unable_to_rename_folder: Kan map niet hernoemen.
template_has_been_removed: Sjabloon is verwijderd. template_has_been_removed: Sjabloon is verwijderd.