75 lines
2.0 KiB
JavaScript
75 lines
2.0 KiB
JavaScript
import { Controller } from "@hotwired/stimulus"
|
|
|
|
export default class extends Controller {
|
|
static targets = ["select", "subject"]
|
|
static values = { templates: Array }
|
|
|
|
connect() {
|
|
this.pendingHtml = null
|
|
this.onEditorReady = this.onEditorReady.bind(this)
|
|
this.editorElement?.addEventListener("trix-initialize", this.onEditorReady)
|
|
if (this.shouldPrefill()) this.apply()
|
|
}
|
|
|
|
disconnect() {
|
|
this.editorElement?.removeEventListener("trix-initialize", this.onEditorReady)
|
|
}
|
|
|
|
apply() {
|
|
const template = this.currentTemplate()
|
|
if (!template) return
|
|
|
|
if (this.hasSubjectTarget) {
|
|
this.subjectTarget.value = template.subject || ""
|
|
this.subjectTarget.dispatchEvent(new Event("input", { bubbles: true }))
|
|
}
|
|
|
|
this.setBody(template.body_html || "")
|
|
}
|
|
|
|
shouldPrefill() {
|
|
if (!this.selectTarget.value) return false
|
|
const subjectBlank = !this.hasSubjectTarget || this.subjectTarget.value.trim() === ""
|
|
return subjectBlank && this.bodyIsBlank()
|
|
}
|
|
|
|
currentTemplate() {
|
|
const id = Number(this.selectTarget.value)
|
|
if (!id) return null
|
|
return (this.templatesValue || []).find((template) => Number(template.id) === id) || null
|
|
}
|
|
|
|
setBody(html) {
|
|
this.pendingHtml = html
|
|
const editor = this.editorElement?.editor
|
|
if (editor) {
|
|
editor.loadHTML(html)
|
|
this.pendingHtml = null
|
|
return
|
|
}
|
|
if (this.hiddenInput) this.hiddenInput.value = html
|
|
}
|
|
|
|
onEditorReady() {
|
|
if (this.pendingHtml != null) {
|
|
this.editorElement.editor?.loadHTML(this.pendingHtml)
|
|
this.pendingHtml = null
|
|
return
|
|
}
|
|
if (this.shouldPrefill()) this.apply()
|
|
}
|
|
|
|
bodyIsBlank() {
|
|
const value = this.hiddenInput?.value || ""
|
|
return value.replace(/<[^>]*>/g, "").replace(/ /g, " ").trim() === ""
|
|
}
|
|
|
|
get editorElement() {
|
|
return this.element.querySelector("trix-editor")
|
|
}
|
|
|
|
get hiddenInput() {
|
|
return this.element.querySelector("[data-wysiwyg-target='input']")
|
|
}
|
|
}
|