fix(editor): show editor if there is no content initially
This commit is contained in:
parent
3cb1e7dede
commit
af13d68c48
@ -118,7 +118,6 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed, nextTick, onBeforeUnmount, onMounted, ref, watch} from 'vue'
|
import {computed, nextTick, onBeforeUnmount, onMounted, ref, watch} from 'vue'
|
||||||
import {refDebounced} from '@vueuse/core'
|
|
||||||
|
|
||||||
import EditorToolbar from './EditorToolbar.vue'
|
import EditorToolbar from './EditorToolbar.vue'
|
||||||
|
|
||||||
@ -173,6 +172,7 @@ import {Placeholder} from '@tiptap/extension-placeholder'
|
|||||||
import {eventToHotkeyString} from '@github/hotkey'
|
import {eventToHotkeyString} from '@github/hotkey'
|
||||||
import {mergeAttributes} from '@tiptap/core'
|
import {mergeAttributes} from '@tiptap/core'
|
||||||
import {createRandomID} from '@/helpers/randomId'
|
import {createRandomID} from '@/helpers/randomId'
|
||||||
|
import {isEditorContentEmpty} from '@/helpers/editorContentEmpty'
|
||||||
|
|
||||||
const tiptapInstanceRef = ref<HTMLInputElement | null>(null)
|
const tiptapInstanceRef = ref<HTMLInputElement | null>(null)
|
||||||
|
|
||||||
@ -272,7 +272,6 @@ const {
|
|||||||
showSave = false,
|
showSave = false,
|
||||||
placeholder = '',
|
placeholder = '',
|
||||||
editShortcut = '',
|
editShortcut = '',
|
||||||
// initialMode = 'edit',
|
|
||||||
} = defineProps<{
|
} = defineProps<{
|
||||||
modelValue: string,
|
modelValue: string,
|
||||||
uploadCallback?: UploadCallback,
|
uploadCallback?: UploadCallback,
|
||||||
@ -281,29 +280,12 @@ const {
|
|||||||
showSave?: boolean,
|
showSave?: boolean,
|
||||||
placeholder?: string,
|
placeholder?: string,
|
||||||
editShortcut?: string,
|
editShortcut?: string,
|
||||||
// initialMode?: Mode,
|
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue', 'save'])
|
const emit = defineEmits(['update:modelValue', 'save'])
|
||||||
|
|
||||||
const inputHTML = ref('')
|
|
||||||
const internalMode = ref<Mode>('edit')
|
const internalMode = ref<Mode>('edit')
|
||||||
const isEditing = computed(() => {
|
const isEditing = computed(() => internalMode.value === 'edit' && isEditEnabled)
|
||||||
console.log('isEditing', {
|
|
||||||
// initialMode,
|
|
||||||
internal: internalMode.value,
|
|
||||||
result: internalMode.value === 'edit' && isEditEnabled,
|
|
||||||
})
|
|
||||||
return internalMode.value === 'edit' && isEditEnabled
|
|
||||||
})
|
|
||||||
|
|
||||||
// watch(
|
|
||||||
// () => initialMode,
|
|
||||||
// () => {
|
|
||||||
// console.log('watch', initialMode)
|
|
||||||
// internalMode.value === initialMode
|
|
||||||
// },
|
|
||||||
// )
|
|
||||||
|
|
||||||
const editor = useEditor({
|
const editor = useEditor({
|
||||||
content: modelValue,
|
content: modelValue,
|
||||||
@ -391,15 +373,17 @@ const editor = useEditor({
|
|||||||
BubbleMenu,
|
BubbleMenu,
|
||||||
],
|
],
|
||||||
onUpdate: () => {
|
onUpdate: () => {
|
||||||
// inputHTML.value = editor.value!.getHTML()
|
|
||||||
console.log('onUpdate')
|
|
||||||
bubbleNow()
|
bubbleNow()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Grundidee: Den Edit Mode intern entscheiden ohne Möglichkeit von außen
|
watch(
|
||||||
// Problem: Der editor setzt den content irgendwie aus Gründen immer wieder auf leer, so dass der edit mode dann wieder enabled wird obwohl content da ist
|
() => isEditing.value,
|
||||||
// --> Heißt eigentlich, dass der Content im Editor und der content in der Komponente nicht der gleiche ist, das ist schonmal ein grundsätzliches Problem
|
() => {
|
||||||
|
editor.value?.setEditable(isEditing.value)
|
||||||
|
},
|
||||||
|
{immediate: true},
|
||||||
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => modelValue,
|
() => modelValue,
|
||||||
@ -410,19 +394,16 @@ watch(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('content', value)
|
|
||||||
|
|
||||||
editor.value.commands.setContent(value, false)
|
editor.value.commands.setContent(value, false)
|
||||||
// inputHTML.value = value
|
|
||||||
},
|
},
|
||||||
{immediate: true}
|
{immediate: true},
|
||||||
)
|
)
|
||||||
|
|
||||||
// const debouncedInputHTML = refDebounced(inputHTML, 1000)
|
|
||||||
// watch(debouncedInputHTML, () => bubbleNow())
|
|
||||||
|
|
||||||
function bubbleNow() {
|
function bubbleNow() {
|
||||||
console.log('bubbleNow')
|
if (editor.value?.getHTML() === modelValue) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
emit('update:modelValue', editor.value?.getHTML())
|
emit('update:modelValue', editor.value?.getHTML())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,23 +417,11 @@ function bubbleSave() {
|
|||||||
|
|
||||||
function setEdit(focus: boolean = true) {
|
function setEdit(focus: boolean = true) {
|
||||||
internalMode.value = 'edit'
|
internalMode.value = 'edit'
|
||||||
editor.value?.setEditable(isEditing.value)
|
|
||||||
if (focus) {
|
if (focus) {
|
||||||
editor.value?.commands.focus()
|
editor.value?.commands.focus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
|
||||||
() => isEditing.value,
|
|
||||||
() => {
|
|
||||||
nextTick(() => {
|
|
||||||
// console.log('wathcer is edit', isEditing.value)
|
|
||||||
setEdit(false)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{immediate: true},
|
|
||||||
)
|
|
||||||
|
|
||||||
onBeforeUnmount(() => editor.value?.destroy())
|
onBeforeUnmount(() => editor.value?.destroy())
|
||||||
|
|
||||||
const uploadInputRef = ref<HTMLInputElement | null>(null)
|
const uploadInputRef = ref<HTMLInputElement | null>(null)
|
||||||
@ -522,15 +491,18 @@ function setLink() {
|
|||||||
.run()
|
.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
// internalMode.value = initialMode
|
|
||||||
nextTick(() => {
|
|
||||||
const input = tiptapInstanceRef.value?.querySelectorAll('.tiptap__editor')[0]?.children[0]
|
|
||||||
input?.addEventListener('paste', handleImagePaste)
|
|
||||||
})
|
|
||||||
if (editShortcut !== '') {
|
if (editShortcut !== '') {
|
||||||
document.addEventListener('keydown', setFocusToEditor)
|
document.addEventListener('keydown', setFocusToEditor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await nextTick()
|
||||||
|
|
||||||
|
const input = tiptapInstanceRef.value?.querySelectorAll('.tiptap__editor')[0]?.children[0]
|
||||||
|
input?.addEventListener('paste', handleImagePaste)
|
||||||
|
|
||||||
|
internalMode.value = isEditorContentEmpty(modelValue) ? 'edit' : 'preview'
|
||||||
|
editor.value?.commands.setContent(modelValue, false)
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
@ -568,9 +540,9 @@ function setFocusToEditor(event) {
|
|||||||
}
|
}
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
// if (initialMode === 'preview' && isEditEnabled && !isEditing.value) {
|
if (!isEditing.value && isEditEnabled) {
|
||||||
// internalMode.value = 'edit'
|
internalMode.value = 'edit'
|
||||||
// }
|
}
|
||||||
|
|
||||||
editor.value?.commands.focus()
|
editor.value?.commands.focus()
|
||||||
}
|
}
|
||||||
|
@ -31,14 +31,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, computed, watch, nextTick} from 'vue'
|
import {ref, computed, watch} from 'vue'
|
||||||
|
|
||||||
import CustomTransition from '@/components/misc/CustomTransition.vue'
|
import CustomTransition from '@/components/misc/CustomTransition.vue'
|
||||||
import Editor from '@/components/input/AsyncEditor'
|
import Editor from '@/components/input/AsyncEditor'
|
||||||
|
|
||||||
import type {ITask} from '@/modelTypes/ITask'
|
import type {ITask} from '@/modelTypes/ITask'
|
||||||
import {useTaskStore} from '@/stores/tasks'
|
import {useTaskStore} from '@/stores/tasks'
|
||||||
import {isEditorContentEmpty} from '@/helpers/editorContentEmpty'
|
|
||||||
|
|
||||||
type AttachmentUploadFunction = (file: File, onSuccess: (attachmentUrl: string) => void) => Promise<string>
|
type AttachmentUploadFunction = (file: File, onSuccess: (attachmentUrl: string) => void) => Promise<string>
|
||||||
|
|
||||||
@ -63,15 +62,10 @@ const saving = ref(false)
|
|||||||
const taskStore = useTaskStore()
|
const taskStore = useTaskStore()
|
||||||
const loading = computed(() => taskStore.isLoading)
|
const loading = computed(() => taskStore.isLoading)
|
||||||
|
|
||||||
const editorMode = ref('preview')
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => modelValue.description,
|
() => modelValue.description,
|
||||||
value => {
|
value => {
|
||||||
description.value = value
|
description.value = value
|
||||||
nextTick(() => {
|
|
||||||
editorMode.value = isEditorContentEmpty(value) ? 'edit' : 'preview'
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
{immediate: true},
|
{immediate: true},
|
||||||
)
|
)
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
'is-modal': isModal,
|
'is-modal': isModal,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="task-view">
|
<!-- Removing everything until the task is loaded to prevent empty initialization of other components -->
|
||||||
|
<div class="task-view" v-if="visible">
|
||||||
<Heading
|
<Heading
|
||||||
:task="task"
|
:task="task"
|
||||||
@update:task="Object.assign(task, $event)"
|
@update:task="Object.assign(task, $event)"
|
||||||
@ -605,7 +606,8 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Object.assign(task.value, await taskService.get({id}))
|
const loaded = await taskService.get({id})
|
||||||
|
Object.assign(task.value, loaded)
|
||||||
attachmentStore.set(task.value.attachments)
|
attachmentStore.set(task.value.attachments)
|
||||||
taskColor.value = task.value.hexColor
|
taskColor.value = task.value.hexColor
|
||||||
setActiveFields()
|
setActiveFields()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user