86 lines
2.4 KiB
TypeScript
86 lines
2.4 KiB
TypeScript
import type { Article, ArticlePage, ArticleStatus } from '@/composables/useArticles'
|
|
|
|
export interface EnvelopeParams {
|
|
page?: number
|
|
size?: number
|
|
q?: string
|
|
status?: ArticleStatus | ''
|
|
sort?: string
|
|
site?: string
|
|
seo?: '' | 'suggestions'
|
|
}
|
|
|
|
function fold(value: string) {
|
|
return value.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase()
|
|
}
|
|
|
|
export function articleEnvelope(all: Article[], params: EnvelopeParams = {}): ArticlePage {
|
|
const { page = 1, size = 25, q = '', status = '', sort = '', seo = '' } = params
|
|
const filtered = all
|
|
.filter(
|
|
(article) =>
|
|
!seo ||
|
|
(article.seo_status === 'suggestions' && (article.seo_suggestions ?? 0) > 0),
|
|
)
|
|
.filter((article) => !status || article.is_online === (status === 'online'))
|
|
.filter((article) => !q || fold(article.title).includes(fold(q)))
|
|
if (sort) {
|
|
const [name, direction] = sort.split(':') as [string, string]
|
|
const field = (name === 'status' ? 'is_online' : name) as keyof Article
|
|
filtered.sort((left, right) => {
|
|
const order = String(left[field]).localeCompare(String(right[field]))
|
|
return direction === 'desc' ? -order : order
|
|
})
|
|
}
|
|
const online = all.filter((article) => article.is_online).length
|
|
return {
|
|
items: filtered.slice((page - 1) * size, page * size),
|
|
total: filtered.length,
|
|
page,
|
|
size,
|
|
counts: { all: all.length, online, draft: all.length - online },
|
|
}
|
|
}
|
|
|
|
export function articleListUrl(params: EnvelopeParams = {}) {
|
|
const { page = 1, size = 25, q = '', status = '', sort = '', site = '', seo = '' } = params
|
|
const query = new URLSearchParams({
|
|
format: 'html',
|
|
page: String(page),
|
|
size: String(size),
|
|
})
|
|
if (q) {
|
|
query.set('q', q)
|
|
}
|
|
if (status) {
|
|
query.set('status', status)
|
|
}
|
|
if (sort) {
|
|
query.set('sort', sort)
|
|
}
|
|
if (site) {
|
|
query.set('site', site)
|
|
}
|
|
if (seo) {
|
|
query.set('seo', seo)
|
|
}
|
|
return `/v1/article/?${query.toString()}`
|
|
}
|
|
|
|
export function articleListRoute(params: EnvelopeParams = {}) {
|
|
return `GET ${articleListUrl(params)}`
|
|
}
|
|
|
|
export function parseListUrl(url: string): EnvelopeParams {
|
|
const query = new URL(url, 'http://localhost').searchParams
|
|
return {
|
|
page: Number(query.get('page')),
|
|
size: Number(query.get('size')),
|
|
q: query.get('q') ?? '',
|
|
status: (query.get('status') ?? '') as ArticleStatus | '',
|
|
sort: query.get('sort') ?? '',
|
|
...(query.get('site') ? { site: query.get('site') ?? '' } : {}),
|
|
...(query.get('seo') ? { seo: 'suggestions' as const } : {}),
|
|
}
|
|
}
|