Skip to content

Commit 060b2cd

Browse files
authored
Support for type references
Support for type references
2 parents 45c206f + af1ab44 commit 060b2cd

84 files changed

Lines changed: 2733 additions & 3026 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,7 @@ out-tsc/
121121
# Heft temporary files
122122
.cache/
123123
.heft/
124+
/libs/xt-type/vitest.config.d.ts
125+
/libs/xt-type/vitest.config.d.ts.map
126+
/libs/xt-type/vitest.config.js
127+
/libs/xt-type/vitest.config.js.map

apps/xt-host/projects/host/src/app/shared/app-config/app-config.service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ export class AppConfigService {
133133
if (errors.length > 0) {
134134
return Promise.reject(errors);
135135
}
136+
// Once all plugins are loaded, we resolve all type references
137+
this.resolverService.resolvePendingReferences();
136138
}
137139
return Promise.resolve(true);
138140
}

apps/xt-host/projects/host/src/app/shared/models/dc-application-model.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { XtTypeReference } from 'xt-type';
2+
13
export type DcApplicationModel = {
24
name:string,
35
description?: string,
@@ -18,10 +20,12 @@ export type DcEntityModel = {
1820
name: string,
1921
fields?: {
2022
[key:string]:DcFieldModel
21-
}
23+
},
24+
compatibleWith?: string[]
2225
}
2326

2427
export type DcFieldModel = {
2528
name: string,
26-
type: string
29+
type: string,
30+
reference?: XtTypeReference
2731
}

