@acorex/platform 19.3.0 → 19.3.2

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.
Files changed (73) hide show
  1. package/common/lib/home-page/home-page-settings.provider.d.ts +1 -0
  2. package/common/lib/utils/index.d.ts +0 -1
  3. package/fesm2022/acorex-platform-common.mjs +3 -135
  4. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  5. package/fesm2022/acorex-platform-layout-components.mjs +277 -0
  6. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -0
  7. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  8. package/fesm2022/acorex-platform-layout-entity.mjs +0 -9
  9. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  10. package/fesm2022/acorex-platform-themes-default.mjs +13 -4
  11. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  12. package/fesm2022/{acorex-platform-widgets-tabular-data-edit-popup.component-CybYV1Kf.mjs → acorex-platform-widgets-tabular-data-edit-popup.component-1IseEVXQ.mjs} +2 -2
  13. package/fesm2022/acorex-platform-widgets-tabular-data-edit-popup.component-1IseEVXQ.mjs.map +1 -0
  14. package/fesm2022/acorex-platform-widgets.mjs +8 -4395
  15. package/fesm2022/acorex-platform-widgets.mjs.map +1 -1
  16. package/layout/components/README.md +3 -0
  17. package/layout/components/index.d.ts +1 -0
  18. package/layout/components/lib/user-avatar/index.d.ts +4 -0
  19. package/layout/components/lib/user-avatar/user-avatar.component.d.ts +38 -0
  20. package/layout/components/lib/user-avatar/user-avatar.provider.d.ts +3 -0
  21. package/layout/components/lib/user-avatar/user-avatar.service.d.ts +42 -0
  22. package/layout/components/lib/user-avatar/user-avatar.types.d.ts +13 -0
  23. package/package.json +5 -1
  24. package/themes/default/lib/layouts/base/page-layout/page-layout.component.d.ts +2 -0
  25. package/widgets/lib/widgets/index.d.ts +0 -11
  26. package/common/lib/utils/data-generator.d.ts +0 -26
  27. package/fesm2022/acorex-platform-widgets-tabular-data-edit-popup.component-CybYV1Kf.mjs.map +0 -1
  28. package/widgets/lib/widgets/charts/bar-chart/bar-chart-widget.component.d.ts +0 -72
  29. package/widgets/lib/widgets/charts/bar-chart/bar-chart-widget.config.d.ts +0 -7
  30. package/widgets/lib/widgets/charts/bar-chart/bar-chart.type.d.ts +0 -34
  31. package/widgets/lib/widgets/charts/bar-chart/index.d.ts +0 -2
  32. package/widgets/lib/widgets/charts/chart.type.d.ts +0 -3
  33. package/widgets/lib/widgets/charts/clock-calendar/clock-calendar-widget.component.d.ts +0 -40
  34. package/widgets/lib/widgets/charts/clock-calendar/clock-calendar-widget.config.d.ts +0 -7
  35. package/widgets/lib/widgets/charts/clock-calendar/clock-calendar.types.d.ts +0 -50
  36. package/widgets/lib/widgets/charts/clock-calendar/index.d.ts +0 -3
  37. package/widgets/lib/widgets/charts/donut-chart/donut-chart-widget.component.d.ts +0 -58
  38. package/widgets/lib/widgets/charts/donut-chart/donut-chart-widget.config.d.ts +0 -7
  39. package/widgets/lib/widgets/charts/donut-chart/donut-chart.type.d.ts +0 -67
  40. package/widgets/lib/widgets/charts/donut-chart/index.d.ts +0 -2
  41. package/widgets/lib/widgets/charts/gauge-chart/gauge-chart-widget.component.d.ts +0 -75
  42. package/widgets/lib/widgets/charts/gauge-chart/gauge-chart-widget.config.d.ts +0 -7
  43. package/widgets/lib/widgets/charts/gauge-chart/gauge-chart.type.d.ts +0 -29
  44. package/widgets/lib/widgets/charts/gauge-chart/index.d.ts +0 -3
  45. package/widgets/lib/widgets/charts/index.d.ts +0 -11
  46. package/widgets/lib/widgets/charts/line-chart/index.d.ts +0 -3
  47. package/widgets/lib/widgets/charts/line-chart/line-chart-widget.component.d.ts +0 -76
  48. package/widgets/lib/widgets/charts/line-chart/line-chart-widget.config.d.ts +0 -7
  49. package/widgets/lib/widgets/charts/line-chart/line-chart.type.d.ts +0 -41
  50. package/widgets/lib/widgets/charts/notification/index.d.ts +0 -3
  51. package/widgets/lib/widgets/charts/notification/notification-widget.component.d.ts +0 -54
  52. package/widgets/lib/widgets/charts/notification/notification-widget.config.d.ts +0 -10
  53. package/widgets/lib/widgets/charts/notification/notification.type.d.ts +0 -47
  54. package/widgets/lib/widgets/charts/shared/chart-base.component.d.ts +0 -44
  55. package/widgets/lib/widgets/charts/shared/chart-base.type.d.ts +0 -37
  56. package/widgets/lib/widgets/charts/shared/components/chart-tooltip/chart-tooltip.component.d.ts +0 -28
  57. package/widgets/lib/widgets/charts/shared/components/chart-tooltip/index.d.ts +0 -1
  58. package/widgets/lib/widgets/charts/shared/index.d.ts +0 -3
  59. package/widgets/lib/widgets/charts/sticky-note/index.d.ts +0 -2
  60. package/widgets/lib/widgets/charts/sticky-note/sticky-note-widget.component.d.ts +0 -21
  61. package/widgets/lib/widgets/charts/sticky-note/sticky-note-widget.config.d.ts +0 -7
  62. package/widgets/lib/widgets/charts/tasklist/index.d.ts +0 -3
  63. package/widgets/lib/widgets/charts/tasklist/tasklist-widget.component.d.ts +0 -34
  64. package/widgets/lib/widgets/charts/tasklist/tasklist-widget.config.d.ts +0 -7
  65. package/widgets/lib/widgets/charts/tasklist/tasklist.type.d.ts +0 -36
  66. package/widgets/lib/widgets/charts/weather/index.d.ts +0 -3
  67. package/widgets/lib/widgets/charts/weather/weather-services/index.d.ts +0 -3
  68. package/widgets/lib/widgets/charts/weather/weather-services/weather-api.abstract.d.ts +0 -174
  69. package/widgets/lib/widgets/charts/weather/weather-services/weather-api.key.d.ts +0 -2
  70. package/widgets/lib/widgets/charts/weather/weather-services/weather-api.mock.service.d.ts +0 -47
  71. package/widgets/lib/widgets/charts/weather/weather-services/weather-api.service.d.ts +0 -48
  72. package/widgets/lib/widgets/charts/weather/weather-widget.component.d.ts +0 -109
  73. package/widgets/lib/widgets/charts/weather/weather-widget.config.d.ts +0 -14
