gantt
Gantt chart with drag-to-reorder tree rows
Gantt chart with drag-to-reorder tree rows
Загрузка превью…
src/gantt/c-gantt-2.vue
<!--
ПОРТ c-gantt-2 ("Gantt chart with drag-to-reorder tree rows").
`Gantt`/`GanttNav`/`GanttView` — настоящий порт целиком (packages/ui/src/reui/gantt).
`onResourceReorder` подключён по контракту (controlled `resources`, ровно как
в оригинале), но сама ручка/жест перетаскивания строки дерева ещё не
портированы (см. заголовок GanttTreeRow.vue/GanttView.vue: `reorderable`/
grip не прокинуты из GanttView) — GanttView.vue не рендерит ручку и не
вызывает `onResourceReorder`, поэтому строки статичны, как в текущем срезе
порта. Дата фиксирована явно в UTC (никаких `new Date()` — детерминизм
стенда), тот же якорь, что и в `ui-gantt`.
-->
<script setup lang="ts">
import { ref } from "vue"
import { addDays, startOfDay, startOfWeek } from "date-fns"
import { Gantt, GanttNav, GanttView } from "@/components/reui/gantt"
import type { GanttEvent, GanttResource } from "@/components/reui/gantt"
import { Card, CardContent } from "@/components/ui/card"
const ANCHOR = new Date(Date.UTC(2024, 0, 8, 0, 0, 0))
const INITIAL_RESOURCES: GanttResource[] = [
{
id: "planning",
title: "Planning",
children: [
{ id: "brief", title: "Project brief" },
{ id: "scope", title: "Scope review" },
],
},
{
id: "design",
title: "Design",
children: [
{ id: "wireframes", title: "Wireframes" },
{ id: "visual-design", title: "Visual design" },
],
},
{
id: "build",
title: "Build",
children: [
{ id: "frontend", title: "Frontend" },
{ id: "backend", title: "Backend" },
{ id: "qa", title: "QA pass" },
],
},
]
function buildBars(anchor: Date): GanttEvent[] {
const week = startOfWeek(startOfDay(anchor), { weekStartsOn: 0 })
const day = (dayOffset: number) => addDays(week, dayOffset)
const bar = (resourceId: string, title: string, startOffset: number, days: number, color: string, progress?: number): GanttEvent => ({
id: `bar-${resourceId}`,
title,
start: day(startOffset),
end: day(startOffset + days),
allDay: true,
color,
resourceId,
progress,
})
return [
bar("brief", "Project brief", -9, 3, "var(--color-blue-500)", 100),
bar("scope", "Scope review", -6, 2, "var(--color-sky-500)", 100),
bar("wireframes", "Wireframes", -4, 4, "var(--color-violet-500)", 80),
bar("visual-design", "Visual design", 0, 5, "var(--color-purple-500)", 35),
bar("frontend", "Frontend", 3, 7, "var(--color-emerald-500)", 10),
bar("backend", "Backend", 5, 6, "var(--color-teal-500)"),
bar("qa", "QA pass", 12, 4, "var(--color-amber-500)"),
]
}
const bars = buildBars(ANCHOR)
const resources = ref<GanttResource[]>(INITIAL_RESOURCES)
</script>
<template>
<div class="w-full p-4">
<Card class="w-full py-0">
<CardContent class="p-0">
<Gantt
:date="ANCHOR"
initial-center="anchor"
:default-events="bars"
:resources="resources"
default-scale="month"
:infinite-scroll="false"
:tree-panel="{ width: 240 }"
:on-resource-reorder="(proposal: { resources: GanttResource[] }) => { resources = proposal.resources }"
class="h-[480px] w-full"
>
<GanttNav />
<GanttView />
</Gantt>
</CardContent>
</Card>
</div>
</template>