xt-components 0.5.0 → 0.6.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.
@@ -1,11 +1,190 @@
1
+ import { isTypeReference, XtBaseTypeReference, xtTypeManager, ManagedDataHandler, isPrimitive } from 'xt-type';
1
2
  import * as i0 from '@angular/core';
2
- import { computed, signal, InjectionToken, inject, Injectable, input, model, output, viewChild, Component } from '@angular/core';
3
- import { xtTypeManager, ManagedDataHandler, isPrimitive } from 'xt-type';
3
+ import { signal, computed, InjectionToken, inject, Injectable, input, model, output, viewChild, Component } from '@angular/core';
4
4
  import { loadRemoteModule } from '@angular-architects/native-federation';
5
+ import { from, firstValueFrom } from 'rxjs';
5
6
  import { NgComponentOutlet, CommonModule } from '@angular/common';
6
7
  import * as i1 from '@angular/forms';
7
8
  import { ReactiveFormsModule, FormControl, FormGroup, FormBuilder, FormArray } from '@angular/forms';
8
9
 
10
+ class XtPluginRegistry {
11
+ constructor() {
12
+ this.pluginRegistry = new Map();
13
+ this.componentRegistry = new Map();
14
+ this.componentByTypeCache = new Map();
15
+ this.actionByTypeRegistry = new Map();
16
+ this.listComponents = signal(new Array(), ...(ngDevMode ? [{ debugName: "listComponents" }] : []));
17
+ this.listPlugins = signal(new Array(), ...(ngDevMode ? [{ debugName: "listPlugins" }] : []));
18
+ }
19
+ /**
20
+ * The component can manage any standard javascript primitives types. That's usually the default whenever we don't know any particular type
21
+ * string
22
+ * number
23
+ * bigint
24
+ * boolean
25
+ * undefined
26
+ * null
27
+ * symbol is not managed
28
+ * Date, while an object and not a primitive, is managed
29
+ */
30
+ static { this.ANY_PRIMITIVE_TYPE = "ANY_PRIMITIVE_TYPE"; }
31
+ /**
32
+ * The components can manage any composite javascript type. Default when no type has been defined and it's a user defined javascript object (not a data type)
33
+ */
34
+ static { this.ANY_OBJECT_TYPE = "ANY_OBJECT_TYPE"; }
35
+ static { this.ANY_PRIMITIVE_SET = "ANY_PRIMITIVE_SET"; }
36
+ static { this.ANY_OBJECT_SET = "ANY_OBJECT_SET"; }
37
+ /**
38
+ * Whenever a component can handle any type of reference to a single entity or to multiple entities.
39
+ */
40
+ static { this.ANY_SINGLE_REFERENCE = "ANY_SINGLE_REFERENCE"; }
41
+ static { this.ANY_MULTIPLE_REFERENCE = "ANY_MULTIPLE_REFERENCE"; }
42
+ registerPlugin(info) {
43
+ this.pluginRegistry.set(info.name, info);
44
+ if (info.components != null) {
45
+ let updated = false;
46
+ for (const comp of info.components) {
47
+ updated = true;
48
+ this.registerComponent(comp);
49
+ }
50
+ if (updated)
51
+ this.componentByTypeCache.clear(); // Force recalculation of type
52
+ }
53
+ if (info.actionHandlers != null) {
54
+ for (const handler of info.actionHandlers) {
55
+ this.registerActionHandler(handler);
56
+ }
57
+ }
58
+ this.listPlugins.update((array) => {
59
+ let found = false;
60
+ for (let i = 0; i < array.length; i++) {
61
+ if (array[i].name == info.name) {
62
+ found = true;
63
+ array[i] = info;
64
+ }
65
+ }
66
+ if (!found)
67
+ array.push(info);
68
+ return [...array]; // You have to send another value, not just update the existing one.
69
+ });
70
+ }
71
+ registerComponent(info) {
72
+ this.componentRegistry.set(info.componentName, info);
73
+ this.listComponents.update((array) => {
74
+ let found = false;
75
+ for (let i = 0; i < array.length; i++) {
76
+ if (array[i].componentName == info.componentName) {
77
+ found = true;
78
+ array[i] = info;
79
+ }
80
+ }
81
+ if (!found)
82
+ array.push(info);
83
+ return array;
84
+ });
85
+ }
86
+ findComponentsForType(valueType, value) {
87
+ let originalType = valueType;
88
+ //console.debug('Finding type from '+valueType+' with value ',value);
89
+ // We don't know the value type, let's try to guess if it's a primitive or object based on the value
90
+ if (valueType == null) {
91
+ valueType = XtPluginRegistry.ANY_OBJECT_TYPE;
92
+ if ((value == null) || (typeof value != 'object')) {
93
+ valueType = XtPluginRegistry.ANY_PRIMITIVE_TYPE;
94
+ }
95
+ else if (value instanceof Date) {
96
+ valueType = XtPluginRegistry.ANY_PRIMITIVE_TYPE;
97
+ }
98
+ if (Array.isArray(value)) {
99
+ valueType = (valueType === XtPluginRegistry.ANY_PRIMITIVE_TYPE) ? XtPluginRegistry.ANY_PRIMITIVE_SET : XtPluginRegistry.ANY_OBJECT_SET;
100
+ }
101
+ }
102
+ else { // originalType has been defined.
103
+ if (Array.isArray(value)) {
104
+ valueType = valueType.endsWith('[]') ? valueType : valueType + '[]';
105
+ originalType = valueType;
106
+ }
107
+ }
108
+ //console.debug('Type found is '+valueType);
109
+ let ret = this.componentByTypeCache.get(valueType);
110
+ if (ret == null) {
111
+ ret = new Array();
112
+ for (const comp of this.componentRegistry) {
113
+ const info = comp[1];
114
+ if (info.typesHandled.includes(valueType)) {
115
+ ret.push(info);
116
+ }
117
+ }
118
+ if ((ret.length == 0) && (originalType != null)) {
119
+ // Couldn't find a specific component, let's try the generic ones, so we don't pass any type
120
+ ret = this.findComponentsForType(null, value);
121
+ // Cache the component only if we were able to assert its type.
122
+ // If no type has been given and value is null, then we cannot assess the real type
123
+ if (value != null) {
124
+ this.componentByTypeCache.set(originalType, ret);
125
+ }
126
+ }
127
+ else {
128
+ // Cache the component only if we were able to assert its type.
129
+ // If no type has been given and value is null, then we cannot assess the real type
130
+ if ((value != null) || (originalType != null)) {
131
+ this.componentByTypeCache.set(originalType ?? valueType, ret);
132
+ }
133
+ }
134
+ }
135
+ return ret;
136
+ }
137
+ static registry() {
138
+ return XT_REGISTRY;
139
+ }
140
+ findComponentInfo(type) {
141
+ // Search for the component registered with this class
142
+ for (const info of this.componentRegistry.values()) {
143
+ if (info.componentClass == type) {
144
+ return info;
145
+ }
146
+ }
147
+ return null;
148
+ }
149
+ getComponentInfo(type) {
150
+ const ret = this.findComponentInfo(type);
151
+ if (ret == null) {
152
+ throw new Error("No component found with class " + type);
153
+ }
154
+ return ret;
155
+ }
156
+ registerActionHandler(handlerInfo) {
157
+ for (const type of handlerInfo.types) {
158
+ const handlers = handlerInfo.actions;
159
+ for (const actionName of Object.keys(handlers)) {
160
+ let exist = this.actionByTypeRegistry.get(type);
161
+ if (exist == null) {
162
+ exist = new Map();
163
+ this.actionByTypeRegistry.set(type, exist);
164
+ }
165
+ exist.set(actionName, handlers[actionName]);
166
+ }
167
+ }
168
+ }
169
+ findActionInfo(type, actionName) {
170
+ const handlers = this.actionByTypeRegistry.get(type);
171
+ if (handlers != null) {
172
+ return handlers.get(actionName);
173
+ }
174
+ return undefined;
175
+ }
176
+ listActionInfos(type) {
177
+ const handlers = this.actionByTypeRegistry.get(type);
178
+ if (handlers != null) {
179
+ return Array.from(handlers.entries()).map(([name, info]) => {
180
+ return { name: name, info: info };
181
+ });
182
+ }
183
+ else
184
+ return [];
185
+ }
186
+ }
187
+
9
188
  class XtBaseContext {
10
189
  /**
11
190
  *
@@ -16,6 +195,16 @@ class XtBaseContext {
16
195
  */
17
196
  constructor(displayMode, subName, parentGroup, parentContext) {
18
197
  this.displayMode = 'FULL_VIEW';
198
+ /**
199
+ * If it's a reference, we keep the context referenced
200
+ *
201
+ referencedContext?:XtContext<any>;*/
202
+ //subReferencesResolved = signal(false);
203
+ /**
204
+ * Keeps track of all the possible actions for this context
205
+ * @protected
206
+ */
207
+ this.listActions = signal(null, ...(ngDevMode ? [{ debugName: "listActions" }] : []));
19
208
  this.displayValue = computed(() => {
20
209
  if (this.nonFormValue !== undefined) {
21
210
  return this.nonFormValue();
@@ -28,6 +217,13 @@ class XtBaseContext {
28
217
  this.parentFormGroup = parentGroup;
29
218
  this.parentContext = parentContext;
30
219
  this.subName = subName;
220
+ if ((parentGroup != null) && (subName != null)) {
221
+ const subControl = parentGroup.get(subName);
222
+ // If it's a form group, then it should be set as localFormGroup
223
+ if (subControl?.controls != null) {
224
+ this.localFormGroup = subControl;
225
+ }
226
+ }
31
227
  }
32
228
  setDisplayValue(newValue, type, updateParent = true) {
33
229
  if (newValue !== undefined) {
@@ -155,11 +351,18 @@ class XtBaseContext {
155
351
  if (!Array.isArray(this.value())) {
156
352
  throw new Error("The value must be an Array / Set to create a subElement context.");
157
353
  }
158
- const ret = new XtBaseContext(this.displayMode, undefined, undefined, this);
159
- ret.setDisplayValue(value[elementIndex]);
160
- if (this.valueType != null) {
161
- // Convert potential array type into single type
162
- ret.valueType = this.valueType.endsWith('[]') ? this.valueType.substring(0, this.valueType.length - 2) : this.valueType;
354
+ const indexKey = elementIndex.toString();
355
+ let ret = this.childContexts?.get(indexKey);
356
+ if (ret == null) {
357
+ ret = new XtBaseContext(this.displayMode, undefined, undefined, this);
358
+ ret.setDisplayValue(value[elementIndex]);
359
+ if (this.valueType != null) {
360
+ // Convert potential array type into single type
361
+ ret.valueType = this.valueType.endsWith('[]') ? this.valueType.substring(0, this.valueType.length - 2) : this.valueType;
362
+ }
363
+ if (this.childContexts == null)
364
+ this.childContexts = new Map();
365
+ this.childContexts?.set(indexKey, ret);
163
366
  }
164
367
  return ret;
165
368
  }
@@ -172,9 +375,9 @@ class XtBaseContext {
172
375
  }
173
376
  else {
174
377
  let subValue = null;
175
- let parentGroup = this.formGroup();
378
+ let currentGroup = this.formGroup();
176
379
  // Recalculate parentGroup and formControlName and value if needed.
177
- if (parentGroup == null) {
380
+ if (currentGroup == null) {
178
381
  let curValue = this.nonFormValue;
179
382
  if (curValue != null) {
180
383
  if (curValue() != null) {
@@ -185,14 +388,32 @@ class XtBaseContext {
185
388
  subValue = signal(null);
186
389
  }
187
390
  }
188
- const ret = new XtBaseContext(this.displayMode, subName, parentGroup, this);
391
+ const ret = new XtBaseContext(this.displayMode, subName, currentGroup, this);
189
392
  if (subValue != null)
190
393
  ret.nonFormValue = subValue;
191
394
  if (subType != null) {
192
395
  ret.valueType = subType;
193
396
  }
194
397
  else if ((this.valueType != null) && (typeResolver != null)) {
195
- ret.valueType = typeResolver.findTypeName(this.valueType, subName, this.value()) ?? undefined;
398
+ const subType = typeResolver.findType(this.valueType, subName, this.value());
399
+ if (subType != null) {
400
+ if (isTypeReference(subType)) {
401
+ if (subType.type == XtBaseTypeReference.UNRESOLVED_TYPE)
402
+ throw new Error("You must resolve all reference types before using them in a context. Missing type " + subType.type + " for subName " + subName + " in valueType " + this.valueType + " of context " + this.toString());
403
+ ret.valueType = subType.toType;
404
+ ret.reference = subType;
405
+ if (this.displayMode == 'LIST_VIEW')
406
+ ret.displayMode = 'INLINE_VIEW'; // We display a reference as inline in a list
407
+ else if (this.displayMode == 'FULL_EDITABLE') {
408
+ // We don't edit directly references, we simply enable selection of them.
409
+ ret.valueType = (subType.referenceType == 'ONE-TO-MANY') ? XtPluginRegistry.ANY_MULTIPLE_REFERENCE : XtPluginRegistry.ANY_SINGLE_REFERENCE;
410
+ }
411
+ }
412
+ else {
413
+ ret.valueType = subType.type;
414
+ }
415
+ }
416
+ //ret.valueType=typeResolver.findTypeName(this.valueType, subName, this.value())??undefined;
196
417
  }
197
418
  if (this.childContexts == null)
198
419
  this.childContexts = new Map();
@@ -203,6 +424,28 @@ class XtBaseContext {
203
424
  formGroup() {
204
425
  return this.localFormGroup ?? this.parentFormGroup;
205
426
  }
427
+ isReference() {
428
+ return (this.reference != null);
429
+ }
430
+ setReferenceInfo(reference) {
431
+ this.reference = reference;
432
+ //this.subReferencesResolved.set(this.reference!=null);
433
+ }
434
+ /**
435
+ * creates the referencedContext by using this referenced value
436
+ * @param val
437
+ *
438
+ updateReferencedContext(val: any, valueType?:string): void {
439
+ if (!this.isReference()) throw new Error ('This context '+this.toString()+' is not a reference.');
440
+
441
+ if( this.referencedContext==null) {
442
+ let refDisplayMode = 'INLINE_VIEW' as XtDisplayMode;
443
+ if (this.displayMode=='FULL_VIEW') refDisplayMode = 'FULL_VIEW';
444
+ this.referencedContext = new XtBaseContext(refDisplayMode);
445
+ }
446
+ this.referencedContext.setDisplayValue(val);
447
+ if( valueType!=null) this.referencedContext.valueType=valueType;
448
+ }*/
206
449
  toString() {
207
450
  let ret = 'XtContext named ';
208
451
  ret += this.subName ?? 'None';
@@ -210,6 +453,10 @@ class XtBaseContext {
210
453
  ret += this.valueType ?? 'None';
211
454
  ret += ' with value ';
212
455
  ret += this.nonFormValue ? this.nonFormValue() : this.formControlValue();
456
+ if (this.isReference()) {
457
+ ret += ' referencing ';
458
+ ret += this.reference?.type;
459
+ }
213
460
  return ret;
214
461
  }
215
462
  }
@@ -229,181 +476,227 @@ class XtResolvedComponent {
229
476
  }
230
477
  }
231
478
 
232
- class XtPluginRegistry {
233
- constructor() {
234
- this.pluginRegistry = new Map();
235
- this.componentRegistry = new Map();
236
- this.componentByTypeCache = new Map();
237
- this.listComponents = signal(new Array(), ...(ngDevMode ? [{ debugName: "listComponents" }] : []));
238
- this.listPlugins = signal(new Array(), ...(ngDevMode ? [{ debugName: "listPlugins" }] : []));
479
+ /**
480
+ * The global plugin registry.
481
+ * Plugins will register to this when loaded.
482
+ */
483
+ function initXtPluginRegistry() {
484
+ if (globalThis.XT_REGISTRY == null) {
485
+ globalThis.XT_REGISTRY = new XtPluginRegistry();
239
486
  }
240
- /**
241
- * The component can manage any standard javascript primitives types. That's usually the default whenever we don't know any particular type
242
- * string
243
- * number
244
- * bigint
245
- * boolean
246
- * undefined
247
- * null
248
- * symbol is not managed
249
- * Date, while an object and not a primitive, is managed
250
- */
251
- static { this.ANY_PRIMITIVE_TYPE = "ANY_PRIMITIVE_TYPE"; }
252
- /**
253
- * The components can manage any composite javascript type. Default when no type has been defined and it's a user defined javascript object (not a data type)
254
- */
255
- static { this.ANY_OBJECT_TYPE = "ANY_OBJECT_TYPE"; }
256
- static { this.ANY_PRIMITIVE_SET = "ANY_PRIMITIVE_SET"; }
257
- static { this.ANY_OBJECT_SET = "ANY_OBJECT_SET"; }
258
- registerPlugin(info) {
259
- this.pluginRegistry.set(info.name, info);
260
- if (info.components != null) {
261
- let updated = false;
262
- for (const comp of info.components) {
263
- updated = true;
264
- this.registerComponent(comp);
265
- }
266
- if (updated)
267
- this.componentByTypeCache.clear(); // Force recalculation of type
268
- }
269
- this.listPlugins.update((array) => {
270
- let found = false;
271
- for (let i = 0; i < array.length; i++) {
272
- if (array[i].name == info.name) {
273
- found = true;
274
- array[i] = info;
275
- }
276
- }
277
- if (!found)
278
- array.push(info);
279
- return [...array]; // You have to send another value, not just update the existing one.
280
- });
487
+ }
488
+ function xtPluginRegistry() {
489
+ if (globalThis.XT_REGISTRY == null) {
490
+ initXtPluginRegistry();
281
491
  }
282
- registerComponent(info) {
283
- this.componentRegistry.set(info.componentName, info);
284
- this.listComponents.update((array) => {
285
- let found = false;
286
- for (let i = 0; i < array.length; i++) {
287
- if (array[i].componentName == info.componentName) {
288
- found = true;
289
- array[i] = info;
290
- }
291
- }
292
- if (!found)
293
- array.push(info);
294
- return array;
295
- });
492
+ return globalThis.XT_REGISTRY;
493
+ }
494
+
495
+ const XT_RESOLVER_TOKEN = new InjectionToken('Enable providing a custom component resolver.');
496
+ const XT_TYPE_RESOLVER_TOKEN = new InjectionToken('Enable providing a custom type resolver.');
497
+ const XT_REGISTRY_TOKEN = new InjectionToken("Injects the Plugin Registry right into your angular component", {
498
+ factory: () => {
499
+ return xtPluginRegistry();
296
500
  }
297
- findComponentsForType(valueType, value) {
298
- let originalType = valueType;
299
- //console.debug('Finding type from '+valueType+' with value ',value);
300
- // We don't know the value type, let's try to guess if it's a primitive or object based on the value
301
- if (valueType == null) {
302
- valueType = XtPluginRegistry.ANY_OBJECT_TYPE;
303
- if ((value == null) || (typeof value != 'object')) {
304
- valueType = XtPluginRegistry.ANY_PRIMITIVE_TYPE;
305
- }
306
- else if (value instanceof Date) {
307
- valueType = XtPluginRegistry.ANY_PRIMITIVE_TYPE;
501
+ });
502
+
503
+ class XtRegistryResolver {
504
+ constructor(registry, typeResolver) {
505
+ this.registry = registry;
506
+ this.typeResolver = typeResolver;
507
+ }
508
+ resolve(baseContext, subName) {
509
+ let typeToFind = baseContext.valueType;
510
+ const typeInfo = this.typeResolver.findType(baseContext.valueType, subName);
511
+ // If it's a type reference, we find the component of the referenced type
512
+ if (isTypeReference(typeInfo)) {
513
+ if (baseContext.displayMode == 'FULL_EDITABLE') {
514
+ typeToFind = XtPluginRegistry.ANY_SINGLE_REFERENCE;
308
515
  }
309
- if (Array.isArray(value)) {
310
- valueType = (valueType === XtPluginRegistry.ANY_PRIMITIVE_TYPE) ? XtPluginRegistry.ANY_PRIMITIVE_SET : XtPluginRegistry.ANY_OBJECT_SET;
516
+ else {
517
+ typeToFind = typeInfo.toType;
311
518
  }
312
519
  }
313
- else { // originalType has been defined.
314
- if (Array.isArray(value)) {
315
- valueType = valueType.endsWith('[]') ? valueType : valueType + '[]';
316
- originalType = valueType;
317
- }
520
+ const ret = this.registry.findComponentsForType(typeToFind, baseContext.subValue(subName));
521
+ if (ret != null && ret.length > 0) {
522
+ return XtResolvedComponent.from(ret[0]);
318
523
  }
319
- //console.debug('Type found is '+valueType);
320
- let ret = this.componentByTypeCache.get(valueType);
321
- if (ret == null) {
322
- ret = new Array();
323
- for (const comp of this.componentRegistry) {
324
- const info = comp[1];
325
- if (info.typesHandled.includes(valueType)) {
326
- ret.push(info);
327
- }
328
- }
329
- if ((ret.length == 0) && (originalType != null)) {
330
- // Couldn't find a specific component, let's try the generic ones, so we don't pass any type
331
- ret = this.findComponentsForType(null, value);
332
- // Cache the component only if we were able to assert its type.
333
- // If no type has been given and value is null, then we cannot assess the real type
334
- if (value != null) {
335
- this.componentByTypeCache.set(originalType, ret);
336
- }
337
- }
338
- else {
339
- // Cache the component only if we were able to assert its type.
340
- // If no type has been given and value is null, then we cannot assess the real type
341
- if ((value != null) || (originalType != null)) {
342
- this.componentByTypeCache.set(originalType ?? valueType, ret);
343
- }
344
- }
524
+ return null;
525
+ }
526
+ }
527
+
528
+ class XtAction {
529
+ constructor(name, info, enabled) {
530
+ this.enabled = signal(false, ...(ngDevMode ? [{ debugName: "enabled" }] : []));
531
+ this.name = name;
532
+ this.info = info;
533
+ if (enabled != null) {
534
+ this.enabled.set(enabled);
535
+ }
536
+ }
537
+ }
538
+
539
+ /**
540
+ * A very light and not 100% compatible storemanager in case you are not using xt-store.
541
+ * It can emulate XtStoreManager to some extends for doing some tests
542
+ */
543
+ class StoreTestHelper {
544
+ static ensureTestProviderOnly() {
545
+ StoreSupport.setTestStoreManager(new TestStoreManager());
546
+ }
547
+ }
548
+ class TestStoreManager {
549
+ constructor() {
550
+ this.defaultProvider = new TestStoreProvider();
551
+ }
552
+ getProvider(name) {
553
+ return this.defaultProvider;
554
+ }
555
+ getProviderSafe(name) {
556
+ return this.defaultProvider;
557
+ }
558
+ getDefaultProvider() {
559
+ return this.defaultProvider;
560
+ }
561
+ getDefaultProviderSafe() {
562
+ return this.defaultProvider;
563
+ }
564
+ newStoreCriteria(name, value, operator) {
565
+ return new TestStoreCriteria(name, value, operator);
566
+ }
567
+ }
568
+ class TestStoreProvider {
569
+ constructor() {
570
+ this.data = new Map();
571
+ }
572
+ getOrCreateArray(name) {
573
+ let ret = this.data.get(name);
574
+ if (ret == null) {
575
+ ret = new Map();
576
+ this.data.set(name, ret);
345
577
  }
346
578
  return ret;
347
579
  }
348
- static registry() {
349
- return XT_REGISTRY;
350
- }
351
- findComponentInfo(type) {
352
- // Search for the component registered with this class
353
- for (const info of this.componentRegistry.values()) {
354
- if (info.componentClass == type) {
355
- return info;
580
+ extractKey(value, create) {
581
+ if (value._id != null)
582
+ return value._id; // ManagedData key
583
+ else if (value.id != null)
584
+ return value.id;
585
+ else {
586
+ if (create === true) {
587
+ const newId = Math.random().toString(36).substring(2, 8);
588
+ value._id = newId;
589
+ return newId;
356
590
  }
591
+ return value.toString();
357
592
  }
358
- return null;
359
593
  }
360
- getComponentInfo(type) {
361
- const ret = this.findComponentInfo(type);
594
+ storeEntity(name, entity) {
595
+ this.getOrCreateArray(name).set(this.extractKey(entity, true), entity);
596
+ return Promise.resolve(entity);
597
+ }
598
+ safeLoadEntity(name, key) {
599
+ const ret = this.getOrCreateArray(name).get(key);
362
600
  if (ret == null) {
363
- throw new Error("No component found with class " + type);
601
+ throw new Error("No entity named " + name + " with key " + key);
364
602
  }
365
- return ret;
603
+ return Promise.resolve(ret);
604
+ }
605
+ loadEntity(name, key) {
606
+ return Promise.resolve(this.getOrCreateArray(name).get(key));
607
+ }
608
+ deleteEntity(name, key) {
609
+ return Promise.resolve(this.getOrCreateArray(name).delete(key));
610
+ }
611
+ searchEntities(name, ...criteria) {
612
+ // No criteria defined, just send the full list
613
+ const ret = new Array();
614
+ if ((criteria == null) || (criteria.length == 0)) {
615
+ for (const toAdd of this.getOrCreateArray(name).values()) {
616
+ ret.push(toAdd);
617
+ }
618
+ }
619
+ else {
620
+ for (const toAdd of this.getOrCreateArray(name).values()) {
621
+ let canAdd = true;
622
+ for (const criter of criteria) {
623
+ if (!criter.filter(toAdd)) {
624
+ canAdd = false;
625
+ break;
626
+ }
627
+ }
628
+ if (canAdd)
629
+ ret.push(toAdd);
630
+ }
631
+ }
632
+ return from([ret]);
633
+ }
634
+ searchAndPrepareEntities(name, sort, groupBy, transformer, ...criteria) {
635
+ throw new Error('Method not implemented.');
636
+ }
637
+ canStoreDocument() {
638
+ return true;
639
+ }
640
+ storeDocument(toStore) {
641
+ const ret = new TestDocumentInfo(toStore.name, true, URL.createObjectURL(toStore));
642
+ return Promise.resolve(ret);
643
+ }
644
+ storeDocuments(toStore) {
645
+ throw new Error('Method not implemented.');
366
646
  }
367
647
  }
368
-
369
- /**
370
- * The global plugin registry.
371
- * Plugins will register to this when loaded.
372
- */
373
- function initXtPluginRegistry() {
374
- if (globalThis.XT_REGISTRY == null) {
375
- globalThis.XT_REGISTRY = new XtPluginRegistry();
648
+ class TestDocumentInfo {
649
+ constructor(documentName, isUrl, documentId) {
650
+ this.documentId = documentId;
651
+ this.documentName = documentName;
652
+ this.isUrl = isUrl;
376
653
  }
377
654
  }
378
- function xtPluginRegistry() {
379
- if (globalThis.XT_REGISTRY == null) {
380
- initXtPluginRegistry();
655
+ class TestStoreCriteria {
656
+ constructor(name, value, operator) {
657
+ this.name = name;
658
+ this.value = value;
659
+ if (!operator)
660
+ this.operator = '=';
661
+ else {
662
+ this.operator = operator;
663
+ }
664
+ }
665
+ filter(toFilter) {
666
+ const testValue = toFilter[this.name];
667
+ switch (this.operator) {
668
+ case '=':
669
+ return testValue == this.value;
670
+ case '<':
671
+ return testValue < this.value;
672
+ case '<=':
673
+ return testValue < this.value;
674
+ default:
675
+ return true;
676
+ }
381
677
  }
382
- return globalThis.XT_REGISTRY;
383
678
  }
384
679
 
385
- const XT_RESOLVER_TOKEN = new InjectionToken('Enable providing a custom component resolver.');
386
- const XT_TYPE_RESOLVER_TOKEN = new InjectionToken('Enable providing a custom type resolver.');
387
- const XT_REGISTRY_TOKEN = new InjectionToken("Injects the Plugin Registry right into your angular component", {
388
- factory: () => {
389
- return xtPluginRegistry();
680
+ class StoreSupport {
681
+ static isStoreManagerAvailable() {
682
+ if (this.testStoreManager != null)
683
+ return true;
684
+ return (globalThis.xtStoreManager != undefined);
390
685
  }
391
- });
392
-
393
- class XtRegistryResolver {
394
- constructor(registry, typeResolver) {
395
- this.registry = registry;
396
- this.typeResolver = typeResolver;
686
+ static getStoreManager() {
687
+ return this.testStoreManager ?? (globalThis.xtStoreManager());
397
688
  }
398
- resolve(baseContext, subName) {
399
- const ret = this.registry.findComponentsForType(this.typeResolver.findTypeName(baseContext.valueType, subName), baseContext.subValue(subName));
400
- if (ret != null && ret.length > 0) {
401
- return XtResolvedComponent.from(ret[0]);
402
- }
403
- return null;
689
+ static setTestStoreManager(testStoreManager) {
690
+ StoreSupport.testStoreManager = testStoreManager;
691
+ }
692
+ static newStoreCriteria(name, value, operator) {
693
+ return new TestStoreCriteria(name, value, operator);
404
694
  }
405
695
  }
406
696
 
697
+ /**
698
+ * An all in one helper class, enabling manipulation of the context, with data and type associated with it.
699
+ */
407
700
  class XtResolverService {
408
701
  constructor() {
409
702
  this.pluginRegistry = inject(XT_REGISTRY_TOKEN);
@@ -438,7 +731,13 @@ class XtResolverService {
438
731
  return ret;
439
732
  }
440
733
  findTypeHandlerOf(baseContext, subName, value) {
441
- const ret = this.typeResolver.findTypeHandler(baseContext.valueType, subName, value);
734
+ let ret = { typeName: undefined, handler: undefined };
735
+ if (baseContext.isReference()) {
736
+ ret = this.typeResolver.findTypeHandler(baseContext.reference.toType, false, undefined, value);
737
+ }
738
+ else {
739
+ ret = this.typeResolver.findTypeHandler(baseContext.valueType, false, subName, value);
740
+ }
442
741
  return ret;
443
742
  }
444
743
  listSubNamesOf(baseContext, value) {
@@ -462,6 +761,54 @@ class XtResolverService {
462
761
  }
463
762
  }
464
763
  }
764
+ /**
765
+ * Calculates all the possible actions for a given context
766
+ * @param context
767
+ * @param onlyVisible
768
+ */
769
+ possibleActions(context, onlyVisible = true) {
770
+ const existingActions = context.listActions();
771
+ if (existingActions != null) {
772
+ return existingActions;
773
+ }
774
+ if (context.valueType != null) {
775
+ const actionInfos = this.pluginRegistry.listActionInfos(context.valueType);
776
+ const actions = actionInfos.map((info) => {
777
+ const ret = new XtAction(info.name, info.info, true);
778
+ return ret;
779
+ });
780
+ context.listActions.set(actions);
781
+ return actions;
782
+ }
783
+ return [];
784
+ }
785
+ /**
786
+ * Finds the possible action with the given name for the current type, and runs it in the current value.
787
+ * If the action is not possible in this context, try a parent context
788
+ * @param actionName
789
+ */
790
+ async runAction(context, actionName, storeMgr) {
791
+ let handler = null;
792
+ for (const action of this.possibleActions(context, false)) {
793
+ if (action.name == actionName) {
794
+ const handlerClass = action.info.handlerClass;
795
+ handler = new handlerClass();
796
+ break;
797
+ }
798
+ }
799
+ if (handler != null) {
800
+ return handler.runAction(context, actionName, this, storeMgr);
801
+ }
802
+ else {
803
+ // Couldn't find the handler, let's see if we can have that up the context chain
804
+ if (context.parentContext != null) {
805
+ return this.runAction(context.parentContext, actionName); // Run the parent without any store indication, as it most probably is different
806
+ }
807
+ else {
808
+ return Promise.reject("Cannot find action " + actionName + " for context " + this.toString());
809
+ }
810
+ }
811
+ }
465
812
  handlerDefinedFor(newType, handlers) {
466
813
  for (const handler of handlers ?? []) {
467
814
  if (handler.typesHandled.includes(newType)) {
@@ -503,10 +850,88 @@ class XtResolverService {
503
850
  return module;
504
851
  });
505
852
  }
506
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: XtResolverService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
507
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: XtResolverService, providedIn: 'root' }); }
853
+ /**
854
+ * Based on the type & value of the element, find which property is on its type and returns it's value
855
+ * @param context
856
+ * @param subPropertyType
857
+ * @param value
858
+ */
859
+ findSubPropertyWithType(context, subPropertyType, value) {
860
+ const subKeys = this.typeResolver.findSubPropertiesWithType(context.valueType, subPropertyType);
861
+ if ((subKeys != null) && (subKeys.length == 1)) {
862
+ return value[subKeys[0]];
863
+ }
864
+ else if (subKeys.length > 1) {
865
+ // Let's pickup the first
866
+ return value[subKeys[0]];
867
+ }
868
+ else {
869
+ return undefined;
870
+ }
871
+ }
872
+ /**
873
+ * Creates a duplicate of an object, using our knowledge on its type given by the context
874
+ * @param context
875
+ * @param value
876
+ */
877
+ safeDuplicate(context, value) {
878
+ const typeHandler = this.typeResolver.findTypeHandler(context.valueType, false, undefined, value);
879
+ if (typeHandler.handler != null) {
880
+ return typeHandler.handler.safeDuplicate(value);
881
+ }
882
+ return structuredClone(value);
883
+ }
884
+ resolveMappingOf(context, targetType, value) {
885
+ if (context.valueType != null) {
886
+ const typeHandler = this.typeResolver.findTypeHandler(targetType, false, undefined, value);
887
+ if (typeHandler.handler != null) {
888
+ const ret = typeHandler.handler.getOrCreateMappingFrom(context.valueType, this.typeResolver);
889
+ if (ret != null) {
890
+ return ret;
891
+ }
892
+ }
893
+ }
894
+ return undefined;
895
+ }
896
+ async resolveReferencedValue(context, storeMgr) {
897
+ if (!context.isReference())
898
+ return undefined;
899
+ const ref = context.reference;
900
+ const storeProvider = storeMgr.getProvider(ref.type);
901
+ if (storeProvider == null) {
902
+ throw new Error('No Store provider found for type ' + ref.type);
903
+ }
904
+ const ret = await firstValueFrom(storeProvider.searchEntities(ref.toType, storeMgr.newStoreCriteria(ref.field, context.value(), '=')));
905
+ if (ret.length == 0)
906
+ return null;
907
+ if (ref.referenceType == 'MANY-TO-ONE') {
908
+ if (ret.length > 1)
909
+ throw new Error('Multiple values for many to one relation between ' + context.valueType + ' and ' + ref.type + ' with value ' + context.value());
910
+ return ret[0];
911
+ }
912
+ else if (ref.referenceType == 'ONE-TO-MANY') {
913
+ return ret;
914
+ }
915
+ return undefined;
916
+ }
917
+ resolvePendingReferences() {
918
+ this.typeResolver.resolveAllTypeReferences();
919
+ }
920
+ /**
921
+ * Calculates the values that can be referenced by the reference & value of this context
922
+ * @param context
923
+ */
924
+ findPossibleReferences(context) {
925
+ if (!context.isReference())
926
+ throw new Error('Cannot find possible references of this non reference context' + context.toString());
927
+ const reference = context.reference;
928
+ const store = StoreSupport.getStoreManager().getProviderSafe(reference.toType);
929
+ return store.searchEntities(reference.toType);
930
+ }
931
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtResolverService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
932
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtResolverService, providedIn: 'root' }); }
508
933
  }
509
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: XtResolverService, decorators: [{
934
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtResolverService, decorators: [{
510
935
  type: Injectable,
511
936
  args: [{
512
937
  providedIn: 'root'
@@ -540,6 +965,10 @@ class XtRenderComponent {
540
965
  let form = this.formGroup();
541
966
  const ret = new XtBaseContext(this.displayMode(), this.subName(), form);
542
967
  ret.valueType = this.valueType();
968
+ const typeInfo = this.resolverService.typeResolver.findType(ret.valueType);
969
+ if (isTypeReference(typeInfo)) {
970
+ ret.setReferenceInfo(typeInfo);
971
+ }
543
972
  if (!ret.isInForm()) {
544
973
  const subName = this.subName();
545
974
  const value = this.value();
@@ -552,6 +981,13 @@ class XtRenderComponent {
552
981
  }
553
982
  return ret;
554
983
  }, ...(ngDevMode ? [{ debugName: "context" }] : []));
984
+ this.realContext = computed(() => {
985
+ let ret = this.context();
986
+ /*if ((ret.isReference())&& (ret.referencedContext!=null)) {
987
+ ret = ret.referencedContext;
988
+ }*/
989
+ return ret;
990
+ }, ...(ngDevMode ? [{ debugName: "realContext" }] : []));
555
991
  this.type = computed(() => {
556
992
  //console.debug("Calculating type in XtRenderSubComponent");
557
993
  let type = this.componentType();
@@ -560,7 +996,7 @@ class XtRenderComponent {
560
996
  //console.debug('XtRender, using component set '+ type);
561
997
  //compFound = this.resolverService.findComponentInfo (type);
562
998
  //} else {
563
- compFound = this.resolverService.findBestComponent(this.context());
999
+ compFound = this.resolverService.findBestComponent(this.realContext());
564
1000
  //console.debug('XtRender, found component ',compFound.componentName);
565
1001
  type = compFound.componentClass;
566
1002
  }
@@ -589,16 +1025,16 @@ class XtRenderComponent {
589
1025
  }
590
1026
  }
591
1027
  }
592
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: XtRenderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
593
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.2.3", type: XtRenderComponent, isStandalone: true, selector: "xt-render", inputs: { componentType: { classPropertyName: "componentType", publicName: "componentType", isSignal: true, isRequired: false, transformFunction: null }, displayMode: { classPropertyName: "displayMode", publicName: "displayMode", isSignal: true, isRequired: true, transformFunction: null }, valueType: { classPropertyName: "valueType", publicName: "valueType", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: false, transformFunction: null }, subName: { classPropertyName: "subName", publicName: "subName", isSignal: true, isRequired: false, transformFunction: null }, inputs: { classPropertyName: "inputs", publicName: "inputs", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", outputs: "outputs" }, viewQueries: [{ propertyName: "outlet", first: true, predicate: NgComponentOutlet, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *ngComponentOutlet=\"type(); inputs: {context:context ()}\" />\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: ReactiveFormsModule }] }); }
1028
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtRenderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1029
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.9", type: XtRenderComponent, isStandalone: true, selector: "xt-render", inputs: { componentType: { classPropertyName: "componentType", publicName: "componentType", isSignal: true, isRequired: false, transformFunction: null }, displayMode: { classPropertyName: "displayMode", publicName: "displayMode", isSignal: true, isRequired: true, transformFunction: null }, valueType: { classPropertyName: "valueType", publicName: "valueType", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: false, transformFunction: null }, subName: { classPropertyName: "subName", publicName: "subName", isSignal: true, isRequired: false, transformFunction: null }, inputs: { classPropertyName: "inputs", publicName: "inputs", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", outputs: "outputs" }, viewQueries: [{ propertyName: "outlet", first: true, predicate: NgComponentOutlet, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *ngComponentOutlet=\"type(); inputs: {context:context ()}\" />\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: ReactiveFormsModule }] }); }
594
1030
  }
595
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: XtRenderComponent, decorators: [{
1031
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtRenderComponent, decorators: [{
596
1032
  type: Component,
597
1033
  args: [{ selector: 'xt-render', standalone: true, imports: [
598
1034
  NgComponentOutlet,
599
1035
  ReactiveFormsModule
600
1036
  ], template: "<ng-container *ngComponentOutlet=\"type(); inputs: {context:context ()}\" />\n" }]
601
- }], ctorParameters: () => [] });
1037
+ }], ctorParameters: () => [], propDecorators: { componentType: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentType", required: false }] }], displayMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayMode", required: true }] }], valueType: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueType", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], formGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "formGroup", required: false }] }], subName: [{ type: i0.Input, args: [{ isSignal: true, alias: "subName", required: false }] }], inputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputs", required: false }] }], outputs: [{ type: i0.Output, args: ["outputs"] }], outlet: [{ type: i0.ViewChild, args: [i0.forwardRef(() => NgComponentOutlet), { isSignal: true }] }] } });
602
1038
 
603
1039
  /**
604
1040
  * Dynamically render a component that will display the given subValue.
@@ -613,6 +1049,13 @@ class XtRenderSubComponent {
613
1049
  this.outputs = output();
614
1050
  this.outlet = viewChild.required(NgComponentOutlet);
615
1051
  this.resolverService = inject(XtResolverService);
1052
+ this.realContext = computed(() => {
1053
+ let ret = this.context();
1054
+ /*if ((ret.isReference()) && (ret.referencedContext!=null)) {
1055
+ ret = ret.referencedContext;
1056
+ }*/
1057
+ return ret;
1058
+ }, ...(ngDevMode ? [{ debugName: "realContext" }] : []));
616
1059
  this.type = computed(() => {
617
1060
  //console.debug("Calculating type in XtRenderSubComponent");
618
1061
  let type = this.componentType();
@@ -621,7 +1064,7 @@ class XtRenderSubComponent {
621
1064
  //console.debug('XtRender, using component set '+ type);
622
1065
  //compFound = this.resolverService.findComponentInfo (type);
623
1066
  //} else {
624
- compFound = this.resolverService.findBestComponent(this.context());
1067
+ compFound = this.resolverService.findBestComponent(this.realContext());
625
1068
  //console.debug('XtRender, found component ',compFound.componentName);
626
1069
  type = compFound.componentClass;
627
1070
  }
@@ -650,16 +1093,16 @@ class XtRenderSubComponent {
650
1093
  }
651
1094
  }
652
1095
  }
653
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: XtRenderSubComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
654
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.2.3", type: XtRenderSubComponent, isStandalone: true, selector: "xt-render-sub", inputs: { context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: true, transformFunction: null }, componentType: { classPropertyName: "componentType", publicName: "componentType", isSignal: true, isRequired: false, transformFunction: null }, inputs: { classPropertyName: "inputs", publicName: "inputs", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { outputs: "outputs" }, viewQueries: [{ propertyName: "outlet", first: true, predicate: NgComponentOutlet, descendants: true, isSignal: true }], ngImport: i0, template: "{{componentType()}}\n<ng-container *ngComponentOutlet=\"type(); inputs: {context:context ()}\" />\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: ReactiveFormsModule }] }); }
1096
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtRenderSubComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1097
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.9", type: XtRenderSubComponent, isStandalone: true, selector: "xt-render-sub", inputs: { context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: true, transformFunction: null }, componentType: { classPropertyName: "componentType", publicName: "componentType", isSignal: true, isRequired: false, transformFunction: null }, inputs: { classPropertyName: "inputs", publicName: "inputs", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { outputs: "outputs" }, viewQueries: [{ propertyName: "outlet", first: true, predicate: NgComponentOutlet, descendants: true, isSignal: true }], ngImport: i0, template: "{{componentType()}}\n<ng-container *ngComponentOutlet=\"type(); inputs: {context:realContext ()}\" />\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: ReactiveFormsModule }] }); }
655
1098
  }
656
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: XtRenderSubComponent, decorators: [{
1099
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtRenderSubComponent, decorators: [{
657
1100
  type: Component,
658
1101
  args: [{ selector: 'xt-render-sub', standalone: true, imports: [
659
1102
  NgComponentOutlet,
660
1103
  ReactiveFormsModule
661
- ], template: "{{componentType()}}\n<ng-container *ngComponentOutlet=\"type(); inputs: {context:context ()}\" />\n" }]
662
- }] });
1104
+ ], template: "{{componentType()}}\n<ng-container *ngComponentOutlet=\"type(); inputs: {context:realContext ()}\" />\n" }]
1105
+ }], propDecorators: { context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: true }] }], componentType: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentType", required: false }] }], inputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputs", required: false }] }], outputs: [{ type: i0.Output, args: ["outputs"] }], outlet: [{ type: i0.ViewChild, args: [i0.forwardRef(() => NgComponentOutlet), { isSignal: true }] }] } });
663
1106
 
664
1107
  class XtBaseInput {
665
1108
  }
@@ -756,17 +1199,17 @@ class XtSimpleComponent {
756
1199
  setupInputOutput() {
757
1200
  // Nothing to do here
758
1201
  }
759
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: XtSimpleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
760
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: XtSimpleComponent, isStandalone: true, selector: "ng-component", inputs: { context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { outputs: "outputs" }, ngImport: i0, template: '', isInline: true }); }
1202
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtSimpleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1203
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: XtSimpleComponent, isStandalone: true, selector: "ng-component", inputs: { context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { outputs: "outputs" }, ngImport: i0, template: '', isInline: true }); }
761
1204
  }
762
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: XtSimpleComponent, decorators: [{
1205
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtSimpleComponent, decorators: [{
763
1206
  type: Component,
764
1207
  args: [{
765
1208
  standalone: true,
766
1209
  imports: [],
767
1210
  template: ''
768
1211
  }]
769
- }], ctorParameters: () => [] });
1212
+ }], ctorParameters: () => [], propDecorators: { context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: true }] }], outputs: [{ type: i0.Output, args: ["outputs"] }] } });
770
1213
 
