Quick Start
EnhancedKanbanBoard — caso più comune
Smart component che orchestra useBoardService + slot dialog. Caricamento dati, drag-and-drop, CRUD e validazione sono gestiti internamente.
<script setup lang="ts">
import { EnhancedKanbanBoard, getIdUtenteFromJwt } from '@pzeta/vue-kanban'
import {
DefaultFormDialog,
DefaultTagDialog,
DefaultCommentDialog,
DefaultAttachmentDialog,
DefaultActivityDialog,
} from '@pzeta/vue-kanban/dialogs'
const getToken = () => sessionStorage.getItem('jwt')
const getCurrentUserId = () => getIdUtenteFromJwt()
</script>
<template>
<EnhancedKanbanBoard
board-id-or-code="TICKET"
:get-token="getToken"
:get-current-user-id="getCurrentUserId"
>
<template #dialog-form="p"><DefaultFormDialog v-bind="p" /></template>
<template #dialog-attachment="p"><DefaultAttachmentDialog v-bind="p" /></template>
<template #dialog-tag="p"><DefaultTagDialog v-bind="p" /></template>
<template #dialog-activity="p"><DefaultActivityDialog v-bind="p" :get-token="getToken" /></template>
<template #dialog-comment="p"><DefaultCommentDialog v-bind="p" /></template>
</EnhancedKanbanBoard>
</template>
board-id-or-code accetta un numero (idboard) o una stringa (codboard). Senza slot dialog, i pulsanti azione sulle card non aprono nulla — utile per board read-only.
KanbanFasiBoard — pipeline con metriche
Variante per board con WIP limit, stallo, avanzamento e team per fase. Usa internamente useFasiService con tipi FasePipeline / SchedaKanban.
<script setup lang="ts">
import { KanbanFasiBoard } from '@pzeta/vue-kanban'
const userId = 42
const getToken = () => sessionStorage.getItem('jwt')
</script>
<template>
<div class="h-screen p-4">
<KanbanFasiBoard
board-id="crm"
:current-user-id="userId"
:get-token="getToken"
:show-toolbar="true"
:show-search="true"
:show-config="true"
@schedaspostata="(idScheda, orig, dest) => console.log('spostata', idScheda)"
@view="scheda => router.push(`/schede/${scheda.idscheda}`)"
/>
</div>
</template>
Anche qui i dialog vanno passati come slot (gli stessi 5 di EnhancedKanbanBoard).
KanbanBoard — headless
Per controllo totale del rendering (board custom, no PostgREST):
Backend custom (no PostgREST)
Quando il backend è REST custom / GraphQL / mock, implementa l'interfaccia KanbanDataSource e iniettala:
import type { KanbanDataSource, MoveItemResult } from '@pzeta/vue-kanban'
import { useBoardService } from '@pzeta/vue-kanban'
const myDataSource: KanbanDataSource = {
async loadBoard(id) { return fetch(`/api/boards/${id}`).then(r => r.json()) },
async loadColumns(boardId) { /* ... */ },
async loadItems(boardId) { /* ... */ },
async loadItem(itemId) { /* ... */ },
async createItem(boardId, data) { /* ... */ },
async updateItem(itemId, data) { /* ... */ },
async deleteItem(itemId) { return true },
async moveItem(itemId, targetCol, order): Promise<MoveItemResult> {
/* ... */
return { success: true }
},
}
const service = useBoardService('PROJECT-X', { dataSource: myDataSource })
Backend con shape diversa (ItemAdapter)
Per item raw che non corrispondono allo schema fasi (campi diversi, naming inglese, ecc.) usa un ItemAdapter:
import type { ItemAdapter } from '@pzeta/vue-kanban'
const myAdapter: ItemAdapter = (raw) => ({
id: raw.uuid,
columnId: raw.status,
title: raw.headline,
description: raw.summary,
priority: raw.priority ? { name: raw.priority.label, color: raw.priority.hex } : undefined,
tags: (raw.labels ?? []).map(l => ({ id: l.id, name: l.name, color: l.color })),
assignee: raw.owner ? { id: raw.owner.id, name: raw.owner.fullName } : undefined,
dueDate: raw.dueAt,
number: raw.code,
commentCount: raw.commentsCount ?? 0,
activities: raw.activities ?? [],
attachments: raw.files ?? [],
raw,
})
<EnhancedKanbanBoard board-id-or-code="X" :item-adapter="myAdapter" />
L'adapter di default (defaultPostgRESTItemAdapter) gestisce automaticamente naming italiano (titolo, priorita, etichette), inglese (title, priority, tags) e flat RPC (priorita_nome, priorita_colore).
Quando usare quale componente
| Scenario | Componente / API |
|---|---|
| Board CRM/ticket su PostgREST con dialog standard | EnhancedKanbanBoard |
| Pipeline con WIP, stallo, metriche, team | KanbanFasiBoard |
| Layout completamente custom | KanbanBoard + composable manuale |
| Backend non-PostgREST | useBoardService(id, { dataSource }) |
| Backend con campi diversi | :item-adapter="..." su Enhanced/FasiBoard |
| Solo logica, nessun componente | useBoardService headless |