fix: bubble changes from the editor immediately and move the delay to callers
This gives the callers more control over when to save data and show/hide additional controls based on the input text
This commit is contained in:
parent
68fd4698ac
commit
f4a7943680
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<vue-easymde
|
<vue-easymde
|
||||||
:configs="config"
|
:configs="config"
|
||||||
@change="() => bubble()"
|
@change="() => bubbleNow()"
|
||||||
@update:modelValue="handleInput"
|
@update:modelValue="handleInput"
|
||||||
class="content"
|
class="content"
|
||||||
v-if="isEditActive"
|
v-if="isEditActive"
|
||||||
@ -35,7 +35,7 @@
|
|||||||
</BaseButton>
|
</BaseButton>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
v-else-if="isEditActive"
|
v-else-if="isEditActive"
|
||||||
@click="toggleEdit"
|
@click="bubbleSaveClick"
|
||||||
class="done-edit">
|
class="done-edit">
|
||||||
{{ $t('misc.save') }}
|
{{ $t('misc.save') }}
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
@ -56,7 +56,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<x-button
|
<x-button
|
||||||
v-else-if="isEditActive"
|
v-else-if="isEditActive"
|
||||||
@click="toggleEdit"
|
@click="bubbleSaveClick"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
:shadow="false"
|
:shadow="false"
|
||||||
v-cy="'saveEditor'">
|
v-cy="'saveEditor'">
|
||||||
@ -84,8 +84,8 @@ import {createRandomID} from '@/helpers/randomId'
|
|||||||
|
|
||||||
import BaseButton from '@/components/base/BaseButton.vue'
|
import BaseButton from '@/components/base/BaseButton.vue'
|
||||||
import ButtonLink from '@/components/misc/ButtonLink.vue'
|
import ButtonLink from '@/components/misc/ButtonLink.vue'
|
||||||
import type { IAttachment } from '@/modelTypes/IAttachment'
|
import type {IAttachment} from '@/modelTypes/IAttachment'
|
||||||
import type { ITask } from '@/modelTypes/ITask'
|
import type {ITask} from '@/modelTypes/ITask'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
@ -115,7 +115,7 @@ const props = defineProps({
|
|||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
bottomActions: {
|
bottomActions: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
emptyText: {
|
emptyText: {
|
||||||
@ -134,10 +134,9 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue', 'save'])
|
||||||
|
|
||||||
const text = ref('')
|
const text = ref('')
|
||||||
const changeTimeout = ref<ReturnType<typeof setTimeout> | null>(null)
|
|
||||||
const isEditActive = ref(false)
|
const isEditActive = ref(false)
|
||||||
const isPreviewActive = ref(true)
|
const isPreviewActive = ref(true)
|
||||||
|
|
||||||
@ -148,7 +147,7 @@ const preview = ref('')
|
|||||||
const attachmentService = new AttachmentService()
|
const attachmentService = new AttachmentService()
|
||||||
|
|
||||||
type CacheKey = `${ITask['id']}-${IAttachment['id']}`
|
type CacheKey = `${ITask['id']}-${IAttachment['id']}`
|
||||||
const loadedAttachments = ref<{[key: CacheKey]: string}>({})
|
const loadedAttachments = ref<{ [key: CacheKey]: string }>({})
|
||||||
const config = ref(createEasyMDEConfig({
|
const config = ref(createEasyMDEConfig({
|
||||||
placeholder: props.placeholder,
|
placeholder: props.placeholder,
|
||||||
uploadImage: props.uploadEnabled,
|
uploadImage: props.uploadEnabled,
|
||||||
@ -175,7 +174,7 @@ watch(
|
|||||||
if (oldVal === '' && text.value === modelValue.value) {
|
if (oldVal === '' && text.value === modelValue.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
bubble()
|
bubbleNow()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -208,17 +207,11 @@ function handleInput(val: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
text.value = val
|
text.value = val
|
||||||
bubble(1000)
|
bubbleNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
function bubble(timeout = 5000) {
|
function bubbleNow() {
|
||||||
if (changeTimeout.value !== null) {
|
emit('update:modelValue', text.value)
|
||||||
clearTimeout(changeTimeout.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
changeTimeout.value = setTimeout(() => {
|
|
||||||
emit('update:modelValue', text.value)
|
|
||||||
}, timeout)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function replaceAt(str: string, index: number, replacement: string) {
|
function replaceAt(str: string, index: number, replacement: string) {
|
||||||
@ -287,24 +280,26 @@ function handleCheckboxClick(e: Event) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const projectPrefix = text.value.substring(index, index + 1)
|
const projectPrefix = text.value.substring(index, index + 1)
|
||||||
|
|
||||||
console.debug({index, projectPrefix, checked, text: text.value})
|
console.debug({index, projectPrefix, checked, text: text.value})
|
||||||
|
|
||||||
text.value = replaceAt(text.value, index, `${projectPrefix} ${checked ? '[x]' : '[ ]'} `)
|
text.value = replaceAt(text.value, index, `${projectPrefix} ${checked ? '[x]' : '[ ]'} `)
|
||||||
bubble()
|
bubbleNow()
|
||||||
|
emit('save', text.value)
|
||||||
renderPreview()
|
renderPreview()
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleEdit() {
|
function toggleEdit() {
|
||||||
if (isEditActive.value) {
|
isPreviewActive.value = false
|
||||||
isPreviewActive.value = true
|
isEditActive.value = true
|
||||||
isEditActive.value = false
|
}
|
||||||
renderPreview()
|
|
||||||
bubble(0) // save instantly
|
function bubbleSaveClick() {
|
||||||
} else {
|
isPreviewActive.value = true
|
||||||
isPreviewActive.value = false
|
isEditActive.value = false
|
||||||
isEditActive.value = true
|
renderPreview()
|
||||||
}
|
bubbleNow()
|
||||||
|
emit('save', text.value)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -74,9 +74,13 @@
|
|||||||
@update:model-value="
|
@update:model-value="
|
||||||
() => {
|
() => {
|
||||||
toggleEdit(c)
|
toggleEdit(c)
|
||||||
editComment()
|
editCommentWithDelay()
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
@save="() => {
|
||||||
|
toggleEdit(c)
|
||||||
|
editComment()
|
||||||
|
}"
|
||||||
:bottom-actions="actions[c.id]"
|
:bottom-actions="actions[c.id]"
|
||||||
:show-save="true"
|
:show-save="true"
|
||||||
/>
|
/>
|
||||||
@ -279,10 +283,26 @@ function toggleDelete(commentId: ITaskComment['id']) {
|
|||||||
commentToDelete.id = commentId
|
commentToDelete.id = commentId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const changeTimeout = ref<ReturnType<typeof setTimeout> | null>(null)
|
||||||
|
|
||||||
|
async function editCommentWithDelay() {
|
||||||
|
if (changeTimeout.value !== null) {
|
||||||
|
clearTimeout(changeTimeout.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
changeTimeout.value = setTimeout(async () => {
|
||||||
|
await editComment()
|
||||||
|
}, 5000)
|
||||||
|
}
|
||||||
|
|
||||||
async function editComment() {
|
async function editComment() {
|
||||||
if (commentEdit.comment === '') {
|
if (commentEdit.comment === '') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changeTimeout.value !== null) {
|
||||||
|
clearTimeout(changeTimeout.value)
|
||||||
|
}
|
||||||
|
|
||||||
saving.value = commentEdit.id
|
saving.value = commentEdit.id
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
:show-save="true"
|
:show-save="true"
|
||||||
edit-shortcut="e"
|
edit-shortcut="e"
|
||||||
v-model="task.description"
|
v-model="task.description"
|
||||||
@update:model-value="save"
|
@update:model-value="saveWithDelay"
|
||||||
|
@save="save"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -40,7 +41,6 @@ import type {ITask} from '@/modelTypes/ITask'
|
|||||||
import {useTaskStore} from '@/stores/tasks'
|
import {useTaskStore} from '@/stores/tasks'
|
||||||
import TaskModel from '@/models/task'
|
import TaskModel from '@/models/task'
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object as PropType<ITask>,
|
type: Object as PropType<ITask>,
|
||||||
@ -74,7 +74,23 @@ watch(
|
|||||||
{immediate: true},
|
{immediate: true},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const changeTimeout = ref<ReturnType<typeof setTimeout> | null>(null)
|
||||||
|
|
||||||
|
async function saveWithDelay() {
|
||||||
|
if (changeTimeout.value !== null) {
|
||||||
|
clearTimeout(changeTimeout.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
changeTimeout.value = setTimeout(async () => {
|
||||||
|
await save()
|
||||||
|
}, 5000)
|
||||||
|
}
|
||||||
|
|
||||||
async function save() {
|
async function save() {
|
||||||
|
if (changeTimeout.value !== null) {
|
||||||
|
clearTimeout(changeTimeout.value)
|
||||||
|
}
|
||||||
|
|
||||||
saving.value = true
|
saving.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user