@yuuvis/client-framework 3.8.0 → 3.8.1

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.
@@ -167,8 +167,15 @@
167
167
  "yuv.smart-search.combinator.or": "ODER",
168
168
  "yuv.smart-search.combinator.as-well-as": "sowie",
169
169
  "yuv.smart-search.condition.edit-aria": "Bedingung bearbeiten: {{label}}",
170
+ "yuv.smart-search.condition.mark-dynamic": "Als auszufüllendes Feld festlegen",
170
171
  "yuv.smart-search.condition.remove": "Bedingung entfernen",
172
+ "yuv.smart-search.condition.unmark-dynamic": "Aus auszufüllenden Feldern entfernen",
173
+ "yuv.smart-search.condition.unset-value": "Wert fehlt",
171
174
  "yuv.smart-search.confirm": "Bestätigen",
175
+ "yuv.smart-search.mode.empty": "Keine auszufüllenden Felder. Markiere Bedingungen mit dem Blitz-Symbol, um sie hier hinzuzufügen.",
176
+ "yuv.smart-search.mode.essentials": "Wesentliches",
177
+ "yuv.smart-search.mode.full": "Vollständige Suche",
178
+ "yuv.smart-search.mode.label": "Suchmodus",
172
179
  "yuv.smart-search.date-preset.this-month": "Dieser Monat",
173
180
  "yuv.smart-search.date-preset.this-week": "Diese Woche",
174
181
  "yuv.smart-search.date-preset.this-year": "Dieses Jahr",
@@ -167,8 +167,15 @@
167
167
  "yuv.smart-search.combinator.or": "OR",
168
168
  "yuv.smart-search.combinator.as-well-as": "as well as",
169
169
  "yuv.smart-search.condition.edit-aria": "Edit condition: {{label}}",
170
+ "yuv.smart-search.condition.mark-dynamic": "Make this a fill-out field",
170
171
  "yuv.smart-search.condition.remove": "Remove condition",
172
+ "yuv.smart-search.condition.unmark-dynamic": "Remove from fill-out fields",
173
+ "yuv.smart-search.condition.unset-value": "value missing",
171
174
  "yuv.smart-search.confirm": "Confirm",
175
+ "yuv.smart-search.mode.empty": "No fill-out fields. Mark conditions with the bolt icon to add them here.",
176
+ "yuv.smart-search.mode.essentials": "Essentials",
177
+ "yuv.smart-search.mode.full": "Full Form",
178
+ "yuv.smart-search.mode.label": "Search mode",
172
179
  "yuv.smart-search.date-preset.this-month": "This month",
173
180
  "yuv.smart-search.date-preset.this-week": "This week",
174
181
  "yuv.smart-search.date-preset.this-year": "This year",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuuvis/client-framework",
3
- "version": "3.8.0",
3
+ "version": "3.8.1",
4
4
  "author": "OPTIMAL SYSTEMS GmbH <npm@optimal-systems.de>",
5
5
  "license": "MIT",
6
6
  "peerDependencies": {
@@ -8,16 +8,16 @@
8
8
  "@angular/common": "^21.2.9",
9
9
  "@angular/core": "^21.2.9",
10
10
  "angular-gridster2": "^21.0.1",
11
- "@yuuvis/client-core": "^3.8.0",
12
- "@yuuvis/client-shell-core": "^3.8.0",
13
- "@yuuvis/client-components": "^3.8.0",
11
+ "@yuuvis/client-core": "^3.8.1",
12
+ "@yuuvis/client-shell-core": "^3.8.1",
13
+ "@yuuvis/client-components": "^3.8.1",
14
14
  "ng-dynamic-component": "^10.8.2",
15
15
  "modern-normalize": "^3.0.1"
16
16
  },
