@edvak99/voice-receptionist-widget 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +56 -43
  2. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-CoVjr5Y3.mjs +113 -0
  3. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-CoVjr5Y3.mjs.map +1 -0
  4. package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-ou9oxnJp.mjs +35 -0
  5. package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-ou9oxnJp.mjs.map +1 -0
  6. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-BV7KOhd9.mjs +316 -0
  7. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-BV7KOhd9.mjs.map +1 -0
  8. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-CWWma-6r.mjs +138 -0
  9. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-CWWma-6r.mjs.map +1 -0
  10. package/fesm2022/edvak99-voice-receptionist-widget-call-recording-player.component-B2IuwsVH.mjs +110 -0
  11. package/fesm2022/edvak99-voice-receptionist-widget-call-recording-player.component-B2IuwsVH.mjs.map +1 -0
  12. package/fesm2022/edvak99-voice-receptionist-widget-call-review.service-D-GutOar.mjs +29 -0
  13. package/fesm2022/edvak99-voice-receptionist-widget-call-review.service-D-GutOar.mjs.map +1 -0
  14. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-DQLIw7xb.mjs +70 -0
  15. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-DQLIw7xb.mjs.map +1 -0
  16. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-B93giErR.mjs +248 -0
  17. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-B93giErR.mjs.map +1 -0
  18. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-PCnIWeOA.mjs +27 -0
  19. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-PCnIWeOA.mjs.map +1 -0
  20. package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-BrMNsxB5.mjs +136 -0
  21. package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-BrMNsxB5.mjs.map +1 -0
  22. package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-DClMfxeY.mjs +2666 -0
  23. package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-DClMfxeY.mjs.map +1 -0
  24. package/fesm2022/edvak99-voice-receptionist-widget-knowledge-hub.page-BNsM-o3z.mjs +575 -0
  25. package/fesm2022/edvak99-voice-receptionist-widget-knowledge-hub.page-BNsM-o3z.mjs.map +1 -0
  26. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-list.service-C2UZJ5wF.mjs +120 -0
  27. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-list.service-C2UZJ5wF.mjs.map +1 -0
  28. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-DQTVJjsP.mjs +115 -0
  29. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-DQTVJjsP.mjs.map +1 -0
  30. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-C3iTtVdn.mjs +574 -0
  31. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-C3iTtVdn.mjs.map +1 -0
  32. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-BQECIuJu.mjs +54 -0
  33. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-BQECIuJu.mjs.map +1 -0
  34. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-C10N-x5g.mjs +265 -0
  35. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-C10N-x5g.mjs.map +1 -0
  36. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-BBE_H2jb.mjs +509 -0
  37. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-BBE_H2jb.mjs.map +1 -0
  38. package/fesm2022/edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs +52 -0
  39. package/fesm2022/edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs.map +1 -0
  40. package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-COnYcaMT.mjs +237 -0
  41. package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-COnYcaMT.mjs.map +1 -0
  42. package/fesm2022/edvak99-voice-receptionist-widget-wizard-page.component-Box7X-Cq.mjs +45 -0
  43. package/fesm2022/edvak99-voice-receptionist-widget-wizard-page.component-Box7X-Cq.mjs.map +1 -0
  44. package/fesm2022/edvak99-voice-receptionist-widget.mjs +1 -41
  45. package/fesm2022/edvak99-voice-receptionist-widget.mjs.map +1 -1
  46. package/lib/api-paths.d.ts +11 -0
  47. package/lib/components/call-conversation-panel/call-conversation-panel.component.d.ts +45 -0
  48. package/lib/components/call-recording-player/call-recording-player.component.d.ts +29 -0
  49. package/lib/components/call-tasks-panel/call-tasks-panel.component.d.ts +19 -0
  50. package/lib/components/live-transcript-panel/live-transcript-panel.component.d.ts +36 -0
  51. package/lib/components/outbound-dial-modal/outbound-dial-modal.component.d.ts +37 -0
  52. package/lib/components/outbound-purpose-form-modal/outbound-purpose-form-modal.component.d.ts +38 -0
  53. package/lib/components/task-detail-drawer/task-detail-drawer.component.d.ts +20 -0
  54. package/lib/config.d.ts +23 -0
  55. package/lib/extract-api-rows.d.ts +2 -0
  56. package/lib/knowledge/components/faq-empty-state/faq-empty-state.component.d.ts +22 -0
  57. package/lib/knowledge/components/faq-form/faq-form.component.d.ts +27 -0
  58. package/lib/knowledge/components/faq-search-tester/faq-search-tester.component.d.ts +17 -0
  59. package/lib/knowledge/mocks/practice-faq.seed.d.ts +2 -0
  60. package/lib/knowledge/models/practice-faq.model.d.ts +47 -0
  61. package/lib/knowledge/pages/knowledge-hub.page.d.ts +47 -0
  62. package/lib/knowledge/services/practice-faq-api.mock.d.ts +16 -0
  63. package/lib/knowledge/services/practice-faq-api.service.d.ts +22 -0
  64. package/lib/knowledge/utils/faq.util.d.ts +3 -0
  65. package/lib/layout/eds-app-rail.component.d.ts +6 -0
  66. package/lib/layout/eds-app-shell.component.d.ts +5 -0
  67. package/lib/layout/eds-module-nav.component.d.ts +24 -0
  68. package/lib/layout/eds-topbar.component.d.ts +29 -0
  69. package/lib/mocks/api-log.seed.d.ts +5 -0
  70. package/lib/mocks/outbound-purpose.seed.d.ts +3 -0
  71. package/lib/mocks/seed-data.d.ts +38 -0
  72. package/lib/models/ai-receptionist.types.d.ts +257 -0
  73. package/lib/models/api-dto.types.d.ts +215 -0
  74. package/lib/models/api-log.types.d.ts +53 -0
  75. package/lib/models/live-transcript.types.d.ts +26 -0
  76. package/lib/models/outbound-purpose.types.d.ts +50 -0
  77. package/lib/pages/analytics-page/analytics-page.component.d.ts +44 -0
  78. package/lib/pages/audit-page/audit-page.component.d.ts +14 -0
  79. package/lib/pages/call-history-detail-page/call-history-detail-page.component.d.ts +25 -0
  80. package/lib/pages/call-history-page/call-history-page.component.d.ts +42 -0
  81. package/lib/pages/dashboard-page/dashboard-page.component.d.ts +60 -0
  82. package/lib/pages/live-calls-page/live-calls-page.component.d.ts +37 -0
  83. package/lib/pages/live-monitor-page/live-monitor-page.component.d.ts +43 -0
  84. package/lib/pages/outbound-purposes-page/outbound-purposes-page.component.d.ts +24 -0
  85. package/lib/pages/settings-page/settings-fields.config.d.ts +35 -0
  86. package/lib/pages/settings-page/settings-page.component.d.ts +50 -0
  87. package/lib/pages/settings-page/tts-voice-presets.d.ts +7 -0
  88. package/lib/pages/tasks-page/tasks-page.component.d.ts +35 -0
  89. package/lib/pages/wizard-page/wizard-page.component.d.ts +17 -0
  90. package/lib/pipes/eds-elapsed.pipe.d.ts +7 -0
  91. package/lib/provide-voice-receptionist.d.ts +6 -0
  92. package/lib/routes.d.ts +8 -0
  93. package/lib/services/agent-online.service.d.ts +29 -0
  94. package/lib/services/ai-receptionist-api.mappers.d.ts +45 -0
  95. package/lib/services/ai-receptionist-api.mock.d.ts +150 -0
  96. package/lib/services/ai-receptionist-api.service.d.ts +156 -0
  97. package/lib/services/call-review.service.d.ts +12 -0
  98. package/lib/services/dashboard-socket.service.d.ts +26 -0
  99. package/lib/services/live-calls-list.service.d.ts +29 -0
  100. package/lib/services/live-transcript.service.d.ts +39 -0
  101. package/lib/shared/copy-button.component.d.ts +14 -0
  102. package/lib/shared/modal.component.d.ts +20 -0
  103. package/lib/shared/toast-container.component.d.ts +7 -0
  104. package/lib/shared/toast.service.d.ts +16 -0
  105. package/lib/ui/eds-avatar.component.d.ts +8 -0
  106. package/lib/ui/eds-badge.component.d.ts +7 -0
  107. package/lib/ui/eds-button.component.d.ts +9 -0
  108. package/lib/ui/eds-icon.component.d.ts +10 -0
  109. package/lib/ui/eds-pulse-dot.component.d.ts +5 -0
  110. package/lib/ui/eds-waveform.component.d.ts +8 -0
  111. package/lib/utils/call-outcome.util.d.ts +8 -0
  112. package/lib/utils/call-review.util.d.ts +8 -0
  113. package/lib/utils/outbound-purpose.util.d.ts +14 -0
  114. package/lib/utils/task.util.d.ts +10 -0
  115. package/lib/utils/tool-labels.util.d.ts +14 -0
  116. package/lib/utils/transcript-timing.util.d.ts +17 -0
  117. package/lib/utils/welcome-message.util.d.ts +5 -0
  118. package/package.json +12 -5
  119. package/public-api.d.ts +6 -2
  120. package/styles/_index.scss +55 -0
  121. package/styles/chat-ui.scss +133 -0
  122. package/styles/eds.scss +328 -0
  123. package/lib/voice-receptionist-widget.component.d.ts +0 -5
  124. package/lib/voice-receptionist-widget.service.d.ts +0 -6
