@eric-emg/symphiq-components 1.2.381 → 1.2.384

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,8 @@ 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" }] : []));
88784
+ this.lastLoadedQuestionId = signal(null, ...(ngDevMode ? [{ debugName: "lastLoadedQuestionId" }] : []));
88755
88785
  this.answerOptions = computed(() => {
88756
88786
  const q = this.question();
88757
88787
  const potentialAnswers = q.potentialAnswers || [];
@@ -88810,17 +88840,36 @@ class ShopProfileQuestionAnswerComponent {
88810
88840
  this.canAddCustomAnswers = computed(() => {
88811
88841
  return this.customAnswerText().trim().length > 0;
88812
88842
  }, ...(ngDevMode ? [{ debugName: "canAddCustomAnswers" }] : []));
88843
+ this.hasAnswersChanged = computed(() => {
88844
+ const initial = this.initialAnswerTexts();
88845
+ const current = this.selectedAnswerTexts();
88846
+ if (initial.length !== current.length)
88847
+ return true;
88848
+ const sortedInitial = [...initial].sort();
88849
+ const sortedCurrent = [...current].sort();
88850
+ return sortedInitial.some((val, idx) => val !== sortedCurrent[idx]);
88851
+ }, ...(ngDevMode ? [{ debugName: "hasAnswersChanged" }] : []));
88813
88852
  this.saveButtonsDisabled = computed(() => {
88814
- return this.selectedAnswerTexts().length === 0 || this.addOtherAnswersExpanded() || this.isSaving();
88853
+ const noAnswers = this.selectedAnswerTexts().length === 0;
88854
+ const isExpanded = this.addOtherAnswersExpanded();
88855
+ const saving = this.isSaving();
88856
+ const hasInitialAnswers = this.initialAnswerTexts().length > 0;
88857
+ const unchanged = hasInitialAnswers && !this.hasAnswersChanged();
88858
+ return noAnswers || isExpanded || saving || unchanged;
88815
88859
  }, ...(ngDevMode ? [{ debugName: "saveButtonsDisabled" }] : []));
88816
88860
  this.stickyState = false;
88817
88861
  this.lastStickyChange = 0;
88818
88862
  effect(() => {
88819
- const questionId = this.question().id;
88820
- const existingAnswers = this.profileShopAnswers()
88863
+ const questionId = this.question().id ?? null;
88864
+ const lastId = untracked(() => this.lastLoadedQuestionId());
88865
+ if (questionId === lastId)
88866
+ return;
88867
+ this.lastLoadedQuestionId.set(questionId);
88868
+ const existingAnswers = untracked(() => this.profileShopAnswers())
88821
88869
  .filter(a => a.profileQuestionId === questionId)
88822
88870
  .map(a => a.answer || '');
88823
88871
  this.selectedAnswerTexts.set(existingAnswers);
88872
+ this.initialAnswerTexts.set(existingAnswers);
88824
88873
  });
88825
88874
  effect(() => {
88826
88875
  const answers = this.profileShopAnswers();
@@ -88829,15 +88878,20 @@ class ShopProfileQuestionAnswerComponent {
88829
88878
  if (pendingId !== null && pendingAction !== null) {
88830
88879
  const hasAnswerForQuestion = answers.some(a => a.profileQuestionId === pendingId);
88831
88880
  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);
88881
+ const elapsed = Date.now() - this.saveStartTime();
88882
+ const minDelay = 300;
88883
+ const remainingDelay = Math.max(0, minDelay - elapsed);
88884
+ setTimeout(() => {
88885
+ this.isSaving.set(false);
88886
+ if (pendingAction === 'save') {
88887
+ this.navigateToList.emit();
88888
+ }
88889
+ else if (pendingAction === 'saveAndNext') {
88890
+ this.navigateToNextQuestion.emit();
88891
+ }
88892
+ this.pendingQuestionId.set(null);
88893
+ this.pendingSaveAction.set(null);
88894
+ }, remainingDelay);
88841
88895
  }
88842
88896
  }
88843
88897
  });
@@ -88935,6 +88989,7 @@ class ShopProfileQuestionAnswerComponent {
88935
88989
  }
88936
88990
  onSave() {
88937
88991
  const questionId = this.question().id;
88992
+ this.saveStartTime.set(Date.now());
88938
88993
  this.isSaving.set(true);
88939
88994
  this.pendingSaveAction.set('save');
88940
88995
  this.pendingQuestionId.set(questionId);
@@ -88946,6 +89001,7 @@ class ShopProfileQuestionAnswerComponent {
88946
89001
  }
88947
89002
  onSaveAndNext() {
88948
89003
  const questionId = this.question().id;
89004
+ this.saveStartTime.set(Date.now());
88949
89005
  this.isSaving.set(true);
88950
89006
  this.pendingSaveAction.set('saveAndNext');
88951
89007
  this.pendingQuestionId.set(questionId);
@@ -89440,7 +89496,7 @@ class ShopProfileQuestionAnswerComponent {
89440
89496
  type: ViewChild,
89441
89497
  args: ['questionTitle']
89442
89498
  }] }); })();
