@eric-emg/symphiq-components 1.2.381 → 1.2.383

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.
@@ -12,7 +12,7 @@ import * as i1$1 from '@angular/common';
12
12
  import { NgClass, CommonModule, isPlatformBrowser, DOCUMENT } from '@angular/common';
13
13
  import * as i2$1 from '@angular/forms';
14
14
  import { FormsModule, FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
15
- import { trigger, transition, style, animate } from '@angular/animations';
15
+ import { trigger, transition, style, animate, keyframes } from '@angular/animations';
16
16
  import { toObservable, toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
17
17
  import { MarkdownComponent } from 'ngx-markdown';
18
18
  import dayjs from 'dayjs';
@@ -88184,7 +88184,7 @@ function ShopProfileQuestionCardComponent_Conditional_8_For_2_Template(rf, ctx)
88184
88184
  } if (rf & 2) {
88185
88185
  const answerData_r3 = ctx.$implicit;
88186
88186
  const ctx_r0 = i0.ɵɵnextContext(2);
88187
- i0.ɵɵproperty("ngClass", ctx_r0.answerChipClasses());
88187
+ i0.ɵɵproperty("@answerAnimation", undefined)("ngClass", ctx_r0.answerChipClasses());
88188
88188
  i0.ɵɵadvance();
88189
88189
  i0.ɵɵproperty("ngClass", ctx_r0.answerTextClasses());
88190
88190
  i0.ɵɵadvance();
@@ -88192,13 +88192,13 @@ function ShopProfileQuestionCardComponent_Conditional_8_For_2_Template(rf, ctx)
88192
88192
  i0.ɵɵadvance();
88193
88193
  i0.ɵɵproperty("viewMode", ctx_r0.viewMode())("user", answerData_r3.user);
88194
88194
  i0.ɵɵadvance();
88195
- i0.ɵɵproperty("ngClass", ctx_r0.answerDateClasses());
88195
+ i0.ɵɵproperty("@answerAnimation", undefined)("ngClass", ctx_r0.answerDateClasses());
88196
88196
  i0.ɵɵadvance();
88197
88197
  i0.ɵɵtextInterpolate1(" Answered ", ctx_r0.formatAnswerDate(answerData_r3.answer.createdDate), " ");
88198
88198
  } }
88199
88199
  function ShopProfileQuestionCardComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
88200
88200
  i0.ɵɵelementStart(0, "div", 7);
88201
- i0.ɵɵrepeaterCreate(1, ShopProfileQuestionCardComponent_Conditional_8_For_2_Template, 6, 7, null, null, _forTrack0$3);
88201
+ i0.ɵɵrepeaterCreate(1, ShopProfileQuestionCardComponent_Conditional_8_For_2_Template, 6, 9, null, null, _forTrack0$3);
88202
88202
  i0.ɵɵelementEnd();
88203
88203
  } if (rf & 2) {
88204
88204
  const ctx_r0 = i0.ɵɵnextContext();
@@ -88404,7 +88404,20 @@ class ShopProfileQuestionCardComponent {
88404
88404
  i0.ɵɵproperty("ngClass", ctx.buttonClasses());
88405
88405
  i0.ɵɵadvance(2);
88406
88406
  i0.ɵɵtextInterpolate(ctx.isAnswered() ? "Edit Answer" : "Answer");
88407
- } }, dependencies: [CommonModule, i1$1.NgClass, UserAvatarComponent], encapsulation: 2, changeDetection: 0 }); }
88407
+ } }, dependencies: [CommonModule, i1$1.NgClass, UserAvatarComponent], encapsulation: 2, data: { animation: [
88408
+ trigger('answerAnimation', [
88409
+ transition(':enter', [
88410
+ animate('500ms ease-out', keyframes([
88411
+ style({ opacity: 0, transform: 'scale(0.8)', boxShadow: '0 0 0 0 rgba(59, 130, 246, 0)', offset: 0 }),
88412
+ style({ opacity: 1, transform: 'scale(1.05)', boxShadow: '0 0 20px 4px rgba(59, 130, 246, 0.5)', offset: 0.5 }),
88413
+ style({ opacity: 1, transform: 'scale(1)', boxShadow: '0 0 0 0 rgba(59, 130, 246, 0)', offset: 1 })
88414
+ ]))
88415
+ ]),
88416
+ transition(':leave', [
88417
+ animate('300ms ease-in', style({ opacity: 0, transform: 'scale(0.8)' }))
88418
+ ])
88419
+ ])
88420
+ ] }, changeDetection: 0 }); }
88408
88421
  }