apps/xt-plugin-tester/projects/plugin-tester/src/app/hierarchy-test/hierarchy-test.component.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ export class HierarchyTestComponent {
2727
// Register the edited type
2828
this.xtResolver.registerTypes (
2929
{
30+
'money': {
31+
amount: 'number',
32+
currency: 'string'
33+
},
3034
'TestPayment': {
3135
toWho: 'string',
3236
payment: 'money'

apps/xt-plugin-tester/projects/plugin-tester/src/app/plugin-manager/plugin-manager.component.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,13 @@ describe('PluginManagerComponent', () => {
7676
}
7777
],
7878
types: {
79-
'TestType21': {
80-
'subProp':'TestType211'
81-
},
8279
'TestType211': {
8380
'TestProperty2111':'date',
8481
'TestProperty2112':'boolean'
8582
},
83+
'TestType21': {
84+
'subProp':'TestType211'
85+
},
8686
'TestType22': 'string',
8787
'TestType23': {
8888
'TestProperty231':'string',

apps/xt-plugin-tester/projects/plugin-tester/src/app/plugin-manager/plugin-manager.component.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
import { XtComponentInfo, XtPluginInfo, XtResolverService } from 'xt-components';
1212
import { Button } from 'primeng/button';
1313
import { PrimeIcons } from 'primeng/api';
14-
import { XtTypeInfo } from 'xt-type';
14+
import { XtTypeDetail, XtTypeInfo, isTypeDetail } from 'xt-type';
1515
import { Card } from 'primeng/card';
1616
import { JsonPipe } from '@angular/common';
1717
import { Panel } from 'primeng/panel';
@@ -130,6 +130,12 @@ export class PluginManagerComponent implements OnDestroy, OnInit {
130130
this.resolverService.loadPlugin(url).catch((error) => {
131131
this.errorHandler.errorOccurred(error, "Error while loading plugin.");
132132
});
133+
134+
try {
135+
this.resolverService.resolvePendingReferences();
136+
} catch (error) {
137+
this.errorHandler.errorOccurred(error, "Error while resolving pending references.");
138+
}
133139
}
134140
}
135141

@@ -188,7 +194,7 @@ class TypeDisplayInfo {
188194
name:string;
189195
typeName?: string;
190196

191-
constructor(name:string, type:XtTypeInfo|string) {
197+
constructor(name:string, type:XtTypeInfo|XtTypeDetail|string) {
192198
this.name=name;
193199
if (typeof type == 'string') {
194200
this.typeName = type;

common/config/rush/pnpm-lock.yaml

Lines changed: 321 additions & 2531 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/workflow-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Must enable:
1010
- Workflow View One per category => Edit
1111
- Workflow New Element
1212
- Workflow Select from SubList => New Element
13+
- Workflow list + report: Display a report in realtime (total expense, monthly expense) while displaying and editing elements of the list
1314

1415
Configuration:
1516
- Menu to Workflow

libs/xt-components/projects/xt-components/src/lib/angular/xt-resolver.service.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ describe('XtResolverService', () => {
5757
service.registerPlugin({
5858
name: 'resolverTest',
5959
types: {
60+
testString: 'string',
61+
testType2:'number',
6062
type1: {
6163
subType1: 'testString'
6264
},

libs/xt-components/projects/xt-components/src/lib/angular/xt-resolver.service.ts

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
1-
import { computed, inject, Injectable, Injector, runInInjectionContext, Type } from '@angular/core';
1+
import { computed, inject, Injectable, Type } from '@angular/core';
22
import { XtContext } from '../xt-context';
33
import { XtRegistryResolver } from '../resolver/xt-registry-resolver';
44
import { XT_REGISTRY_TOKEN, XT_RESOLVER_TOKEN, XT_TYPE_RESOLVER_TOKEN } from './xt-tokens';
55
import { XtResolvedComponent } from '../xt-resolved-component';
6-
import { ManagedDataHandler,
7-
MappingHelper, XtTypeHandler, XtTypeInfo, xtTypeManager, XtTypeResolver, XtUpdatableTypeResolver } from 'xt-type';
6+
import {
7+
ManagedDataHandler,
8+
MappingHelper,
9+
XtSpecialFieldsHelper,
10+
XtTypeHandler,
11+
XtTypeInfo,
12+
xtTypeManager,
13+
XtTypeResolver,
14+
XtUpdatableTypeResolver
15+
} from 'xt-type';
816
import { XtComponentInfo, XtPluginInfo, XtTypeHandlerInfo } from '../plugin/xt-plugin-info';
917
import { XtResolver } from '../resolver/xt-resolver';
1018
import { XtComponent } from '../xt-component';
1119
import { loadRemoteModule } from '@angular-architects/native-federation';
1220
import { XtAction } from '../action/xt-action';
13-
import { IStoreProvider } from '../store/store-support';
1421
import { XtActionHandler, XtActionResult } from '../action/xt-action-handler';
22+
import { IStoreManager, StoreSupport } from '../store/store-support';
23+
import { firstValueFrom, Observable } from 'rxjs';
1524

1625
/**
1726
* An all in one helper class, enabling manipulation of the context, with data and type associated with it.
@@ -52,7 +61,12 @@ export class XtResolverService {
5261
}
5362

5463
findTypeHandlerOf<T> (baseContext:XtContext<T>, subName?:string, value?:T): {typeName?:string | null, handler?:XtTypeHandler<any>} {
55-
const ret = this.typeResolver.findTypeHandler(baseContext.valueType, false, subName, value);
64+
let ret:{typeName?:string | null, handler?:XtTypeHandler<any>} = {typeName:undefined, handler:undefined};
65+
if (baseContext.isReference()){
66+
ret = this.typeResolver.findTypeHandler(baseContext.reference!.toType, false, undefined, value);
67+
}else {
68+
ret = this.typeResolver.findTypeHandler(baseContext.valueType, false, subName, value);
69+
}
5670
return ret;
5771
}
5872

@@ -71,6 +85,7 @@ export class XtResolverService {
7185

7286
registerTypes (types:XtTypeInfo|undefined, handlers?:XtTypeHandlerInfo<any>[]): void {
7387
if ((types !=null) && (this.typeResolver.canUpdate())) {
88+
7489
for (const newType in types) {
7590
let handler=this.handlerDefinedFor (newType, handlers);
7691
if (handler==null) {
@@ -232,4 +247,62 @@ export class XtResolverService {
232247
return undefined;
233248
}
234249

250+
async resolveReferencedValue<T,U> (context: XtContext<T>, storeMgr: IStoreManager): Promise<U | U[] | null | undefined> {
251+
if (!context.isReference()) return undefined;
252+
const ref= context.reference!;
253+
const storeProvider = storeMgr.getProvider<U> (ref.type);
254+
if (storeProvider == null) {
255+
throw new Error ('No Store provider found for type '+ref.type);
256+
}
257+
258+
const ret= await firstValueFrom(storeProvider.searchEntities(ref.toType, storeMgr.newStoreCriteria(ref.field, context.value(),'=')));
259+
if (ret.length == 0) return null;
260+
if (ref.referenceType=='MANY-TO-ONE') {
261+
if (ret.length > 1) throw new Error('Multiple values for many to one relation between ' + context.valueType + ' and ' + ref.type + ' with value ' + context.value());
262+
return ret[0];
263+
} else if (ref.referenceType=='ONE-TO-MANY') {
264+
return ret;
265+
}
266+
return undefined;
267+
}
268+
269+
resolvePendingReferences () {
270+
(this.typeResolver as XtUpdatableTypeResolver).resolveAllTypeReferences();
271+
}
272+
273+
/**
274+
* Calculates the values that can be referenced by the reference & value of this context
275+
* @param context
276+
*/
277+
findPossibleReferences<T, U> (context:XtContext<T>): Observable<U[]> {
278+
if (!context.isReference()) throw new Error('Cannot find possible references of this non reference context'+context.toString());
279+
const reference = context.reference!;
280+
const store =StoreSupport.getStoreManager().getProviderSafe<U>(reference.toType);
281+
return store.searchEntities(reference.toType );
282+
}
283+
284+
/* async loadAllReferencesForContext<T> (context:XtContext<T>, storeMgr: IStoreManager): Promise<void> {
285+
const refs =this.typeResolver.listReferences(context.valueType);
286+
const promises:Promise<void>[]=[];
287+
for (const ref of Object.keys(refs)) {
288+
const subContext= context.subContext(ref, undefined, this.typeResolver);
289+
promises.push(this.resolveReferencedValue(subContext, storeMgr).then ((value) => {
290+
subContext.updateReferencedContext(value);
291+
}));
292+
}
293+
294+
if( promises.length>0) {
295+
return Promise.all(promises).then((values) => {
296+
context.subReferencesResolved.set(true);
297+
return;
298+
});
299+
} else {
300+
return Promise.resolve().then (() => {
301+
context.subReferencesResolved.set(true);
302+
});
303+
}
304+
305+
}
306+
*/
307+
235308
}

0 commit comments

Comments
 (0)