@edvak99/voice-receptionist-widget 1.1.3 → 1.1.4

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.
Files changed (126) hide show
  1. package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-DT9UKvQO.mjs +307 -0
  2. package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-DT9UKvQO.mjs.map +1 -0
  3. package/fesm2022/{edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-Dn0GrZ6_.mjs → edvak99-voice-receptionist-widget-ai-receptionist-api.service-48cifVPF.mjs} +1275 -561
  4. package/fesm2022/edvak99-voice-receptionist-widget-ai-receptionist-api.service-48cifVPF.mjs.map +1 -0
  5. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-C5inEHJw.mjs +278 -0
  6. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-C5inEHJw.mjs.map +1 -0
  7. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-sYhM20CE.mjs +418 -0
  8. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-sYhM20CE.mjs.map +1 -0
  9. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-DpwajEOE.mjs +194 -0
  10. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-DpwajEOE.mjs.map +1 -0
  11. package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-B8_qp7Fe.mjs → edvak99-voice-receptionist-widget-call-recording-player.component-CgkRcFOl.mjs} +3 -2
  12. package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-B8_qp7Fe.mjs.map → edvak99-voice-receptionist-widget-call-recording-player.component-CgkRcFOl.mjs.map} +1 -1
  13. package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-Cj2XTeK4.mjs → edvak99-voice-receptionist-widget-call-review.service-CIMcjGKX.mjs} +2 -2
  14. package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-Cj2XTeK4.mjs.map → edvak99-voice-receptionist-widget-call-review.service-CIMcjGKX.mjs.map} +1 -1
  15. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-Deh3jPgo.mjs +21 -0
  16. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-Deh3jPgo.mjs.map +1 -0
  17. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-CxbO0eDS.mjs +440 -0
  18. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-CxbO0eDS.mjs.map +1 -0
  19. package/fesm2022/{edvak99-voice-receptionist-widget-eds-elapsed.pipe-BgLsnq6A.mjs → edvak99-voice-receptionist-widget-dashboard-socket.service-BX91r74O.mjs} +5 -21
  20. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-socket.service-BX91r74O.mjs.map +1 -0
  21. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-CWRiJGfv.mjs +38 -0
  22. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-CWRiJGfv.mjs.map +1 -0
  23. package/fesm2022/edvak99-voice-receptionist-widget-eds-button.component-Bg5T5BN8.mjs +27 -0
  24. package/fesm2022/edvak99-voice-receptionist-widget-eds-button.component-Bg5T5BN8.mjs.map +1 -0
  25. package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-BFCiJOT3.mjs +22 -0
  26. package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-BFCiJOT3.mjs.map +1 -0
  27. package/fesm2022/{edvak99-voice-receptionist-widget-live-calls-list.service-0kGWO6sh.mjs → edvak99-voice-receptionist-widget-eds-pulse-dot.component-BPY6xN7C.mjs} +15 -5
  28. package/fesm2022/edvak99-voice-receptionist-widget-eds-pulse-dot.component-BPY6xN7C.mjs.map +1 -0
  29. package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-BsBQIS_f.mjs +203 -0
  30. package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-BsBQIS_f.mjs.map +1 -0
  31. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-CaSDMxpV.mjs +81 -0
  32. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-CaSDMxpV.mjs.map +1 -0
  33. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-Cy3ND-c-.mjs +1070 -0
  34. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-Cy3ND-c-.mjs.map +1 -0
  35. package/fesm2022/edvak99-voice-receptionist-widget-modal.component-COfi7biN.mjs +48 -0
  36. package/fesm2022/edvak99-voice-receptionist-widget-modal.component-COfi7biN.mjs.map +1 -0
  37. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-Bdh4QfFe.mjs +127 -0
  38. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-Bdh4QfFe.mjs.map +1 -0
  39. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-fHVzpiVk.mjs +268 -0
  40. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-fHVzpiVk.mjs.map +1 -0
  41. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-Bok64X2q.mjs +968 -0
  42. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-Bok64X2q.mjs.map +1 -0
  43. package/fesm2022/{edvak99-voice-receptionist-widget-tasks-page.component-DXxjMVUv.mjs → edvak99-voice-receptionist-widget-tasks-page.component-Bb9lPcYi.mjs} +56 -5
  44. package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-Bb9lPcYi.mjs.map +1 -0
  45. package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-C1Z6yC0q.mjs → edvak99-voice-receptionist-widget-wizard-page.component-BZVlWLWh.mjs} +4 -2
  46. package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-C1Z6yC0q.mjs.map → edvak99-voice-receptionist-widget-wizard-page.component-BZVlWLWh.mjs.map} +1 -1
  47. package/fesm2022/edvak99-voice-receptionist-widget.mjs +1 -1
  48. package/lib/components/call-conversation-panel/call-conversation-panel.component.d.ts +9 -6
  49. package/lib/components/call-tasks-panel/call-tasks-panel.component.d.ts +8 -8
  50. package/lib/components/knowledge-test-modal/knowledge-test-modal.component.d.ts +28 -0
  51. package/lib/components/live-transcript-panel/live-transcript-panel.component.d.ts +7 -4
  52. package/lib/components/outbound-dial-modal/outbound-dial-modal.component.d.ts +26 -0
  53. package/lib/layout/eds-module-nav.component.d.ts +0 -3
  54. package/lib/mocks/agent-activity.seed.d.ts +2 -0
  55. package/lib/models/agent-activity.types.d.ts +54 -0
  56. package/lib/models/ai-receptionist.types.d.ts +25 -0
  57. package/lib/models/api-dto.types.d.ts +18 -0
  58. package/lib/models/live-transcript.types.d.ts +2 -1
  59. package/lib/models/outbound-patient.types.d.ts +23 -0
  60. package/lib/models/outbound-purpose.types.d.ts +2 -0
  61. package/lib/models/staff-media.types.d.ts +36 -0
  62. package/lib/pages/activities-page/activities-page.component.d.ts +57 -0
  63. package/lib/pages/analytics-page/analytics-page.component.d.ts +38 -14
  64. package/lib/pages/call-history-detail-page/call-history-detail-page.component.d.ts +2 -3
  65. package/lib/pages/call-history-page/call-history-page.component.d.ts +9 -6
  66. package/lib/pages/dashboard-page/dashboard-page.component.d.ts +12 -8
  67. package/lib/pages/live-calls-page/live-calls-page.component.d.ts +14 -24
  68. package/lib/pages/live-monitor-page/live-monitor-page.component.d.ts +34 -1
  69. package/lib/pages/settings-page/settings-fields.config.d.ts +16 -0
  70. package/lib/pages/settings-page/settings-page.component.d.ts +48 -14
  71. package/lib/services/ai-receptionist-api.mock.d.ts +34 -0
  72. package/lib/services/ai-receptionist-api.service.d.ts +56 -1
  73. package/lib/services/live-transcript.service.d.ts +1 -0
  74. package/lib/services/staff-media.service.d.ts +52 -0
  75. package/lib/ui/eds-avatar.component.d.ts +5 -2
  76. package/lib/ui/eds-button.component.d.ts +1 -1
  77. package/lib/utils/call-history-display.util.d.ts +21 -0
  78. package/lib/utils/outbound-purpose.util.d.ts +19 -0
  79. package/lib/utils/transcript-timing.util.d.ts +1 -1
  80. package/lib/utils/welcome-message.util.d.ts +1 -1
  81. package/package.json +2 -1
  82. package/styles/eds.scss +95 -66
  83. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-Dsujn5az.mjs +0 -113
  84. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-Dsujn5az.mjs.map +0 -1
  85. package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-xoLlHj8K.mjs +0 -67
  86. package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-xoLlHj8K.mjs.map +0 -1
  87. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-2K9W77As.mjs +0 -316
  88. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-2K9W77As.mjs.map +0 -1
  89. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-B5AnEjoh.mjs +0 -174
  90. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-B5AnEjoh.mjs.map +0 -1
  91. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-BgsBCKgZ.mjs +0 -70
  92. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-BgsBCKgZ.mjs.map +0 -1
  93. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-BNdnbAVM.mjs +0 -248
  94. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-BNdnbAVM.mjs.map +0 -1
  95. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-CbphhP6o.mjs +0 -27
  96. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-CbphhP6o.mjs.map +0 -1
  97. package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-BgLsnq6A.mjs.map +0 -1
  98. package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-Dn0GrZ6_.mjs.map +0 -1
  99. package/fesm2022/edvak99-voice-receptionist-widget-knowledge-hub.page-BngGx_Lc.mjs +0 -609
  100. package/fesm2022/edvak99-voice-receptionist-widget-knowledge-hub.page-BngGx_Lc.mjs.map +0 -1
  101. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-list.service-0kGWO6sh.mjs.map +0 -1
  102. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-DfLmK89M.mjs +0 -115
  103. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-DfLmK89M.mjs.map +0 -1
  104. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-DNpLFqBw.mjs +0 -574
  105. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-DNpLFqBw.mjs.map +0 -1
  106. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-BQECIuJu.mjs +0 -54
  107. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-BQECIuJu.mjs.map +0 -1
  108. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-CYSZ832p.mjs +0 -265
  109. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-CYSZ832p.mjs.map +0 -1
  110. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-B9nv6wtB.mjs +0 -509
  111. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-B9nv6wtB.mjs.map +0 -1
  112. package/fesm2022/edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs +0 -52
  113. package/fesm2022/edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs.map +0 -1
  114. package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-DXxjMVUv.mjs.map +0 -1
  115. package/lib/knowledge/components/faq-empty-state/faq-empty-state.component.d.ts +0 -22
  116. package/lib/knowledge/components/faq-form/faq-form.component.d.ts +0 -27
  117. package/lib/knowledge/components/faq-search-tester/faq-search-tester.component.d.ts +0 -17
  118. package/lib/knowledge/mocks/practice-faq.seed.d.ts +0 -2
  119. package/lib/knowledge/models/practice-faq.model.d.ts +0 -50
  120. package/lib/knowledge/pages/knowledge-hub.page.d.ts +0 -54
  121. package/lib/knowledge/services/practice-faq-api.mock.d.ts +0 -16
  122. package/lib/knowledge/services/practice-faq-api.service.d.ts +0 -26
  123. package/lib/knowledge/utils/faq.util.d.ts +0 -3
  124. package/lib/layout/eds-topbar.component.d.ts +0 -29
  125. package/lib/pages/audit-page/audit-page.component.d.ts +0 -21
  126. package/lib/ui/eds-waveform.component.d.ts +0 -8
