feat: make time reactive (#2627)
Reviewed-on: https://kolaente.dev/vikunja/vikunja/pulls/2627 Reviewed-by: konrad <k@knt.li> Co-authored-by: Dominik Pschenitschni <mail@celement.de> Co-committed-by: Dominik Pschenitschni <mail@celement.de>
This commit is contained in:
parent
a7be41ef04
commit
cb8fd09824
|
|
@ -122,11 +122,14 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {computed} from 'vue'
|
||||
import {useGlobalNow} from '@/composables/useGlobalNow'
|
||||
import {formatDateShort} from '@/helpers/time/formatDate'
|
||||
|
||||
import BaseButton from '@/components/base/BaseButton.vue'
|
||||
|
||||
const exampleDate = formatDateShort(new Date())
|
||||
const {now} = useGlobalNow()
|
||||
const exampleDate = computed(() => formatDateShort(now.value))
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
|||
|
|
@ -43,9 +43,11 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {computed, ref, watch, toRefs, onActivated} from 'vue'
|
||||
import {computed, ref, watch, toRefs} from 'vue'
|
||||
import {useRouter} from 'vue-router'
|
||||
|
||||
import { useGlobalNow } from '@/composables/useGlobalNow'
|
||||
|
||||
import {getHexColor} from '@/models/task'
|
||||
|
||||
import {colorIsDark} from '@/helpers/color/colorIsDark'
|
||||
|
|
@ -122,7 +124,7 @@ const GANTT_COLOR_SCHEME: ColorScheme = {
|
|||
hoverHighlight: 'var(--grey-700)',
|
||||
text: 'var(--grey-800)',
|
||||
background: 'var(--white)',
|
||||
}
|
||||
} as const
|
||||
|
||||
/**
|
||||
* Update ganttBars when tasks change
|
||||
|
|
@ -198,8 +200,7 @@ function openTask(e: {
|
|||
|
||||
const weekDayFromDate = useWeekDayFromDate()
|
||||
|
||||
const today = ref(new Date())
|
||||
onActivated(() => today.value = new Date())
|
||||
const {now: today} = useGlobalNow()
|
||||
const dateIsToday = computed(() => (date: Date) => {
|
||||
return (
|
||||
date.getDate() === today.value.getDate() &&
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
<span
|
||||
v-if="task.dueDate > 0"
|
||||
v-tooltip="formatDateLong(task.dueDate)"
|
||||
:class="{'overdue': task.dueDate <= new Date() && !task.done}"
|
||||
:class="{'overdue': isOverdue}"
|
||||
class="due-date"
|
||||
>
|
||||
<span class="icon">
|
||||
|
|
@ -107,6 +107,8 @@
|
|||
import {computed, ref, watch} from 'vue'
|
||||
import {useRouter} from 'vue-router'
|
||||
|
||||
import {useGlobalNow} from '@/composables/useGlobalNow'
|
||||
|
||||
import PriorityLabel from '@/components/tasks/partials/PriorityLabel.vue'
|
||||
import ProgressBar from '@/components/misc/ProgressBar.vue'
|
||||
import Done from '@/components/misc/Done.vue'
|
||||
|
|
@ -145,7 +147,7 @@ const projectStore = useProjectStore()
|
|||
|
||||
const projectTitle = computed(() => {
|
||||
if (props.projectId === props.task.projectId) {
|
||||
return false
|
||||
return
|
||||
}
|
||||
|
||||
const project = projectStore.projects[props.task.projectId]
|
||||
|
|
@ -154,6 +156,14 @@ const projectTitle = computed(() => {
|
|||
|
||||
const showTaskPosition = computed(() => window.DEBUG_TASK_POSITION)
|
||||
|
||||
const {now} = useGlobalNow()
|
||||
const isOverdue = computed(() => (
|
||||
!props.task.done &&
|
||||
props.task.dueDate !== null &&
|
||||
props.task.dueDate.getTime() > 0 &&
|
||||
props.task.dueDate.getTime() <= now.value.getTime()
|
||||
))
|
||||
|
||||
async function toggleTaskDone(task: ITask) {
|
||||
loadingInternal.value = true
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
import { ref } from 'vue'
|
||||
import { createGlobalState, useIntervalFn } from '@vueuse/core'
|
||||
import { onBeforeRouteUpdate } from 'vue-router'
|
||||
|
||||
import { MILLISECONDS_A_SECOND } from '@/constants/date'
|
||||
|
||||
const GLOBAL_NOW_INTERVAL = 60 * MILLISECONDS_A_SECOND
|
||||
|
||||
/**
|
||||
* A global shared state that provides the current time, updated at a regular interval.
|
||||
*
|
||||
* Sharing this state globally ensures that all components accessing this hook use the same time reference, avoiding redundant intervals and ensuring consistency across the application.
|
||||
*/
|
||||
export const useGlobalNow = createGlobalState(() => {
|
||||
const now = ref(new Date())
|
||||
|
||||
const update = () => now.value = new Date()
|
||||
|
||||
useIntervalFn(update, GLOBAL_NOW_INTERVAL, { immediate: true })
|
||||
|
||||
// ensure the now value is refreshed when the route changes
|
||||
onBeforeRouteUpdate(() => {
|
||||
update()
|
||||
})
|
||||
|
||||
return {
|
||||
now,
|
||||
update,
|
||||
}
|
||||
})
|
||||
Loading…
Reference in New Issue