import { defineStore } from 'pinia' import { ref } from 'vue' import { apiRequest } from '../lib/api' import type { Card } from '../types' type CardPatch = Partial> export const useCardsStore = defineStore('cards', () => { // One project's cards, grouped by status then position. Views re-sort as // needed (Explore's list is alphabetical). Moving a card in or out of this // project (including via the inbox) goes through lib/cardOrder.ts, not // this store -- callers re-load() afterwards. const cards = ref([]) const projectId = ref(null) const loading = ref(false) const loaded = ref(false) const completedCount = () => cards.value.filter((c) => c.complete).length async function load(id: number): Promise { projectId.value = id loaded.value = false loading.value = true try { const { cards: fetched } = await apiRequest<{ cards: Card[] }>(`/projects/${id}/cards`, { auth: true, }) cards.value = fetched loaded.value = true } finally { loading.value = false } } /** Adds to the project's first status, unless a particular one is given * (e.g. a kanban column's own "new card" form) -- either way, at the end. */ async function add(text: string, statusId?: number): Promise { const { card } = await apiRequest<{ card: Card }>(`/projects/${projectId.value}/cards`, { method: 'POST', auth: true, body: statusId === undefined ? { text } : { text, status_id: statusId }, }) // The API appends the card, so the end of the array is its correct place. cards.value.push(card) } async function patch(card: Card, fields: CardPatch): Promise { const { card: updated } = await apiRequest<{ card: Card }>(`/cards/${card.id}`, { method: 'PATCH', auth: true, body: fields, }) const i = cards.value.findIndex((x) => x.id === updated.id) if (i !== -1) cards.value[i] = updated } const setComplete = (card: Card, complete: boolean) => patch(card, { complete }) function reset(): void { cards.value = [] projectId.value = null loaded.value = false } return { cards, projectId, loading, loaded, completedCount, load, add, setComplete, reset, } })