@yuuvis/client-framework 3.9.0 → 3.11.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuuvis/client-framework",
3
- "version": "3.9.0",
3
+ "version": "3.11.0",
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.9.0",
12
- "@yuuvis/client-shell-core": "^3.9.0",
13
- "@yuuvis/client-components": "^3.9.0",
11
+ "@yuuvis/client-core": "^3.11.0",
12
+ "@yuuvis/client-shell-core": "^3.11.0",
13
+ "@yuuvis/client-components": "^3.11.0",
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.9.0",
20
+ "@yuuvis/material": "^3.11.0",
21
21
  "@yuuvis/media-viewer": "^3.0.6",
22
22
  "angular-split": "^20.0.0",
23
23
  "vis-network": "^10.0.2",
@@ -1,5 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { TemplateRef, OnInit, AfterViewInit, OnDestroy } from '@angular/core';
2
+ import { TemplateRef, InjectionToken, Signal, OnInit, AfterViewInit, OnDestroy } from '@angular/core';
3
3
  import { Situation, ObjectTypeField, ObjectFormControl } from '@yuuvis/client-core';
4
4
  import { AbstractControl } from '@angular/forms';
5
5
  import { Subject } from 'rxjs';
@@ -100,6 +100,27 @@ declare class MetadataFormElementRegistry {
100
100
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<MetadataFormElementRegistry>;
101
101
  }
102
102
 
103
+ /**
104
+ * Read-only view of the object a metadata form is rendered for. Exposed to
105
+ * element templates (`yuvMetadataElementTemplate`) via the field context.
106
+ *
107
+ * Intentionally minimal and framework-agnostic: it does NOT reference
108
+ * `DmsObject` so the token stays usable outside object-details (smart-search,
109
+ * BPM forms, …). Producers map their object onto this shape.
110
+ */
111
+ interface ObjectContext {
112
+ id?: string;
113
+ objectTypeId?: string;
114
+ /** Immutable initial index data of the object (not live form edits). */
115
+ data: Record<string, unknown>;
116
+ }
117
+ /**
118
+ * Provide at the component that owns the object (e.g. `ObjectMetadataComponent`)
119
+ * so it is scoped to that instance's view subtree. Consumers inject it
120
+ * `{ optional: true }` — it is absent when a form runs standalone.
121
+ */
122
+ declare const OBJECT_CONTEXT: InjectionToken<Signal<ObjectContext | undefined>>;
123
+
103
124
  /**
104
125
  * Context provided to each metadata form field.
105
126
  */
@@ -109,6 +130,8 @@ interface MetadataFormFieldContext {
109
130
  field: ObjectTypeField;
110
131
  ctrl?: AbstractControl<any, any>;
111
132
  formChangedSubject?: Subject<ParentFormChangedEvent>;
133
+ /** The object the form is rendered for. Undefined when no producer provided it. */
134
+ object?: ObjectContext;
112
135
  }
