import { Select } from "@digdir/designsystemet-react"; import { XMarkIcon } from "@navikt/aksel-icons"; import { changeOperator, createExpression, type FieldMetadata, type FilterExpression, type FilterOperator, getLocalizedString, getOperatorLabel, getOperatorsForField, normalizeOperator, } from "@olenbetong/appframe-core"; import { Combobox } from "@olenbetong/appframe-ds"; import { FilterValueEditor } from "./FilterValueEditor.js"; import type { FilterEditorSize, GetFieldOptions } from "./types.js"; export function getFieldLabel(field: FieldMetadata) { return field.caption || field.name; } export type FilterRowProps = { expression: FilterExpression; fields: FieldMetadata[]; onChange: (expression: FilterExpression) => void; onRemove: () => void; getFieldOptions?: GetFieldOptions; readOnly?: boolean; "data-size"?: FilterEditorSize; }; /** A single `field operator value` row. */ export function FilterRow({ expression, fields, onChange, onRemove, getFieldOptions, readOnly, "data-size": size = "sm", }: FilterRowProps) { let field = fields.find((item) => item.name === expression.column); let operator = normalizeOperator(expression.operator); // A filter can reference a field that is no longer in the view. Keep the row // editable by falling back to a string field rather than dropping it. let effectiveField: FieldMetadata = field ?? { name: expression.column, type: "string" }; let operators = getOperatorsForField(effectiveField); if (!operators.includes(operator)) { operators = [...operators, operator]; } function handleFieldChange(next: FieldMetadata | null) { if (!next) return; // Keep the operator when the new field supports it, so switching between // two fields of the same type does not reset the row. let operators = getOperatorsForField(next); let keep = operators.includes(operator) ? operator : undefined; let created = createExpression(next, keep); onChange(keep ? { ...created, value: expression.value, valueType: expression.valueType } : created); } return (
option.name} isOptionEqualToValue={(a, b) => a.name === b.name} value={effectiveField} onChange={(_event, next) => handleFieldChange(next)} /> {!readOnly && ( )}
); }