17
17
  "dependencies": {
18
18
  "@angular/material": "^21.2.7",
19
19
  "@ngrx/signals": "^21.1.0",
20
- "@yuuvis/material": "^3.8.0",
20
+ "@yuuvis/material": "^3.8.1",
21
21
  "@yuuvis/media-viewer": "^3.0.4",
22
22
  "angular-split": "^20.0.0",
23
23
  "vis-network": "^10.0.2",
@@ -1,8 +1,8 @@
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
1
  import * as _angular_core from '@angular/core';
5
2
  import { FormControl } from '@angular/forms';
3
+ import * as _yuuvis_client_core from '@yuuvis/client-core';
4
+ import { ObjectTypeField, GenericObjectType } from '@yuuvis/client-core';
5
+ import * as _yuuvis_client_framework_smart_search from '@yuuvis/client-framework/smart-search';
6
6
  import { MatAutocomplete, MatAutocompleteTrigger, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
7
7
  import { RendererDirectiveInput } from '@yuuvis/client-framework/renderer';
8
8
 
@@ -27,6 +27,13 @@ interface FieldCondition {
27
27
  value: string | string[];
28
28
  /** Full human-readable label for the chip (`"Name like foo"`). */
29
29
  conditionLabel: string;
30
+ /**
31
+ * Marked by the user as a *dynamic* condition: it is surfaced in the generated
32
+ * fill-out form (see form mode) so its value can be supplied/overridden at run time
33
+ * without rebuilding the query. Purely a builder annotation — it does not affect the
34
+ * emitted query on its own.
35
+ */
36
+ dynamic?: boolean;
30
37
  }
31
38
  /**
32
39
  * A parenthesized sub-expression with its own AND/OR combinator. Groups can
@@ -117,6 +124,26 @@ interface SmartSearchState {
117
124
  fulltext?: FulltextSearch;
118
125
  }
119
126
 
127
+ /**
128
+ * A single row of the generated fill-out form: the dynamic condition it edits, its
129
+ * resolved value-editor field definition (or `null` to fall back to a plain text input)
130
+ * and the `FormControl` bound to the value widget.
131
+ */
132
+ interface DynamicFormField {
133
+ condition: FieldCondition;
134
+ def: ObjectTypeField | null;
135
+ control: FormControl;
136
+ }
137
+ /**
138
+ * A block's worth of dynamic form rows. The generated fill-out form mirrors the builder's
139
+ * block layout: each block contributes a muted header listing its target types, followed by
140
+ * the dynamic conditions ({@link DynamicFormField}s) collected from anywhere within that block.
141
+ * Blocks with no dynamic conditions are omitted.
142
+ */
143
+ interface DynamicFormBlock {
144
+ block: SearchBlock;
145
+ fields: DynamicFormField[];
146
+ }
120
147
  /**
121
148
  * State + mutators for SmartSearch, shared between the host component and the
122
149
  * recursive `SmartSearchGroupComponent`. Provided at the host component level
@@ -160,6 +187,25 @@ declare class SmartSearchEditController {
160
187
  inputTerm: _angular_core.WritableSignal<string>;
161
188
  /** The whole-object full-text search unit (independent of the condition blocks). */
162
189
  fulltext: _angular_core.WritableSignal<FulltextSearch>;
190
+ /** Whether the dynamic-conditions feature is enabled (mirrors the host `supportDynamicConditions` input). */
191
+ supportDynamic: _angular_core.WritableSignal<boolean>;
192
+ /**
193
+ * Form mode: replace the builder with a generated form of the user-marked dynamic
194
+ * conditions. View state only — the template ({@link blocks}) is never mutated; the
195
+ * form's values are overlaid onto the dynamic conditions to drive {@link cmisQuery},
196
+ * so the template stays reusable.
197
+ */
198
+ formMode: _angular_core.WritableSignal<boolean>;
199
+ /** The dynamic conditions surfaced as form rows; rebuilt on each {@link enterFormMode}. */
200
+ formFields: _angular_core.WritableSignal<DynamicFormField[]>;
201
+ /**
202
+ * The dynamic form rows grouped by their owning block (each carrying a muted header of
203
+ * target types); rebuilt on each {@link enterFormMode}. Blocks combine with `OR`
204
+ * ("as well as"), matching the builder.
205
+ */
206
+ formBlocks: _angular_core.WritableSignal<DynamicFormBlock[]>;
207
+ /** Whether any condition is marked dynamic (gates the form-mode toggle). */
208
+ hasDynamicConditions: _angular_core.Signal<boolean>;
163
209
  objectTypes: _angular_core.Signal<GenericObjectType[]>;
164
210
  /** Fields for the active top-level block, used by the field-step suggestions. */
165
211
  activeBlockFields: _angular_core.Signal<SuggestionItem[]>;
@@ -187,6 +233,20 @@ declare class SmartSearchEditController {
187
233
  loadState(state: SmartSearchState): void;
188
234
  /** Reset all search state back to its initial empty values. */
189
235
  reset(): void;
236
+ /** Mark or unmark a condition as dynamic (immutably replaces the node in its container). */
237
+ setConditionDynamic(container: ConditionContainer, condition: FieldCondition, dynamic: boolean): void;
238
+ /**
239
+ * Enter form mode: collect every dynamic condition, resolve its value editor and seed a
240
+ * `FormControl` with its current value. The blocks themselves are left untouched — the
241
+ * form's edits are overlaid via {@link setFormValue} / {@link cmisQuery}.
242
+ */
243
+ enterFormMode(): void;
244
+ /** Leave form mode and discard the transient form state (the template is untouched). */
245
+ exitFormMode(): void;
246
+ /** Toggle form mode (rebuilds the form rows on each entry). */
247
+ toggleFormMode(): void;
248
+ /** Record a value entered in the form for a dynamic condition (drives the overlaid {@link cmisQuery}). */
249
+ setFormValue(condition: FieldCondition, raw: unknown): void;
190
250
  /** Set the full-text search term. */
191
251
  setFulltextTerm(term: string): void;
192
252
  /** Set the full-text search scope (`all` / `metadata` / `content`). */
@@ -244,7 +304,11 @@ declare class SmartSearchEditController {
244
304
  * original verbatim at its original index.
245
305
  */
246
306
  restoreEditingSnapshot(): void;
247
- /** Whether the in-progress condition has all parts needed to be committed. */
307
+ /**
308
+ * Whether the in-progress condition has all parts needed to be committed. A value
309
+ * is *not* required: a field + operator with a blank value commits as an unset
310
+ * placeholder (see {@link isConditionUnset}).
311
+ */
248
312
  isConditionComplete(): boolean;
249
313
  /** The operators available for a field's internal type, as autocomplete items. */
250
314
  operatorsForField(field: SuggestionItem): SuggestionItem[];
@@ -262,6 +326,20 @@ declare class SmartSearchEditController {
262
326
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<SmartSearchEditController>;
263
327
  }
264
328
 
329
+ /**
330
+ * Operators that carry their own meaning and need no value step: date presets,
331
+ * the boolean `= true/false` shortcuts, and the null checks (`empty`/`not_empty`).
332
+ * The build flow commits these immediately instead of advancing to the value editor.
333
+ */
334
+ declare function isValuelessOperator(operator: string): boolean;
335
+ /**
336
+ * Whether a condition is an *unset placeholder*: it uses a value-requiring operator
337
+ * (eq / like / gt / …) but carries no value yet. Such conditions are kept in the tree
338
+ * — so a saved query can act as a fill-in template — but contribute nothing to the
339
+ * emitted CMIS query. An empty value is unambiguously "unset" here because null-checks
340
+ * have their own `empty` / `not_empty` operators (offered on every queryable type).
341
+ */
342
+ declare function isConditionUnset(cond: FieldCondition): boolean;
265
343
  /**
266
344
  * Recursively render a condition node. Groups produce parenthesized
267
345
  * sub-expressions; empty groups contribute nothing; single-child groups
@@ -350,6 +428,13 @@ declare class SmartSearchComponent {
350
428
  * table columns alike.
351
429
  */
352
430
  skipProperties: _angular_core.InputSignal<string[]>;
431
+ /**
432
+ * Enables the **dynamic conditions** feature. When `true`, each committed condition can
433
+ * be marked dynamic and a form-mode toggle appears that swaps the builder for a generated
434
+ * fill-out form of those conditions. Off by default — the builder then behaves exactly as
435
+ * it does without the feature.
436
+ */
437
+ supportDynamicConditions: _angular_core.InputSignal<boolean>;
353
438
  /**
354
439
  * Emits the current CMIS query string whenever the search changes. An empty
355
440
  * string is emitted for an empty search (including the initial seed), so
@@ -402,6 +487,18 @@ declare class SmartSearchComponent {
402
487
  readonly fulltext: _angular_core.WritableSignal<_yuuvis_client_framework_smart_search.FulltextSearch>;
403
488
  readonly objectTypes: _angular_core.Signal<_yuuvis_client_core.GenericObjectType[]>;
404
489
  readonly activeBlockFields: _angular_core.Signal<SuggestionItem[]>;
490
+ readonly formMode: _angular_core.WritableSignal<boolean>;
491
+ readonly formFields: _angular_core.WritableSignal<DynamicFormField[]>;
492
+ readonly formBlocks: _angular_core.WritableSignal<DynamicFormBlock[]>;
493
+ readonly hasDynamicConditions: _angular_core.Signal<boolean>;
494
+ /** Whether a committed condition is an unset placeholder (drives the chip's "fill me" affordance). */
495
+ isUnset: typeof isConditionUnset;
496
+ /**
497
+ * Whether an operator carries its own meaning and has no value input (`is empty`,
498
+ * `is not empty`, date presets). Such conditions can't be made dynamic — there is
499
+ * nothing to fill out in the form.
500
+ */
501
+ isValueless: typeof isValuelessOperator;
405
502
  /**
406
503
  * Selected ids for the type multi-select. Falls back to the `ALL_TYPES`
407
504
  * sentinel when no concrete type is picked (empty selection = no restriction).
@@ -430,6 +527,18 @@ declare class SmartSearchComponent {
430
527
  loadState(state: SmartSearchState): void;
431
528
  /** Clear the whole search: discard all blocks, conditions and the full-text term. */
432
529
  clear(): void;
530
+ /**
531
+ * Toggle form mode: swap the builder for a generated fill-out form of the user-marked
532
+ * dynamic conditions. The template is left intact — the form's values are overlaid onto
533
+ * the query. No-op unless {@link supportDynamicConditions} is set.
534
+ */
535
+ toggleFormMode(): void;
536
+ /** Enter form mode ("Essentials") — generated fill-out form of the dynamic conditions. */
537
+ enterFormMode(): void;
538
+ /** Leave form mode ("Full Form") — back to the full builder search. */
539
+ exitFormMode(): void;
540
+ /** Mark/unmark a committed condition as dynamic (surfaced in the fill-out form). */
541
+ toggleDynamic(container: ConditionContainer, condition: FieldCondition): void;
433
542
  /**
434
543
  * Set the top-level combinator joining the query units (the full-text unit and
435
544
  * the type blocks). Kept for state round-tripping; the UI currently always
@@ -530,7 +639,7 @@ declare class SmartSearchComponent {
530
639
  */
531
640
  getObjectTypeField(item: SuggestionItem | null): ObjectTypeField | null;
532
641
  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>;
642
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SmartSearchComponent, "yuv-smart-search", never, { "types": { "alias": "types"; "required": false; "isSignal": true; }; "skipProperties": { "alias": "skipProperties"; "required": false; "isSignal": true; }; "supportDynamicConditions": { "alias": "supportDynamicConditions"; "required": false; "isSignal": true; }; }, { "queryChange": "queryChange"; }, never, never, true, never>;
534
643
  }
535
644
 
536
645
  declare class YuvSmartSearchModule {