@ifsworld/granite-components 13.2.9 → 13.3.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.
@@ -4005,6 +4005,57 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
4005
4005
  }]
4006
4006
  }], ctorParameters: () => [{ type: i0.TemplateRef }] });
4007
4007
 
4008
+ class NamesUtilsService {
4009
+ static getInitialsFrom(firstName) {
4010
+ return firstName
4011
+ .split(' ')
4012
+ .map((part) => part.charAt(0).toUpperCase())
4013
+ .join('');
4014
+ }
4015
+ static buildNameData(namesFormat) {
4016
+ const { firstName, lastName, name } = namesFormat;
4017
+ const getInitials = (fullName) => NamesUtilsService.getInitialsFrom(fullName);
4018
+ if (firstName && lastName) {
4019
+ return {
4020
+ firstName: firstName,
4021
+ lastName: lastName,
4022
+ initials: `${getInitials(firstName)[0]}${getInitials(lastName)[0]}`,
4023
+ };
4024
+ }
4025
+ if (firstName) {
4026
+ const firstNameInitials = getInitials(firstName);
4027
+ return {
4028
+ firstName: firstName,
4029
+ initials: `${firstNameInitials[0]}${firstNameInitials[1] || ''}`,
4030
+ };
4031
+ }
4032
+ if (lastName) {
4033
+ const lastNameInitials = getInitials(lastName);
4034
+ return {
4035
+ lastName: lastName,
4036
+ initials: `${lastNameInitials[0]}${lastNameInitials[1] || ''}`,
4037
+ };
4038
+ }
4039
+ if (name) {
4040
+ const nameInitials = getInitials(name);
4041
+ const nameParts = name.split(' ');
4042
+ const firstNameParts = nameParts.length > 1 ? nameParts.slice(0, -1) : [name];
4043
+ const lastName = nameParts.length > 1 ? nameParts[nameParts.length - 1] : '';
4044
+ const firstName = firstNameParts.join(' ');
4045
+ return {
4046
+ firstName: firstName,
4047
+ lastName: lastName,
4048
+ initials: `${nameInitials[0]}${nameInitials[1] || ''}`,
4049
+ };
4050
+ }
4051
+ return {
4052
+ firstName: '',
4053
+ lastName: '',
4054
+ initials: '',
4055
+ };
4056
+ }
4057
+ }
4058
+
4008
4059
  class GraniteCustomAvatarStatusDirective {
4009
4060
  constructor(templateRef) {
4010
4061
  this.templateRef = templateRef;
@@ -4062,27 +4113,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
4062
4113
  }] } });
4063
4114
 
4064
4115
  class GraniteEmptyAvatarComponent {
4065
- constructor() {
4066
- this._firstNameLetter = '';
4067
- this._firstSurnameLetter = '';
4068
- }
4069
- ngOnChanges(changes) {
4070
- if (changes.name) {
4071
- this._firstNameLetter =
4072
- changes.name.currentValue?.charAt(0)?.toUpperCase() || '';
4073
- }
4074
- if (changes.surname) {
4075
- this._firstSurnameLetter =
4076
- changes.surname.currentValue?.charAt(0)?.toUpperCase() || '';
4077
- }
4078
- }
4079
4116
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: GraniteEmptyAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4080
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: GraniteEmptyAvatarComponent, selector: "granite-empty-avatar", inputs: { name: "name", surname: "surname" }, host: { classAttribute: "granite-empty-avatar" }, usesOnChanges: true, ngImport: i0, template: `
4117
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: GraniteEmptyAvatarComponent, selector: "granite-empty-avatar", inputs: { initials: "initials" }, host: { classAttribute: "granite-empty-avatar" }, ngImport: i0, template: `
4081
4118
  <div class="no-profile-avatar">
4082
4119
  <span
4083
4120
  data-fnd="no-profile-avatar-initials"
4084
4121
  class="no-profile-avatar-initials"
4085
- >{{ _firstNameLetter }}{{ _firstSurnameLetter }}</span
4122
+ >{{ initials }}</span
4086
4123
  >
4087
4124
  </div>
4088
4125
  `, isInline: true, styles: [":host{width:inherit;height:inherit}:host .no-profile-avatar{display:flex;width:inherit;height:inherit;border-radius:100%;background:var(--granite-color-background-info);justify-content:center;align-items:center}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
@@ -4096,17 +4133,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
4096
4133
  <span
4097
4134
  data-fnd="no-profile-avatar-initials"
4098
4135
  class="no-profile-avatar-initials"
4099
- >{{ _firstNameLetter }}{{ _firstSurnameLetter }}</span
4136
+ >{{ initials }}</span
4100
4137
  >
4101
4138
  </div>
4102
4139
  `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{width:inherit;height:inherit}:host .no-profile-avatar{display:flex;width:inherit;height:inherit;border-radius:100%;background:var(--granite-color-background-info);justify-content:center;align-items:center}\n"] }]
4103
- }], propDecorators: { name: [{
4104
- type: Input
4105
- }], surname: [{
4140
+ }], propDecorators: { initials: [{
4106
4141
  type: Input
4107
4142
  }] } });
