Introduced `loadingCurrentlyBuilding` and `errorCurrentlyBuilding` states to manage the fetching of currently building packages independently. Updated the logic in `fetchCurrentlyBuilding` and related UI bindings to reflect this change, ensuring clearer state handling and improved error tracking.
230 lines
6.0 KiB
TypeScript
230 lines
6.0 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { reactive } from 'vue'
|
|
import { components, getPackages } from '@/api'
|
|
|
|
interface PackageFilters {
|
|
status?: components['schemas']['Package']['status'][]
|
|
pkgbase?: components['schemas']['Package']['pkgbase']
|
|
exact?: boolean
|
|
repo?: components['schemas']['Package']['repo']
|
|
}
|
|
|
|
export const usePackagesStore = defineStore('packages', () => {
|
|
const state = reactive({
|
|
packages: [] as components['schemas']['Package'][],
|
|
currentlyBuildingPackages: [] as components['schemas']['Package'][],
|
|
total: 0,
|
|
offset: 0,
|
|
limit: Number(import.meta.env.VITE_LIMIT) || 50,
|
|
loading: false,
|
|
loadingCurrentlyBuilding: false,
|
|
error: null as string | null,
|
|
errorCurrentlyBuilding: null as string | null,
|
|
lastUpdated: Date.now(),
|
|
filters: {
|
|
status: undefined,
|
|
pkgbase: undefined,
|
|
exact: undefined,
|
|
repo: undefined
|
|
} as PackageFilters
|
|
})
|
|
|
|
// Actions
|
|
const fetchPackages = (init = false) => {
|
|
state.loading = true
|
|
state.error = null
|
|
state.packages = []
|
|
state.total = 0
|
|
|
|
if (init) {
|
|
initFromUrl()
|
|
}
|
|
|
|
const filter: PackageFilters = {}
|
|
if (state.filters.status && state.filters.status.length > 0) {
|
|
filter.status = state.filters.status
|
|
}
|
|
if (state.filters.pkgbase) {
|
|
filter.pkgbase = state.filters.pkgbase
|
|
}
|
|
if (state.filters.exact === true) {
|
|
filter.exact = state.filters.exact
|
|
}
|
|
if (state.filters.repo) {
|
|
filter.repo = state.filters.repo
|
|
}
|
|
|
|
// @ts-ignore
|
|
getPackages({
|
|
limit: state.limit,
|
|
offset: state.offset,
|
|
...filter
|
|
})
|
|
.then((response) => {
|
|
if (!response) throw new Error('No response from API')
|
|
state.packages = response.packages || []
|
|
state.total = response.total || 0
|
|
state.offset = response.offset || 0
|
|
state.limit = response.limit || state.limit
|
|
})
|
|
.catch((err) => {
|
|
if (err.statusCode === 404) {
|
|
state.packages = []
|
|
state.total = 0
|
|
state.offset = 0
|
|
state.limit = Number(import.meta.env.VITE_LIMIT) || 50
|
|
} else {
|
|
state.error = err instanceof Error ? err.message : 'Failed to fetch packages'
|
|
console.error('Error fetching packages:', err)
|
|
}
|
|
})
|
|
.finally(() => {
|
|
state.loading = false
|
|
state.lastUpdated = Date.now()
|
|
})
|
|
}
|
|
|
|
const fetchCurrentlyBuilding = () => {
|
|
state.loadingCurrentlyBuilding = true
|
|
state.errorCurrentlyBuilding = null
|
|
state.currentlyBuildingPackages = []
|
|
|
|
getPackages({
|
|
limit: 0,
|
|
offset: 0,
|
|
status: ['queued', 'building', 'built']
|
|
})
|
|
.then((response) => {
|
|
state.currentlyBuildingPackages = response?.packages || []
|
|
})
|
|
.catch((err) => {
|
|
if (err.statusCode === 404) {
|
|
state.currentlyBuildingPackages = []
|
|
} else {
|
|
state.errorCurrentlyBuilding =
|
|
err instanceof Error ? err.message : 'Failed to fetch currently building packages'
|
|
console.error('Error fetching queued packages:', err)
|
|
}
|
|
})
|
|
.finally(() => {
|
|
state.loadingCurrentlyBuilding = false
|
|
})
|
|
}
|
|
|
|
const goToPage = (page: number) => {
|
|
state.offset = (page - 1) * state.limit
|
|
|
|
updateUrlParams()
|
|
fetchPackages()
|
|
}
|
|
|
|
const setFilters = (newFilters: PackageFilters, page?: number) => {
|
|
state.filters = JSON.parse(JSON.stringify(newFilters))
|
|
if (state.filters.exact === false) {
|
|
state.filters.exact = undefined
|
|
}
|
|
if (page) {
|
|
state.offset = (page - 1) * state.limit
|
|
}
|
|
|
|
updateUrlParams()
|
|
fetchPackages()
|
|
}
|
|
|
|
const resetFilters = () => {
|
|
state.filters = {
|
|
status: undefined,
|
|
pkgbase: undefined,
|
|
exact: undefined,
|
|
repo: undefined
|
|
}
|
|
state.offset = 0
|
|
state.limit = Number(import.meta.env.VITE_LIMIT) || 50
|
|
|
|
updateUrlParams()
|
|
fetchPackages()
|
|
}
|
|
|
|
const updateUrlParams = () => {
|
|
const params = new URLSearchParams()
|
|
|
|
let page = state.offset / state.limit + 1
|
|
// Only add a page parameter if it's not the first page
|
|
if (page > 1) {
|
|
params.set('page', page.toString())
|
|
}
|
|
|
|
if (state.filters.status && state.filters.status.length > 0) {
|
|
state.filters.status.forEach((status: components['schemas']['Package']['status']) => {
|
|
if (status) {
|
|
params.append('status', status)
|
|
}
|
|
})
|
|
}
|
|
|
|
if (state.filters.pkgbase) {
|
|
params.set('pkgbase', state.filters.pkgbase.toLowerCase())
|
|
}
|
|
|
|
if (state.filters.repo) {
|
|
params.set('repo', state.filters.repo)
|
|
}
|
|
|
|
if (state.filters.exact === true) {
|
|
params.set('exact', '')
|
|
} else {
|
|
params.delete('exact')
|
|
}
|
|
|
|
const paramsString = params.toString()
|
|
if (paramsString) {
|
|
window.history.pushState(null, '', `${window.location.pathname}?${paramsString}`)
|
|
} else {
|
|
window.history.pushState(null, '', window.location.pathname)
|
|
}
|
|
}
|
|
|
|
const initFromUrl = () => {
|
|
const urlParams = new URLSearchParams(window.location.search)
|
|
|
|
if (urlParams.has('page')) {
|
|
const pageParam = urlParams.get('page') || '1'
|
|
const parsedPage = parseInt(pageParam, 10)
|
|
const page = !isNaN(parsedPage) && parsedPage > 0 ? parsedPage : 1
|
|
state.offset = (page - 1) * state.limit
|
|
}
|
|
|
|
if (urlParams.has('status')) {
|
|
const status = urlParams.getAll('status')
|
|
state.filters.status = status as components['schemas']['Package']['status'][]
|
|
}
|
|
|
|
if (urlParams.has('pkgbase')) {
|
|
const pkgbase = urlParams.get('pkgbase')
|
|
if (pkgbase === null) return
|
|
state.filters.pkgbase = pkgbase as components['schemas']['Package']['pkgbase']
|
|
}
|
|
|
|
if (urlParams.has('repo')) {
|
|
const repo = urlParams.get('repo')
|
|
if (repo === null) return
|
|
state.filters.repo = repo as components['schemas']['Package']['repo']
|
|
}
|
|
|
|
if (urlParams.has('exact')) {
|
|
state.filters.exact = true
|
|
}
|
|
}
|
|
|
|
return {
|
|
state,
|
|
|
|
// Actions
|
|
fetchPackages,
|
|
fetchCurrentlyBuilding,
|
|
goToPage,
|
|
setFilters,
|
|
resetFilters
|
|
}
|
|
})
|