@bizdoc/core 3.9.2 → 3.9.5

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.
@@ -499,6 +499,10 @@ const MATERIAL_PALETTES = {
499
499
  };
500
500
 
501
501
  const IMAGE_TYPE = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'];
502
+ const START_CAP = /^[A-Z][^A-Z]/;
503
+ function decapitalize(str) {
504
+ return str.replace(START_CAP, e => e.toLowerCase());
505
+ }
502
506
  function anyKeys(obj) {
503
507
  return obj && Object.keys(obj).find(k => obj[k] != null && obj[k] !== undefined) !== undefined;
504
508
  }
@@ -7214,11 +7218,13 @@ class HelpTipComponent {
7214
7218
  <button mat-icon-button (click)="dismiss()" [bizdocTooltip]="'Dismiss'|translate"><mat-icon>close</mat-icon></button>
7215
7219
  </p>
7216
7220
  }
7217
- `, isInline: true, styles: [".form-help-tip{align-items:center;border:1px rgb(0 0 0 / 38%) solid;border-radius:3px;padding:0 8px}.form-help-tip span:first-letter{text-transform:capitalize}\n"], dependencies: [{ kind: "component", type: i8.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: TooltipDirective, selector: "[bizdocTooltip]", inputs: ["bizdocTooltip", "bizdocTooltipTemplate", "bizdocTooltipContext", "bizdocTooltipPosition", "bizdocTooltipDuration", "bizdocTooltipDisabled"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
7221
+ `, isInline: true, dependencies: [{ kind: "component", type: i8.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: TooltipDirective, selector: "[bizdocTooltip]", inputs: ["bizdocTooltip", "bizdocTooltipTemplate", "bizdocTooltipContext", "bizdocTooltipPosition", "bizdocTooltipDuration", "bizdocTooltipDisabled"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
7218
7222
  }
7219
7223
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: HelpTipComponent, decorators: [{
7220
7224
  type: Component,
7221
- args: [{ standalone: false, template: `
7225
+ args: [{
7226
+ standalone: false,
7227
+ template: `
7222
7228
  @if (showTip) {
7223
7229
  <p class="row form-help-tip">
7224
7230
  <mat-icon>help_outline</mat-icon> &nbsp;
@@ -7227,7 +7233,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.2", ngImpor
7227
7233
  <button mat-icon-button (click)="dismiss()" [bizdocTooltip]="'Dismiss'|translate"><mat-icon>close</mat-icon></button>
7228
7234
  </p>
7229
7235
  }
7230
- `, selector: 'bizdoc-help-tip', styles: [".form-help-tip{align-items:center;border:1px rgb(0 0 0 / 38%) solid;border-radius:3px;padding:0 8px}.form-help-tip span:first-letter{text-transform:capitalize}\n"] }]
7236
+ `,
7237
+ selector: 'bizdoc-help-tip'
7238
+ }]
7231
7239
  }], ctorParameters: () => [{ type: GuideService }], propDecorators: { name: [{
7232
7240
  type: Input
7233
7241
  }] } });