88409
88422
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ShopProfileQuestionCardComponent, [{
88410
88423
  type: Component,
@@ -88413,6 +88426,20 @@ class ShopProfileQuestionCardComponent {
88413
88426
  standalone: true,
88414
88427
  imports: [CommonModule, UserAvatarComponent],
88415
88428
  changeDetection: ChangeDetectionStrategy.OnPush,
88429
+ animations: [
88430
+ trigger('answerAnimation', [
88431
+ transition(':enter', [
88432
+ animate('500ms ease-out', keyframes([
88433
+ style({ opacity: 0, transform: 'scale(0.8)', boxShadow: '0 0 0 0 rgba(59, 130, 246, 0)', offset: 0 }),
88434
+ style({ opacity: 1, transform: 'scale(1.05)', boxShadow: '0 0 20px 4px rgba(59, 130, 246, 0.5)', offset: 0.5 }),
88435
+ style({ opacity: 1, transform: 'scale(1)', boxShadow: '0 0 0 0 rgba(59, 130, 246, 0)', offset: 1 })
88436
+ ]))
88437
+ ]),
88438
+ transition(':leave', [
88439
+ animate('300ms ease-in', style({ opacity: 0, transform: 'scale(0.8)' }))
88440
+ ])
88441
+ ])
88442
+ ],
88416
88443
  template: `
88417
88444
  <div [ngClass]="containerClasses()" class="rounded-xl border-2 p-6 transition-all duration-200">
88418
88445
  <!-- Question Header with Checkbox -->
@@ -88461,7 +88488,7 @@ class ShopProfileQuestionCardComponent {
88461
88488
  <!-- Answered State - Show answer chips -->
88462
88489
  <div class="flex flex-wrap gap-3">
88463
88490
  @for (answerData of questionAnswers(); track answerData.answer.id) {
88464
- <div [ngClass]="answerChipClasses()" class="flex items-center gap-2 px-4 py-2.5 rounded-full">
88491
+ <div @answerAnimation [ngClass]="answerChipClasses()" class="flex items-center gap-2 px-4 py-2.5 rounded-full">
88465
88492
  <span [ngClass]="answerTextClasses()" class="text-sm font-medium">
88466
88493
  {{ answerData.answer.answer }}
88467
88494
  </span>
@@ -88471,7 +88498,7 @@ class ShopProfileQuestionCardComponent {
88471
88498
  size="small"
88472
88499
  />
88473
88500
  </div>
88474
- <div [ngClass]="answerDateClasses()" class="self-center text-xs -ml-1">
88501
+ <div @answerAnimation [ngClass]="answerDateClasses()" class="self-center text-xs -ml-1">
88475
88502
  Answered {{ formatAnswerDate(answerData.answer.createdDate) }}
88476
88503
  </div>
88477
88504
  }
@@ -88516,7 +88543,7 @@ class ShopProfileQuestionCardComponent {
88516
88543
  `
88517
88544
  }]
88518
88545
  }], null, { question: [{ type: i0.Input, args: [{ isSignal: true, alias: "question", required: true }] }], viewMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewMode", required: false }] }], viewType: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewType", required: false }] }], profileShopAnswers: [{ type: i0.Input, args: [{ isSignal: true, alias: "profileShopAnswers", required: false }] }], users: [{ type: i0.Input, args: [{ isSignal: true, alias: "users", required: false }] }], answerClick: [{ type: i0.Output, args: ["answerClick"] }] }); })();
88519
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ShopProfileQuestionCardComponent, { className: "ShopProfileQuestionCardComponent", filePath: "lib/components/profile-analysis-dashboard/cards/shop-profile-question-card.component.ts", lineNumber: 119 }); })();
88546
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ShopProfileQuestionCardComponent, { className: "ShopProfileQuestionCardComponent", filePath: "lib/components/profile-analysis-dashboard/cards/shop-profile-question-card.component.ts", lineNumber: 134 }); })();
88520
88547
 
88521
88548
  const _c0$5 = ["scrollContainer"];
88522
88549
  const _c1$2 = ["stickySentinel"];
