fix(task): multiple overlapping defer due date popups
Resolves https://github.com/go-vikunja/vikunja/issues/131 (cherry picked from commit 4c55016c1a450f75f0a8c5acd8ed01517ed08a1d)
This commit is contained in:
parent
8e32d099c4
commit
b297cb5398
@ -135,18 +135,8 @@ async function updateDueDate() {
|
|||||||
$defer-task-max-width: 350px + 100px;
|
$defer-task-max-width: 350px + 100px;
|
||||||
|
|
||||||
.defer-task {
|
.defer-task {
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: $defer-task-max-width;
|
max-width: $defer-task-max-width;
|
||||||
border-radius: $radius;
|
|
||||||
border: 1px solid var(--grey-200);
|
|
||||||
padding: 1rem;
|
|
||||||
margin: 1rem;
|
|
||||||
background: var(--white);
|
|
||||||
color: var(--text);
|
|
||||||
cursor: default;
|
|
||||||
z-index: 10;
|
|
||||||
box-shadow: var(--shadow-lg);
|
|
||||||
|
|
||||||
@media screen and (max-width: ($defer-task-max-width)) {
|
@media screen and (max-width: ($defer-task-max-width)) {
|
||||||
left: .5rem;
|
left: .5rem;
|
||||||
|
@ -73,29 +73,32 @@
|
|||||||
:inline="true"
|
:inline="true"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- FIXME: use popup -->
|
<Popup
|
||||||
<BaseButton
|
|
||||||
v-if="+new Date(task.dueDate) > 0"
|
v-if="+new Date(task.dueDate) > 0"
|
||||||
v-tooltip="formatDateLong(task.dueDate)"
|
|
||||||
class="dueDate"
|
|
||||||
@click.prevent.stop="showDefer = !showDefer"
|
|
||||||
>
|
>
|
||||||
<time
|
<template #trigger="{toggle, isOpen}">
|
||||||
:datetime="formatISO(task.dueDate)"
|
<BaseButton
|
||||||
:class="{'overdue': task.dueDate <= new Date() && !task.done}"
|
v-tooltip="formatDateLong(task.dueDate)"
|
||||||
class="is-italic"
|
class="dueDate"
|
||||||
:aria-expanded="showDefer ? 'true' : 'false'"
|
@click.prevent.stop="toggle()"
|
||||||
>
|
>
|
||||||
– {{ $t('task.detail.due', {at: dueDateFormatted}) }}
|
<time
|
||||||
</time>
|
:datetime="formatISO(task.dueDate)"
|
||||||
</BaseButton>
|
:class="{'overdue': task.dueDate <= new Date() && !task.done}"
|
||||||
<CustomTransition name="fade">
|
class="is-italic"
|
||||||
<DeferTask
|
:aria-expanded="isOpen ? 'true' : 'false'"
|
||||||
v-if="+new Date(task.dueDate) > 0 && showDefer"
|
>
|
||||||
ref="deferDueDate"
|
– {{ $t('task.detail.due', {at: dueDateFormatted}) }}
|
||||||
v-model="task"
|
</time>
|
||||||
/>
|
</BaseButton>
|
||||||
</CustomTransition>
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<DeferTask
|
||||||
|
v-model="task"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</Popup>
|
||||||
|
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
<span
|
<span
|
||||||
@ -176,7 +179,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, watch, shallowReactive, onMounted, onBeforeUnmount, computed} from 'vue'
|
import {ref, watch, shallowReactive, onMounted, computed} from 'vue'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
|
||||||
import TaskModel, {getHexColor} from '@/models/task'
|
import TaskModel, {getHexColor} from '@/models/task'
|
||||||
@ -191,11 +194,10 @@ import ProgressBar from '@/components/misc/ProgressBar.vue'
|
|||||||
import BaseButton from '@/components/base/BaseButton.vue'
|
import BaseButton from '@/components/base/BaseButton.vue'
|
||||||
import FancyCheckbox from '@/components/input/FancyCheckbox.vue'
|
import FancyCheckbox from '@/components/input/FancyCheckbox.vue'
|
||||||
import ColorBubble from '@/components/misc/ColorBubble.vue'
|
import ColorBubble from '@/components/misc/ColorBubble.vue'
|
||||||
import CustomTransition from '@/components/misc/CustomTransition.vue'
|
import Popup from '@/components/misc/Popup.vue'
|
||||||
|
|
||||||
import TaskService from '@/services/task'
|
import TaskService from '@/services/task'
|
||||||
|
|
||||||
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
|
|
||||||
import {formatDateSince, formatISO, formatDateLong} from '@/helpers/time/formatDate'
|
import {formatDateSince, formatISO, formatDateLong} from '@/helpers/time/formatDate'
|
||||||
import {success} from '@/message'
|
import {success} from '@/message'
|
||||||
|
|
||||||
@ -239,7 +241,6 @@ const {t} = useI18n({useScope: 'global'})
|
|||||||
|
|
||||||
const taskService = shallowReactive(new TaskService())
|
const taskService = shallowReactive(new TaskService())
|
||||||
const task = ref<ITask>(new TaskModel())
|
const task = ref<ITask>(new TaskModel())
|
||||||
const showDefer = ref(false)
|
|
||||||
|
|
||||||
const isRepeating = computed(() => task.value.repeatAfter.amount > 0 || (task.value.repeatAfter.amount === 0 && task.value.repeatMode === TASK_REPEAT_MODES.REPEAT_MODE_MONTH))
|
const isRepeating = computed(() => task.value.repeatAfter.amount > 0 || (task.value.repeatAfter.amount === 0 && task.value.repeatMode === TASK_REPEAT_MODES.REPEAT_MODE_MONTH))
|
||||||
|
|
||||||
@ -254,14 +255,6 @@ watch(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
document.addEventListener('click', hideDeferDueDatePopup)
|
|
||||||
})
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
document.removeEventListener('click', hideDeferDueDatePopup)
|
|
||||||
})
|
|
||||||
|
|
||||||
const baseStore = useBaseStore()
|
const baseStore = useBaseStore()
|
||||||
const projectStore = useProjectStore()
|
const projectStore = useProjectStore()
|
||||||
const taskStore = useTaskStore()
|
const taskStore = useTaskStore()
|
||||||
@ -350,17 +343,6 @@ async function toggleFavorite() {
|
|||||||
emit('taskUpdated', task.value)
|
emit('taskUpdated', task.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const deferDueDate = ref<typeof DeferTask | null>(null)
|
|
||||||
|
|
||||||
function hideDeferDueDatePopup(e) {
|
|
||||||
if (!showDefer.value) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
closeWhenClickedOutside(e, deferDueDate.value.$el, () => {
|
|
||||||
showDefer.value = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const taskLink = ref<HTMLElement | null>(null)
|
const taskLink = ref<HTMLElement | null>(null)
|
||||||
const taskContainerRef = ref<HTMLElement | null>(null)
|
const taskContainerRef = ref<HTMLElement | null>(null)
|
||||||
|
|
||||||
@ -542,4 +524,17 @@ function focusTaskLink() {
|
|||||||
.subtask-nested {
|
.subtask-nested {
|
||||||
margin-left: 1.75rem;
|
margin-left: 1.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.popup) {
|
||||||
|
border-radius: $radius;
|
||||||
|
background-color: var(--white);
|
||||||
|
box-shadow: var(--shadow-lg);
|
||||||
|
color: var(--text);
|
||||||
|
top: unset;
|
||||||
|
|
||||||
|
&.is-open {
|
||||||
|
padding: 1rem;
|
||||||
|
border: 1px solid var(--grey-200);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user