113
136
  interface ParentFormChangedEvent {
114
137
  invalid: boolean;
@@ -271,5 +294,5 @@ declare class MetadataFormFieldComponent {
271
294
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<MetadataFormFieldComponent, "yuv-metadata-form-field", never, { "formChangedSubject": { "alias": "formChangedSubject"; "required": false; "isSignal": true; }; "formField": { "alias": "field"; "required": true; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "situation": { "alias": "situation"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.NoopValueAccessorDirective; inputs: {}; outputs: {}; }]>;
272
295
  }
273
296
 
274
- export { MetadataFormElementRegistry, MetadataFormFieldComponent, ObjectMetadataElementErrorDirective, ObjectMetadataElementLabelDirective, ObjectMetadataElementRawDirective, ObjectMetadataElementTemplateDirective };
275
- export type { MetadataFormFieldContext, ParentFormChangedEvent };
297
+ export { MetadataFormElementRegistry, MetadataFormFieldComponent, OBJECT_CONTEXT, ObjectMetadataElementErrorDirective, ObjectMetadataElementLabelDirective, ObjectMetadataElementRawDirective, ObjectMetadataElementTemplateDirective };
298
+ export type { MetadataFormFieldContext, ObjectContext, ParentFormChangedEvent };
@@ -1,9 +1,9 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { TemplateRef, OnDestroy, PipeTransform } from '@angular/core';
2
+ import { TemplateRef, OnDestroy, WritableSignal, PipeTransform } from '@angular/core';
3
3
  import * as _yuuvis_client_core from '@yuuvis/client-core';
4
4
  import { AuditQueryResult, AuditEntry, DmsObject, VirtualObjectType, RetentionState, TranslateService, ObjectTypeFlavor, Situation, FlavoredDmsObject, ObjectTypeField } from '@yuuvis/client-core';
5
5
  import { RendererDirectiveInput } from '@yuuvis/client-framework/renderer';
6
- import { ObjectFormComponent, IObjectFormElementExtension, ObjectFormOptions, FormStatusChangedEvent } from '@yuuvis/client-framework/object-form';
6
+ import { ObjectFormComponent, IObjectFormElementExtension, ObjectFormOptions, FormStatusChangedEvent, SotRendererContext } from '@yuuvis/client-framework/object-form';
7
7
  import * as i7 from '@yuuvis/client-framework/common';
8
8
  import { FormGroup } from '@angular/forms';
9
9
 
@@ -183,14 +183,43 @@ declare class ObjectMetadataSectionComponent {
183
183
  expandedInput: _angular_core.InputSignal<boolean>;
184
184
  elementExtensions: _angular_core.InputSignal<IObjectFormElementExtension[]>;
185
185
  readonly: _angular_core.InputSignal<boolean | undefined>;
186
+ /**
187
+ * When `true`, the section's expand/collapse feature is removed: the content is
188
+ * always visible, cannot be collapsed, and the accordion toggle (arrow) is hidden.
189
+ */
190
+ skipExpand: _angular_core.InputSignal<boolean | undefined>;
191
+ /**
192
+ * When `true`, the section header (title, icon and toggle) is not rendered while the
193
+ * content region is still shown. Typically combined with {@link skipExpand} to display
194
+ * a title-less, always-open section.
195
+ */
196
+ skipTitle: _angular_core.InputSignal<boolean | undefined>;
186
197
  expanded: _angular_core.WritableSignal<boolean>;
198
+ /**
199
+ * Effective expanded state. When `skipExpand` is set the section is always visible
200
+ * and cannot be collapsed, so it is treated as permanently expanded.
201
+ */
202
+ isExpanded: _angular_core.Signal<boolean>;
187
203
  busy: _angular_core.WritableSignal<boolean>;
188
204
  formOptions: _angular_core.WritableSignal<ObjectFormOptions | undefined>;
189
205
  statusChanged: _angular_core.OutputEmitterRef<FormStatusChangedEvent>;
206
+ /**
207
+ * A custom SOT renderer registered for this section's SOT id, or undefined when
208
+ * the default schema-driven form should be used.
209
+ */
210
+ customTemplate: _angular_core.Signal<_angular_core.TemplateRef<any> | undefined>;
211
+ /**
212
+ * Last status emitted by a custom renderer. Used to drive the host dirty/invalid
213
+ * classes when the default `yuv-object-form` (and thus `objectForm()`) is absent.
214
+ */
215
+ customStatus: _angular_core.WritableSignal<FormStatusChangedEvent | undefined>;
216
+ renderCustom: _angular_core.Signal<boolean>;
217
+ sotContext: _angular_core.Signal<SotRendererContext>;
218
+ toggle(): void;
190
219
  resetForm(): void;
191
220
  setFormPristine(): void;
192
221
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<ObjectMetadataSectionComponent, never>;
193
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<ObjectMetadataSectionComponent, "yuv-object-metadata-section", never, { "section": { "alias": "section"; "required": true; "isSignal": true; }; "expandedInput": { "alias": "expanded"; "required": false; "isSignal": true; }; "elementExtensions": { "alias": "elementExtensions"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; }, { "statusChanged": "statusChanged"; }, never, never, true, never>;
222
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ObjectMetadataSectionComponent, "yuv-object-metadata-section", never, { "section": { "alias": "section"; "required": true; "isSignal": true; }; "expandedInput": { "alias": "expanded"; "required": false; "isSignal": true; }; "elementExtensions": { "alias": "elementExtensions"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "skipExpand": { "alias": "skipExpand"; "required": false; "isSignal": true; }; "skipTitle": { "alias": "skipTitle"; "required": false; "isSignal": true; }; }, { "statusChanged": "statusChanged"; }, never, never, true, never>;
194
223
  }
195
224
 
196
225
  declare class ObjectMetadataComponent implements OnDestroy {
@@ -200,8 +229,8 @@ declare class ObjectMetadataComponent implements OnDestroy {
200
229
  hasWritePermission: _angular_core.Signal<boolean>;
201
230
  objectForms: _angular_core.Signal<readonly ObjectFormComponent[]>;
202
231
  objectMetadataSectionForms: _angular_core.Signal<readonly ObjectMetadataSectionComponent[]>;
203
- busySaving: _angular_core.WritableSignal<boolean>;
204
- busyLoading: _angular_core.WritableSignal<boolean>;
232
+ busySaving: WritableSignal<boolean>;
233
+ busyLoading: WritableSignal<boolean>;
205
234
  disableControls: _angular_core.InputSignal<boolean>;
206
235
  /**
207
236
  * Set to 'true' to disable the basic metadata form. This will hide
@@ -210,7 +239,7 @@ declare class ObjectMetadataComponent implements OnDestroy {
210
239
  */
211
240
  disableBasicMetadata: _angular_core.InputSignal<boolean>;
212
241
  elementExtensions: _angular_core.InputSignal<IObjectFormElementExtension[]>;
213
- controlsVisible: _angular_core.WritableSignal<boolean>;
242
+ controlsVisible: WritableSignal<boolean>;
214
243
  empty: _angular_core.Signal<boolean>;
215
244
  baseData: {
216
245
  label: string;
@@ -223,9 +252,9 @@ declare class ObjectMetadataComponent implements OnDestroy {
223
252
  /**
224
253
  * Set to 'true' to prevent all metadata from being edited
225
254
  */
226
- formDisabled: _angular_core.WritableSignal<boolean>;
255
+ formDisabled: WritableSignal<boolean>;
227
256
  dmsObjectInput: _angular_core.InputSignal<DmsObject | undefined>;
228
- dmsObject: _angular_core.WritableSignal<DmsObject | undefined>;
257
+ dmsObject: WritableSignal<DmsObject | undefined>;
229
258
  /**
230
259
  * @deprecated This input will be removed in the future.
231
260
  * Please migrate to using `dmsObject` and `flavors` inputs instead.
@@ -240,7 +269,7 @@ declare class ObjectMetadataComponent implements OnDestroy {
240
269
  * Emits the current state of the metadata form.
241
270
  */
242
271
  statusChanged: _angular_core.OutputEmitterRef<FormStatusChangedEvent>;
243
- mainFormOptions: _angular_core.WritableSignal<ObjectFormOptions | undefined>;
272
+ mainFormOptions: WritableSignal<ObjectFormOptions | undefined>;
244
273
  mainFormOptionsIsLoading: _angular_core.Signal<boolean>;
245
274
  flavors: _angular_core.InputSignal<ObjectTypeFlavor[] | undefined>;
246
275
  flavorFormOptions: _angular_core.Signal<{
@@ -1,6 +1,6 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { Type, OnDestroy, AfterViewInit } from '@angular/core';
3
- import { YuvEvent, YuvUser, HttpOptions, ObjectFormGroup } from '@yuuvis/client-core';
2
+ import { Type, OnDestroy, AfterViewInit, OnInit, TemplateRef } from '@angular/core';
3
+ import { YuvEvent, YuvUser, HttpOptions, ObjectFormGroup, Situation } from '@yuuvis/client-core';
4
4
  import { Observable } from 'rxjs';
5
5
 
6
6
  interface IObjectForm {
@@ -284,5 +284,148 @@ declare class YuvObjectFormModule {
284
284
  static ɵinj: _angular_core.ɵɵInjectorDeclaration<YuvObjectFormModule>;
285
285
  }
286
286
 
287
- export { ObjectFormComponent, ObjectFormElementExtension, YuvObjectFormModule };
288
- export type { FormStatusChangedEvent, IObjectForm, IObjectFormElementExtension, IObjectFormElementExtensionComponentInput, ObjectFormModelChange, ObjectFormOptions };
287
+ /**
288
+ * Directive to be applied to a `ng-template`. It registers the template as the
289
+ * renderer for a complete secondary object type (SOT / flavor) inside the object
290
+ * metadata form. When a SOT has a registered template, its section renders that
291
+ * template instead of the auto-generated field-by-field form.
292
+ *
293
+ * The template receives a `SotRendererContext` as its implicit context. Use it to
294
+ * push status changes upward (`ctx.setStatus`) and to react to reset/pristine
295
+ * commands (`ctx.command$`), keeping the shared form integration intact.
296
+ *
297
+ * A single template can be registered for one SOT or for several at once by
298
+ * passing an array of SOT ids to `sot`.
299
+ *
300
+ * @example
301
+ * <ng-template yuvMetadataSotTemplate="default" sot="sot:invoice" let-ctx>
302
+ * <my-invoice-sot [ctx]="ctx" />
303
+ * </ng-template>
304
+ *
305
+ * @example
306
+ * <ng-template yuvMetadataSotTemplate="default" [sot]="['sot:invoice', 'sot:receipt']" let-ctx>
307
+ * <my-invoice-sot [ctx]="ctx" />
308
+ * </ng-template>
309
+ */
310
+ declare class ObjectMetadataSotTemplateDirective implements OnInit, OnDestroy {
311
+ #private;
312
+ /**
313
+ * Bucket to register the template. Use 'default' for templates that should be
314
+ * used across all situations.
315
+ */
316
+ yuvMetadataSotTemplate: _angular_core.InputSignal<string | undefined>;
317
+ /**
318
+ * The secondary object type (SOT / flavor) id(s) to register the template for.
319
+ * Pass a single id or an array of ids to reuse the same template for multiple SOTs.
320
+ */
321
+ sot: _angular_core.InputSignal<string | string[]>;
322
+ /**
323
+ * Situation to register the template for. So only object forms for that
324
+ * situation (CREATE, EDIT, SEARCH) will use the template. Defaults to `EDIT`.
325
+ */
326
+ situation: _angular_core.InputSignal<Situation>;
327
+ ngOnInit(): void;
328
+ ngOnDestroy(): void;
329
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ObjectMetadataSotTemplateDirective, never>;
330
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ObjectMetadataSotTemplateDirective, "[yuvMetadataSotTemplate]", never, { "yuvMetadataSotTemplate": { "alias": "yuvMetadataSotTemplate"; "required": false; "isSignal": true; }; "sot": { "alias": "sot"; "required": true; "isSignal": true; }; "situation": { "alias": "situation"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
331
+ }
332
+
333
+ /**
334
+ * Metadata forms render each applied secondary object type (SOT / flavor) as its
335
+ * own section. By default a section auto-generates a field-by-field form from the
336
+ * SOT's schema. This registry lets you replace the body of a SOT's section with a
337
+ * custom template so you can render all of the SOT's properties in one freely
338
+ * designed component (a compact header, a computed summary widget, ...) while the
339
+ * surrounding save/reset/pristine machinery stays intact.
340
+ *
341
+ * Templates are keyed by SOT id and can be registered per situation (EDIT, SEARCH,
342
+ * CREATE). Registering with the `default` bucket makes a template apply across all
343
+ * situations. Registration is normally done declaratively via the
344
+ * `yuvMetadataSotTemplate` directive.
345
+ */
346
+ declare class SotRendererRegistry {
347
+ private _defaults;
348
+ private _edit;
349
+ private _search;
350
+ private _create;
351
+ /**
352
+ * Get the template to render a certain SOT with. Defaults are always merged in,
353
+ * then overlaid by the situation-specific map.
354
+ * @param sot The secondary object type id to get the template for
355
+ * @param situation Form situation
356
+ * @returns TemplateRef or undefined
357
+ */
358
+ getSotTemplate(sot: string, situation?: string): TemplateRef<any> | undefined;
359
+ /**
360
+ * Register a template for rendering a certain SOT.
361
+ * @param sot The secondary object type id to provide the template for
362
+ * @param templateRef The template
363
+ * @param situation Form situation to provide the template for (defaults to EDIT)
364
+ */
365
+ addSotTemplate(sot: string, templateRef: TemplateRef<any>, situation?: Situation): void;
366
+ /**
367
+ * Remove a registered SOT template.
368
+ * @param sot The secondary object type id to remove the template for
369
+ * @param situation Form situation (defaults to EDIT)
370
+ */
371
+ removeSotTemplate(sot: string, situation?: Situation): void;
372
+ /**
373
+ * Register a default SOT template (used across all situations).
374
+ * @param sot The secondary object type id to provide the template for
375
+ * @param templateRef The default template
376
+ */
377
+ _addDefaultSotTemplate(sot: string, templateRef: TemplateRef<any>): void;
378
+ /**
379
+ * Remove a registered default SOT template.
380
+ * @param sot The secondary object type id to remove the template for
381
+ */
382
+ _removeDefaultSotTemplate(sot: string): void;
383
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SotRendererRegistry, never>;
384
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<SotRendererRegistry>;
385
+ }
386
+
387
+ /**
388
+ * Command pushed from the metadata form down into a custom SOT renderer.
389
+ * - `reset`: restore the renderer to its initially loaded data (user hit "reset")
390
+ * - `pristine`: mark the renderer clean (a save succeeded)
391
+ */
392
+ type SotRendererCommand = {
393
+ type: 'reset' | 'pristine';
394
+ };
395
+ /**
396
+ * Context object handed to a template registered via `yuvMetadataSotTemplate`.
397
+ * Passed as `$implicit`, so pick it up with `let-ctx`.
398
+ *
399
+ * It is the two-way bridge between the custom renderer and the surrounding
400
+ * metadata form:
401
+ * - OUTBOUND: call `setStatus()` whenever your form changes so its dirty/invalid
402
+ * state and value payload flow into the shared save/reset/pristine machinery.
403
+ * - INBOUND: subscribe to `command$` to react to reset/pristine triggered by the
404
+ * metadata form (e.g. the user hitting "reset" or a successful save).
405
+ */
406
+ interface SotRendererContext {
407
+ /** The secondary object type (SOT / flavor) id this renderer was registered for. */
408
+ sot: string;
409
+ /** Form situation the metadata form is running in. */
410
+ situation: Situation;
411
+ /** Whether the section is readonly (e.g. missing write permission or a lock). */
412
+ readonly: boolean;
413
+ /**
414
+ * The SOT's form model as loaded by the section. May be `undefined` for a fully
415
+ * custom renderer that does not rely on the schema-driven model.
416
+ */
417
+ formModel: any;
418
+ /** The SOT's current data slice (property/value pairs). */
419
+ data: Record<string, unknown>;
420
+ /**
421
+ * OUTBOUND. Push a status whenever your form changes. The `data` you provide
422
+ * must be keyed by real property names — it is flat-merged into the object's
423
+ * save payload alongside every other section.
424
+ */
425
+ setStatus: (evt: FormStatusChangedEvent) => void;
426
+ /** INBOUND. Emits when the metadata form asks the renderer to reset or go pristine. */
427
+ command$: Observable<SotRendererCommand>;
428
+ }
429
+
430
+ export { ObjectFormComponent, ObjectFormElementExtension, ObjectMetadataSotTemplateDirective, SotRendererRegistry, YuvObjectFormModule };
431
+ export type { FormStatusChangedEvent, IObjectForm, IObjectFormElementExtension, IObjectFormElementExtensionComponentInput, ObjectFormModelChange, ObjectFormOptions, SotRendererCommand, SotRendererContext };