@acorex/platform 20.8.19 → 20.8.22

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.
@@ -5328,7 +5328,7 @@ class AXPUserAvatarComponent {
5328
5328
  this.userInfo = signal(null, ...(ngDevMode ? [{ debugName: "userInfo" }] : []));
5329
5329
  this.size = input(40, ...(ngDevMode ? [{ debugName: "size" }] : []));
5330
5330
  this.userId = input('', ...(ngDevMode ? [{ debugName: "userId" }] : []));
5331
- this.src = signal('', ...(ngDevMode ? [{ debugName: "src" }] : []));
5331
+ this.avatarUrl = signal('', ...(ngDevMode ? [{ debugName: "avatarUrl" }] : []));
5332
5332
  this.userName = computed(() => this.userInfo()?.username || '', ...(ngDevMode ? [{ debugName: "userName" }] : []));
5333
5333
  this.firstName = computed(() => this.userInfo()?.firstName || 'Root', ...(ngDevMode ? [{ debugName: "firstName" }] : []));
5334
5334
  this.lastName = computed(() => this.userInfo()?.lastName || 'User', ...(ngDevMode ? [{ debugName: "lastName" }] : []));
@@ -5336,17 +5336,17 @@ class AXPUserAvatarComponent {
5336
5336
  this.isOnline = computed(() => this.userInfo()?.status === 'online', ...(ngDevMode ? [{ debugName: "isOnline" }] : []));
5337
5337
  this.avatarText = computed(() => this.getInitials(), ...(ngDevMode ? [{ debugName: "avatarText" }] : []));
5338
5338
  this.avatarColor = computed(() => this.pickColor(this.avatarText()), ...(ngDevMode ? [{ debugName: "avatarColor" }] : []));
5339
- this.hasAvatar = computed(() => !isNil(this.src()) && !isEmpty(this.src()), ...(ngDevMode ? [{ debugName: "hasAvatar" }] : []));
5339
+ this.hasAvatarUrl = computed(() => !isNil(this.avatarUrl()) && !isEmpty(this.avatarUrl()), ...(ngDevMode ? [{ debugName: "hasAvatarUrl" }] : []));
5340
5340
  this.isAvatarLoaded = signal(false, ...(ngDevMode ? [{ debugName: "isAvatarLoaded" }] : []));
5341
- this.isLoading = computed(() => this.hasAvatar() && !this.isAvatarLoaded(), ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
5341
+ this.hasImageError = signal(false, ...(ngDevMode ? [{ debugName: "hasImageError" }] : []));
5342
+ this.showImage = computed(() => this.hasAvatarUrl() && this.isAvatarLoaded() && !this.hasImageError(), ...(ngDevMode ? [{ debugName: "showImage" }] : []));
5343
+ this.showPlaceholder = computed(() => this.hasAvatarUrl() && !this.showImage(), ...(ngDevMode ? [{ debugName: "showPlaceholder" }] : []));
5342
5344
  }
5343
- onImageError(event) {
5344
- // Clear src on error to fall back to initials
5345
- this.isAvatarLoaded.set(false);
5346
- this.src.set('');
5345
+ onImageError(_event) {
5346
+ this.markImageAsFailed();
5347
5347
  }
5348
- onImageLoad(event) {
5349
- this.isAvatarLoaded.set(true);
5348
+ onImageLoad(_event) {
5349
+ this.markImageAsLoaded();
5350
5350
  }
5351
5351
  ngOnInit() {
5352
5352
  this.loadUserData();
@@ -5371,17 +5371,47 @@ class AXPUserAvatarComponent {
5371
5371
  });
5372
5372
  }
5373
5373
  /**
5374
- * Generate avatar image source
5375
- * This is a placeholder - implement based on your actual requirements
5374
+ * Resolves avatar image URL from user data and resets load state.
5376
5375
  */
5377
5376
  generateAvatarSrc() {
5378
- // Example: Check if the user has a custom avatar URL
5379
- // If not, generate a placeholder using initials
5380
- if (this.userInfo()?.avatarUrl) {
5381
- // Reset loading state when setting new src
5377
+ const url = this.userInfo()?.avatarUrl;
5378
+ if (url) {
5382
5379
  this.isAvatarLoaded.set(false);
5383
- this.src.set(this.userInfo()?.avatarUrl);
5380
+ this.hasImageError.set(false);
5381
+ this.avatarUrl.set(url);
5382
+ this.preloadAvatar(url);
5383
+ return;
5384
5384
  }
5385
+ this.avatarUrl.set('');
5386
+ this.isAvatarLoaded.set(false);
5387
+ this.hasImageError.set(false);
5388
+ }
5389
+ /**
5390
+ * Preloads avatar image without breaking ax-avatar content projection.
5391
+ */
5392
+ preloadAvatar(url) {
5393
+ const image = new Image();
5394
+ image.onload = () => {
5395
+ if (this.avatarUrl() !== url) {
5396
+ return;
5397
+ }
5398
+ this.markImageAsLoaded();
5399
+ };
5400
+ image.onerror = () => {
5401
+ if (this.avatarUrl() !== url) {
5402
+ return;
5403
+ }
5404
+ this.markImageAsFailed();
5405
+ };
5406
+ image.src = url;
5407
+ }
5408
+ markImageAsLoaded() {
5409
+ this.hasImageError.set(false);
5410
+ this.isAvatarLoaded.set(true);
5411
+ }
5412
+ markImageAsFailed() {
5413
+ this.hasImageError.set(true);
5414
+ this.isAvatarLoaded.set(false);
5385
5415
  }
5386
5416
  /**
5387
5417
  * Get initials from first and last name
@@ -5405,11 +5435,11 @@ class AXPUserAvatarComponent {
5405
5435
  return colors[idx];
5406
5436
  }
5407
5437
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPUserAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5408
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", 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 ax-relative\" [title]=\"this.src()\">\n @if(hasAvatar()){\n <ng-container>\n <ax-image (onError)=\"onImageError($event)\" (onLoad)=\"onImageLoad($event)\" [src]=\"src()\"\n [class.ax-opacity-0]=\"isLoading()\" class=\"ax-transition-opacity ax-duration-200\"></ax-image>\n @if(isLoading()){\n <!-- <ax-image [src]=\"src()\"></ax-image> -->\n <ax-icon icon=\"fa-solid fa-user fa-2x\" class=\"ax-text-3xl\"></ax-icon>\n }\n </ng-container>\n }@else{\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n <!-- TODO: Add initials if firstName and lastName are not available -->\n <!-- <ng-container>\n @if(firstName() && lastName())\n {\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n }\n @else {\n <ax-icon icon=\"fa-solid fa-user fa-2x\" class=\"ax-text-3xl\"></ax-icon>\n }\n </ng-container> -->\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-->", styles: [""], dependencies: [{ kind: "ngmodule", type: AXAvatarModule }, { kind: "component", type: i1$7.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.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: i2$6.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXSkeletonModule }], encapsulation: i0.ViewEncapsulation.None }); }
5438
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", 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 ax-relative\" [title]=\"title()\">\n @if (showImage()) {\n <ax-image\n (onError)=\"onImageError($event)\"\n (onLoad)=\"onImageLoad($event)\"\n [src]=\"avatarUrl()\"\n class=\"ax-transition-opacity ax-duration-200\"\n ></ax-image>\n } @else if (showPlaceholder()) {\n <ax-text class=\"ax-bg-primary-light\">\n <ax-icon\n icon=\"fa-solid fa-user\"\n class=\"ax-text-sm ax-text-primary-500 ax-flex ax-text-center ax-justify-center\"\n aria-hidden=\"true\"\n ></ax-icon>\n </ax-text>\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", styles: [""], dependencies: [{ kind: "ngmodule", type: AXAvatarModule }, { kind: "component", type: i1$7.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.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: i2$6.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXSkeletonModule }], encapsulation: i0.ViewEncapsulation.None }); }
5409
5439
  }
5410
5440
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPUserAvatarComponent, decorators: [{
5411
5441
  type: Component,
5412
- args: [{ selector: 'axp-user-avatar', imports: [AXAvatarModule, AXDecoratorModule, AXImageModule, AXBadgeModule, AXSkeletonModule], encapsulation: ViewEncapsulation.None, providers: [], template: "<ax-avatar #avatar [size]=\"size()\" class=\"ax-cursor-pointer ax-relative\" [title]=\"this.src()\">\n @if(hasAvatar()){\n <ng-container>\n <ax-image (onError)=\"onImageError($event)\" (onLoad)=\"onImageLoad($event)\" [src]=\"src()\"\n [class.ax-opacity-0]=\"isLoading()\" class=\"ax-transition-opacity ax-duration-200\"></ax-image>\n @if(isLoading()){\n <!-- <ax-image [src]=\"src()\"></ax-image> -->\n <ax-icon icon=\"fa-solid fa-user fa-2x\" class=\"ax-text-3xl\"></ax-icon>\n }\n </ng-container>\n }@else{\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n <!-- TODO: Add initials if firstName and lastName are not available -->\n <!-- <ng-container>\n @if(firstName() && lastName())\n {\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n }\n @else {\n <ax-icon icon=\"fa-solid fa-user fa-2x\" class=\"ax-text-3xl\"></ax-icon>\n }\n </ng-container> -->\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-->" }]
5442
+ args: [{ selector: 'axp-user-avatar', imports: [AXAvatarModule, AXDecoratorModule, AXImageModule, AXBadgeModule, AXSkeletonModule], encapsulation: ViewEncapsulation.None, providers: [], template: "<ax-avatar #avatar [size]=\"size()\" class=\"ax-cursor-pointer ax-relative\" [title]=\"title()\">\n @if (showImage()) {\n <ax-image\n (onError)=\"onImageError($event)\"\n (onLoad)=\"onImageLoad($event)\"\n [src]=\"avatarUrl()\"\n class=\"ax-transition-opacity ax-duration-200\"\n ></ax-image>\n } @else if (showPlaceholder()) {\n <ax-text class=\"ax-bg-primary-light\">\n <ax-icon\n icon=\"fa-solid fa-user\"\n class=\"ax-text-sm ax-text-primary-500 ax-flex ax-text-center ax-justify-center\"\n aria-hidden=\"true\"\n ></ax-icon>\n </ax-text>\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" }]
5413
5443
  }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], userId: [{ type: i0.Input, args: [{ isSignal: true, alias: "userId", required: false }] }] } });
5414
5444
 
5415
5445
  class AXPQueryViewsComponent {