diff --git a/src/components/date/datepickerWithRange.vue b/src/components/date/datepickerWithRange.vue index ca7e1c77..a118b563 100644 --- a/src/components/date/datepickerWithRange.vue +++ b/src/components/date/datepickerWithRange.vue @@ -139,8 +139,8 @@ watch( emitChanged() }, ) -watch(() => from, inputChanged) -watch(() => to, inputChanged) +watch(() => from.value, inputChanged) +watch(() => to.value, inputChanged) function setDateRange(range: string[] | null) { if (range === null) { @@ -152,7 +152,6 @@ function setDateRange(range: string[] | null) { from.value = range[0] to.value = range[1] - } const customRangeActive = computed(() => { diff --git a/src/helpers/time/getNextWeekDate.ts b/src/helpers/time/getNextWeekDate.ts new file mode 100644 index 00000000..d0bb303f --- /dev/null +++ b/src/helpers/time/getNextWeekDate.ts @@ -0,0 +1,3 @@ +export function getNextWeekDate(): Date { + return new Date((new Date()).getTime() + 7 * 24 * 60 * 60 * 1000) +} diff --git a/src/helpers/time/parseDateOrString.ts b/src/helpers/time/parseDateOrString.ts index ac44a925..1aeeb115 100644 --- a/src/helpers/time/parseDateOrString.ts +++ b/src/helpers/time/parseDateOrString.ts @@ -1,4 +1,4 @@ -export function parseDateOrString(rawValue: string, fallback: any): string | Date { +export function parseDateOrString(rawValue: string | undefined, fallback: any): string | Date { if (typeof rawValue === 'undefined') { return fallback } diff --git a/src/router/index.ts b/src/router/index.ts index ddcb7d2c..0f232b7e 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -3,6 +3,8 @@ import {saveLastVisited} from '@/helpers/saveLastVisited' import {store} from '@/store' import {saveListView, getListView} from '@/helpers/saveListView' +import {parseDateOrString} from '@/helpers/time/parseDateOrString' +import {getNextWeekDate} from '@/helpers/time/getNextWeekDate' import HomeComponent from '../views/Home.vue' import NotFoundComponent from '../views/404.vue' @@ -249,6 +251,12 @@ const router = createRouter({ path: '/tasks/by/upcoming', name: 'tasks.range', component: UpcomingTasksComponent, + props: route => ({ + dateFrom: parseDateOrString(route.query.from, new Date()), + dateTo: parseDateOrString(route.query.to, getNextWeekDate()), + showNulls: route.query.showNulls === 'true', + showOverdue: route.query.showOverdue === 'true', + }) }, { path: '/lists/new/:namespaceId/', diff --git a/src/views/Home.vue b/src/views/Home.vue index 14c160d4..b5bcae97 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -50,7 +50,12 @@ /> - + @@ -83,13 +88,14 @@ const userInfo = computed(() => store.state.auth.info) const hasTasks = computed(() => store.state.hasTasks) const defaultListId = computed(() => store.state.auth.defaultListId) const defaultNamespaceId = computed(() => store.state.namespaces.namespaces?.[0]?.id || 0) -const hasLists = computed (() => store.state.namespaces.namespaces?.[0]?.lists.length > 0) +const hasLists = computed(() => store.state.namespaces.namespaces?.[0]?.lists.length > 0) const loading = computed(() => store.state.loading && store.state.loadingModule === 'tasks') const deletionScheduledAt = computed(() => parseDateOrNull(store.state.auth.info?.deletionScheduledAt)) // This is to reload the tasks list after adding a new task through the global task add. // FIXME: Should use vuex (somehow?) const showTasksKey = ref(0) + function updateTaskList() { showTasksKey.value++ } diff --git a/src/views/tasks/ShowTasks.vue b/src/views/tasks/ShowTasks.vue index dd03c0a5..a67f83bc 100644 --- a/src/views/tasks/ShowTasks.vue +++ b/src/views/tasks/ShowTasks.vue @@ -62,10 +62,6 @@ import {useI18n} from 'vue-i18n' import {setTitle} from '@/helpers/setTitle' import {DATE_RANGES} from '@/components/date/dateRanges' -function getNextWeekDate() { - return new Date((new Date()).getTime() + 7 * 24 * 60 * 60 * 1000) -} - const store = useStore() const route = useRoute() const router = useRouter() @@ -76,28 +72,35 @@ const showNothingToDo = ref(false) setTimeout(() => showNothingToDo.value = true, 100) -const props = defineProps({ - showAll: Boolean, -}) +// NOTE: You MUST provide either dateFrom and dateTo OR showAll for the component to actually show tasks. +const { + dateFrom, + dateTo, + showAll = false, + showNulls = false, + showOverdue = false, +} = defineProps<{ + dateFrom?: Date | string, + dateTo?: Date | string, + showAll?: Boolean, + showNulls?: Boolean, + showOverdue?: Boolean, +}>() -const dateFrom = computed(() => parseDateOrString(route.query.from as string, new Date())) -const dateTo = computed(() => parseDateOrString(route.query.to as string, getNextWeekDate())) -const showNulls = computed(() => route.query.showNulls === 'true') -const showOverdue = computed(() => route.query.showOverdue === 'true') const pageTitle = computed(() => { let title = '' // We need to define "key" because it is the first parameter in the array and we need the second // eslint-disable-next-line no-unused-vars - const predefinedRange = Object.entries(DATE_RANGES).find(([key, value]) => dateFrom.value === value[0] && dateTo.value === value[1]) + const predefinedRange = Object.entries(DATE_RANGES).find(([key, value]) => dateFrom === value[0] && dateTo === value[1]) if (typeof predefinedRange !== 'undefined') { title = t(`input.datepickerRange.ranges.${predefinedRange[0]}`) } else { - title = props.showAll + title = showAll ? t('task.show.titleCurrent') : t('task.show.fromuntil', { - from: formatDate(dateFrom.value, 'PPP'), - until: formatDate(dateTo.value, 'PPP'), + from: formatDate(dateFrom, 'PPP'), + until: formatDate(dateTo, 'PPP'), }) } @@ -140,8 +143,8 @@ function setDate(dates: dateStrings) { query: { from: dates.dateFrom ?? dateFrom, to: dates.dateTo ?? dateTo, - showOverdue: showOverdue.value ? 'true' : 'false', - showNulls: showNulls.value ? 'true' : 'false', + showOverdue: showOverdue ? 'true' : 'false', + showNulls: showNulls ? 'true' : 'false', }, }) } @@ -181,10 +184,10 @@ async function loadPendingTasks(from: string, to: string) { filter_value: ['false'], filter_comparator: ['equals'], filter_concat: 'and', - filter_include_nulls: showNulls.value, + filter_include_nulls: showNulls, } - if (!props.showAll) { + if (!showAll) { params.filter_by.push('due_date') params.filter_value.push(to) params.filter_comparator.push('less') @@ -192,7 +195,7 @@ async function loadPendingTasks(from: string, to: string) { // NOTE: Ideally we could also show tasks with a start or end date in the specified range, but the api // is not capable (yet) of combining multiple filters with 'and' and 'or'. - if (!showOverdue.value) { + if (!showOverdue) { params.filter_by.push('due_date') params.filter_value.push(from) params.filter_comparator.push('greater') @@ -203,7 +206,7 @@ async function loadPendingTasks(from: string, to: string) { } // FIXME: this modification should happen in the store -function updateTasks(updatedTask) { +function updateTasks(updatedTask: TaskModel) { for (const t in tasks.value) { if (tasks.value[t].id === updatedTask.id) { tasks.value[t] = updatedTask @@ -217,7 +220,7 @@ function updateTasks(updatedTask) { } } -watchEffect(() => loadPendingTasks(dateFrom.value as string, dateTo.value as string)) +watchEffect(() => loadPendingTasks(dateFrom as string, dateTo as string)) watchEffect(() => setTitle(pageTitle.value)) diff --git a/vite.config.ts b/vite.config.ts index e1679ef6..85f66a7c 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,8 @@ /// -import { defineConfig } from 'vite' +import {defineConfig} from 'vite' import vue from '@vitejs/plugin-vue' import legacyFn from '@vitejs/plugin-legacy' + const {VitePWA} = require('vite-plugin-pwa') const path = require('path') const {visualizer} = require('rollup-plugin-visualizer') @@ -49,6 +50,7 @@ export default defineConfig({ }, }, }, + reactivityTransform: true, }), legacy, svgLoader({