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.
- package/fesm2022/xt-components.mjs +655 -311
- package/fesm2022/xt-components.mjs.map +1 -1
- package/index.d.ts +252 -99
- package/package.json +4 -1
|
@@ -1,11 +1,190 @@
|
|
|
1
|
+
import { isTypeReference, XtBaseTypeReference, xtTypeManager, ManagedDataHandler, isPrimitive } from 'xt-type';
|
|
1
2
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
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
|
|
159
|
-
ret.
|
|
160
|
-
if (
|
|
161
|
-
|
|
162
|
-
ret.
|
|
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
|
|
378
|
+
let currentGroup = this.formGroup();
|
|
176
379
|
// Recalculate parentGroup and formControlName and value if needed.
|
|
177
|
-
if (
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
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
|
-
|
|
310
|
-
|
|
516
|
+
else {
|
|
517
|
+
typeToFind = typeInfo.toType;
|
|
311
518
|
}
|
|
312
519
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
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
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
if (
|
|
355
|
-
|
|
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
|
-
|
|
361
|
-
|
|
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
|
|
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
|
-
|
|
371
|
-
|
|
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
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
return
|
|
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
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
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
|
-
|
|
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
|
-
|
|
507
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
593
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.
|
|
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.
|
|
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.
|
|
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.
|
|
654
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.
|
|
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.
|
|
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:
|
|
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.
|
|
760
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.
|
|
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.
|
|
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.
|
|
812
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.
|
|
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.
|
|
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
|
|
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.
|
|
827
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
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.
|
|
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?.
|
|
876
|
-
const
|
|
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,
|
|
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,
|
|
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,
|
|
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.
|
|
935
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.
|
|
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.
|
|
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.
|
|
984
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.
|
|
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.
|
|
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.
|
|
1012
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.
|
|
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.
|
|
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.
|
|
1085
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.
|
|
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.
|
|
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,
|
|
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
|