@acorex/platform 19.3.1 → 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.
@@ -1,17 +1,15 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, Injectable, input, signal, computed, ViewEncapsulation, Component } from '@angular/core';
2
+ import { InjectionToken, inject, Injectable, signal, input, computed, ViewEncapsulation, Component } from '@angular/core';
3
3
  import { BehaviorSubject, timer, Subject, takeUntil } from 'rxjs';
4
4
  import { tap } from 'rxjs/operators';
5
- import { AXFormModule } from '@acorex/components/form';
6
- import { AXButtonModule } from '@acorex/components/button';
7
- import { AXTextBoxModule } from '@acorex/components/text-box';
8
- import { AXCheckBoxModule } from '@acorex/components/check-box';
9
- import { AXLabelModule } from '@acorex/components/label';
10
5
  import { CommonModule } from '@angular/common';
11
- import * as i1 from '@acorex/components/image';
12
- import { AXImageModule } from '@acorex/components/image';
13
- import * as i2 from '@acorex/components/badge';
14
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';
15
13
 
16
14
  const AXP_USER_AVATAR_PROVIDER = new InjectionToken('AXP_USER_AVATAR_PROVIDER', {
17
15
  providedIn: 'root',
@@ -20,9 +18,10 @@ const AXP_USER_AVATAR_PROVIDER = new InjectionToken('AXP_USER_AVATAR_PROVIDER',
20
18
  }
21
19
  });
