Prüfung / Lint, Typen, Tests (push) Canceled after 0s
Prüfung / Images bauen (pdf) (push) Canceled after 0s
Prüfung / Images bauen (web) (push) Canceled after 0s
Prüfung / Images bauen (worker) (push) Canceled after 0s
Images / bauen (pdf, docker/pdf.Dockerfile) (push) Canceled after 0s
Images / bauen (web, docker/web.Dockerfile) (push) Canceled after 0s
Images / bauen (worker, docker/worker.Dockerfile) (push) Canceled after 0s
375 Vorkommen in 210 Dateien. Betrifft Kommentare, Oberflaechentexte und die README; an keiner Stelle Bedeutung, nur Zeichensetzung.
72 lines
2.5 KiB
TypeScript
72 lines
2.5 KiB
TypeScript
/**
|
|
* Die Filter einer Suche, als Adressparameter und als Objekt.
|
|
*
|
|
* Ohne Abhängigkeiten: die Suchseite baut damit ihre Adresse, und gespeicherte
|
|
* Ansichten sind nichts anderes als eine solche Adresse. Dass beides dieselbe
|
|
* Darstellung benutzt, ist der Punkt - eine Ansicht ist ein Lesezeichen.
|
|
*/
|
|
|
|
/** Die Arten, über die einzeln gesucht werden kann. */
|
|
export const SEARCH_KINDS = ['case', 'document', 'personnel'] as const
|
|
export type SearchKind = (typeof SEARCH_KINDS)[number]
|
|
|
|
/**
|
|
* Was in der Adresse stehen kann. `all` ist der Auslieferungszustand: wer
|
|
* einen Namen eintippt, will wissen, wo er überhaupt vorkommt, und nicht
|
|
* zuerst entscheiden, wonach er sucht. Die einzelnen Arten bleiben als Filter.
|
|
*/
|
|
export const SEARCH_SCOPES = ['all', ...SEARCH_KINDS] as const
|
|
export type SearchScope = (typeof SEARCH_SCOPES)[number]
|
|
|
|
export type SearchFilters = {
|
|
q: string
|
|
kind: SearchScope
|
|
status?: string
|
|
templateKey?: string
|
|
classification?: number
|
|
/** Nur Akten, an denen der Suchende beteiligt ist. */
|
|
mine?: boolean
|
|
/** Wiedervorlage bis einschliesslich diesem Tag. */
|
|
dueBefore?: string
|
|
/** Seit diesem Zeitpunkt geändert, ISO. */
|
|
changedSince?: string
|
|
/** Seit diesem Zeitpunkt **nicht** geändert, ISO. */
|
|
idleSince?: string
|
|
cursor?: string
|
|
}
|
|
|
|
export function parseFilters(params: URLSearchParams | Record<string, string | undefined>): SearchFilters {
|
|
const get = (name: string): string | undefined => {
|
|
const wert = params instanceof URLSearchParams ? params.get(name) : params[name]
|
|
return wert && wert.length > 0 ? wert : undefined
|
|
}
|
|
|
|
const kind = get('kind')
|
|
const stufe = get('classification')
|
|
|
|
return {
|
|
q: (get('q') ?? '').slice(0, 200),
|
|
kind: (SEARCH_SCOPES as readonly string[]).includes(kind ?? '')
|
|
? (kind as SearchScope)
|
|
: 'all',
|
|
status: get('status'),
|
|
templateKey: get('templateKey'),
|
|
classification: stufe !== undefined && /^[0-5]$/.test(stufe) ? Number(stufe) : undefined,
|
|
mine: get('mine') === '1',
|
|
dueBefore: get('dueBefore'),
|
|
changedSince: get('changedSince'),
|
|
idleSince: get('idleSince'),
|
|
cursor: get('cursor'),
|
|
}
|
|
}
|
|
|
|
/** Zurück in eine Adresse. Leere Filter fallen weg, damit sie kurz bleibt. */
|
|
export function toSearchParams(filters: Partial<SearchFilters>): string {
|
|
const params = new URLSearchParams()
|
|
for (const [name, wert] of Object.entries(filters)) {
|
|
if (wert === undefined || wert === '' || wert === false) continue
|
|
params.set(name, wert === true ? '1' : String(wert))
|
|
}
|
|
return params.toString()
|
|
}
|