771
1214
  class XtCompositeComponent extends XtSimpleComponent {
772
1215
  constructor() {
@@ -808,45 +1251,31 @@ class XtCompositeComponent extends XtSimpleComponent {
808
1251
  this.formGroupIfAny(); // Ensure the context is properly initialized
809
1252
  return this.context().subContext(subName, subType, this.resolverService.typeResolver);
810
1253
  }
811
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: XtCompositeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
812
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: XtCompositeComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: '', isInline: true, styles: [""] }); }
1254
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtCompositeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1255
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: XtCompositeComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: '', isInline: true, styles: [""] }); }
813
1256
  }
814
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: XtCompositeComponent, decorators: [{
1257
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtCompositeComponent, decorators: [{
815
1258
  type: Component,
816
1259
  args: [{ standalone: true, imports: [], template: '' }]
817
1260
  }] });
818
1261
 
819
- class MessageHandler {
1262
+ class XtMessageHandler {
820
1263
  errorOccurred(error, errorMsg) {
821
1264
  console.error(errorMsg, error);
822
1265
  }
823
1266
  warningOccurred(warningMsg) {
824
1267
  console.warn(warningMsg);
825
1268
  }
826
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MessageHandler, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
827
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MessageHandler, providedIn: 'root' }); }
1269
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtMessageHandler, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1270
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtMessageHandler, providedIn: 'root' }); }
828
1271
  }