22
20
  class AXPUserAvatarProviderDefault {
23
- provide(username) {
21
+ provide(userId) {
24
22
  return Promise.resolve({
25
- username: username,
23
+ id: userId,
24
+ username: 'johndoe',
26
25
  firstName: 'John',
27
26
  lastName: 'Doe',
28
27
  status: 'online',
@@ -42,54 +41,55 @@ class AXPUserAvatarService {
42
41
  }
43
42
  /**
44
43
  * Gets user information with caching and auto-refresh
45
- * @param username The username to fetch information for
44
+ * @param userId The username to fetch information for
46
45
  * @returns Observable that emits user avatar data
47
46
  */
48
- getUserInfo$(username) {
47
+ getUserInfo$(userId) {
49
48
  // Check if we have a cached entry
50
- if (!this.cache.has(username) || this.isExpired(username)) {
49
+ if (!this.cache.has(userId) || this.isExpired(userId)) {
51
50
  // Create a new cache entry with default values
52
51
  const defaultData = {
52
+ id: userId,
53
53
  status: 'offline',
54
- username: username,
54
+ username: '',
55
55
  firstName: '',
56
56
  lastName: ''
57
57
  };
58
58
  const subject = new BehaviorSubject(defaultData);
59
- this.cache.set(username, {
59
+ this.cache.set(userId, {
60
60
  data: defaultData,
61
61
  timestamp: Date.now(),
62
62
  subject
63
63
  });
64
64
  // Fetch fresh data immediately
65
- this.fetchAndUpdateCache(username);
65
+ this.fetchAndUpdateCache(userId);
66
66
  // Set up auto refresh
67
67
  timer(this.refreshInterval, this.refreshInterval)
68
- .pipe(tap(() => this.fetchAndUpdateCache(username)))
68
+ .pipe(tap(() => this.fetchAndUpdateCache(userId)))
69
69
  .subscribe();
70
70
  }
71
- return this.cache.get(username).subject.asObservable();
71
+ return this.cache.get(userId).subject.asObservable();
72
72
  }
73
73
  /**
74
74
  * Gets user information (Promise-based for backward compatibility)
75
- * @param username The username to fetch information for
75
+ * @param userId The username to fetch information for
76
76
  * @returns Promise that resolves to user avatar data
77
77
  */
78
- async getUserInfo(username) {
78
+ async getUserInfo(userId) {
79
79
  // Check if we have an unexpired cached entry
80
- if (this.cache.has(username) && !this.isExpired(username)) {
81
- return this.cache.get(username).data;
80
+ if (this.cache.has(userId) && !this.isExpired(userId)) {
81
+ return this.cache.get(userId).data;
82
82
  }
83
83
  // Fetch fresh data and cache it
84
- return this.fetchAndUpdateCache(username);
84
+ return this.fetchAndUpdateCache(userId);
85
85
  }
86
86
  /**
87
87
  * Clears the entire cache or a specific user's cache
88
- * @param username Optional username to clear specific cache
88
+ * @param userId Optional username to clear specific cache
89
89
  */
90
- clearCache(username) {
91
- if (username) {
92
- this.cache.delete(username);
90
+ clearCache(userId) {
91
+ if (userId) {
92
+ this.cache.delete(userId);
93
93
  }
94
94
  else {
95
95
  this.cache.clear();
@@ -97,17 +97,17 @@ class AXPUserAvatarService {
97
97
  }
98
98
  /**
99
99
  * Force refresh data for a specific username
100
- * @param username The username to refresh
100
+ * @param userId The username to refresh
101
101
  * @returns Promise that resolves to the refreshed data
102
102
  */
103
- async refreshUserInfo(username) {
104
- return this.fetchAndUpdateCache(username);
103
+ async refreshUserInfo(userId) {
104
+ return this.fetchAndUpdateCache(userId);
105
105
  }
106
106
  /**
107
107
  * Checks if a cache entry is expired
108
108
  */
109
- isExpired(username) {
110
- const entry = this.cache.get(username);
109
+ isExpired(userId) {
110
+ const entry = this.cache.get(userId);
111
111
  if (!entry)
112
112
  return true;
113
113
  return (Date.now() - entry.timestamp) > this.cacheExpiryTime;
@@ -115,10 +115,14 @@ class AXPUserAvatarService {
115
115
  /**
116
116
  * Fetches data from provider and updates the cache
117
117
  */
118
- async fetchAndUpdateCache(username) {
118
+ async fetchAndUpdateCache(userId) {
119
119
  try {
120
- const data = await this.provider.provide(username);
121
- const entry = this.cache.get(username);
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);
122
126
  // Update the cache entry
123
127
  if (entry) {
124
128
  entry.data = data;
@@ -128,7 +132,7 @@ class AXPUserAvatarService {
128
132
  else {
129
133
  // Create a new cache entry if needed
130
134
  const subject = new BehaviorSubject(data);
131
- this.cache.set(username, {
135
+ this.cache.set(userId, {
132
136
  data,
133
137
  timestamp: Date.now(),
134
138
  subject
@@ -137,7 +141,7 @@ class AXPUserAvatarService {
137
141
  return data;
138
142
  }
139
143
  catch (error) {
140
- console.error(`Error fetching user info for ${username}:`, error);
144
+ console.error(`Error fetching user info for ${userId}:`, error);
141
145
  throw error;
142
146
  }
143
147
  }
@@ -155,13 +159,24 @@ class AXPUserAvatarComponent {
155
159
  constructor() {
156
160
  this.userAvatarService = inject(AXPUserAvatarService);
157
161
  this.destroy$ = new Subject();
162
+ this.userInfo = signal(null);
158
163
  this.size = input(40);
159
- this.username = input('');
164
+ this.userId = input('');
160
165
  this.src = signal('');
161
- this.firstName = signal('');
162
- this.lastName = signal('');
166
+ this.userName = computed(() => this.userInfo()?.username || '');
167
+ this.firstName = computed(() => this.userInfo()?.firstName || '');
168
+ this.lastName = computed(() => this.userInfo()?.lastName || '');
163
169
  this.title = computed(() => `${this.firstName()} ${this.lastName()}`);
164
- this.isOnline = signal(false);
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);
165
180
  }
166
181
  ngOnInit() {
167
182
  this.loadUserData();
@@ -172,18 +187,14 @@ class AXPUserAvatarComponent {
172
187
  }
173
188
  loadUserData() {
174
189
  // Skip if no username provided
175
- if (!this.username()) {
190
+ if (!this.userId()) {
176
191
  return;
177
192
  }
178
193
  // Subscribe to the user info observable to get real-time updates
179
- this.userAvatarService.getUserInfo$(this.username())
194
+ this.userAvatarService.getUserInfo$(this.userId())
180
195
  .pipe(takeUntil(this.destroy$))
181
196
  .subscribe(userData => {
182
- // Update component signals with user data
183
- this.firstName.set(userData.firstName || '');
184
- this.lastName.set(userData.lastName || '');
185
- this.isOnline.set(userData.status === 'online');
186
- // Generate avatar image source if needed
197
+ this.userInfo.set(userData);
187
198
  // This is a placeholder - replace with your actual avatar URL logic
188
199
  this.generateAvatarSrc(userData);
189
200
  });
@@ -202,7 +213,7 @@ class AXPUserAvatarComponent {
202
213
  // Generate a placeholder - you could use an external service like UI Avatars
203
214
  // or implement your own logic
204
215
  const initials = this.getInitials(userData.firstName || '', userData.lastName || '');
205
- this.src.set(`https://ui-avatars.com/api/?name=${encodeURIComponent(initials)}&size=${this.size()}&background=random`);
216
+ this.src.set(`https://avatar.iran.liara.run/username?username=${encodeURIComponent(initials)}`);
206
217
  }
207
218
  }
208
219
  /**
@@ -213,14 +224,36 @@ class AXPUserAvatarComponent {
213
224
  const lastInitial = lastName.charAt(0).toUpperCase();
214
225
  return firstInitial + lastInitial;
215
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
+ }
216
249
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPUserAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
217
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.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 }, username: { classPropertyName: "username", publicName: "username", isSignal: true, isRequired: false, transformFunction: null } }, providers: [], ngImport: i0, template: "<ax-image [src]=\"src()\" [alt]=\"title()\" [width]=\"size()\" [height]=\"size()\">\n <ax-badge [color]=\"isOnline() ? 'success' : 'danger'\"></ax-badge>\n</ax-image>\n", styles: [""], dependencies: [{ kind: "ngmodule", type:
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:
218
251
  // Angular
219
252
  CommonModule }, { kind: "ngmodule", type:
220
253
  // ACoreX
221
- AXFormModule }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXLabelModule }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "ngmodule", type:
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:
222
255
  // Platform
223
- AXImageModule }, { kind: "component", type: i1.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }], encapsulation: i0.ViewEncapsulation.None }); }
256
+ AXBadgeModule }], encapsulation: i0.ViewEncapsulation.None }); }
224
257
  }
225
258
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPUserAvatarComponent, decorators: [{
226
259
  type: Component,
@@ -228,15 +261,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
228
261
  // Angular
229
262
  CommonModule,
230
263
  // ACoreX
231
- AXFormModule,
232
- AXTextBoxModule,
233
- AXButtonModule,
234
- AXLabelModule,
235
- AXCheckBoxModule,
236
- // Platform
264
+ AXAvatarModule,
265
+ AXDecoratorModule,
237
266
  AXImageModule,
267
+ // Platform
238
268
  AXBadgeModule
239
- ], encapsulation: ViewEncapsulation.None, providers: [], template: "<ax-image [src]=\"src()\" [alt]=\"title()\" [width]=\"size()\" [height]=\"size()\">\n <ax-badge [color]=\"isOnline() ? 'success' : 'danger'\"></ax-badge>\n</ax-image>\n" }]
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" }]
240
270
  }] });
241
271
 
242
272
  /**
@@ -1 +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(username: string): Promise<AXPUserAvatarData> {\n return Promise.resolve({\n username: username,\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 username The username to fetch information for\n * @returns Observable that emits user avatar data\n */\n getUserInfo$(username: string): Observable<AXPUserAvatarData> {\n // Check if we have a cached entry\n if (!this.cache.has(username) || this.isExpired(username)) {\n // Create a new cache entry with default values\n const defaultData: AXPUserAvatarData = {\n status: 'offline',\n username: username,\n firstName: '',\n lastName: ''\n };\n const subject = new BehaviorSubject<AXPUserAvatarData>(defaultData);\n this.cache.set(username, {\n data: defaultData,\n timestamp: Date.now(),\n subject\n });\n\n // Fetch fresh data immediately\n this.fetchAndUpdateCache(username);\n\n // Set up auto refresh\n timer(this.refreshInterval, this.refreshInterval)\n .pipe(\n tap(() => this.fetchAndUpdateCache(username))\n )\n .subscribe();\n }\n\n return this.cache.get(username)!.subject.asObservable();\n }\n\n /**\n * Gets user information (Promise-based for backward compatibility)\n * @param username The username to fetch information for\n * @returns Promise that resolves to user avatar data\n */\n async getUserInfo(username: string): Promise<AXPUserAvatarData> {\n // Check if we have an unexpired cached entry\n if (this.cache.has(username) && !this.isExpired(username)) {\n return this.cache.get(username)!.data;\n }\n\n // Fetch fresh data and cache it\n return this.fetchAndUpdateCache(username);\n }\n\n /**\n * Clears the entire cache or a specific user's cache\n * @param username Optional username to clear specific cache\n */\n clearCache(username?: string): void {\n if (username) {\n this.cache.delete(username);\n } else {\n this.cache.clear();\n }\n }\n\n /**\n * Force refresh data for a specific username\n * @param username The username to refresh\n * @returns Promise that resolves to the refreshed data\n */\n async refreshUserInfo(username: string): Promise<AXPUserAvatarData> {\n return this.fetchAndUpdateCache(username);\n }\n\n /**\n * Checks if a cache entry is expired\n */\n private isExpired(username: string): boolean {\n const entry = this.cache.get(username);\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(username: string): Promise<AXPUserAvatarData> {\n try {\n const data = await this.provider.provide(username);\n const entry = this.cache.get(username);\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(username, {\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 ${username}:`, error);\n throw error;\n }\n }\n}","import { Component, OnDestroy, OnInit, ViewEncapsulation, computed, inject, input, signal } from '@angular/core';\n\nimport { AXFormModule } from '@acorex/components/form';\nimport { AXButtonModule } from '@acorex/components/button';\nimport { AXTextBoxModule } from '@acorex/components/text-box';\nimport { AXCheckBoxModule } from '@acorex/components/check-box';\nimport { AXLabelModule } from '@acorex/components/label';\nimport { CommonModule } from '@angular/common';\nimport { AXImageModule } from '@acorex/components/image';\nimport { AXBadgeModule } from '@acorex/components/badge';\nimport { AXPUserAvatarService } from './user-avatar.service';\nimport { Subject, takeUntil } from 'rxjs';\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 AXFormModule,\n AXTextBoxModule,\n AXButtonModule,\n AXLabelModule,\n AXCheckBoxModule,\n // Platform\n AXImageModule,\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 size = input<number>(40);\n username = input<string>('');\n\n src = signal<string>('');\n firstName = signal<string>('');\n lastName = signal<string>('');\n title = computed(() => `${this.firstName()} ${this.lastName()}`);\n isOnline = signal<boolean>(false);\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.username()) {\n return;\n }\n\n // Subscribe to the user info observable to get real-time updates\n this.userAvatarService.getUserInfo$(this.username())\n .pipe(takeUntil(this.destroy$))\n .subscribe(userData => {\n // Update component signals with user data\n this.firstName.set(userData.firstName || '');\n this.lastName.set(userData.lastName || '');\n this.isOnline.set(userData.status === 'online');\n\n // Generate avatar image source if needed\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://ui-avatars.com/api/?name=${encodeURIComponent(initials)}&size=${this.size()}&background=random`);\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","<ax-image [src]=\"src()\" [alt]=\"title()\" [width]=\"size()\" [height]=\"size()\">\n <ax-badge [color]=\"isOnline() ? 'success' : 'danger'\"></ax-badge>\n</ax-image>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
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":";;;;;;;;;;;;;MAGa,wBAAwB,GAAG,IAAI,cAAc,CACtD,0BAA0B,EAC1B;AACI,IAAA,UAAU,EAAE,MAAM;IAClB,OAAO,EAAE,MAAK;QACV,OAAO,IAAI,4BAA4B,EAAE;;AAEhD,CAAA;AAIL,MAAM,4BAA4B,CAAA;AAC9B,IAAA,OAAO,CAAC,MAAc,EAAA;QAClB,OAAO,OAAO,CAAC,OAAO,CAAC;AACnB,YAAA,EAAE,EAAE,MAAM;AACV,YAAA,QAAQ,EAAE,SAAS;AACnB,YAAA,SAAS,EAAE,MAAM;AACjB,YAAA,QAAQ,EAAE,KAAK;AACf,YAAA,MAAM,EAAE,QAAQ;AAChB,YAAA,SAAS,EAAE,iCAAiC;AAC/C,SAAA,CAAC;;AAET;;MCVY,oBAAoB,CAAA;AAHjC,IAAA,WAAA,GAAA;AAIY,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,wBAAwB,CAAC;;QAGlC,IAAe,CAAA,eAAA,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QAChC,IAAe,CAAA,eAAA,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;;AAGzC,QAAA,IAAA,CAAA,KAAK,GAAG,IAAI,GAAG,EAAsB;AAuHhD;AArHG;;;;AAIG;AACH,IAAA,YAAY,CAAC,MAAc,EAAA;;AAEvB,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;;AAEnD,YAAA,MAAM,WAAW,GAAsB;AACnC,gBAAA,EAAE,EAAE,MAAM;AACV,gBAAA,MAAM,EAAE,SAAS;AACjB,gBAAA,QAAQ,EAAE,EAAE;AACZ,gBAAA,SAAS,EAAE,EAAE;AACb,gBAAA,QAAQ,EAAE;aACb;AACD,YAAA,MAAM,OAAO,GAAG,IAAI,eAAe,CAAoB,WAAW,CAAC;AACnE,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE;AACnB,gBAAA,IAAI,EAAE,WAAW;AACjB,gBAAA,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gBACrB;AACH,aAAA,CAAC;;AAGF,YAAA,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC;;YAGhC,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,eAAe;AAC3C,iBAAA,IAAI,CACD,GAAG,CAAC,MAAM,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAE9C,iBAAA,SAAS,EAAE;;AAGpB,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC,OAAO,CAAC,YAAY,EAAE;;AAGzD;;;;AAIG;IACH,MAAM,WAAW,CAAC,MAAc,EAAA;;AAE5B,QAAA,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;YACnD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC,IAAI;;;AAIvC,QAAA,OAAO,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC;;AAG3C;;;AAGG;AACH,IAAA,UAAU,CAAC,MAAe,EAAA;QACtB,IAAI,MAAM,EAAE;AACR,YAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;;aACtB;AACH,YAAA,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;;;AAI1B;;;;AAIG;IACH,MAAM,eAAe,CAAC,MAAc,EAAA;AAChC,QAAA,OAAO,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC;;AAG3C;;AAEG;AACK,IAAA,SAAS,CAAC,MAAc,EAAA;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;AACpC,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,IAAI;AAEvB,QAAA,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,eAAe;;AAGhE;;AAEG;IACK,MAAM,mBAAmB,CAAC,MAAc,EAAA;AAC5C,QAAA,IAAI;YACA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;AAEhD,YAAA,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC;YACzB,IAAI,CAAC,IAAI,EAAE;AACP,gBAAA,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAA,CAAE,CAAC;;YAExD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;;YAGpC,IAAI,KAAK,EAAE;AACP,gBAAA,KAAK,CAAC,IAAI,GAAG,IAAI;AACjB,gBAAA,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;AAC5B,gBAAA,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;;iBACrB;;AAEH,gBAAA,MAAM,OAAO,GAAG,IAAI,eAAe,CAAoB,IAAI,CAAC;AAC5D,gBAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE;oBACnB,IAAI;AACJ,oBAAA,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;oBACrB;AACH,iBAAA,CAAC;;AAGN,YAAA,OAAO,IAAI;;QACb,OAAO,KAAK,EAAE;YACZ,OAAO,CAAC,KAAK,CAAC,CAAA,6BAAA,EAAgC,MAAM,CAAG,CAAA,CAAA,EAAE,KAAK,CAAC;AAC/D,YAAA,MAAM,KAAK;;;8GA5HV,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAApB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,oBAAoB,cAFjB,MAAM,EAAA,CAAA,CAAA;;2FAET,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAHhC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,UAAU,EAAE,MAAM;AACrB,iBAAA;;;MCgBY,sBAAsB,CAAA;AAjBnC,IAAA,WAAA,GAAA;AAkBqB,QAAA,IAAA,CAAA,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,CAAC;AAChD,QAAA,IAAA,CAAA,QAAQ,GAAG,IAAI,OAAO,EAAQ;AAErC,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAA2B,IAAI,CAAC;AAG3D,QAAA,IAAA,CAAA,IAAI,GAAG,KAAK,CAAS,EAAE,CAAC;AACxB,QAAA,IAAA,CAAA,MAAM,GAAG,KAAK,CAAS,EAAE,CAAC;AAE1B,QAAA,IAAA,CAAA,GAAG,GAAG,MAAM,CAAS,EAAE,CAAC;AACxB,QAAA,IAAA,CAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,EAAE,QAAQ,IAAI,EAAE,CAAC;AAC1D,QAAA,IAAA,CAAA,SAAS,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,IAAI,EAAE,CAAC;AAC5D,QAAA,IAAA,CAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,EAAE,QAAQ,IAAI,EAAE,CAAC;AAC1D,QAAA,IAAA,CAAA,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAA,CAAE,CAAC;AAChE,QAAA,IAAA,CAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,KAAK,QAAQ,CAAC;QAE/D,IAAU,CAAA,UAAA,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;AAChF,QAAA,IAAA,CAAA,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;AAErD,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC;AAsFvC;AApFa,IAAA,YAAY,CAAC,KAA8B,EAAA;AACjD,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;;AAGpB,IAAA,WAAW,CAAC,KAAyB,EAAA;AAC3C,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;;IAG7B,QAAQ,GAAA;QACJ,IAAI,CAAC,YAAY,EAAE;;IAGvB,WAAW,GAAA;AACP,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;AACpB,QAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;;IAGpB,YAAY,GAAA;;AAEhB,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE;YAChB;;;QAIJ,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE;AAC5C,aAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC7B,SAAS,CAAC,QAAQ,IAAG;AAClB,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;;AAE3B,YAAA,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC;AACpC,SAAC,CAAC;;AAGV;;;AAGG;AACK,IAAA,iBAAiB,CAAC,QAAa,EAAA;;;AAGnC,QAAA,IAAI,QAAQ,CAAC,SAAS,EAAE;YACpB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC;;aAC7B;;;AAGH,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,EAAE,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC;AACpF,YAAA,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA,gDAAA,EAAmD,kBAAkB,CAAC,QAAQ,CAAC,CAAE,CAAA,CAAC;;;AAIvG;;AAEG;IACK,WAAW,CAAC,SAAiB,EAAE,QAAgB,EAAA;QACnD,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;QACtD,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;QACpD,OAAO,YAAY,GAAG,WAAW;;AAG7B,IAAA,UAAU,CAAC,GAAW,EAAA;QAC1B,IAAI,IAAI,GAAG,CAAC;AACZ,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACjC,YAAA,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;YAC7C,IAAI,IAAI,CAAC;;AAEb,QAAA,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;;AAGjB,IAAA,SAAS,CAAC,QAAgB,EAAA;AAC9B,QAAA,MAAM,MAAM,GAAG;YACX,SAAS;YACT,WAAW;YACX,QAAQ;YACR,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;YACT,SAAS;SACZ;AACD,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM;AACrD,QAAA,OAAO,MAAM,CAAC,GAAG,CAAC;;8GAtGb,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAtB,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,SAAA,EAFpB,EAAE,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC5BjB,mjBAsBA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA;;gBDHQ,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA;;gBAEZ,cAAc,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,OAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACd,iBAAiB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,2BAAA,EAAA,QAAA,EAAA,8IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACjB,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,aAAA,EAAA,KAAA,EAAA,KAAA,EAAA,UAAA,EAAA,MAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA;;gBAEb,aAAa,EAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA,CAAA;;2FAKR,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBAjBlC,SAAS;AACI,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,iBAAiB,EAGlB,OAAA,EAAA;;wBAEL,YAAY;;wBAEZ,cAAc;wBACd,iBAAiB;wBACjB,aAAa;;wBAEb;AACH,qBAAA,EAAA,aAAA,EACc,iBAAiB,CAAC,IAAI,EAAA,SAAA,EAC1B,EAAE,EAAA,QAAA,EAAA,mjBAAA,EAAA;;;AE5BjB;;AAEG;;;;"}
@@ -3411,7 +3411,6 @@ function routesFacory() {
3411
3411
  class AXPEntityModule {
3412
3412
  constructor(appInitService, injector) {
3413
3413
  const service = injector.get(AXPEntityDefinitionRegistryService);
3414
- const seederService = injector.get(AXPDataSeederService);
3415
3414
  appInitService.registerTask({
3416
3415
  name: 'layout-theme',
3417
3416
  statusText: 'Preload entities ...',
@@ -3421,14 +3420,6 @@ class AXPEntityModule {
3421
3420
  service.preload();
3422
3421
  },
3423
3422
  });
3424
- appInitService.registerTask({
3425
- name: 'Seeder',
3426
- statusText: 'Seed Data ...',
3427
- priority: 100,
3428
- run: async () => {
3429
- await seederService.seed();
3430
- },
3431
- });
3432
3423
  }
3433
3424
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPEntityModule, deps: [{ token: i1$4.AXPAppStartUpService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.NgModule }); }
3434
3425
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.3", ngImport: i0, type: AXPEntityModule, imports: [RouterModule, i2$2.AXPWorkflowModule, i7.AXPLayoutBuilderModule] }); }