4108
4143
 
4109
4144
  class GraniteAvatarComponent extends ContactsTriggerDataComponent {
4145
+ constructor(cd) {
4146
+ super();
4147
+ this.cd = cd;
4148
+ }
4149
+ ngOnChanges(changes) {
4150
+ if (changes.firstName || changes.lastName || changes.name) {
4151
+ this._nameInitials = NamesUtilsService.buildNameData({
4152
+ firstName: changes.firstName?.currentValue,
4153
+ lastName: changes.lastName?.currentValue,
4154
+ name: changes.name?.currentValue,
4155
+ }).initials;
4156
+ this.cd.markForCheck();
4157
+ }
4158
+ }
4110
4159
  ngAfterContentChecked() {
4111
4160
  this._customStatusDirectives = this._customStatusesQueryList
4112
4161
  .toArray()
@@ -4117,17 +4166,19 @@ class GraniteAvatarComponent extends ContactsTriggerDataComponent {
4117
4166
  };
4118
4167
  }, {});
4119
4168
  }
4120
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: GraniteAvatarComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
4121
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: GraniteAvatarComponent, selector: "granite-avatar", inputs: { name: "name", surname: "surname", avatar: "avatar", status: "status" }, host: { classAttribute: "granite-avatar" }, queries: [{ propertyName: "_customStatusesQueryList", predicate: GraniteCustomAvatarStatusDirective }], exportAs: ["graniteAvatar"], usesInheritance: true, ngImport: i0, template: "<img\n data-fnd=\"profile-avatar\"\n *ngIf=\"avatar; else noProfileAvatar\"\n [src]=\"avatar\"\n alt=\"avatar\"\n class=\"profile-avatar profile-size\"\n/>\n\n<ng-template #noProfileAvatar>\n <granite-empty-avatar\n class=\"profile-size\"\n [name]=\"name\"\n [surname]=\"surname\"\n ></granite-empty-avatar>\n</ng-template>\n\n@if (status && _customStatusDirectives[status]) {\n <ng-container *ngTemplateOutlet=\"customStatus\"></ng-container>\n} @else if (status) {\n <ng-container *ngTemplateOutlet=\"defaultStatus\"></ng-container>\n}\n\n<ng-template #defaultStatus>\n <granite-avatar-default-status\n class=\"profile-default-status\"\n [attr.data-fnd]=\"status + '-status'\"\n [status]=\"status\"\n ></granite-avatar-default-status>\n</ng-template>\n\n<ng-template #customStatus>\n <div\n [attr.data-fnd]=\"'profile-status-custom'\"\n [class]=\"'profile-status-' + status\"\n class=\"profile-custom-status\"\n >\n <ng-container\n *ngTemplateOutlet=\"_customStatusDirectives[status]\"\n ></ng-container>\n </div>\n</ng-template>\n", styles: [":host .profile-default-status,:host .profile-custom-status{position:absolute;inset-inline-end:0;bottom:0}:host{display:block;position:relative;width:1.5rem;height:1.5rem;color:var(--granite-color-signal-info);font-size:var(--granite-font-size-body-small);font-weight:var(--granite-font-weight-regular);object-fit:contain}:host .profile{display:flex;align-items:center;margin-bottom:var(--granite-spacing-8);gap:var(--granite-spacing-4)}:host .profile-avatar{width:inherit;height:inherit;border-radius:50%}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: GraniteAvatarDefaultStatusComponent, selector: "granite-avatar-default-status", inputs: ["status"] }, { kind: "component", type: GraniteEmptyAvatarComponent, selector: "granite-empty-avatar", inputs: ["name", "surname"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4169
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: GraniteAvatarComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
4170
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.4", type: GraniteAvatarComponent, selector: "granite-avatar", inputs: { name: "name", firstName: "firstName", lastName: "lastName", avatar: "avatar", status: "status" }, host: { classAttribute: "granite-avatar" }, queries: [{ propertyName: "_customStatusesQueryList", predicate: GraniteCustomAvatarStatusDirective }], exportAs: ["graniteAvatar"], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<img\n data-fnd=\"profile-avatar\"\n *ngIf=\"avatar; else noProfileAvatar\"\n [src]=\"avatar\"\n alt=\"avatar\"\n class=\"profile-avatar profile-size\"\n/>\n\n<ng-template #noProfileAvatar>\n <granite-empty-avatar\n class=\"profile-size\"\n [initials]=\"_nameInitials\"\n ></granite-empty-avatar>\n</ng-template>\n\n@if (status && _customStatusDirectives[status]) {\n <ng-container *ngTemplateOutlet=\"customStatus\"></ng-container>\n} @else if (status) {\n <ng-container *ngTemplateOutlet=\"defaultStatus\"></ng-container>\n}\n\n<ng-template #defaultStatus>\n <granite-avatar-default-status\n class=\"profile-default-status\"\n [attr.data-fnd]=\"status + '-status'\"\n [status]=\"status\"\n ></granite-avatar-default-status>\n</ng-template>\n\n<ng-template #customStatus>\n <div\n [attr.data-fnd]=\"'profile-status-custom'\"\n [class]=\"'profile-status-' + status\"\n class=\"profile-custom-status\"\n >\n <ng-container\n *ngTemplateOutlet=\"_customStatusDirectives[status]\"\n ></ng-container>\n </div>\n</ng-template>\n", styles: [":host .profile-default-status,:host .profile-custom-status{position:absolute;inset-inline-end:0;bottom:0}:host{display:block;position:relative;width:1.5rem;height:1.5rem;color:var(--granite-color-signal-info);font-size:var(--granite-font-size-body-small);font-weight:var(--granite-font-weight-regular);object-fit:contain}:host .profile{display:flex;align-items:center;margin-bottom:var(--granite-spacing-8);gap:var(--granite-spacing-4)}:host .profile-avatar{width:inherit;height:inherit;border-radius:50%}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: GraniteAvatarDefaultStatusComponent, selector: "granite-avatar-default-status", inputs: ["status"] }, { kind: "component", type: GraniteEmptyAvatarComponent, selector: "granite-empty-avatar", inputs: ["initials"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4122
4171
  }
4123
4172
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: GraniteAvatarComponent, decorators: [{
4124
4173
  type: Component,
4125
4174
  args: [{ selector: 'granite-avatar', exportAs: 'graniteAvatar', host: {
4126
4175
  class: 'granite-avatar',
4127
- }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<img\n data-fnd=\"profile-avatar\"\n *ngIf=\"avatar; else noProfileAvatar\"\n [src]=\"avatar\"\n alt=\"avatar\"\n class=\"profile-avatar profile-size\"\n/>\n\n<ng-template #noProfileAvatar>\n <granite-empty-avatar\n class=\"profile-size\"\n [name]=\"name\"\n [surname]=\"surname\"\n ></granite-empty-avatar>\n</ng-template>\n\n@if (status && _customStatusDirectives[status]) {\n <ng-container *ngTemplateOutlet=\"customStatus\"></ng-container>\n} @else if (status) {\n <ng-container *ngTemplateOutlet=\"defaultStatus\"></ng-container>\n}\n\n<ng-template #defaultStatus>\n <granite-avatar-default-status\n class=\"profile-default-status\"\n [attr.data-fnd]=\"status + '-status'\"\n [status]=\"status\"\n ></granite-avatar-default-status>\n</ng-template>\n\n<ng-template #customStatus>\n <div\n [attr.data-fnd]=\"'profile-status-custom'\"\n [class]=\"'profile-status-' + status\"\n class=\"profile-custom-status\"\n >\n <ng-container\n *ngTemplateOutlet=\"_customStatusDirectives[status]\"\n ></ng-container>\n </div>\n</ng-template>\n", styles: [":host .profile-default-status,:host .profile-custom-status{position:absolute;inset-inline-end:0;bottom:0}:host{display:block;position:relative;width:1.5rem;height:1.5rem;color:var(--granite-color-signal-info);font-size:var(--granite-font-size-body-small);font-weight:var(--granite-font-weight-regular);object-fit:contain}:host .profile{display:flex;align-items:center;margin-bottom:var(--granite-spacing-8);gap:var(--granite-spacing-4)}:host .profile-avatar{width:inherit;height:inherit;border-radius:50%}\n"] }]
4128
- }], propDecorators: { name: [{
4176
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<img\n data-fnd=\"profile-avatar\"\n *ngIf=\"avatar; else noProfileAvatar\"\n [src]=\"avatar\"\n alt=\"avatar\"\n class=\"profile-avatar profile-size\"\n/>\n\n<ng-template #noProfileAvatar>\n <granite-empty-avatar\n class=\"profile-size\"\n [initials]=\"_nameInitials\"\n ></granite-empty-avatar>\n</ng-template>\n\n@if (status && _customStatusDirectives[status]) {\n <ng-container *ngTemplateOutlet=\"customStatus\"></ng-container>\n} @else if (status) {\n <ng-container *ngTemplateOutlet=\"defaultStatus\"></ng-container>\n}\n\n<ng-template #defaultStatus>\n <granite-avatar-default-status\n class=\"profile-default-status\"\n [attr.data-fnd]=\"status + '-status'\"\n [status]=\"status\"\n ></granite-avatar-default-status>\n</ng-template>\n\n<ng-template #customStatus>\n <div\n [attr.data-fnd]=\"'profile-status-custom'\"\n [class]=\"'profile-status-' + status\"\n class=\"profile-custom-status\"\n >\n <ng-container\n *ngTemplateOutlet=\"_customStatusDirectives[status]\"\n ></ng-container>\n </div>\n</ng-template>\n", styles: [":host .profile-default-status,:host .profile-custom-status{position:absolute;inset-inline-end:0;bottom:0}:host{display:block;position:relative;width:1.5rem;height:1.5rem;color:var(--granite-color-signal-info);font-size:var(--granite-font-size-body-small);font-weight:var(--granite-font-weight-regular);object-fit:contain}:host .profile{display:flex;align-items:center;margin-bottom:var(--granite-spacing-8);gap:var(--granite-spacing-4)}:host .profile-avatar{width:inherit;height:inherit;border-radius:50%}\n"] }]
4177
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { name: [{
4178
+ type: Input
4179
+ }], firstName: [{
4129
4180
  type: Input
4130
- }], surname: [{
4181
+ }], lastName: [{
4131
4182
  type: Input
4132
4183
  }], avatar: [{
4133
4184
  type: Input
@@ -4139,23 +4190,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
4139
4190
  }] } });