829
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MessageHandler, decorators: [{
1272
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: XtMessageHandler, decorators: [{
830
1273
  type: Injectable,
831
1274
  args: [{
832
1275
  providedIn: 'root'
833
1276
  }]
834
1277
  }] });
835
1278
 
836
- class StoreSupport {
837
- static isStoreManagerAvailable() {
838
- if (this.testStoreManager != null)
839
- return true;
840
- return (globalThis.xtStoreManager != undefined);
841
- }
842
- static getStoreManager() {
843
- return this.testStoreManager ?? (globalThis.xtStoreManager());
844
- }
845
- static setTestStoreManager(testStoreManager) {
846
- StoreSupport.testStoreManager = testStoreManager;
847
- }
848
- }
849
-
850
1279
  function attachToFormGroup(formGroup, controlName, value, valueType, resolver) {
851
1280
  // If it's a single value, just create the control
852
1281
  if (((value != null) && (isPrimitive(value))
@@ -872,13 +1301,14 @@ function updateFormGroupWithValue(formGroup, value, valueType, resolver) {
872
1301
  }
873
1302
  for (const valueKey of keySet) {
874
1303
  const subValue = (value != null) ? value[valueKey] : null;
875
- const subType = resolver?.findTypeName(valueType, valueKey, subValue) ?? undefined;
876
- const primitive = (subType != null) ? resolver?.isPrimitiveType(subType, subValue) : isPrimitive(subValue);
1304
+ const subType = resolver?.findType(valueType, valueKey, subValue) ?? undefined;
1305
+ const subTypeName = isTypeReference(subType) ? subType.toType : subType?.type;
1306
+ const primitive = resolver?.isPrimitiveType(subType, subValue);
877
1307
  if (toDelete.delete(valueKey)) {
878
1308
  // Already a control
879
1309
  const oldControl = formGroup.get(valueKey);
880
1310
  // Is it the right type ?
881
- if (primitive) {
1311
+ if ((primitive) || (isTypeReference(subType))) {
882
1312
  // Must be an FormControl2
883
1313
  if (oldControl.controls === undefined) {
884
1314
  // It's ok, just set the value
@@ -893,22 +1323,22 @@ function updateFormGroupWithValue(formGroup, value, valueType, resolver) {
893
1323
  if (oldControl.controls === undefined) {
894
1324
  const newFormGroup = new FormGroup({});
895
1325
  formGroup.setControl(valueKey, newFormGroup);
896
- updateFormGroupWithValue(newFormGroup, subValue, subType, resolver);
1326
+ updateFormGroupWithValue(newFormGroup, subValue, subTypeName, resolver);
897
1327
  }
898
1328
  else {
899
1329
  // It was already a formgroup, so just update it
900
- updateFormGroupWithValue(oldControl, subValue, subType, resolver);
1330
+ updateFormGroupWithValue(oldControl, subValue, subTypeName, resolver);
901
1331
  }
902
1332
  }
903
1333
  }
904
1334
  else {
905
- if (primitive) {
1335
+ if ((primitive) || (isTypeReference(subType))) {
906
1336
  formGroup.addControl(valueKey, new FormControl(subValue));
907
1337
  }
908
1338
  else {
909
1339
  const newFormGroup = new FormGroup({});
910
1340
  formGroup.addControl(valueKey, newFormGroup);
911
- updateFormGroupWithValue(newFormGroup, subValue, subType, resolver);
1341
+ updateFormGroupWithValue(newFormGroup, subValue, subTypeName, resolver);
912
1342
  }
913
1343
  }
914
1344
  }
@@ -931,10 +1361,10 @@ class HostTestSimpleComponent {
931
1361
  this.displayMode = input('FULL_VIEW', ...(ngDevMode ? [{ debugName: "displayMode" }] : []));
932
1362
  this.value = input(undefined, ...(ngDevMode ? [{ debugName: "value" }] : []));
933
1363
  }
934
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HostTestSimpleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
935
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: HostTestSimpleComponent, isStandalone: true, selector: "test-host", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, displayMode: { classPropertyName: "displayMode", publicName: "displayMode", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: '<h1>Test Simple Component</h1> <xt-render [componentType]="type()" [displayMode]="displayMode()" [value]="value()" ></xt-render> ', isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: XtRenderComponent, selector: "xt-render", inputs: ["componentType", "displayMode", "valueType", "value", "formGroup", "subName", "inputs"], outputs: ["valueChange", "outputs"] }] }); }
1364
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: HostTestSimpleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1365
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: HostTestSimpleComponent, isStandalone: true, selector: "test-host", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, displayMode: { classPropertyName: "displayMode", publicName: "displayMode", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: '<h1>Test Simple Component</h1> <xt-render [componentType]="type()" [displayMode]="displayMode()" [value]="value()" ></xt-render> ', isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: XtRenderComponent, selector: "xt-render", inputs: ["componentType", "displayMode", "valueType", "value", "formGroup", "subName", "inputs"], outputs: ["valueChange", "outputs"] }] }); }
936
1366
  }
