feat: update ganttastic version

This commit is contained in:
Dominik Pschenitschni 2022-10-03 18:37:44 +02:00
parent 0f1c5e9394
commit 1d495b8603
No known key found for this signature in database
GPG key ID: B257AC0149F43A77
6 changed files with 1599 additions and 1626 deletions

View file

@ -23,7 +23,7 @@
"@fortawesome/free-solid-svg-icons": "6.2.0", "@fortawesome/free-solid-svg-icons": "6.2.0",
"@fortawesome/vue-fontawesome": "3.0.1", "@fortawesome/vue-fontawesome": "3.0.1",
"@github/hotkey": "2.0.1", "@github/hotkey": "2.0.1",
"@infectoone/vue-ganttastic": "^2.0.4", "@infectoone/vue-ganttastic": "./vendor/infectoone-vue-ganttastic-2.1.1.tgz",
"@kyvg/vue3-notification": "2.4.1", "@kyvg/vue3-notification": "2.4.1",
"@sentry/tracing": "7.14.1", "@sentry/tracing": "7.14.1",
"@sentry/vue": "7.14.1", "@sentry/vue": "7.14.1",

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
<template> <template>
<Loading class="gantt-container" v-if="taskService.loading || taskCollectionService.loading"/> <Loading class="gantt-container" v-if="taskService.loading || taskCollectionService.loading"/>
<div class="gantt-container" v-else> <div class="gantt-container" v-else>
<g-gantt-chart <GGanttChart
:chart-start="`${dateFrom} 00:00`" :chart-start="`${dateFrom} 00:00`"
:chart-end="`${dateTo} 23:59`" :chart-end="`${dateTo} 23:59`"
:precision="PRECISION" :precision="PRECISION"
@ -10,7 +10,6 @@
:grid="true" :grid="true"
@dragend-bar="updateTask" @dragend-bar="updateTask"
@dblclick-bar="openTask" @dblclick-bar="openTask"
font="inherit"
:width="ganttChartWidth + 'px'" :width="ganttChartWidth + 'px'"
> >
<template #timeunit="{label, value}"> <template #timeunit="{label, value}">
@ -23,75 +22,45 @@
</span> </span>
</div> </div>
</template> </template>
<g-gantt-row <GGanttRow
v-for="(bar, k) in ganttBars" v-for="(bar, k) in ganttBars"
:key="k" :key="k"
label="" label=""
:bars="bar" :bars="bar"
/> />
</g-gantt-chart> </GGanttChart>
</div> </div>
<TaskForm v-if="canWrite" @create-task="createTask" /> <TaskForm v-if="canWrite" @create-task="createTask" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {computed, ref, watchEffect, shallowReactive, type Ref, type PropType} from 'vue' import {computed, ref, watch, watchEffect, shallowReactive, type PropType} from 'vue'
import {useRouter} from 'vue-router' import {useRouter} from 'vue-router'
import {format, parse} from 'date-fns' import {format, parse} from 'date-fns'
import TaskCollectionService from '@/services/taskCollection' import TaskCollectionService from '@/services/taskCollection'
import TaskService from '@/services/task' import TaskService from '@/services/task'
import TaskModel from '@/models/task' import TaskModel, { getHexColor } from '@/models/task'
import type ListModel from '@/models/list' import type ListModel from '@/models/list'
import {colorIsDark} from '@/helpers/color/colorIsDark' import {colorIsDark} from '@/helpers/color/colorIsDark'
import {RIGHTS} from '@/constants/rights' import {RIGHTS} from '@/constants/rights'
import {
extendDayjs,
GGanttChart,
GGanttRow,
type GanttBarObject,
} from '@infectoone/vue-ganttastic'
import Loading from '@/components/misc/loading.vue' import Loading from '@/components/misc/loading.vue'
import TaskForm from '@/components/tasks/TaskForm.vue' import TaskForm from '@/components/tasks/TaskForm.vue'
import {useBaseStore} from '@/stores/base' import {useBaseStore} from '@/stores/base'
// FIXME: these types should be exported from vue-ganttastic extendDayjs()
// see: https://github.com/InfectoOne/vue-ganttastic/blob/master/src/models/models.ts
export interface GanttBarConfig {
id: string,
label?: string
hasHandles?: boolean
immobile?: boolean
bundle?: string
pushOnOverlap?: boolean
dragLimitLeft?: number
dragLimitRight?: number
style?: CSSStyleSheet
}
export type GanttBarObject = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any,
ganttBarConfig: GanttBarConfig
}
export type GGanttChartPropsRefs = {
chartStart: Ref<string>
chartEnd: Ref<string>
precision: Ref<'hour' | 'day' | 'month'>
barStart: Ref<string>
barEnd: Ref<string>
rowHeight: Ref<number>
dateFormat: Ref<string>
width: Ref<string>
hideTimeaxis: Ref<boolean>
colorScheme: Ref<string>
grid: Ref<boolean>
pushOnOverlap: Ref<boolean>
noOverlap: Ref<boolean>
gGanttChart: Ref<HTMLElement | null>
font: Ref<string>
}
const PRECISION = 'day'
const PRECISION = 'day' as const
const DATE_FORMAT = 'yyyy-LL-dd HH:mm' const DATE_FORMAT = 'yyyy-LL-dd HH:mm'
const baseStore = useBaseStore() const baseStore = useBaseStore()
@ -111,7 +80,7 @@ const props = defineProps({
required: true, required: true,
}, },
showTasksWithoutDates: { showTasksWithoutDates: {
type: Boolean as PropType<boolean>, type: Boolean,
default: false, default: false,
}, },
}) })
@ -134,6 +103,18 @@ const canWrite = computed(() => baseStore.currentList.maxRight > RIGHTS.READ)
const tasks = ref<Map<TaskModel['id'], TaskModel>>(new Map()) const tasks = ref<Map<TaskModel['id'], TaskModel>>(new Map())
const ganttBars = ref<GanttBarObject[][]>([]) const ganttBars = ref<GanttBarObject[][]>([])
watch(
tasks,
// We need a "real" ref object for the gantt bars to instantly update the tasks when they are dragged on the chart.
// A computed won't work directly.
// function mapGanttBars() {
() => {
ganttBars.value = []
tasks.value.forEach(t => ganttBars.value.push(transformTaskToGanttBar(t)))
},
{deep: true}
)
const defaultStartDate = format(new Date(), DATE_FORMAT) const defaultStartDate = format(new Date(), DATE_FORMAT)
const defaultEndDate = format(new Date((new Date()).setDate((new Date()).getDate() + 7)), DATE_FORMAT) const defaultEndDate = format(new Date((new Date()).setDate((new Date()).getDate() + 7)), DATE_FORMAT)
@ -143,12 +124,12 @@ function transformTaskToGanttBar(t: TaskModel) {
startDate: t.startDate ? format(t.startDate, DATE_FORMAT) : defaultStartDate, startDate: t.startDate ? format(t.startDate, DATE_FORMAT) : defaultStartDate,
endDate: t.endDate ? format(t.endDate, DATE_FORMAT) : defaultEndDate, endDate: t.endDate ? format(t.endDate, DATE_FORMAT) : defaultEndDate,
ganttBarConfig: { ganttBarConfig: {
id: t.id, id: String(t.id),
label: t.title, label: t.title,
hasHandles: true, hasHandles: true,
style: { style: {
color: t.startDate ? (colorIsDark(t.getHexColor(t.hexColor)) ? black : 'white') : black, color: t.startDate ? (colorIsDark(getHexColor(t.hexColor)) ? black : 'white') : black,
backgroundColor: t.startDate ? t.getHexColor(t.hexColor) : 'var(--grey-100)', backgroundColor: t.startDate ? getHexColor(t.hexColor) : 'var(--grey-100)',
border: t.startDate ? '' : '2px dashed var(--grey-300)', border: t.startDate ? '' : '2px dashed var(--grey-300)',
'text-decoration': t.done ? 'line-through' : null, 'text-decoration': t.done ? 'line-through' : null,
}, },
@ -156,13 +137,7 @@ function transformTaskToGanttBar(t: TaskModel) {
} as GanttBarObject] } as GanttBarObject]
} }
// We need a "real" ref object for the gantt bars to instantly update the tasks when they are dragged on the chart.
// A computed won't work directly.
function mapGanttBars() {
ganttBars.value = []
tasks.value.forEach(t => ganttBars.value.push(transformTaskToGanttBar(t)))
}
// FIXME: unite with other filter params types // FIXME: unite with other filter params types
interface GetAllTasksParams { interface GetAllTasksParams {
@ -208,8 +183,6 @@ async function loadTasks({
const loadedTasks = await getAllTasks(params) const loadedTasks = await getAllTasks(params)
loadedTasks.forEach(t => tasks.value.set(t.id, t)) loadedTasks.forEach(t => tasks.value.set(t.id, t))
mapGanttBars()
} }
watchEffect(() => loadTasks({ watchEffect(() => loadTasks({
@ -226,7 +199,6 @@ async function createTask(title: TaskModel['title']) {
endDate: defaultEndDate, endDate: defaultEndDate,
})) }))
tasks.value.set(newTask.id, newTask) tasks.value.set(newTask.id, newTask)
mapGanttBars()
return newTask return newTask
} }
@ -268,14 +240,25 @@ function dayIsToday(label: string): boolean {
} }
</script> </script>
<style scoped lang="scss">
.gantt-container {
overflow-x: auto;
}
</style>
<style lang="scss"> <style lang="scss">
// Not scoped because we need to style the elements inside the gantt chart component // Not scoped because we need to style the elements inside the gantt chart component
.g-gantt-chart {
width: 2000px;
}
.g-gantt-row-label { .g-gantt-row-label {
display: none !important; display: none;
} }
.g-upper-timeunit, .g-timeunit { .g-upper-timeunit, .g-timeunit {
background: var(--white) !important; background: var(--white);
font-family: $vikunja-font; font-family: $vikunja-font;
} }
@ -287,7 +270,7 @@ function dayIsToday(label: string): boolean {
.g-timeunit .timeunit-wrapper { .g-timeunit .timeunit-wrapper {
padding: 0.5rem 0; padding: 0.5rem 0;
font-size: 1rem !important; font-size: 1rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@ -306,13 +289,13 @@ function dayIsToday(label: string): boolean {
} }
.g-timeaxis { .g-timeaxis {
height: auto !important; height: auto;
box-shadow: none !important; box-shadow: none;
} }
.g-gantt-row > .g-gantt-row-bars-container { .g-gantt-row > .g-gantt-row-bars-container {
border-bottom: none !important; border-bottom: none;
border-top: none !important; border-top: none;
} }
.g-gantt-row:nth-child(odd) { .g-gantt-row:nth-child(odd) {
@ -326,21 +309,11 @@ function dayIsToday(label: string): boolean {
&-handle-left, &-handle-left,
&-handle-right { &-handle-right {
width: 6px !important; width: 6px;
height: 75% !important; height: 75%;
opacity: .75 !important; opacity: .75;
border-radius: $radius !important; border-radius: $radius;
margin-top: 4px; margin-top: 4px;
} }
} }
</style> </style>
<style scoped lang="scss">
.gantt-container {
overflow-x: auto;
}
#g-gantt-chart {
width: 2000px;
}
</style>

View file

@ -4,7 +4,7 @@
* @param color * @param color
* @returns {string} * @returns {string}
*/ */
export function colorFromHex(color) { export function colorFromHex(color: string) {
if (color.substring(0, 1) === '#') { if (color.substring(0, 1) === '#') {
color = color.substring(1, 7) color = color.substring(1, 7)
} }

View file

@ -59,7 +59,6 @@ import FontAwesomeIcon from '@/components/misc/Icon'
import Button from '@/components/input/button.vue' import Button from '@/components/input/button.vue'
import Modal from '@/components/misc/modal.vue' import Modal from '@/components/misc/modal.vue'
import Card from '@/components/misc/card.vue' import Card from '@/components/misc/card.vue'
import ganttastic from '@infectoone/vue-ganttastic'
app.component('icon', FontAwesomeIcon) app.component('icon', FontAwesomeIcon)
app.component('x-button', Button) app.component('x-button', Button)
@ -103,8 +102,6 @@ if (window.SENTRY_ENABLED) {
import('./sentry').then(sentry => sentry.default(app, router)) import('./sentry').then(sentry => sentry.default(app, router))
} }
app.use(ganttastic)
app.use(pinia) app.use(pinia)
app.use(router) app.use(router)
app.use(i18n) app.use(i18n)

Binary file not shown.