@@ -0,0 +1,277 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, inject, Injectable, signal, input, computed, ViewEncapsulation, Component } from '@angular/core';
3
+ import { BehaviorSubject, timer, Subject, takeUntil } from 'rxjs';
4
+ import { tap } from 'rxjs/operators';
5
+ import { CommonModule } from '@angular/common';
6
+ import { AXBadgeModule } from '@acorex/components/badge';
7
+ import * as i1 from '@acorex/components/avatar';
8
+ import { AXAvatarModule } from '@acorex/components/avatar';
9
+ import * as i2 from '@acorex/components/decorators';
10
+ import { AXDecoratorModule } from '@acorex/components/decorators';
11
+ import * as i3 from '@acorex/components/image';
12
+ import { AXImageModule } from '@acorex/components/image';
13
+
14
+ const AXP_USER_AVATAR_PROVIDER = new InjectionToken('AXP_USER_AVATAR_PROVIDER', {
15
+ providedIn: 'root',
16
+ factory: () => {
17
+ return new AXPUserAvatarProviderDefault();
18
+ }
19
+ });
20
+ class AXPUserAvatarProviderDefault {
21
+ provide(userId) {
22
+ return Promise.resolve({
23
+ id: userId,
24
+ username: 'johndoe',
25
+ firstName: 'John',
26
+ lastName: 'Doe',
27
+ status: 'online',
28
+ avatarUrl: 'https://via.placeholder.com/150',
29
+ });
30
+ }
31
+ }
32
+
33
+ class AXPUserAvatarService {
34
+ constructor() {
35
+ this.provider = inject(AXP_USER_AVATAR_PROVIDER);
36
+ // Cache configuration
37
+ this.cacheExpiryTime = 5 * 60 * 1000; // 5 minutes in milliseconds
38
+ this.refreshInterval = 3 * 60 * 1000; // 3 minutes in milliseconds
39
+ // Cache storage
40
+ this.cache = new Map();
41
+ }
42
+ /**
43
+ * Gets user information with caching and auto-refresh
44
+ * @param userId The username to fetch information for
45
+ * @returns Observable that emits user avatar data
46
+ */
47
+ getUserInfo$(userId) {
48
+ // Check if we have a cached entry
49
+ if (!this.cache.has(userId) || this.isExpired(userId)) {
50
+ // Create a new cache entry with default values
51
+ const defaultData = {
52
+ id: userId,
53
+ status: 'offline',
54
+ username: '',
55
+ firstName: '',
56
+ lastName: ''
57
+ };
58
+ const subject = new BehaviorSubject(defaultData);
59
+ this.cache.set(userId, {
60
+ data: defaultData,
61
+ timestamp: Date.now(),
62
+ subject
63
+ });
64
+ // Fetch fresh data immediately
65
+ this.fetchAndUpdateCache(userId);
66
+ // Set up auto refresh
67
+ timer(this.refreshInterval, this.refreshInterval)
68
+ .pipe(tap(() => this.fetchAndUpdateCache(userId)))
69
+ .subscribe();
70
+ }
71
+ return this.cache.get(userId).subject.asObservable();
72
+ }
73
+ /**
74
+ * Gets user information (Promise-based for backward compatibility)
75
+ * @param userId The username to fetch information for
76
+ * @returns Promise that resolves to user avatar data
77
+ */
78
+ async getUserInfo(userId) {
79
+ // Check if we have an unexpired cached entry
80
+ if (this.cache.has(userId) && !this.isExpired(userId)) {
81
+ return this.cache.get(userId).data;
82
+ }
83
+ // Fetch fresh data and cache it
84
+ return this.fetchAndUpdateCache(userId);
85
+ }
86
+ /**
87
+ * Clears the entire cache or a specific user's cache
88
+ * @param userId Optional username to clear specific cache
89
+ */
90
+ clearCache(userId) {
91
+ if (userId) {
92
+ this.cache.delete(userId);
93
+ }
94
+ else {
95
+ this.cache.clear();
96
+ }
97
+ }
98
+ /**
99
+ * Force refresh data for a specific username
100
+ * @param userId The username to refresh
101
+ * @returns Promise that resolves to the refreshed data
102
+ */
103
+ async refreshUserInfo(userId) {
104
+ return this.fetchAndUpdateCache(userId);
105
+ }
106
+ /**
107
+ * Checks if a cache entry is expired
108
+ */
109
+ isExpired(userId) {
110
+ const entry = this.cache.get(userId);
111
+ if (!entry)
112
+ return true;
113
+ return (Date.now() - entry.timestamp) > this.cacheExpiryTime;
114
+ }
115
+ /**
116
+ * Fetches data from provider and updates the cache
117
+ */
118
+ async fetchAndUpdateCache(userId) {
119
+ try {
120
+ const data = await this.provider.provide(userId);
121
+ console.log('data', data);
122
+ if (!data) {
123
+ throw new Error(`User info not found for ${userId}`);
124
+ }
125
+ const entry = this.cache.get(userId);
126
+ // Update the cache entry
127
+ if (entry) {
128
+ entry.data = data;
129
+ entry.timestamp = Date.now();
130
+ entry.subject.next(data);
131
+ }
132
+ else {
133
+ // Create a new cache entry if needed
134
+ const subject = new BehaviorSubject(data);
135
+ this.cache.set(userId, {
136
+ data,
137
+ timestamp: Date.now(),
138
+ subject
139
+ });
140
+ }
141
+ return data;
142
+ }
143
+ catch (error) {
144
+ console.error(`Error fetching user info for ${userId}:`, error);
145
+ throw error;
146
+ }
147
+ }
148
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPUserAvatarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
149
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPUserAvatarService, providedIn: 'root' }); }
150
+ }
151
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPUserAvatarService, decorators: [{
152
+ type: Injectable,
153
+ args: [{
154
+ providedIn: 'root',
155
+ }]
156
+ }] });
157
+
158
+ class AXPUserAvatarComponent {
159
+ constructor() {
160
+ this.userAvatarService = inject(AXPUserAvatarService);
161
+ this.destroy$ = new Subject();
162
+ this.userInfo = signal(null);
163
+ this.size = input(40);
164
+ this.userId = input('');
165
+ this.src = signal('');
166
+ this.userName = computed(() => this.userInfo()?.username || '');
167
+ this.firstName = computed(() => this.userInfo()?.firstName || '');
168
+ this.lastName = computed(() => this.userInfo()?.lastName || '');
169
+ this.title = computed(() => `${this.firstName()} ${this.lastName()}`);
170
+ this.isOnline = computed(() => this.userInfo()?.status === 'online');
171
+ this.avatarText = computed(() => this.getInitials(this.firstName(), this.lastName()));
172
+ this.avatarColor = computed(() => this.pickColor(this.avatarText()));
173
+ this.hasPicture = signal(false);
174
+ }
175
+ onImageError(event) {
176
+ this.hasPicture.set(false);
177
+ }
178
+ onImageLoad(event) {
179
+ this.hasPicture.set(true);
180
+ }
181
+ ngOnInit() {
182
+ this.loadUserData();
183
+ }
184
+ ngOnDestroy() {
185
+ this.destroy$.next();
186
+ this.destroy$.complete();
187
+ }
188
+ loadUserData() {
189
+ // Skip if no username provided
190
+ if (!this.userId()) {
191
+ return;
192
+ }
193
+ // Subscribe to the user info observable to get real-time updates
194
+ this.userAvatarService.getUserInfo$(this.userId())
195
+ .pipe(takeUntil(this.destroy$))
196
+ .subscribe(userData => {
197
+ this.userInfo.set(userData);
198
+ // This is a placeholder - replace with your actual avatar URL logic
199
+ this.generateAvatarSrc(userData);
200
+ });
201
+ }
202
+ /**
203
+ * Generate avatar image source
204
+ * This is a placeholder - implement based on your actual requirements
205
+ */
206
+ generateAvatarSrc(userData) {
207
+ // Example: Check if the user has a custom avatar URL
208
+ // If not, generate a placeholder using initials
209
+ if (userData.avatarUrl) {
210
+ this.src.set(userData.avatarUrl);
211
+ }
212
+ else {
213
+ // Generate a placeholder - you could use an external service like UI Avatars
214
+ // or implement your own logic
215
+ const initials = this.getInitials(userData.firstName || '', userData.lastName || '');
216
+ this.src.set(`https://avatar.iran.liara.run/username?username=${encodeURIComponent(initials)}`);
217
+ }
218
+ }
219
+ /**
220
+ * Get initials from first and last name
221
+ */
222
+ getInitials(firstName, lastName) {
223
+ const firstInitial = firstName.charAt(0).toUpperCase();
224
+ const lastInitial = lastName.charAt(0).toUpperCase();
225
+ return firstInitial + lastInitial;
226
+ }
227
+ hashString(str) {
228
+ let hash = 0;
229
+ for (let i = 0; i < str.length; i++) {
230
+ hash = (hash << 5) - hash + str.charCodeAt(i);
231
+ hash |= 0;
232
+ }
233
+ return Math.abs(hash);
234
+ }
235
+ pickColor(initials) {
236
+ const colors = [
237
+ 'primary',
238
+ 'secondary',
239
+ 'danger',
240
+ 'warning',
241
+ 'success',
242
+ 'accent1',
243
+ 'accent2',
244
+ 'accent3',
245
+ ];
246
+ const idx = this.hashString(initials) % colors.length;
247
+ return colors[idx];
248
+ }
249
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPUserAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
250
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.3", type: AXPUserAvatarComponent, isStandalone: true, selector: "axp-user-avatar", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userId: { classPropertyName: "userId", publicName: "userId", isSignal: true, isRequired: false, transformFunction: null } }, providers: [], ngImport: i0, template: "<ax-avatar #avatar [size]=\"size()\" class=\"ax-cursor-pointer\">\n @if(hasPicture()){\n <ax-image (onError)=\"onImageError($event)\" (onLoad)=\"onImageLoad($event)\" [src]=\"src()\"></ax-image>\n }@else{\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n }\n</ax-avatar>\n\n<!--\n\nax-primary-lightest\nax-warning-lightest\nax-success-lightest\nax-danger-lightest\nax-secondary-lightest\nax-accent1-lightest\nax-accent2-lightest\nax-accent3-lightest\n\n-->\n", styles: [""], dependencies: [{ kind: "ngmodule", type:
251
+ // Angular
252
+ CommonModule }, { kind: "ngmodule", type:
253
+ // ACoreX
254
+ AXAvatarModule }, { kind: "component", type: i1.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXImageModule }, { kind: "component", type: i3.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type:
255
+ // Platform
256
+ AXBadgeModule }], encapsulation: i0.ViewEncapsulation.None }); }
257
+ }
258
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPUserAvatarComponent, decorators: [{
259
+ type: Component,
260
+ args: [{ selector: 'axp-user-avatar', imports: [
261
+ // Angular
262
+ CommonModule,
263
+ // ACoreX
264
+ AXAvatarModule,
265
+ AXDecoratorModule,
266
+ AXImageModule,
267
+ // Platform
268
+ AXBadgeModule
269
+ ], encapsulation: ViewEncapsulation.None, providers: [], template: "<ax-avatar #avatar [size]=\"size()\" class=\"ax-cursor-pointer\">\n @if(hasPicture()){\n <ax-image (onError)=\"onImageError($event)\" (onLoad)=\"onImageLoad($event)\" [src]=\"src()\"></ax-image>\n }@else{\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n }\n</ax-avatar>\n\n<!--\n\nax-primary-lightest\nax-warning-lightest\nax-success-lightest\nax-danger-lightest\nax-secondary-lightest\nax-accent1-lightest\nax-accent2-lightest\nax-accent3-lightest\n\n-->\n" }]
270
+ }] });
271
+
272
+ /**
273
+ * Generated bundle index. Do not edit.
274
+ */
275
+
276
+ export { AXPUserAvatarComponent, AXPUserAvatarService, AXP_USER_AVATAR_PROVIDER };
277
+ //# sourceMappingURL=acorex-platform-layout-components.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-layout-components.mjs","sources":["../../../../libs/platform/layout/components/src/lib/user-avatar/user-avatar.provider.ts","../../../../libs/platform/layout/components/src/lib/user-avatar/user-avatar.service.ts","../../../../libs/platform/layout/components/src/lib/user-avatar/user-avatar.component.ts","../../../../libs/platform/layout/components/src/lib/user-avatar/user-avatar.component.html","../../../../libs/platform/layout/components/src/acorex-platform-layout-components.ts"],"sourcesContent":["import { InjectionToken } from \"@angular/core\";\nimport { AXPUserAvatarData, AXPUserAvatarProvider } from \"./user-avatar.types\";\n\nexport const AXP_USER_AVATAR_PROVIDER = new InjectionToken<AXPUserAvatarProvider>(\n 'AXP_USER_AVATAR_PROVIDER',\n {\n providedIn: 'root',\n factory: () => {\n return new AXPUserAvatarProviderDefault();\n }\n }\n);\n\n\nclass AXPUserAvatarProviderDefault implements AXPUserAvatarProvider {\n provide(userId: string): Promise<AXPUserAvatarData> {\n return Promise.resolve({\n id: userId,\n username: 'johndoe',\n firstName: 'John',\n lastName: 'Doe',\n status: 'online',\n avatarUrl: 'https://via.placeholder.com/150',\n });\n }\n}\n","import { inject, Injectable } from \"@angular/core\";\nimport { AXPUserAvatarData } from \"./user-avatar.types\";\nimport { AXP_USER_AVATAR_PROVIDER } from \"./user-avatar.provider\";\nimport { BehaviorSubject, Observable, timer } from 'rxjs';\nimport { map, shareReplay, switchMap, tap } from 'rxjs/operators';\n\ninterface CacheEntry {\n data: AXPUserAvatarData;\n timestamp: number;\n subject: BehaviorSubject<AXPUserAvatarData>;\n}\n\n@Injectable({\n providedIn: 'root',\n})\nexport class AXPUserAvatarService {\n private provider = inject(AXP_USER_AVATAR_PROVIDER);\n\n // Cache configuration\n private readonly cacheExpiryTime = 5 * 60 * 1000; // 5 minutes in milliseconds\n private readonly refreshInterval = 3 * 60 * 1000; // 3 minutes in milliseconds\n\n // Cache storage\n private cache = new Map<string, CacheEntry>();\n\n /**\n * Gets user information with caching and auto-refresh\n * @param userId The username to fetch information for\n * @returns Observable that emits user avatar data\n */\n getUserInfo$(userId: string): Observable<AXPUserAvatarData> {\n // Check if we have a cached entry\n if (!this.cache.has(userId) || this.isExpired(userId)) {\n // Create a new cache entry with default values\n const defaultData: AXPUserAvatarData = {\n id: userId,\n status: 'offline',\n username: '',\n firstName: '',\n lastName: ''\n };\n const subject = new BehaviorSubject<AXPUserAvatarData>(defaultData);\n this.cache.set(userId, {\n data: defaultData,\n timestamp: Date.now(),\n subject\n });\n\n // Fetch fresh data immediately\n this.fetchAndUpdateCache(userId);\n\n // Set up auto refresh\n timer(this.refreshInterval, this.refreshInterval)\n .pipe(\n tap(() => this.fetchAndUpdateCache(userId))\n )\n .subscribe();\n }\n\n return this.cache.get(userId)!.subject.asObservable();\n }\n\n /**\n * Gets user information (Promise-based for backward compatibility)\n * @param userId The username to fetch information for\n * @returns Promise that resolves to user avatar data\n */\n async getUserInfo(userId: string): Promise<AXPUserAvatarData> {\n // Check if we have an unexpired cached entry\n if (this.cache.has(userId) && !this.isExpired(userId)) {\n return this.cache.get(userId)!.data;\n }\n\n // Fetch fresh data and cache it\n return this.fetchAndUpdateCache(userId);\n }\n\n /**\n * Clears the entire cache or a specific user's cache\n * @param userId Optional username to clear specific cache\n */\n clearCache(userId?: string): void {\n if (userId) {\n this.cache.delete(userId);\n } else {\n this.cache.clear();\n }\n }\n\n /**\n * Force refresh data for a specific username\n * @param userId The username to refresh\n * @returns Promise that resolves to the refreshed data\n */\n async refreshUserInfo(userId: string): Promise<AXPUserAvatarData> {\n return this.fetchAndUpdateCache(userId);\n }\n\n /**\n * Checks if a cache entry is expired\n */\n private isExpired(userId: string): boolean {\n const entry = this.cache.get(userId);\n if (!entry) return true;\n\n return (Date.now() - entry.timestamp) > this.cacheExpiryTime;\n }\n\n /**\n * Fetches data from provider and updates the cache\n */\n private async fetchAndUpdateCache(userId: string): Promise<AXPUserAvatarData> {\n try {\n const data = await this.provider.provide(userId);\n\n console.log('data', data);\n if (!data) {\n throw new Error(`User info not found for ${userId}`);\n }\n const entry = this.cache.get(userId);\n\n // Update the cache entry\n if (entry) {\n entry.data = data;\n entry.timestamp = Date.now();\n entry.subject.next(data);\n } else {\n // Create a new cache entry if needed\n const subject = new BehaviorSubject<AXPUserAvatarData>(data);\n this.cache.set(userId, {\n data,\n timestamp: Date.now(),\n subject\n });\n }\n\n return data;\n } catch (error) {\n console.error(`Error fetching user info for ${userId}:`, error);\n throw error;\n }\n }\n}","import { Component, OnDestroy, OnInit, ViewEncapsulation, computed, inject, input, signal } from '@angular/core';\n\nimport { CommonModule } from '@angular/common';\nimport { AXBadgeModule } from '@acorex/components/badge';\nimport { AXPUserAvatarService } from './user-avatar.service';\nimport { Subject, takeUntil } from 'rxjs';\nimport { AXAvatarModule } from '@acorex/components/avatar';\nimport { AXHtmlEvent } from '@acorex/components/common';\nimport { AXPUserAvatarData } from './user-avatar.types';\nimport { AXDecoratorModule } from '@acorex/components/decorators';\nimport { AXImageModule } from '@acorex/components/image';\nimport { AXPDataGenerator } from '@acorex/platform/core';\n\n@Component({\n selector: 'axp-user-avatar',\n templateUrl: './user-avatar.component.html',\n styleUrl: './user-avatar.component.scss',\n imports: [\n // Angular\n CommonModule,\n // ACoreX\n AXAvatarModule,\n AXDecoratorModule,\n AXImageModule,\n // Platform\n AXBadgeModule\n ],\n encapsulation: ViewEncapsulation.None,\n providers: [],\n})\nexport class AXPUserAvatarComponent implements OnInit, OnDestroy {\n private readonly userAvatarService = inject(AXPUserAvatarService);\n private readonly destroy$ = new Subject<void>();\n\n protected userInfo = signal<AXPUserAvatarData | null>(null);\n\n\n size = input<number>(40);\n userId = input<string>('');\n\n src = signal<string>('');\n userName = computed(() => this.userInfo()?.username || '');\n firstName = computed(() => this.userInfo()?.firstName || '');\n lastName = computed(() => this.userInfo()?.lastName || '');\n title = computed(() => `${this.firstName()} ${this.lastName()}`);\n isOnline = computed(() => this.userInfo()?.status === 'online');\n\n avatarText = computed(() => this.getInitials(this.firstName(), this.lastName()));\n avatarColor = computed(() => this.pickColor(this.avatarText()));\n\n protected hasPicture = signal(false);\n\n protected onImageError(event: AXHtmlEvent<ErrorEvent>) {\n this.hasPicture.set(false);\n }\n\n protected onImageLoad(event: AXHtmlEvent<Event>) {\n this.hasPicture.set(true);\n }\n\n ngOnInit(): void {\n this.loadUserData();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private loadUserData(): void {\n // Skip if no username provided\n if (!this.userId()) {\n return;\n }\n\n // Subscribe to the user info observable to get real-time updates\n this.userAvatarService.getUserInfo$(this.userId())\n .pipe(takeUntil(this.destroy$))\n .subscribe(userData => {\n this.userInfo.set(userData);\n // This is a placeholder - replace with your actual avatar URL logic\n this.generateAvatarSrc(userData);\n });\n }\n\n /**\n * Generate avatar image source\n * This is a placeholder - implement based on your actual requirements\n */\n private generateAvatarSrc(userData: any): void {\n // Example: Check if the user has a custom avatar URL\n // If not, generate a placeholder using initials\n if (userData.avatarUrl) {\n this.src.set(userData.avatarUrl);\n } else {\n // Generate a placeholder - you could use an external service like UI Avatars\n // or implement your own logic\n const initials = this.getInitials(userData.firstName || '', userData.lastName || '');\n this.src.set(`https://avatar.iran.liara.run/username?username=${encodeURIComponent(initials)}`);\n }\n }\n\n /**\n * Get initials from first and last name\n */\n private getInitials(firstName: string, lastName: string): string {\n const firstInitial = firstName.charAt(0).toUpperCase();\n const lastInitial = lastName.charAt(0).toUpperCase();\n return firstInitial + lastInitial;\n }\n\n private hashString(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) - hash + str.charCodeAt(i);\n hash |= 0;\n }\n return Math.abs(hash);\n }\n\n private pickColor(initials: string): string {\n const colors = [\n 'primary',\n 'secondary',\n 'danger',\n 'warning',\n 'success',\n 'accent1',\n 'accent2',\n 'accent3',\n ];\n const idx = this.hashString(initials) % colors.length;\n return colors[idx];\n }\n\n\n}\n","<ax-avatar #avatar [size]=\"size()\" class=\"ax-cursor-pointer\">\n @if(hasPicture()){\n <ax-image (onError)=\"onImageError($event)\" (onLoad)=\"onImageLoad($event)\" [src]=\"src()\"></ax-image>\n }@else{\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n }\n</ax-avatar>\n\n<!--\n\nax-primary-lightest\nax-warning-lightest\nax-success-lightest\nax-danger-lightest\nax-secondary-lightest\nax-accent1-lightest\nax-accent2-lightest\nax-accent3-lightest\n\n-->\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}