@@ -9144,21 +9152,21 @@ class ExpandedItemComponent {
9144
9152
  return name;
9145
9153
  switch (gender) {
9146
9154
  case 'adjective':
9147
- return (action.adjective || action.past || action.title).toLowerCase();
9155
+ return decapitalize(action.adjective || action.past || action.title);
9148
9156
  case 'you':
9149
9157
  const gender = this._session.gender;
9150
- return ((gender === 'Male' ? (action.youMale || action.you) :
9158
+ return decapitalize((gender === 'Male' ? (action.youMale || action.you) :
9151
9159
  gender === 'Female' ? (action.youFemale || action.you) :
9152
9160
  action.you) || action.past ||
9153
- action.title).toLowerCase();
9161
+ action.title);
9154
9162
  case 'Male':
9155
- return (action.pastMale || action.past ||
9156
- action.title).toLowerCase();
9163
+ return decapitalize(action.pastMale || action.past ||
9164
+ action.title);
9157
9165
  case 'Female':
9158
- return (action.pastFemale || action.past ||
9159
- action.title).toLowerCase();
9166
+ return decapitalize(action.pastFemale || action.past ||
9167
+ action.title);
9160
9168
  default:
9161
- return (action.past || action.title).toLowerCase();
9169
+ return decapitalize(action.past || action.title);
9162
9170
  }
9163
9171
  }
9164
9172
  _fromNow(date) {
@@ -9731,7 +9739,7 @@ class BrowseItemsComponent {
9731
9739
  }
9732
9740
  _getActionAdjective(name, plural) {
9733
9741
  const action = this._session.profile.actions.find(a => a.name === name);
9734
- return ((plural ? (action.adjectivePlural || action.adjective) : action.adjective) || action.title).toLowerCase();
9742
+ return decapitalize((plural ? (action.adjectivePlural || action.adjective) : action.adjective) || action.title);
9735
9743
  }
9736
9744
  ngOnDestroy() {
9737
9745
  this._destroy.next();
@@ -10047,7 +10055,7 @@ class ComposeFormComponent {
10047
10055
  }
10048
10056
  _getActionAdjective(name) {
10049
10057
  const action = this._session.profile.actions.find(a => a.name === name);
10050
- return (action.adjective || action.past || action.title).toLowerCase();
10058
+ return decapitalize(action.adjective || action.past || action.title);
10051
10059
  }
10052
10060
  /**
10053
10061
  *
@@ -12969,6 +12977,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.2", ngImpor
12969
12977
  type: Input
12970
12978
  }] } });
12971
12979
 
12980
+ const NAME_DIVIDER = /\s+|\-/;
12972
12981
  class UserTaggingComponent extends TaggingComponentBase {
12973
12982
  constructor() {
12974
12983
  super(...arguments);
@@ -12976,16 +12985,19 @@ class UserTaggingComponent extends TaggingComponentBase {
12976
12985
  this._accounts = inject(AccountService);
12977
12986
  this._me = this._session.userId;
12978
12987
  }
12988
+ normalizedName(name) {
12989
+ return name.split(NAME_DIVIDER).map(p => p.charAt(0).toUpperCase() + p.substring(1)).join('');
12990
+ }
12979
12991
  onBind(value) {
12980
12992
  this.items = this._accounts.findAll(value, { take: 9 }).
12981
12993
  pipe(map(u => u.filter(u => u.id !== this._me)));
12982
12994
  }
12983
12995
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: UserTaggingComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
12984
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.2", type: UserTaggingComponent, isStandalone: false, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div role=\"listbox\" cdkTrapFocus class=\"tag-list\">\r\n @for (item of items | async; track item.id) {\r\n <bizdoc-tag-item [key]='item.name' [value]='item.id'\r\n matRipple [attr.aria-label]='item.name'>\r\n <div class=\"row\">\r\n <bizdoc-avatar [person]=item dense></bizdoc-avatar>\r\n &nbsp;\r\n <div class=\"column\">\r\n <span>{{item.name}}</span>\r\n <span>{{item.email}}</span>\r\n </div>\r\n </div>\r\n </bizdoc-tag-item>\r\n }\r\n</div>\r\n", styles: [".tag-list{display:flex;-ms-flex-direction:column;-webkit-flex-direction:column;flex-direction:column}.tag-item{cursor:pointer;padding:8px}.tag-item .row{align-items:center}.tag-item.active{background:#d3d3d3}\n"], dependencies: [{ kind: "directive", type: i1$3.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "component", type: AvatarComponent, selector: "bizdoc-avatar", inputs: ["person", "showMode", "dense"], outputs: ["clickChange"] }, { kind: "component", type: TaggingItemDirective, selector: "bizdoc-tag-item", inputs: ["key", "value"], outputs: ["selected"] }, { kind: "pipe", type: i9.AsyncPipe, name: "async" }] }); }
12996
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.2", type: UserTaggingComponent, isStandalone: false, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div role=\"listbox\" cdkTrapFocus class=\"tag-list\">\r\n @for (person of items | async; track person.id) {\r\n <bizdoc-tag-person [key]='normalizedName(person.name)' [value]='person.id'\r\n matRipple [attr.aria-label]='person.name'>\r\n <div class=\"row\">\r\n <bizdoc-avatar [person]=person dense></bizdoc-avatar>\r\n &nbsp;\r\n <div class=\"column\">\r\n <span>{{person.name}}</span>\r\n <span>{{person.email}}</span>\r\n </div>\r\n </div>\r\n </bizdoc-tag-person>\r\n }\r\n</div>\r\n", styles: [".tag-list{display:flex;-ms-flex-direction:column;-webkit-flex-direction:column;flex-direction:column}.tag-item{cursor:pointer;padding:8px}.tag-item .row{align-items:center}.tag-item.active{background:#d3d3d3}\n"], dependencies: [{ kind: "directive", type: i1$3.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "component", type: AvatarComponent, selector: "bizdoc-avatar", inputs: ["person", "showMode", "dense"], outputs: ["clickChange"] }, { kind: "pipe", type: i9.AsyncPipe, name: "async" }] }); }
12985
12997
  }
12986
12998
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: UserTaggingComponent, decorators: [{
12987
12999
  type: Component,
12988
- args: [{ standalone: false, template: "<div role=\"listbox\" cdkTrapFocus class=\"tag-list\">\r\n @for (item of items | async; track item.id) {\r\n <bizdoc-tag-item [key]='item.name' [value]='item.id'\r\n matRipple [attr.aria-label]='item.name'>\r\n <div class=\"row\">\r\n <bizdoc-avatar [person]=item dense></bizdoc-avatar>\r\n &nbsp;\r\n <div class=\"column\">\r\n <span>{{item.name}}</span>\r\n <span>{{item.email}}</span>\r\n </div>\r\n </div>\r\n </bizdoc-tag-item>\r\n }\r\n</div>\r\n", styles: [".tag-list{display:flex;-ms-flex-direction:column;-webkit-flex-direction:column;flex-direction:column}.tag-item{cursor:pointer;padding:8px}.tag-item .row{align-items:center}.tag-item.active{background:#d3d3d3}\n"] }]
13000
+ args: [{ standalone: false, template: "<div role=\"listbox\" cdkTrapFocus class=\"tag-list\">\r\n @for (person of items | async; track person.id) {\r\n <bizdoc-tag-person [key]='normalizedName(person.name)' [value]='person.id'\r\n matRipple [attr.aria-label]='person.name'>\r\n <div class=\"row\">\r\n <bizdoc-avatar [person]=person dense></bizdoc-avatar>\r\n &nbsp;\r\n <div class=\"column\">\r\n <span>{{person.name}}</span>\r\n <span>{{person.email}}</span>\r\n </div>\r\n </div>\r\n </bizdoc-tag-person>\r\n }\r\n</div>\r\n", styles: [".tag-list{display:flex;-ms-flex-direction:column;-webkit-flex-direction:column;flex-direction:column}.tag-item{cursor:pointer;padding:8px}.tag-item .row{align-items:center}.tag-item.active{background:#d3d3d3}\n"] }]
12989
13001
  }] });
12990
13002
 
12991
13003
  class FormPipe {
@@ -15744,24 +15756,24 @@ class FlowViewComponent extends TraceBase {
15744
15756
  if (recipients.length) {
15745
15757
  let r = 0;
15746
15758
  do {
15747
- var recipient = recipients[r];
15759
+ let { userId, estimate } = recipients[r];
15748
15760
  let exists = false;
15749
15761
  // remove duplicate user recipient on same node
15750
15762
  let j = 0;
15751
15763
  while (j < r && !exists) {
15752
- if (recipients[j].userId === recipient.userId)
15764
+ if (recipients[j].userId === userId)
15753
15765
  exists = true;
15754
15766
  else
15755
15767
  j++;
15756
15768
  }
15757
15769
  if (exists)
15758
- recipients.splice(recipient.estimate ? r : j, 1);
15770
+ recipients.splice(estimate ? r : j, 1);
15759
15771
  else
15760
15772
  r++;
15761
15773
  } while (r < recipients.length);
15762
15774
  for (r = 0; r < recipients.length; r++) {
15763
- let recipient = recipients[r];
15764
- const { annotation, tooltip } = await this._note(node, recipient), content = this._tooltip(tooltip), id = r === 0 ? node.id : node.id + r.toString();
15775
+ let recipient = recipients[r], { userId, actionId, escalated, fyi, pending } = recipient;
15776
+ let { annotation, tooltip } = await this._note(node, recipient), content = this._tooltip(tooltip), id = r === 0 ? node.id : node.id + r.toString();
15765
15777
  nodes.push({
15766
15778
  id,
15767
15779
  width: 50,
@@ -15770,8 +15782,8 @@ class FlowViewComponent extends TraceBase {
15770
15782
  strokeWidth: 2,
15771
15783
  //opacity: node.estimate ? .6 : 1,
15772
15784
  strokeColor: node.estimate ? this.dimColor : this._accentColor,
15773
- fill: !node.estimate && recipient.pending ?
15774
- this._session.getAccent(recipient.userId === this._session.userId ? 500 : 400) : this.transparentColor
15785
+ fill: !node.estimate && pending ?
15786
+ this._session.getAccent(userId === this._session.userId ? 500 : 400) : this.transparentColor
15775
15787
  },
15776
15788
  shape: this._configuration[node.type].shape,
15777
15789
  zIndex: zIndex++,
@@ -15803,9 +15815,9 @@ class FlowViewComponent extends TraceBase {
15803
15815
  }]
15804
15816
  });
15805
15817
  // add action indicator
15806
- if (recipient.actionId) {
15807
- const action = this._session.profile.actions.find(a => a.name === recipient.actionId);
15808
- action.shape && !recipient.pending &&
15818
+ if (actionId) {
15819
+ const action = this._session.profile.actions.find(a => a.name === actionId);
15820
+ action.shape && !pending &&
15809
15821
  indicators.push({
15810
15822
  id: id + 'action',
15811
15823
  width: 15,
@@ -15827,7 +15839,7 @@ class FlowViewComponent extends TraceBase {
15827
15839
  });
15828
15840
  }
15829
15841
  // fyi indicator
15830
- recipient.fyi &&
15842
+ fyi &&
15831
15843
  indicators.push({
15832
15844
  id: id + 'fyi',
15833
15845
  width: 15,
@@ -15848,7 +15860,7 @@ class FlowViewComponent extends TraceBase {
15848
15860
  }
15849
15861
  });
15850
15862
  // escalate indicator
15851
- recipient.escalated &&
15863
+ escalated &&
15852
15864
  indicators.push({
15853
15865
  id: id + 'escalate',
15854
15866
  width: 15,
@@ -16124,66 +16136,67 @@ class FlowViewComponent extends TraceBase {
16124
16136
  async _note(node, recipient) {
16125
16137
  const tooltip = {};
16126
16138
  let annotation;
16139
+ const { userId, id, pending, fyi, roleId, escalated, originId, replied, repliedBy, actionId, estimate, substituteId, received } = recipient;
16127
16140
  // you
16128
- if (recipient.userId === this._session.userId) {
16141
+ if (userId === this._session.userId) {
16129
16142
  if (this._session.isImpersonating)
16130
16143
  annotation = this._session.profile.name;
16131
16144
  else
16132
16145
  annotation = this._translate.get('You');
16133
- if (recipient.role) {
16134
- const role = this._roleName(recipient.role);
16135
- tooltip.role = `- ${role}`;
16146
+ if (roleId) {
16147
+ const roleName = this._roleName(roleId);
16148
+ tooltip.role = `- ${roleName}`;
16136
16149
  }
16137
16150
  }
16138
16151
  else
16139
16152
  // someone else
16140
16153
  {
16141
- const who = await firstValueFrom(this._accounts.get(recipient.userId));
16154
+ const who = await firstValueFrom(this._accounts.get(userId));
16142
16155
  annotation = who.name;
16143
16156
  if (who.role)
16144
16157
  tooltip.role = `- ${who.role}`;
16145
- else if (recipient.role) {
16146
- const role = this._roleName(recipient.role);
16147
- tooltip.role = `- ${role}`;
16158
+ else if (roleId) {
16159
+ const roleName = this._roleName(roleId);
16160
+ tooltip.role = `- ${roleName}`;
16148
16161
  }
16149
16162
  }
16150
- if (recipient.replied) {
16151
- const ago = dayjs(recipient.replied).fromNow();
16152
- const targets = this.model.recipients.filter(r => r.originId === recipient.id), to = [];
16163
+ if (replied) {
16164
+ const ago = dayjs(replied).fromNow();
16165
+ const targets = this.model.recipients.filter(r => r.originId === id), to = [];
16153
16166
  if (targets.length)
16154
16167
  for (let sibling of targets) {
16155
16168
  const who = await firstValueFrom(this._accounts.get(sibling.userId));
16156
16169
  to.push(who.name);
16157
16170
  }
16158
- if (recipient.repliedBy) {
16159
- if (recipient.repliedBy === this._session.profile.byId) {
16160
- const action = this._action(recipient.actionId, this._session.profile.byGender);
16171
+ if (repliedBy) {
16172
+ if (repliedBy === this._session.profile.byId) {
16173
+ const action = this._action(actionId, this._session.profile.byGender);
16161
16174
  if (to.length) {
16162
- if (recipient.userId === this._session.profile.userId)
16175
+ if (userId === this._session.profile.userId)
16163
16176
  tooltip.note = this._translate.get('ActionTakenByYouTo', action, this._translate.join(to), this._session.profile.name, ago);
16164
16177
  else {
16165
- const who = await firstValueFrom(this._accounts.get(recipient.userId));
16178
+ const who = await firstValueFrom(this._accounts.get(userId));
16166
16179
  tooltip.note = this._translate.get('ActionTakenByYouTo', action, this._translate.join(to), who.name, ago);
16167
16180
  }
16168
16181
  }
16169
- else if (recipient.userId === this._session.profile.userId)
16182
+ else if (userId === this._session.profile.userId)
16170
16183
  tooltip.note = this._translate.get('ActionTakenByYou', action, this._session.profile.name, ago);
16171
16184
  else {
16172
- const who = await firstValueFrom(this._accounts.get(recipient.userId));
16185
+ const who = await firstValueFrom(this._accounts.get(userId));
16173
16186
  tooltip.note = this._translate.get('ActionTakenByYou', action, who.name, ago);
16174
16187
  }
16175
16188
  }
16176
16189
  else {
16177
- const by = await firstValueFrom(this._accounts.get(recipient.repliedBy));
16178
- const action = this._action(recipient.actionId, by.gender);
16179
- if (recipient.userId === this._session.profile.userId) {
16190
+ const by = await firstValueFrom(this._accounts.get(repliedBy));
16191
+ const action = this._action(actionId, by.gender);
16192
+ if (userId === this._session.profile.userId) {
16180
16193
  if (to.length)
16181
16194
  tooltip.note = this._translate.get('YouTakenActionByTo', by.name, action, this._translate.join(to), ago);
16182
16195
  else
16183
16196
  tooltip.note = this._translate.get('YouTakenActionBy', by.name, action, ago);
16184
16197
  }
16185
16198
  else {
16186
- const who = await firstValueFrom(this._accounts.get(recipient.userId));
16199
+ const who = await firstValueFrom(this._accounts.get(userId));
16187
16200
  if (to.length)
16188
16201
  tooltip.note = this._translate.get('ActionTakenByTo', by.name, action, this._translate.join(to), who.name, ago);
16189
16202
  else
@@ -16192,80 +16205,80 @@ class FlowViewComponent extends TraceBase {
16192
16205
  }
16193
16206
  }
16194
16207
  else if (to.length) {
16195
- if (recipient.userId === this._session.profile.userId) {
16196
- const action = this._action(recipient.actionId, this._session.profile.gender);
16208
+ if (userId === this._session.profile.userId) {
16209
+ const action = this._action(actionId, this._session.profile.gender);
16197
16210
  if (this._session.isImpersonating)
16198
16211
  tooltip.note = this._translate.get('ActionTakenTo', this._session.profile.name, action, this._translate.join(to), ago);
16199
16212
  else
16200
16213
  tooltip.note = this._translate.get('YouTakenActionTo', action, this._translate.join(to), ago);
16201
16214
  }
16202
16215
  else {
16203
- const who = await firstValueFrom(this._accounts.get(recipient.userId));
16204
- const action = this._action(recipient.actionId, who.gender);
16216
+ const who = await firstValueFrom(this._accounts.get(userId));
16217
+ const action = this._action(actionId, who.gender);
16205
16218
  tooltip.note = this._translate.get('ActionTakenTo', who.name, action, this._translate.join(to), ago);
16206
16219
  }
16207
16220
  }
16208
16221
  else if (this._session.isImpersonating) {
16209
- const action = this._action(recipient.actionId, this._session.profile.gender);
16222
+ const action = this._action(actionId, this._session.profile.gender);
16210
16223
  tooltip.note = this._translate.get('ActionTaken', this._session.profile.name, action, ago);
16211
16224
  }
16212
- else if (recipient.userId === this._session.profile.userId) {
16213
- const action = this._action(recipient.actionId, You);
16225
+ else if (userId === this._session.profile.userId) {
16226
+ const action = this._action(actionId, You);
16214
16227
  tooltip.note = this._translate.get('YouTakenAction', action, ago);
16215
16228
  }
16216
16229
  else {
16217
- const who = await firstValueFrom(this._accounts.get(recipient.userId));
16218
- const action = this._action(recipient.actionId, who.gender);
16230
+ const who = await firstValueFrom(this._accounts.get(userId));
16231
+ const action = this._action(actionId, who.gender);
16219
16232
  tooltip.note = this._translate.get('ActionTaken', who.name, action, ago);
16220
16233
  }
16221
16234
  }
16222
- else if (!recipient.estimate) {
16223
- const ago = dayjs(recipient.received).fromNow();
16224
- if (recipient.userId === this._session.userId) {
16235
+ else if (!estimate) {
16236
+ const ago = dayjs(received).fromNow();
16237
+ if (userId === this._session.userId) {
16225
16238
  if (this._session.isImpersonating)
16226
16239
  tooltip.note = this._translate.personalize('ReceivedBy', this._session.profile.gender, this._session.profile.name, ago);
16227
16240
  else
16228
16241
  tooltip.note = this._translate.get('YouReceived', ago);
16229
16242
  }
16230
16243
  else {
16231
- const who = await firstValueFrom(this._accounts.get(recipient.userId));
16244
+ const who = await firstValueFrom(this._accounts.get(userId));
16232
16245
  tooltip.note = this._translate.personalize('ReceivedTime', who.gender, ago);
16233
16246
  }
16234
16247
  }
16235
- if (recipient.substituteId) {
16236
- if (recipient.substituteId === this._session.userId)
16248
+ if (substituteId) {
16249
+ if (substituteId === this._session.userId)
16237
16250
  tooltip.substituting = this._translate.personalize('SubstitutingYou', this._session.gender);
16238
16251
  else {
16239
- const substituting = await firstValueFrom(this._accounts.get(recipient.substituteId));
16252
+ const substituting = await firstValueFrom(this._accounts.get(substituteId));
16240
16253
  tooltip.substituting = this._translate.personalize('SubstitutingFor', substituting.gender, substituting.name);
16241
16254
  }
16242
16255
  }
16243
- if (recipient.originId && !recipient.replied) {
16244
- const origin = this.model.recipients.find(r => r.id === recipient.originId), action = this._session.profile.actions.find(a => a.name === origin.actionId), adjective = action.adjective || action.past || action.title;
16256
+ if (originId && !replied) {
16257
+ const origin = this.model.recipients.find(r => r.id === originId), action = this._action(origin.actionId, 'adjective');
16245
16258
  if ((origin.repliedBy || origin.userId) === this._session.userId)
16246
- tooltip.substituting = this._translate.get('ActionByYou', adjective);
16259
+ tooltip.substituting = this._translate.get('ActionByYou', action);
16247
16260
  else if (origin.repliedBy) {
16248
16261
  const who = await firstValueFrom(this._accounts.get(origin.userId));
16249
16262
  const by = await firstValueFrom(this._accounts.get(origin.repliedBy));
16250
- tooltip.substituting = this._translate.get('ActionByBy', adjective, by.name, who.name);
16263
+ tooltip.substituting = this._translate.get('ActionByBy', action, by.name, who.name);
16251
16264
  }
16252
16265
  else {
16253
16266
  const who = await firstValueFrom(this._accounts.get(origin.userId));
16254
- tooltip.substituting = this._translate.get('ActionBy', adjective, who.name);
16267
+ tooltip.substituting = this._translate.get('ActionBy', action, who.name);
16255
16268
  }
16256
16269
  }
16257
- if (recipient.escalated) {
16258
- const escalation = this.model.log.find(l => l.type === 'Escalation' && l.recipientId === recipient.originId);
16270
+ if (escalated) {
16271
+ const escalation = this.model.log.find(l => l.type === 'Escalation' && l.recipientId === originId);
16259
16272
  const who = await firstValueFrom(this._accounts.get(escalation.userId));
16260
16273
  const duration = this._duration.transform(dayjs.duration(escalation.duration, 's'));
16261
16274
  tooltip.escalation = this._translate.get('EscalatedFrom', who.name, duration);
16262
16275
  }
16263
- if (recipient.replied) {
16264
- const duration = dayjs(recipient.replied).diff(recipient.received, 's');
16276
+ if (replied) {
16277
+ const duration = dayjs(replied).diff(received, 's');
16265
16278
  tooltip.duration = this._translate.get('DurationTime', this._duration.transform(duration));
16266
16279
  }
16267
- else if (recipient.pending) {
16268
- if (recipient.estimate)
16280
+ else if (pending) {
16281
+ if (estimate)
16269
16282
  tooltip.estimatedTime = this._timeEstimate(node);
16270
16283
  else if (node.standardTime) {
16271
16284
  const diff = node.standardTime - dayjs().diff(node.time, 's');
@@ -16275,21 +16288,35 @@ class FlowViewComponent extends TraceBase {
16275
16288
  }
16276
16289
  else if (node.standardTime)
16277
16290
  tooltip.standardTime = this._translate.get('NodeStandardTime', this._duration.transform(node.standardTime));
16278
- if (recipient.fyi)
16291
+ if (fyi)
16279
16292
  tooltip.fyi = this._translate.get('FYI');
16280
16293
  return { annotation, tooltip };
16281
16294
  }
16295
+ /**
16296
+ *
16297
+ * @param name
16298
+ * @param gender
16299
+ * @returns
16300
+ */
16282
16301
  _action(name, gender) {
16283
16302
  const action = this._session.profile.actions.find(a => a.name === name);
16284
- if (gender === You) {
16285
- const gender = this._session.gender, you = gender === 'Male' ? action?.youMale :
16286
- gender === 'Female' ? action?.youFemale :
16287
- null;
16288
- return (you || action?.you || action?.past || action?.title || name).toLowerCase();
16303
+ if (!action)
16304
+ return name;
16305
+ switch (gender) {
16306
+ case 'adjective':
16307
+ return decapitalize(action.adjective || action.past || action.title);
16308
+ case You:
16309
+ const gender = this._session.gender, you = gender === 'Male' ? action.youMale :
16310
+ gender === 'Female' ? action.youFemale :
16311
+ null;
16312
+ return decapitalize(you || action.you || action.past || action.title);
16313
+ case 'Male':
16314
+ return decapitalize(action.pastMale || action.past || action.title);
16315
+ case 'Female':
16316
+ return decapitalize(action.pastFemale || action.past || action.title);
16317
+ default:
16318
+ return decapitalize(action.past || action.title);
16289
16319
  }
16290
- const past = gender === 'Male' ? action?.pastMale :
16291
- gender === 'Female' ? action?.pastFemale : null;
16292
- return (past || action?.past || action?.title || name).toLowerCase();
16293
16320
  }
16294
16321
  ngOnDestroy() {
16295
16322
  this.diagram?.destroy();
@@ -16457,90 +16484,90 @@ class TraceViewComponent extends TraceBase {
16457
16484
  };
16458
16485
  trace.push(step);
16459
16486
  if (l.recipientId) {
16460
- let recipient = recipients.find(r => r.id === l.recipientId);
16461
- if (recipient.role)
16462
- step.role = this._roleName(recipient.role);
16463
- step.fyi = recipient.fyi;
16464
- if (recipient.substituteId) {
16465
- if (recipient.repliedBy) {
16466
- if (recipient.repliedBy === this._session.userId) {
16467
- let who = await profileOf(recipient.userId);
16468
- if (recipient.substituteId === this._session.userId)
16487
+ let recipient = recipients.find(r => r.id === l.recipientId), { roleId, fyi, id, repliedBy, substituteId, userId } = recipient;
16488
+ if (roleId)
16489
+ step.role = this._roleName(roleId);
16490
+ step.fyi = fyi;
16491
+ if (substituteId) {
16492
+ if (repliedBy) {
16493
+ if (repliedBy === this._session.userId) {
16494
+ let who = await profileOf(userId);
16495
+ if (substituteId === this._session.userId)
16469
16496
  step.name = this._translate.get('ByYou', nameOf(who));
16470
16497
  else {
16471
- let substituting = await profileOf(recipient.substituteId);
16498
+ let substituting = await profileOf(substituteId);
16472
16499
  step.name = this._translate.personalize('SubstitutingByYou', who.gender, nameOf(who), nameOf(substituting));
16473
16500
  }
16474
16501
  if (action)
16475
- step.action = await actionBy(action, You, recipient.id);
16502
+ step.action = await actionBy(action, You, id);
16476
16503
  }
16477
16504
  else {
16478
- let by = await profileOf(recipient.repliedBy), who = await profileOf(recipient.userId), substituting = await profileOf(recipient.substituteId);
16505
+ let by = await profileOf(repliedBy), who = await profileOf(userId), substituting = await profileOf(substituteId);
16479
16506
  step.name = this._translate.get('SubstitutingBy', nameOf(who), nameOf(substituting), nameOf(by));
16480
16507
  if (by.role)
16481
16508
  step.role = by.role;
16482
16509
  if (action)
16483
- step.action = await actionBy(action, by.gender, recipient.id);
16510
+ step.action = await actionBy(action, by.gender, id);
16484
16511
  }
16485
16512
  }
16486
- else if (recipient.userId === this._session.userId) {
16487
- let substituting = await profileOf(recipient.substituteId);
16513
+ else if (userId === this._session.userId) {
16514
+ let substituting = await profileOf(substituteId);
16488
16515
  step.name = this._translate.personalize('YouSubstituting', this._session.gender, nameOf(substituting));
16489
16516
  if (action)
16490
- step.action = await actionBy(action, this._session.gender, recipient.id);
16517
+ step.action = await actionBy(action, this._session.gender, id);
16491
16518
  }
16492
- else if (recipient.substituteId === this._session.userId) {
16493
- let who = await profileOf(recipient.userId);
16519
+ else if (substituteId === this._session.userId) {
16520
+ let who = await profileOf(userId);
16494
16521
  step.name = this._translate.personalize('SubstitutingForYou', who.gender, nameOf(who));
16495
16522
  if (action)
16496
- step.action = await actionBy(action, who.gender, recipient.id);
16523
+ step.action = await actionBy(action, who.gender, id);
16497
16524
  }
16498
16525
  else {
16499
- let who = await profileOf(recipient.userId), substituting = await profileOf(recipient.substituteId);
16526
+ let who = await profileOf(userId), substituting = await profileOf(substituteId);
16500
16527
  step.name = this._translate.personalize('Substituting', who.gender, nameOf(who), nameOf(substituting));
16501
16528
  if (who.role)
16502
16529
  step.role = who.role;
16503
16530
  if (action)
16504
- step.action = await actionBy(action, who.gender, recipient.id);
16531
+ step.action = await actionBy(action, who.gender, id);
16505
16532
  }
16506
16533
  }
16507
- else if (recipient.repliedBy) {
16508
- if (recipient.userId === this._session.userId) {
16509
- let by = await profileOf(recipient.repliedBy);
16534
+ else if (repliedBy) {
16535
+ if (userId === this._session.userId) {
16536
+ let by = await profileOf(repliedBy);
16510
16537
  step.name = this._translate.get('YouBy', nameOf(by));
16511
16538
  if (action)
16512
- step.action = await actionBy(action, by.gender, recipient.id);
16539
+ step.action = await actionBy(action, by.gender, id);
16513
16540
  }
16514
16541
  else {
16515
- let who = await profileOf(recipient.userId);
16516
- if (recipient.repliedBy === this._session.userId) {
16542
+ let who = await profileOf(userId);
16543
+ if (repliedBy === this._session.userId) {
16517
16544
  step.name = this._translate.get('ByYou', nameOf(who));
16518
16545
  if (action)
16519
- step.action = await actionBy(action, You, recipient.id);
16546
+ step.action = await actionBy(action, You, id);
16520
16547
  }
16521
16548
  else {
16522
- let by = await profileOf(recipient.repliedBy);
16549
+ let by = await profileOf(repliedBy);
16523
16550
  step.name = this._translate.get('By', nameOf(who), nameOf(by));
16524
16551
  if (by.role)
16525
16552
  step.role = by.role;
16526
16553
  if (action)
16527
- step.action = await actionBy(action, by.gender, recipient.id);
16554
+ step.action = await actionBy(action, by.gender, id);
16528
16555
  }
16529
16556
  }
16530
16557
  }
16531
16558
  else {
16532
- if (recipient.userId === this._session.userId) {
16559
+ if (userId === this._session.userId) {
16533
16560
  step.name = this._translate.get('You');
16534
16561
  if (action)
16535
- step.action = await actionBy(action, You, recipient.id);
16562
+ step.action = await actionBy(action, You, id);
16536
16563
  }
16537
16564
  else {
16538
- let who = await profileOf(recipient.userId);
16565
+ let who = await profileOf(userId);
16539
16566
  step.name = nameOf(who);
16540
16567
  if (who.role)
16541
16568
  step.role = who.role;
16542
16569
  if (action)
16543
- step.action = await actionBy(action, who.gender, recipient.id);
16570
+ step.action = await actionBy(action, who.gender, id);
16544
16571
  }
16545
16572
  }
16546
16573
  }
@@ -16572,23 +16599,24 @@ class TraceViewComponent extends TraceBase {
16572
16599
  }
16573
16600
  }
16574
16601
  for (let recipient of recipients) {
16575
- if (!recipient.pending && !recipient.estimate)
16602
+ const { repliedBy, originId, note, escalated, pending, substituteId, actionId, userId, estimate, fyi, received, roleId, nodeId } = recipient;
16603
+ if (!pending && !estimate)
16576
16604
  continue;
16577
16605
  let step = {
16578
- time: recipient.received,
16579
- fyi: recipient.fyi,
16580
- estimate: recipient.estimate,
16581
- pending: recipient.pending,
16582
- action: recipient.actionId,
16583
- note: recipient.note,
16584
- type: recipient.estimate ? 'Estimate' : 'Pending',
16585
- duration: recipient.pending ? dayjs().diff(recipient.received, 's') : null,
16586
- role: recipient.role ? this._roleName(recipient.role) : null
16606
+ time: received,
16607
+ fyi,
16608
+ estimate,
16609
+ pending,
16610
+ action: actionId,
16611
+ note,
16612
+ type: estimate ? 'Estimate' : 'Pending',
16613
+ duration: pending ? dayjs().diff(received, 's') : null,
16614
+ role: roleId ? this._roleName(roleId) : null
16587
16615
  };
16588
- if (recipient.nodeId) {
16589
- const node = this.model.workflow.nodes.find(n => n.id === recipient.nodeId);
16616
+ if (nodeId) {
16617
+ const node = this.model.workflow.nodes.find(n => n.id === nodeId);
16590
16618
  if (node) {
16591
- if (recipient.estimate) {
16619
+ if (estimate) {
16592
16620
  const { min, max } = super._estimateTime(node);
16593
16621
  if (max)
16594
16622
  step.durationMin = min,
@@ -16596,36 +16624,36 @@ class TraceViewComponent extends TraceBase {
16596
16624
  }
16597
16625
  }
16598
16626
  }
16599
- if (recipient.substituteId) {
16600
- if (recipient.substituteId === this._session.userId) {
16601
- let who = await profileOf(recipient.userId);
16627
+ if (substituteId) {
16628
+ if (substituteId === this._session.userId) {
16629
+ let who = await profileOf(userId);
16602
16630
  step.name = this._translate.personalize('SubstitutingForYou', who.gender, nameOf(who));
16603
16631
  }
16604
- else if (recipient.userId === this._session.userId) {
16605
- let substituting = await profileOf(recipient.substituteId);
16632
+ else if (userId === this._session.userId) {
16633
+ let substituting = await profileOf(substituteId);
16606
16634
  step.name = this._translate.personalize('YouSubstituting', this._session.gender, nameOf(substituting));
16607
16635
  }
16608
16636
  else {
16609
- let who = await profileOf(recipient.userId), substituting = await profileOf(recipient.substituteId);
16637
+ let who = await profileOf(userId), substituting = await profileOf(substituteId);
16610
16638
  step.name = this._translate.personalize('Substituting', who.gender, nameOf(who), nameOf(substituting));
16611
16639
  if (who.role)
16612
16640
  step.role = who.role;
16613
16641
  }
16614
16642
  }
16615
- else if (recipient.repliedBy) {
16616
- let who = await profileOf(recipient.userId);
16617
- if (recipient.repliedBy === this._session.userId)
16643
+ else if (repliedBy) {
16644
+ let who = await profileOf(userId);
16645
+ if (repliedBy === this._session.userId)
16618
16646
  step.name = this._translate.get('ByYou', nameOf(who));
16619
16647
  else {
16620
- let by = await profileOf(recipient.repliedBy);
16648
+ let by = await profileOf(repliedBy);
16621
16649
  step.name = this._translate.get('By', nameOf(who), nameOf(by));
16622
16650
  if (by.role)
16623
16651
  step.role = by.role;
16624
16652
  }
16625
16653
  }
16626
- else if (recipient.escalated) {
16627
- let escalation = this.model.log.find(l => l.type === 'Escalation' && l.recipientId === recipient.originId);
16628
- let to = await profileOf(recipient.userId);
16654
+ else if (escalated) {
16655
+ let escalation = this.model.log.find(l => l.type === 'Escalation' && l.recipientId === originId);
16656
+ let to = await profileOf(userId);
16629
16657
  if (escalation.userId === this._session.userId)
16630
16658
  step.name = this._translate.get('EscalatedByYou', nameOf(to));
16631
16659
  else {
@@ -16634,10 +16662,10 @@ class TraceViewComponent extends TraceBase {
16634
16662
  }
16635
16663
  }
16636
16664
  else {
16637
- if (recipient.userId === this._session.userId)
16665
+ if (userId === this._session.userId)
16638
16666
  step.name = this._translate.get('You');
16639
16667
  else {
16640
- let who = await profileOf(recipient.userId);
16668
+ let who = await profileOf(userId);
16641
16669
  step.name = nameOf(who);
16642
16670
  if (who.role)
16643
16671
  step.role = who.role;
@@ -28879,7 +28907,7 @@ let TimelineViewComponent = class TimelineViewComponent {
28879
28907
  task.duration = l.duration * 1000;
28880
28908
  }
28881
28909
  else
28882
- task.ending = this.model.completed ? new Date(l.time) : new Date();
28910
+ task.ending = this.model.completed ? new Date(this.model.completed) : new Date(l.time);
28883
28911
  tasks.push(task);
28884
28912
  break;
28885
28913
  }
@@ -28988,8 +29016,8 @@ let TimelineViewComponent = class TimelineViewComponent {
28988
29016
  task.name = this._translate.get('WhoSubstituting', u[0].name, u[1].name);
28989
29017
  if (u[0].role)
28990
29018
  task.name += `, ${u[0].role}`;
28991
- if (r.role) {
28992
- const role = this._session.profile.roles.find(o => o.name === r.role);
29019
+ if (r.roleId) {
29020
+ const role = this._session.profile.roles.find(o => o.name === r.roleId);
28993
29021
  if (role)
28994
29022
  task.name += `, ${role.name}`;
28995
29023
  }
@@ -29001,8 +29029,8 @@ let TimelineViewComponent = class TimelineViewComponent {
29001
29029
  task.name = u.name;
29002
29030
  if (u.role)
29003
29031
  task.name += `, ${u.role}`;
29004
- else if (r.role) {
29005
- const role = this._session.profile.roles.find(o => o.name === r.role);
29032
+ else if (r.roleId) {
29033
+ const role = this._session.profile.roles.find(o => o.name === r.roleId);
29006
29034
  if (role)
29007
29035
  task.name += `, ${role.name}`;
29008
29036
  }