fix: gantt route sync (#2664)
Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/2664
This commit is contained in:
commit
94508173dc
@ -62,7 +62,7 @@ describe('List View Gantt', () => {
|
|||||||
it('Drags a task around', () => {
|
it('Drags a task around', () => {
|
||||||
cy.intercept('**/api/v1/tasks/*')
|
cy.intercept('**/api/v1/tasks/*')
|
||||||
.as('taskUpdate')
|
.as('taskUpdate')
|
||||||
|
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
TaskFactory.create(1, {
|
TaskFactory.create(1, {
|
||||||
start_date: formatISO(now),
|
start_date: formatISO(now),
|
||||||
@ -77,4 +77,49 @@ describe('List View Gantt', () => {
|
|||||||
.trigger('mouseup', {force: true})
|
.trigger('mouseup', {force: true})
|
||||||
cy.wait('@taskUpdate')
|
cy.wait('@taskUpdate')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should change the query parameters when selecting a date range', () => {
|
||||||
|
const now = Date.UTC(2022, 10, 9)
|
||||||
|
cy.clock(now, ['Date'])
|
||||||
|
|
||||||
|
cy.visit('/lists/1/gantt')
|
||||||
|
|
||||||
|
cy.get('.list-gantt .gantt-options .field .control input.input.form-control')
|
||||||
|
.click()
|
||||||
|
cy.get('.flatpickr-calendar .flatpickr-innerContainer .dayContainer .flatpickr-day')
|
||||||
|
.first()
|
||||||
|
.click()
|
||||||
|
cy.get('.flatpickr-calendar .flatpickr-innerContainer .dayContainer .flatpickr-day')
|
||||||
|
.last()
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.url().should('contain', 'dateFrom=2022-09-25')
|
||||||
|
cy.url().should('contain', 'dateTo=2022-11-05')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should change the date range based on date query parameters', () => {
|
||||||
|
cy.visit('/lists/1/gantt?dateFrom=2022-09-25&dateTo=2022-11-05')
|
||||||
|
|
||||||
|
cy.get('.g-timeunits-container')
|
||||||
|
.should('contain', 'September 2022')
|
||||||
|
.should('contain', 'October 2022')
|
||||||
|
.should('contain', 'November 2022')
|
||||||
|
cy.get('.list-gantt .gantt-options .field .control input.input.form-control')
|
||||||
|
.should('have.value', '25 Sep 2022 to 5 Nov 2022')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should open a task when double clicked on it', () => {
|
||||||
|
const now = new Date()
|
||||||
|
const tasks = TaskFactory.create(1, {
|
||||||
|
start_date: formatISO(now),
|
||||||
|
end_date: formatISO(now.setDate(now.getDate() + 4)),
|
||||||
|
})
|
||||||
|
cy.visit('/lists/1/gantt')
|
||||||
|
|
||||||
|
cy.get('.gantt-container .g-gantt-chart .g-gantt-row-bars-container .g-gantt-bar')
|
||||||
|
.dblclick()
|
||||||
|
|
||||||
|
cy.url()
|
||||||
|
.should('contain', `/tasks/${tasks[0].id}`)
|
||||||
|
})
|
||||||
})
|
})
|
@ -16,16 +16,22 @@ export function useRouteFilters<CurrentFilters extends Filters>(
|
|||||||
|
|
||||||
const routeFromFiltersFullPath = computed(() => router.resolve(filtersToRoute(filters.value)).fullPath)
|
const routeFromFiltersFullPath = computed(() => router.resolve(filtersToRoute(filters.value)).fullPath)
|
||||||
|
|
||||||
watch(() => route.value, (route, oldRoute) => {
|
watch(
|
||||||
if (
|
route,
|
||||||
(route && oldRoute && typeof route.name !== 'undefined' && typeof oldRoute.name !== 'undefined' && route.name !== oldRoute.name) ||
|
(route, oldRoute) => {
|
||||||
routeFromFiltersFullPath.value === route.fullPath
|
if (
|
||||||
) {
|
route?.name !== oldRoute?.name ||
|
||||||
return
|
routeFromFiltersFullPath.value === route.fullPath
|
||||||
}
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
filters.value = routeToFilters(route)
|
filters.value = routeToFilters(route)
|
||||||
})
|
},
|
||||||
|
{
|
||||||
|
immediate: true, // set the filter from the initial route
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
filters,
|
filters,
|
||||||
@ -35,12 +41,23 @@ export function useRouteFilters<CurrentFilters extends Filters>(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// only apply new route after all filters have changed in component cycle
|
// only apply new route after all filters have changed in component cycle
|
||||||
{flush: 'post'},
|
{
|
||||||
|
deep: true,
|
||||||
|
flush: 'post',
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const hasDefaultFilters = computed(() => {
|
const hasDefaultFilters = ref(false)
|
||||||
return equal(filters.value, getDefaultFilters(route.value))
|
watch(
|
||||||
})
|
[filters, route],
|
||||||
|
([filters, route]) => {
|
||||||
|
hasDefaultFilters.value = equal(filters, getDefaultFilters(route))
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
function setDefaultFilters() {
|
function setDefaultFilters() {
|
||||||
filters.value = getDefaultFilters(route.value)
|
filters.value = getDefaultFilters(route.value)
|
||||||
|
@ -1,8 +1,16 @@
|
|||||||
import {format} from 'date-fns'
|
|
||||||
import {DATEFNS_DATE_FORMAT_KEBAB} from '@/constants/date'
|
|
||||||
import type {DateISO} from '@/types/DateISO'
|
import type {DateISO} from '@/types/DateISO'
|
||||||
import type {DateKebab} from '@/types/DateKebab'
|
import type {DateKebab} from '@/types/DateKebab'
|
||||||
|
|
||||||
|
// ✅ Format a date to YYYY-MM-DD (or any other format)
|
||||||
|
function padTo2Digits(num: number) {
|
||||||
|
return num.toString().padStart(2, '0')
|
||||||
|
}
|
||||||
|
|
||||||
export function isoToKebabDate(isoDate: DateISO) {
|
export function isoToKebabDate(isoDate: DateISO) {
|
||||||
return format(new Date(isoDate), DATEFNS_DATE_FORMAT_KEBAB) as DateKebab
|
const date = new Date(isoDate)
|
||||||
|
return [
|
||||||
|
date.getFullYear(),
|
||||||
|
padTo2Digits(date.getMonth() + 1), // January is 0, but we want it to be 1
|
||||||
|
padTo2Digits(date.getDate()),
|
||||||
|
].join('-') as DateKebab
|
||||||
}
|
}
|
@ -22,7 +22,7 @@ export function parseDateProp(kebabDate: DateKebab | undefined): string | undefi
|
|||||||
if (!dateValuesAreValid) {
|
if (!dateValuesAreValid) {
|
||||||
throw new Error('Invalid date values')
|
throw new Error('Invalid date values')
|
||||||
}
|
}
|
||||||
return new Date(year, month, date).toISOString() as DateISO
|
return new Date(year, month - 1, date).toISOString() as DateISO
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
// ignore nonsense route queries
|
// ignore nonsense route queries
|
||||||
return
|
return
|
||||||
|
@ -88,9 +88,15 @@ const {
|
|||||||
updateTask,
|
updateTask,
|
||||||
} = useGanttFilters(route)
|
} = useGanttFilters(route)
|
||||||
|
|
||||||
const today = new Date(new Date().setHours(0,0,0,0))
|
const DEFAULT_DATE_RANGE_DAYS = 7
|
||||||
const defaultTaskStartDate: DateISO = new Date(today).toISOString()
|
|
||||||
const defaultTaskEndDate: DateISO = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7, 23,59,0,0).toISOString()
|
const today = new Date()
|
||||||
|
const defaultTaskStartDate: DateISO = new Date(today.setHours(0, 0, 0, 0)).toISOString()
|
||||||
|
const defaultTaskEndDate: DateISO = new Date(new Date(
|
||||||
|
today.getFullYear(),
|
||||||
|
today.getMonth(),
|
||||||
|
today.getDate() + DEFAULT_DATE_RANGE_DAYS,
|
||||||
|
).setHours(23, 59, 0, 0)).toISOString()
|
||||||
|
|
||||||
async function addGanttTask(title: ITask['title']) {
|
async function addGanttTask(title: ITask['title']) {
|
||||||
return await addTask({
|
return await addTask({
|
||||||
|
@ -98,8 +98,8 @@ export function useGanttFilters(route: Ref<RouteLocationNormalized>): UseGanttFi
|
|||||||
setDefaultFilters,
|
setDefaultFilters,
|
||||||
} = useRouteFilters<GanttFilters>(
|
} = useRouteFilters<GanttFilters>(
|
||||||
route,
|
route,
|
||||||
ganttRouteToFilters,
|
|
||||||
ganttGetDefaultFilters,
|
ganttGetDefaultFilters,
|
||||||
|
ganttRouteToFilters,
|
||||||
ganttFiltersToRoute,
|
ganttFiltersToRoute,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user