4140
4191
 
4141
4192
  class GraniteContactsProfileComponent {
4142
- ngOnChanges(changes) {
4143
- const profile = changes.profile?.currentValue;
4144
- if (profile && profile.name && profile.surname) {
4145
- this.createProfileInitials(profile.name, profile.surname);
4146
- }
4147
- }
4148
- createProfileInitials(name, surname) {
4149
- this._initials = name[0].toUpperCase() + surname[0].toUpperCase();
4150
- }
4151
4193
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: GraniteContactsProfileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4152
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: GraniteContactsProfileComponent, selector: "granite-contacts-profile", inputs: { profile: "profile", profileClass: "profileClass" }, host: { classAttribute: "granite-contacts-profile" }, usesOnChanges: true, ngImport: i0, template: "<div [class]=\"profileClass\" data-fnd=\"profile\" class=\"profile\">\n <granite-avatar\n data-fnd=\"profile-avatar\"\n class=\"profile-avatar\"\n [name]=\"profile.name\"\n [surname]=\"profile.surname\"\n [avatar]=\"profile.avatar\"\n ></granite-avatar>\n\n <ng-template #noProfileAvatar>\n <div class=\"no-profile-avatar\">\n <span\n data-fnd=\"no-profile-avatar-initials\"\n class=\"no-profile-avatar-initials\"\n >{{ _initials }}</span\n >\n </div>\n </ng-template>\n\n <div class=\"profile-info\">\n <p data-fnd=\"profile-info-names\" class=\"profile-info-names\">\n {{ profile?.name }} {{ profile?.surname }}\n </p>\n <p data-fnd=\"profile-info-job-title\" class=\"profile-info-job-title\">\n {{ profile?.jobTitle }}\n </p>\n </div>\n</div>\n", styles: [".profile{display:flex;align-items:center;margin-bottom:var(--granite-spacing-8);gap:var(--granite-spacing-4)}.profile-avatar{width:3rem;height:3rem;border-radius:50%}.profile-info{display:flex;flex-direction:column;gap:var(--granite-spacing-8)}.profile-info-names{color:var(--granite-color-text);font-size:var(--granite-font-size-body-small);font-weight:var(--granite-font-weight-regular);margin:0}.profile-info-job-title{color:var(--granite-color-text-hint);font-size:var(--granite-font-size-body-small);margin:0}.no-profile-avatar{display:flex;width:3rem;height:3rem;border-radius:360px;background:var(--granite-color-background-info);justify-content:center;align-items:center}.no-profile-avatar-initials{font-size:var(--granite-font-size-micro);color:var(--granite-color-signal-info);font-weight:var(--granite-font-weight-regular)}\n"], dependencies: [{ kind: "component", type: GraniteAvatarComponent, selector: "granite-avatar", inputs: ["name", "surname", "avatar", "status"], exportAs: ["graniteAvatar"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4194
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: GraniteContactsProfileComponent, selector: "granite-contacts-profile", inputs: { profile: "profile", profileClass: "profileClass" }, host: { classAttribute: "granite-contacts-profile" }, ngImport: i0, template: "<div [class]=\"profileClass\" data-fnd=\"profile\" class=\"profile\">\n <granite-avatar\n data-fnd=\"profile-avatar\"\n class=\"profile-avatar\"\n [firstName]=\"profile.firstName\"\n [lastName]=\"profile.lastName\"\n [avatar]=\"profile.avatar\"\n ></granite-avatar>\n\n <ng-template #noProfileAvatar>\n <div class=\"no-profile-avatar\">\n <span\n data-fnd=\"no-profile-avatar-initials\"\n class=\"no-profile-avatar-initials\"\n >{{ profile?.initials }}</span\n >\n </div>\n </ng-template>\n\n <div class=\"profile-info\">\n <p data-fnd=\"profile-info-names\" class=\"profile-info-names\">\n {{ profile?.firstName }} {{ profile?.lastName }}\n </p>\n <p data-fnd=\"profile-info-job-title\" class=\"profile-info-job-title\">\n {{ profile?.jobTitle }}\n </p>\n </div>\n</div>\n", styles: [".profile{display:flex;align-items:center;margin-bottom:var(--granite-spacing-8);gap:var(--granite-spacing-4)}.profile-avatar{width:3rem;height:3rem;border-radius:50%}.profile-info{display:flex;flex-direction:column;gap:var(--granite-spacing-8)}.profile-info-names{color:var(--granite-color-text);font-size:var(--granite-font-size-body-small);font-weight:var(--granite-font-weight-regular);margin:0}.profile-info-job-title{color:var(--granite-color-text-hint);font-size:var(--granite-font-size-body-small);margin:0}.no-profile-avatar{display:flex;width:3rem;height:3rem;border-radius:360px;background:var(--granite-color-background-info);justify-content:center;align-items:center}.no-profile-avatar-initials{font-size:var(--granite-font-size-micro);color:var(--granite-color-signal-info);font-weight:var(--granite-font-weight-regular)}\n"], dependencies: [{ kind: "component", type: GraniteAvatarComponent, selector: "granite-avatar", inputs: ["name", "firstName", "lastName", "avatar", "status"], exportAs: ["graniteAvatar"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4153
4195
  }
4154
4196
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: GraniteContactsProfileComponent, decorators: [{
4155
4197
  type: Component,
4156
4198
  args: [{ selector: 'granite-contacts-profile', host: {
4157
4199
  class: 'granite-contacts-profile',
4158
- }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"profileClass\" data-fnd=\"profile\" class=\"profile\">\n <granite-avatar\n data-fnd=\"profile-avatar\"\n class=\"profile-avatar\"\n [name]=\"profile.name\"\n [surname]=\"profile.surname\"\n [avatar]=\"profile.avatar\"\n ></granite-avatar>\n\n <ng-template #noProfileAvatar>\n <div class=\"no-profile-avatar\">\n <span\n data-fnd=\"no-profile-avatar-initials\"\n class=\"no-profile-avatar-initials\"\n >{{ _initials }}</span\n >\n </div>\n </ng-template>\n\n <div class=\"profile-info\">\n <p data-fnd=\"profile-info-names\" class=\"profile-info-names\">\n {{ profile?.name }} {{ profile?.surname }}\n </p>\n <p data-fnd=\"profile-info-job-title\" class=\"profile-info-job-title\">\n {{ profile?.jobTitle }}\n </p>\n </div>\n</div>\n", styles: [".profile{display:flex;align-items:center;margin-bottom:var(--granite-spacing-8);gap:var(--granite-spacing-4)}.profile-avatar{width:3rem;height:3rem;border-radius:50%}.profile-info{display:flex;flex-direction:column;gap:var(--granite-spacing-8)}.profile-info-names{color:var(--granite-color-text);font-size:var(--granite-font-size-body-small);font-weight:var(--granite-font-weight-regular);margin:0}.profile-info-job-title{color:var(--granite-color-text-hint);font-size:var(--granite-font-size-body-small);margin:0}.no-profile-avatar{display:flex;width:3rem;height:3rem;border-radius:360px;background:var(--granite-color-background-info);justify-content:center;align-items:center}.no-profile-avatar-initials{font-size:var(--granite-font-size-micro);color:var(--granite-color-signal-info);font-weight:var(--granite-font-weight-regular)}\n"] }]
4200
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"profileClass\" data-fnd=\"profile\" class=\"profile\">\n <granite-avatar\n data-fnd=\"profile-avatar\"\n class=\"profile-avatar\"\n [firstName]=\"profile.firstName\"\n [lastName]=\"profile.lastName\"\n [avatar]=\"profile.avatar\"\n ></granite-avatar>\n\n <ng-template #noProfileAvatar>\n <div class=\"no-profile-avatar\">\n <span\n data-fnd=\"no-profile-avatar-initials\"\n class=\"no-profile-avatar-initials\"\n >{{ profile?.initials }}</span\n >\n </div>\n </ng-template>\n\n <div class=\"profile-info\">\n <p data-fnd=\"profile-info-names\" class=\"profile-info-names\">\n {{ profile?.firstName }} {{ profile?.lastName }}\n </p>\n <p data-fnd=\"profile-info-job-title\" class=\"profile-info-job-title\">\n {{ profile?.jobTitle }}\n </p>\n </div>\n</div>\n", styles: [".profile{display:flex;align-items:center;margin-bottom:var(--granite-spacing-8);gap:var(--granite-spacing-4)}.profile-avatar{width:3rem;height:3rem;border-radius:50%}.profile-info{display:flex;flex-direction:column;gap:var(--granite-spacing-8)}.profile-info-names{color:var(--granite-color-text);font-size:var(--granite-font-size-body-small);font-weight:var(--granite-font-weight-regular);margin:0}.profile-info-job-title{color:var(--granite-color-text-hint);font-size:var(--granite-font-size-body-small);margin:0}.no-profile-avatar{display:flex;width:3rem;height:3rem;border-radius:360px;background:var(--granite-color-background-info);justify-content:center;align-items:center}.no-profile-avatar-initials{font-size:var(--granite-font-size-micro);color:var(--granite-color-signal-info);font-weight:var(--granite-font-weight-regular)}\n"] }]
4159
4201
  }], propDecorators: { profile: [{
4160
4202
  type: Input
4161
4203
  }], profileClass: [{
@@ -4222,8 +4264,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImpor
4222
4264
  }] } });
4223
4265
 
4224
4266
  class GraniteContactsComponent extends ContactsTriggerDataComponent {
4225
- constructor() {
4226
- super(...arguments);
4267
+ constructor(cd) {
4268
+ super();
4269
+ this.cd = cd;
4227
4270
  this.contacts = [];
4228
4271
  this.defaultShow = false;
4229
4272
  this.selectedContact = new EventEmitter();
@@ -4233,6 +4276,11 @@ class GraniteContactsComponent extends ContactsTriggerDataComponent {
4233
4276
  if (changes.contacts && !changes.contacts.currentValue) {
4234
4277
  this.contacts = [];
4235
4278
  }
4279
+ if (changes.profile?.currentValue) {
4280
+ const profile = changes.profile.currentValue;
4281
+ this._profile = this.createProfileData(profile);
4282
+ }
4283
+ this.cd.markForCheck();
4236
4284
  }
4237
4285
  ngAfterContentChecked() {
4238
4286
  this._contactsExtended = this.setProperCustomStatusTemplates(this._customStatuses.toArray(), this.contacts);
@@ -4256,15 +4304,29 @@ class GraniteContactsComponent extends ContactsTriggerDataComponent {
4256
4304
  return result;
4257
4305
  });
4258
4306
  }
4259
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: GraniteContactsComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
4260
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: GraniteContactsComponent, selector: "granite-contacts", inputs: { contacts: "contacts", contactsClass: "contactsClass", profile: "profile", profileClass: "profileClass", defaultShow: "defaultShow" }, outputs: { selectedContact: "selectedContact" }, host: { classAttribute: "granite-contacts" }, queries: [{ propertyName: "customProfileDirective", first: true, predicate: GraniteCustomProfileDirective, descendants: true }, { propertyName: "_customStatuses", predicate: GraniteCustomStatusDirective }], exportAs: ["graniteContacts"], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<ng-template #contactsTemplate>\n <div data-fnd=\"contacts\" [class]=\"contactsClass\" class=\"granite-contact\">\n <ng-container *ngIf=\"customProfileDirective; else defaultProfile\">\n <ng-container\n *ngTemplateOutlet=\"customProfileDirective.templateRef\"\n ></ng-container>\n </ng-container>\n\n <ng-template #defaultProfile>\n <granite-contacts-profile\n data-fnd=\"default-profile\"\n [profileClass]=\"profileClass\"\n [profile]=\"profile\"\n ></granite-contacts-profile>\n </ng-template>\n\n <ul class=\"contact-list\">\n <li *ngFor=\"let contact of _contactsExtended\">\n <granite-contact-item\n [contact]=\"contact\"\n (selectedContact)=\"onSelectedContact($event)\"\n ></granite-contact-item>\n </li>\n </ul>\n </div>\n</ng-template>\n\n<ng-container *ngIf=\"defaultShow\">\n <ng-container *ngTemplateOutlet=\"contactsTemplate\"></ng-container>\n</ng-container>\n", styles: [".granite-contact{display:inline-block;font-size:var(--granite-font-size-body);font-family:var(--granite-font-family-default);color:var(--granite-color-text-weak);height:-moz-fit-content;height:fit-content;min-width:10rem;max-width:20rem;padding:var(--granite-spacing-16);box-shadow:var(--granite-shadow-popover);background:var(--granite-color-background-variant)}.granite-contact .contact-list{display:flex;flex-direction:column;align-items:flex-start;gap:var(--granite-spacing-8);list-style-type:none;padding:0;margin:0}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: GraniteContactsProfileComponent, selector: "granite-contacts-profile", inputs: ["profile", "profileClass"] }, { kind: "component", type: GraniteContactItemComponent, selector: "granite-contact-item", inputs: ["contact"], outputs: ["selectedContact"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4307
+ createProfileData(profile) {
4308
+ const nameData = NamesUtilsService.buildNameData({
4309
+ firstName: profile.firstName,
4310
+ lastName: profile.lastName,
4311
+ name: profile.name,
4312
+ });
4313
+ return {
4314
+ firstName: nameData.firstName,
4315
+ lastName: nameData.lastName,
4316
+ initials: nameData.initials,
4317
+ jobTitle: profile.jobTitle,
4318
+ avatar: profile.avatar,
4319
+ };
4320
+ }
4321
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: GraniteContactsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
4322
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: GraniteContactsComponent, selector: "granite-contacts", inputs: { contacts: "contacts", contactsClass: "contactsClass", profile: "profile", profileClass: "profileClass", defaultShow: "defaultShow" }, outputs: { selectedContact: "selectedContact" }, host: { classAttribute: "granite-contacts" }, queries: [{ propertyName: "customProfileDirective", first: true, predicate: GraniteCustomProfileDirective, descendants: true }, { propertyName: "_customStatuses", predicate: GraniteCustomStatusDirective }], exportAs: ["graniteContacts"], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<ng-template #contactsTemplate>\n <div data-fnd=\"contacts\" [class]=\"contactsClass\" class=\"granite-contact\">\n <ng-container *ngIf=\"customProfileDirective; else defaultProfile\">\n <ng-container\n *ngTemplateOutlet=\"customProfileDirective.templateRef\"\n ></ng-container>\n </ng-container>\n\n <ng-template #defaultProfile>\n <granite-contacts-profile\n data-fnd=\"default-profile\"\n [profileClass]=\"profileClass\"\n [profile]=\"_profile\"\n ></granite-contacts-profile>\n </ng-template>\n\n <ul class=\"contact-list\">\n <li *ngFor=\"let contact of _contactsExtended\">\n <granite-contact-item\n [contact]=\"contact\"\n (selectedContact)=\"onSelectedContact($event)\"\n ></granite-contact-item>\n </li>\n </ul>\n </div>\n</ng-template>\n\n<ng-container *ngIf=\"defaultShow\">\n <ng-container *ngTemplateOutlet=\"contactsTemplate\"></ng-container>\n</ng-container>\n", styles: [".granite-contact{display:inline-block;font-size:var(--granite-font-size-body);font-family:var(--granite-font-family-default);color:var(--granite-color-text-weak);height:-moz-fit-content;height:fit-content;min-width:10rem;max-width:20rem;padding:var(--granite-spacing-16);box-shadow:var(--granite-shadow-popover);background:var(--granite-color-background-variant)}.granite-contact .contact-list{display:flex;flex-direction:column;align-items:flex-start;gap:var(--granite-spacing-8);list-style-type:none;padding:0;margin:0}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: GraniteContactsProfileComponent, selector: "granite-contacts-profile", inputs: ["profile", "profileClass"] }, { kind: "component", type: GraniteContactItemComponent, selector: "granite-contact-item", inputs: ["contact"], outputs: ["selectedContact"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4261
4323
  }
4262
4324
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: GraniteContactsComponent, decorators: [{
4263
4325
  type: Component,
4264
4326
  args: [{ selector: 'granite-contacts', exportAs: 'graniteContacts', host: {
4265
4327
  class: 'granite-contacts',
4266
- }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #contactsTemplate>\n <div data-fnd=\"contacts\" [class]=\"contactsClass\" class=\"granite-contact\">\n <ng-container *ngIf=\"customProfileDirective; else defaultProfile\">\n <ng-container\n *ngTemplateOutlet=\"customProfileDirective.templateRef\"\n ></ng-container>\n </ng-container>\n\n <ng-template #defaultProfile>\n <granite-contacts-profile\n data-fnd=\"default-profile\"\n [profileClass]=\"profileClass\"\n [profile]=\"profile\"\n ></granite-contacts-profile>\n </ng-template>\n\n <ul class=\"contact-list\">\n <li *ngFor=\"let contact of _contactsExtended\">\n <granite-contact-item\n [contact]=\"contact\"\n (selectedContact)=\"onSelectedContact($event)\"\n ></granite-contact-item>\n </li>\n </ul>\n </div>\n</ng-template>\n\n<ng-container *ngIf=\"defaultShow\">\n <ng-container *ngTemplateOutlet=\"contactsTemplate\"></ng-container>\n</ng-container>\n", styles: [".granite-contact{display:inline-block;font-size:var(--granite-font-size-body);font-family:var(--granite-font-family-default);color:var(--granite-color-text-weak);height:-moz-fit-content;height:fit-content;min-width:10rem;max-width:20rem;padding:var(--granite-spacing-16);box-shadow:var(--granite-shadow-popover);background:var(--granite-color-background-variant)}.granite-contact .contact-list{display:flex;flex-direction:column;align-items:flex-start;gap:var(--granite-spacing-8);list-style-type:none;padding:0;margin:0}\n"] }]
4267
- }], propDecorators: { contacts: [{
4328
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #contactsTemplate>\n <div data-fnd=\"contacts\" [class]=\"contactsClass\" class=\"granite-contact\">\n <ng-container *ngIf=\"customProfileDirective; else defaultProfile\">\n <ng-container\n *ngTemplateOutlet=\"customProfileDirective.templateRef\"\n ></ng-container>\n </ng-container>\n\n <ng-template #defaultProfile>\n <granite-contacts-profile\n data-fnd=\"default-profile\"\n [profileClass]=\"profileClass\"\n [profile]=\"_profile\"\n ></granite-contacts-profile>\n </ng-template>\n\n <ul class=\"contact-list\">\n <li *ngFor=\"let contact of _contactsExtended\">\n <granite-contact-item\n [contact]=\"contact\"\n (selectedContact)=\"onSelectedContact($event)\"\n ></granite-contact-item>\n </li>\n </ul>\n </div>\n</ng-template>\n\n<ng-container *ngIf=\"defaultShow\">\n <ng-container *ngTemplateOutlet=\"contactsTemplate\"></ng-container>\n</ng-container>\n", styles: [".granite-contact{display:inline-block;font-size:var(--granite-font-size-body);font-family:var(--granite-font-family-default);color:var(--granite-color-text-weak);height:-moz-fit-content;height:fit-content;min-width:10rem;max-width:20rem;padding:var(--granite-spacing-16);box-shadow:var(--granite-shadow-popover);background:var(--granite-color-background-variant)}.granite-contact .contact-list{display:flex;flex-direction:column;align-items:flex-start;gap:var(--granite-spacing-8);list-style-type:none;padding:0;margin:0}\n"] }]
4329
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { contacts: [{
4268
4330
  type: Input
4269
4331
  }], contactsClass: [{
4270
4332
  type: Input