@acorex/platform 20.4.2 → 20.5.0-next.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/common/index.d.ts +1 -1
- package/core/index.d.ts +405 -193
- package/fesm2022/acorex-platform-common.mjs +2 -2
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +638 -244
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-components.mjs +614 -31
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +14 -386
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +51 -47
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widgets.mjs +1182 -305
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default.mjs +6 -1
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-shared.mjs +676 -271
- package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
- package/layout/components/index.d.ts +245 -3
- package/layout/entity/index.d.ts +1 -59
- package/layout/widgets/index.d.ts +237 -3
- package/package.json +5 -5
- package/themes/default/index.d.ts +1 -0
|
@@ -1,11 +1,265 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, Injectable, computed, input, effect, Directive, EventEmitter, HostListener, Output, ViewContainerRef, ElementRef, Injector, runInInjectionContext, provideAppInitializer, signal, Pipe } from '@angular/core';
|
|
1
3
|
import { signalStore, withState, withComputed, withMethods, patchState } from '@ngrx/signals';
|
|
2
4
|
import { get, isPlainObject, set, isArray, merge, isNil, isObjectLike, transform, isEmpty, isEqual, differenceWith, union, cloneDeep, isUndefined, endsWith, startsWith, includes, lte, gte, lt, gt, orderBy } from 'lodash-es';
|
|
3
|
-
import * as i0 from '@angular/core';
|
|
4
|
-
import { computed, InjectionToken, inject, Injectable, input, effect, Directive, EventEmitter, HostListener, Output, ViewContainerRef, ElementRef, provideAppInitializer, signal, Pipe, Injector, runInInjectionContext } from '@angular/core';
|
|
5
5
|
import { Subject, interval } from 'rxjs';
|
|
6
6
|
import { AXCalendarService } from '@acorex/core/date-time';
|
|
7
7
|
import { startWith, map } from 'rxjs/operators';
|
|
8
8
|
|
|
9
|
+
const AXP_ACTIVITY_LOG_PROVIDER = new InjectionToken('AXP_ACTIVITY_LOGS_PROVIDER');
|
|
10
|
+
class AXPActivityLogService {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.providers = inject(AXP_ACTIVITY_LOG_PROVIDER, { optional: true });
|
|
13
|
+
}
|
|
14
|
+
async getHistory(refId, refType, options) {
|
|
15
|
+
return (await Promise.all(this.providers?.map((p) => p.getHistory(refId, refType, options)) ?? [])).flat();
|
|
16
|
+
}
|
|
17
|
+
async getHistoryByIds(refId, refType, ids) {
|
|
18
|
+
return (await Promise.all(this.providers?.map((p) => p.getHistoryByIds(refId, refType, ids)) ?? [])).flat();
|
|
19
|
+
}
|
|
20
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPActivityLogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
21
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPActivityLogService, providedIn: 'root' }); }
|
|
22
|
+
}
|
|
23
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPActivityLogService, decorators: [{
|
|
24
|
+
type: Injectable,
|
|
25
|
+
args: [{ providedIn: 'root' }]
|
|
26
|
+
}] });
|
|
27
|
+
|
|
28
|
+
class AXPActivityLogProvider {
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//#region ---- Color Palette Provider ----
|
|
32
|
+
/**
|
|
33
|
+
* Abstract class for color palette providers
|
|
34
|
+
* Implement this to provide palettes from different sources (system, app, module, etc.)
|
|
35
|
+
*/
|
|
36
|
+
class AXPColorPaletteProvider {
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Injection token for color palette providers
|
|
40
|
+
* Use this to register multiple palette providers
|
|
41
|
+
*/
|
|
42
|
+
const AXP_COLOR_PALETTE_PROVIDER = new InjectionToken('AXP_COLOR_PALETTE_PROVIDER');
|
|
43
|
+
//#endregion
|
|
44
|
+
|
|
45
|
+
//#region ---- Color Palette Service ----
|
|
46
|
+
/**
|
|
47
|
+
* Service for managing color palettes from multiple providers
|
|
48
|
+
* Aggregates palettes from all registered providers
|
|
49
|
+
*/
|
|
50
|
+
class AXPColorPaletteService {
|
|
51
|
+
constructor() {
|
|
52
|
+
//#region ---- Dependencies ----
|
|
53
|
+
this.providers = inject(AXP_COLOR_PALETTE_PROVIDER, { optional: true }) ?? [];
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region ---- State ----
|
|
56
|
+
this.cache = null;
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region ---- Public API ----
|
|
60
|
+
/**
|
|
61
|
+
* Get all palettes from all providers
|
|
62
|
+
* @param options Filter options
|
|
63
|
+
* @returns Promise of palettes
|
|
64
|
+
*/
|
|
65
|
+
async getPalettes(options) {
|
|
66
|
+
if (!this.cache) {
|
|
67
|
+
await this.loadPalettes();
|
|
68
|
+
}
|
|
69
|
+
let palettes = this.cache;
|
|
70
|
+
// Apply category filter
|
|
71
|
+
if (options?.category) {
|
|
72
|
+
palettes = palettes.filter((palette) => palette.category === options.category);
|
|
73
|
+
}
|
|
74
|
+
// Apply search filter
|
|
75
|
+
if (options?.search) {
|
|
76
|
+
const searchLower = options.search.toLowerCase();
|
|
77
|
+
palettes = palettes.filter((palette) => palette.name.toLowerCase().includes(searchLower) ||
|
|
78
|
+
palette.title.toLowerCase().includes(searchLower) ||
|
|
79
|
+
palette.description?.toLowerCase().includes(searchLower));
|
|
80
|
+
}
|
|
81
|
+
return palettes;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get a palette by name
|
|
85
|
+
* @param name The unique name of the palette
|
|
86
|
+
* @returns Promise of palette or undefined if not found
|
|
87
|
+
*/
|
|
88
|
+
async getPalette(name) {
|
|
89
|
+
if (!this.cache) {
|
|
90
|
+
await this.loadPalettes();
|
|
91
|
+
}
|
|
92
|
+
return this.cache.find((p) => p.name === name);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get palettes by category
|
|
96
|
+
* @param category The category to filter by
|
|
97
|
+
* @returns Promise of palettes in the specified category
|
|
98
|
+
*/
|
|
99
|
+
async getByCategory(category) {
|
|
100
|
+
return this.getPalettes({ category });
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Check if a palette exists
|
|
104
|
+
* @param name The unique name of the palette
|
|
105
|
+
* @returns Promise of true if the palette exists
|
|
106
|
+
*/
|
|
107
|
+
async has(name) {
|
|
108
|
+
const palette = await this.getPalette(name);
|
|
109
|
+
return palette !== undefined;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Reload palettes from all providers
|
|
113
|
+
*/
|
|
114
|
+
async reload() {
|
|
115
|
+
this.cache = null;
|
|
116
|
+
await this.loadPalettes();
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region ---- Private Methods ----
|
|
120
|
+
/**
|
|
121
|
+
* Load palettes from all providers
|
|
122
|
+
*/
|
|
123
|
+
async loadPalettes() {
|
|
124
|
+
const allPalettes = [];
|
|
125
|
+
for (const provider of this.providers) {
|
|
126
|
+
try {
|
|
127
|
+
const palettes = await provider.provide();
|
|
128
|
+
allPalettes.push(...palettes);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
console.error(`Error loading palettes from provider ${provider.name}:`, error);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Remove duplicates based on name
|
|
135
|
+
const uniquePalettes = allPalettes.filter((palette, index, self) => index === self.findIndex((p) => p.name === palette.name));
|
|
136
|
+
this.cache = uniquePalettes;
|
|
137
|
+
}
|
|
138
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPColorPaletteService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
139
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPColorPaletteService, providedIn: 'root' }); }
|
|
140
|
+
}
|
|
141
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPColorPaletteService, decorators: [{
|
|
142
|
+
type: Injectable,
|
|
143
|
+
args: [{
|
|
144
|
+
providedIn: 'root',
|
|
145
|
+
}]
|
|
146
|
+
}] });
|
|
147
|
+
|
|
148
|
+
//#region ---- Color Palette Types ----
|
|
149
|
+
//#endregion
|
|
150
|
+
|
|
151
|
+
//#region ---- Default System Palettes Provider ----
|
|
152
|
+
/**
|
|
153
|
+
* Default system color palette provider
|
|
154
|
+
* Provides built-in color palettes
|
|
155
|
+
*/
|
|
156
|
+
class AXPDefaultColorPalettesProvider extends AXPColorPaletteProvider {
|
|
157
|
+
constructor() {
|
|
158
|
+
super(...arguments);
|
|
159
|
+
this.name = 'system';
|
|
160
|
+
}
|
|
161
|
+
async provide() {
|
|
162
|
+
return [
|
|
163
|
+
{
|
|
164
|
+
name: 'material-design',
|
|
165
|
+
title: 'Material Design',
|
|
166
|
+
category: 'material',
|
|
167
|
+
description: 'Google Material Design color palette',
|
|
168
|
+
colors: [
|
|
169
|
+
'#F44336', // Red
|
|
170
|
+
'#E91E63', // Pink
|
|
171
|
+
'#9C27B0', // Purple
|
|
172
|
+
'#673AB7', // Deep Purple
|
|
173
|
+
'#3F51B5', // Indigo
|
|
174
|
+
'#2196F3', // Blue
|
|
175
|
+
'#03A9F4', // Light Blue
|
|
176
|
+
'#00BCD4', // Cyan
|
|
177
|
+
'#009688', // Teal
|
|
178
|
+
'#4CAF50', // Green
|
|
179
|
+
'#8BC34A', // Light Green
|
|
180
|
+
'#CDDC39', // Lime
|
|
181
|
+
'#FFEB3B', // Yellow
|
|
182
|
+
'#FFC107', // Amber
|
|
183
|
+
'#FF9800', // Orange
|
|
184
|
+
'#FF5722', // Deep Orange
|
|
185
|
+
],
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: 'pastel',
|
|
189
|
+
title: 'Pastel Colors',
|
|
190
|
+
category: 'theme',
|
|
191
|
+
description: 'Soft pastel color palette',
|
|
192
|
+
colors: [
|
|
193
|
+
'#FFB3BA', // Light Pink
|
|
194
|
+
'#FFDFBA', // Light Peach
|
|
195
|
+
'#FFFFBA', // Light Yellow
|
|
196
|
+
'#BAFFC9', // Light Green
|
|
197
|
+
'#BAE1FF', // Light Blue
|
|
198
|
+
'#E0BBE4', // Light Purple
|
|
199
|
+
'#FFDFD3', // Light Coral
|
|
200
|
+
'#D4F1F4', // Light Cyan
|
|
201
|
+
],
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: 'vibrant',
|
|
205
|
+
title: 'Vibrant Colors',
|
|
206
|
+
category: 'theme',
|
|
207
|
+
description: 'Bold and vibrant color palette',
|
|
208
|
+
colors: [
|
|
209
|
+
'#FF6B6B', // Vibrant Red
|
|
210
|
+
'#4ECDC4', // Vibrant Teal
|
|
211
|
+
'#45B7D1', // Vibrant Blue
|
|
212
|
+
'#FFA07A', // Vibrant Salmon
|
|
213
|
+
'#98D8C8', // Vibrant Mint
|
|
214
|
+
'#F7DC6F', // Vibrant Yellow
|
|
215
|
+
'#BB8FCE', // Vibrant Purple
|
|
216
|
+
'#85C1E2', // Vibrant Sky Blue
|
|
217
|
+
],
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
name: 'earth-tones',
|
|
221
|
+
title: 'Earth Tones',
|
|
222
|
+
category: 'theme',
|
|
223
|
+
description: 'Natural earth tone color palette',
|
|
224
|
+
colors: [
|
|
225
|
+
'#8B4513', // Saddle Brown
|
|
226
|
+
'#A0522D', // Sienna
|
|
227
|
+
'#D2691E', // Chocolate
|
|
228
|
+
'#CD853F', // Peru
|
|
229
|
+
'#DEB887', // Burlywood
|
|
230
|
+
'#F5DEB3', // Wheat
|
|
231
|
+
'#556B2F', // Dark Olive Green
|
|
232
|
+
'#6B8E23', // Olive Drab
|
|
233
|
+
],
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: 'monochrome',
|
|
237
|
+
title: 'Monochrome',
|
|
238
|
+
category: 'theme',
|
|
239
|
+
description: 'Grayscale color palette',
|
|
240
|
+
colors: [
|
|
241
|
+
'#000000', // Black
|
|
242
|
+
'#262626', // Very Dark Gray
|
|
243
|
+
'#404040', // Dark Gray
|
|
244
|
+
'#595959', // Medium Dark Gray
|
|
245
|
+
'#737373', // Medium Gray
|
|
246
|
+
'#8C8C8C', // Light Medium Gray
|
|
247
|
+
'#A6A6A6', // Light Gray
|
|
248
|
+
'#BFBFBF', // Very Light Gray
|
|
249
|
+
'#D9D9D9', // Lighter Gray
|
|
250
|
+
'#F2F2F2', // Almost White
|
|
251
|
+
'#FFFFFF', // White
|
|
252
|
+
],
|
|
253
|
+
},
|
|
254
|
+
];
|
|
255
|
+
}
|
|
256
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPDefaultColorPalettesProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
257
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPDefaultColorPalettesProvider }); }
|
|
258
|
+
}
|
|
259
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPDefaultColorPalettesProvider, decorators: [{
|
|
260
|
+
type: Injectable
|
|
261
|
+
}] });
|
|
262
|
+
|
|
9
263
|
function extractNestedFieldsWildcard(obj, basePath, fields) {
|
|
10
264
|
const result = {};
|
|
11
265
|
if (fields.length === 1 && fields[0] === '*') {
|
|
@@ -712,6 +966,152 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
712
966
|
}]
|
|
713
967
|
}] });
|
|
714
968
|
|
|
969
|
+
const AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER = new InjectionToken('AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER');
|
|
970
|
+
|
|
971
|
+
//#region ---- Imports ----
|
|
972
|
+
//#endregion
|
|
973
|
+
class AXPDistributedEventListenerService {
|
|
974
|
+
constructor() {
|
|
975
|
+
//#region ---- Providers & Caches ----
|
|
976
|
+
this.listenerProviders = inject(AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, { optional: true }) || [];
|
|
977
|
+
this.injector = inject(Injector);
|
|
978
|
+
/** Cache for listeners by key. */
|
|
979
|
+
this.listenersByKey = new Map();
|
|
980
|
+
/** Flag to track if providers have been loaded */
|
|
981
|
+
this.providersLoaded = false;
|
|
982
|
+
}
|
|
983
|
+
//#endregion
|
|
984
|
+
//#region ---- Public API ----
|
|
985
|
+
/**
|
|
986
|
+
* Dispatches an event to all registered listeners for the given key.
|
|
987
|
+
* @param key The event key.
|
|
988
|
+
* @param data The event data to pass to listeners.
|
|
989
|
+
*/
|
|
990
|
+
async dispatch(key, data) {
|
|
991
|
+
const providers = await this.resolveProviders();
|
|
992
|
+
const matched = providers.filter(p => p.key === key);
|
|
993
|
+
if (!matched.length) {
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
996
|
+
for (const provider of matched) {
|
|
997
|
+
try {
|
|
998
|
+
await Promise.resolve(runInInjectionContext(this.injector, () => provider.execute(data)));
|
|
999
|
+
}
|
|
1000
|
+
catch (err) {
|
|
1001
|
+
console.error(`[AXPDistributedEventListenerService] Provider for key='${key}' failed`, err);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* Dispatch with async response (first matching provider, with retry/timeout)
|
|
1007
|
+
*/
|
|
1008
|
+
async dispatchAsync(key, data, options = {
|
|
1009
|
+
timeout: 60_000,
|
|
1010
|
+
retries: 3,
|
|
1011
|
+
retryDelay: 1000,
|
|
1012
|
+
}) {
|
|
1013
|
+
const providers = await this.resolveProviders();
|
|
1014
|
+
const matched = providers.filter(p => p.key === key);
|
|
1015
|
+
if (!matched.length) {
|
|
1016
|
+
throw new Error(`No provider found for key='${key}'`);
|
|
1017
|
+
}
|
|
1018
|
+
const attempt = (n) => {
|
|
1019
|
+
return new Promise((resolve, reject) => {
|
|
1020
|
+
let finished = false;
|
|
1021
|
+
const timer = setTimeout(() => {
|
|
1022
|
+
if (!finished) {
|
|
1023
|
+
if (n < options.retries) {
|
|
1024
|
+
resolve(attempt(n + 1));
|
|
1025
|
+
}
|
|
1026
|
+
else {
|
|
1027
|
+
reject(new Error(`Timeout: no response for key='${key}' after ${options.retries} attempts.`));
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
}, options.timeout);
|
|
1031
|
+
try {
|
|
1032
|
+
const provider = matched[0];
|
|
1033
|
+
const result = runInInjectionContext(this.injector, () => provider.execute(data));
|
|
1034
|
+
Promise.resolve(result)
|
|
1035
|
+
.then((r) => {
|
|
1036
|
+
finished = true;
|
|
1037
|
+
clearTimeout(timer);
|
|
1038
|
+
resolve(r);
|
|
1039
|
+
})
|
|
1040
|
+
.catch(err => {
|
|
1041
|
+
finished = true;
|
|
1042
|
+
clearTimeout(timer);
|
|
1043
|
+
reject(err);
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
catch (err) {
|
|
1047
|
+
clearTimeout(timer);
|
|
1048
|
+
reject(err);
|
|
1049
|
+
}
|
|
1050
|
+
});
|
|
1051
|
+
};
|
|
1052
|
+
return attempt(0);
|
|
1053
|
+
}
|
|
1054
|
+
/**
|
|
1055
|
+
* Resolve all providers (handle both direct provider and Promise<provider>)
|
|
1056
|
+
*/
|
|
1057
|
+
async resolveProviders() {
|
|
1058
|
+
return Promise.all(this.listenerProviders.map(p => p instanceof Promise ? p : Promise.resolve(p)));
|
|
1059
|
+
}
|
|
1060
|
+
/**
|
|
1061
|
+
* Returns all listeners for a specific event key.
|
|
1062
|
+
* @param key The event key.
|
|
1063
|
+
* @returns Array of listeners for the key.
|
|
1064
|
+
*/
|
|
1065
|
+
async getListeners(key) {
|
|
1066
|
+
await this.ensureProvidersLoaded();
|
|
1067
|
+
return this.listenersByKey.get(key) || [];
|
|
1068
|
+
}
|
|
1069
|
+
/**
|
|
1070
|
+
* Returns all registered event keys.
|
|
1071
|
+
* @returns Array of all event keys that have listeners.
|
|
1072
|
+
*/
|
|
1073
|
+
async getRegisteredKeys() {
|
|
1074
|
+
await this.ensureProvidersLoaded();
|
|
1075
|
+
return Array.from(this.listenersByKey.keys());
|
|
1076
|
+
}
|
|
1077
|
+
//#endregion
|
|
1078
|
+
//#region ---- Private Methods ----
|
|
1079
|
+
/**
|
|
1080
|
+
* Ensures that all providers have been loaded and cached.
|
|
1081
|
+
*/
|
|
1082
|
+
async ensureProvidersLoaded() {
|
|
1083
|
+
if (this.providersLoaded) {
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
// Resolve all providers
|
|
1087
|
+
const resolvedProviders = await Promise.all(this.listenerProviders);
|
|
1088
|
+
// Group listeners by key
|
|
1089
|
+
for (const provider of resolvedProviders) {
|
|
1090
|
+
if (provider) {
|
|
1091
|
+
const existingListeners = this.listenersByKey.get(provider.key) || [];
|
|
1092
|
+
existingListeners.push(provider);
|
|
1093
|
+
this.listenersByKey.set(provider.key, existingListeners);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
this.providersLoaded = true;
|
|
1097
|
+
}
|
|
1098
|
+
//#endregion
|
|
1099
|
+
//#region ---- Cache Management ----
|
|
1100
|
+
/** Clears the listeners cache and forces reload on next access. */
|
|
1101
|
+
clearListenersCache() {
|
|
1102
|
+
this.listenersByKey.clear();
|
|
1103
|
+
this.providersLoaded = false;
|
|
1104
|
+
}
|
|
1105
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPDistributedEventListenerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1106
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPDistributedEventListenerService, providedIn: 'root' }); }
|
|
1107
|
+
}
|
|
1108
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPDistributedEventListenerService, decorators: [{
|
|
1109
|
+
type: Injectable,
|
|
1110
|
+
args: [{
|
|
1111
|
+
providedIn: 'root',
|
|
1112
|
+
}]
|
|
1113
|
+
}] });
|
|
1114
|
+
|
|
715
1115
|
class AXPBroadcastEventService {
|
|
716
1116
|
constructor() {
|
|
717
1117
|
this.eventSubjects = new Map();
|
|
@@ -991,6 +1391,60 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
991
1391
|
args: [{ providedIn: 'root' }]
|
|
992
1392
|
}] });
|
|
993
1393
|
|
|
1394
|
+
class AXPHookService {
|
|
1395
|
+
constructor() {
|
|
1396
|
+
this.listenerProviders = inject(AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, { optional: true }) || [];
|
|
1397
|
+
this.injector = inject(Injector);
|
|
1398
|
+
}
|
|
1399
|
+
/**
|
|
1400
|
+
* Resolve all providers (handle both direct providers and Promise<provider>)
|
|
1401
|
+
*/
|
|
1402
|
+
async resolveProviders() {
|
|
1403
|
+
return Promise.all(this.listenerProviders.map(p => p instanceof Promise ? p : Promise.resolve(p)));
|
|
1404
|
+
}
|
|
1405
|
+
/**
|
|
1406
|
+
* Fire sync hooks (fire-and-forget).
|
|
1407
|
+
* All providers with the given key will be executed.
|
|
1408
|
+
* Execution is not awaited.
|
|
1409
|
+
*/
|
|
1410
|
+
fire(key, data) {
|
|
1411
|
+
this.resolveProviders().then(providers => {
|
|
1412
|
+
providers
|
|
1413
|
+
.filter(p => p.key === key)
|
|
1414
|
+
.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0))
|
|
1415
|
+
.forEach(p => {
|
|
1416
|
+
try {
|
|
1417
|
+
runInInjectionContext(this.injector, () => p.execute(data));
|
|
1418
|
+
}
|
|
1419
|
+
catch (err) {
|
|
1420
|
+
console.error(`[AXPHookService] Hook '${key}' failed`, err);
|
|
1421
|
+
}
|
|
1422
|
+
});
|
|
1423
|
+
});
|
|
1424
|
+
}
|
|
1425
|
+
/**
|
|
1426
|
+
* Run async hooks sequentially (waterfall).
|
|
1427
|
+
* The output of each hook is passed as input to the next hook.
|
|
1428
|
+
* Returns the final merged data after all hooks are executed.
|
|
1429
|
+
*/
|
|
1430
|
+
async runAsync(key, initialData) {
|
|
1431
|
+
const providers = (await this.resolveProviders())
|
|
1432
|
+
.filter(p => p.key === key)
|
|
1433
|
+
.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
1434
|
+
let data = initialData;
|
|
1435
|
+
for (const p of providers) {
|
|
1436
|
+
data = await Promise.resolve(runInInjectionContext(this.injector, () => p.execute(data)));
|
|
1437
|
+
}
|
|
1438
|
+
return data;
|
|
1439
|
+
}
|
|
1440
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPHookService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1441
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPHookService, providedIn: 'root' }); }
|
|
1442
|
+
}
|
|
1443
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPHookService, decorators: [{
|
|
1444
|
+
type: Injectable,
|
|
1445
|
+
args: [{ providedIn: 'root' }]
|
|
1446
|
+
}] });
|
|
1447
|
+
|
|
994
1448
|
class AXPAppStartUpService {
|
|
995
1449
|
constructor() {
|
|
996
1450
|
this.tasks = [];
|
|
@@ -998,35 +1452,197 @@ class AXPAppStartUpService {
|
|
|
998
1452
|
registerTask(task) {
|
|
999
1453
|
this.tasks.push(task);
|
|
1000
1454
|
}
|
|
1001
|
-
async runAllTasks() {
|
|
1002
|
-
for (const task of this.tasks.sort((a, b) => a.priority - b.priority)) {
|
|
1003
|
-
console.log(`Running "${task.statusText}" with priority "${task.priority}"`);
|
|
1004
|
-
this.updateStatus(task.statusText);
|
|
1005
|
-
await task.run();
|
|
1455
|
+
async runAllTasks() {
|
|
1456
|
+
for (const task of this.tasks.sort((a, b) => a.priority - b.priority)) {
|
|
1457
|
+
console.log(`Running "${task.statusText}" with priority "${task.priority}"`);
|
|
1458
|
+
this.updateStatus(task.statusText);
|
|
1459
|
+
await task.run();
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
updateStatus(status) {
|
|
1463
|
+
const loadingText = document.querySelector('#loadingText');
|
|
1464
|
+
if (loadingText) {
|
|
1465
|
+
loadingText.innerHTML = status;
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPAppStartUpService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1469
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPAppStartUpService, providedIn: 'root' }); }
|
|
1470
|
+
}
|
|
1471
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPAppStartUpService, decorators: [{
|
|
1472
|
+
type: Injectable,
|
|
1473
|
+
args: [{
|
|
1474
|
+
providedIn: 'root',
|
|
1475
|
+
}]
|
|
1476
|
+
}] });
|
|
1477
|
+
function initAppFactory(appInitService) {
|
|
1478
|
+
return () => appInitService.runAllTasks();
|
|
1479
|
+
}
|
|
1480
|
+
const AXPAppStartUpProvider = provideAppInitializer(() => {
|
|
1481
|
+
const initializerFn = initAppFactory(inject(AXPAppStartUpService));
|
|
1482
|
+
return initializerFn();
|
|
1483
|
+
});
|
|
1484
|
+
|
|
1485
|
+
//#region ---- Tag Types ----
|
|
1486
|
+
//#endregion
|
|
1487
|
+
|
|
1488
|
+
//#region ---- Tag Provider ----
|
|
1489
|
+
/**
|
|
1490
|
+
* Abstract class for tag providers
|
|
1491
|
+
* Implement this to provide tags from different sources (system, tenant, user, etc.)
|
|
1492
|
+
*/
|
|
1493
|
+
class AXPTagProvider {
|
|
1494
|
+
/**
|
|
1495
|
+
* Create a new tag (optional - not all providers support creation)
|
|
1496
|
+
* @param tag Tag to create
|
|
1497
|
+
* @returns Created tag with id
|
|
1498
|
+
*/
|
|
1499
|
+
async create(tag) {
|
|
1500
|
+
throw new Error(`Provider ${this.name} does not support tag creation`);
|
|
1501
|
+
}
|
|
1502
|
+
/**
|
|
1503
|
+
* Update an existing tag (optional)
|
|
1504
|
+
* @param tag Tag to update
|
|
1505
|
+
* @returns Updated tag
|
|
1506
|
+
*/
|
|
1507
|
+
async update(tag) {
|
|
1508
|
+
throw new Error(`Provider ${this.name} does not support tag updates`);
|
|
1509
|
+
}
|
|
1510
|
+
/**
|
|
1511
|
+
* Delete a tag (optional)
|
|
1512
|
+
* @param id Tag id to delete
|
|
1513
|
+
*/
|
|
1514
|
+
async delete(id) {
|
|
1515
|
+
throw new Error(`Provider ${this.name} does not support tag deletion`);
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
/**
|
|
1519
|
+
* Injection token for tag providers
|
|
1520
|
+
* Use this to register multiple tag providers
|
|
1521
|
+
*/
|
|
1522
|
+
const AXP_TAG_PROVIDER = new InjectionToken('AXP_TAG_PROVIDER');
|
|
1523
|
+
//#endregion
|
|
1524
|
+
|
|
1525
|
+
//#region ---- Tag Service ----
|
|
1526
|
+
/**
|
|
1527
|
+
* Service for managing tags from multiple providers
|
|
1528
|
+
* Aggregates tags from all registered providers
|
|
1529
|
+
*/
|
|
1530
|
+
class AXPTagService {
|
|
1531
|
+
constructor() {
|
|
1532
|
+
//#region ---- Dependencies ----
|
|
1533
|
+
this.providers = inject(AXP_TAG_PROVIDER, { optional: true }) ?? [];
|
|
1534
|
+
//#endregion
|
|
1535
|
+
//#region ---- State ----
|
|
1536
|
+
this.cache = null;
|
|
1537
|
+
}
|
|
1538
|
+
//#endregion
|
|
1539
|
+
//#region ---- Public API ----
|
|
1540
|
+
/**
|
|
1541
|
+
* Get all tags from all providers
|
|
1542
|
+
* @param options Filter options
|
|
1543
|
+
* @returns Promise of tags
|
|
1544
|
+
*/
|
|
1545
|
+
async getTags(options) {
|
|
1546
|
+
if (!this.cache) {
|
|
1547
|
+
await this.loadTags();
|
|
1548
|
+
}
|
|
1549
|
+
let tags = this.cache;
|
|
1550
|
+
// Apply scope filter
|
|
1551
|
+
if (options?.scope && options.scope.length > 0) {
|
|
1552
|
+
tags = tags.filter((tag) => tag.scope && options.scope.includes(tag.scope));
|
|
1553
|
+
}
|
|
1554
|
+
// Apply search filter
|
|
1555
|
+
if (options?.search) {
|
|
1556
|
+
const searchLower = options.search.toLowerCase();
|
|
1557
|
+
tags = tags.filter((tag) => tag.title.toLowerCase().includes(searchLower) ||
|
|
1558
|
+
tag.description?.toLowerCase().includes(searchLower));
|
|
1559
|
+
}
|
|
1560
|
+
return tags;
|
|
1561
|
+
}
|
|
1562
|
+
/**
|
|
1563
|
+
* Create a new tag using the appropriate provider
|
|
1564
|
+
* @param tag Tag to create
|
|
1565
|
+
* @param providerName Provider to use (defaults to first writable provider)
|
|
1566
|
+
* @returns Created tag
|
|
1567
|
+
*/
|
|
1568
|
+
async createTag(tag, providerName) {
|
|
1569
|
+
const provider = providerName
|
|
1570
|
+
? this.providers.find((p) => p.name === providerName)
|
|
1571
|
+
: this.providers.find((p) => p.create);
|
|
1572
|
+
if (!provider || !provider.create) {
|
|
1573
|
+
throw new Error('No writable tag provider available');
|
|
1574
|
+
}
|
|
1575
|
+
const createdTag = await provider.create(tag);
|
|
1576
|
+
// Invalidate cache
|
|
1577
|
+
this.cache = null;
|
|
1578
|
+
return createdTag;
|
|
1579
|
+
}
|
|
1580
|
+
/**
|
|
1581
|
+
* Update an existing tag
|
|
1582
|
+
* @param tag Tag to update
|
|
1583
|
+
* @returns Updated tag
|
|
1584
|
+
*/
|
|
1585
|
+
async updateTag(tag) {
|
|
1586
|
+
const provider = this.providers.find((p) => p.name === tag.scope && p.update);
|
|
1587
|
+
if (!provider || !provider.update) {
|
|
1588
|
+
throw new Error(`No provider found for updating tag with scope: ${tag.scope}`);
|
|
1589
|
+
}
|
|
1590
|
+
const updatedTag = await provider.update(tag);
|
|
1591
|
+
// Invalidate cache
|
|
1592
|
+
this.cache = null;
|
|
1593
|
+
return updatedTag;
|
|
1594
|
+
}
|
|
1595
|
+
/**
|
|
1596
|
+
* Delete a tag
|
|
1597
|
+
* @param tagId Tag id to delete
|
|
1598
|
+
* @param scope Tag scope
|
|
1599
|
+
*/
|
|
1600
|
+
async deleteTag(tagId, scope) {
|
|
1601
|
+
const provider = this.providers.find((p) => p.name === scope && p.delete);
|
|
1602
|
+
if (!provider || !provider.delete) {
|
|
1603
|
+
throw new Error(`No provider found for deleting tag with scope: ${scope}`);
|
|
1006
1604
|
}
|
|
1605
|
+
await provider.delete(tagId);
|
|
1606
|
+
// Invalidate cache
|
|
1607
|
+
this.cache = null;
|
|
1007
1608
|
}
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1609
|
+
/**
|
|
1610
|
+
* Reload tags from all providers
|
|
1611
|
+
*/
|
|
1612
|
+
async reload() {
|
|
1613
|
+
this.cache = null;
|
|
1614
|
+
await this.loadTags();
|
|
1615
|
+
}
|
|
1616
|
+
//#endregion
|
|
1617
|
+
//#region ---- Private Methods ----
|
|
1618
|
+
/**
|
|
1619
|
+
* Load tags from all providers
|
|
1620
|
+
*/
|
|
1621
|
+
async loadTags() {
|
|
1622
|
+
debugger;
|
|
1623
|
+
const allTags = [];
|
|
1624
|
+
for (const provider of this.providers) {
|
|
1625
|
+
try {
|
|
1626
|
+
const tags = await provider.provide();
|
|
1627
|
+
allTags.push(...tags);
|
|
1628
|
+
}
|
|
1629
|
+
catch (error) {
|
|
1630
|
+
console.error(`Error loading tags from provider ${provider.name}:`, error);
|
|
1631
|
+
}
|
|
1012
1632
|
}
|
|
1633
|
+
// Remove duplicates based on title (case-insensitive)
|
|
1634
|
+
const uniqueTags = allTags.filter((tag, index, self) => index === self.findIndex((t) => t.title.toLowerCase() === tag.title.toLowerCase()));
|
|
1635
|
+
this.cache = uniqueTags;
|
|
1013
1636
|
}
|
|
1014
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type:
|
|
1015
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type:
|
|
1637
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPTagService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1638
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPTagService, providedIn: 'root' }); }
|
|
1016
1639
|
}
|
|
1017
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type:
|
|
1640
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPTagService, decorators: [{
|
|
1018
1641
|
type: Injectable,
|
|
1019
1642
|
args: [{
|
|
1020
1643
|
providedIn: 'root',
|
|
1021
1644
|
}]
|
|
1022
1645
|
}] });
|
|
1023
|
-
function initAppFactory(appInitService) {
|
|
1024
|
-
return () => appInitService.runAllTasks();
|
|
1025
|
-
}
|
|
1026
|
-
const AXPAppStartUpProvider = provideAppInitializer(() => {
|
|
1027
|
-
const initializerFn = initAppFactory(inject(AXPAppStartUpService));
|
|
1028
|
-
return initializerFn();
|
|
1029
|
-
});
|
|
1030
1646
|
|
|
1031
1647
|
/**
|
|
1032
1648
|
* Additional suggested generic actions for future consideration:
|
|
@@ -2382,231 +2998,9 @@ function extractTextFromHtml(value) {
|
|
|
2382
2998
|
return div.textContent || div.innerText || '';
|
|
2383
2999
|
}
|
|
2384
3000
|
|
|
2385
|
-
const AXP_ACTIVITY_LOG_PROVIDER = new InjectionToken('AXP_ACTIVITY_LOGS_PROVIDER');
|
|
2386
|
-
class AXPActivityLogService {
|
|
2387
|
-
constructor() {
|
|
2388
|
-
this.providers = inject(AXP_ACTIVITY_LOG_PROVIDER, { optional: true });
|
|
2389
|
-
}
|
|
2390
|
-
async getHistory(refId, refType, options) {
|
|
2391
|
-
return (await Promise.all(this.providers?.map((p) => p.getHistory(refId, refType, options)) ?? [])).flat();
|
|
2392
|
-
}
|
|
2393
|
-
async getHistoryByIds(refId, refType, ids) {
|
|
2394
|
-
return (await Promise.all(this.providers?.map((p) => p.getHistoryByIds(refId, refType, ids)) ?? [])).flat();
|
|
2395
|
-
}
|
|
2396
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPActivityLogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2397
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPActivityLogService, providedIn: 'root' }); }
|
|
2398
|
-
}
|
|
2399
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPActivityLogService, decorators: [{
|
|
2400
|
-
type: Injectable,
|
|
2401
|
-
args: [{ providedIn: 'root' }]
|
|
2402
|
-
}] });
|
|
2403
|
-
|
|
2404
|
-
class AXPActivityLogProvider {
|
|
2405
|
-
}
|
|
2406
|
-
|
|
2407
|
-
const AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER = new InjectionToken('AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER');
|
|
2408
|
-
|
|
2409
|
-
//#region ---- Imports ----
|
|
2410
|
-
//#endregion
|
|
2411
|
-
class AXPDistributedEventListenerService {
|
|
2412
|
-
constructor() {
|
|
2413
|
-
//#region ---- Providers & Caches ----
|
|
2414
|
-
this.listenerProviders = inject(AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, { optional: true }) || [];
|
|
2415
|
-
this.injector = inject(Injector);
|
|
2416
|
-
/** Cache for listeners by key. */
|
|
2417
|
-
this.listenersByKey = new Map();
|
|
2418
|
-
/** Flag to track if providers have been loaded */
|
|
2419
|
-
this.providersLoaded = false;
|
|
2420
|
-
}
|
|
2421
|
-
//#endregion
|
|
2422
|
-
//#region ---- Public API ----
|
|
2423
|
-
/**
|
|
2424
|
-
* Dispatches an event to all registered listeners for the given key.
|
|
2425
|
-
* @param key The event key.
|
|
2426
|
-
* @param data The event data to pass to listeners.
|
|
2427
|
-
*/
|
|
2428
|
-
async dispatch(key, data) {
|
|
2429
|
-
const providers = await this.resolveProviders();
|
|
2430
|
-
const matched = providers.filter(p => p.key === key);
|
|
2431
|
-
if (!matched.length) {
|
|
2432
|
-
return;
|
|
2433
|
-
}
|
|
2434
|
-
for (const provider of matched) {
|
|
2435
|
-
try {
|
|
2436
|
-
await Promise.resolve(runInInjectionContext(this.injector, () => provider.execute(data)));
|
|
2437
|
-
}
|
|
2438
|
-
catch (err) {
|
|
2439
|
-
console.error(`[AXPDistributedEventListenerService] Provider for key='${key}' failed`, err);
|
|
2440
|
-
}
|
|
2441
|
-
}
|
|
2442
|
-
}
|
|
2443
|
-
/**
|
|
2444
|
-
* Dispatch with async response (first matching provider, with retry/timeout)
|
|
2445
|
-
*/
|
|
2446
|
-
async dispatchAsync(key, data, options = {
|
|
2447
|
-
timeout: 60_000,
|
|
2448
|
-
retries: 3,
|
|
2449
|
-
retryDelay: 1000,
|
|
2450
|
-
}) {
|
|
2451
|
-
const providers = await this.resolveProviders();
|
|
2452
|
-
const matched = providers.filter(p => p.key === key);
|
|
2453
|
-
if (!matched.length) {
|
|
2454
|
-
throw new Error(`No provider found for key='${key}'`);
|
|
2455
|
-
}
|
|
2456
|
-
const attempt = (n) => {
|
|
2457
|
-
return new Promise((resolve, reject) => {
|
|
2458
|
-
let finished = false;
|
|
2459
|
-
const timer = setTimeout(() => {
|
|
2460
|
-
if (!finished) {
|
|
2461
|
-
if (n < options.retries) {
|
|
2462
|
-
resolve(attempt(n + 1));
|
|
2463
|
-
}
|
|
2464
|
-
else {
|
|
2465
|
-
reject(new Error(`Timeout: no response for key='${key}' after ${options.retries} attempts.`));
|
|
2466
|
-
}
|
|
2467
|
-
}
|
|
2468
|
-
}, options.timeout);
|
|
2469
|
-
try {
|
|
2470
|
-
const provider = matched[0];
|
|
2471
|
-
const result = runInInjectionContext(this.injector, () => provider.execute(data));
|
|
2472
|
-
Promise.resolve(result)
|
|
2473
|
-
.then((r) => {
|
|
2474
|
-
finished = true;
|
|
2475
|
-
clearTimeout(timer);
|
|
2476
|
-
resolve(r);
|
|
2477
|
-
})
|
|
2478
|
-
.catch(err => {
|
|
2479
|
-
finished = true;
|
|
2480
|
-
clearTimeout(timer);
|
|
2481
|
-
reject(err);
|
|
2482
|
-
});
|
|
2483
|
-
}
|
|
2484
|
-
catch (err) {
|
|
2485
|
-
clearTimeout(timer);
|
|
2486
|
-
reject(err);
|
|
2487
|
-
}
|
|
2488
|
-
});
|
|
2489
|
-
};
|
|
2490
|
-
return attempt(0);
|
|
2491
|
-
}
|
|
2492
|
-
/**
|
|
2493
|
-
* Resolve all providers (handle both direct provider and Promise<provider>)
|
|
2494
|
-
*/
|
|
2495
|
-
async resolveProviders() {
|
|
2496
|
-
return Promise.all(this.listenerProviders.map(p => p instanceof Promise ? p : Promise.resolve(p)));
|
|
2497
|
-
}
|
|
2498
|
-
/**
|
|
2499
|
-
* Returns all listeners for a specific event key.
|
|
2500
|
-
* @param key The event key.
|
|
2501
|
-
* @returns Array of listeners for the key.
|
|
2502
|
-
*/
|
|
2503
|
-
async getListeners(key) {
|
|
2504
|
-
await this.ensureProvidersLoaded();
|
|
2505
|
-
return this.listenersByKey.get(key) || [];
|
|
2506
|
-
}
|
|
2507
|
-
/**
|
|
2508
|
-
* Returns all registered event keys.
|
|
2509
|
-
* @returns Array of all event keys that have listeners.
|
|
2510
|
-
*/
|
|
2511
|
-
async getRegisteredKeys() {
|
|
2512
|
-
await this.ensureProvidersLoaded();
|
|
2513
|
-
return Array.from(this.listenersByKey.keys());
|
|
2514
|
-
}
|
|
2515
|
-
//#endregion
|
|
2516
|
-
//#region ---- Private Methods ----
|
|
2517
|
-
/**
|
|
2518
|
-
* Ensures that all providers have been loaded and cached.
|
|
2519
|
-
*/
|
|
2520
|
-
async ensureProvidersLoaded() {
|
|
2521
|
-
if (this.providersLoaded) {
|
|
2522
|
-
return;
|
|
2523
|
-
}
|
|
2524
|
-
// Resolve all providers
|
|
2525
|
-
const resolvedProviders = await Promise.all(this.listenerProviders);
|
|
2526
|
-
// Group listeners by key
|
|
2527
|
-
for (const provider of resolvedProviders) {
|
|
2528
|
-
if (provider) {
|
|
2529
|
-
const existingListeners = this.listenersByKey.get(provider.key) || [];
|
|
2530
|
-
existingListeners.push(provider);
|
|
2531
|
-
this.listenersByKey.set(provider.key, existingListeners);
|
|
2532
|
-
}
|
|
2533
|
-
}
|
|
2534
|
-
this.providersLoaded = true;
|
|
2535
|
-
}
|
|
2536
|
-
//#endregion
|
|
2537
|
-
//#region ---- Cache Management ----
|
|
2538
|
-
/** Clears the listeners cache and forces reload on next access. */
|
|
2539
|
-
clearListenersCache() {
|
|
2540
|
-
this.listenersByKey.clear();
|
|
2541
|
-
this.providersLoaded = false;
|
|
2542
|
-
}
|
|
2543
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPDistributedEventListenerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2544
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPDistributedEventListenerService, providedIn: 'root' }); }
|
|
2545
|
-
}
|
|
2546
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPDistributedEventListenerService, decorators: [{
|
|
2547
|
-
type: Injectable,
|
|
2548
|
-
args: [{
|
|
2549
|
-
providedIn: 'root',
|
|
2550
|
-
}]
|
|
2551
|
-
}] });
|
|
2552
|
-
|
|
2553
|
-
class AXPHookService {
|
|
2554
|
-
constructor() {
|
|
2555
|
-
this.listenerProviders = inject(AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, { optional: true }) || [];
|
|
2556
|
-
this.injector = inject(Injector);
|
|
2557
|
-
}
|
|
2558
|
-
/**
|
|
2559
|
-
* Resolve all providers (handle both direct providers and Promise<provider>)
|
|
2560
|
-
*/
|
|
2561
|
-
async resolveProviders() {
|
|
2562
|
-
return Promise.all(this.listenerProviders.map(p => p instanceof Promise ? p : Promise.resolve(p)));
|
|
2563
|
-
}
|
|
2564
|
-
/**
|
|
2565
|
-
* Fire sync hooks (fire-and-forget).
|
|
2566
|
-
* All providers with the given key will be executed.
|
|
2567
|
-
* Execution is not awaited.
|
|
2568
|
-
*/
|
|
2569
|
-
fire(key, data) {
|
|
2570
|
-
this.resolveProviders().then(providers => {
|
|
2571
|
-
providers
|
|
2572
|
-
.filter(p => p.key === key)
|
|
2573
|
-
.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0))
|
|
2574
|
-
.forEach(p => {
|
|
2575
|
-
try {
|
|
2576
|
-
runInInjectionContext(this.injector, () => p.execute(data));
|
|
2577
|
-
}
|
|
2578
|
-
catch (err) {
|
|
2579
|
-
console.error(`[AXPHookService] Hook '${key}' failed`, err);
|
|
2580
|
-
}
|
|
2581
|
-
});
|
|
2582
|
-
});
|
|
2583
|
-
}
|
|
2584
|
-
/**
|
|
2585
|
-
* Run async hooks sequentially (waterfall).
|
|
2586
|
-
* The output of each hook is passed as input to the next hook.
|
|
2587
|
-
* Returns the final merged data after all hooks are executed.
|
|
2588
|
-
*/
|
|
2589
|
-
async runAsync(key, initialData) {
|
|
2590
|
-
const providers = (await this.resolveProviders())
|
|
2591
|
-
.filter(p => p.key === key)
|
|
2592
|
-
.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
2593
|
-
let data = initialData;
|
|
2594
|
-
for (const p of providers) {
|
|
2595
|
-
data = await Promise.resolve(runInInjectionContext(this.injector, () => p.execute(data)));
|
|
2596
|
-
}
|
|
2597
|
-
return data;
|
|
2598
|
-
}
|
|
2599
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPHookService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2600
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPHookService, providedIn: 'root' }); }
|
|
2601
|
-
}
|
|
2602
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AXPHookService, decorators: [{
|
|
2603
|
-
type: Injectable,
|
|
2604
|
-
args: [{ providedIn: 'root' }]
|
|
2605
|
-
}] });
|
|
2606
|
-
|
|
2607
3001
|
/**
|
|
2608
3002
|
* Generated bundle index. Do not edit.
|
|
2609
3003
|
*/
|
|
2610
3004
|
|
|
2611
|
-
export { AXHighlightService, AXPActivityLogProvider, AXPActivityLogService, AXPAppStartUpProvider, AXPAppStartUpService, AXPBroadcastEventService, AXPComponentLogoConfig, AXPContentCheckerDirective, AXPContextChangeEvent, AXPContextStore, AXPCountdownPipe, AXPDataGenerator, AXPDataSourceDefinitionProviderService, AXPDblClickDirective, AXPDistributedEventListenerService, AXPElementDataDirective, AXPExportTemplateToken, AXPExpressionEvaluatorScopeProviderContext, AXPExpressionEvaluatorScopeProviderService, AXPExpressionEvaluatorService, AXPGridLayoutDirective, AXPHookService, AXPImageUrlLogoConfig, AXPPlatformScope, AXPSystemActionType, AXPSystemActions, AXP_ACTIVITY_LOG_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, applyFilterArray, applyPagination, applyQueryArray, applySortArray, applySystemActionDefault, cleanDeep, extractNestedFieldsWildcard, extractTextFromHtml, extractValue, getActionButton, getChangedPaths, getDetailedChanges, getEnumValues, getNestedKeys, getSmart, getSystemActions, objectKeyValueTransforms, resolveActionLook, resolvePlatformScopeKey, resolvePlatformScopeName, setSmart };
|
|
3005
|
+
export { AXHighlightService, AXPActivityLogProvider, AXPActivityLogService, AXPAppStartUpProvider, AXPAppStartUpService, AXPBroadcastEventService, AXPColorPaletteProvider, AXPColorPaletteService, AXPComponentLogoConfig, AXPContentCheckerDirective, AXPContextChangeEvent, AXPContextStore, AXPCountdownPipe, AXPDataGenerator, AXPDataSourceDefinitionProviderService, AXPDblClickDirective, AXPDefaultColorPalettesProvider, AXPDistributedEventListenerService, AXPElementDataDirective, AXPExportTemplateToken, AXPExpressionEvaluatorScopeProviderContext, AXPExpressionEvaluatorScopeProviderService, AXPExpressionEvaluatorService, AXPGridLayoutDirective, AXPHookService, AXPImageUrlLogoConfig, AXPPlatformScope, AXPSystemActionType, AXPSystemActions, AXPTagProvider, AXPTagService, AXP_ACTIVITY_LOG_PROVIDER, AXP_COLOR_PALETTE_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, AXP_TAG_PROVIDER, applyFilterArray, applyPagination, applyQueryArray, applySortArray, applySystemActionDefault, cleanDeep, extractNestedFieldsWildcard, extractTextFromHtml, extractValue, getActionButton, getChangedPaths, getDetailedChanges, getEnumValues, getNestedKeys, getSmart, getSystemActions, objectKeyValueTransforms, resolveActionLook, resolvePlatformScopeKey, resolvePlatformScopeName, setSmart };
|
|
2612
3006
|
//# sourceMappingURL=acorex-platform-core.mjs.map
|