import { useEffect, useState } from 'react' import DateTimeField from '@/components/common/DateTimeField' import { Button } from '@/components/ui/button' import { countsEventTypes, countsFieldLabel, countsFilterFields, useCountsDefinition } from '@/lib/countsDefinitions' import useDialogue from '@/lib/dialogues/useDialogue' import { inputClass } from '@/lib/utils' import { useUITranslation } from '@/lib/useUITranslation' import { readCountState, encodeCountState } from '@/lib/queryState' import type { DialogueFormControls } from '@/lib/dialogues/useDialogue' import type { CountsCondition, CountsDefinition } from '@/lib/countsDefinitions' const ConditionEditor = ( { definition, initial, controls, save }: { definition: CountsDefinition; initial?: CountsCondition controls: DialogueFormControls save: (condition: CountsCondition) => void }, ) => { const { label, message } = useUITranslation ('counts') const fields = definition.filterFields ?? definition.fields const fieldName = (key: string) => (fields.find (item => item.key === key)?.labels ?? [countsFieldLabel (key)]).map (key => message (key).text).join (' › ') const [condition, setCondition] = useState (() => { const next = { ...initial, field: initial?.field ?? 'resource_id', operator: initial?.operator ?? 'eq' } if (next.operator !== 'range') delete next.end return next }) const { field, operator } = condition const operators = fields.find (item => item.key === field)?.operators ?? [] useEffect (() => { controls.setActions ([{ label: label (initial == null ? 'add' : 'shared:actions.edit'), onSelect: () => save (condition) }]) }, [controls, condition, initial, label, save]) return
} const CountsAdditionalConditions = ({ params, update }: { params: URLSearchParams update: (key: string, value: string) => void }, ) => { const { label, message } = useUITranslation ('counts') const definition = useCountsDefinition () const dialogue = useDialogue () const conditions = readCountState (params, 'conditions', []) const metadata = definition.filterFields ?? definition.fields const fields = metadata.filter (field => field.operators.length > 0) const fieldName = (key: string) => (metadata.find (item => item.key === key)?.labels ?? [countsFieldLabel (key)]).map (key => message (key).text).join (' › ') const write = (next: CountsCondition[]) => update ( 'conditions', encodeCountState ('conditions', next)) const replace = (index: number, condition: CountsCondition) => write ( conditions.map ((item, position) => position === index ? condition : item)) const patch = (index: number, change: Partial) => replace (index, { ...conditions[index], ...change }) const edit = (index?: number) => { const initial = index == null ? undefined : conditions[index] const save = (condition: CountsCondition) => { if (index == null) write ([...conditions, condition]) else replace (index, condition) } void dialogue.form ({ title: label ('additionalConditions'), footerLayout: 'inline', body: controls => }) } const valueInput = (condition: CountsCondition, index: number, key: 'value' | 'end') => { const type = countsFilterFields (definition)[condition.field] const aria = message (key === 'end' ? 'through' : (condition.operator === 'range' ? 'from' : 'value')) if (type === 'boolean' || condition.field === 'event_type') { const options: string[] = type === 'boolean' ? ['true', 'false'] : [...countsEventTypes] const namespace = type === 'boolean' ? 'truthValues' : 'events' return } if (type === 'datetime') return patch (index, { [key]: value ?? '' })}/> return patch (index, { [key]: event.target.value })}/> } return
{label ('additionalConditions')} {conditions.map ((condition, index) => (
{valueInput (condition, index, 'value')} {condition.operator === 'range' && <> {valueInput (condition, index, 'end')} }
))}
} export default CountsAdditionalConditions