@@ -88745,6 +88772,7 @@ class ShopProfileQuestionAnswerComponent {
88745
88772
  this.ngZone = inject(NgZone);
88746
88773
  this.isSticky = false;
88747
88774
  this.selectedAnswerTexts = signal([], ...(ngDevMode ? [{ debugName: "selectedAnswerTexts" }] : []));
88775
+ this.initialAnswerTexts = signal([], ...(ngDevMode ? [{ debugName: "initialAnswerTexts" }] : []));
88748
88776
  this.addOtherAnswersExpanded = signal(false, ...(ngDevMode ? [{ debugName: "addOtherAnswersExpanded" }] : []));
88749
88777
  this.customAnswerText = signal('', ...(ngDevMode ? [{ debugName: "customAnswerText" }] : []));
88750
88778
  this.isSaving = signal(false, ...(ngDevMode ? [{ debugName: "isSaving" }] : []));
@@ -88752,6 +88780,7 @@ class ShopProfileQuestionAnswerComponent {
88752
88780
  this.pendingQuestionId = signal(null, ...(ngDevMode ? [{ debugName: "pendingQuestionId" }] : []));
88753
88781
  this.isCountAnimating = signal(false, ...(ngDevMode ? [{ debugName: "isCountAnimating" }] : []));
88754
88782
  this.previousAnsweredCount = signal(null, ...(ngDevMode ? [{ debugName: "previousAnsweredCount" }] : []));
88783
+ this.saveStartTime = signal(0, ...(ngDevMode ? [{ debugName: "saveStartTime" }] : []));
88755
88784
  this.answerOptions = computed(() => {
88756
88785
  const q = this.question();
88757
88786
  const potentialAnswers = q.potentialAnswers || [];
@@ -88810,8 +88839,22 @@ class ShopProfileQuestionAnswerComponent {
88810
88839
  this.canAddCustomAnswers = computed(() => {
88811
88840
  return this.customAnswerText().trim().length > 0;
88812
88841
  }, ...(ngDevMode ? [{ debugName: "canAddCustomAnswers" }] : []));
88842
+ this.hasAnswersChanged = computed(() => {
88843
+ const initial = this.initialAnswerTexts();
88844
+ const current = this.selectedAnswerTexts();
88845
+ if (initial.length !== current.length)
88846
+ return true;
88847
+ const sortedInitial = [...initial].sort();
88848
+ const sortedCurrent = [...current].sort();
88849
+ return sortedInitial.some((val, idx) => val !== sortedCurrent[idx]);
88850
+ }, ...(ngDevMode ? [{ debugName: "hasAnswersChanged" }] : []));
88813
88851
  this.saveButtonsDisabled = computed(() => {
88814
- return this.selectedAnswerTexts().length === 0 || this.addOtherAnswersExpanded() || this.isSaving();
88852
+ const noAnswers = this.selectedAnswerTexts().length === 0;
88853
+ const isExpanded = this.addOtherAnswersExpanded();
88854
+ const saving = this.isSaving();
88855
+ const hasInitialAnswers = this.initialAnswerTexts().length > 0;
88856
+ const unchanged = hasInitialAnswers && !this.hasAnswersChanged();
88857
+ return noAnswers || isExpanded || saving || unchanged;
88815
88858
  }, ...(ngDevMode ? [{ debugName: "saveButtonsDisabled" }] : []));
88816
88859
  this.stickyState = false;
88817
88860
  this.lastStickyChange = 0;
@@ -88821,6 +88864,7 @@ class ShopProfileQuestionAnswerComponent {
88821
88864
  .filter(a => a.profileQuestionId === questionId)
88822
88865
  .map(a => a.answer || '');
88823
88866
  this.selectedAnswerTexts.set(existingAnswers);
88867
+ this.initialAnswerTexts.set(existingAnswers);
88824
88868
  });
88825
88869
  effect(() => {
88826
88870
  const answers = this.profileShopAnswers();
@@ -88829,15 +88873,20 @@ class ShopProfileQuestionAnswerComponent {
88829
88873
  if (pendingId !== null && pendingAction !== null) {
88830
88874
  const hasAnswerForQuestion = answers.some(a => a.profileQuestionId === pendingId);
88831
88875
  if (hasAnswerForQuestion) {
88832
- this.isSaving.set(false);
88833
- if (pendingAction === 'save') {
88834
- this.navigateToList.emit();
88835
- }
88836
- else if (pendingAction === 'saveAndNext') {
88837
- this.navigateToNextQuestion.emit();
88838
- }
88839
- this.pendingQuestionId.set(null);
88840
- this.pendingSaveAction.set(null);
88876
+ const elapsed = Date.now() - this.saveStartTime();
88877
+ const minDelay = 300;
88878
+ const remainingDelay = Math.max(0, minDelay - elapsed);
88879
+ setTimeout(() => {
88880
+ this.isSaving.set(false);
88881
+ if (pendingAction === 'save') {
88882
+ this.navigateToList.emit();
88883
+ }
88884
+ else if (pendingAction === 'saveAndNext') {
88885
+ this.navigateToNextQuestion.emit();
88886
+ }
88887
+ this.pendingQuestionId.set(null);
88888
+ this.pendingSaveAction.set(null);
88889
+ }, remainingDelay);
88841
88890
  }
88842
88891
  }
88843
88892
  });
@@ -88935,6 +88984,7 @@ class ShopProfileQuestionAnswerComponent {
88935
88984
  }
88936
88985
  onSave() {
88937
88986
  const questionId = this.question().id;
88987
+ this.saveStartTime.set(Date.now());
88938
88988
  this.isSaving.set(true);
88939
88989
  this.pendingSaveAction.set('save');
88940
88990
  this.pendingQuestionId.set(questionId);
@@ -88946,6 +88996,7 @@ class ShopProfileQuestionAnswerComponent {
88946
88996
  }
88947
88997
  onSaveAndNext() {
88948
88998
  const questionId = this.question().id;
88999
+ this.saveStartTime.set(Date.now());
88949
89000
  this.isSaving.set(true);
88950
89001
  this.pendingSaveAction.set('saveAndNext');
88951
89002
  this.pendingQuestionId.set(questionId);
@@ -90201,6 +90252,7 @@ class ShopProfileStatusCardComponent {
90201
90252
  }, ...(ngDevMode ? [{ debugName: "hasQuestions" }] : []));
90202
90253
  this.questionsByCategory = computed(() => {
90203
90254
  const questions = this.questions();
90255
+ const answers = this.profileShopAnswers();
90204
90256
  const categoryMap = new Map();
90205
90257
  questions.forEach(q => {
90206
90258
  const category = q.category || 'Other';
@@ -90211,7 +90263,7 @@ class ShopProfileStatusCardComponent {
90211
90263
  });
90212
90264
  const items = [];
90213
90265
  categoryMap.forEach((categoryQuestions, category) => {
90214
- const answeredCount = categoryQuestions.filter(q => q.answered === true).length;
90266
+ const answeredCount = categoryQuestions.filter(q => answers.some(a => a.profileQuestionId === q.id)).length;
90215
90267
  const totalCount = categoryQuestions.length;
90216
90268
  const progress = totalCount > 0 ? (answeredCount / totalCount) * 100 : 0;
90217
90269
  items.push({
@@ -90223,15 +90275,11 @@ class ShopProfileStatusCardComponent {
90223
90275
  progress
90224
90276
  });
90225
90277
  });
90226
- return items.sort((a, b) => {
90227
- if (a.progress !== b.progress) {
90228
- return a.progress - b.progress;
90229
- }
90230
- return a.name.localeCompare(b.name);
90231
- });
90278
+ return items.sort((a, b) => a.name.localeCompare(b.name));
90232
90279
  }, ...(ngDevMode ? [{ debugName: "questionsByCategory" }] : []));
90233
90280
  this.questionsByFocusArea = computed(() => {
90234
90281
  const questions = this.questions();
90282
+ const answers = this.profileShopAnswers();
90235
90283
  const focusAreaMap = new Map();
90236
90284
  questions.forEach(q => {
90237
90285
  const focusAreas = q.focusAreaDomains || [];
@@ -90253,7 +90301,7 @@ class ShopProfileStatusCardComponent {
90253
90301
  });
90254
90302
  const items = [];
90255
90303
  focusAreaMap.forEach((faQuestions, focusArea) => {
90256
- const answeredCount = faQuestions.filter(q => q.answered === true).length;
90304
+ const answeredCount = faQuestions.filter(q => answers.some(a => a.profileQuestionId === q.id)).length;
90257
90305
  const totalCount = faQuestions.length;
90258
90306
  const progress = totalCount > 0 ? (answeredCount / totalCount) * 100 : 0;
90259
90307
  items.push({
@@ -90265,12 +90313,7 @@ class ShopProfileStatusCardComponent {
90265
90313
  progress
90266
90314
  });
90267
90315
  });
90268
- return items.sort((a, b) => {
90269
- if (a.progress !== b.progress) {
90270
- return a.progress - b.progress;
90271
- }
90272
- return a.name.localeCompare(b.name);
90273
- });
90316
+ return items.sort((a, b) => a.name.localeCompare(b.name));
90274
90317
  }, ...(ngDevMode ? [{ debugName: "questionsByFocusArea" }] : []));
90275
90318
  this.currentGroupedQuestions = computed(() => {
90276
90319
  return this.currentView() === 'category'