fix: related tasks add button and task dates in read only view (#1268)
Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/1268 Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
This commit is contained in:
parent
2ea3499bf7
commit
581b2cb4ab
3 changed files with 69 additions and 52 deletions
47
src/components/tasks/partials/createdUpdated.vue
Normal file
47
src/components/tasks/partials/createdUpdated.vue
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<template>
|
||||||
|
<p class="created">
|
||||||
|
<time :datetime="formatISO(task.created)" v-tooltip="formatDate(task.created)">
|
||||||
|
<i18n-t keypath="task.detail.created">
|
||||||
|
<span>{{ formatDateSince(task.created) }}</span>
|
||||||
|
{{ task.createdBy.getDisplayName() }}
|
||||||
|
</i18n-t>
|
||||||
|
</time>
|
||||||
|
<template v-if="+new Date(task.created) !== +new Date(task.updated)">
|
||||||
|
<br/>
|
||||||
|
<!-- Computed properties to show the actual date every time it gets updated -->
|
||||||
|
<time :datetime="formatISO(task.updated)" v-tooltip="updatedFormatted">
|
||||||
|
<i18n-t keypath="task.detail.updated">
|
||||||
|
<span>{{ updatedSince }}</span>
|
||||||
|
</i18n-t>
|
||||||
|
</time>
|
||||||
|
</template>
|
||||||
|
<template v-if="task.done">
|
||||||
|
<br/>
|
||||||
|
<time :datetime="formatISO(task.doneAt)" v-tooltip="doneFormatted">
|
||||||
|
<i18n-t keypath="task.detail.doneAt">
|
||||||
|
<span>{{ doneSince }}</span>
|
||||||
|
</i18n-t>
|
||||||
|
</time>
|
||||||
|
</template>
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {computed, toRefs} from 'vue'
|
||||||
|
import TaskModel from '@/models/task'
|
||||||
|
import {formatDateLong, formatDateSince} from '@/helpers/time/formatDate'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
task: {
|
||||||
|
type: TaskModel,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const {task} = toRefs(props)
|
||||||
|
|
||||||
|
const updatedSince = computed(() => formatDateSince(task.value.updated))
|
||||||
|
const updatedFormatted = computed(() => formatDateLong(task.value.updated))
|
||||||
|
const doneSince = computed(() => formatDateSince(task.value.doneAt))
|
||||||
|
const doneFormatted = computed(() => formatDateLong(task.value.doneAt))
|
||||||
|
</script>
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="task-relations">
|
<div class="task-relations">
|
||||||
<x-button
|
<x-button
|
||||||
v-if="Object.keys(relatedTasks).length > 0"
|
v-if="editEnabled && Object.keys(relatedTasks).length > 0"
|
||||||
@click="showNewRelationForm = !showNewRelationForm"
|
@click="showNewRelationForm = !showNewRelationForm"
|
||||||
class="is-pulled-right add-task-relation-button"
|
class="is-pulled-right add-task-relation-button"
|
||||||
:class="{'is-active': showNewRelationForm}"
|
:class="{'is-active': showNewRelationForm}"
|
||||||
|
|
|
@ -246,11 +246,11 @@
|
||||||
<!-- Comments -->
|
<!-- Comments -->
|
||||||
<comments :can-write="canWrite" :task-id="taskId"/>
|
<comments :can-write="canWrite" :task-id="taskId"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="column is-one-third action-buttons">
|
<div class="column is-one-third action-buttons" v-if="canWrite || shouldShowClosePopup">
|
||||||
<a @click="$router.back()" class="is-fullwidth is-block has-text-centered mb-4" v-if="shouldShowClosePopup">
|
<BaseButton @click="$router.back()" class="is-fullwidth is-block has-text-centered mb-4 has-text-primary" v-if="shouldShowClosePopup">
|
||||||
<icon icon="arrow-left"/>
|
<icon icon="arrow-left"/>
|
||||||
{{ $t('task.detail.closePopup') }}
|
{{ $t('task.detail.closePopup') }}
|
||||||
</a>
|
</BaseButton>
|
||||||
<template v-if="canWrite">
|
<template v-if="canWrite">
|
||||||
<x-button
|
<x-button
|
||||||
:class="{'is-success': !task.done}"
|
:class="{'is-success': !task.done}"
|
||||||
|
@ -386,33 +386,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- Created / Updated [by] -->
|
<!-- Created / Updated [by] -->
|
||||||
<p class="created">
|
<created-updated :task="task"/>
|
||||||
<time :datetime="formatISO(task.created)" v-tooltip="formatDate(task.created)">
|
|
||||||
<i18n-t keypath="task.detail.created">
|
|
||||||
<span>{{ formatDateSince(task.created) }}</span>
|
|
||||||
{{ task.createdBy.getDisplayName() }}
|
|
||||||
</i18n-t>
|
|
||||||
</time>
|
|
||||||
<template v-if="+new Date(task.created) !== +new Date(task.updated)">
|
|
||||||
<br/>
|
|
||||||
<!-- Computed properties to show the actual date every time it gets updated -->
|
|
||||||
<time :datetime="formatISO(task.updated)" v-tooltip="updatedFormatted">
|
|
||||||
<i18n-t keypath="task.detail.updated">
|
|
||||||
<span>{{ updatedSince }}</span>
|
|
||||||
</i18n-t>
|
|
||||||
</time>
|
|
||||||
</template>
|
|
||||||
<template v-if="task.done">
|
|
||||||
<br/>
|
|
||||||
<time :datetime="formatISO(task.doneAt)" v-tooltip="doneFormatted">
|
|
||||||
<i18n-t keypath="task.detail.doneAt">
|
|
||||||
<span>{{ doneSince }}</span>
|
|
||||||
</i18n-t>
|
|
||||||
</time>
|
|
||||||
</template>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Created / Updated [by] -->
|
||||||
|
<created-updated :task="task" v-if="!canWrite && !shouldShowClosePopup"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<transition name="modal">
|
<transition name="modal">
|
||||||
|
@ -453,18 +431,22 @@ import description from '@/components/tasks/partials/description.vue'
|
||||||
import ColorPicker from '../../components/input/colorPicker'
|
import ColorPicker from '../../components/input/colorPicker'
|
||||||
import heading from '@/components/tasks/partials/heading.vue'
|
import heading from '@/components/tasks/partials/heading.vue'
|
||||||
import Datepicker from '@/components/input/datepicker.vue'
|
import Datepicker from '@/components/input/datepicker.vue'
|
||||||
|
import BaseButton from '@/components/base/BaseButton'
|
||||||
import {playPop} from '@/helpers/playPop'
|
import {playPop} from '@/helpers/playPop'
|
||||||
import TaskSubscription from '@/components/misc/subscription.vue'
|
import TaskSubscription from '@/components/misc/subscription.vue'
|
||||||
import {CURRENT_LIST} from '@/store/mutation-types'
|
import {CURRENT_LIST} from '@/store/mutation-types'
|
||||||
|
|
||||||
import {uploadFile} from '@/helpers/attachments'
|
import {uploadFile} from '@/helpers/attachments'
|
||||||
import ChecklistSummary from '../../components/tasks/partials/checklist-summary'
|
import ChecklistSummary from '../../components/tasks/partials/checklist-summary'
|
||||||
|
import CreatedUpdated from '@/components/tasks/partials/createdUpdated'
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TaskDetailView',
|
name: 'TaskDetailView',
|
||||||
compatConfig: { ATTR_FALSE_VALUE: false },
|
compatConfig: { ATTR_FALSE_VALUE: false },
|
||||||
components: {
|
components: {
|
||||||
|
BaseButton,
|
||||||
|
CreatedUpdated,
|
||||||
ChecklistSummary,
|
ChecklistSummary,
|
||||||
TaskSubscription,
|
TaskSubscription,
|
||||||
Datepicker,
|
Datepicker,
|
||||||
|
@ -560,18 +542,6 @@ export default {
|
||||||
canWrite() {
|
canWrite() {
|
||||||
return typeof this.task !== 'undefined' && typeof this.task.maxRight !== 'undefined' && this.task.maxRight > rights.READ
|
return typeof this.task !== 'undefined' && typeof this.task.maxRight !== 'undefined' && this.task.maxRight > rights.READ
|
||||||
},
|
},
|
||||||
updatedSince() {
|
|
||||||
return this.formatDateSince(this.task.updated)
|
|
||||||
},
|
|
||||||
updatedFormatted() {
|
|
||||||
return this.formatDate(this.task.updated)
|
|
||||||
},
|
|
||||||
doneSince() {
|
|
||||||
return this.formatDateSince(this.task.doneAt)
|
|
||||||
},
|
|
||||||
doneFormatted() {
|
|
||||||
return this.formatDate(this.task.doneAt)
|
|
||||||
},
|
|
||||||
hasAttachments() {
|
hasAttachments() {
|
||||||
return this.$store.state.attachments.attachments.length > 0
|
return this.$store.state.attachments.attachments.length > 0
|
||||||
},
|
},
|
||||||
|
@ -723,7 +693,7 @@ $flash-background-duration: 750ms;
|
||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
color: var(--grey-500);
|
color: var(--grey-500);
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: var(--grey-800);
|
color: var(--grey-800);
|
||||||
|
@ -751,15 +721,15 @@ $flash-background-duration: 750ms;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title.input {
|
.title.input {
|
||||||
// 1.8rem is the font-size, 1.125 is the line-height, .3rem padding everywhere, 1px border around the whole thing.
|
// 1.8rem is the font-size, 1.125 is the line-height, .3rem padding everywhere, 1px border around the whole thing.
|
||||||
min-height: calc(1.8rem * 1.125 + .6rem + 2px);
|
min-height: calc(1.8rem * 1.125 + .6rem + 2px);
|
||||||
|
|
||||||
@media screen and (max-width: $tablet) {
|
@media screen and (max-width: $tablet) {
|
||||||
margin: 0 -.3rem .5rem -.3rem; // the title has 0.3rem padding - this make the text inside of it align with the rest
|
margin: 0 -.3rem .5rem -.3rem; // the title has 0.3rem padding - this make the text inside of it align with the rest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.title.task-id {
|
.title.task-id {
|
||||||
|
@ -823,7 +793,7 @@ $flash-background-duration: 750ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.labels-list,
|
&.labels-list,
|
||||||
.assignees {
|
.assignees {
|
||||||
:deep(.multiselect) {
|
:deep(.multiselect) {
|
||||||
.input-wrapper {
|
.input-wrapper {
|
||||||
&:not(:focus-within):not(:hover) {
|
&:not(:focus-within):not(:hover) {
|
||||||
|
@ -908,7 +878,7 @@ $flash-background-duration: 750ms;
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 1rem;
|
||||||
|
|
||||||
@media screen and (max-width: $desktop) {
|
@media screen and (max-width: $desktop) {
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-view * {
|
.task-view * {
|
||||||
|
@ -935,7 +905,7 @@ $flash-background-duration: 750ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flash-background-enter-from,
|
.flash-background-enter-from,
|
||||||
.flash-background-enter-active {
|
.flash-background-enter-active {
|
||||||
animation: flash-background $flash-background-duration ease 1;
|
animation: flash-background $flash-background-duration ease 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue