@yuuvis/client-framework 3.7.1 → 3.8.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.
@@ -0,0 +1,543 @@
1
+ import * as _yuuvis_client_core from '@yuuvis/client-core';
2
+ import { GenericObjectType, ObjectTypeField } from '@yuuvis/client-core';
3
+ import * as _yuuvis_client_framework_smart_search from '@yuuvis/client-framework/smart-search';
4
+ import * as _angular_core from '@angular/core';
5
+ import { FormControl } from '@angular/forms';
6
+ import { MatAutocomplete, MatAutocompleteTrigger, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
7
+ import { RendererDirectiveInput } from '@yuuvis/client-framework/renderer';
8
+
9
+ /**
10
+ * A single committed `field operator value` condition (e.g. `name LIKE 'foo'`).
11
+ * The `*Label` fields are display strings for the chip; `fieldId`, `operator` and
12
+ * `value` are what actually drive the CMIS clause. `value` is a `string[]` for
13
+ * multi-value operators (which render as `IN (...)`), a string otherwise.
14
+ */
15
+ interface FieldCondition {
16
+ /** The queryable property id (or bare column id inside a table). */
17
+ fieldId: string;
18
+ /** The field's internal form-element type (e.g. `string`, `datetime`, `string:catalog`). */
19
+ internalType: string;
20
+ /** Localized field label shown on the chip. */
21
+ fieldLabel: string;
22
+ /** Operator id (e.g. `eq`, `like`, `gt`, `empty`, `date:today`). */
23
+ operator: string;
24
+ /** Display label for the operator (symbol or translated text). */
25
+ operatorLabel: string;
26
+ /** The comparison value; an array for multi-value `IN`-style conditions. */
27
+ value: string | string[];
28
+ /** Full human-readable label for the chip (`"Name like foo"`). */
29
+ conditionLabel: string;
30
+ }
31
+ /**
32
+ * A parenthesized sub-expression with its own AND/OR combinator. Groups can
33
+ * hold conditions and further groups recursively, allowing deeply nested
34
+ * boolean expressions.
35
+ */
36
+ interface ConditionGroup {
37
+ kind: 'group';
38
+ conditions: ConditionNode[];
39
+ combinator: Combinator;
40
+ }
41
+ /**
42
+ * A condition on a queryable `table`-type property. A table has no operator of its own;
43
+ * instead it holds column conditions directly — `FieldCondition`s targeting the table's
44
+ * columns, joined by `combinator` and matched against any row. Maps to
45
+ * `tableField[*].(col op val AND/OR …)` in CMIS (`[*]` = any row).
46
+ */
47
+ interface TableCondition {
48
+ kind: 'table';
49
+ /** The table property id. */
50
+ fieldId: string;
51
+ fieldLabel: string;
52
+ /** Column conditions (`FieldCondition`s targeting the table's columns). */
53
+ conditions: ConditionNode[];
54
+ /** How the column conditions combine (AND/OR). */
55
+ combinator: Combinator;
56
+ }
57
+ /** A child of a `SearchBlock` or `ConditionGroup`. */
58
+ type ConditionNode = FieldCondition | ConditionGroup | TableCondition;
59
+ declare function isConditionGroup(node: ConditionNode | SearchBlock): node is ConditionGroup;
60
+ declare function isTableCondition(node: ConditionNode | SearchBlock): node is TableCondition;
61
+ declare function isFieldCondition(node: ConditionNode): node is FieldCondition;
62
+ /** One target object type within a (potentially multi-type) search block. */
63
+ interface SearchBlockType {
64
+ id: string;
65
+ label: string;
66
+ isSot?: boolean;
67
+ }
68
+ interface SearchBlock {
69
+ /** Stable key for `@for` tracking — generated, not derived from a type id. */
70
+ id: string;
71
+ /** The object types this block targets. Conditions apply to their shared fields. */
72
+ types: SearchBlockType[];
73
+ conditions: ConditionNode[];
74
+ conditionCombinator: Combinator;
75
+ }
76
+ /**
77
+ * A container whose `conditions` can be mutated by the edit flow. A `TableCondition` is a
78
+ * container too: its children are row-groups; each row-group's children are column conditions.
79
+ */
80
+ type ConditionContainer = SearchBlock | ConditionGroup | TableCondition;
81
+ /**
82
+ * Where a full-text search looks. Maps to the column-qualified CONTAINS forms:
83
+ * `all` → `CONTAINS('q')` (metadata + content), `content` → `system:content CONTAINS('q')`,
84
+ * `metadata` → `system:metadata CONTAINS('q')`.
85
+ */
86
+ type FulltextScope = 'all' | 'content' | 'metadata';
87
+ /**
88
+ * The whole-object full-text search unit. Independent of the condition blocks: it carries its own
89
+ * target types and renders a single `CONTAINS` predicate.
90
+ */
91
+ interface FulltextSearch {
92
+ term: string;
93
+ scope: FulltextScope;
94
+ types: SearchBlockType[];
95
+ }
96
+ type Combinator = 'AND' | 'OR';
97
+ type BuildStep = 'type' | 'field' | 'operator' | 'value';
98
+ interface SuggestionItem {
99
+ kind: 'type' | 'field' | 'operator' | 'date-preset';
100
+ id: string;
101
+ label: string;
102
+ internalType?: string;
103
+ /** Set when a field has been paired with an operator while building a condition. */
104
+ operator?: string;
105
+ }
106
+ /**
107
+ * Serializable snapshot of a SmartSearch query.
108
+ *
109
+ * Capture via {@link SmartSearchComponent.getState} and restore via
110
+ * {@link SmartSearchComponent.loadState}. Safe for `JSON.stringify` /
111
+ * `JSON.parse` roundtrips (plain data, no class instances or signals).
112
+ */
113
+ interface SmartSearchState {
114
+ blocks: SearchBlock[];
115
+ combinator: Combinator;
116
+ /** Optional so states saved before full-text support remain loadable. */
117
+ fulltext?: FulltextSearch;
118
+ }
119
+
120
+ /**
121
+ * State + mutators for SmartSearch, shared between the host component and the
122
+ * recursive `SmartSearchGroupComponent`. Provided at the host component level
123
+ * so each `<yuv-smart-search>` instance gets its own controller.
124
+ *
125
+ * UI concerns (focus management, autocomplete plumbing, blur suppression) stay
126
+ * in the host component; this controller is purely about data.
127
+ */
128
+ declare class SmartSearchEditController {
129
+ #private;
130
+ /** The set of object type IDs that can be used as search blocks. */
131
+ allowedTypes: _angular_core.WritableSignal<string[]>;
132
+ /** ObjectTypeField IDs to exclude from the field-step autocomplete suggestions. */
133
+ skipProperties: _angular_core.WritableSignal<string[]>;
134
+ fieldCtrl: FormControl<string | null>;
135
+ operatorCtrl: FormControl<string | null>;
136
+ valueCtrl: FormControl<unknown>;
137
+ /** Current input step */
138
+ step: _angular_core.WritableSignal<BuildStep>;
139
+ /** The owning top-level block (drives field suggestions for the active edit) */
140
+ activeBlock: _angular_core.WritableSignal<SearchBlock | null>;
141
+ /** The immediate parent container the new condition will land in */
142
+ activeContainer: _angular_core.WritableSignal<ConditionContainer | null>;
143
+ /** Field selected waiting for operator/value */
144
+ pendingField: _angular_core.WritableSignal<SuggestionItem | null>;
145
+ /** Operator label for the pending operator (displayed as a pill) */
146
+ pendingOperatorLabel: _angular_core.WritableSignal<string>;
147
+ /** The accumulated search blocks */
148
+ blocks: _angular_core.WritableSignal<SearchBlock[]>;
149
+ /** Types staged in the multi-select before the block is committed (type step). */
150
+ draftTypes: _angular_core.WritableSignal<SearchBlockType[]>;
151
+ /** Index of the condition being edited (-1 = new condition) */
152
+ editingConditionIndex: _angular_core.WritableSignal<number>;
153
+ /**
154
+ * How to combine the top-level units (full-text unit + type blocks). These are
155
+ * type-scoped, so they always join with OR ("this as well as that"); the UI no
156
+ * longer exposes a toggle. Kept as a signal so saved states still round-trip.
157
+ */
158
+ combinator: _angular_core.WritableSignal<Combinator>;
159
+ /** The current filter term for autocomplete suggestions */
160
+ inputTerm: _angular_core.WritableSignal<string>;
161
+ /** The whole-object full-text search unit (independent of the condition blocks). */
162
+ fulltext: _angular_core.WritableSignal<FulltextSearch>;
163
+ objectTypes: _angular_core.Signal<GenericObjectType[]>;
164
+ /** Fields for the active top-level block, used by the field-step suggestions. */
165
+ activeBlockFields: _angular_core.Signal<SuggestionItem[]>;
166
+ /**
167
+ * When the active edit is scoped inside a table, the resolved column definitions
168
+ * of that table (as full `ObjectTypeField`s with `_internalType`). `null` when
169
+ * not editing inside a table.
170
+ */
171
+ activeTableColumns: _angular_core.Signal<ObjectTypeField[] | null>;
172
+ /**
173
+ * The fields offered at the field step: a table's **columns** when editing
174
+ * inside a table, otherwise the active block's shared fields.
175
+ */
176
+ activeFields: _angular_core.Signal<SuggestionItem[]>;
177
+ suggestions: _angular_core.Signal<SuggestionItem[]>;
178
+ /** Number of top-level query units: the full-text unit (when it has a term) plus each block. */
179
+ unitCount: _angular_core.Signal<number>;
180
+ showCombinator: _angular_core.Signal<boolean>;
181
+ cmisQuery: _angular_core.Signal<string>;
182
+ /** The active input control for the current step. */
183
+ activeCtrl: _angular_core.Signal<FormControl<unknown>>;
184
+ /** Deep-clone the current blocks, combinator and full-text unit into a serializable {@link SmartSearchState}. */
185
+ getState(): SmartSearchState;
186
+ /** Replace the current state with a saved one, normalizing legacy blocks and cancelling any in-progress edit. */
187
+ loadState(state: SmartSearchState): void;
188
+ /** Reset all search state back to its initial empty values. */
189
+ reset(): void;
190
+ /** Set the full-text search term. */
191
+ setFulltextTerm(term: string): void;
192
+ /** Set the full-text search scope (`all` / `metadata` / `content`). */
193
+ setFulltextScope(scope: FulltextScope): void;
194
+ /** Add a target type to the full-text unit (no-op if already present). */
195
+ addFulltextType(type: GenericObjectType, label: string): void;
196
+ /** Remove a target type from the full-text unit by id. */
197
+ removeFulltextType(id: string): void;
198
+ /** Replace the full-text target types from a list of object-type ids (unknown ids are dropped). */
199
+ setFulltextTypes(ids: string[]): void;
200
+ /** Stage a type in the draft multi-select (no-op if already staged). */
201
+ addDraftType(type: GenericObjectType, label: string): void;
202
+ /** Remove a staged type from the draft multi-select. */
203
+ removeDraftType(id: string): void;
204
+ /**
205
+ * Commit the staged draft types into a new block and clear the draft.
206
+ * Returns the created block, or `null` when the draft is empty.
207
+ */
208
+ confirmDraftTypes(): SearchBlock | null;
209
+ /** Remove a whole block; cancels the in-progress edit if it belonged to that block. */
210
+ removeBlock(block: SearchBlock): void;
211
+ /** Append an empty `ConditionGroup` to a container and start adding inside it. */
212
+ addGroup(parent: ConditionContainer): ConditionGroup;
213
+ /**
214
+ * Remove a group from its parent container. If the parent group becomes
215
+ * empty, it is also removed (cascading up). Top-level blocks are preserved.
216
+ */
217
+ removeGroup(group: ConditionGroup): void;
218
+ /** Remove a condition from the tree; empty parent groups/tables are pruned by the cascade. */
219
+ removeCondition(_container: ConditionContainer, condition: FieldCondition): void;
220
+ /** Set the top-level combinator joining the query units (full-text unit + blocks). */
221
+ setCombinator(value: Combinator): void;
222
+ /** Set the AND/OR combinator of a single container (block, group or table). */
223
+ setContainerCombinator(container: ConditionContainer, value: Combinator): void;
224
+ /**
225
+ * The picked field resolves to a queryable `table` type. A table has no operator
226
+ * of its own; instead it holds column conditions directly. Insert an empty
227
+ * {@link TableCondition} and scope the edit into it so the user picks a column next.
228
+ */
229
+ addTableCondition(field: SuggestionItem): void;
230
+ /** Begin adding a condition inside `container`. */
231
+ startAddCondition(container: ConditionContainer): void;
232
+ /** Begin editing an existing condition inside `container`. */
233
+ editCondition(container: ConditionContainer, condition: FieldCondition, index: number): void;
234
+ /** Jump back to the field step and clear the input so the user can re-type. */
235
+ editField(): void;
236
+ /** Jump back to the operator step and clear the input so the user can re-type. */
237
+ editOperator(): void;
238
+ /** Abandon the in-progress edit, restoring state and pruning any empty container created for it. */
239
+ cancelPending(): void;
240
+ /** Insert (or, when editing, re-insert at its original index) the finished condition into the active container. */
241
+ commitCondition(condition: FieldCondition): void;
242
+ /**
243
+ * On blur with an incomplete edit of an existing condition, reinsert the
244
+ * original verbatim at its original index.
245
+ */
246
+ restoreEditingSnapshot(): void;
247
+ /** Whether the in-progress condition has all parts needed to be committed. */
248
+ isConditionComplete(): boolean;
249
+ /** The operators available for a field's internal type, as autocomplete items. */
250
+ operatorsForField(field: SuggestionItem): SuggestionItem[];
251
+ /** Human-readable label for an operator id: a math symbol (`=`, `≠`, …), a translated key, or the id itself. */
252
+ operatorLabel(operator: string): string;
253
+ /** Build a condition record from a date preset / boolean operator / value. */
254
+ buildCommitCondition(field: SuggestionItem, operatorId: string, operatorLabelText: string, value: string | string[], internalTypeOverride?: string): FieldCondition;
255
+ /**
256
+ * Resolve a field definition by id across the given block types, falling back to
257
+ * the universal base fields. Used by the host to render the value editor for a
258
+ * picked field (including inherited base fields not present on any type).
259
+ */
260
+ resolveFieldDefinition(types: SearchBlockType[], fieldId: string): ObjectTypeField | null;
261
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SmartSearchEditController, never>;
262
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<SmartSearchEditController>;
263
+ }
264
+
265
+ /**
266
+ * Recursively render a condition node. Groups produce parenthesized
267
+ * sub-expressions; empty groups contribute nothing; single-child groups
268
+ * collapse their redundant parens. Table conditions delegate to
269
+ * {@link buildTableClause}.
270
+ */
271
+ declare function buildNodeClause(node: ConditionNode): string;
272
+ /**
273
+ * Build the whole-object full-text clause: a single `CONTAINS('term')` predicate, optionally scoped
274
+ * to a column and AND-ed with a type restriction. Returns `''` when the term is blank.
275
+ */
276
+ declare function buildFulltextClause(fulltext: FulltextSearch): string;
277
+ /**
278
+ * Assemble the full CMIS statement from the search state. Each unit — the
279
+ * full-text clause plus every type block (type restriction `AND`-ed with its
280
+ * conditions) — is parenthesized and joined by `combinator`. Returns `''` when
281
+ * nothing contributes a clause, so an empty search yields no query.
282
+ *
283
+ * @param blocks The type blocks with their conditions.
284
+ * @param combinator How the top-level units combine (`AND` / `OR`).
285
+ * @param fulltext Optional whole-object full-text unit.
286
+ * @returns A `SELECT * FROM system:object WHERE …` statement, or `''`.
287
+ */
288
+ declare function buildCmisQuery(blocks: SearchBlock[], combinator: Combinator, fulltext?: FulltextSearch): string;
289
+
290
+ /**
291
+ * Visual query builder that turns guided, chip-based user input into a CMIS query.
292
+ *
293
+ * The user composes a search in two independent parts:
294
+ * - a **full-text bar** (`CONTAINS`) with a scope (all / metadata / content) and an
295
+ * optional object-type restriction, and
296
+ * - one or more **type blocks**, each targeting one or more object types and holding
297
+ * field conditions, nested groups and table-column conditions.
298
+ *
299
+ * Conditions are built step by step (type → field → operator → value) with an inline
300
+ * autocomplete editor; the value step renders the field's real metadata widget
301
+ * (datepicker, catalog select, organization picker, …). The resulting CMIS query is
302
+ * emitted through {@link queryChange} on every change and can be saved/restored as a
303
+ * plain-data {@link SmartSearchState} via {@link getState} / {@link loadState}.
304
+ *
305
+ * State and mutators live in {@link SmartSearchEditController} (provided per instance);
306
+ * this component owns only the UI concerns (focus, autocomplete plumbing, blur handling).
307
+ *
308
+ * @example
309
+ * ```html
310
+ * <!-- Restrict the picker to two object types and skip a noisy property -->
311
+ * <yuv-smart-search
312
+ * [types]="['document', 'invoice']"
313
+ * [skipProperties]="['system:traceId']"
314
+ * (queryChange)="onQuery($event)"
315
+ * />
316
+ * ```
317
+ *
318
+ * @example
319
+ * ```ts
320
+ * // Save and restore the builder state (e.g. a stored search)
321
+ * const search = viewChild.required(SmartSearchComponent);
322
+ *
323
+ * onQuery(cmisQuery: string) {
324
+ * // empty string means "no query" — treat it as a cleared search
325
+ * this.results.set(cmisQuery ? this.backend.search(cmisQuery) : []);
326
+ * }
327
+ *
328
+ * persist() {
329
+ * localStorage.setItem('search', JSON.stringify(this.search().getState()));
330
+ * }
331
+ *
332
+ * restore() {
333
+ * const state = localStorage.getItem('search');
334
+ * if (state) this.search().loadState(JSON.parse(state));
335
+ * }
336
+ * ```
337
+ */
338
+ declare class SmartSearchComponent {
339
+ #private;
340
+ ctrl: SmartSearchEditController;
341
+ /**
342
+ * Object-type ids that may be searched. Restricts the type picker (both the
343
+ * full-text type filter and the type-block multi-select) to these types. When
344
+ * empty, no type is offered — set at least one id to enable building blocks.
345
+ */
346
+ types: _angular_core.InputSignal<string[]>;
347
+ /**
348
+ * Field ids to hide from the field-step autocomplete (e.g. internal/system
349
+ * properties that should not be user-queryable). Applies to block fields and
350
+ * table columns alike.
351
+ */
352
+ skipProperties: _angular_core.InputSignal<string[]>;
353
+ /**
354
+ * Emits the current CMIS query string whenever the search changes. An empty
355
+ * string is emitted for an empty search (including the initial seed), so
356
+ * consumers should treat `''` as "no query" rather than expecting only
357
+ * non-empty values.
358
+ */
359
+ queryChange: _angular_core.OutputEmitterRef<string>;
360
+ auto: _angular_core.Signal<MatAutocomplete>;
361
+ /** Trigger of the currently-focused autocomplete input — used to re-open the
362
+ * panel after a type pick so the multi-select stays open. */
363
+ trigger: _angular_core.Signal<MatAutocompleteTrigger | undefined>;
364
+ /** Term control for the full-text bar (independent of the build-step controls). */
365
+ fulltextTermCtrl: FormControl<string | null>;
366
+ /** Sentinel option value representing "no type restriction" in the type multi-select. */
367
+ readonly ALL_TYPES = "__all__";
368
+ /**
369
+ * Guard that prevents `onInlineBlur` from cancelling the pending condition
370
+ * when we programmatically open the inline editor.
371
+ */
372
+ _suppressNextBlur: boolean;
373
+ /** Prevents the valueChanges subscriber from overwriting inputTerm during programmatic setValue */
374
+ _suppressInputTerm: boolean;
375
+ /**
376
+ * Set when a type is staged via the autocomplete so the ENTER that triggered the
377
+ * selection does not also fall through to `confirmTypes()`. Cleared on the next
378
+ * tick. Needed because the chip-input directive changes the keydown listener order,
379
+ * so `onTypeEnter` can run *after* the autocomplete has already closed its panel.
380
+ */
381
+ _suppressTypeConfirm: boolean;
382
+ /**
383
+ * Set while an autocomplete option is being applied so the panel's `closed`
384
+ * event (which Material emits synchronously right after `optionSelected`) is not
385
+ * mistaken for the user abandoning an empty property picker. Consumed
386
+ * synchronously in `onPickerClosed`.
387
+ */
388
+ _pickerJustSelected: boolean;
389
+ readonly blocks: _angular_core.WritableSignal<SearchBlock[]>;
390
+ readonly draftTypes: _angular_core.WritableSignal<_yuuvis_client_framework_smart_search.SearchBlockType[]>;
391
+ readonly combinator: _angular_core.WritableSignal<Combinator>;
392
+ readonly step: _angular_core.WritableSignal<_yuuvis_client_framework_smart_search.BuildStep>;
393
+ readonly activeBlock: _angular_core.WritableSignal<SearchBlock | null>;
394
+ readonly activeContainer: _angular_core.WritableSignal<ConditionContainer | null>;
395
+ readonly pendingField: _angular_core.WritableSignal<SuggestionItem | null>;
396
+ readonly pendingOperatorLabel: _angular_core.WritableSignal<string>;
397
+ readonly editingConditionIndex: _angular_core.WritableSignal<number>;
398
+ readonly inputTerm: _angular_core.WritableSignal<string>;
399
+ readonly cmisQuery: _angular_core.Signal<string>;
400
+ readonly showCombinator: _angular_core.Signal<boolean>;
401
+ readonly suggestions: _angular_core.Signal<SuggestionItem[]>;
402
+ readonly fulltext: _angular_core.WritableSignal<_yuuvis_client_framework_smart_search.FulltextSearch>;
403
+ readonly objectTypes: _angular_core.Signal<_yuuvis_client_core.GenericObjectType[]>;
404
+ readonly activeBlockFields: _angular_core.Signal<SuggestionItem[]>;
405
+ /**
406
+ * Selected ids for the type multi-select. Falls back to the `ALL_TYPES`
407
+ * sentinel when no concrete type is picked (empty selection = no restriction).
408
+ */
409
+ readonly fulltextTypeSelection: _angular_core.Signal<string[]>;
410
+ readonly fieldCtrl: FormControl<string | null>;
411
+ readonly operatorCtrl: FormControl<string | null>;
412
+ readonly valueCtrl: FormControl<unknown>;
413
+ /**
414
+ * Field definition driving the value-step editor. Memoized so the `[field]`
415
+ * reference stays stable across change-detection cycles — re-resolving on every
416
+ * CD (via a template method call) would re-create the editor and reset widgets
417
+ * like the catalog select before their options render.
418
+ */
419
+ readonly valueFieldDef: _angular_core.Signal<ObjectTypeField | null>;
420
+ constructor();
421
+ /** Set the AND/OR combinator that joins the conditions within a single container (block, group or table). */
422
+ setConditionCombinator(container: ConditionContainer, value: Combinator): void;
423
+ /**
424
+ * Capture the current search as a serializable snapshot. Safe for
425
+ * `JSON.stringify`/`JSON.parse` roundtrips — use it to persist a search and
426
+ * later restore it with {@link loadState}.
427
+ */
428
+ getState(): SmartSearchState;
429
+ /** Restore a previously {@link getState saved} search, replacing the current one. */
430
+ loadState(state: SmartSearchState): void;
431
+ /** Clear the whole search: discard all blocks, conditions and the full-text term. */
432
+ clear(): void;
433
+ /**
434
+ * Set the top-level combinator joining the query units (the full-text unit and
435
+ * the type blocks). Kept for state round-tripping; the UI currently always
436
+ * joins units with `OR`.
437
+ */
438
+ setCombinator(value: Combinator): void;
439
+ /** Remove an entire type block and all of its conditions. */
440
+ removeBlock(block: SearchBlock): void;
441
+ /** Commit the staged draft types into a new block and reset the type input. */
442
+ confirmTypes(): void;
443
+ /** Start adding a new condition inside the given container and focus the inline editor. */
444
+ startAddCondition(block: SearchBlock): void;
445
+ /** Add a nested condition group inside the given container and focus the inline editor. */
446
+ addGroup(block: SearchBlock): void;
447
+ /**
448
+ * `displayWith` for the shared autocomplete. Suggestions are objects but the
449
+ * input text is driven by the form controls, so a picked option must not write
450
+ * a label back into the field — return the raw string, or empty otherwise.
451
+ */
452
+ displayFn: (item: SuggestionItem | string | null) => string;
453
+ /** Set where the full-text search looks: `all` (metadata + content), `metadata`, or `content`. */
454
+ setFulltextScope(scope: FulltextScope): void;
455
+ /**
456
+ * Reconcile the type multi-select with the "All types" sentinel. Picking
457
+ * "All types" while concrete types are selected clears the restriction;
458
+ * picking any concrete type drops the sentinel.
459
+ */
460
+ onFulltextTypesChange(ids: string[]): void;
461
+ /**
462
+ * Handle a pick from the shared autocomplete panel. Branches on the current
463
+ * build step: stages a type (keeping the panel open for more), advances a
464
+ * field to its operator (or opens a table container), or applies a chosen
465
+ * operator. Single-operator fields and valueless operators commit immediately.
466
+ */
467
+ onSuggestionSelected(event: MatAutocompleteSelectedEvent): void;
468
+ /**
469
+ * Enter in the add-type input. When the input is empty there's no option to
470
+ * pick, so Enter commits the staged types — even while the autocomplete panel
471
+ * is open. While the user is typing a filter term, Enter is left to the
472
+ * autocomplete so it can select the highlighted option.
473
+ */
474
+ onTypeEnter(): void;
475
+ /**
476
+ * Enter / confirm-button handler for the value step. Commits the in-progress
477
+ * condition when a value is present. No-op while the autocomplete panel is open
478
+ * (Enter selects the highlighted option there) or before the value step.
479
+ */
480
+ onEnter(): void;
481
+ /**
482
+ * Called when the inline-input wrapper loses focus.
483
+ * Commits the condition if complete, discards it if incomplete.
484
+ *
485
+ * Deferred via setTimeout(0): raw value renderers (datepicker dialog,
486
+ * mat-select panel, mat-autocomplete panel) mount their UI in the
487
+ * .cdk-overlay-container, which is OUTSIDE the wrapper. Reading
488
+ * document.activeElement on the next task lets us detect that focus
489
+ * is still in our logical scope.
490
+ */
491
+ onInlineBlur(event: FocusEvent): void;
492
+ /**
493
+ * Fired when the shared autocomplete panel closes. Starting a condition opens
494
+ * the property picker; if the user dismisses it (outside click, Escape) without
495
+ * choosing a field, there's an empty editor with nothing to commit — drop it.
496
+ *
497
+ * Only the field step is handled here: operator/value abandonment is already
498
+ * covered by `onInlineBlur` (those steps don't auto-open a picker the user can
499
+ * dismiss while keeping focus). Restores the original when editing an existing
500
+ * condition, mirroring the blur path.
501
+ */
502
+ onPickerClosed(): void;
503
+ /** Abandon the in-progress condition edit, discarding any partial input. */
504
+ cancelPending(): void;
505
+ /** Jump the inline editor back to the field step so the user can re-pick the field. */
506
+ editField(): void;
507
+ /** Jump the inline editor back to the operator step so the user can re-pick the operator. */
508
+ editOperator(): void;
509
+ /**
510
+ * Open an already-committed condition for editing in place. The condition is
511
+ * pulled out of the tree into the inline editor at its original index, pre-set
512
+ * to the appropriate step (value, or operator for valueless operators).
513
+ */
514
+ editCondition(container: ConditionContainer, condition: FieldCondition, index: number): void;
515
+ /** Remove a committed condition from its container. */
516
+ removeCondition(container: ConditionContainer, condition: FieldCondition): void;
517
+ /**
518
+ * Renderer input for a committed condition's value, or `null` when the value
519
+ * should render as plain text. id-based fields (e.g. organization) store an
520
+ * opaque id as the query value; routing it through the property renderer
521
+ * resolves it to a human-readable label for the chip. Valueless operators
522
+ * (empty/not_empty, date presets) and booleans keep their plain text: their
523
+ * stored value is synthetic/serialized, not the shape those renderers expect.
524
+ */
525
+ valueRendererInput(condition: FieldCondition): RendererDirectiveInput | null;
526
+ /**
527
+ * Resolve the full {@link ObjectTypeField} definition for a suggestion item in
528
+ * the active block, or `null` when none applies. Drives the value-step metadata
529
+ * widget so the right editor (datepicker, catalog, …) is rendered.
530
+ */
531
+ getObjectTypeField(item: SuggestionItem | null): ObjectTypeField | null;
532
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SmartSearchComponent, never>;
533
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SmartSearchComponent, "yuv-smart-search", never, { "types": { "alias": "types"; "required": false; "isSignal": true; }; "skipProperties": { "alias": "skipProperties"; "required": false; "isSignal": true; }; }, { "queryChange": "queryChange"; }, never, never, true, never>;
534
+ }
535
+
536
+ declare class YuvSmartSearchModule {
537
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<YuvSmartSearchModule, never>;
538
+ static ɵmod: _angular_core.ɵɵNgModuleDeclaration<YuvSmartSearchModule, never, [typeof SmartSearchComponent], [typeof SmartSearchComponent]>;
539
+ static ɵinj: _angular_core.ɵɵInjectorDeclaration<YuvSmartSearchModule>;
540
+ }
541
+
542
+ export { SmartSearchComponent, YuvSmartSearchModule, buildCmisQuery, buildFulltextClause, buildNodeClause, isConditionGroup, isFieldCondition, isTableCondition };
543
+ export type { BuildStep, Combinator, ConditionContainer, ConditionGroup, ConditionNode, FieldCondition, FulltextScope, FulltextSearch, SearchBlock, SearchBlockType, SmartSearchState, SuggestionItem, TableCondition };