@@ -1,7 +1,7 @@
1
1
  import { OnInit } from '@angular/core';
2
2
  import { HistoryCall } from '../../models/ai-receptionist.types';
3
- import { formatOutcomeLabel, outcomeBadgeTone } from '../../utils/call-outcome.util';
4
- import { isNeedsReview, reviewBadgeTone, reviewLabel, ReviewFilterTab } from '../../utils/call-review.util';
3
+ import { callerMetaLine, historyResolution, historyResolutionLabel, historyResultChips, resultChipIcon } from '../../utils/call-history-display.util';
4
+ import { isNeedsReview, ReviewFilterTab } from '../../utils/call-review.util';
5
5
  import * as i0 from "@angular/core";
6
6
  export declare class CallHistoryPageComponent implements OnInit {
7
7
  private readonly api;
@@ -24,11 +24,12 @@ export declare class CallHistoryPageComponent implements OnInit {
24
24
  id: ReviewFilterTab;
25
25
  label: string;
26
26
  }[];
27
- protected reviewLabel: typeof reviewLabel;
28
- protected reviewTone: typeof reviewBadgeTone;
29
27
  protected isNeedsReview: typeof isNeedsReview;
30
- protected outcomeTone: typeof outcomeBadgeTone;
31
- protected outcomeLabel: typeof formatOutcomeLabel;
28
+ protected callerMetaLine: typeof callerMetaLine;
29
+ protected resultChipIcon: typeof resultChipIcon;
30
+ protected historyResultChips: typeof historyResultChips;
31
+ protected historyResolution: typeof historyResolution;
32
+ protected historyResolutionLabel: typeof historyResolutionLabel;
32
33
  ngOnInit(): void;
33
34
  protected load(): void;
34
35
  protected applyFilters(): void;
@@ -40,6 +41,8 @@ export declare class CallHistoryPageComponent implements OnInit {
40
41
  protected markReviewed(row: HistoryCall, event: Event): void;
41
42
  protected formatDuration(sec: number): string;
42
43
  protected openCallDetail(id: string): void;
44
+ protected avatarTone(row: HistoryCall): 'gray' | 'brand';
45
+ protected resolutionOf(row: HistoryCall): import("../../utils/call-history-display.util").HistoryResolution;
43
46
  protected exportCsv(): void;
44
47
  static ɵfac: i0.ɵɵFactoryDeclaration<CallHistoryPageComponent, never>;
45
48
  static ɵcmp: i0.ɵɵComponentDeclaration<CallHistoryPageComponent, "eds-call-history-page", never, {}, {}, never, never, true, never>;
@@ -1,7 +1,7 @@
1
1
  import { OnDestroy, OnInit } from '@angular/core';
2
- import { DashboardData } from '../../models/ai-receptionist.types';
3
- import { formatOutcomeLabel, outcomeBadgeTone } from '../../utils/call-outcome.util';
4
- import { isNeedsReview, reviewBadgeTone, reviewLabel } from '../../utils/call-review.util';
2
+ import { DashboardData, HistoryCall } from '../../models/ai-receptionist.types';
3
+ import { callerMetaLine, historyResolutionLabel, historyResultChips, resultChipIcon } from '../../utils/call-history-display.util';
4
+ import { isNeedsReview } from '../../utils/call-review.util';
5
5
  import * as i0 from "@angular/core";
6
6
  export declare class DashboardPageComponent implements OnInit, OnDestroy {
7
7
  private readonly api;
@@ -40,21 +40,25 @@ export declare class DashboardPageComponent implements OnInit, OnDestroy {
40
40
  icon: string;
41
41
  suffix: string;
42
42
  })[];
43
+ protected isNeedsReview: typeof isNeedsReview;
44
+ protected callerMetaLine: typeof callerMetaLine;
45
+ protected resultChipIcon: typeof resultChipIcon;
46
+ protected historyResultChips: typeof historyResultChips;
47
+ protected historyResolutionLabel: typeof historyResolutionLabel;
43
48
  ngOnInit(): void;
44
49
  ngOnDestroy(): void;
45
50
  protected statValue(key: keyof DashboardData['stats']): number;
46
51
  protected statusTone(status: string): 'brand' | 'pos' | 'notice' | 'neg' | 'violet' | 'gray';
47
52
  protected statusLabel(status: string): string;
48
- protected outcomeTone: typeof outcomeBadgeTone;
49
- protected outcomeLabel: typeof formatOutcomeLabel;
50
- protected reviewLabel: typeof reviewLabel;
51
- protected reviewTone: typeof reviewBadgeTone;
52
- protected isNeedsReview: typeof isNeedsReview;
53
+ protected historyAvatarTone(row: HistoryCall): 'gray' | 'brand';
54
+ protected resolutionOf(row: HistoryCall): import("../../utils/call-history-display.util").HistoryResolution;
55
+ protected formatDuration(sec: number): string;
53
56
  protected exportCsv(): void;
54
57
  protected openOutboundDial(): void;
55
58
  protected closeOutboundDial(): void;
56
59
  protected openHistoryDetail(id: string): void;
57
60
  protected callDetailLink(callId: string): string[];
61
+ protected appointmentDetailLink(callId: string | null | undefined): string[];
58
62
  static ɵfac: i0.ɵɵFactoryDeclaration<DashboardPageComponent, never>;
59
63
  static ɵcmp: i0.ɵɵComponentDeclaration<DashboardPageComponent, "eds-dashboard-page", never, {}, {}, never, never, true, never>;
60
64
  }
@@ -1,37 +1,27 @@
1
1
  import { OnDestroy, OnInit } from '@angular/core';
2
+ import { LiveCall, Sentiment } from '../../models/ai-receptionist.types';
2
3
  import * as i0 from "@angular/core";
3
- type LiveFilter = 'all' | 'ai' | 'needs-staff';
4
- interface LiveCallsEmptyState {
5
- title: string;
6
- detail: string;
7
- icon: string;
8
- }
9
4
  export declare class LiveCallsPageComponent implements OnInit, OnDestroy {
10
- private readonly api;
11
5
  private readonly router;
12
6
  private readonly route;
13
7
  private readonly liveCallsList;
14
- protected readonly filter: import("@angular/core").WritableSignal<LiveFilter>;
15
- protected readonly calls: import("@angular/core").WritableSignal<import("../../models/ai-receptionist.types").LiveCall[]>;
8
+ protected readonly calls: import("@angular/core").WritableSignal<LiveCall[]>;
16
9
  protected readonly loading: import("@angular/core").WritableSignal<boolean>;
17
10
  protected readonly error: import("@angular/core").WritableSignal<string | null>;
18
- protected readonly lastUpdated: import("@angular/core").WritableSignal<number | null>;
19
- protected readonly filters: {
20
- id: LiveFilter;
21
- label: string;
22
- }[];
23
- protected readonly filteredCalls: import("@angular/core").Signal<import("../../models/ai-receptionist.types").LiveCall[]>;
24
- protected readonly emptyState: import("@angular/core").Signal<LiveCallsEmptyState | null>;
25
- protected readonly waveHeights: number[];
11
+ protected readonly emptyState: import("@angular/core").Signal<{
12
+ title: string;
13
+ detail: string;
14
+ icon: string;
15
+ } | null>;
26
16
  ngOnInit(): void;
27
17
  ngOnDestroy(): void;
28
- protected setFilter(id: LiveFilter): void;
29
- protected refresh(): void;
30
- protected statusTone(status: string): 'brand' | 'pos' | 'notice' | 'neg' | 'violet' | 'gray';
31
- protected statusLabel(status: string): string;
32
- protected monitor(id: string): void;
33
- protected takeover(id: string, event: Event): void;
18
+ protected openMonitor(id: string): void;
19
+ protected displayName(call: LiveCall): string;
20
+ protected displayMeta(call: LiveCall): string;
21
+ protected isUnknown(call: LiveCall): boolean;
22
+ protected sentimentLabel(sentiment: Sentiment | string | null | undefined): string;
23
+ protected avatarInitials(call: LiveCall): string;
24
+ protected avatarTone(call: LiveCall): 'gray' | 'brand';
34
25
  static ɵfac: i0.ɵɵFactoryDeclaration<LiveCallsPageComponent, never>;
35
26
  static ɵcmp: i0.ɵɵComponentDeclaration<LiveCallsPageComponent, "eds-live-calls-page", never, {}, {}, never, never, true, never>;
36
27
  }
37
- export {};
@@ -1,11 +1,15 @@
1
1
  import { OnDestroy, OnInit } from '@angular/core';
2
2
  import { LiveCall, Sentiment } from '../../models/ai-receptionist.types';
3
+ import { StaffMediaMode } from '../../models/staff-media.types';
3
4
  import { toolEventTrackKey } from '../../utils/tool-labels.util';
4
5
  import * as i0 from "@angular/core";
5
6
  export declare class LiveMonitorPageComponent implements OnInit, OnDestroy {
6
7
  private readonly api;
7
8
  private readonly route;
8
9
  private readonly stream;
10
+ private readonly staffMedia;
11
+ private readonly socket;
12
+ private readonly toast;
9
13
  private readonly destroyRef;
10
14
  protected readonly call: import("@angular/core").WritableSignal<LiveCall | null>;
11
15
  protected readonly staffMessage: import("@angular/core").WritableSignal<string>;
@@ -13,24 +17,53 @@ export declare class LiveMonitorPageComponent implements OnInit, OnDestroy {
13
17
  protected readonly callId: import("@angular/core").WritableSignal<string>;
14
18
  protected readonly summary: import("@angular/core").WritableSignal<string | null>;
15
19
  protected readonly summaryLoading: import("@angular/core").WritableSignal<boolean>;
20
+ protected readonly mediaBusy: import("@angular/core").WritableSignal<boolean>;
16
21
  protected readonly liveTools: import("@angular/core").WritableSignal<import("../../models/ai-receptionist.types").ToolEvent[]>;
17
22
  protected readonly callEnded: import("@angular/core").WritableSignal<boolean>;
23
+ protected readonly mediaState: import("@angular/core").WritableSignal<import("../../services/staff-media.service").StaffMediaConnectionState>;
24
+ protected readonly mediaMode: import("@angular/core").WritableSignal<StaffMediaMode | null>;
25
+ protected readonly micEnabled: import("@angular/core").WritableSignal<boolean>;
26
+ protected readonly audioPlaybackAllowed: import("@angular/core").WritableSignal<boolean>;
18
27
  private summaryLoaded;
28
+ private staffJoined;
29
+ private readonly onControlChanged;
19
30
  constructor();
20
31
  ngOnInit(): void;
32
+ /**
33
+ * Leaving the page must never drop the caller. The LiveKit session is owned by the
34
+ * root StaffMediaService and keeps running until End Call or an explicit leave.
35
+ */
21
36
  ngOnDestroy(): void;
37
+ /** True when this page's call is the one the softphone is connected to. */
38
+ protected isMediaForThisCall(): boolean;
22
39
  protected isTakeover(): boolean;
40
+ /** After takeover the AI is gone for good — no resume path is offered. */
41
+ protected isHandedOff(): boolean;
23
42
  protected isPaused(): boolean;
24
43
  protected isLive(): boolean;
25
44
  protected confidenceLevel(confidence: number): 'high' | 'low' | 'mid';
26
45
  protected sentimentPercent(sentiment: Sentiment): number;
27
46
  protected toolStateClass(state: string): string;
28
47
  protected readonly toolTrackKey: typeof toolEventTrackKey;
48
+ protected isUnknownCaller(call: LiveCall): boolean;
49
+ protected displayName(call: LiveCall): string;
50
+ protected profileInitials(call: LiveCall): string;
51
+ protected profileMeta(call: LiveCall): string;
52
+ protected goalBadge(call: LiveCall): string | null;
29
53
  protected takeover(): void;
30
- protected resumeAi(): void;
54
+ protected toggleMic(): void;
31
55
  protected transfer(): void;
32
56
  protected endCall(): void;
33
57
  protected sendMessage(): void;
58
+ protected enableSound(): void;
59
+ private joinMedia;
60
+ /**
61
+ * Disconnect LiveKit first, then tell the server to drop staff and restore AI.
62
+ * Only valid in listen mode — a taken-over call stays with the human.
63
+ * Does not hang up the patient.
64
+ */
65
+ private leaveMedia;
66
+ private applyJoinMetadata;
34
67
  /** Initial load — seeds transcript/tools from REST, then starts socket. */
35
68
  private loadCallMetadata;
36
69
  /** Metadata-only refresh after staff actions — does not overwrite live transcript/tools. */
@@ -16,6 +16,20 @@ export interface SettingsSectionMeta {
16
16
  title: string;
17
17
  description: string;
18
18
  }
19
+ export declare const AGENT_TONE_OPTIONS: SettingsFieldOption[];
20
+ export declare const LANGUAGE_OPTIONS: SettingsFieldOption[];
21
+ export declare const GREETING_VARIABLES: {
22
+ key: string;
23
+ label: string;
24
+ token: string;
25
+ }[];
26
+ export declare const RETENTION_DAY_OPTIONS: SettingsFieldOption[];
27
+ export declare const RING_TIMEOUT_OPTIONS: SettingsFieldOption[];
28
+ export declare const MAX_CALL_DURATION_OPTIONS: SettingsFieldOption[];
29
+ export declare const SILENCE_TIMEOUT_OPTIONS: SettingsFieldOption[];
30
+ export declare const AI_ANSWER_MODE_OPTIONS: SettingsFieldOption[];
31
+ export declare const AFTER_HOURS_OPTIONS: SettingsFieldOption[];
32
+ export declare const DEFAULT_DISCLOSURE_WARNING = "This call may be handled by an automated assistant and could be recorded for quality and training. You can ask to speak with a staff member at any time.";
19
33
  export declare const SETTINGS_SECTION_META: Record<SettingsSection, SettingsSectionMeta>;
20
34
  /** Entire sections where every field is read-only (including unknown API fields). */
21
35
  export declare const READ_ONLY_SECTIONS: Set<SettingsSection>;
@@ -33,3 +47,5 @@ export declare const SETTINGS_FIELDS: Record<SettingsSection, SettingsFieldMeta[
33
47
  /** Fallback label for API fields not listed in config. */
34
48
  export declare function humanizeFieldKey(key: string): string;
35
49
  export declare function resolveFieldMeta(section: SettingsSection, key: string, value: string | boolean | number): SettingsFieldMeta;
50
+ export declare function parseCsvList(value: unknown): string[];
51
+ export declare function toCsvList(values: string[]): string;
@@ -1,37 +1,58 @@
1
1
  import { OnInit } from '@angular/core';
2
- import { AgentSettings } from '../../models/ai-receptionist.types';
3
- import { isFieldReadOnly, SettingsFieldMeta, SettingsSection } from './settings-fields.config';
2
+ import { AgentSettings, LocationOption } from '../../models/ai-receptionist.types';
3
+ import { isFieldReadOnly, SettingsFieldMeta } from './settings-fields.config';
4
4
  import * as i0 from "@angular/core";
5
5
  type SettingsTab = keyof AgentSettings;
6
6
  export declare class SettingsPageComponent implements OnInit {
7
7
  private readonly api;
8
8
  private readonly toast;
9
+ private readonly route;
10
+ private readonly agentOnline;
9
11
  private originalSettings;
10
12
  protected readonly isFieldReadOnly: typeof isFieldReadOnly;
11
- protected readonly readOnlySections: Set<SettingsSection>;
12
- protected readonly disabledTabs: Set<SettingsSection>;
13
+ protected readonly knowledgeMax = 8000;
14
+ protected readonly disclosureMax = 1000;
15
+ protected readonly welcomeMax = 1000;
16
+ protected readonly voicePresets: readonly import("./tts-voice-presets").TtsVoicePreset[];
17
+ protected readonly toneOptions: import("./settings-fields.config").SettingsFieldOption[];
18
+ protected readonly greetingVariables: {
19
+ key: string;
20
+ label: string;
21
+ token: string;
22
+ }[];
23
+ protected readonly retentionOptions: import("./settings-fields.config").SettingsFieldOption[];
24
+ protected readonly ringTimeoutOptions: import("./settings-fields.config").SettingsFieldOption[];
25
+ protected readonly maxCallDurationOptions: import("./settings-fields.config").SettingsFieldOption[];
26
+ protected readonly silenceTimeoutOptions: import("./settings-fields.config").SettingsFieldOption[];
27
+ protected readonly answerModeOptions: import("./settings-fields.config").SettingsFieldOption[];
28
+ protected readonly afterHoursOptions: import("./settings-fields.config").SettingsFieldOption[];
13
29
  protected readonly settings: import("@angular/core").WritableSignal<AgentSettings | null>;
14
30
  protected readonly tab: import("@angular/core").WritableSignal<keyof AgentSettings>;
15
31
  protected readonly loading: import("@angular/core").WritableSignal<boolean>;
16
32
  protected readonly saving: import("@angular/core").WritableSignal<boolean>;
17
33
  protected readonly saved: import("@angular/core").WritableSignal<boolean>;
18
- protected readonly welcomeMax = 500;
19
- protected readonly previewingVoice: import("@angular/core").WritableSignal<boolean>;
20
- private voicePreviewAudio;
34
+ protected readonly knowledgeTestOpen: import("@angular/core").WritableSignal<boolean>;
35
+ protected readonly locations: import("@angular/core").WritableSignal<LocationOption[]>;
36
+ protected readonly confirmOffOpen: import("@angular/core").WritableSignal<boolean>;
37
+ protected readonly online: import("@angular/core").Signal<import("../../services/agent-online.service").AgentOnlineKnownState>;
38
+ protected readonly agentLoading: import("@angular/core").Signal<boolean>;
39
+ protected readonly toggling: import("@angular/core").Signal<boolean>;
21
40
  protected readonly tabs: {
22
41
  id: SettingsTab;
23
42
  label: string;
24
- icon: string;
25
43
  }[];
26
44
  protected readonly sectionMeta: import("@angular/core").Signal<import("./settings-fields.config").SettingsSectionMeta>;
27
45
  protected readonly fieldsForTab: import("@angular/core").Signal<SettingsFieldMeta[]>;
28
- protected readonly generalIdentityFields: import("@angular/core").Signal<SettingsFieldMeta[]>;
29
- protected readonly generalOtherFields: import("@angular/core").Signal<SettingsFieldMeta[]>;
30
46
  protected readonly welcomeMessage: import("@angular/core").Signal<string>;
31
47
  protected readonly welcomePlaceholder: import("@angular/core").Signal<string>;
32
48
  protected readonly welcomePreview: import("@angular/core").Signal<string>;
33
- protected readonly usingDefaultWelcome: import("@angular/core").Signal<boolean>;
34
- protected readonly showRecordingConsentHint: import("@angular/core").Signal<boolean>;
49
+ protected readonly whatToSay: import("@angular/core").Signal<string>;
50
+ protected readonly whatNotToSay: import("@angular/core").Signal<string>;
51
+ protected readonly selectedLocationIds: import("@angular/core").Signal<string[]>;
52
+ protected readonly selectedTone: import("@angular/core").Signal<string>;
53
+ protected readonly disclosureEnabled: import("@angular/core").Signal<boolean>;
54
+ protected readonly disclosureText: import("@angular/core").Signal<string>;
55
+ protected readonly agentSwitchDisabled: import("@angular/core").Signal<boolean>;
35
56
  ngOnInit(): void;
36
57
  protected fieldIsReadOnly(section: SettingsTab, key: string): boolean;
37
58
  protected sectionIsReadOnly(section: SettingsTab): boolean;
@@ -39,8 +60,21 @@ export declare class SettingsPageComponent implements OnInit {
39
60
  protected setTab(id: SettingsTab): void;
40
61
  protected updateField(section: SettingsTab, key: string, value: string | boolean | number): void;
41
62
  protected updateWelcomeMessage(value: string): void;
42
- protected resetWelcomeMessage(): void;
43
- protected previewSelectedVoice(): void;
63
+ protected insertGreetingVariable(token: string): void;
64
+ protected updateKnowledgeField(key: 'whatToSay' | 'whatNotToSay', value: string): void;
65
+ protected setTone(tone: string): void;
66
+ protected toggleLocation(id: string): void;
67
+ protected selectNumberField(section: 'phone' | 'transcripts', key: string, value: string): void;
68
+ protected numberFieldAsString(section: 'phone' | 'transcripts', key: string): string;
69
+ protected setDisclosureEnabled(enabled: boolean): void;
70
+ protected updateDisclosureText(value: string): void;
71
+ protected openTestCall(): void;
72
+ protected closeTestCall(): void;
73
+ protected selectedVoiceId(): string;
74
+ protected onAgentToggleClick(): void;
75
+ protected cancelConfirmOff(): void;
76
+ protected confirmTurnOff(): void;
77
+ private applyOnline;
44
78
  protected fieldValue(section: SettingsTab, key: string): string | boolean | number;
45
79
  protected save(): void;
46
80
  private restoreReadOnlyFields;
@@ -1,8 +1,11 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import { AgentSettings, AiReceptionistStatus, AnalyticsData, AuditEvent, DashboardData, CallRecordingMeta, HistoryCall, HistoryDetail, LiveCall, LocationOption, ProviderOption, SetupData, TaskItem, CreateTaskRequest, TaskFilters, RegenerateSummaryResult, ToolEvent, TranscriptLine } from '../models/ai-receptionist.types';
3
+ import { StaffMediaJoinResult, StaffMediaMode } from '../models/staff-media.types';
3
4
  import { type PaginatedResult } from '../models/pagination';
4
5
  import { ApiLogDetail, ApiLogFilters, ApiLogListResponse, ApiLogStats } from '../models/api-log.types';
5
6
  import { CreateOutboundPurposeRequest, OutboundPurpose, OutboundPurposesResponse, PlaceOutboundCallRequest, PlaceOutboundCallResponse, UpdateOutboundPurposeRequest } from '../models/outbound-purpose.types';
7
+ import type { OutboundAppointmentHit, OutboundPatientHit } from '../models/outbound-patient.types';
8
+ import type { AgentActivity, AgentActivityFilters } from '../models/agent-activity.types';
6
9
  import * as i0 from "@angular/core";
7
10
  export declare class AiReceptionistApiMockService {
8
11
  private readonly liveCalls;
@@ -58,6 +61,14 @@ export declare class AiReceptionistApiMockService {
58
61
  success: boolean;
59
62
  };
60
63
  }>;
64
+ postMediaJoin(id: string, mode: StaffMediaMode): Observable<{
65
+ data: StaffMediaJoinResult;
66
+ }>;
67
+ postMediaLeave(id: string): Observable<{
68
+ data: {
69
+ success: boolean;
70
+ };
71
+ }>;
61
72
  postResumeAi(id: string): Observable<{
62
73
  data: {
63
74
  success: boolean;
@@ -68,6 +79,16 @@ export declare class AiReceptionistApiMockService {
68
79
  success: boolean;
69
80
  };
70
81
  }>;
82
+ postResume(id: string): Observable<{
83
+ data: {
84
+ success: boolean;
85
+ };
86
+ }>;
87
+ postListen(id: string): Observable<{
88
+ data: {
89
+ success: boolean;
90
+ };
91
+ }>;
71
92
  postTransfer(id: string): Observable<{
72
93
  data: {
73
94
  success: boolean;
@@ -108,11 +129,22 @@ export declare class AiReceptionistApiMockService {
108
129
  data: AgentSettings;
109
130
  }>;
110
131
  previewVoice(_voiceId: string): Observable<Blob>;
132
+ testKnowledgeAnswer(params: {
133
+ question: string;
134
+ whatToSay: string;
135
+ whatNotToSay: string;
136
+ voiceId?: string;
137
+ }): Observable<{
138
+ answer: string;
139
+ voiceId: string;
140
+ audioBlob: Blob;
141
+ }>;
111
142
  private withEffectiveWelcome;
112
143
  getAudit(q?: string, actor?: string, opts?: {
113
144
  page?: number;
114
145
  limit?: number;
115
146
  }): Observable<PaginatedResult<AuditEvent>>;
147
+ getActivities(filters?: AgentActivityFilters): Observable<PaginatedResult<AgentActivity>>;
116
148
  getSetup(): Observable<{
117
149
  data: SetupData;
118
150
  }>;
@@ -145,6 +177,8 @@ export declare class AiReceptionistApiMockService {
145
177
  success: boolean;
146
178
  }>;
147
179
  placeOutboundCall(body: PlaceOutboundCallRequest): Observable<PlaceOutboundCallResponse>;
180
+ searchPatientsForOutbound(q: string, limit?: number): Observable<OutboundPatientHit[]>;
181
+ listPatientAppointmentsForOutbound(patientId: string, limit?: number): Observable<OutboundAppointmentHit[]>;
148
182
  private patchLive;
149
183
  static ɵfac: i0.ɵɵFactoryDeclaration<AiReceptionistApiMockService, never>;
150
184
  static ɵprov: i0.ɵɵInjectableDeclaration<AiReceptionistApiMockService>;
@@ -1,7 +1,10 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import { ApiLogDetail, ApiLogFilters, ApiLogListResponse, ApiLogStats } from '../models/api-log.types';
3
3
  import { CreateOutboundPurposeRequest, OutboundPurpose, OutboundPurposesResponse, PlaceOutboundCallRequest, PlaceOutboundCallResponse, UpdateOutboundPurposeRequest } from '../models/outbound-purpose.types';
4
+ import { type OutboundAppointmentHit, type OutboundPatientHit } from '../models/outbound-patient.types';
5
+ import { type StaffMediaJoinResult, type StaffMediaMode } from '../models/staff-media.types';
4
6
  import { AgentSettings, AiReceptionistStatus, AnalyticsData, AuditEvent, DashboardData, HistoryCall, HistoryDetail, LiveCall, RegenerateSummaryResult, LocationOption, ProviderOption, SetupData, TaskItem, CreateTaskRequest, TaskFilters, ToolEvent, TranscriptLine, CallRecordingMeta } from '../models/ai-receptionist.types';
7
+ import { type AgentActivity, type AgentActivityFilters } from '../models/agent-activity.types';
5
8
  import { type PaginatedResult } from '../models/pagination';
6
9
  import * as i0 from "@angular/core";
7
10
  export declare class AiReceptionistApiService {
@@ -57,11 +60,26 @@ export declare class AiReceptionistApiService {
57
60
  regenerateCallSummary(callId: string): Observable<{
58
61
  data: RegenerateSummaryResult;
59
62
  }>;
60
- postTakeover(id: string): Observable<{
63
+ /**
64
+ * Staff softphone join into LiveKit room `call-{callId}`.
65
+ * POST /calls/:id/media/join { mode: listen|takeover }
66
+ */
67
+ postMediaJoin(id: string, mode: StaffMediaMode): Observable<{
68
+ data: StaffMediaJoinResult;
69
+ }>;
70
+ /** Drop staff WebRTC only; does not hang up the patient. */
71
+ postMediaLeave(id: string): Observable<{
61
72
  data: {
62
73
  success: boolean;
63
74
  };
64
75
  }>;
76
+ /**
77
+ * Take over — same join payload as media/join { mode: takeover }.
78
+ * Prefer this or postMediaJoin('takeover'); both are supported by BE.
79
+ */
80
+ postTakeover(id: string): Observable<{
81
+ data: StaffMediaJoinResult;
82
+ }>;
65
83
  postResumeAi(id: string): Observable<{
66
84
  data: {
67
85
  success: boolean;
@@ -72,6 +90,15 @@ export declare class AiReceptionistApiService {
72
90
  success: boolean;
73
91
  };
74
92
  }>;
93
+ postResume(id: string): Observable<{
94
+ data: {
95
+ success: boolean;
96
+ };
97
+ }>;
98
+ /** Listen — same join payload as media/join { mode: listen }. */
99
+ postListen(id: string): Observable<{
100
+ data: StaffMediaJoinResult;
101
+ }>;
75
102
  postTransfer(id: string): Observable<{
76
103
  data: {
77
104
  success: boolean;
@@ -113,10 +140,29 @@ export declare class AiReceptionistApiService {
113
140
  }>;
114
141
  /** ElevenLabs spoken sample for Agent Settings voice picker. */
115
142
  previewVoice(voiceId: string): Observable<Blob>;
143
+ /**
144
+ * Knowledge Base test: draft an answer from whatToSay / whatNotToSay and
145
+ * return spoken audio in the practice (or selected) voice.
146
+ */
147
+ testKnowledgeAnswer(params: {
148
+ question: string;
149
+ whatToSay: string;
150
+ whatNotToSay: string;
151
+ voiceId?: string;
152
+ }): Observable<{
153
+ answer: string;
154
+ voiceId: string;
155
+ audioBlob: Blob;
156
+ }>;
116
157
  getAudit(q?: string, opts?: {
117
158
  page?: number;
118
159
  limit?: number;
119
160
  }): Observable<PaginatedResult<AuditEvent>>;
161
+ /**
162
+ * Agent activity feed: patients created, appointments booked, tasks from AI.
163
+ * GET /api/ai-receptionist/activities
164
+ */
165
+ getActivities(filters?: AgentActivityFilters): Observable<PaginatedResult<AgentActivity>>;
120
166
  getSetup(): Observable<{
121
167
  data: SetupData;
122
168
  }>;
@@ -149,6 +195,15 @@ export declare class AiReceptionistApiService {
149
195
  success: boolean;
150
196
  }>;
151
197
  placeOutboundCall(body: PlaceOutboundCallRequest): Observable<PlaceOutboundCallResponse>;
198
+ /**
199
+ * Patient typeahead for outbound dialer.
200
+ * Tries `/api/v1/patients/search`, then `/api/v1/patients?q=`, then by-phone for digit queries.
201
+ */
202
+ searchPatientsForOutbound(q: string, limit?: number): Observable<OutboundPatientHit[]>;
203
+ /** Upcoming appointments for a patient (dialer picker). */
204
+ listPatientAppointmentsForOutbound(patientId: string, limit?: number): Observable<OutboundAppointmentHit[]>;
205
+ private mapPatientHits;
206
+ private mapAppointmentHits;
152
207
  private postCallAction;
153
208
  private apiErrorMessage;
154
209
  static ɵfac: i0.ɵɵFactoryDeclaration<AiReceptionistApiService, never>;
@@ -10,6 +10,7 @@ export declare class LiveTranscriptService {
10
10
  readonly lines: import("@angular/core").WritableSignal<TranscriptLine[]>;
11
11
  readonly patientInterim: import("@angular/core").WritableSignal<string | null>;
12
12
  readonly aiInterim: import("@angular/core").WritableSignal<string | null>;
13
+ readonly staffInterim: import("@angular/core").WritableSignal<string | null>;
13
14
  readonly tools: import("@angular/core").WritableSignal<ToolEvent[]>;
14
15
  readonly connected: import("@angular/core").WritableSignal<boolean>;
15
16
  readonly error: import("@angular/core").WritableSignal<string | null>;
@@ -0,0 +1,52 @@
1
+ import { StaffMediaJoinResult, StaffMediaMode } from '../models/staff-media.types';
2
+ import * as i0 from "@angular/core";
3
+ export type StaffMediaConnectionState = 'idle' | 'connecting' | 'connected' | 'disconnecting' | 'error';
4
+ /**
5
+ * Browser softphone for staff Listen / Take Over via LiveKit.
6
+ * Secrets stay on the server — FE only uses short-lived clientToken + livekitUrl.
7
+ *
8
+ * Root-provided on purpose: the session must survive navigating away from the
9
+ * Live Monitor page, otherwise switching dashboard tabs would drop the call.
10
+ */
11
+ export declare class StaffMediaService {
12
+ readonly connectionState: import("@angular/core").WritableSignal<StaffMediaConnectionState>;
13
+ readonly mode: import("@angular/core").WritableSignal<StaffMediaMode | null>;
14
+ readonly micEnabled: import("@angular/core").WritableSignal<boolean>;
15
+ readonly error: import("@angular/core").WritableSignal<string | null>;
16
+ readonly activeCallId: import("@angular/core").WritableSignal<string | null>;
17
+ /** False when the browser blocks autoplay — UI should offer an "enable sound" action. */
18
+ readonly audioPlaybackAllowed: import("@angular/core").WritableSignal<boolean>;
19
+ /** True once remote caller audio is actually attached and playing. */
20
+ readonly remoteAudioAttached: import("@angular/core").WritableSignal<boolean>;
21
+ private room;
22
+ private audioContainer;
23
+ private readonly attached;
24
+ get isConnected(): boolean;
25
+ /** True when a softphone session is live for this call, regardless of page. */
26
+ isConnectedTo(callId: string): boolean;
27
+ /**
28
+ * getUserMedia only exists in a secure context (https or localhost) and, inside an
29
+ * iframe, requires allow="microphone". Returns null when capture is possible.
30
+ */
31
+ microphoneBlockedReason(): string | null;
32
+ join(join: StaffMediaJoinResult): Promise<void>;
33
+ setMicrophoneEnabled(enabled: boolean): Promise<void>;
34
+ toggleMicrophone(): Promise<void>;
35
+ /** Retry blocked autoplay — must be called from a user gesture. */
36
+ startAudioPlayback(): Promise<void>;
37
+ disconnect(): Promise<void>;
38
+ private readonly onTrackSubscribed;
39
+ private readonly onTrackUnsubscribed;
40
+ private readonly onParticipantDisconnected;
41
+ /** Staff tracks are dropped server-side as soon as they appear. */
42
+ private readonly onTrackPublished;
43
+ private attachExistingRemoteTracks;
44
+ private isStaff;
45
+ private detachKey;
46
+ private ensureAudioContainer;
47
+ private enableMicrophone;
48
+ private friendlyError;
49
+ private cleanupLocal;
50
+ static ɵfac: i0.ɵɵFactoryDeclaration<StaffMediaService, never>;
51
+ static ɵprov: i0.ɵɵInjectableDeclaration<StaffMediaService>;
52
+ }
@@ -1,8 +1,11 @@
1
1
  import * as i0 from "@angular/core";
2
+ export type EdsAvatarTone = 'gray' | 'brand' | 'green' | 'amber' | 'violet' | 'rose';
3
+ export type EdsAvatarShape = 'circle' | 'box';
2
4
  export declare class EdsAvatarComponent {
3
5
  readonly initials: import("@angular/core").InputSignal<string>;
4
- readonly tone: import("@angular/core").InputSignal<"brand" | "gray">;
6
+ readonly tone: import("@angular/core").InputSignal<string>;
7
+ readonly shape: import("@angular/core").InputSignal<EdsAvatarShape>;
5
8
  readonly gradient: import("@angular/core").InputSignal<boolean>;
6
9
  static ɵfac: i0.ɵɵFactoryDeclaration<EdsAvatarComponent, never>;
7
- static ɵcmp: i0.ɵɵComponentDeclaration<EdsAvatarComponent, "eds-avatar", never, { "initials": { "alias": "initials"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "gradient": { "alias": "gradient"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
10
+ static ɵcmp: i0.ɵɵComponentDeclaration<EdsAvatarComponent, "eds-avatar", never, { "initials": { "alias": "initials"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "gradient": { "alias": "gradient"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
8
11
  }
@@ -2,7 +2,7 @@ import * as i0 from "@angular/core";
2
2
  export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'positive';
3
3
  export declare class EdsButtonComponent {
4
4
  readonly variant: import("@angular/core").InputSignal<ButtonVariant>;
5
- readonly type: import("@angular/core").InputSignal<"button" | "submit">;
5
+ readonly type: import("@angular/core").InputSignal<"submit" | "button">;
6
6
  readonly disabled: import("@angular/core").InputSignal<boolean>;
7
7
  static ɵfac: i0.ɵɵFactoryDeclaration<EdsButtonComponent, never>;
8
8
  static ɵcmp: i0.ɵɵComponentDeclaration<EdsButtonComponent, "eds-button", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
@@ -0,0 +1,21 @@
1
+ /** Call history table helpers — resolution badges + result chips. */
2
+ export type HistoryResolution = 'resolved' | 'needs_attention';
3
+ export declare function historyResolution(input: {
4
+ outcome?: string;
5
+ risk?: 'urgent' | 'review' | null;
6
+ }): HistoryResolution;
7
+ export declare function historyResolutionLabel(resolution: HistoryResolution): string;
8
+ export declare function resultChipIcon(label: string): string;
9
+ export declare function callerMetaLine(input: {
10
+ dob?: string | null;
11
+ age?: number | null;
12
+ gender?: string | null;
13
+ phone?: string | null;
14
+ name?: string | null;
15
+ matched?: boolean;
16
+ }): string;
17
+ /** Age in whole years from YYYY-MM-DD (or partial ISO). */
18
+ export declare function ageFromDob(dob: string | null | undefined, at?: Date): number | null;
19
+ export declare function isUnknownCaller(name: string | null | undefined, matched?: boolean): boolean;
20
+ /** Derive result chips from explicit actions, else from outcome text. */
21
+ export declare function historyResultChips(results: string[] | undefined, outcome: string): string[];