@tensor_1/react 2.49.1 → 2.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/DataWorkspace.d.ts +216 -9
- package/dist/components/DataWorkspace.js +849 -93
- package/dist/components/FilterEditor.d.ts +3 -1
- package/dist/components/FilterEditor.js +22 -6
- package/dist/components/SearchBar.d.ts +3 -1
- package/dist/components/SearchBar.js +2 -0
- package/dist/components/Table.d.ts +10 -1
- package/dist/components/Table.js +12 -4
- package/dist/filter-model.d.ts +15 -1
- package/dist/filter-model.js +8 -2
- package/dist/index.cjs +911 -118
- package/dist/index.d.cts +263 -14
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -0
- package/dist/labels-context.d.ts +6 -1
- package/dist/table-engine.d.ts +14 -3
- package/dist/table-engine.js +7 -2
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { TextFilterOperator, NumberFilterOperator, DateFilterOperator, FilterField, FilterValue } from '../filter-model.js';
|
|
2
|
+
import { TextFilterOperator, NumberFilterOperator, DateFilterOperator, EnumFilterOperator, FilterField, FilterValue } from '../filter-model.js';
|
|
3
3
|
|
|
4
4
|
interface FilterEditorLabels {
|
|
5
5
|
apply: string;
|
|
@@ -35,6 +35,8 @@ interface FilterEditorLabels {
|
|
|
35
35
|
operators: Record<TextFilterOperator | NumberFilterOperator, string>;
|
|
36
36
|
/** `date` conditions (HAR-1832). Optional, like `presets`. */
|
|
37
37
|
dateOperators?: Partial<Record<DateFilterOperator, string>>;
|
|
38
|
+
/** `enum` conditions (HAR-2631), when the field offers both. Optional, like `presets`. */
|
|
39
|
+
enumOperators?: Partial<Record<EnumFilterOperator, string>>;
|
|
38
40
|
}
|
|
39
41
|
declare const DEFAULT_FILTER_EDITOR_LABELS: FilterEditorLabels;
|
|
40
42
|
interface FilterEditorProps {
|
|
@@ -12,7 +12,7 @@ import { cx } from "../cx.js";
|
|
|
12
12
|
import { useUixLabels } from "../labels-context.js";
|
|
13
13
|
import { useDelayedPending } from "../hooks/useDelayedPending.js";
|
|
14
14
|
import { foldForSearch } from "../search-suggest-model.js";
|
|
15
|
-
import { DATE_FILTER_OPERATORS, NUMBER_FILTER_OPERATORS, TEXT_FILTER_OPERATORS, emptyFilterValue, isUnresolvedChoice, matchFilterPreset, orderFilterRange } from "../filter-model.js";
|
|
15
|
+
import { DATE_FILTER_OPERATORS, ENUM_FILTER_OPERATORS, NUMBER_FILTER_OPERATORS, TEXT_FILTER_OPERATORS, emptyFilterValue, isUnresolvedChoice, matchFilterPreset, orderFilterRange } from "../filter-model.js";
|
|
16
16
|
const DEFAULT_FILTER_EDITOR_LABELS = {
|
|
17
17
|
apply: "Apply",
|
|
18
18
|
clear: "Clear",
|
|
@@ -38,6 +38,7 @@ const DEFAULT_FILTER_EDITOR_LABELS = {
|
|
|
38
38
|
addTagHint: "Enter or a comma adds it.",
|
|
39
39
|
date: "Date",
|
|
40
40
|
dateOperators: { on: "on", before: "before", after: "after", between: "between" },
|
|
41
|
+
enumOperators: { "is-any-of": "is any of", "is-none-of": "is none of" },
|
|
41
42
|
operators: {
|
|
42
43
|
contains: "contains",
|
|
43
44
|
"not-contains": "does not contain",
|
|
@@ -60,7 +61,8 @@ function FilterEditor({ field, value: valueProp, onValueChange, onApply, onClear
|
|
|
60
61
|
...provided,
|
|
61
62
|
...labelOverrides,
|
|
62
63
|
operators: { ...DEFAULT_FILTER_EDITOR_LABELS.operators, ...provided?.operators, ...labelOverrides?.operators },
|
|
63
|
-
dateOperators: { ...DEFAULT_FILTER_EDITOR_LABELS.dateOperators, ...provided?.dateOperators, ...labelOverrides?.dateOperators }
|
|
64
|
+
dateOperators: { ...DEFAULT_FILTER_EDITOR_LABELS.dateOperators, ...provided?.dateOperators, ...labelOverrides?.dateOperators },
|
|
65
|
+
enumOperators: { ...DEFAULT_FILTER_EDITOR_LABELS.enumOperators, ...provided?.enumOperators, ...labelOverrides?.enumOperators }
|
|
64
66
|
};
|
|
65
67
|
const id = useId();
|
|
66
68
|
let value = valueProp?.kind === field.kind ? valueProp : emptyFilterValue(field.kind);
|
|
@@ -163,16 +165,30 @@ function EnumBody({ field, value, onChange, labels, threshold }) {
|
|
|
163
165
|
return q ? options.filter((o) => foldForSearch(o.label).text.includes(q)) : options;
|
|
164
166
|
}, [options, query]);
|
|
165
167
|
const selected = new Set(value.values);
|
|
166
|
-
const
|
|
168
|
+
const ops = (field.enumOperators ?? []).filter((op) => ENUM_FILTER_OPERATORS.includes(op));
|
|
169
|
+
const condition = value.operator ?? (ops.length === 1 ? ops[0] : void 0);
|
|
170
|
+
const withValues = (values) => condition && condition !== "is-any-of" ? { kind: "enum", values, operator: condition } : { kind: "enum", values };
|
|
171
|
+
const toggle = (v, on) => onChange(withValues(on ? [...value.values, v] : value.values.filter((x) => x !== v)));
|
|
167
172
|
const presets = field.presets ?? [];
|
|
168
173
|
const active = matchFilterPreset(field, value);
|
|
174
|
+
const words = labels.enumOperators ?? {};
|
|
169
175
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
170
|
-
|
|
176
|
+
ops.length > 1 && /* @__PURE__ */ jsx("div", { className: "uix-filter-editor__row", children: /* @__PURE__ */ jsx(
|
|
177
|
+
Select,
|
|
178
|
+
{
|
|
179
|
+
size: "sm",
|
|
180
|
+
"aria-label": labels.operator,
|
|
181
|
+
value: value.operator ?? "is-any-of",
|
|
182
|
+
options: ops.map((op) => ({ value: op, label: words[op] ?? DEFAULT_FILTER_EDITOR_LABELS.enumOperators[op] })),
|
|
183
|
+
onValueChange: (op) => onChange(op === "is-none-of" ? { kind: "enum", values: value.values, operator: "is-none-of" } : { kind: "enum", values: value.values })
|
|
184
|
+
}
|
|
185
|
+
) }),
|
|
186
|
+
presets.length > 0 && /* @__PURE__ */ jsx("div", { className: "uix-chip-group uix-filter-editor__presets", role: "group", "aria-label": labels.presets ?? DEFAULT_FILTER_EDITOR_LABELS.presets, children: presets.map((p) => /* @__PURE__ */ jsx(Chip, { pressed: p === active, onPressedChange: () => onChange(withValues([...p.values])), children: p.label }, p.id)) }),
|
|
171
187
|
options.length > threshold && /* @__PURE__ */ jsx(Input, { type: "search", size: "sm", "aria-label": labels.search, placeholder: labels.search, value: query, onChange: (e) => setQuery(e.currentTarget.value), autoFocus: true }),
|
|
172
188
|
/* @__PURE__ */ jsxs("div", { className: "uix-filter-editor__bulk", children: [
|
|
173
189
|
/* @__PURE__ */ jsx("span", { className: "uix-filter-editor__count", "aria-live": "polite", children: fillLabel(labels.selected, { count: value.values.length }) }),
|
|
174
|
-
/* @__PURE__ */ jsx(Button, { type: "button", variant: "link", size: "sm", onClick: () => onChange(
|
|
175
|
-
/* @__PURE__ */ jsx(Button, { type: "button", variant: "link", size: "sm", onClick: () => onChange(
|
|
190
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "link", size: "sm", onClick: () => onChange(withValues([.../* @__PURE__ */ new Set([...value.values, ...shown.map((o) => o.value)])])), children: labels.selectAll }),
|
|
191
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "link", size: "sm", onClick: () => onChange(withValues([])), children: labels.selectNone })
|
|
176
192
|
] }),
|
|
177
193
|
/* @__PURE__ */ jsx("div", { className: "uix-filter-editor__list", children: shown.length === 0 ? /* @__PURE__ */ jsx("p", { className: "uix-filter-editor__note", children: labels.noMatches }) : shown.map((o) => /* @__PURE__ */ jsx(Checkbox, { label: o.label, checked: selected.has(o.value), onChange: (e) => toggle(o.value, e.currentTarget.checked) }, o.value)) })
|
|
178
194
|
] });
|
|
@@ -46,6 +46,8 @@ interface SearchBarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSubmit'
|
|
|
46
46
|
labels?: Partial<SearchBarLabels>;
|
|
47
47
|
/** The field's `name`. */
|
|
48
48
|
name?: string;
|
|
49
|
+
/** The longest text the field takes (HAR-2622). */
|
|
50
|
+
maxLength?: number;
|
|
49
51
|
/** The field's `id`, e.g. for a "/" shortcut that focuses it. Default: generated. */
|
|
50
52
|
inputId?: string;
|
|
51
53
|
inputRef?: Ref<HTMLInputElement>;
|
|
@@ -63,6 +65,6 @@ interface SearchBarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSubmit'
|
|
|
63
65
|
* takes Escape itself before the field (a ConfirmPopover, the table's view menu), Escape closes
|
|
64
66
|
* the overlay rather than clearing the text.
|
|
65
67
|
*/
|
|
66
|
-
declare function SearchBar({ label, value: valueProp, defaultValue, onValueChange, onSubmit, onClear, placeholder, size, submitButton, submitVariant, landmark, inputDescribedBy, labels: labelsProp, name, inputId, inputRef, autoFocus, disabled, className, ...props }: SearchBarProps): react.JSX.Element;
|
|
68
|
+
declare function SearchBar({ label, value: valueProp, defaultValue, onValueChange, onSubmit, onClear, placeholder, size, submitButton, submitVariant, landmark, inputDescribedBy, labels: labelsProp, name, maxLength, inputId, inputRef, autoFocus, disabled, className, ...props }: SearchBarProps): react.JSX.Element;
|
|
67
69
|
|
|
68
70
|
export { SearchBar, type SearchBarLabels, type SearchBarProps };
|
|
@@ -25,6 +25,7 @@ function SearchBar({
|
|
|
25
25
|
inputDescribedBy,
|
|
26
26
|
labels: labelsProp,
|
|
27
27
|
name,
|
|
28
|
+
maxLength,
|
|
28
29
|
inputId,
|
|
29
30
|
inputRef,
|
|
30
31
|
autoFocus,
|
|
@@ -83,6 +84,7 @@ function SearchBar({
|
|
|
83
84
|
id: fieldId,
|
|
84
85
|
type: "search",
|
|
85
86
|
name,
|
|
87
|
+
maxLength,
|
|
86
88
|
className: "uix-input",
|
|
87
89
|
value,
|
|
88
90
|
placeholder,
|
|
@@ -20,6 +20,10 @@ declare const TableWrap: react.ForwardRefExoticComponent<TableWrapProps & react.
|
|
|
20
20
|
type TableDensity = 'compact' | 'standard' | 'comfortable';
|
|
21
21
|
type SortDirection = 'ascending' | 'descending' | 'none';
|
|
22
22
|
interface TableProps extends TableHTMLAttributes<HTMLTableElement> {
|
|
23
|
+
/**
|
|
24
|
+
* The row height. Named, the table holds it, `standard` included, whatever the page sets
|
|
25
|
+
* `--uix-row-h` to (a density preference); left out, the table follows `--uix-row-h`.
|
|
26
|
+
*/
|
|
23
27
|
density?: TableDensity;
|
|
24
28
|
zebra?: boolean;
|
|
25
29
|
pinnedCol?: boolean;
|
|
@@ -40,9 +44,14 @@ interface ThProps extends ThHTMLAttributes<HTMLTableCellElement> {
|
|
|
40
44
|
sortDirection?: SortDirection;
|
|
41
45
|
/** 1-based ordinal shown when this column is a secondary key in a multi-sort */
|
|
42
46
|
sortOrder?: number;
|
|
47
|
+
/**
|
|
48
|
+
* The ordinal in words for assistive tech, e.g. "Sort priority 2" (2.50, HAR-2623). The visible
|
|
49
|
+
* ordinal is CSS content with empty alt text, so without this it is not announced at all.
|
|
50
|
+
*/
|
|
51
|
+
sortOrderLabel?: string;
|
|
43
52
|
onSort?: () => void;
|
|
44
53
|
}
|
|
45
|
-
declare function Th({ sortable, sortDirection, sortOrder, onSort, className, children, onClick, ...props }: ThProps): react.JSX.Element;
|
|
54
|
+
declare function Th({ sortable, sortDirection, sortOrder, sortOrderLabel, onSort, className, children, onClick, ...props }: ThProps): react.JSX.Element;
|
|
46
55
|
interface TdProps extends TdHTMLAttributes<HTMLTableCellElement> {
|
|
47
56
|
pinned?: boolean;
|
|
48
57
|
}
|
package/dist/components/Table.js
CHANGED
|
@@ -13,7 +13,7 @@ const TableWrap = forwardRef(function TableWrap2({ announcement, refreshing, chi
|
|
|
13
13
|
] });
|
|
14
14
|
});
|
|
15
15
|
function Table({
|
|
16
|
-
density
|
|
16
|
+
density,
|
|
17
17
|
zebra = true,
|
|
18
18
|
pinnedCol,
|
|
19
19
|
pinnedActions,
|
|
@@ -35,7 +35,7 @@ function Table({
|
|
|
35
35
|
fixed && "uix-table--fixed",
|
|
36
36
|
className
|
|
37
37
|
),
|
|
38
|
-
"data-density": density
|
|
38
|
+
"data-density": density,
|
|
39
39
|
"data-uix-rowpeek": rowPeek || void 0,
|
|
40
40
|
"data-uix-table-v2": v2 || void 0,
|
|
41
41
|
...props,
|
|
@@ -43,17 +43,25 @@ function Table({
|
|
|
43
43
|
}
|
|
44
44
|
);
|
|
45
45
|
}
|
|
46
|
-
function Th({ sortable, sortDirection, sortOrder, onSort, className, children, onClick, ...props }) {
|
|
46
|
+
function Th({ sortable, sortDirection, sortOrder, sortOrderLabel, onSort, className, children, onClick, ...props }) {
|
|
47
|
+
const ordinal = sortOrder != null && sortOrder > 0 && sortOrderLabel ? /* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", children: `, ${sortOrderLabel}` }) : null;
|
|
47
48
|
return /* @__PURE__ */ jsx(
|
|
48
49
|
"th",
|
|
49
50
|
{
|
|
50
51
|
className,
|
|
51
52
|
"data-sort": sortable || void 0,
|
|
52
53
|
"data-sort-order": sortOrder != null && sortOrder > 0 ? sortOrder : void 0,
|
|
54
|
+
"data-sort-labelled": ordinal != null || void 0,
|
|
53
55
|
"aria-sort": sortDirection && sortDirection !== "none" ? sortDirection : void 0,
|
|
54
56
|
onClick: sortable && onSort ? void 0 : onClick,
|
|
55
57
|
...props,
|
|
56
|
-
children: sortable ? /* @__PURE__ */
|
|
58
|
+
children: sortable ? /* @__PURE__ */ jsxs("button", { type: "button", className: "uix-th__sortbtn", onClick: onSort, children: [
|
|
59
|
+
children,
|
|
60
|
+
ordinal
|
|
61
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
62
|
+
children,
|
|
63
|
+
ordinal
|
|
64
|
+
] })
|
|
57
65
|
}
|
|
58
66
|
);
|
|
59
67
|
}
|
package/dist/filter-model.d.ts
CHANGED
|
@@ -15,9 +15,15 @@ type NumberFilterOperator = 'eq' | 'neq' | 'lt' | 'lte' | 'gt' | 'gte' | 'betwee
|
|
|
15
15
|
* `dateFilterBounds` turns each into the half-open range a query needs.
|
|
16
16
|
*/
|
|
17
17
|
type DateFilterOperator = 'on' | 'before' | 'after' | 'between';
|
|
18
|
+
/**
|
|
19
|
+
* An `enum` condition (HAR-2631): the row's value is one of the chosen values, or none of them
|
|
20
|
+
* ("status is none of Withdrawn, Lost"). Absent means `is-any-of`.
|
|
21
|
+
*/
|
|
22
|
+
type EnumFilterOperator = 'is-any-of' | 'is-none-of';
|
|
18
23
|
type FilterValue = {
|
|
19
24
|
kind: 'enum';
|
|
20
25
|
values: string[];
|
|
26
|
+
operator?: EnumFilterOperator;
|
|
21
27
|
} | {
|
|
22
28
|
kind: 'text';
|
|
23
29
|
operator: TextFilterOperator;
|
|
@@ -79,6 +85,11 @@ interface FilterField {
|
|
|
79
85
|
operators?: readonly (TextFilterOperator | NumberFilterOperator)[];
|
|
80
86
|
/** `date`: the conditions offered, in order. Default: on, before, after, between. */
|
|
81
87
|
dateOperators?: readonly DateFilterOperator[];
|
|
88
|
+
/**
|
|
89
|
+
* `enum`: the conditions offered, in order (HAR-2631). Default: `is-any-of` alone, so the editor
|
|
90
|
+
* shows no condition control; with both, it shows one above the options.
|
|
91
|
+
*/
|
|
92
|
+
enumOperators?: readonly EnumFilterOperator[];
|
|
82
93
|
/** `number`: a unit shown after the value, e.g. "days". */
|
|
83
94
|
unit?: string;
|
|
84
95
|
/** `boolean`: words for true and false, e.g. Escalated / Not escalated. Default from labels. */
|
|
@@ -105,6 +116,8 @@ interface FilterSummaryLabels {
|
|
|
105
116
|
more: string;
|
|
106
117
|
/** An `enum` value equal to a preset: `{label}` (the preset), `{field}`. Default `{label}`. */
|
|
107
118
|
preset?: string;
|
|
119
|
+
/** An `enum` value that excludes (`is-none-of`, HAR-2631): `{values}`. Default "not {values}" ("Status: not Open, Closed"). */
|
|
120
|
+
noneOf?: string;
|
|
108
121
|
/** `date` conditions (HAR-1832), `{date}`. Default "{date}", "before {date}", "after {date}". */
|
|
109
122
|
on?: string;
|
|
110
123
|
before?: string;
|
|
@@ -114,6 +127,7 @@ declare const DEFAULT_FILTER_SUMMARY_LABELS: FilterSummaryLabels;
|
|
|
114
127
|
declare const TEXT_FILTER_OPERATORS: readonly TextFilterOperator[];
|
|
115
128
|
declare const NUMBER_FILTER_OPERATORS: readonly NumberFilterOperator[];
|
|
116
129
|
declare const DATE_FILTER_OPERATORS: readonly DateFilterOperator[];
|
|
130
|
+
declare const ENUM_FILTER_OPERATORS: readonly EnumFilterOperator[];
|
|
117
131
|
/** The empty value for a field kind (what Clear resets to). */
|
|
118
132
|
declare function emptyFilterValue(kind: FilterValueKind): FilterValue;
|
|
119
133
|
/** True when the value filters nothing (so the chip goes away). */
|
|
@@ -165,4 +179,4 @@ interface SummarizeFilterOptions {
|
|
|
165
179
|
*/
|
|
166
180
|
declare function summarizeFilter(field: FilterField, input: FilterValue | undefined, options?: SummarizeFilterOptions): string;
|
|
167
181
|
|
|
168
|
-
export { DATE_FILTER_OPERATORS, DEFAULT_FILTER_SUMMARY_LABELS, type DateFilterOperator, type FilterChoice, type FilterField, type FilterPreset, type FilterSummaryLabels, type FilterValue, type FilterValueKind, NUMBER_FILTER_OPERATORS, type NumberFilterOperator, type SummarizeFilterOptions, TEXT_FILTER_OPERATORS, type TextFilterOperator, dateFilterBounds, emptyFilterValue, isFilterEmpty, isUnresolvedChoice, matchFilterPreset, orderFilterRange, resolveFilterLabels, summarizeFilter };
|
|
182
|
+
export { DATE_FILTER_OPERATORS, DEFAULT_FILTER_SUMMARY_LABELS, type DateFilterOperator, ENUM_FILTER_OPERATORS, type EnumFilterOperator, type FilterChoice, type FilterField, type FilterPreset, type FilterSummaryLabels, type FilterValue, type FilterValueKind, NUMBER_FILTER_OPERATORS, type NumberFilterOperator, type SummarizeFilterOptions, TEXT_FILTER_OPERATORS, type TextFilterOperator, dateFilterBounds, emptyFilterValue, isFilterEmpty, isUnresolvedChoice, matchFilterPreset, orderFilterRange, resolveFilterLabels, summarizeFilter };
|
package/dist/filter-model.js
CHANGED
|
@@ -20,6 +20,7 @@ const DEFAULT_FILTER_SUMMARY_LABELS = {
|
|
|
20
20
|
until: "until {to}",
|
|
21
21
|
more: "{first} +{count}",
|
|
22
22
|
preset: "{label}",
|
|
23
|
+
noneOf: "not {values}",
|
|
23
24
|
on: "{date}",
|
|
24
25
|
before: "before {date}",
|
|
25
26
|
after: "after {date}"
|
|
@@ -27,6 +28,7 @@ const DEFAULT_FILTER_SUMMARY_LABELS = {
|
|
|
27
28
|
const TEXT_FILTER_OPERATORS = ["contains", "not-contains", "is", "is-not", "starts-with"];
|
|
28
29
|
const NUMBER_FILTER_OPERATORS = ["eq", "neq", "lt", "lte", "gt", "gte", "between"];
|
|
29
30
|
const DATE_FILTER_OPERATORS = ["on", "before", "after", "between"];
|
|
31
|
+
const ENUM_FILTER_OPERATORS = ["is-any-of", "is-none-of"];
|
|
30
32
|
function emptyFilterValue(kind) {
|
|
31
33
|
switch (kind) {
|
|
32
34
|
case "enum":
|
|
@@ -108,7 +110,7 @@ async function resolveFilterLabels(field, value) {
|
|
|
108
110
|
return { kind: "reference", values: value.values.map((v) => resolved.has(v.value) ? { value: v.value, label: resolved.get(v.value) } : v) };
|
|
109
111
|
}
|
|
110
112
|
function matchFilterPreset(field, value) {
|
|
111
|
-
if (value?.kind !== "enum" || !field.presets?.length) return void 0;
|
|
113
|
+
if (value?.kind !== "enum" || value.operator === "is-none-of" || !field.presets?.length) return void 0;
|
|
112
114
|
const chosen = new Set(value.values);
|
|
113
115
|
return field.presets.find((preset) => {
|
|
114
116
|
const wanted = new Set(preset.values);
|
|
@@ -131,7 +133,10 @@ function summarizeFilter(field, input, options = {}) {
|
|
|
131
133
|
const preset = matchFilterPreset(field, value);
|
|
132
134
|
if (preset) return fill(labels.preset ?? DEFAULT_FILTER_SUMMARY_LABELS.preset, { label: preset.label, field: field.label });
|
|
133
135
|
const byValue = new Map((field.options ?? []).map((o) => [o.value, o.label]));
|
|
134
|
-
|
|
136
|
+
const named = list(value.values.map((v) => byValue.get(v) ?? v));
|
|
137
|
+
const condition = value.operator ?? (field.enumOperators?.length === 1 ? field.enumOperators[0] : "is-any-of");
|
|
138
|
+
if (condition === "is-none-of") return `${field.label}: ${fill(labels.noneOf ?? DEFAULT_FILTER_SUMMARY_LABELS.noneOf, { values: named, field: field.label })}`;
|
|
139
|
+
return `${field.label}: ${named}`;
|
|
135
140
|
}
|
|
136
141
|
case "reference":
|
|
137
142
|
return `${field.label}: ${list(value.values.map((v) => v.label))}`;
|
|
@@ -155,6 +160,7 @@ function summarizeFilter(field, input, options = {}) {
|
|
|
155
160
|
export {
|
|
156
161
|
DATE_FILTER_OPERATORS,
|
|
157
162
|
DEFAULT_FILTER_SUMMARY_LABELS,
|
|
163
|
+
ENUM_FILTER_OPERATORS,
|
|
158
164
|
NUMBER_FILTER_OPERATORS,
|
|
159
165
|
TEXT_FILTER_OPERATORS,
|
|
160
166
|
dateFilterBounds,
|