2020-11-22 17:32:35 +01:00
|
|
|
<template>
|
|
|
|
<div class="heading">
|
2021-09-08 11:59:46 +02:00
|
|
|
<h1 class="title task-id">{{ textIdentifier }}</h1>
|
2020-11-22 17:32:35 +01:00
|
|
|
<div class="is-done" v-if="task.done">Done</div>
|
|
|
|
<h1
|
2020-11-28 15:30:34 +01:00
|
|
|
class="title input"
|
|
|
|
:class="{'disabled': !canWrite}"
|
2021-09-10 14:57:59 +02:00
|
|
|
@blur="save($event.target.textContent)"
|
|
|
|
@keydown.enter.prevent.stop="$event.target.blur()"
|
2020-11-28 15:30:34 +01:00
|
|
|
:contenteditable="canWrite ? 'true' : 'false'"
|
2021-09-10 14:57:59 +02:00
|
|
|
spellcheck="false"
|
2021-09-08 11:59:46 +02:00
|
|
|
>
|
|
|
|
{{ task.title.trim() }}
|
|
|
|
</h1>
|
2020-11-22 17:32:35 +01:00
|
|
|
<transition name="fade">
|
|
|
|
<span class="is-inline-flex is-align-items-center" v-if="loading && saving">
|
|
|
|
<span class="loader is-inline-block mr-2"></span>
|
2021-06-24 01:24:57 +02:00
|
|
|
{{ $t('misc.saving') }}
|
2020-11-22 17:32:35 +01:00
|
|
|
</span>
|
2021-09-08 11:59:46 +02:00
|
|
|
<span class="has-text-success is-inline-flex is-align-content-center" v-else-if="!loading && showSavedMessage">
|
2020-11-22 17:32:35 +01:00
|
|
|
<icon icon="check" class="mr-2"/>
|
2021-06-24 01:24:57 +02:00
|
|
|
{{ $t('misc.saved') }}
|
2020-11-22 17:32:35 +01:00
|
|
|
</span>
|
|
|
|
</transition>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import {mapState} from 'vuex'
|
|
|
|
|
|
|
|
export default {
|
|
|
|
name: 'heading',
|
|
|
|
data() {
|
|
|
|
return {
|
2021-09-10 14:57:59 +02:00
|
|
|
showSavedMessage: false,
|
2020-11-22 17:32:35 +01:00
|
|
|
saving: false, // Since loading is global state, this variable ensures we're only showing the saving icon when saving the description.
|
|
|
|
}
|
|
|
|
},
|
2021-09-10 14:57:59 +02:00
|
|
|
computed: {
|
|
|
|
...mapState(['loading']),
|
|
|
|
task() {
|
|
|
|
return this.value
|
|
|
|
},
|
2021-09-08 11:59:46 +02:00
|
|
|
textIdentifier() {
|
|
|
|
return this.task?.getTextIdentifier() || ''
|
|
|
|
},
|
2021-09-10 14:57:59 +02:00
|
|
|
},
|
2020-11-22 17:32:35 +01:00
|
|
|
props: {
|
|
|
|
value: {
|
|
|
|
required: true,
|
|
|
|
},
|
2020-11-28 15:30:34 +01:00
|
|
|
canWrite: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false,
|
|
|
|
},
|
2020-11-22 17:32:35 +01:00
|
|
|
},
|
|
|
|
methods: {
|
2021-09-10 14:57:59 +02:00
|
|
|
save(title) {
|
|
|
|
// We only want to save if the title was actually changed.
|
|
|
|
// Because the contenteditable does not have a change event
|
|
|
|
// we're building it ourselves and only continue
|
2020-11-22 17:32:35 +01:00
|
|
|
// if the task title changed.
|
2021-09-10 14:57:59 +02:00
|
|
|
if (title === this.task.title) {
|
2021-09-08 19:36:55 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-11-22 17:32:35 +01:00
|
|
|
this.saving = true
|
|
|
|
|
2021-09-10 14:57:59 +02:00
|
|
|
const newTask = {
|
|
|
|
...this.task,
|
|
|
|
title,
|
|
|
|
}
|
|
|
|
|
|
|
|
this.$store.dispatch('tasks/update', newTask)
|
|
|
|
.then((task) => {
|
|
|
|
this.$emit('input', task)
|
|
|
|
this.showSavedMessage = true
|
2020-11-22 17:32:35 +01:00
|
|
|
setTimeout(() => {
|
2021-09-10 14:57:59 +02:00
|
|
|
this.showSavedMessage = false
|
2020-11-22 17:32:35 +01:00
|
|
|
}, 2000)
|
|
|
|
})
|
|
|
|
.catch(e => {
|
2021-08-25 12:28:29 +02:00
|
|
|
this.$message.error(e)
|
2020-11-22 17:32:35 +01:00
|
|
|
})
|
|
|
|
.finally(() => {
|
|
|
|
this.saving = false
|
|
|
|
})
|
2021-07-17 23:21:46 +02:00
|
|
|
},
|
2020-11-22 17:32:35 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|