@@ -0,0 +1,45 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, computed, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { A as AiReceptionistApiService, a as EdsBadgeComponent, E as EdsButtonComponent, b as EdsIconComponent } from './edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-DClMfxeY.mjs';
4
+
5
+ class WizardPageComponent {
6
+ constructor() {
7
+ this.api = inject(AiReceptionistApiService);
8
+ this.setup = signal(null);
9
+ this.activeStep = signal(1);
10
+ this.loading = signal(true);
11
+ this.activated = signal(false);
12
+ this.completedCount = computed(() => {
13
+ return this.setup()?.steps.filter((s) => s.complete).length ?? 0;
14
+ });
15
+ }
16
+ ngOnInit() {
17
+ this.api.getSetup().subscribe(({ data }) => {
18
+ this.setup.set(data);
19
+ const firstIncomplete = data.steps.find((s) => !s.complete);
20
+ this.activeStep.set(firstIncomplete?.id ?? 1);
21
+ this.loading.set(false);
22
+ });
23
+ }
24
+ selectStep(step) {
25
+ this.activeStep.set(step.id);
26
+ }
27
+ progressPercent() {
28
+ return this.setup()?.readiness ?? 0;
29
+ }
30
+ activate() {
31
+ this.api.activateSetup().subscribe(() => {
32
+ this.api.setAgentOn(true);
33
+ this.activated.set(true);
34
+ });
35
+ }
36
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: WizardPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
37
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: WizardPageComponent, isStandalone: true, selector: "eds-wizard-page", ngImport: i0, template: "<div class=\"eds-page wizard-page\">\n <header class=\"wizard-page__header\">\n <div>\n <h1 class=\"eds-h1\">Setup wizard</h1>\n <p class=\"eds-body-sm\">Configure and activate your AI receptionist</p>\n </div>\n <div class=\"wizard-page__progress-wrap\">\n <span class=\"eds-label\">Readiness</span>\n <div class=\"wizard-page__progress\">\n <span class=\"wizard-page__progress-fill\" [style.width.%]=\"progressPercent()\"></span>\n </div>\n <span class=\"eds-body-sm-bold\">{{ progressPercent() }}%</span>\n </div>\n </header>\n\n @if (loading()) {\n <p class=\"eds-body-sm\">Loading setup\u2026</p>\n } @else if (setup()) {\n <div class=\"wizard-page__layout\">\n <nav class=\"eds-card wizard-page__steps\">\n @for (step of setup()!.steps; track step.id) {\n <button\n type=\"button\"\n class=\"wizard-page__step\"\n [class.wizard-page__step--active]=\"activeStep() === step.id\"\n [class.wizard-page__step--done]=\"step.complete\"\n (click)=\"selectStep(step)\"\n >\n <span class=\"wizard-page__step-num\">\n @if (step.complete) {\n <eds-icon name=\"check\" [size]=\"16\" />\n } @else {\n {{ step.id }}\n }\n </span>\n <div>\n <span class=\"eds-body-sm-bold\">{{ step.title }}</span>\n <span class=\"eds-body-sm\">{{ step.description }}</span>\n </div>\n </button>\n }\n </nav>\n\n <article class=\"eds-card wizard-page__content\">\n @for (step of setup()!.steps; track step.id) {\n @if (activeStep() === step.id) {\n <header class=\"wizard-page__content-head\">\n <h2 class=\"eds-h2\">Step {{ step.id }}: {{ step.title }}</h2>\n <eds-badge [tone]=\"step.complete ? 'pos' : 'notice'\">\n {{ step.complete ? 'Complete' : 'Incomplete' }}\n </eds-badge>\n </header>\n <p class=\"eds-body\">{{ step.description }}</p>\n }\n }\n\n <section class=\"wizard-page__test\">\n <h3 class=\"eds-h3\">Test transcript preview</h3>\n <div class=\"wizard-page__transcript\">\n @for (line of setup()!.testTranscript; track $index) {\n <div class=\"wizard-page__line\" [attr.data-who]=\"line.who\">\n <span class=\"eds-label\">{{ line.who }}</span>\n <p>{{ line.text }}</p>\n </div>\n }\n </div>\n </section>\n\n <footer class=\"wizard-page__footer\">\n <p class=\"eds-body-sm\">\n {{ completedCount() }} of {{ setup()!.steps.length }} steps complete\n </p>\n @if (activated()) {\n <eds-badge tone=\"pos\">Agent activated</eds-badge>\n } @else {\n <eds-button variant=\"primary\" (click)=\"activate()\">\n <eds-icon name=\"rocket_launch\" [size]=\"18\" /> Activate AI receptionist\n </eds-button>\n }\n </footer>\n </article>\n </div>\n }\n</div>\n", styles: [".wizard-page__header{display:flex;align-items:flex-start;justify-content:space-between;gap:20px;margin-bottom:20px}.wizard-page__progress-wrap{display:flex;flex-direction:column;align-items:flex-end;gap:6px;min-width:200px}.wizard-page__progress{width:200px;height:8px;background:var(--surface-l2);border-radius:4px;overflow:hidden}.wizard-page__progress-fill{display:block;height:100%;background:linear-gradient(90deg,var(--brand-500),var(--violet-500));border-radius:4px;transition:width .3s ease}.wizard-page__layout{display:grid;grid-template-columns:300px 1fr;gap:16px;align-items:start}.wizard-page__steps{padding:8px;display:flex;flex-direction:column;gap:4px;max-height:600px;overflow-y:auto}.wizard-page__step{display:flex;gap:10px;align-items:flex-start;padding:10px;border:none;background:none;border-radius:var(--eds-radius-md);text-align:left;cursor:pointer;width:100%}.wizard-page__step:hover{background:var(--surface-l1)}.wizard-page__step--active{background:#3681f41a;outline:1px solid rgba(54,129,244,.25)}.wizard-page__step--done .wizard-page__step-num{background:var(--green-500);color:#fff}.wizard-page__step div{display:flex;flex-direction:column;gap:2px}.wizard-page__step-num{width:28px;height:28px;border-radius:50%;background:var(--surface-l2);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;flex-shrink:0}.wizard-page__content{padding:20px}.wizard-page__content-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px}.wizard-page__test{margin-top:24px;padding-top:20px;border-top:1px solid var(--border-default)}.wizard-page__transcript{display:flex;flex-direction:column;gap:10px;margin-top:12px}.wizard-page__line{padding:10px 12px;border-radius:var(--eds-radius-md);background:var(--surface-l1)}.wizard-page__line[data-who=ai]{border-left:3px solid var(--brand-500)}.wizard-page__line p{margin:4px 0 0;font-size:14px}.wizard-page__footer{display:flex;align-items:center;justify-content:space-between;margin-top:24px;padding-top:16px;border-top:1px solid var(--border-default)}@media(max-width:900px){.wizard-page__layout{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "component", type: EdsBadgeComponent, selector: "eds-badge", inputs: ["tone"] }, { kind: "component", type: EdsButtonComponent, selector: "eds-button", inputs: ["variant", "type", "disabled"] }, { kind: "component", type: EdsIconComponent, selector: "eds-icon", inputs: ["name", "size", "fill", "weight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
38
+ }
39
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: WizardPageComponent, decorators: [{
40
+ type: Component,
41
+ args: [{ selector: 'eds-wizard-page', imports: [EdsBadgeComponent, EdsButtonComponent, EdsIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"eds-page wizard-page\">\n <header class=\"wizard-page__header\">\n <div>\n <h1 class=\"eds-h1\">Setup wizard</h1>\n <p class=\"eds-body-sm\">Configure and activate your AI receptionist</p>\n </div>\n <div class=\"wizard-page__progress-wrap\">\n <span class=\"eds-label\">Readiness</span>\n <div class=\"wizard-page__progress\">\n <span class=\"wizard-page__progress-fill\" [style.width.%]=\"progressPercent()\"></span>\n </div>\n <span class=\"eds-body-sm-bold\">{{ progressPercent() }}%</span>\n </div>\n </header>\n\n @if (loading()) {\n <p class=\"eds-body-sm\">Loading setup\u2026</p>\n } @else if (setup()) {\n <div class=\"wizard-page__layout\">\n <nav class=\"eds-card wizard-page__steps\">\n @for (step of setup()!.steps; track step.id) {\n <button\n type=\"button\"\n class=\"wizard-page__step\"\n [class.wizard-page__step--active]=\"activeStep() === step.id\"\n [class.wizard-page__step--done]=\"step.complete\"\n (click)=\"selectStep(step)\"\n >\n <span class=\"wizard-page__step-num\">\n @if (step.complete) {\n <eds-icon name=\"check\" [size]=\"16\" />\n } @else {\n {{ step.id }}\n }\n </span>\n <div>\n <span class=\"eds-body-sm-bold\">{{ step.title }}</span>\n <span class=\"eds-body-sm\">{{ step.description }}</span>\n </div>\n </button>\n }\n </nav>\n\n <article class=\"eds-card wizard-page__content\">\n @for (step of setup()!.steps; track step.id) {\n @if (activeStep() === step.id) {\n <header class=\"wizard-page__content-head\">\n <h2 class=\"eds-h2\">Step {{ step.id }}: {{ step.title }}</h2>\n <eds-badge [tone]=\"step.complete ? 'pos' : 'notice'\">\n {{ step.complete ? 'Complete' : 'Incomplete' }}\n </eds-badge>\n </header>\n <p class=\"eds-body\">{{ step.description }}</p>\n }\n }\n\n <section class=\"wizard-page__test\">\n <h3 class=\"eds-h3\">Test transcript preview</h3>\n <div class=\"wizard-page__transcript\">\n @for (line of setup()!.testTranscript; track $index) {\n <div class=\"wizard-page__line\" [attr.data-who]=\"line.who\">\n <span class=\"eds-label\">{{ line.who }}</span>\n <p>{{ line.text }}</p>\n </div>\n }\n </div>\n </section>\n\n <footer class=\"wizard-page__footer\">\n <p class=\"eds-body-sm\">\n {{ completedCount() }} of {{ setup()!.steps.length }} steps complete\n </p>\n @if (activated()) {\n <eds-badge tone=\"pos\">Agent activated</eds-badge>\n } @else {\n <eds-button variant=\"primary\" (click)=\"activate()\">\n <eds-icon name=\"rocket_launch\" [size]=\"18\" /> Activate AI receptionist\n </eds-button>\n }\n </footer>\n </article>\n </div>\n }\n</div>\n", styles: [".wizard-page__header{display:flex;align-items:flex-start;justify-content:space-between;gap:20px;margin-bottom:20px}.wizard-page__progress-wrap{display:flex;flex-direction:column;align-items:flex-end;gap:6px;min-width:200px}.wizard-page__progress{width:200px;height:8px;background:var(--surface-l2);border-radius:4px;overflow:hidden}.wizard-page__progress-fill{display:block;height:100%;background:linear-gradient(90deg,var(--brand-500),var(--violet-500));border-radius:4px;transition:width .3s ease}.wizard-page__layout{display:grid;grid-template-columns:300px 1fr;gap:16px;align-items:start}.wizard-page__steps{padding:8px;display:flex;flex-direction:column;gap:4px;max-height:600px;overflow-y:auto}.wizard-page__step{display:flex;gap:10px;align-items:flex-start;padding:10px;border:none;background:none;border-radius:var(--eds-radius-md);text-align:left;cursor:pointer;width:100%}.wizard-page__step:hover{background:var(--surface-l1)}.wizard-page__step--active{background:#3681f41a;outline:1px solid rgba(54,129,244,.25)}.wizard-page__step--done .wizard-page__step-num{background:var(--green-500);color:#fff}.wizard-page__step div{display:flex;flex-direction:column;gap:2px}.wizard-page__step-num{width:28px;height:28px;border-radius:50%;background:var(--surface-l2);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;flex-shrink:0}.wizard-page__content{padding:20px}.wizard-page__content-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px}.wizard-page__test{margin-top:24px;padding-top:20px;border-top:1px solid var(--border-default)}.wizard-page__transcript{display:flex;flex-direction:column;gap:10px;margin-top:12px}.wizard-page__line{padding:10px 12px;border-radius:var(--eds-radius-md);background:var(--surface-l1)}.wizard-page__line[data-who=ai]{border-left:3px solid var(--brand-500)}.wizard-page__line p{margin:4px 0 0;font-size:14px}.wizard-page__footer{display:flex;align-items:center;justify-content:space-between;margin-top:24px;padding-top:16px;border-top:1px solid var(--border-default)}@media(max-width:900px){.wizard-page__layout{grid-template-columns:1fr}}\n"] }]
42
+ }] });
43
+
44
+ export { WizardPageComponent };
45
+ //# sourceMappingURL=edvak99-voice-receptionist-widget-wizard-page.component-Box7X-Cq.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edvak99-voice-receptionist-widget-wizard-page.component-Box7X-Cq.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/pages/wizard-page/wizard-page.component.ts","../../../projects/voice-receptionist-widget/src/lib/pages/wizard-page/wizard-page.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, inject, OnInit, signal } from '@angular/core';\n\nimport { SetupData, SetupStep } from '../../models/ai-receptionist.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { EdsBadgeComponent } from '../../ui/eds-badge.component';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\n\n@Component({\n selector: 'eds-wizard-page',\n imports: [EdsBadgeComponent, EdsButtonComponent, EdsIconComponent],\n templateUrl: './wizard-page.component.html',\n styleUrl: './wizard-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class WizardPageComponent implements OnInit {\n private readonly api = inject(AiReceptionistApiService);\n\n protected readonly setup = signal<SetupData | null>(null);\n protected readonly activeStep = signal(1);\n protected readonly loading = signal(true);\n protected readonly activated = signal(false);\n\n protected readonly completedCount = computed(() => {\n return this.setup()?.steps.filter((s) => s.complete).length ?? 0;\n });\n\n ngOnInit(): void {\n this.api.getSetup().subscribe(({ data }) => {\n this.setup.set(data);\n const firstIncomplete = data.steps.find((s) => !s.complete);\n this.activeStep.set(firstIncomplete?.id ?? 1);\n this.loading.set(false);\n });\n }\n\n protected selectStep(step: SetupStep): void {\n this.activeStep.set(step.id);\n }\n\n protected progressPercent(): number {\n return this.setup()?.readiness ?? 0;\n }\n\n protected activate(): void {\n this.api.activateSetup().subscribe(() => {\n this.api.setAgentOn(true);\n this.activated.set(true);\n });\n }\n}\n","<div class=\"eds-page wizard-page\">\n <header class=\"wizard-page__header\">\n <div>\n <h1 class=\"eds-h1\">Setup wizard</h1>\n <p class=\"eds-body-sm\">Configure and activate your AI receptionist</p>\n </div>\n <div class=\"wizard-page__progress-wrap\">\n <span class=\"eds-label\">Readiness</span>\n <div class=\"wizard-page__progress\">\n <span class=\"wizard-page__progress-fill\" [style.width.%]=\"progressPercent()\"></span>\n </div>\n <span class=\"eds-body-sm-bold\">{{ progressPercent() }}%</span>\n </div>\n </header>\n\n @if (loading()) {\n <p class=\"eds-body-sm\">Loading setup…</p>\n } @else if (setup()) {\n <div class=\"wizard-page__layout\">\n <nav class=\"eds-card wizard-page__steps\">\n @for (step of setup()!.steps; track step.id) {\n <button\n type=\"button\"\n class=\"wizard-page__step\"\n [class.wizard-page__step--active]=\"activeStep() === step.id\"\n [class.wizard-page__step--done]=\"step.complete\"\n (click)=\"selectStep(step)\"\n >\n <span class=\"wizard-page__step-num\">\n @if (step.complete) {\n <eds-icon name=\"check\" [size]=\"16\" />\n } @else {\n {{ step.id }}\n }\n </span>\n <div>\n <span class=\"eds-body-sm-bold\">{{ step.title }}</span>\n <span class=\"eds-body-sm\">{{ step.description }}</span>\n </div>\n </button>\n }\n </nav>\n\n <article class=\"eds-card wizard-page__content\">\n @for (step of setup()!.steps; track step.id) {\n @if (activeStep() === step.id) {\n <header class=\"wizard-page__content-head\">\n <h2 class=\"eds-h2\">Step {{ step.id }}: {{ step.title }}</h2>\n <eds-badge [tone]=\"step.complete ? 'pos' : 'notice'\">\n {{ step.complete ? 'Complete' : 'Incomplete' }}\n </eds-badge>\n </header>\n <p class=\"eds-body\">{{ step.description }}</p>\n }\n }\n\n <section class=\"wizard-page__test\">\n <h3 class=\"eds-h3\">Test transcript preview</h3>\n <div class=\"wizard-page__transcript\">\n @for (line of setup()!.testTranscript; track $index) {\n <div class=\"wizard-page__line\" [attr.data-who]=\"line.who\">\n <span class=\"eds-label\">{{ line.who }}</span>\n <p>{{ line.text }}</p>\n </div>\n }\n </div>\n </section>\n\n <footer class=\"wizard-page__footer\">\n <p class=\"eds-body-sm\">\n {{ completedCount() }} of {{ setup()!.steps.length }} steps complete\n </p>\n @if (activated()) {\n <eds-badge tone=\"pos\">Agent activated</eds-badge>\n } @else {\n <eds-button variant=\"primary\" (click)=\"activate()\">\n <eds-icon name=\"rocket_launch\" [size]=\"18\" /> Activate AI receptionist\n </eds-button>\n }\n </footer>\n </article>\n </div>\n }\n</div>\n"],"names":[],"mappings":";;;;MAea,mBAAmB,CAAA;AAPhC,IAAA,WAAA,GAAA;AAQmB,QAAA,IAAA,CAAA,GAAG,GAAG,MAAM,CAAC,wBAAwB,CAAC;AAEpC,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAmB,IAAI,CAAC;AACtC,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC;AACtB,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC;AACtB,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC;AAEzB,QAAA,IAAA,CAAA,cAAc,GAAG,QAAQ,CAAC,MAAK;YAChD,OAAO,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,IAAI,CAAC;AAClE,QAAA,CAAC,CAAC;AAyBH,IAAA;IAvBC,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,KAAI;AACzC,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;AACpB,YAAA,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;YAC3D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,eAAe,EAAE,EAAE,IAAI,CAAC,CAAC;AAC7C,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;AACzB,QAAA,CAAC,CAAC;IACJ;AAEU,IAAA,UAAU,CAAC,IAAe,EAAA;QAClC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;IAC9B;IAEU,eAAe,GAAA;QACvB,OAAO,IAAI,CAAC,KAAK,EAAE,EAAE,SAAS,IAAI,CAAC;IACrC;IAEU,QAAQ,GAAA;QAChB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,SAAS,CAAC,MAAK;AACtC,YAAA,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;AACzB,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AAC1B,QAAA,CAAC,CAAC;IACJ;+GAlCW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAnB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,mBAAmB,2ECfhC,uoGAoFA,EAAA,MAAA,EAAA,CAAA,+mEAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,ED1Ec,iBAAiB,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,kBAAkB,gGAAE,gBAAgB,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAKxD,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAP/B,SAAS;+BACI,iBAAiB,EAAA,OAAA,EAClB,CAAC,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,CAAC,EAAA,eAAA,EAGjD,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,uoGAAA,EAAA,MAAA,EAAA,CAAA,+mEAAA,CAAA,EAAA;;;;;"}
@@ -1,42 +1,2 @@
1
- import * as i0 from '@angular/core';
2
- import { Injectable, Component } from '@angular/core';
3
-
4
- class VoiceReceptionistWidgetService {
5
- constructor() { }
6
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: VoiceReceptionistWidgetService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
7
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: VoiceReceptionistWidgetService, providedIn: 'root' }); }
8
- }
9
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: VoiceReceptionistWidgetService, decorators: [{
10
- type: Injectable,
11
- args: [{
12
- providedIn: 'root'
13
- }]
14
- }], ctorParameters: () => [] });
15
-
16
- class VoiceReceptionistWidgetComponent {
17
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: VoiceReceptionistWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
18
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: VoiceReceptionistWidgetComponent, isStandalone: true, selector: "lib-voice-receptionist-widget", ngImport: i0, template: `
19
- <p>
20
- voice-receptionist-widget works!
21
- </p>
22
- `, isInline: true, styles: [""] }); }
23
- }
24
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: VoiceReceptionistWidgetComponent, decorators: [{
25
- type: Component,
26
- args: [{ selector: 'lib-voice-receptionist-widget', imports: [], template: `
27
- <p>
28
- voice-receptionist-widget works!
29
- </p>
30
- ` }]
31
- }] });
32
-
33
- /*
34
- * Public API Surface of voice-receptionist-widget
35
- */
36
-
37
- /**
38
- * Generated bundle index. Do not edit.
39
- */
40
-
41
- export { VoiceReceptionistWidgetComponent, VoiceReceptionistWidgetService };
1
+ export { h as EdsAppShellComponent, a as EdsBadgeComponent, T as ToastService, V as VOICE_RECEPTIONIST_CONFIG, i as VOICE_RECEPTIONIST_FEATURE_ROUTES, j as VOICE_RECEPTIONIST_ROUTES, k as VOICE_RECEPTIONIST_SESSION, p as provideVoiceReceptionist } from './edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-DClMfxeY.mjs';
42
2
  //# sourceMappingURL=edvak99-voice-receptionist-widget.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"edvak99-voice-receptionist-widget.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/voice-receptionist-widget.service.ts","../../../projects/voice-receptionist-widget/src/lib/voice-receptionist-widget.component.ts","../../../projects/voice-receptionist-widget/src/public-api.ts","../../../projects/voice-receptionist-widget/src/edvak99-voice-receptionist-widget.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class VoiceReceptionistWidgetService {\n\n constructor() { }\n}\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'lib-voice-receptionist-widget',\n imports: [],\n template: `\n <p>\n voice-receptionist-widget works!\n </p>\n `,\n styles: ``\n})\nexport class VoiceReceptionistWidgetComponent {\n\n}\n","/*\n * Public API Surface of voice-receptionist-widget\n */\n\nexport * from './lib/voice-receptionist-widget.service';\nexport * from './lib/voice-receptionist-widget.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;MAKa,8BAA8B,CAAA;AAEzC,IAAA,WAAA,GAAA,EAAgB;+GAFL,8BAA8B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAA9B,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,8BAA8B,cAF7B,MAAM,EAAA,CAAA,CAAA;;4FAEP,8BAA8B,EAAA,UAAA,EAAA,CAAA;kBAH1C,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE;AACb,iBAAA;;;MCQY,gCAAgC,CAAA;+GAAhC,gCAAgC,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAhC,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,gCAAgC,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,+BAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAPjC;;;;AAIT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA;;4FAGU,gCAAgC,EAAA,UAAA,EAAA,CAAA;kBAV5C,SAAS;+BACE,+BAA+B,EAAA,OAAA,EAChC,EAAE,EAAA,QAAA,EACD;;;;AAIT,EAAA,CAAA,EAAA;;;ACTH;;AAEG;;ACFH;;AAEG;;;;"}
