feat: replace our home-grown gantt implementation with ganttastic #2180
|
@ -23,6 +23,7 @@
|
|||
"@fortawesome/free-solid-svg-icons": "6.2.0",
|
||||
"@fortawesome/vue-fontawesome": "3.0.1",
|
||||
"@github/hotkey": "2.0.1",
|
||||
"@infectoone/vue-ganttastic": "^2.0.4",
|
||||
"@kyvg/vue3-notification": "2.4.1",
|
||||
"@sentry/tracing": "7.17.0",
|
||||
"@sentry/vue": "7.17.0",
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
<template>
|
||||
<g-gantt-chart
|
||||
konrad marked this conversation as resolved
Outdated
|
||||
:chart-start="dateFromFormatted"
|
||||
:chart-end="dateToFormatted"
|
||||
precision="day"
|
||||
bar-start="startDate"
|
||||
bar-end="endDate"
|
||||
:grid="true"
|
||||
@dragend-bar="updateTask"
|
||||
>
|
||||
<g-gantt-row
|
||||
v-for="bar in ganttBars"
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
Is it possible to use here simply Is it possible to use here simply `inherit` as value?
konrad
commented
Seems to work, yes. Seems to work, yes.
dpschen
commented
Not necessary with lates release. Removed. Not necessary with lates release. Removed.
|
||||
label=""
|
||||
:bars="bar"
|
||||
/>
|
||||
</g-gantt-chart>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {computed, ref} from 'vue'
|
||||
import TaskCollectionService from '@/services/taskCollection'
|
||||
import {format} from 'date-fns'
|
||||
import {colorIsDark} from '@/helpers/color/colorIsDark'
|
||||
import TaskService from '@/services/task'
|
||||
|
||||
const dateFormat = 'yyyy-LL-dd kk:mm'
|
||||
|
||||
const props = defineProps({
|
||||
listId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
dateFrom: {
|
||||
default: () => new Date(new Date().setDate(new Date().getDate() - 15)),
|
||||
},
|
||||
dateTo: {
|
||||
default: () => new Date(new Date().setDate(new Date().getDate() + 30)),
|
||||
},
|
||||
})
|
||||
|
||||
const dateFromFormatted = computed(() => format(props.dateFrom, dateFormat))
|
||||
const dateToFormatted = computed(() => format(props.dateTo, dateFormat))
|
||||
|
||||
const tasks = ref([])
|
||||
|
||||
const ganttBars = ref([])
|
||||
|
||||
// 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() {
|
||||
const defaultStartDate = '2022-07-19 12:00'
|
||||
const defaultEndDate = '2022-07-25 12:00'
|
||||
|
||||
tasks.value.forEach(t => ganttBars.value.push([{
|
||||
startDate: t.startDate ? format(t.startDate, dateFormat) : defaultStartDate,
|
||||
endDate: t.endDate ? format(t.endDate, dateFormat) : defaultEndDate,
|
||||
ganttBarConfig: {
|
||||
id: t.id,
|
||||
label: t.title,
|
||||
hasHandles: true,
|
||||
style: {
|
||||
color: colorIsDark(t.getHexColor()) ? 'black' : 'white',
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
Picky: Use Picky: Use `@/models...`
|
||||
backgroundColor: t.getHexColor(),
|
||||
},
|
||||
},
|
||||
}]))
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
picky: use picky: use `DATE_FORMAT` to make clear it's a 'config const'
dpschen
commented
But also: shouldn't this depend on the user setting / language? But also: shouldn't this depend on the user setting / language?
konrad
commented
It's only used to pass the date in the correct format to the gantt chart libaray so it will always be the same. Not sure why they only take strings as input instead of > shouldn't this depend on the user setting / language?
It's only used to pass the date in the correct format to the gantt chart libaray so it will always be the same. Not sure why they only take strings as input instead of `Date` objects but that's how it is.
|
||||
}
|
||||
|
||||
async function loadTasks() {
|
||||
tasks.value = new Map()
|
||||
|
||||
const params = {
|
||||
sort_by: ['start_date', 'done', 'id'],
|
||||
order_by: ['asc', 'asc', 'desc'],
|
||||
filter_by: ['done'], // TODO: only load tasks in the current date range
|
||||
filter_comparator: ['equals'],
|
||||
filter_value: ['false'],
|
||||
filter_concat: 'and',
|
||||
}
|
||||
|
||||
const taskCollectionService = new TaskCollectionService()
|
||||
|
||||
const getAllTasks = async (page = 1) => {
|
||||
const tasks = await taskCollectionService.getAll({listId: props.listId}, params, page)
|
||||
if (page < taskCollectionService.totalPages) {
|
||||
const nextTasks = await getAllTasks(page + 1)
|
||||
return tasks.concat(nextTasks)
|
||||
}
|
||||
return tasks
|
||||
}
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
picky: If you use a default value there is no need to define picky: If you use a default value there is no need to define `required`
|
||||
|
||||
const loadedTasks = await getAllTasks()
|
||||
|
||||
loadedTasks
|
||||
.forEach(t => {
|
||||
tasks.value.set(t.id, t)
|
||||
})
|
||||
|
||||
mapGanttBars()
|
||||
}
|
||||
|
||||
loadTasks()
|
||||
|
||||
async function updateTask(e) {
|
||||
const task = tasks.value.get(e.bar.ganttBarConfig.id)
|
||||
task.startDate = e.bar.startDate
|
||||
task.endDate = e.bar.endDate
|
||||
dpschen marked this conversation as resolved
Outdated
dpschen
commented
User User `TaskModel['id']`
konrad
commented
Done (I think you did that one?) Done (I think you did that one?)
|
||||
const taskService = new TaskService()
|
||||
await taskService.update(task)
|
||||
// TODO: Loading animation
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
define types define types
konrad
commented
Done. Done.
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.g-gantt-row-label {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
|
@ -49,7 +49,7 @@
|
|||
<template #default>
|
||||
<div class="gantt-chart-container">
|
||||
<card :padding="false" class="has-overflow">
|
||||
|
||||
|
||||
<gantt-chart
|
||||
:date-from="dateFrom"
|
||||
:date-to="dateTo"
|
||||
|
@ -72,7 +72,7 @@ import {useI18n} from 'vue-i18n'
|
|||
import {useAuthStore} from '@/stores/auth'
|
||||
|
||||
import ListWrapper from './ListWrapper.vue'
|
||||
import GanttChart from '@/components/tasks/gantt-component.vue'
|
||||
import GanttChart from '@/components/tasks/gantt-chart.vue'
|
||||
import Fancycheckbox from '@/components/input/fancycheckbox.vue'
|
||||
|
||||
const props = defineProps({
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
Should this update? Should this update?
konrad
commented
No, doesn't even need to be ref. No, doesn't even need to be ref.
|
||||
|
|
Reference in New Issue
Use loading component. This way it's easier for us to refactor the
is-loading
styles from bulma later.Done.