937
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HostTestSimpleComponent, decorators: [{
1367
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: HostTestSimpleComponent, decorators: [{
938
1368
  type: Component,
939
1369
  args: [{
940
1370
  selector: 'test-host',
@@ -942,7 +1372,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImpor
942
1372
  imports: [CommonModule, XtRenderComponent],
943
1373
  template: '<h1>Test Simple Component</h1> <xt-render [componentType]="type()" [displayMode]="displayMode()" [value]="value()" ></xt-render> '
944
1374
  }]
945
- }] });
1375
+ }], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: true }] }], displayMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayMode", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });
946
1376
  /**
947
1377
  * Same as HostTestSimpleComponent but it includes everything in a form.
948
1378
  * Just set the component type, the formGroup and the component name, and your component will be run.
@@ -957,6 +1387,7 @@ class HostTestFormComponent {
957
1387
  this.formDescription = input({}, ...(ngDevMode ? [{ debugName: "formDescription" }] : []));
958
1388
  // Or set the FormGroup directly
959
1389
  this.formGroup = input(...(ngDevMode ? [undefined, { debugName: "formGroup" }] : []));
1390
+ // parentFormGroup = this.builder.group<{[keys:string]: AbstractControl}>({});
960
1391
  this.createdFormGroup = null;
961
1392
  }
962
1393
  computedFormGroup() {
@@ -964,6 +1395,7 @@ class HostTestFormComponent {
964
1395
  const formGroup = this.formGroup();
965
1396
  this.createdFormGroup = formGroup ?? generateFormGroup(this.formDescription());
966
1397
  }
1398
+ // this.parentFormGroup.addControl(this.controlName()??HostTestTypedFormComponent.CONTROL_NAME, this.createdFormGroup);
967
1399
  return this.createdFormGroup;
968
1400
  }
969
1401
  patchValue(newVal) {
@@ -980,10 +1412,10 @@ class HostTestFormComponent {
980
1412
  else
981
1413
  throw new Error("FormGroup not yet created. Did you set formGroup or formDescription property ?");
982
1414
  }
983
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HostTestFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
984
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: HostTestFormComponent, isStandalone: true, selector: "test-form-host", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, controlName: { classPropertyName: "controlName", publicName: "controlName", isSignal: true, isRequired: true, transformFunction: null }, formDescription: { classPropertyName: "formDescription", publicName: "formDescription", isSignal: true, isRequired: false, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: '<h1>Test Form Component</h1> <form [formGroup]="computedFormGroup()"> <xt-render [componentType]="type()" displayMode="FULL_EDITABLE" [subName]="controlName()" [formGroup]="computedFormGroup()"></xt-render></form>', isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: XtRenderComponent, selector: "xt-render", inputs: ["componentType", "displayMode", "valueType", "value", "formGroup", "subName", "inputs"], outputs: ["valueChange", "outputs"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }] }); }
1415
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: HostTestFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1416
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: HostTestFormComponent, isStandalone: true, selector: "test-form-host", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, controlName: { classPropertyName: "controlName", publicName: "controlName", isSignal: true, isRequired: true, transformFunction: null }, formDescription: { classPropertyName: "formDescription", publicName: "formDescription", isSignal: true, isRequired: false, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: '<h1>Test Form Component</h1> <form [formGroup]="computedFormGroup()"> <xt-render [componentType]="type()" displayMode="FULL_EDITABLE" [subName]="controlName()" [formGroup]="computedFormGroup()"></xt-render></form>', isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: XtRenderComponent, selector: "xt-render", inputs: ["componentType", "displayMode", "valueType", "value", "formGroup", "subName", "inputs"], outputs: ["valueChange", "outputs"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }] }); }
985
1417
  }
986
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HostTestFormComponent, decorators: [{
1418
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: HostTestFormComponent, decorators: [{
987
1419
  type: Component,
988
1420
  args: [{
989
1421
  selector: 'test-form-host',
@@ -991,7 +1423,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImpor
991
1423
  imports: [CommonModule, XtRenderComponent, ReactiveFormsModule],
992
1424
  template: '<h1>Test Form Component</h1> <form [formGroup]="computedFormGroup()"> <xt-render [componentType]="type()" displayMode="FULL_EDITABLE" [subName]="controlName()" [formGroup]="computedFormGroup()"></xt-render></form>'
993
1425
  }]
994
- }] });
1426
+ }], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: true }] }], controlName: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlName", required: true }] }], formDescription: [{ type: i0.Input, args: [{ isSignal: true, alias: "formDescription", required: false }] }], formGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "formGroup", required: false }] }] } });
995
1427
  /**
996
1428
  * Component that can be used to test your component based on the type it handles
997
1429
  * Just set the type hierarchy to register, the value, and it will instantiate the right component in your plugin
@@ -1008,10 +1440,10 @@ class HostTestTypedComponent {
1008
1440
  return ret;
1009
1441
  }, ...(ngDevMode ? [{ debugName: "context" }] : []));
1010
1442
  }
1011
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HostTestTypedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1012
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: HostTestTypedComponent, isStandalone: true, selector: "test-typed-host", inputs: { displayMode: { classPropertyName: "displayMode", publicName: "displayMode", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, valueType: { classPropertyName: "valueType", publicName: "valueType", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: '<h1>Test Typed Component</h1> <xt-render-sub [context]="context()" ></xt-render-sub> ', isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: XtRenderSubComponent, selector: "xt-render-sub", inputs: ["context", "componentType", "inputs"], outputs: ["outputs"] }] }); }
1443
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: HostTestTypedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1444
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: HostTestTypedComponent, isStandalone: true, selector: "test-typed-host", inputs: { displayMode: { classPropertyName: "displayMode", publicName: "displayMode", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, valueType: { classPropertyName: "valueType", publicName: "valueType", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: '<h1>Test Typed Component</h1> <xt-render-sub [context]="context()" ></xt-render-sub> ', isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: XtRenderSubComponent, selector: "xt-render-sub", inputs: ["context", "componentType", "inputs"], outputs: ["outputs"] }] }); }
1013
1445
  }
1014
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HostTestTypedComponent, decorators: [{
1446
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: HostTestTypedComponent, decorators: [{
1015
1447
  type: Component,
1016
1448
  args: [{
1017
1449
  selector: 'test-typed-host',
@@ -1019,7 +1451,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImpor
1019
1451
  imports: [CommonModule, XtRenderSubComponent],
1020
1452
  template: '<h1>Test Typed Component</h1> <xt-render-sub [context]="context()" ></xt-render-sub> '
1021
1453
  }]
1022
- }] });
1454
+ }], propDecorators: { displayMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayMode", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], valueType: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueType", required: false }] }] } });
1023
1455
  /**
1024
1456
  * Same as HostTestSimpleComponent but it includes everything in a form.
1025
1457
  * Just set the component type, the formGroup and the component name, and your component will be run.
@@ -1081,10 +1513,10 @@ class HostTestTypedFormComponent {
1081
1513
  retrieveValue(controlName) {
1082
1514
  return this.computeFormGroup().value[controlName];
1083
1515
  }
1084
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HostTestTypedFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1085
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: HostTestTypedFormComponent, isStandalone: true, selector: "test-typed-form-host", inputs: { valueType: { classPropertyName: "valueType", publicName: "valueType", isSignal: true, isRequired: false, transformFunction: null }, controlName: { classPropertyName: "controlName", publicName: "controlName", isSignal: true, isRequired: false, transformFunction: null }, formDescription: { classPropertyName: "formDescription", publicName: "formDescription", isSignal: true, isRequired: false, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: '<h1>Test Typed Form Component</h1> <form [formGroup]="parentFormGroup"> <xt-render-sub [context]="subContext()"></xt-render-sub></form>', isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: XtRenderSubComponent, selector: "xt-render-sub", inputs: ["context", "componentType", "inputs"], outputs: ["outputs"] }] }); }
1516
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: HostTestTypedFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1517
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: HostTestTypedFormComponent, isStandalone: true, selector: "test-typed-form-host", inputs: { valueType: { classPropertyName: "valueType", publicName: "valueType", isSignal: true, isRequired: false, transformFunction: null }, controlName: { classPropertyName: "controlName", publicName: "controlName", isSignal: true, isRequired: false, transformFunction: null }, formDescription: { classPropertyName: "formDescription", publicName: "formDescription", isSignal: true, isRequired: false, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: '<h1>Test Typed Form Component</h1> <form [formGroup]="parentFormGroup"> <xt-render-sub [context]="subContext()"></xt-render-sub></form>', isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: XtRenderSubComponent, selector: "xt-render-sub", inputs: ["context", "componentType", "inputs"], outputs: ["outputs"] }] }); }
1086
1518
  }
1087
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HostTestTypedFormComponent, decorators: [{
1519
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: HostTestTypedFormComponent, decorators: [{
1088
1520
  type: Component,
1089
1521
  args: [{
1090
1522
  selector: 'test-typed-form-host',
@@ -1092,7 +1524,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImpor
1092
1524
  imports: [CommonModule, ReactiveFormsModule, XtRenderSubComponent],
1093
1525
  template: '<h1>Test Typed Form Component</h1> <form [formGroup]="parentFormGroup"> <xt-render-sub [context]="subContext()"></xt-render-sub></form>'
1094
1526
  }]
1095
- }] });
1527
+ }], propDecorators: { valueType: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueType", required: false }] }], controlName: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlName", required: false }] }], formDescription: [{ type: i0.Input, args: [{ isSignal: true, alias: "formDescription", required: false }] }], formGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "formGroup", required: false }] }] } });
1096
1528
  function generateFormGroup(formDescription) {
1097
1529
  if (typeof formDescription != 'object') {
1098
1530
  throw new Error('Form Description should be an object of values');
@@ -1120,94 +1552,6 @@ function generateFormControl(formDescription) {
1120
1552
  return new FormControl(formDescription);
1121
1553
  }
1122
1554
 
1123
- /**
1124
- * A very light and not 100% compatible storemanager in case you are not using xt-store.
1125
- * It can emulate XtStoreManager to some extends for doing some tests
1126
- */
1127
- class StoreTestHelper {
1128
- static ensureTestProviderOnly() {
1129
- StoreSupport.setTestStoreManager(new TestStoreManager());
1130
- }
1131
- }
1132
- class TestStoreManager {
1133
- constructor() {
1134
- this.defaultProvider = new TestStoreProvider();
1135
- }
1136
- getProvider(name) {
1137
- return this.defaultProvider;
1138
- }
1139
- getProviderSafe(name) {
1140
- return this.defaultProvider;
1141
- }
1142
- getDefaultProvider() {
1143
- return this.defaultProvider;
1144
- }
1145
- getDefaultProviderSafe() {
1146
- return this.defaultProvider;
1147
- }
1148
- }
1149
- class TestStoreProvider {
1150
- constructor() {
1151
- this.data = new Map();
1152
- }
1153
- getOrCreateArray(name) {
1154
- let ret = this.data.get(name);
1155
- if (ret == null) {
1156
- ret = new Map();
1157
- this.data.set(name, ret);
1158
- }
1159
- return ret;
1160
- }
1161
- extractKey(value) {
1162
- if (value.__id != null)
1163
- return value.__id;
1164
- else if (value.id != null)
1165
- return value.id;
1166
- else
1167
- return value.toString();
1168
- }
1169
- storeEntity(name, entity) {
1170
- this.getOrCreateArray(name).set(this.extractKey(entity), entity);
1171
- return Promise.resolve(entity);
1172
- }
1173
- safeLoadEntity(name, key) {
1174
- const ret = this.getOrCreateArray(name).get(key);
1175
- if (ret == null) {
1176
- throw new Error("No entity named " + name + " with key " + key);
1177
- }
1178
- return Promise.resolve(ret);
1179
- }
1180
- loadEntity(name, key) {
1181
- return Promise.resolve(this.getOrCreateArray(name).get(key));
1182
- }
1183
- deleteEntity(name, key) {
1184
- return Promise.resolve(this.getOrCreateArray(name).delete(key));
1185
- }
1186
- searchEntities(name, ...criteria) {
1187
- throw new Error('Method not implemented.');
1188
- }
1189
- searchAndPrepareEntities(name, sort, groupBy, transformer, ...criteria) {
1190
- throw new Error('Method not implemented.');
1191
- }
1192
- canStoreDocument() {
1193
- return true;
1194
- }
1195
- storeDocument(toStore) {
1196
- const ret = new TestDocumentInfo(toStore.name, true, URL.createObjectURL(toStore));
1197
- return Promise.resolve(ret);
1198
- }
1199
- storeDocuments(toStore) {
1200
- throw new Error('Method not implemented.');
1201
- }
1202
- }
1203
- class TestDocumentInfo {
1204
- constructor(documentName, isUrl, documentId) {
1205
- this.documentId = documentId;
1206
- this.documentName = documentName;
1207
- this.isUrl = isUrl;
1208
- }
1209
- }
1210
-
1211
1555
  /*
1212
1556
  * Public API Surface of xt-components
1213
1557
  */