1
+ {"version":3,"file":"edvak99-voice-receptionist-widget.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import { VoiceReceptionistConfig } from './config';
2
+ export interface VoiceReceptionistPaths {
3
+ apiRoot(): string;
4
+ authPath(suffix?: string): string;
5
+ v1Path(suffix?: string): string;
6
+ apiPath(suffix?: string): string;
7
+ aiReceptionistPath(suffix?: string): string;
8
+ healthPath(suffix?: string): string;
9
+ }
10
+ /** Build URL helpers from a config (or raw base URL). Safe outside injection context. */
11
+ export declare function createVoiceReceptionistPaths(configOrBase: VoiceReceptionistConfig | string): VoiceReceptionistPaths;
@@ -0,0 +1,45 @@
1
+ import { ToolEvent, TranscriptLine } from '../../models/ai-receptionist.types';
2
+ import { formatPlaybackTime, TimedTranscriptLine, toolStateClass, transcriptRoleLabel } from '../../utils/transcript-timing.util';
3
+ import { toolEventTrackKey } from '../../utils/tool-labels.util';
4
+ import * as i0 from "@angular/core";
5
+ export declare class CallConversationPanelComponent {
6
+ private readonly api;
7
+ private readonly toast;
8
+ readonly callId: import("@angular/core").InputSignal<string>;
9
+ readonly summary: import("@angular/core").InputSignal<string>;
10
+ readonly transcript: import("@angular/core").InputSignal<TranscriptLine[]>;
11
+ readonly tools: import("@angular/core").InputSignal<ToolEvent[]>;
12
+ readonly callDurationSec: import("@angular/core").InputSignal<number>;
13
+ readonly allowRegenerate: import("@angular/core").InputSignal<boolean>;
14
+ readonly summaryRegenerated: import("@angular/core").OutputEmitterRef<void>;
15
+ private readonly player;
16
+ private readonly scrollHost;
17
+ protected readonly currentTime: import("@angular/core").WritableSignal<number>;
18
+ protected readonly playbackDuration: import("@angular/core").WritableSignal<number>;
19
+ protected readonly summaryExpanded: import("@angular/core").WritableSignal<boolean>;
20
+ private readonly regeneratedSummary;
21
+ protected readonly displaySummary: import("@angular/core").Signal<string>;
22
+ protected readonly regenerating: import("@angular/core").WritableSignal<boolean>;
23
+ protected readonly summaryMeta: import("@angular/core").WritableSignal<{
24
+ model?: string;
25
+ generatedAt?: string;
26
+ turnCount?: number;
27
+ } | null>;
28
+ protected readonly timedLines: import("@angular/core").Signal<TimedTranscriptLine[]>;
29
+ protected readonly activeIndex: import("@angular/core").Signal<number>;
30
+ protected readonly hasExplicitTiming: import("@angular/core").Signal<boolean>;
31
+ protected readonly roleLabel: typeof transcriptRoleLabel;
32
+ protected readonly toolClass: typeof toolStateClass;
33
+ protected readonly formatTime: typeof formatPlaybackTime;
34
+ protected readonly toolTrackKey: typeof toolEventTrackKey;
35
+ constructor();
36
+ protected onPlaybackTime(sec: number): void;
37
+ protected onPlaybackDuration(sec: number): void;
38
+ protected seekLine(line: TimedTranscriptLine): void;
39
+ protected toggleSummary(): void;
40
+ protected regenerateSummary(): void;
41
+ protected lineClass(line: TimedTranscriptLine): Record<string, boolean>;
42
+ protected toolTone(state: ToolEvent['state']): 'pos' | 'notice' | 'neg' | 'brand' | 'gray';
43
+ static ɵfac: i0.ɵɵFactoryDeclaration<CallConversationPanelComponent, never>;
44
+ static ɵcmp: i0.ɵɵComponentDeclaration<CallConversationPanelComponent, "eds-call-conversation-panel", never, { "callId": { "alias": "callId"; "required": true; "isSignal": true; }; "summary": { "alias": "summary"; "required": true; "isSignal": true; }; "transcript": { "alias": "transcript"; "required": true; "isSignal": true; }; "tools": { "alias": "tools"; "required": true; "isSignal": true; }; "callDurationSec": { "alias": "callDurationSec"; "required": false; "isSignal": true; }; "allowRegenerate": { "alias": "allowRegenerate"; "required": false; "isSignal": true; }; }, { "summaryRegenerated": "summaryRegenerated"; }, never, ["[summary-side]"], true, never>;
45
+ }
@@ -0,0 +1,29 @@
1
+ import { CallRecordingStatus } from '../../models/ai-receptionist.types';
2
+ import * as i0 from "@angular/core";
3
+ type PlayerPhase = 'loading' | CallRecordingStatus | 'error';
4
+ export declare class CallRecordingPlayerComponent {
5
+ readonly callId: import("@angular/core").InputSignal<string>;
6
+ readonly currentTimeChange: import("@angular/core").OutputEmitterRef<number>;
7
+ readonly durationChange: import("@angular/core").OutputEmitterRef<number>;
8
+ private readonly audioRef;
9
+ private readonly api;
10
+ private readonly destroyRef;
11
+ protected readonly phase: import("@angular/core").WritableSignal<PlayerPhase>;
12
+ protected readonly blobUrl: import("@angular/core").WritableSignal<string | null>;
13
+ protected readonly durationSeconds: import("@angular/core").WritableSignal<number | null>;
14
+ protected readonly message: import("@angular/core").WritableSignal<string | null>;
15
+ /** Tracked outside signals so cleanup never reads blobUrl (avoids effect/subscription loops). */
16
+ private objectUrl;
17
+ constructor();
18
+ protected formatDuration(seconds: number): string;
19
+ protected onAudioError(): void;
20
+ protected onTimeUpdate(event: Event): void;
21
+ protected onLoadedMetadata(event: Event): void;
22
+ /** Seek playback — used by synced transcript lines. */
23
+ seekTo(seconds: number): void;
24
+ private revokeObjectUrl;
25
+ private resetUi;
26
+ static ɵfac: i0.ɵɵFactoryDeclaration<CallRecordingPlayerComponent, never>;
27
+ static ɵcmp: i0.ɵɵComponentDeclaration<CallRecordingPlayerComponent, "eds-call-recording-player", never, { "callId": { "alias": "callId"; "required": true; "isSignal": true; }; }, { "currentTimeChange": "currentTimeChange"; "durationChange": "durationChange"; }, never, never, true, never>;
28
+ }
29
+ export {};
@@ -0,0 +1,19 @@
1
+ import { OnInit } from '@angular/core';
2
+ import { TaskItem } from '../../models/ai-receptionist.types';
3
+ import { taskStatusLabel, taskStatusTone, taskTypeTone } from '../../utils/task.util';
4
+ import * as i0 from "@angular/core";
5
+ export declare class CallTasksPanelComponent implements OnInit {
6
+ private readonly api;
7
+ readonly callId: import("@angular/core").InputSignal<string>;
8
+ readonly compact: import("@angular/core").InputSignal<boolean>;
9
+ protected readonly tasks: import("@angular/core").WritableSignal<TaskItem[]>;
10
+ protected readonly loading: import("@angular/core").WritableSignal<boolean>;
11
+ protected readonly expandedId: import("@angular/core").WritableSignal<string | null>;
12
+ protected readonly taskStatusLabel: typeof taskStatusLabel;
13
+ protected readonly taskStatusTone: typeof taskStatusTone;
14
+ protected readonly taskTypeTone: typeof taskTypeTone;
15
+ ngOnInit(): void;
16
+ protected toggleExpand(id: string): void;
17
+ static ɵfac: i0.ɵɵFactoryDeclaration<CallTasksPanelComponent, never>;
18
+ static ɵcmp: i0.ɵɵComponentDeclaration<CallTasksPanelComponent, "eds-call-tasks-panel", never, { "callId": { "alias": "callId"; "required": true; "isSignal": true; }; "compact": { "alias": "compact"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
19
+ }
@@ -0,0 +1,36 @@
1
+ import { AfterViewChecked } from '@angular/core';
2
+ import { TranscriptWho } from '../../models/ai-receptionist.types';
3
+ import * as i0 from "@angular/core";
4
+ export declare class LiveTranscriptPanelComponent implements AfterViewChecked {
5
+ readonly live: import("@angular/core").InputSignal<boolean>;
6
+ readonly paused: import("@angular/core").InputSignal<boolean>;
7
+ readonly humanTakeover: import("@angular/core").InputSignal<boolean>;
8
+ readonly showStaffInput: import("@angular/core").InputSignal<boolean>;
9
+ readonly staffMessage: import("@angular/core").InputSignal<string>;
10
+ readonly staffMessageChange: import("@angular/core").OutputEmitterRef<string>;
11
+ readonly sendMessage: import("@angular/core").OutputEmitterRef<void>;
12
+ private readonly stream;
13
+ private scrollHost?;
14
+ protected readonly lines: import("@angular/core").WritableSignal<import("../../models/ai-receptionist.types").TranscriptLine[]>;
15
+ protected readonly patientInterim: import("@angular/core").WritableSignal<string | null>;
16
+ protected readonly aiInterim: import("@angular/core").WritableSignal<string | null>;
17
+ protected readonly connected: import("@angular/core").WritableSignal<boolean>;
18
+ protected readonly error: import("@angular/core").WritableSignal<string | null>;
19
+ private shouldScroll;
20
+ constructor();
21
+ ngAfterViewChecked(): void;
22
+ protected waveformActive(): boolean;
23
+ protected waveformTone(): 'brand' | 'violet';
24
+ protected recLabel(): string;
25
+ protected roleLabel(who: TranscriptWho): string;
26
+ protected speakerIcon(who: TranscriptWho): string;
27
+ protected systemIcon(flag?: string): string;
28
+ protected systemClass(flag?: string): string;
29
+ protected msgClass(who: TranscriptWho): string;
30
+ protected avatarClass(who: TranscriptWho): string;
31
+ protected onStaffInput(value: string): void;
32
+ protected onSend(): void;
33
+ private requestScroll;
34
+ static ɵfac: i0.ɵɵFactoryDeclaration<LiveTranscriptPanelComponent, never>;
35
+ static ɵcmp: i0.ɵɵComponentDeclaration<LiveTranscriptPanelComponent, "eds-live-transcript-panel", never, { "live": { "alias": "live"; "required": false; "isSignal": true; }; "paused": { "alias": "paused"; "required": false; "isSignal": true; }; "humanTakeover": { "alias": "humanTakeover"; "required": false; "isSignal": true; }; "showStaffInput": { "alias": "showStaffInput"; "required": false; "isSignal": true; }; "staffMessage": { "alias": "staffMessage"; "required": false; "isSignal": true; }; }, { "staffMessageChange": "staffMessageChange"; "sendMessage": "sendMessage"; }, never, never, true, never>;
36
+ }
@@ -0,0 +1,37 @@
1
+ import { EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
2
+ import { OutboundPurpose } from '../../models/outbound-purpose.types';
3
+ import { requiredFieldLabel } from '../../utils/outbound-purpose.util';
4
+ import * as i0 from "@angular/core";
5
+ export declare class OutboundDialModalComponent implements OnChanges {
6
+ private readonly api;
7
+ private readonly toast;
8
+ open: boolean;
9
+ readonly closed: EventEmitter<void>;
10
+ readonly dialed: EventEmitter<void>;
11
+ protected readonly purposes: import("@angular/core").WritableSignal<OutboundPurpose[]>;
12
+ protected readonly loading: import("@angular/core").WritableSignal<boolean>;
13
+ protected readonly submitting: import("@angular/core").WritableSignal<boolean>;
14
+ protected readonly serverError: import("@angular/core").WritableSignal<string | null>;
15
+ protected phone: string;
16
+ protected name: string;
17
+ protected purposeId: string;
18
+ protected appointmentDate: string;
19
+ protected appointmentTime: string;
20
+ protected providerName: string;
21
+ protected customScript: string;
22
+ protected requiredFieldLabel: typeof requiredFieldLabel;
23
+ ngOnChanges(changes: SimpleChanges): void;
24
+ protected get selectedPurpose(): OutboundPurpose | null;
25
+ protected get previewText(): string;
26
+ protected showsField(field: 'appointmentDate' | 'appointmentTime' | 'providerName'): boolean;
27
+ protected showsCustomScript(): boolean;
28
+ protected customScriptRequired(): boolean;
29
+ protected canPlaceCall(): boolean;
30
+ protected onPurposeChange(): void;
31
+ protected close(): void;
32
+ protected submit(): void;
33
+ private resetForm;
34
+ private loadPurposes;
35
+ static ɵfac: i0.ɵɵFactoryDeclaration<OutboundDialModalComponent, never>;
36
+ static ɵcmp: i0.ɵɵComponentDeclaration<OutboundDialModalComponent, "eds-outbound-dial-modal", never, { "open": { "alias": "open"; "required": false; }; }, { "closed": "closed"; "dialed": "dialed"; }, never, never, true, never>;
37
+ }
@@ -0,0 +1,38 @@
1
+ import { ElementRef, EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
2
+ import { OutboundPurpose, OutboundPurposePlaceholder, OutboundRequiredField } from '../../models/outbound-purpose.types';
3
+ import * as i0 from "@angular/core";
4
+ export declare class OutboundPurposeFormModalComponent implements OnChanges {
5
+ private readonly api;
6
+ open: boolean;
7
+ purpose: OutboundPurpose | null;
8
+ readonly closed: EventEmitter<void>;
9
+ readonly saved: EventEmitter<OutboundPurpose>;
10
+ templateInput?: ElementRef<HTMLTextAreaElement>;
11
+ protected readonly fieldOptions: {
12
+ value: OutboundRequiredField;
13
+ label: string;
14
+ }[];
15
+ protected readonly saving: import("@angular/core").WritableSignal<boolean>;
16
+ protected readonly error: import("@angular/core").WritableSignal<string | null>;
17
+ protected label: string;
18
+ protected description: string;
19
+ protected sampleOpening: string;
20
+ protected openingTemplate: string;
21
+ protected agentContextHint: string;
22
+ protected requiredFields: Set<OutboundRequiredField>;
23
+ protected allowsCustomScript: boolean;
24
+ protected sortOrder: number;
25
+ protected isActive: boolean;
26
+ protected placeholders: OutboundPurposePlaceholder[];
27
+ protected get isEdit(): boolean;
28
+ protected get previewText(): string;
29
+ ngOnChanges(changes: SimpleChanges): void;
30
+ protected close(): void;
31
+ protected toggleRequired(field: OutboundRequiredField): void;
32
+ protected isRequiredSelected(field: OutboundRequiredField): boolean;
33
+ protected insertPlaceholder(token: string): void;
34
+ protected submit(): void;
35
+ private resetForm;
36
+ static ɵfac: i0.ɵɵFactoryDeclaration<OutboundPurposeFormModalComponent, never>;
37
+ static ɵcmp: i0.ɵɵComponentDeclaration<OutboundPurposeFormModalComponent, "eds-outbound-purpose-form-modal", never, { "open": { "alias": "open"; "required": false; }; "purpose": { "alias": "purpose"; "required": false; }; }, { "closed": "closed"; "saved": "saved"; }, never, never, true, never>;
38
+ }
@@ -0,0 +1,20 @@
1
+ import { TaskItem, TaskStatus } from '../../models/ai-receptionist.types';
2
+ import { taskCallRoute, taskPriorityLabel, taskPriorityTone, taskSourceLabel, taskStatusLabel, taskStatusTone, taskTypeTone } from '../../utils/task.util';
3
+ import * as i0 from "@angular/core";
4
+ export declare class TaskDetailDrawerComponent {
5
+ readonly task: import("@angular/core").InputSignal<TaskItem>;
6
+ readonly closed: import("@angular/core").OutputEmitterRef<void>;
7
+ readonly statusChange: import("@angular/core").OutputEmitterRef<TaskStatus>;
8
+ protected readonly taskStatusLabel: typeof taskStatusLabel;
9
+ protected readonly taskStatusTone: typeof taskStatusTone;
10
+ protected readonly taskPriorityLabel: typeof taskPriorityLabel;
11
+ protected readonly taskPriorityTone: typeof taskPriorityTone;
12
+ protected readonly taskSourceLabel: typeof taskSourceLabel;
13
+ protected readonly taskTypeTone: typeof taskTypeTone;
14
+ protected readonly taskCallRoute: typeof taskCallRoute;
15
+ protected close(): void;
16
+ protected markDone(): void;
17
+ protected onBackdropClick(event: MouseEvent): void;
18
+ static ɵfac: i0.ɵɵFactoryDeclaration<TaskDetailDrawerComponent, never>;
19
+ static ɵcmp: i0.ɵɵComponentDeclaration<TaskDetailDrawerComponent, "eds-task-detail-drawer", never, { "task": { "alias": "task"; "required": true; "isSignal": true; }; }, { "closed": "closed"; "statusChange": "statusChange"; }, never, never, true, never>;
20
+ }
@@ -0,0 +1,23 @@
1
+ import { InjectionToken, Signal } from '@angular/core';
2
+ /** Host-provided session for topbar / admin-only nav. */
3
+ export interface VoiceReceptionistSession {
4
+ /** Current user email for display. */
5
+ readonly email: Signal<string | null>;
6
+ isAdmin(): boolean;
7
+ logout(): void;
8
+ }
9
+ export interface VoiceReceptionistConfig {
10
+ /** Backend base URL (no trailing slash), e.g. https://api.example.com */
11
+ apiBaseUrl: string;
12
+ /** Use in-memory mock API (local demos). Default false. */
13
+ useMockApi?: boolean;
14
+ callLogsLimit?: number;
15
+ liveCallsPollIntervalMs?: number;
16
+ /**
17
+ * Show Practice nav links (patients / providers / appointments / admin).
18
+ * Enable in the standalone Voice Hub host; leave false for EHR embed.
19
+ */
20
+ includePracticeNav?: boolean;
21
+ }
22
+ export declare const VOICE_RECEPTIONIST_CONFIG: InjectionToken<VoiceReceptionistConfig>;
23
+ export declare const VOICE_RECEPTIONIST_SESSION: InjectionToken<VoiceReceptionistSession | null>;
@@ -0,0 +1,2 @@
1
+ /** Normalize list/detail API payloads into a row array. */
2
+ export declare function extractApiRows(body: unknown): unknown[];
@@ -0,0 +1,22 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import { FAQ_STARTER_TEMPLATES } from '../../models/practice-faq.model';
3
+ import * as i0 from "@angular/core";
4
+ export declare class FaqEmptyStateComponent {
5
+ protected readonly starters: {
6
+ label: string;
7
+ question: string;
8
+ answer: string;
9
+ category: string;
10
+ }[];
11
+ readonly add: EventEmitter<void>;
12
+ readonly useTemplate: EventEmitter<{
13
+ label: string;
14
+ question: string;
15
+ answer: string;
16
+ category: string;
17
+ }>;
18
+ protected onAdd(): void;
19
+ protected onTemplate(t: (typeof FAQ_STARTER_TEMPLATES)[number]): void;
20
+ static ɵfac: i0.ɵɵFactoryDeclaration<FaqEmptyStateComponent, never>;
21
+ static ɵcmp: i0.ɵɵComponentDeclaration<FaqEmptyStateComponent, "eds-faq-empty-state", never, {}, { "add": "add"; "useTemplate": "useTemplate"; }, never, never, true, never>;
22
+ }
@@ -0,0 +1,27 @@
1
+ import { EventEmitter, OnChanges } from '@angular/core';
2
+ import { CreatePracticeFaqRequest, PracticeFaq, UpdatePracticeFaqRequest } from '../../models/practice-faq.model';
3
+ import * as i0 from "@angular/core";
4
+ export declare class FaqFormComponent implements OnChanges {
5
+ open: boolean;
6
+ faq: PracticeFaq | null;
7
+ initialQuestion: string;
8
+ initialAnswer: string;
9
+ initialCategory: string;
10
+ readonly closed: EventEmitter<void>;
11
+ readonly saved: EventEmitter<CreatePracticeFaqRequest | UpdatePracticeFaqRequest>;
12
+ protected readonly categories: readonly ["hours", "location", "parking", "insurance", "services", "policies", "general"];
13
+ protected readonly saving: import("@angular/core").WritableSignal<boolean>;
14
+ protected readonly error: import("@angular/core").WritableSignal<string | null>;
15
+ protected question: string;
16
+ protected answer: string;
17
+ protected category: string;
18
+ protected sortOrder: number;
19
+ protected isActive: boolean;
20
+ protected get isEdit(): boolean;
21
+ ngOnChanges(): void;
22
+ protected close(): void;
23
+ protected submit(): void;
24
+ private resetForm;
25
+ static ɵfac: i0.ɵɵFactoryDeclaration<FaqFormComponent, never>;
26
+ static ɵcmp: i0.ɵɵComponentDeclaration<FaqFormComponent, "eds-faq-form", never, { "open": { "alias": "open"; "required": false; }; "faq": { "alias": "faq"; "required": false; }; "initialQuestion": { "alias": "initialQuestion"; "required": false; }; "initialAnswer": { "alias": "initialAnswer"; "required": false; }; "initialCategory": { "alias": "initialCategory"; "required": false; }; }, { "closed": "closed"; "saved": "saved"; }, never, never, true, never>;
27
+ }
@@ -0,0 +1,17 @@
1
+ import { PracticeFaqSearchItem } from '../../models/practice-faq.model';
2
+ import { categoryBadgeClass, scorePercent } from '../../utils/faq.util';
3
+ import * as i0 from "@angular/core";
4
+ export declare class FaqSearchTesterComponent {
5
+ private readonly api;
6
+ protected query: string;
7
+ protected readonly loading: import("@angular/core").WritableSignal<boolean>;
8
+ protected readonly searched: import("@angular/core").WritableSignal<boolean>;
9
+ protected readonly found: import("@angular/core").WritableSignal<boolean>;
10
+ protected readonly results: import("@angular/core").WritableSignal<PracticeFaqSearchItem[]>;
11
+ protected readonly error: import("@angular/core").WritableSignal<string | null>;
12
+ protected categoryClass: typeof categoryBadgeClass;
13
+ protected scorePercent: typeof scorePercent;
14
+ protected search(): void;
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<FaqSearchTesterComponent, never>;
16
+ static ɵcmp: i0.ɵɵComponentDeclaration<FaqSearchTesterComponent, "eds-faq-search-tester", never, {}, {}, never, never, true, never>;
17
+ }
@@ -0,0 +1,2 @@
1
+ import { PracticeFaq } from '../models/practice-faq.model';
2
+ export declare const SEED_PRACTICE_FAQS: PracticeFaq[];
@@ -0,0 +1,47 @@
1
+ export interface PracticeFaq {
2
+ faqId: string;
3
+ question: string;
4
+ answer: string;
5
+ category: string | null;
6
+ sortOrder: number;
7
+ isActive: boolean;
8
+ hasEmbedding: boolean;
9
+ createdAt: string;
10
+ updatedAt: string;
11
+ }
12
+ export interface CreatePracticeFaqRequest {
13
+ question: string;
14
+ answer: string;
15
+ category?: string;
16
+ sortOrder?: number;
17
+ isActive?: boolean;
18
+ }
19
+ export interface UpdatePracticeFaqRequest {
20
+ question?: string;
21
+ answer?: string;
22
+ category?: string | null;
23
+ sortOrder?: number;
24
+ isActive?: boolean;
25
+ }
26
+ export interface PracticeFaqSearchResult {
27
+ found: boolean;
28
+ items: PracticeFaqSearchItem[];
29
+ }
30
+ export interface PracticeFaqSearchItem {
31
+ faqId: string;
32
+ question: string;
33
+ answer: string;
34
+ category: string | null;
35
+ score: number;
36
+ }
37
+ export interface PracticeFaqListResponse {
38
+ items: PracticeFaq[];
39
+ }
40
+ export type FaqActiveFilter = 'all' | 'active' | 'inactive';
41
+ export declare const FAQ_CATEGORY_PRESETS: readonly ["hours", "location", "parking", "insurance", "services", "policies", "general"];
42
+ export declare const FAQ_STARTER_TEMPLATES: Array<{
43
+ label: string;
44
+ question: string;
45
+ answer: string;
46
+ category: string;
47
+ }>;
@@ -0,0 +1,47 @@
1
+ import { OnInit } from '@angular/core';
2
+ import { CreatePracticeFaqRequest, FaqActiveFilter, PracticeFaq, UpdatePracticeFaqRequest } from '../models/practice-faq.model';
3
+ import { categoryBadgeClass, truncateText } from '../utils/faq.util';
4
+ import * as i0 from "@angular/core";
5
+ export declare class KnowledgeHubPageComponent implements OnInit {
6
+ private readonly api;
7
+ private readonly toast;
8
+ protected readonly allFaqs: import("@angular/core").WritableSignal<PracticeFaq[]>;
9
+ protected readonly loading: import("@angular/core").WritableSignal<boolean>;
10
+ protected readonly error: import("@angular/core").WritableSignal<string | null>;
11
+ protected readonly activeFilter: import("@angular/core").WritableSignal<FaqActiveFilter>;
12
+ protected readonly categoryFilter: import("@angular/core").WritableSignal<string>;
13
+ protected readonly listSearch: import("@angular/core").WritableSignal<string>;
14
+ protected readonly formOpen: import("@angular/core").WritableSignal<boolean>;
15
+ protected readonly editing: import("@angular/core").WritableSignal<PracticeFaq | null>;
16
+ protected readonly formSeed: import("@angular/core").WritableSignal<{
17
+ question: string;
18
+ answer: string;
19
+ category: string;
20
+ }>;
21
+ protected readonly categories: readonly ["hours", "location", "parking", "insurance", "services", "policies", "general"];
22
+ protected readonly activeTabs: {
23
+ id: FaqActiveFilter;
24
+ label: string;
25
+ }[];
26
+ protected readonly faqs: import("@angular/core").Signal<PracticeFaq[]>;
27
+ protected categoryClass: typeof categoryBadgeClass;
28
+ protected truncate: typeof truncateText;
29
+ ngOnInit(): void;
30
+ protected load(): void;
31
+ protected setActiveFilter(id: FaqActiveFilter): void;
32
+ protected toggleCategory(cat: string): void;
33
+ protected isCategorySelected(cat: string): boolean;
34
+ protected openCreate(): void;
35
+ protected openEdit(faq: PracticeFaq): void;
36
+ protected closeForm(): void;
37
+ protected onStarterTemplate(t: {
38
+ question: string;
39
+ answer: string;
40
+ category: string;
41
+ }): void;
42
+ protected onSave(payload: CreatePracticeFaqRequest | UpdatePracticeFaqRequest): void;
43
+ protected toggleActive(faq: PracticeFaq, active: boolean): void;
44
+ protected deleteFaq(faq: PracticeFaq): void;
45
+ static ɵfac: i0.ɵɵFactoryDeclaration<KnowledgeHubPageComponent, never>;
46
+ static ɵcmp: i0.ɵɵComponentDeclaration<KnowledgeHubPageComponent, "eds-knowledge-hub-page", never, {}, {}, never, never, true, never>;
47
+ }
@@ -0,0 +1,16 @@
1
+ import { Observable } from 'rxjs';
2
+ import { CreatePracticeFaqRequest, PracticeFaq, PracticeFaqSearchResult, UpdatePracticeFaqRequest } from '../models/practice-faq.model';
3
+ import * as i0 from "@angular/core";
4
+ export declare class PracticeFaqApiMockService {
5
+ private readonly faqs;
6
+ list(activeOnly?: boolean): Observable<PracticeFaq[]>;
7
+ get(faqId: string): Observable<PracticeFaq | null>;
8
+ create(body: CreatePracticeFaqRequest): Observable<PracticeFaq>;
9
+ update(faqId: string, body: UpdatePracticeFaqRequest): Observable<PracticeFaq>;
10
+ delete(faqId: string): Observable<{
11
+ success: boolean;
12
+ }>;
13
+ search(q: string, limit?: number): Observable<PracticeFaqSearchResult>;
14
+ static ɵfac: i0.ɵɵFactoryDeclaration<PracticeFaqApiMockService, never>;
15
+ static ɵprov: i0.ɵɵInjectableDeclaration<PracticeFaqApiMockService>;
16
+ }