Tickets: ticketPath, Listenzustand in der URL (Reiter, Art, Dringend, Suche, limit), woid-Umleitung, Zeilenklick-Helfer
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f3b73ca1dd
commit
54fc44ed11
7 files changed
+249
-1
No files matched your search
@@ -0,0 +1,85 @@
|
||||
/* Zustand der Ticketliste in der Adresse: status (Reiter-Id), art (Id aus TYPE_FILTERS),
|
||||
dringend (1), q, limit - in dieser Reihenfolge, Standardwerte werden nicht geschrieben.
|
||||
Aus dem Zustand entstehen die Filter fuer Liste und Zaehler (beide muessen dieselben nutzen). */
|
||||
|
||||
import { STATUS_GROUPS, DEFAULT_STATUS_GROUPS, statusValuesFor, TYPE_FILTERS } from './ticketStatus'
|
||||
import { ticketPath } from './ticketRoutes'
|
||||
|
||||
// Reiter: "Aktiv" (alles Laufende), je eine Statusgruppe, zuletzt "Alle" (groups: null = kein Statusfilter)
|
||||
export const LIST_TABS = [
|
||||
{ id: 'aktiv', label: 'Aktiv', groups: DEFAULT_STATUS_GROUPS },
|
||||
...STATUS_GROUPS.map((group) => ({ id: group.id, label: group.label, groups: [group.id] })),
|
||||
{ id: 'alle', label: 'Alle', groups: null },
|
||||
]
|
||||
|
||||
export const LIST_DEFAULTS = { tab: 'aktiv', typeId: 'orders', urgentOnly: false, search: '', limit: 10 }
|
||||
|
||||
const MIN_LIMIT = 10
|
||||
const MAX_LIMIT = 500
|
||||
const LIMIT_STEP = 10
|
||||
// Hoch (3) und Kritisch (4) gelten als dringend (siehe ticketStatus.js)
|
||||
const URGENT_PRIORITIES = [3, 4]
|
||||
|
||||
export function clampLimit(value) {
|
||||
const n = Math.floor(Number(value))
|
||||
if (!Number.isFinite(n)) return MIN_LIMIT
|
||||
return Math.min(MAX_LIMIT, Math.max(MIN_LIMIT, n))
|
||||
}
|
||||
|
||||
// input: URLSearchParams oder String ("?status=done" und "status=done" gehen beide)
|
||||
export function parseListParams(input) {
|
||||
const params = new URLSearchParams(input)
|
||||
const tab = params.get('status')
|
||||
const typeId = params.get('art')
|
||||
const limit = params.get('limit')
|
||||
return {
|
||||
tab: LIST_TABS.some((t) => t.id === tab) ? tab : LIST_DEFAULTS.tab,
|
||||
typeId: TYPE_FILTERS.some((f) => f.id === typeId) ? typeId : LIST_DEFAULTS.typeId,
|
||||
urgentOnly: params.get('dringend') === '1',
|
||||
search: (params.get('q') || '').trim(),
|
||||
limit: limit !== null && /^\d+$/.test(limit) ? clampLimit(limit) : LIST_DEFAULTS.limit,
|
||||
}
|
||||
}
|
||||
|
||||
export function serializeListParams(state) {
|
||||
const params = new URLSearchParams()
|
||||
if (state.tab !== LIST_DEFAULTS.tab) params.set('status', state.tab)
|
||||
if (state.typeId !== LIST_DEFAULTS.typeId) params.set('art', state.typeId)
|
||||
if (state.urgentOnly) params.set('dringend', '1')
|
||||
if (state.search) params.set('q', state.search)
|
||||
const limit = clampLimit(state.limit)
|
||||
if (limit !== LIST_DEFAULTS.limit) params.set('limit', String(limit))
|
||||
return params
|
||||
}
|
||||
|
||||
// Jede Filteraenderung beginnt wieder bei der ersten Seite
|
||||
export function withFilter(state, patch) {
|
||||
return { ...state, ...patch, limit: LIST_DEFAULTS.limit }
|
||||
}
|
||||
|
||||
// "Mehr laden"
|
||||
export function nextLimit(state) {
|
||||
return clampLimit(Number(state.limit) + LIMIT_STEP)
|
||||
}
|
||||
|
||||
// Filter fuer den Zaehler eines Reiters: wie die Liste, aber ohne Suche und limit
|
||||
export function countFilters(state, tabId) {
|
||||
const tab = LIST_TABS.find((t) => t.id === tabId) || LIST_TABS[0]
|
||||
const type = TYPE_FILTERS.find((f) => f.id === state.typeId) || TYPE_FILTERS[0]
|
||||
return {
|
||||
status: tab.groups === null ? [] : statusValuesFor(tab.groups),
|
||||
type: [...(type.types || [])],
|
||||
excludeType: type.excludeType,
|
||||
priority: state.urgentOnly ? [...URGENT_PRIORITIES] : [],
|
||||
}
|
||||
}
|
||||
|
||||
export function listFilters(state) {
|
||||
return { ...countFilters(state, state.tab), search: state.search || undefined, limit: state.limit }
|
||||
}
|
||||
|
||||
// Altlinks "/tickets?woid=100131" fuehren zur Ticketseite und haben Vorrang vor allen Filtern
|
||||
export function woidRedirectTarget(input) {
|
||||
const woid = (new URLSearchParams(input).get('woid') || '').trim()
|
||||
return woid ? ticketPath(woid) : null
|
||||
}
|
||||
Reference in new issue
Block a user