mirror of
https://github.com/gotson/komga.git
synced 2026-05-08 12:35:30 +02:00
filter stuff
This commit is contained in:
parent
b24bc27748
commit
81a463a741
4 changed files with 119 additions and 0 deletions
41
next-ui/src/composables/useRouteQuerySchema.ts
Normal file
41
next-ui/src/composables/useRouteQuerySchema.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import * as v from 'valibot'
|
||||
import { useRouteQuery } from '@vueuse/router'
|
||||
import { syncRef } from '@vueuse/core'
|
||||
|
||||
/**
|
||||
* Reactive `route.query` with schema validation.
|
||||
* If value is not valid, the `schema` default values are used.
|
||||
*
|
||||
* @param queryName the query parameter name
|
||||
* @param schema valibot schema to validate against
|
||||
*/
|
||||
export function useRouteQuerySchema<T extends v.GenericSchema>(queryName: string, schema: T) {
|
||||
const queryString = useRouteQuery(queryName, '{}')
|
||||
|
||||
const defaults = v.getDefaults(schema)
|
||||
|
||||
function getInitialValue(stringValue: string) {
|
||||
try {
|
||||
return v.parse(schema, JSON.parse(stringValue))
|
||||
} catch {
|
||||
return defaults
|
||||
}
|
||||
}
|
||||
|
||||
const data = ref(getInitialValue(String(queryString.value)))
|
||||
|
||||
syncRef(data, queryString, {
|
||||
direction: 'ltr',
|
||||
deep: true,
|
||||
transform: {
|
||||
ltr: (left) => {
|
||||
if (JSON.stringify(left) !== JSON.stringify(defaults)) return JSON.stringify(left)
|
||||
return undefined
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
data: data as v.InferOutput<T>,
|
||||
}
|
||||
}
|
||||
22
next-ui/src/functions/filter.ts
Normal file
22
next-ui/src/functions/filter.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import type { SchemaFilterSeriesStatus } from '@/types/filter'
|
||||
import type { InferOutput } from 'valibot'
|
||||
|
||||
export function schemaFilterSeriesStatusToConditions(
|
||||
filter: MaybeRefOrGetter<InferOutput<typeof SchemaFilterSeriesStatus>>,
|
||||
) {
|
||||
const list = toValue(filter).v.map((it) => ({
|
||||
seriesStatus: {
|
||||
operator: it.i === 'e' ? 'isNot' : 'is',
|
||||
value: it.v,
|
||||
},
|
||||
}))
|
||||
|
||||
if (toValue(filter).m === 'allOf')
|
||||
return {
|
||||
allOf: list,
|
||||
}
|
||||
else
|
||||
return {
|
||||
anyOf: list,
|
||||
}
|
||||
}
|
||||
32
next-ui/src/types/filter.test.ts
Normal file
32
next-ui/src/types/filter.test.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import { describe, expect, test } from 'vitest'
|
||||
import * as v from 'valibot'
|
||||
import { SchemaAnyAll } from '@/types/filter'
|
||||
|
||||
describe('schema any all', () => {
|
||||
test('anyOf', () => {
|
||||
const input = { m: 'anyOf' }
|
||||
const result = v.parse(SchemaAnyAll, input)
|
||||
|
||||
expect(result).toStrictEqual(input)
|
||||
})
|
||||
|
||||
test('allOf', () => {
|
||||
const input = { m: 'allOf' }
|
||||
const result = v.parse(SchemaAnyAll, input)
|
||||
|
||||
expect(result).toStrictEqual(input)
|
||||
})
|
||||
|
||||
test('other value throws error', () => {
|
||||
const input = { m: 'other' }
|
||||
|
||||
expect(() => v.parse(SchemaAnyAll, input)).toThrowError()
|
||||
})
|
||||
|
||||
test('defaults to anyOf', () => {
|
||||
const input = { m: 'anyOf' }
|
||||
const defaults = v.getDefaults(SchemaAnyAll)
|
||||
|
||||
expect(defaults).toStrictEqual(input)
|
||||
})
|
||||
})
|
||||
24
next-ui/src/types/filter.ts
Normal file
24
next-ui/src/types/filter.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import * as v from 'valibot'
|
||||
|
||||
export type AnyAll = 'anyOf' | 'allOf'
|
||||
|
||||
export const SchemaAnyAll = v.object({
|
||||
m: v.optional(v.picklist(['anyOf', 'allOf']), 'anyOf'),
|
||||
})
|
||||
|
||||
const SchemaIncludeExclude = v.object({ i: v.optional(v.picklist(['i', 'e'])) })
|
||||
|
||||
const SchemaSeriesStatus = v.object({
|
||||
...SchemaIncludeExclude.entries,
|
||||
v: v.optional(v.picklist(['ENDED', 'ONGOING', 'ABANDONED', 'HIATUS'])),
|
||||
})
|
||||
|
||||
export const SchemaFilterSeriesStatus = v.object({
|
||||
...SchemaAnyAll.entries,
|
||||
v: v.fallback(v.optional(v.array(SchemaSeriesStatus), []), []),
|
||||
})
|
||||
|
||||
export const FilterSeriesGenre = v.object({
|
||||
...SchemaAnyAll.entries,
|
||||
value: v.array(v.string()),
|
||||
})
|
||||
Loading…
Reference in a new issue