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>

Установка

npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-gantt-2.json

Зависимости реестра

npm-зависимости

  • date-fns

Источник: порт из ReUI (Keenthemes, MIT)