mirror of
https://github.com/abhinavxd/libredesk.git
synced 2025-11-11 01:15:54 +00:00
- Update shadcn charts. - Refactors user store. - Fix: pagination incorrect total pages. - Comestic changes and cleanups. - Fixes toaster not working in OuterApp.vue. - Allow complete from address in notification settings from address form field.
155 lines
3.1 KiB
Vue
155 lines
3.1 KiB
Vue
<template>
|
|
<div class="max-h-[600px] overflow-y-auto">
|
|
<EditorContent :editor="editor" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, watch, watchEffect, onUnmounted } from 'vue'
|
|
import { useEditor, EditorContent } from '@tiptap/vue-3'
|
|
import Placeholder from '@tiptap/extension-placeholder'
|
|
import Image from '@tiptap/extension-image'
|
|
import StarterKit from '@tiptap/starter-kit'
|
|
import Link from '@tiptap/extension-link'
|
|
|
|
const emit = defineEmits([
|
|
'send',
|
|
'editorText',
|
|
'updateBold',
|
|
'updateItalic',
|
|
'contentCleared',
|
|
'contentSet',
|
|
'editorReady'
|
|
])
|
|
|
|
const props = defineProps({
|
|
placeholder: String,
|
|
isBold: Boolean,
|
|
isItalic: Boolean,
|
|
clearContent: Boolean,
|
|
contentToSet: String
|
|
})
|
|
|
|
const editor = ref(
|
|
useEditor({
|
|
content: '',
|
|
extensions: [
|
|
StarterKit,
|
|
Image.configure({
|
|
HTMLAttributes: {
|
|
// Common class for all inline images.
|
|
class: 'inline-image',
|
|
},
|
|
}),
|
|
Placeholder.configure({
|
|
placeholder: () => {
|
|
return props.placeholder
|
|
}
|
|
}),
|
|
Link,
|
|
],
|
|
autofocus: true,
|
|
editorProps: {
|
|
attributes: {
|
|
// No outline for the editor.
|
|
class: 'outline-none'
|
|
},
|
|
}
|
|
})
|
|
)
|
|
|
|
watchEffect(() => {
|
|
if (editor.value) {
|
|
// Emit the editor instance when it's ready
|
|
if (editor.value) {
|
|
emit('editorReady', editor.value)
|
|
}
|
|
|
|
emit('editorText', {
|
|
text: editor.value.getText(),
|
|
html: editor.value.getHTML()
|
|
})
|
|
|
|
// Emit bold and italic state changes
|
|
emit('updateBold', editor.value.isActive('bold'))
|
|
emit('updateItalic', editor.value.isActive('italic'))
|
|
}
|
|
})
|
|
|
|
// Watcher for bold and italic changes
|
|
watchEffect(() => {
|
|
if (props.isBold !== editor.value?.isActive('bold')) {
|
|
if (props.isBold) {
|
|
editor.value?.chain().focus().setBold().run()
|
|
} else {
|
|
editor.value?.chain().focus().unsetBold().run()
|
|
}
|
|
}
|
|
if (props.isItalic !== editor.value?.isActive('italic')) {
|
|
if (props.isItalic) {
|
|
editor.value?.chain().focus().setItalic().run()
|
|
} else {
|
|
editor.value?.chain().focus().unsetItalic().run()
|
|
}
|
|
}
|
|
})
|
|
|
|
// Watcher for clearContent prop
|
|
watchEffect(() => {
|
|
if (props.clearContent) {
|
|
editor.value?.commands.clearContent()
|
|
emit('contentCleared')
|
|
}
|
|
})
|
|
|
|
watch(
|
|
() => props.contentToSet,
|
|
(newContent) => {
|
|
if (newContent) {
|
|
// Remove trailing break when setting content
|
|
editor.value.commands.setContent(newContent)
|
|
editor.value.commands.focus()
|
|
emit('contentSet')
|
|
}
|
|
}
|
|
)
|
|
|
|
onUnmounted(() => {
|
|
editor.value.destroy()
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
// Moving placeholder to the top.
|
|
.tiptap p.is-editor-empty:first-child::before {
|
|
content: attr(data-placeholder);
|
|
float: left;
|
|
color: #adb5bd;
|
|
pointer-events: none;
|
|
height: 0;
|
|
}
|
|
|
|
// Editor height
|
|
.ProseMirror {
|
|
min-height: 150px !important;
|
|
max-height: 100% !important;
|
|
overflow-y: scroll !important;
|
|
padding: 10px 10px;
|
|
}
|
|
|
|
.tiptap {
|
|
a {
|
|
color: #0066cc;
|
|
cursor: pointer;
|
|
|
|
&:hover {
|
|
color: #003d7a;
|
|
}
|
|
}
|
|
}
|
|
|
|
br.ProseMirror-trailingBreak {
|
|
display: none;
|
|
}
|
|
</style>
|