123 lines
3.1 KiB
TypeScript
123 lines
3.1 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { ref } from 'vue'
|
|
import {
|
|
type CreateProjectInput,
|
|
itemCreate,
|
|
itemDelete,
|
|
itemGetById,
|
|
itemsList,
|
|
itemUpdate,
|
|
type Project,
|
|
type UpdateProjectInput,
|
|
} from '@/api/project.api.ts'
|
|
import type { Meta } from '@/api/issue.api.ts'
|
|
|
|
const CURRENT_PROJECT_KEY = 'currentProjectId'
|
|
|
|
function readStoredProjectId(): string | null {
|
|
try {
|
|
return localStorage.getItem(CURRENT_PROJECT_KEY)
|
|
} catch {
|
|
// ignore storage errors (e.g. disabled in private mode)
|
|
return null
|
|
}
|
|
}
|
|
|
|
export const useProjectStore = defineStore('project', () => {
|
|
const projects = ref<Project[]>([])
|
|
const current = ref<Project | null>(null)
|
|
// Seeded synchronously from localStorage so consumers (e.g. the issues list)
|
|
// know the selected project id immediately, without waiting for `current`
|
|
// to be resolved over the network via restoreCurrent().
|
|
const currentProjectId = ref<string | null>(readStoredProjectId())
|
|
const error = ref<string | null>(null)
|
|
const lastMeta = ref<Meta>({
|
|
page: 1,
|
|
totalCount: 0,
|
|
totalPages: 0,
|
|
})
|
|
|
|
async function list(params: { page: number; limit: number }) {
|
|
try {
|
|
const res = await itemsList(params)
|
|
projects.value = res.list
|
|
return res
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'error get list of projects'
|
|
return { list: [], meta: lastMeta.value }
|
|
}
|
|
}
|
|
|
|
async function getById(id: string) {
|
|
try {
|
|
return await itemGetById(id)
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'error get project by id'
|
|
}
|
|
}
|
|
|
|
async function create(input: CreateProjectInput) {
|
|
try {
|
|
return await itemCreate(input)
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'error creating project'
|
|
}
|
|
}
|
|
|
|
async function update(id: string, input: UpdateProjectInput) {
|
|
try {
|
|
return await itemUpdate(id, input)
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'error updating project'
|
|
}
|
|
}
|
|
|
|
async function remove(id: string) {
|
|
try {
|
|
return await itemDelete(id)
|
|
} catch (e) {
|
|
error.value = e instanceof Error ? e.message : 'error deleting project'
|
|
return false
|
|
}
|
|
}
|
|
|
|
function clearError() {
|
|
error.value = null
|
|
}
|
|
|
|
function select(project: Project | null) {
|
|
current.value = project
|
|
currentProjectId.value = project?.id ?? null
|
|
try {
|
|
if (project) localStorage.setItem(CURRENT_PROJECT_KEY, project.id)
|
|
else localStorage.removeItem(CURRENT_PROJECT_KEY)
|
|
} catch {
|
|
// ignore storage errors (e.g. disabled in private mode)
|
|
}
|
|
}
|
|
|
|
async function restoreCurrent() {
|
|
const id = readStoredProjectId()
|
|
if (!id) return
|
|
|
|
const project = projects.value.find((el) => el.id === id) ?? (await getById(id))
|
|
if (project) current.value = project
|
|
else select(null) // stored id no longer refers to an existing project
|
|
}
|
|
|
|
return {
|
|
projects,
|
|
current,
|
|
currentProjectId,
|
|
error,
|
|
list,
|
|
getById,
|
|
create,
|
|
update,
|
|
remove,
|
|
clearError,
|
|
select,
|
|
restoreCurrent,
|
|
}
|
|
})
|