@@ -1216,5 +1560,5 @@ class TestDocumentInfo {
1216
1560
  * Generated bundle index. Do not edit.
1217
1561
  */
1218
1562
 
1219
- export { HostTestFormComponent, HostTestSimpleComponent, HostTestTypedComponent, HostTestTypedFormComponent, MessageHandler, StoreSupport, StoreTestHelper, TestDocumentInfo, TestStoreManager, TestStoreProvider, XT_REGISTRY_TOKEN, XT_RESOLVER_TOKEN, XT_TYPE_RESOLVER_TOKEN, XtBaseContext, XtCompositeComponent, XtPluginRegistry, XtRenderComponent, XtRenderSubComponent, XtResolvedComponent, XtResolverService, XtSimpleComponent, XtUnitTestHelper, attachToFormGroup, initXtPluginRegistry, updateFormGroupWithValue, xtPluginRegistry };
1563
+ export { HostTestFormComponent, HostTestSimpleComponent, HostTestTypedComponent, HostTestTypedFormComponent, StoreSupport, StoreTestHelper, TestDocumentInfo, TestStoreCriteria, TestStoreManager, TestStoreProvider, XT_REGISTRY_TOKEN, XT_RESOLVER_TOKEN, XT_TYPE_RESOLVER_TOKEN, XtBaseContext, XtCompositeComponent, XtMessageHandler, XtPluginRegistry, XtRenderComponent, XtRenderSubComponent, XtResolvedComponent, XtResolverService, XtSimpleComponent, XtUnitTestHelper, attachToFormGroup, initXtPluginRegistry, updateFormGroupWithValue, xtPluginRegistry };
1220
1564
  //# sourceMappingURL=xt-components.mjs.map