diff --git a/web/src/stores/projects.ts b/web/src/stores/projects.ts new file mode 100644 index 0000000..8992748 --- /dev/null +++ b/web/src/stores/projects.ts @@ -0,0 +1,48 @@ +import { defineStore } from 'pinia' +import { ref, computed } from 'vue' +import { projectsApi, type Project, type Visibility } from '@/api/projects' + +export const useProjectsStore = defineStore('projects', () => { + const items = ref([]) + const current = ref(null) + const includeArchived = ref(false) + const loading = ref(false) + + async function refresh() { + loading.value = true + try { + const out = await projectsApi.list(includeArchived.value) + items.value = out.items + } finally { + loading.value = false + } + } + + async function load(slug: string) { + current.value = await projectsApi.get(slug) + return current.value + } + + async function create(body: { slug: string; name: string; description?: string; visibility?: Visibility }) { + const p = await projectsApi.create(body) + items.value = [p, ...items.value] + return p + } + + async function archive(slug: string) { + await projectsApi.archive(slug) + await refresh() + if (current.value?.slug === slug) current.value = await projectsApi.get(slug) + } + + async function unarchive(slug: string) { + await projectsApi.unarchive(slug) + await refresh() + if (current.value?.slug === slug) current.value = await projectsApi.get(slug) + } + + const archivedItems = computed(() => items.value.filter((p) => p.archived_at)) + const activeItems = computed(() => items.value.filter((p) => !p.archived_at)) + + return { items, current, loading, includeArchived, archivedItems, activeItems, refresh, load, create, archive, unarchive } +}) diff --git a/web/src/stores/requirements.ts b/web/src/stores/requirements.ts new file mode 100644 index 0000000..6311190 --- /dev/null +++ b/web/src/stores/requirements.ts @@ -0,0 +1,49 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' +import { projectsApi, type Phase, type Requirement, type Status } from '@/api/projects' + +export const useRequirementsStore = defineStore('requirements', () => { + const items = ref([]) + const slug = ref('') + const loading = ref(false) + const filterPhase = ref('') + const filterStatus = ref('') + + async function refresh(forSlug: string) { + slug.value = forSlug + loading.value = true + try { + const out = await projectsApi.listRequirements(forSlug, { + phase: filterPhase.value || undefined, + status: filterStatus.value || undefined, + }) + items.value = out.items + } finally { + loading.value = false + } + } + + async function create(forSlug: string, body: { title: string; description?: string }) { + const r = await projectsApi.createRequirement(forSlug, body) + items.value = [r, ...items.value] + return r + } + + async function changePhase(forSlug: string, number: number, phase: Phase) { + const out = await projectsApi.changeRequirementPhase(forSlug, number, phase) + items.value = items.value.map((x) => (x.number === number ? out : x)) + return out + } + + async function close(forSlug: string, number: number) { + await projectsApi.closeRequirement(forSlug, number) + await refresh(forSlug) + } + + async function reopen(forSlug: string, number: number) { + await projectsApi.reopenRequirement(forSlug, number) + await refresh(forSlug) + } + + return { items, slug, loading, filterPhase, filterStatus, refresh, create, changePhase, close, reopen } +})