89443
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ShopProfileQuestionAnswerComponent, { className: "ShopProfileQuestionAnswerComponent", filePath: "lib/components/profile-analysis-dashboard/cards/shop-profile-question-answer.component.ts", lineNumber: 259 }); })();
89499
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ShopProfileQuestionAnswerComponent, { className: "ShopProfileQuestionAnswerComponent", filePath: "lib/components/profile-analysis-dashboard/cards/shop-profile-question-answer.component.ts", lineNumber: 260 }); })();
89444
89500
 
89445
89501
  const _c0$4 = ["modalContent"];
89446
89502
  const _c1$1 = ["modalWrapper"];
@@ -90201,6 +90257,7 @@ class ShopProfileStatusCardComponent {
90201
90257
  }, ...(ngDevMode ? [{ debugName: "hasQuestions" }] : []));
90202
90258
  this.questionsByCategory = computed(() => {
90203
90259
  const questions = this.questions();
90260
+ const answers = this.profileShopAnswers();
90204
90261
  const categoryMap = new Map();
90205
90262
  questions.forEach(q => {
90206
90263
  const category = q.category || 'Other';
@@ -90211,7 +90268,7 @@ class ShopProfileStatusCardComponent {
90211
90268
  });
90212
90269
  const items = [];
90213
90270
  categoryMap.forEach((categoryQuestions, category) => {
90214
- const answeredCount = categoryQuestions.filter(q => q.answered === true).length;
90271
+ const answeredCount = categoryQuestions.filter(q => answers.some(a => a.profileQuestionId === q.id)).length;
90215
90272
  const totalCount = categoryQuestions.length;
90216
90273
  const progress = totalCount > 0 ? (answeredCount / totalCount) * 100 : 0;
90217
90274
  items.push({
@@ -90223,15 +90280,11 @@ class ShopProfileStatusCardComponent {
90223
90280
  progress
90224
90281
  });
90225
90282
  });
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
- });
90283
+ return items.sort((a, b) => a.name.localeCompare(b.name));
90232
90284
  }, ...(ngDevMode ? [{ debugName: "questionsByCategory" }] : []));
90233
90285
  this.questionsByFocusArea = computed(() => {
90234
90286
  const questions = this.questions();
90287
+ const answers = this.profileShopAnswers();
90235
90288
  const focusAreaMap = new Map();
90236
90289
  questions.forEach(q => {
90237
90290
  const focusAreas = q.focusAreaDomains || [];
@@ -90253,7 +90306,7 @@ class ShopProfileStatusCardComponent {
90253
90306
  });
90254
90307
  const items = [];
90255
90308
  focusAreaMap.forEach((faQuestions, focusArea) => {
90256
- const answeredCount = faQuestions.filter(q => q.answered === true).length;
90309
+ const answeredCount = faQuestions.filter(q => answers.some(a => a.profileQuestionId === q.id)).length;
90257
90310
  const totalCount = faQuestions.length;
90258
90311
  const progress = totalCount > 0 ? (answeredCount / totalCount) * 100 : 0;
90259
90312
  items.push({
@@ -90265,12 +90318,7 @@ class ShopProfileStatusCardComponent {
90265
90318
  progress
90266
90319
  });
90267
90320
  });
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
- });
90321
+ return items.sort((a, b) => a.name.localeCompare(b.name));
90274
90322
  }, ...(ngDevMode ? [{ debugName: "questionsByFocusArea" }] : []));
90275
90323
  this.currentGroupedQuestions = computed(() => {
90276
90324
  return this.currentView() === 'category'