Apply Mentions everywhere (#595)
* variables and mentions * fix lint * add missing changes * fix tests * update quilly, fix bugs * fix lint * apply fixes * apply fixes * Fix MentionParser * Apply Mentions everywhere * Fix MentionParserTest * Small refactoring * Fixing quill import issues * Polished email integration, added customer sender mail * Add missing changes * improve migration command --------- Co-authored-by: Frank <csskfaves@gmail.com> Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
130
client/lib/quill/quillMentionExtension.js
vendored
Normal file
130
client/lib/quill/quillMentionExtension.js
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
import { reactive } from 'vue'
|
||||
import Quill from 'quill'
|
||||
const Inline = Quill.import('blots/inline')
|
||||
|
||||
export default function registerMentionExtension(Quill) {
|
||||
class MentionBlot extends Inline {
|
||||
static blotName = 'mention'
|
||||
static tagName = 'SPAN'
|
||||
|
||||
static create(data) {
|
||||
let node = super.create()
|
||||
MentionBlot.setAttributes(node, data)
|
||||
return node
|
||||
}
|
||||
|
||||
static setAttributes(node, data) {
|
||||
node.setAttribute('contenteditable', 'false')
|
||||
node.setAttribute('mention', 'true')
|
||||
|
||||
if (data && typeof data === 'object') {
|
||||
node.setAttribute('mention-field-id', data.field?.nf_id || '')
|
||||
node.setAttribute('mention-field-name', data.field?.name || '')
|
||||
node.setAttribute('mention-fallback', data.fallback || '')
|
||||
node.textContent = data.field?.name || ''
|
||||
} else {
|
||||
// Handle case where data is not an object (e.g., during undo)
|
||||
node.textContent = data || ''
|
||||
}
|
||||
}
|
||||
|
||||
static formats(domNode) {
|
||||
return {
|
||||
'mention-field-id': domNode.getAttribute('mention-field-id') || '',
|
||||
'mention-field-name': domNode.getAttribute('mention-field-name') || '',
|
||||
'mention-fallback': domNode.getAttribute('mention-fallback') || ''
|
||||
}
|
||||
}
|
||||
|
||||
format(name, value) {
|
||||
if (name === 'mention' && value) {
|
||||
MentionBlot.setAttributes(this.domNode, value)
|
||||
} else {
|
||||
super.format(name, value)
|
||||
}
|
||||
}
|
||||
|
||||
formats() {
|
||||
let formats = super.formats()
|
||||
formats['mention'] = MentionBlot.formats(this.domNode)
|
||||
return formats
|
||||
}
|
||||
|
||||
static value(domNode) {
|
||||
return {
|
||||
field: {
|
||||
nf_id: domNode.getAttribute('mention-field-id') || '',
|
||||
name: domNode.getAttribute('mention-field-name') || ''
|
||||
},
|
||||
fallback: domNode.getAttribute('mention-fallback') || ''
|
||||
}
|
||||
}
|
||||
|
||||
// Override attach to ensure contenteditable is always set
|
||||
attach() {
|
||||
super.attach()
|
||||
this.domNode.setAttribute('contenteditable', 'false')
|
||||
}
|
||||
|
||||
length() {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
Quill.register(MentionBlot)
|
||||
|
||||
const mentionState = reactive({
|
||||
open: false,
|
||||
onInsert: null,
|
||||
onCancel: null,
|
||||
})
|
||||
|
||||
class MentionModule {
|
||||
constructor(quill, options) {
|
||||
this.quill = quill
|
||||
this.options = options
|
||||
|
||||
this.setupMentions()
|
||||
}
|
||||
|
||||
setupMentions() {
|
||||
const toolbar = this.quill.getModule('toolbar')
|
||||
if (toolbar) {
|
||||
toolbar.addHandler('mention', () => {
|
||||
const range = this.quill.getSelection()
|
||||
if (range) {
|
||||
mentionState.open = true
|
||||
mentionState.onInsert = (mention) => {
|
||||
this.insertMention(mention, range.index)
|
||||
}
|
||||
mentionState.onCancel = () => {
|
||||
mentionState.open = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
insertMention(mention, index) {
|
||||
mentionState.open = false
|
||||
|
||||
// Insert the mention
|
||||
this.quill.insertEmbed(index, 'mention', mention, Quill.sources.USER)
|
||||
|
||||
// Calculate the length of the inserted mention
|
||||
const mentionLength = this.quill.getLength() - index
|
||||
|
||||
nextTick(() => {
|
||||
// Focus the editor
|
||||
this.quill.focus()
|
||||
|
||||
// Set the selection after the mention
|
||||
this.quill.setSelection(index + mentionLength, 0, Quill.sources.SILENT)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Quill.register('modules/mention', MentionModule)
|
||||
|
||||
return mentionState
|
||||
}
|
||||
Reference in New Issue
Block a user