@edvak99/voice-receptionist-widget 1.1.10 → 1.1.12
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.
- package/fesm2022/{edvak99-voice-receptionist-widget-activities-page.component-BQS9JITk.mjs → edvak99-voice-receptionist-widget-activities-page.component-CACfxM4x.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-activities-page.component-BQS9JITk.mjs.map → edvak99-voice-receptionist-widget-activities-page.component-CACfxM4x.mjs.map} +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-ai-receptionist-api.service-CK6tM862.mjs → edvak99-voice-receptionist-widget-ai-receptionist-api.service-DcRiHn8q.mjs} +64 -8
- package/fesm2022/edvak99-voice-receptionist-widget-ai-receptionist-api.service-DcRiHn8q.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-analytics-page.component-CM5-vgzu.mjs → edvak99-voice-receptionist-widget-analytics-page.component-Dj9vw97B.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-analytics-page.component-CM5-vgzu.mjs.map → edvak99-voice-receptionist-widget-analytics-page.component-Dj9vw97B.mjs.map} +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget-api-log.util-C0TOKF1q.mjs +57 -0
- package/fesm2022/edvak99-voice-receptionist-widget-api-log.util-C0TOKF1q.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-api-logs-page.component-CwXaCPpV.mjs +227 -0
- package/fesm2022/edvak99-voice-receptionist-widget-api-logs-page.component-CwXaCPpV.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-api-logs-table.component-CEf4NPe5.mjs +110 -0
- package/fesm2022/edvak99-voice-receptionist-widget-api-logs-table.component-CEf4NPe5.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-call-history-detail-page.component-BkT3Qfsk.mjs → edvak99-voice-receptionist-widget-call-history-detail-page.component-DEplWBbz.mjs} +104 -8
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-DEplWBbz.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-Br9R0PQh.mjs +201 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-Br9R0PQh.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-Cy9DGRci.mjs → edvak99-voice-receptionist-widget-call-recording-player.component-j1mY5wU0.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-Cy9DGRci.mjs.map → edvak99-voice-receptionist-widget-call-recording-player.component-j1mY5wU0.mjs.map} +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-BAjx3n3v.mjs → edvak99-voice-receptionist-widget-call-review.service-DQ4TT_Su.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-BAjx3n3v.mjs.map → edvak99-voice-receptionist-widget-call-review.service-DQ4TT_Su.mjs.map} +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-DPxQ-wst.mjs +148 -0
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-DPxQ-wst.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-dashboard-socket.service-BuFQz1lN.mjs → edvak99-voice-receptionist-widget-dashboard-socket.service-tTQIsZO6.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-dashboard-socket.service-BuFQz1lN.mjs.map → edvak99-voice-receptionist-widget-dashboard-socket.service-tTQIsZO6.mjs.map} +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-eds-pulse-dot.component-CQIqnrcs.mjs → edvak99-voice-receptionist-widget-eds-pulse-dot.component-CUWZfYRR.mjs} +3 -3
- package/fesm2022/{edvak99-voice-receptionist-widget-eds-pulse-dot.component-CQIqnrcs.mjs.map → edvak99-voice-receptionist-widget-eds-pulse-dot.component-CUWZfYRR.mjs.map} +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget-eds-search-field.component-OGRDvYBp.mjs +83 -0
- package/fesm2022/edvak99-voice-receptionist-widget-eds-search-field.component-OGRDvYBp.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-live-calls-page.component-4LJuMn28.mjs → edvak99-voice-receptionist-widget-live-calls-page.component-BG9cB3zW.mjs} +3 -3
- package/fesm2022/{edvak99-voice-receptionist-widget-live-calls-page.component-4LJuMn28.mjs.map → edvak99-voice-receptionist-widget-live-calls-page.component-BG9cB3zW.mjs.map} +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-live-monitor-page.component-CJ7N-Jq6.mjs → edvak99-voice-receptionist-widget-live-monitor-page.component-BOQeTD3P.mjs} +4 -4
- package/fesm2022/{edvak99-voice-receptionist-widget-live-monitor-page.component-CJ7N-Jq6.mjs.map → edvak99-voice-receptionist-widget-live-monitor-page.component-BOQeTD3P.mjs.map} +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-outbound-purposes-page.component-HJmMq0b6.mjs → edvak99-voice-receptionist-widget-outbound-purposes-page.component-D407n7l0.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-outbound-purposes-page.component-HJmMq0b6.mjs.map → edvak99-voice-receptionist-widget-outbound-purposes-page.component-D407n7l0.mjs.map} +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-settings-page.component-9qSZL9mc.mjs → edvak99-voice-receptionist-widget-settings-page.component-YAvQ_XV6.mjs} +9 -11
- package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-YAvQ_XV6.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-tasks-page.component-s3fXlWkQ.mjs → edvak99-voice-receptionist-widget-tasks-page.component-BIOGiTgM.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-tasks-page.component-s3fXlWkQ.mjs.map → edvak99-voice-receptionist-widget-tasks-page.component-BIOGiTgM.mjs.map} +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-BD4Zhp0Y.mjs → edvak99-voice-receptionist-widget-wizard-page.component-DpF6y1go.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-BD4Zhp0Y.mjs.map → edvak99-voice-receptionist-widget-wizard-page.component-DpF6y1go.mjs.map} +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget.mjs +135 -24
- package/fesm2022/edvak99-voice-receptionist-widget.mjs.map +1 -1
- package/lib/components/api-health-widget/api-health-widget.component.d.ts +16 -0
- package/lib/components/api-log-detail-drawer/api-log-detail-drawer.component.d.ts +29 -0
- package/lib/components/api-logs-call-panel/api-logs-call-panel.component.d.ts +23 -0
- package/lib/components/api-logs-table/api-logs-table.component.d.ts +21 -0
- package/lib/config.d.ts +5 -0
- package/lib/guards/api-logs-standalone.guard.d.ts +6 -0
- package/lib/layout/eds-app-shell.component.d.ts +5 -0
- package/lib/layout/eds-module-nav.component.d.ts +4 -0
- package/lib/layout/eds-route-progress.component.d.ts +15 -0
- package/lib/models/ai-receptionist.types.d.ts +4 -0
- package/lib/models/api-log.types.d.ts +10 -0
- package/lib/pages/api-logs-page/api-logs-page.component.d.ts +50 -0
- package/lib/pages/call-history-detail-page/call-history-detail-page.component.d.ts +3 -0
- package/lib/pages/dashboard-page/dashboard-page.component.d.ts +3 -0
- package/lib/pages/settings-page/settings-fields.config.d.ts +1 -1
- package/lib/pages/settings-page/settings-page.component.d.ts +2 -2
- package/lib/services/ai-receptionist-api.mock.d.ts +6 -0
- package/lib/services/ai-receptionist-api.service.d.ts +8 -1
- package/lib/ui/eds-search-field.component.d.ts +22 -0
- package/lib/utils/api-log.util.d.ts +11 -0
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-ai-receptionist-api.service-CK6tM862.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-BkT3Qfsk.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-B-99E9Rs.mjs +0 -193
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-B-99E9Rs.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-9ao09dEd.mjs +0 -113
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-9ao09dEd.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-9qSZL9mc.mjs.map +0 -1
|
@@ -5,7 +5,7 @@ import { DatePipe } from '@angular/common';
|
|
|
5
5
|
import { E as EdsAvatarComponent } from './edvak99-voice-receptionist-widget-eds-avatar.component-BJs_TH8X.mjs';
|
|
6
6
|
import { EdsIconComponent, EdsButtonComponent } from './edvak99-voice-receptionist-widget.mjs';
|
|
7
7
|
import { T as TaskDetailDrawerComponent } from './edvak99-voice-receptionist-widget-task-detail-drawer.component-B3KmFJNH.mjs';
|
|
8
|
-
import { A as AiReceptionistApiService, D as DEFAULT_PAGE_SIZE,
|
|
8
|
+
import { A as AiReceptionistApiService, D as DEFAULT_PAGE_SIZE, g as totalPages, d as ageFromDob, l as initialsFromName } from './edvak99-voice-receptionist-widget-ai-receptionist-api.service-DcRiHn8q.mjs';
|
|
9
9
|
|
|
10
10
|
class PatientProfileDrawerComponent {
|
|
11
11
|
constructor() {
|
|
@@ -452,4 +452,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
452
452
|
}] });
|
|
453
453
|
|
|
454
454
|
export { ActivitiesPageComponent };
|
|
455
|
-
//# sourceMappingURL=edvak99-voice-receptionist-widget-activities-page.component-
|
|
455
|
+
//# sourceMappingURL=edvak99-voice-receptionist-widget-activities-page.component-CACfxM4x.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edvak99-voice-receptionist-widget-activities-page.component-BQS9JITk.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/components/patient-profile-drawer/patient-profile-drawer.component.ts","../../../projects/voice-receptionist-widget/src/lib/components/patient-profile-drawer/patient-profile-drawer.component.html","../../../projects/voice-receptionist-widget/src/lib/pages/activities-page/activities-page.component.ts","../../../projects/voice-receptionist-widget/src/lib/pages/activities-page/activities-page.component.html"],"sourcesContent":["import { DatePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n input,\n output,\n} from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nimport { AgentActivity } from '../../models/agent-activity.types';\nimport { EdsAvatarComponent } from '../../ui/eds-avatar.component';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\n\n@Component({\n selector: 'eds-patient-profile-drawer',\n imports: [DatePipe, RouterLink, EdsAvatarComponent, EdsIconComponent],\n templateUrl: './patient-profile-drawer.component.html',\n styleUrl: './patient-profile-drawer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PatientProfileDrawerComponent {\n readonly patient = input.required<AgentActivity>();\n\n readonly closed = output<void>();\n\n protected close(): void {\n this.closed.emit();\n }\n\n protected onBackdropClick(event: MouseEvent): void {\n if (event.target === event.currentTarget) this.close();\n }\n\n protected display(value: string | null | undefined): string {\n const s = String(value ?? '').trim();\n return s || '—';\n }\n\n protected insuranceLabel(): string {\n const p = this.patient();\n if (p.hasInsurance === true) {\n return p.insuranceName ? `Insured — ${p.insuranceName}` : 'Insured';\n }\n if (p.hasInsurance === false) return 'No insurance on file';\n return p.insuranceName || 'Not verified';\n }\n\n protected insuranceTone(): 'covered' | 'none' | 'unknown' {\n const p = this.patient();\n if (p.hasInsurance === true) return 'covered';\n if (p.hasInsurance === false) return 'none';\n return 'unknown';\n }\n}\n","<div\n class=\"fixed inset-0 z-[200] flex justify-end bg-[rgba(15,23,42,0.4)]\"\n (click)=\"onBackdropClick($event)\"\n>\n <aside\n class=\"patient-profile-drawer flex h-full w-[min(520px,100%)] flex-col bg-[#f7f8fa] shadow-[-8px_0_32px_rgba(15,23,42,0.12)]\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"display(patient().patientName)\"\n >\n <header class=\"flex items-center justify-between gap-3 border-b border-zinc-200 bg-white px-4 py-3\">\n <h2 class=\"m-0 text-base font-semibold text-zinc-900\">Patient profile</h2>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-9 cursor-pointer items-center justify-center rounded-md border-none bg-transparent text-zinc-500 hover:bg-zinc-100 hover:text-zinc-800\"\n (click)=\"close()\"\n aria-label=\"Close\"\n >\n <eds-icon name=\"close\" [size]=\"22\" />\n </button>\n </header>\n\n <div class=\"flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-4\">\n <section class=\"rounded-xl border border-zinc-200 bg-white p-4\">\n <div class=\"flex items-start gap-3\">\n <eds-avatar\n shape=\"box\"\n [initials]=\"patient().patientInitials || '?'\"\n tone=\"brand\"\n />\n <div class=\"min-w-0 flex-1\">\n <h3 class=\"m-0 text-xl font-semibold leading-snug text-zinc-900\">\n {{ display(patient().patientName) }}\n </h3>\n @if (patient().patientDob || patient().patientAge != null || patient().patientGender) {\n <p class=\"mt-1 mb-0 text-sm text-zinc-500\">\n @if (patient().patientDob) {\n DOB: {{ patient().patientDob | date: 'MM/dd/yyyy' }}\n }\n @if (patient().patientAge != null) {\n · {{ patient().patientAge }}Y\n }\n @if (patient().patientGender) {\n · {{ patient().patientGender }}\n }\n </p>\n }\n </div>\n </div>\n </section>\n\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">MRN</span>\n <span class=\"text-sm text-zinc-600\">{{ display(patient().patientMrn) }}</span>\n </div>\n </section>\n\n @if (patient().patientId) {\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Patient ID</span>\n <span class=\"font-mono text-sm text-zinc-600\">{{ patient().patientId }}</span>\n </div>\n </section>\n }\n\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Insurance</span>\n <span\n class=\"patient-profile-drawer__insurance inline-flex items-center rounded-full border px-2.5 py-1 text-xs font-medium\"\n [attr.data-state]=\"insuranceTone()\"\n >\n {{ insuranceLabel() }}\n </span>\n </div>\n </section>\n\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Registered</span>\n <span class=\"text-sm text-zinc-600\">\n @if (patient().occurredAt) {\n {{ patient().occurredAt | date: 'MMM d, y, h:mm a' }}\n } @else {\n —\n }\n </span>\n </div>\n </section>\n\n @if (patient().detail) {\n <section class=\"rounded-xl border border-zinc-200 bg-white p-4\">\n <h3 class=\"m-0 text-sm font-semibold text-zinc-800\">Details</h3>\n <p class=\"mt-2 mb-0 whitespace-pre-wrap text-sm leading-relaxed text-zinc-600\">\n {{ patient().detail }}\n </p>\n </section>\n }\n\n @if (patient().callId) {\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Call</span>\n <a\n [routerLink]=\"['../history', patient().callId]\"\n class=\"text-sm font-medium text-blue-600 no-underline hover:underline\"\n (click)=\"close()\"\n >\n {{ patient().callId }}\n </a>\n </div>\n </section>\n }\n </div>\n </aside>\n</div>\n","import { ChangeDetectionStrategy, Component, OnInit, inject, signal } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\n\nimport { PatientProfileDrawerComponent } from '../../components/patient-profile-drawer/patient-profile-drawer.component';\nimport { TaskDetailDrawerComponent } from '../../components/task-detail-drawer/task-detail-drawer.component';\nimport {\n ActivitiesTab,\n AgentActivity,\n initialsFromName,\n} from '../../models/agent-activity.types';\nimport { TaskItem, TaskStatus } from '../../models/ai-receptionist.types';\nimport { DEFAULT_PAGE_SIZE, totalPages as calcTotalPages } from '../../models/pagination';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { ageFromDob } from '../../utils/call-history-display.util';\nimport { EdsAvatarComponent } from '../../ui/eds-avatar.component';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\n\ntype TabId = ActivitiesTab;\n\nconst TABS: { id: TabId; label: string }[] = [\n { id: 'task_created', label: 'Tasks' },\n { id: 'appointment_booked', label: 'Appointments' },\n { id: 'patient_created', label: 'Registrations' },\n];\n\nconst AVATAR_TONES = ['green', 'amber', 'brand', 'violet', 'rose'] as const;\n\n@Component({\n selector: 'eds-activities-page',\n imports: [\n EdsAvatarComponent,\n EdsButtonComponent,\n EdsIconComponent,\n TaskDetailDrawerComponent,\n PatientProfileDrawerComponent,\n ],\n templateUrl: './activities-page.component.html',\n styleUrl: './activities-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ActivitiesPageComponent implements OnInit {\n private readonly api = inject(AiReceptionistApiService);\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n\n protected readonly tabs = TABS;\n protected readonly pageSize = DEFAULT_PAGE_SIZE;\n protected readonly items = signal<AgentActivity[]>([]);\n protected readonly total = signal(0);\n protected readonly page = signal(1);\n protected readonly activeTab = signal<TabId>('task_created');\n protected readonly callIdFilter = signal<string | null>(null);\n protected readonly loading = signal(true);\n protected readonly loadError = signal<string | null>(null);\n protected readonly selectedTask = signal<TaskItem | null>(null);\n protected readonly selectedPatient = signal<AgentActivity | null>(null);\n\n ngOnInit(): void {\n const callId = this.route.snapshot.queryParamMap.get('callId')?.trim() || null;\n if (callId) this.callIdFilter.set(callId);\n\n const tabParam = (this.route.snapshot.queryParamMap.get('tab') || '').trim().toLowerCase();\n const tabFromQuery = this.tabFromQuery(tabParam);\n if (tabFromQuery) {\n this.activeTab.set(tabFromQuery);\n } else {\n this.activeTab.set('task_created');\n void this.router.navigate([], {\n relativeTo: this.route,\n queryParams: { tab: 'tasks' },\n queryParamsHandling: 'merge',\n replaceUrl: true,\n });\n }\n\n this.load();\n }\n\n protected setTab(tab: TabId): void {\n if (this.activeTab() === tab) return;\n this.activeTab.set(tab);\n this.page.set(1);\n void this.router.navigate([], {\n relativeTo: this.route,\n queryParams: { tab: this.tabQueryValue(tab) },\n queryParamsHandling: 'merge',\n replaceUrl: true,\n });\n this.load();\n }\n\n private tabFromQuery(raw: string): TabId | null {\n switch (raw) {\n case 'tasks':\n case 'task':\n case 'task_created':\n return 'task_created';\n case 'appointments':\n case 'appointment':\n case 'appointment_booked':\n return 'appointment_booked';\n case 'registrations':\n case 'registration':\n case 'patient_created':\n return 'patient_created';\n default:\n return null;\n }\n }\n\n private tabQueryValue(tab: TabId): string {\n switch (tab) {\n case 'task_created':\n return 'tasks';\n case 'patient_created':\n return 'registrations';\n default:\n return 'appointments';\n }\n }\n\n protected clearCallFilter(): void {\n this.callIdFilter.set(null);\n this.page.set(1);\n this.load();\n }\n\n protected load(): void {\n this.loading.set(true);\n this.loadError.set(null);\n const tab = this.activeTab();\n this.api\n .getActivities({\n page: this.page(),\n limit: DEFAULT_PAGE_SIZE,\n types: tab,\n callId: this.callIdFilter() || undefined,\n })\n .subscribe({\n next: ({ items, total, page }) => {\n this.items.set(items);\n this.total.set(total);\n this.page.set(page);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.items.set([]);\n this.total.set(0);\n this.loadError.set(\n 'Activities feed is unavailable. Confirm GET /api/ai-receptionist/activities is deployed.',\n );\n },\n });\n }\n\n protected totalPages(): number {\n return calcTotalPages(this.total(), DEFAULT_PAGE_SIZE);\n }\n\n protected prevPage(): void {\n if (this.page() <= 1) return;\n this.page.update((p) => p - 1);\n this.load();\n }\n\n protected nextPage(): void {\n if (this.page() >= this.totalPages()) return;\n this.page.update((p) => p + 1);\n this.load();\n }\n\n protected historyLink(callId: string | null | undefined): string[] | null {\n return callId ? ['../history', callId] : null;\n }\n\n protected openCallHistory(callId: string | null | undefined, ev?: Event): void {\n if (!callId) return;\n if (ev && (ev.target as HTMLElement).closest('a,button')) return;\n void this.router.navigate(['../history', callId], { relativeTo: this.route });\n }\n\n protected openTask(item: AgentActivity): void {\n this.selectedPatient.set(null);\n this.selectedTask.set(this.activityToTask(item));\n }\n\n protected openPatient(item: AgentActivity): void {\n this.selectedTask.set(null);\n this.selectedPatient.set(item);\n }\n\n protected closeTaskDrawer(): void {\n this.selectedTask.set(null);\n }\n\n protected closePatientDrawer(): void {\n this.selectedPatient.set(null);\n }\n\n protected onTaskStatusChange(status: TaskStatus): void {\n const task = this.selectedTask();\n if (!task) return;\n this.api.patchTask(task.id, status).subscribe({\n next: ({ data }) => {\n if (data) {\n this.selectedTask.set(data);\n } else {\n this.selectedTask.set({ ...task, status });\n }\n },\n error: () => {\n // Optimistic local update if patch fails (activity-sourced ids may not exist).\n this.selectedTask.set({ ...task, status });\n },\n });\n }\n\n private activityToTask(item: AgentActivity): TaskItem {\n const priority =\n item.priority === 'urgent' || item.priority === 'high' ? 'urgent' : 'normal';\n const created = this.parseDate(item.occurredAt)?.getTime() ?? Date.now();\n return {\n id: item.taskId || item.id,\n created,\n title: this.taskTitle(item),\n type: 'task',\n description: item.detail || '',\n patient: item.patientName || 'Unknown caller',\n priority,\n status: 'open',\n source: 'voice',\n assignee: 'AI Receptionist',\n callId: item.callId || undefined,\n };\n }\n\n protected displayMrn(item: AgentActivity): string {\n return item.patientMrn?.trim() || '—';\n }\n\n protected providerSpecialtyLabel(item: AgentActivity): string | null {\n const s = item.providerSpecialty?.trim();\n if (!s) return null;\n // Hide stray numeric IDs that sometimes land in specialty.\n if (/^\\d+(\\.\\d+)?$/.test(s)) return null;\n return s;\n }\n\n /** Day-anchored stamp — a bare clock time gave no idea which day a row belonged to. */\n protected timestampLabel(item: AgentActivity): string {\n const start = this.parseDate(item.startAt || item.occurredAt);\n if (!start) return '—';\n const stamp = `${this.formatDay(start)}, ${this.formatClock(start)}`;\n const end = this.parseDate(item.endAt);\n if (end && end.getTime() > start.getTime()) {\n return `${stamp} – ${this.formatClock(end)}`;\n }\n return stamp;\n }\n\n protected durationLabel(item: AgentActivity): string | null {\n const mins = item.durationMinutes;\n if (mins == null || mins <= 0) {\n if (item.startAt && item.endAt) {\n const ms = Date.parse(item.endAt) - Date.parse(item.startAt);\n if (Number.isFinite(ms) && ms > 0) {\n return `${Math.round(ms / 60000)} MIN`;\n }\n }\n return null;\n }\n return `${mins} MIN`;\n }\n\n protected categoryLabel(item: AgentActivity): string {\n if (item.visitType) return item.visitType;\n switch (item.type) {\n case 'appointment_booked':\n return 'Appointment';\n case 'patient_created':\n return 'Registration';\n case 'task_created':\n return item.title && !/^task created$/i.test(item.title) ? item.title : 'Task';\n default:\n return item.title || 'Activity';\n }\n }\n\n protected patientMeta(item: AgentActivity): string | null {\n const parts: string[] = [];\n const dob = item.patientDob;\n const age = item.patientAge ?? (dob ? ageFromDob(dob) : null);\n if (dob && age != null) parts.push(`DOB: ${this.formatDob(dob)} · ${age}Y`);\n else if (dob) parts.push(`DOB: ${this.formatDob(dob)}`);\n else if (age != null) parts.push(`${age}Y`);\n if (item.patientGender) parts.push(item.patientGender);\n return parts.length ? parts.join(' | ') : null;\n }\n\n protected patientInitials(item: AgentActivity): string {\n return item.patientInitials || initialsFromName(item.patientName) || '?';\n }\n\n protected providerInitials(item: AgentActivity): string {\n return item.providerInitials || initialsFromName(item.providerName) || '?';\n }\n\n protected avatarTone(key: string | null | undefined, salt: number): string {\n const raw = `${key || 'x'}:${salt}`;\n let hash = 0;\n for (let i = 0; i < raw.length; i++) hash = (hash + raw.charCodeAt(i) * (i + 1)) % 997;\n return AVATAR_TONES[hash % AVATAR_TONES.length];\n }\n\n protected insuranceState(item: AgentActivity): 'covered' | 'none' | 'unknown' {\n if (item.hasInsurance === true) return 'covered';\n if (item.hasInsurance === false) return 'none';\n return 'unknown';\n }\n\n protected insuranceIcon(item: AgentActivity): string {\n switch (this.insuranceState(item)) {\n case 'covered':\n return 'verified_user';\n case 'none':\n return 'gpp_bad';\n default:\n return 'gpp_maybe';\n }\n }\n\n protected insuranceLabel(item: AgentActivity): string {\n switch (this.insuranceState(item)) {\n case 'covered':\n return 'Insured';\n case 'none':\n return 'No insurance';\n default:\n return 'Unverified';\n }\n }\n\n protected insuranceTitle(item: AgentActivity): string {\n switch (this.insuranceState(item)) {\n case 'covered':\n return item.insuranceName ? `Insured — ${item.insuranceName}` : 'Insured';\n case 'none':\n return 'No insurance on file';\n default:\n return 'Insurance not verified';\n }\n }\n\n protected isTaskRow(item: AgentActivity): boolean {\n return item.type === 'task_created';\n }\n\n protected taskTitle(item: AgentActivity): string {\n const title = (item.title || '').trim();\n if (title && !/^task created$/i.test(title)) return title;\n return item.visitType || 'Task';\n }\n\n protected priorityLabel(item: AgentActivity): string {\n switch (item.priority) {\n case 'urgent':\n return 'Urgent';\n case 'high':\n return 'High';\n case 'low':\n return 'Low';\n case 'medium':\n case 'normal':\n default:\n return 'Medium';\n }\n }\n\n protected priorityTone(item: AgentActivity): string {\n switch (item.priority) {\n case 'urgent':\n return 'urgent';\n case 'high':\n return 'high';\n case 'low':\n return 'low';\n default:\n return 'medium';\n }\n }\n\n protected isRegistrationTab(): boolean {\n return this.activeTab() === 'patient_created';\n }\n\n protected emptyLabel(): string {\n if (this.callIdFilter()) return 'No activities found for this call.';\n switch (this.activeTab()) {\n case 'task_created':\n return 'No tasks created by the AI yet.';\n case 'patient_created':\n return 'No patient registrations yet.';\n default:\n return 'No appointments booked by the AI yet.';\n }\n }\n\n private parseDate(iso: string | null | undefined): Date | null {\n if (!iso) return null;\n const d = new Date(iso);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n\n private formatDay(d: Date): string {\n const midnight = (x: Date) => new Date(x.getFullYear(), x.getMonth(), x.getDate()).getTime();\n const now = new Date();\n const days = Math.round((midnight(d) - midnight(now)) / 86_400_000);\n if (days === 0) return 'Today';\n if (days === 1) return 'Tomorrow';\n if (days === -1) return 'Yesterday';\n return d.toLocaleDateString(\n undefined,\n d.getFullYear() === now.getFullYear()\n ? { weekday: 'short', month: 'short', day: 'numeric' }\n : { month: 'short', day: 'numeric', year: 'numeric' },\n );\n }\n\n private formatClock(d: Date): string {\n return d.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n }\n\n private formatDob(iso: string): string {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(iso.trim());\n if (m) return `${m[2]}-${m[3]}-${m[1]}`;\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n const mm = String(d.getMonth() + 1).padStart(2, '0');\n const dd = String(d.getDate()).padStart(2, '0');\n return `${mm}-${dd}-${d.getFullYear()}`;\n }\n}\n","<div class=\"eds-page activities-page\">\n <header class=\"mb-5\">\n <div>\n <h1 class=\"eds-h1\">Activities</h1>\n <p class=\"eds-body-sm\">Review all the activities done by the AI at one place</p>\n </div>\n </header>\n\n @if (callIdFilter(); as callId) {\n <div\n class=\"mb-4 flex flex-wrap items-center justify-between gap-3 rounded-lg bg-blue-50 px-4 py-3 text-sm font-normal leading-snug text-zinc-600\"\n role=\"status\"\n >\n <span>Showing activities for call <strong class=\"font-medium text-zinc-700\">{{ callId }}</strong></span>\n <button\n type=\"button\"\n class=\"cursor-pointer border-none bg-transparent px-0 py-1 text-sm font-medium text-blue-600 hover:underline\"\n (click)=\"clearCallFilter()\"\n >\n Clear filter\n </button>\n </div>\n }\n\n <nav class=\"mb-5 flex flex-wrap gap-2\" aria-label=\"Activity type\">\n @for (tab of tabs; track tab.id) {\n <button\n type=\"button\"\n [class]=\"\n activeTab() === tab.id\n ? 'cursor-pointer rounded-full border-none bg-blue-50 px-4 py-2 text-sm font-medium text-blue-600 transition-colors'\n : 'cursor-pointer rounded-full border-none bg-transparent px-4 py-2 text-sm font-medium text-zinc-500 transition-colors hover:bg-white hover:text-zinc-700'\n \"\n (click)=\"setTab(tab.id)\"\n >\n {{ tab.label }}\n </button>\n }\n </nav>\n\n @if (loading()) {\n <p class=\"eds-body-sm\">Loading activities…</p>\n } @else if (loadError()) {\n <p class=\"text-sm text-red-700\" role=\"alert\">{{ loadError() }}</p>\n } @else {\n @if (activeTab() === 'task_created') {\n <div\n class=\"activities-page__col-head activities-page__col-head--tasks grid gap-x-7 gap-y-4 pb-2 text-sm font-semibold leading-tight text-zinc-600 max-lg:hidden\"\n aria-hidden=\"true\"\n >\n <span>Priority</span>\n <span>Task</span>\n <span>Patient / Caller</span>\n </div>\n } @else if (activeTab() === 'appointment_booked') {\n <div\n class=\"activities-page__col-head activities-page__col-head--appointments grid gap-x-7 gap-y-4 pb-2 text-sm font-semibold leading-tight text-zinc-600 max-lg:hidden\"\n aria-hidden=\"true\"\n >\n <span>When</span>\n <span>Patient</span>\n <span>Provider</span>\n <span class=\"justify-self-end text-right\">Insurance</span>\n </div>\n } @else if (activeTab() === 'patient_created') {\n <div\n class=\"activities-page__col-head activities-page__col-head--registration grid gap-x-7 gap-y-4 pb-2 text-sm font-semibold leading-tight text-zinc-600 max-lg:hidden\"\n aria-hidden=\"true\"\n >\n <span>When</span>\n <span>Patient</span>\n <span>MRN</span>\n <span class=\"justify-self-end text-right\">Insurance</span>\n </div>\n }\n\n <ul class=\"m-0 flex list-none flex-col gap-3 p-0\">\n @for (item of items(); track item.id; let i = $index) {\n @if (isTaskRow(item)) {\n <li\n class=\"activities-page__card activities-page__card--task grid cursor-pointer items-center gap-x-7 gap-y-4 rounded-xl border border-zinc-200 bg-white px-4 py-4 max-lg:gap-x-4 max-lg:gap-y-4 hover:border-blue-200 hover:shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'View task: ' + taskTitle(item)\"\n (click)=\"openTask(item)\"\n (keyup.enter)=\"openTask(item)\"\n >\n <div class=\"inline-flex items-center gap-2 text-sm font-medium leading-snug text-zinc-700\" [attr.data-tone]=\"priorityTone(item)\">\n <span class=\"activities-page__priority-mark h-2.5 w-2.5 shrink-0 rotate-45 rounded-sm\" aria-hidden=\"true\"></span>\n <span class=\"capitalize\">{{ priorityLabel(item) }}</span>\n </div>\n\n <div class=\"text-sm font-medium leading-snug text-zinc-700 max-lg:col-span-full\">{{ taskTitle(item) }}</div>\n\n <div class=\"flex min-w-0 items-center gap-3 max-lg:col-span-full\">\n <eds-avatar\n shape=\"box\"\n [initials]=\"patientInitials(item)\"\n [tone]=\"avatarTone(item.patientId || item.patientName || item.id, i)\"\n />\n <div class=\"flex min-w-0 flex-col gap-1\">\n <span class=\"truncate text-sm font-medium leading-snug text-zinc-700\">{{ item.patientName || 'Unknown caller' }}</span>\n @if (patientMeta(item); as meta) {\n <span class=\"truncate text-xs leading-snug text-zinc-500\">{{ meta }}</span>\n }\n </div>\n </div>\n </li>\n } @else if (isRegistrationTab()) {\n <li\n class=\"activities-page__card activities-page__card--registration grid cursor-pointer items-center gap-x-7 gap-y-4 rounded-xl border border-zinc-200 bg-white px-4 py-4 max-lg:gap-x-4 max-lg:gap-y-4 hover:border-blue-200 hover:shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'View patient: ' + (item.patientName || 'Unknown patient')\"\n (click)=\"openPatient(item)\"\n (keyup.enter)=\"openPatient(item)\"\n >\n <div class=\"min-w-0\">\n <div class=\"mb-1 flex flex-wrap items-center gap-2\">\n <span class=\"whitespace-nowrap text-base font-medium leading-snug text-zinc-700 max-md:whitespace-normal\">{{ timestampLabel(item) }}</span>\n </div>\n <p class=\"m-0 text-sm leading-snug text-zinc-500\">{{ categoryLabel(item) }}</p>\n </div>\n\n <div class=\"flex min-w-0 items-center gap-3 max-lg:col-span-full\">\n <eds-avatar\n shape=\"box\"\n [initials]=\"patientInitials(item)\"\n [tone]=\"avatarTone(item.patientId || item.patientName || item.id, i)\"\n />\n <div class=\"flex min-w-0 flex-col gap-1\">\n <span class=\"truncate text-sm font-medium leading-snug text-zinc-700\">{{ item.patientName || 'Unknown patient' }}</span>\n @if (patientMeta(item); as meta) {\n <span class=\"truncate text-xs leading-snug text-zinc-500\">{{ meta }}</span>\n }\n </div>\n </div>\n\n <div class=\"text-sm font-normal leading-snug text-zinc-600\">{{ displayMrn(item) }}</div>\n\n <div class=\"flex items-center justify-end gap-2.5\">\n <span\n class=\"activities-page__insurance inline-flex h-8 w-8 items-center justify-center rounded-full border border-transparent max-md:px-1.5\"\n [attr.data-state]=\"insuranceState(item)\"\n [title]=\"insuranceTitle(item)\"\n [attr.aria-label]=\"insuranceLabel(item)\"\n >\n <eds-icon [name]=\"insuranceIcon(item)\" [size]=\"18\" />\n </span>\n </div>\n </li>\n } @else {\n <li\n [class]=\"\n 'activities-page__card grid items-center gap-x-7 gap-y-4 rounded-xl border border-zinc-200 bg-white px-4 py-4 max-lg:gap-x-4 max-lg:gap-y-4' +\n (item.callId\n ? ' cursor-pointer hover:border-blue-200 hover:shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600'\n : '')\n \"\n [attr.role]=\"item.callId ? 'link' : null\"\n [attr.tabindex]=\"item.callId ? 0 : null\"\n (click)=\"openCallHistory(item.callId, $event)\"\n (keyup.enter)=\"openCallHistory(item.callId)\"\n >\n <div class=\"min-w-0\">\n <div class=\"mb-1 flex flex-wrap items-center gap-2\">\n <span class=\"whitespace-nowrap text-base font-medium leading-snug text-zinc-700 max-md:whitespace-normal\">{{ timestampLabel(item) }}</span>\n </div>\n <p class=\"m-0 text-sm leading-snug text-zinc-500\">{{ categoryLabel(item) }}</p>\n </div>\n\n <div class=\"flex min-w-0 items-center gap-3 max-lg:col-span-full\">\n <eds-avatar\n shape=\"box\"\n [initials]=\"patientInitials(item)\"\n [tone]=\"avatarTone(item.patientId || item.patientName || item.id, i)\"\n />\n <div class=\"flex min-w-0 flex-col gap-1\">\n <span class=\"truncate text-sm font-medium leading-snug text-zinc-700\">{{ item.patientName || 'Unknown patient' }}</span>\n @if (patientMeta(item); as meta) {\n <span class=\"truncate text-xs leading-snug text-zinc-500\">{{ meta }}</span>\n }\n </div>\n </div>\n\n <div class=\"flex min-w-0 items-center gap-3 max-lg:col-span-full\">\n @if (item.providerName) {\n <eds-avatar\n shape=\"circle\"\n [initials]=\"providerInitials(item)\"\n [tone]=\"avatarTone(item.providerId || item.providerName, i + 3)\"\n />\n <div class=\"flex min-w-0 flex-col gap-1\">\n <span class=\"truncate text-sm font-medium leading-snug text-zinc-700\">{{ item.providerName }}</span>\n @if (providerSpecialtyLabel(item); as specialty) {\n <span class=\"truncate text-xs leading-snug text-zinc-500\">{{ specialty }}</span>\n }\n </div>\n } @else {\n <div class=\"flex min-h-9 items-center\">\n <span class=\"truncate text-xs leading-snug text-zinc-500\">No provider assigned</span>\n </div>\n }\n </div>\n\n <div class=\"flex items-center justify-end gap-3\">\n <span\n class=\"activities-page__insurance inline-flex h-8 w-8 items-center justify-center rounded-full border border-transparent max-md:px-2\"\n [attr.data-state]=\"insuranceState(item)\"\n [title]=\"insuranceTitle(item)\"\n [attr.aria-label]=\"insuranceLabel(item)\"\n >\n <eds-icon [name]=\"insuranceIcon(item)\" [size]=\"18\" />\n </span>\n </div>\n </li>\n }\n } @empty {\n <li class=\"rounded-xl border border-dashed border-zinc-200 bg-white px-4 py-10 text-center text-sm leading-snug text-zinc-500\">\n {{ emptyLabel() }}\n </li>\n }\n </ul>\n\n @if (total() > pageSize) {\n <footer class=\"mt-4 flex flex-wrap items-center justify-between gap-3\">\n <span class=\"eds-body-sm\">\n Page {{ page() }} of {{ totalPages() }} · {{ total() }} total\n </span>\n <div class=\"flex gap-2\">\n <eds-button variant=\"secondary\" [disabled]=\"page() <= 1\" (click)=\"prevPage()\">Previous</eds-button>\n <eds-button variant=\"secondary\" [disabled]=\"page() >= totalPages()\" (click)=\"nextPage()\">Next</eds-button>\n </div>\n </footer>\n }\n }\n</div>\n\n@if (selectedTask(); as task) {\n <eds-task-detail-drawer\n [task]=\"task\"\n (closed)=\"closeTaskDrawer()\"\n (statusChange)=\"onTaskStatusChange($event)\"\n />\n}\n\n@if (selectedPatient(); as patient) {\n <eds-patient-profile-drawer\n [patient]=\"patient\"\n (closed)=\"closePatientDrawer()\"\n />\n}\n"],"names":["calcTotalPages"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"edvak99-voice-receptionist-widget-activities-page.component-CACfxM4x.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/components/patient-profile-drawer/patient-profile-drawer.component.ts","../../../projects/voice-receptionist-widget/src/lib/components/patient-profile-drawer/patient-profile-drawer.component.html","../../../projects/voice-receptionist-widget/src/lib/pages/activities-page/activities-page.component.ts","../../../projects/voice-receptionist-widget/src/lib/pages/activities-page/activities-page.component.html"],"sourcesContent":["import { DatePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n input,\n output,\n} from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nimport { AgentActivity } from '../../models/agent-activity.types';\nimport { EdsAvatarComponent } from '../../ui/eds-avatar.component';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\n\n@Component({\n selector: 'eds-patient-profile-drawer',\n imports: [DatePipe, RouterLink, EdsAvatarComponent, EdsIconComponent],\n templateUrl: './patient-profile-drawer.component.html',\n styleUrl: './patient-profile-drawer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PatientProfileDrawerComponent {\n readonly patient = input.required<AgentActivity>();\n\n readonly closed = output<void>();\n\n protected close(): void {\n this.closed.emit();\n }\n\n protected onBackdropClick(event: MouseEvent): void {\n if (event.target === event.currentTarget) this.close();\n }\n\n protected display(value: string | null | undefined): string {\n const s = String(value ?? '').trim();\n return s || '—';\n }\n\n protected insuranceLabel(): string {\n const p = this.patient();\n if (p.hasInsurance === true) {\n return p.insuranceName ? `Insured — ${p.insuranceName}` : 'Insured';\n }\n if (p.hasInsurance === false) return 'No insurance on file';\n return p.insuranceName || 'Not verified';\n }\n\n protected insuranceTone(): 'covered' | 'none' | 'unknown' {\n const p = this.patient();\n if (p.hasInsurance === true) return 'covered';\n if (p.hasInsurance === false) return 'none';\n return 'unknown';\n }\n}\n","<div\n class=\"fixed inset-0 z-[200] flex justify-end bg-[rgba(15,23,42,0.4)]\"\n (click)=\"onBackdropClick($event)\"\n>\n <aside\n class=\"patient-profile-drawer flex h-full w-[min(520px,100%)] flex-col bg-[#f7f8fa] shadow-[-8px_0_32px_rgba(15,23,42,0.12)]\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"display(patient().patientName)\"\n >\n <header class=\"flex items-center justify-between gap-3 border-b border-zinc-200 bg-white px-4 py-3\">\n <h2 class=\"m-0 text-base font-semibold text-zinc-900\">Patient profile</h2>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-9 cursor-pointer items-center justify-center rounded-md border-none bg-transparent text-zinc-500 hover:bg-zinc-100 hover:text-zinc-800\"\n (click)=\"close()\"\n aria-label=\"Close\"\n >\n <eds-icon name=\"close\" [size]=\"22\" />\n </button>\n </header>\n\n <div class=\"flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-4\">\n <section class=\"rounded-xl border border-zinc-200 bg-white p-4\">\n <div class=\"flex items-start gap-3\">\n <eds-avatar\n shape=\"box\"\n [initials]=\"patient().patientInitials || '?'\"\n tone=\"brand\"\n />\n <div class=\"min-w-0 flex-1\">\n <h3 class=\"m-0 text-xl font-semibold leading-snug text-zinc-900\">\n {{ display(patient().patientName) }}\n </h3>\n @if (patient().patientDob || patient().patientAge != null || patient().patientGender) {\n <p class=\"mt-1 mb-0 text-sm text-zinc-500\">\n @if (patient().patientDob) {\n DOB: {{ patient().patientDob | date: 'MM/dd/yyyy' }}\n }\n @if (patient().patientAge != null) {\n · {{ patient().patientAge }}Y\n }\n @if (patient().patientGender) {\n · {{ patient().patientGender }}\n }\n </p>\n }\n </div>\n </div>\n </section>\n\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">MRN</span>\n <span class=\"text-sm text-zinc-600\">{{ display(patient().patientMrn) }}</span>\n </div>\n </section>\n\n @if (patient().patientId) {\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Patient ID</span>\n <span class=\"font-mono text-sm text-zinc-600\">{{ patient().patientId }}</span>\n </div>\n </section>\n }\n\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Insurance</span>\n <span\n class=\"patient-profile-drawer__insurance inline-flex items-center rounded-full border px-2.5 py-1 text-xs font-medium\"\n [attr.data-state]=\"insuranceTone()\"\n >\n {{ insuranceLabel() }}\n </span>\n </div>\n </section>\n\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Registered</span>\n <span class=\"text-sm text-zinc-600\">\n @if (patient().occurredAt) {\n {{ patient().occurredAt | date: 'MMM d, y, h:mm a' }}\n } @else {\n —\n }\n </span>\n </div>\n </section>\n\n @if (patient().detail) {\n <section class=\"rounded-xl border border-zinc-200 bg-white p-4\">\n <h3 class=\"m-0 text-sm font-semibold text-zinc-800\">Details</h3>\n <p class=\"mt-2 mb-0 whitespace-pre-wrap text-sm leading-relaxed text-zinc-600\">\n {{ patient().detail }}\n </p>\n </section>\n }\n\n @if (patient().callId) {\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Call</span>\n <a\n [routerLink]=\"['../history', patient().callId]\"\n class=\"text-sm font-medium text-blue-600 no-underline hover:underline\"\n (click)=\"close()\"\n >\n {{ patient().callId }}\n </a>\n </div>\n </section>\n }\n </div>\n </aside>\n</div>\n","import { ChangeDetectionStrategy, Component, OnInit, inject, signal } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\n\nimport { PatientProfileDrawerComponent } from '../../components/patient-profile-drawer/patient-profile-drawer.component';\nimport { TaskDetailDrawerComponent } from '../../components/task-detail-drawer/task-detail-drawer.component';\nimport {\n ActivitiesTab,\n AgentActivity,\n initialsFromName,\n} from '../../models/agent-activity.types';\nimport { TaskItem, TaskStatus } from '../../models/ai-receptionist.types';\nimport { DEFAULT_PAGE_SIZE, totalPages as calcTotalPages } from '../../models/pagination';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { ageFromDob } from '../../utils/call-history-display.util';\nimport { EdsAvatarComponent } from '../../ui/eds-avatar.component';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\n\ntype TabId = ActivitiesTab;\n\nconst TABS: { id: TabId; label: string }[] = [\n { id: 'task_created', label: 'Tasks' },\n { id: 'appointment_booked', label: 'Appointments' },\n { id: 'patient_created', label: 'Registrations' },\n];\n\nconst AVATAR_TONES = ['green', 'amber', 'brand', 'violet', 'rose'] as const;\n\n@Component({\n selector: 'eds-activities-page',\n imports: [\n EdsAvatarComponent,\n EdsButtonComponent,\n EdsIconComponent,\n TaskDetailDrawerComponent,\n PatientProfileDrawerComponent,\n ],\n templateUrl: './activities-page.component.html',\n styleUrl: './activities-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ActivitiesPageComponent implements OnInit {\n private readonly api = inject(AiReceptionistApiService);\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n\n protected readonly tabs = TABS;\n protected readonly pageSize = DEFAULT_PAGE_SIZE;\n protected readonly items = signal<AgentActivity[]>([]);\n protected readonly total = signal(0);\n protected readonly page = signal(1);\n protected readonly activeTab = signal<TabId>('task_created');\n protected readonly callIdFilter = signal<string | null>(null);\n protected readonly loading = signal(true);\n protected readonly loadError = signal<string | null>(null);\n protected readonly selectedTask = signal<TaskItem | null>(null);\n protected readonly selectedPatient = signal<AgentActivity | null>(null);\n\n ngOnInit(): void {\n const callId = this.route.snapshot.queryParamMap.get('callId')?.trim() || null;\n if (callId) this.callIdFilter.set(callId);\n\n const tabParam = (this.route.snapshot.queryParamMap.get('tab') || '').trim().toLowerCase();\n const tabFromQuery = this.tabFromQuery(tabParam);\n if (tabFromQuery) {\n this.activeTab.set(tabFromQuery);\n } else {\n this.activeTab.set('task_created');\n void this.router.navigate([], {\n relativeTo: this.route,\n queryParams: { tab: 'tasks' },\n queryParamsHandling: 'merge',\n replaceUrl: true,\n });\n }\n\n this.load();\n }\n\n protected setTab(tab: TabId): void {\n if (this.activeTab() === tab) return;\n this.activeTab.set(tab);\n this.page.set(1);\n void this.router.navigate([], {\n relativeTo: this.route,\n queryParams: { tab: this.tabQueryValue(tab) },\n queryParamsHandling: 'merge',\n replaceUrl: true,\n });\n this.load();\n }\n\n private tabFromQuery(raw: string): TabId | null {\n switch (raw) {\n case 'tasks':\n case 'task':\n case 'task_created':\n return 'task_created';\n case 'appointments':\n case 'appointment':\n case 'appointment_booked':\n return 'appointment_booked';\n case 'registrations':\n case 'registration':\n case 'patient_created':\n return 'patient_created';\n default:\n return null;\n }\n }\n\n private tabQueryValue(tab: TabId): string {\n switch (tab) {\n case 'task_created':\n return 'tasks';\n case 'patient_created':\n return 'registrations';\n default:\n return 'appointments';\n }\n }\n\n protected clearCallFilter(): void {\n this.callIdFilter.set(null);\n this.page.set(1);\n this.load();\n }\n\n protected load(): void {\n this.loading.set(true);\n this.loadError.set(null);\n const tab = this.activeTab();\n this.api\n .getActivities({\n page: this.page(),\n limit: DEFAULT_PAGE_SIZE,\n types: tab,\n callId: this.callIdFilter() || undefined,\n })\n .subscribe({\n next: ({ items, total, page }) => {\n this.items.set(items);\n this.total.set(total);\n this.page.set(page);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.items.set([]);\n this.total.set(0);\n this.loadError.set(\n 'Activities feed is unavailable. Confirm GET /api/ai-receptionist/activities is deployed.',\n );\n },\n });\n }\n\n protected totalPages(): number {\n return calcTotalPages(this.total(), DEFAULT_PAGE_SIZE);\n }\n\n protected prevPage(): void {\n if (this.page() <= 1) return;\n this.page.update((p) => p - 1);\n this.load();\n }\n\n protected nextPage(): void {\n if (this.page() >= this.totalPages()) return;\n this.page.update((p) => p + 1);\n this.load();\n }\n\n protected historyLink(callId: string | null | undefined): string[] | null {\n return callId ? ['../history', callId] : null;\n }\n\n protected openCallHistory(callId: string | null | undefined, ev?: Event): void {\n if (!callId) return;\n if (ev && (ev.target as HTMLElement).closest('a,button')) return;\n void this.router.navigate(['../history', callId], { relativeTo: this.route });\n }\n\n protected openTask(item: AgentActivity): void {\n this.selectedPatient.set(null);\n this.selectedTask.set(this.activityToTask(item));\n }\n\n protected openPatient(item: AgentActivity): void {\n this.selectedTask.set(null);\n this.selectedPatient.set(item);\n }\n\n protected closeTaskDrawer(): void {\n this.selectedTask.set(null);\n }\n\n protected closePatientDrawer(): void {\n this.selectedPatient.set(null);\n }\n\n protected onTaskStatusChange(status: TaskStatus): void {\n const task = this.selectedTask();\n if (!task) return;\n this.api.patchTask(task.id, status).subscribe({\n next: ({ data }) => {\n if (data) {\n this.selectedTask.set(data);\n } else {\n this.selectedTask.set({ ...task, status });\n }\n },\n error: () => {\n // Optimistic local update if patch fails (activity-sourced ids may not exist).\n this.selectedTask.set({ ...task, status });\n },\n });\n }\n\n private activityToTask(item: AgentActivity): TaskItem {\n const priority =\n item.priority === 'urgent' || item.priority === 'high' ? 'urgent' : 'normal';\n const created = this.parseDate(item.occurredAt)?.getTime() ?? Date.now();\n return {\n id: item.taskId || item.id,\n created,\n title: this.taskTitle(item),\n type: 'task',\n description: item.detail || '',\n patient: item.patientName || 'Unknown caller',\n priority,\n status: 'open',\n source: 'voice',\n assignee: 'AI Receptionist',\n callId: item.callId || undefined,\n };\n }\n\n protected displayMrn(item: AgentActivity): string {\n return item.patientMrn?.trim() || '—';\n }\n\n protected providerSpecialtyLabel(item: AgentActivity): string | null {\n const s = item.providerSpecialty?.trim();\n if (!s) return null;\n // Hide stray numeric IDs that sometimes land in specialty.\n if (/^\\d+(\\.\\d+)?$/.test(s)) return null;\n return s;\n }\n\n /** Day-anchored stamp — a bare clock time gave no idea which day a row belonged to. */\n protected timestampLabel(item: AgentActivity): string {\n const start = this.parseDate(item.startAt || item.occurredAt);\n if (!start) return '—';\n const stamp = `${this.formatDay(start)}, ${this.formatClock(start)}`;\n const end = this.parseDate(item.endAt);\n if (end && end.getTime() > start.getTime()) {\n return `${stamp} – ${this.formatClock(end)}`;\n }\n return stamp;\n }\n\n protected durationLabel(item: AgentActivity): string | null {\n const mins = item.durationMinutes;\n if (mins == null || mins <= 0) {\n if (item.startAt && item.endAt) {\n const ms = Date.parse(item.endAt) - Date.parse(item.startAt);\n if (Number.isFinite(ms) && ms > 0) {\n return `${Math.round(ms / 60000)} MIN`;\n }\n }\n return null;\n }\n return `${mins} MIN`;\n }\n\n protected categoryLabel(item: AgentActivity): string {\n if (item.visitType) return item.visitType;\n switch (item.type) {\n case 'appointment_booked':\n return 'Appointment';\n case 'patient_created':\n return 'Registration';\n case 'task_created':\n return item.title && !/^task created$/i.test(item.title) ? item.title : 'Task';\n default:\n return item.title || 'Activity';\n }\n }\n\n protected patientMeta(item: AgentActivity): string | null {\n const parts: string[] = [];\n const dob = item.patientDob;\n const age = item.patientAge ?? (dob ? ageFromDob(dob) : null);\n if (dob && age != null) parts.push(`DOB: ${this.formatDob(dob)} · ${age}Y`);\n else if (dob) parts.push(`DOB: ${this.formatDob(dob)}`);\n else if (age != null) parts.push(`${age}Y`);\n if (item.patientGender) parts.push(item.patientGender);\n return parts.length ? parts.join(' | ') : null;\n }\n\n protected patientInitials(item: AgentActivity): string {\n return item.patientInitials || initialsFromName(item.patientName) || '?';\n }\n\n protected providerInitials(item: AgentActivity): string {\n return item.providerInitials || initialsFromName(item.providerName) || '?';\n }\n\n protected avatarTone(key: string | null | undefined, salt: number): string {\n const raw = `${key || 'x'}:${salt}`;\n let hash = 0;\n for (let i = 0; i < raw.length; i++) hash = (hash + raw.charCodeAt(i) * (i + 1)) % 997;\n return AVATAR_TONES[hash % AVATAR_TONES.length];\n }\n\n protected insuranceState(item: AgentActivity): 'covered' | 'none' | 'unknown' {\n if (item.hasInsurance === true) return 'covered';\n if (item.hasInsurance === false) return 'none';\n return 'unknown';\n }\n\n protected insuranceIcon(item: AgentActivity): string {\n switch (this.insuranceState(item)) {\n case 'covered':\n return 'verified_user';\n case 'none':\n return 'gpp_bad';\n default:\n return 'gpp_maybe';\n }\n }\n\n protected insuranceLabel(item: AgentActivity): string {\n switch (this.insuranceState(item)) {\n case 'covered':\n return 'Insured';\n case 'none':\n return 'No insurance';\n default:\n return 'Unverified';\n }\n }\n\n protected insuranceTitle(item: AgentActivity): string {\n switch (this.insuranceState(item)) {\n case 'covered':\n return item.insuranceName ? `Insured — ${item.insuranceName}` : 'Insured';\n case 'none':\n return 'No insurance on file';\n default:\n return 'Insurance not verified';\n }\n }\n\n protected isTaskRow(item: AgentActivity): boolean {\n return item.type === 'task_created';\n }\n\n protected taskTitle(item: AgentActivity): string {\n const title = (item.title || '').trim();\n if (title && !/^task created$/i.test(title)) return title;\n return item.visitType || 'Task';\n }\n\n protected priorityLabel(item: AgentActivity): string {\n switch (item.priority) {\n case 'urgent':\n return 'Urgent';\n case 'high':\n return 'High';\n case 'low':\n return 'Low';\n case 'medium':\n case 'normal':\n default:\n return 'Medium';\n }\n }\n\n protected priorityTone(item: AgentActivity): string {\n switch (item.priority) {\n case 'urgent':\n return 'urgent';\n case 'high':\n return 'high';\n case 'low':\n return 'low';\n default:\n return 'medium';\n }\n }\n\n protected isRegistrationTab(): boolean {\n return this.activeTab() === 'patient_created';\n }\n\n protected emptyLabel(): string {\n if (this.callIdFilter()) return 'No activities found for this call.';\n switch (this.activeTab()) {\n case 'task_created':\n return 'No tasks created by the AI yet.';\n case 'patient_created':\n return 'No patient registrations yet.';\n default:\n return 'No appointments booked by the AI yet.';\n }\n }\n\n private parseDate(iso: string | null | undefined): Date | null {\n if (!iso) return null;\n const d = new Date(iso);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n\n private formatDay(d: Date): string {\n const midnight = (x: Date) => new Date(x.getFullYear(), x.getMonth(), x.getDate()).getTime();\n const now = new Date();\n const days = Math.round((midnight(d) - midnight(now)) / 86_400_000);\n if (days === 0) return 'Today';\n if (days === 1) return 'Tomorrow';\n if (days === -1) return 'Yesterday';\n return d.toLocaleDateString(\n undefined,\n d.getFullYear() === now.getFullYear()\n ? { weekday: 'short', month: 'short', day: 'numeric' }\n : { month: 'short', day: 'numeric', year: 'numeric' },\n );\n }\n\n private formatClock(d: Date): string {\n return d.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n }\n\n private formatDob(iso: string): string {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(iso.trim());\n if (m) return `${m[2]}-${m[3]}-${m[1]}`;\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n const mm = String(d.getMonth() + 1).padStart(2, '0');\n const dd = String(d.getDate()).padStart(2, '0');\n return `${mm}-${dd}-${d.getFullYear()}`;\n }\n}\n","<div class=\"eds-page activities-page\">\n <header class=\"mb-5\">\n <div>\n <h1 class=\"eds-h1\">Activities</h1>\n <p class=\"eds-body-sm\">Review all the activities done by the AI at one place</p>\n </div>\n </header>\n\n @if (callIdFilter(); as callId) {\n <div\n class=\"mb-4 flex flex-wrap items-center justify-between gap-3 rounded-lg bg-blue-50 px-4 py-3 text-sm font-normal leading-snug text-zinc-600\"\n role=\"status\"\n >\n <span>Showing activities for call <strong class=\"font-medium text-zinc-700\">{{ callId }}</strong></span>\n <button\n type=\"button\"\n class=\"cursor-pointer border-none bg-transparent px-0 py-1 text-sm font-medium text-blue-600 hover:underline\"\n (click)=\"clearCallFilter()\"\n >\n Clear filter\n </button>\n </div>\n }\n\n <nav class=\"mb-5 flex flex-wrap gap-2\" aria-label=\"Activity type\">\n @for (tab of tabs; track tab.id) {\n <button\n type=\"button\"\n [class]=\"\n activeTab() === tab.id\n ? 'cursor-pointer rounded-full border-none bg-blue-50 px-4 py-2 text-sm font-medium text-blue-600 transition-colors'\n : 'cursor-pointer rounded-full border-none bg-transparent px-4 py-2 text-sm font-medium text-zinc-500 transition-colors hover:bg-white hover:text-zinc-700'\n \"\n (click)=\"setTab(tab.id)\"\n >\n {{ tab.label }}\n </button>\n }\n </nav>\n\n @if (loading()) {\n <p class=\"eds-body-sm\">Loading activities…</p>\n } @else if (loadError()) {\n <p class=\"text-sm text-red-700\" role=\"alert\">{{ loadError() }}</p>\n } @else {\n @if (activeTab() === 'task_created') {\n <div\n class=\"activities-page__col-head activities-page__col-head--tasks grid gap-x-7 gap-y-4 pb-2 text-sm font-semibold leading-tight text-zinc-600 max-lg:hidden\"\n aria-hidden=\"true\"\n >\n <span>Priority</span>\n <span>Task</span>\n <span>Patient / Caller</span>\n </div>\n } @else if (activeTab() === 'appointment_booked') {\n <div\n class=\"activities-page__col-head activities-page__col-head--appointments grid gap-x-7 gap-y-4 pb-2 text-sm font-semibold leading-tight text-zinc-600 max-lg:hidden\"\n aria-hidden=\"true\"\n >\n <span>When</span>\n <span>Patient</span>\n <span>Provider</span>\n <span class=\"justify-self-end text-right\">Insurance</span>\n </div>\n } @else if (activeTab() === 'patient_created') {\n <div\n class=\"activities-page__col-head activities-page__col-head--registration grid gap-x-7 gap-y-4 pb-2 text-sm font-semibold leading-tight text-zinc-600 max-lg:hidden\"\n aria-hidden=\"true\"\n >\n <span>When</span>\n <span>Patient</span>\n <span>MRN</span>\n <span class=\"justify-self-end text-right\">Insurance</span>\n </div>\n }\n\n <ul class=\"m-0 flex list-none flex-col gap-3 p-0\">\n @for (item of items(); track item.id; let i = $index) {\n @if (isTaskRow(item)) {\n <li\n class=\"activities-page__card activities-page__card--task grid cursor-pointer items-center gap-x-7 gap-y-4 rounded-xl border border-zinc-200 bg-white px-4 py-4 max-lg:gap-x-4 max-lg:gap-y-4 hover:border-blue-200 hover:shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'View task: ' + taskTitle(item)\"\n (click)=\"openTask(item)\"\n (keyup.enter)=\"openTask(item)\"\n >\n <div class=\"inline-flex items-center gap-2 text-sm font-medium leading-snug text-zinc-700\" [attr.data-tone]=\"priorityTone(item)\">\n <span class=\"activities-page__priority-mark h-2.5 w-2.5 shrink-0 rotate-45 rounded-sm\" aria-hidden=\"true\"></span>\n <span class=\"capitalize\">{{ priorityLabel(item) }}</span>\n </div>\n\n <div class=\"text-sm font-medium leading-snug text-zinc-700 max-lg:col-span-full\">{{ taskTitle(item) }}</div>\n\n <div class=\"flex min-w-0 items-center gap-3 max-lg:col-span-full\">\n <eds-avatar\n shape=\"box\"\n [initials]=\"patientInitials(item)\"\n [tone]=\"avatarTone(item.patientId || item.patientName || item.id, i)\"\n />\n <div class=\"flex min-w-0 flex-col gap-1\">\n <span class=\"truncate text-sm font-medium leading-snug text-zinc-700\">{{ item.patientName || 'Unknown caller' }}</span>\n @if (patientMeta(item); as meta) {\n <span class=\"truncate text-xs leading-snug text-zinc-500\">{{ meta }}</span>\n }\n </div>\n </div>\n </li>\n } @else if (isRegistrationTab()) {\n <li\n class=\"activities-page__card activities-page__card--registration grid cursor-pointer items-center gap-x-7 gap-y-4 rounded-xl border border-zinc-200 bg-white px-4 py-4 max-lg:gap-x-4 max-lg:gap-y-4 hover:border-blue-200 hover:shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"'View patient: ' + (item.patientName || 'Unknown patient')\"\n (click)=\"openPatient(item)\"\n (keyup.enter)=\"openPatient(item)\"\n >\n <div class=\"min-w-0\">\n <div class=\"mb-1 flex flex-wrap items-center gap-2\">\n <span class=\"whitespace-nowrap text-base font-medium leading-snug text-zinc-700 max-md:whitespace-normal\">{{ timestampLabel(item) }}</span>\n </div>\n <p class=\"m-0 text-sm leading-snug text-zinc-500\">{{ categoryLabel(item) }}</p>\n </div>\n\n <div class=\"flex min-w-0 items-center gap-3 max-lg:col-span-full\">\n <eds-avatar\n shape=\"box\"\n [initials]=\"patientInitials(item)\"\n [tone]=\"avatarTone(item.patientId || item.patientName || item.id, i)\"\n />\n <div class=\"flex min-w-0 flex-col gap-1\">\n <span class=\"truncate text-sm font-medium leading-snug text-zinc-700\">{{ item.patientName || 'Unknown patient' }}</span>\n @if (patientMeta(item); as meta) {\n <span class=\"truncate text-xs leading-snug text-zinc-500\">{{ meta }}</span>\n }\n </div>\n </div>\n\n <div class=\"text-sm font-normal leading-snug text-zinc-600\">{{ displayMrn(item) }}</div>\n\n <div class=\"flex items-center justify-end gap-2.5\">\n <span\n class=\"activities-page__insurance inline-flex h-8 w-8 items-center justify-center rounded-full border border-transparent max-md:px-1.5\"\n [attr.data-state]=\"insuranceState(item)\"\n [title]=\"insuranceTitle(item)\"\n [attr.aria-label]=\"insuranceLabel(item)\"\n >\n <eds-icon [name]=\"insuranceIcon(item)\" [size]=\"18\" />\n </span>\n </div>\n </li>\n } @else {\n <li\n [class]=\"\n 'activities-page__card grid items-center gap-x-7 gap-y-4 rounded-xl border border-zinc-200 bg-white px-4 py-4 max-lg:gap-x-4 max-lg:gap-y-4' +\n (item.callId\n ? ' cursor-pointer hover:border-blue-200 hover:shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600'\n : '')\n \"\n [attr.role]=\"item.callId ? 'link' : null\"\n [attr.tabindex]=\"item.callId ? 0 : null\"\n (click)=\"openCallHistory(item.callId, $event)\"\n (keyup.enter)=\"openCallHistory(item.callId)\"\n >\n <div class=\"min-w-0\">\n <div class=\"mb-1 flex flex-wrap items-center gap-2\">\n <span class=\"whitespace-nowrap text-base font-medium leading-snug text-zinc-700 max-md:whitespace-normal\">{{ timestampLabel(item) }}</span>\n </div>\n <p class=\"m-0 text-sm leading-snug text-zinc-500\">{{ categoryLabel(item) }}</p>\n </div>\n\n <div class=\"flex min-w-0 items-center gap-3 max-lg:col-span-full\">\n <eds-avatar\n shape=\"box\"\n [initials]=\"patientInitials(item)\"\n [tone]=\"avatarTone(item.patientId || item.patientName || item.id, i)\"\n />\n <div class=\"flex min-w-0 flex-col gap-1\">\n <span class=\"truncate text-sm font-medium leading-snug text-zinc-700\">{{ item.patientName || 'Unknown patient' }}</span>\n @if (patientMeta(item); as meta) {\n <span class=\"truncate text-xs leading-snug text-zinc-500\">{{ meta }}</span>\n }\n </div>\n </div>\n\n <div class=\"flex min-w-0 items-center gap-3 max-lg:col-span-full\">\n @if (item.providerName) {\n <eds-avatar\n shape=\"circle\"\n [initials]=\"providerInitials(item)\"\n [tone]=\"avatarTone(item.providerId || item.providerName, i + 3)\"\n />\n <div class=\"flex min-w-0 flex-col gap-1\">\n <span class=\"truncate text-sm font-medium leading-snug text-zinc-700\">{{ item.providerName }}</span>\n @if (providerSpecialtyLabel(item); as specialty) {\n <span class=\"truncate text-xs leading-snug text-zinc-500\">{{ specialty }}</span>\n }\n </div>\n } @else {\n <div class=\"flex min-h-9 items-center\">\n <span class=\"truncate text-xs leading-snug text-zinc-500\">No provider assigned</span>\n </div>\n }\n </div>\n\n <div class=\"flex items-center justify-end gap-3\">\n <span\n class=\"activities-page__insurance inline-flex h-8 w-8 items-center justify-center rounded-full border border-transparent max-md:px-2\"\n [attr.data-state]=\"insuranceState(item)\"\n [title]=\"insuranceTitle(item)\"\n [attr.aria-label]=\"insuranceLabel(item)\"\n >\n <eds-icon [name]=\"insuranceIcon(item)\" [size]=\"18\" />\n </span>\n </div>\n </li>\n }\n } @empty {\n <li class=\"rounded-xl border border-dashed border-zinc-200 bg-white px-4 py-10 text-center text-sm leading-snug text-zinc-500\">\n {{ emptyLabel() }}\n </li>\n }\n </ul>\n\n @if (total() > pageSize) {\n <footer class=\"mt-4 flex flex-wrap items-center justify-between gap-3\">\n <span class=\"eds-body-sm\">\n Page {{ page() }} of {{ totalPages() }} · {{ total() }} total\n </span>\n <div class=\"flex gap-2\">\n <eds-button variant=\"secondary\" [disabled]=\"page() <= 1\" (click)=\"prevPage()\">Previous</eds-button>\n <eds-button variant=\"secondary\" [disabled]=\"page() >= totalPages()\" (click)=\"nextPage()\">Next</eds-button>\n </div>\n </footer>\n }\n }\n</div>\n\n@if (selectedTask(); as task) {\n <eds-task-detail-drawer\n [task]=\"task\"\n (closed)=\"closeTaskDrawer()\"\n (statusChange)=\"onTaskStatusChange($event)\"\n />\n}\n\n@if (selectedPatient(); as patient) {\n <eds-patient-profile-drawer\n [patient]=\"patient\"\n (closed)=\"closePatientDrawer()\"\n />\n}\n"],"names":["calcTotalPages"],"mappings":"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"}
|
|
@@ -1070,15 +1070,32 @@ function mapSettingsResponse(body, safetyBody) {
|
|
|
1070
1070
|
knowledge: normalizeKnowledgeSection(section('knowledgeBase')),
|
|
1071
1071
|
safety,
|
|
1072
1072
|
transcripts: normalizeTranscriptsSection(section('transcriptsRecording')),
|
|
1073
|
-
advanced: section('advanced'),
|
|
1073
|
+
advanced: normalizeAdvancedSection(section('advanced')),
|
|
1074
1074
|
};
|
|
1075
1075
|
mapped.effectiveWelcomeMessage =
|
|
1076
1076
|
raw.effectiveWelcomeMessage ?? computeEffectiveWelcomeMessage(mapped);
|
|
1077
|
+
const root = body;
|
|
1078
|
+
mapped.effectiveVoiceSystemPrompt = String(root['effectiveVoiceSystemPrompt'] ??
|
|
1079
|
+
root['effective_voice_system_prompt'] ??
|
|
1080
|
+
mapped.advanced['voiceSystemPrompt'] ??
|
|
1081
|
+
'');
|
|
1082
|
+
const usingDefaultRaw = root['usingDefaultVoiceSystemPrompt'] ?? root['using_default_voice_system_prompt'];
|
|
1083
|
+
mapped.usingDefaultVoiceSystemPrompt =
|
|
1084
|
+
typeof usingDefaultRaw === 'boolean'
|
|
1085
|
+
? usingDefaultRaw
|
|
1086
|
+
: !String(mapped.advanced['voiceSystemPrompt'] ?? '').trim();
|
|
1077
1087
|
if (!mapped.knowledge) {
|
|
1078
1088
|
mapped.knowledge = { whatToSay: '', whatNotToSay: '' };
|
|
1079
1089
|
}
|
|
1080
1090
|
return mapped;
|
|
1081
1091
|
}
|
|
1092
|
+
function normalizeAdvancedSection(raw) {
|
|
1093
|
+
return {
|
|
1094
|
+
...raw,
|
|
1095
|
+
voiceSystemPrompt: String(raw['voiceSystemPrompt'] ?? raw['voice_system_prompt'] ?? ''),
|
|
1096
|
+
customVoiceInstructions: String(raw['customVoiceInstructions'] ?? raw['custom_voice_instructions'] ?? ''),
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1082
1099
|
function normalizeKnowledgeSection(raw) {
|
|
1083
1100
|
return {
|
|
1084
1101
|
...raw,
|
|
@@ -1212,6 +1229,7 @@ const now$2 = Date.now();
|
|
|
1212
1229
|
function item(partial) {
|
|
1213
1230
|
return {
|
|
1214
1231
|
callId: 'LC-4821',
|
|
1232
|
+
clientPracticeId: 'practice-demo',
|
|
1215
1233
|
method: 'POST',
|
|
1216
1234
|
urlPath: '/api/v1/patients/search',
|
|
1217
1235
|
statusCode: 200,
|
|
@@ -1906,7 +1924,12 @@ const SEED_SETTINGS = {
|
|
|
1906
1924
|
retainDays: 30,
|
|
1907
1925
|
redactPhi: true,
|
|
1908
1926
|
},
|
|
1909
|
-
advanced: {
|
|
1927
|
+
advanced: {
|
|
1928
|
+
modelVersion: 'edvak-v2',
|
|
1929
|
+
debugMode: false,
|
|
1930
|
+
voiceSystemPrompt: '',
|
|
1931
|
+
customVoiceInstructions: '',
|
|
1932
|
+
},
|
|
1910
1933
|
effectiveWelcomeMessage: 'Thanks for calling Riverside Family Medicine! This is Robin, the practice’s virtual assistant. How can I help you today?',
|
|
1911
1934
|
};
|
|
1912
1935
|
const SEED_SETUP = {
|
|
@@ -2509,6 +2532,14 @@ class AiReceptionistApiMockService {
|
|
|
2509
2532
|
this.settings.set(saved);
|
|
2510
2533
|
return this.mock(saved);
|
|
2511
2534
|
}
|
|
2535
|
+
getVoicePromptDefault() {
|
|
2536
|
+
return of({
|
|
2537
|
+
defaultVoiceSystemPrompt: 'You are an AI receptionist for a medical practice. Be warm, concise, and HIPAA-aware.',
|
|
2538
|
+
voiceSystemPromptMaxLength: 24000,
|
|
2539
|
+
customVoiceInstructionsMaxLength: 8000,
|
|
2540
|
+
notes: 'Leave voiceSystemPrompt empty to use this shipped default.',
|
|
2541
|
+
}).pipe(delay(MOCK_DELAY_MS));
|
|
2542
|
+
}
|
|
2512
2543
|
previewVoice(_voiceId) {
|
|
2513
2544
|
// Silent tiny wav so mock mode does not break the Play button.
|
|
2514
2545
|
const silent = new Uint8Array([
|
|
@@ -2631,12 +2662,21 @@ class AiReceptionistApiMockService {
|
|
|
2631
2662
|
const to = Date.parse(filters.to);
|
|
2632
2663
|
rows = rows.filter((r) => Date.parse(r.startedAt) <= to);
|
|
2633
2664
|
}
|
|
2634
|
-
|
|
2665
|
+
if (filters.practiceId) {
|
|
2666
|
+
rows = rows.filter((r) => (r.clientPracticeId ?? '') === filters.practiceId);
|
|
2667
|
+
}
|
|
2668
|
+
rows = [...rows].sort((a, b) => Date.parse(b.startedAt) - Date.parse(a.startedAt));
|
|
2635
2669
|
const page = filters.page ?? 1;
|
|
2636
2670
|
const limit = filters.limit ?? 50;
|
|
2637
2671
|
const start = (page - 1) * limit;
|
|
2638
2672
|
const items = rows.slice(start, start + limit);
|
|
2639
|
-
return of({
|
|
2673
|
+
return of({
|
|
2674
|
+
items,
|
|
2675
|
+
total: rows.length,
|
|
2676
|
+
page,
|
|
2677
|
+
limit,
|
|
2678
|
+
practiceId: filters.practiceId ?? null,
|
|
2679
|
+
}).pipe(delay(MOCK_DELAY_MS));
|
|
2640
2680
|
}
|
|
2641
2681
|
getApiLogDetail(logId) {
|
|
2642
2682
|
const detail = SEED_API_LOG_DETAILS[logId];
|
|
@@ -3150,6 +3190,17 @@ class AiReceptionistApiService {
|
|
|
3150
3190
|
.put(`${this.arBase}/settings`, { settings: mapSettingsToRequest(next) })
|
|
3151
3191
|
.pipe(switchMap(() => this.getSettings()), catchError((err) => throwError(() => new Error(this.apiErrorMessage(err, 'Failed to save agent settings')))));
|
|
3152
3192
|
}
|
|
3193
|
+
/** Shipped default voice system prompt + max lengths. */
|
|
3194
|
+
getVoicePromptDefault() {
|
|
3195
|
+
if (this.useMock)
|
|
3196
|
+
return this.mock.getVoicePromptDefault();
|
|
3197
|
+
return this.http.get(`${this.arBase}/settings/voice-prompt-default`).pipe(map((body) => ({
|
|
3198
|
+
defaultVoiceSystemPrompt: String(body?.defaultVoiceSystemPrompt ?? ''),
|
|
3199
|
+
voiceSystemPromptMaxLength: Number(body?.voiceSystemPromptMaxLength) || 24000,
|
|
3200
|
+
customVoiceInstructionsMaxLength: Number(body?.customVoiceInstructionsMaxLength) || 8000,
|
|
3201
|
+
notes: body?.notes ? String(body.notes) : undefined,
|
|
3202
|
+
})));
|
|
3203
|
+
}
|
|
3153
3204
|
/** ElevenLabs spoken sample for Agent Settings voice picker. */
|
|
3154
3205
|
previewVoice(voiceId) {
|
|
3155
3206
|
if (this.useMock)
|
|
@@ -3294,6 +3345,8 @@ class AiReceptionistApiService {
|
|
|
3294
3345
|
params = params.set('page', String(filters.page));
|
|
3295
3346
|
if (filters.limit != null)
|
|
3296
3347
|
params = params.set('limit', String(filters.limit));
|
|
3348
|
+
if (filters.practiceId)
|
|
3349
|
+
params = params.set('practiceId', filters.practiceId);
|
|
3297
3350
|
return this.http.get(`${this.arBase}/api-logs`, { params });
|
|
3298
3351
|
}
|
|
3299
3352
|
getApiLogDetail(logId) {
|
|
@@ -3304,11 +3357,14 @@ class AiReceptionistApiService {
|
|
|
3304
3357
|
.get(`${this.arBase}/api-logs/${enc}`)
|
|
3305
3358
|
.pipe(map((data) => ({ data })));
|
|
3306
3359
|
}
|
|
3307
|
-
getApiLogStats() {
|
|
3360
|
+
getApiLogStats(practiceId) {
|
|
3308
3361
|
if (this.useMock)
|
|
3309
3362
|
return this.mock.getApiLogStats();
|
|
3363
|
+
let params = new HttpParams();
|
|
3364
|
+
if (practiceId)
|
|
3365
|
+
params = params.set('practiceId', practiceId);
|
|
3310
3366
|
return this.http
|
|
3311
|
-
.get(`${this.arBase}/api-logs/stats
|
|
3367
|
+
.get(`${this.arBase}/api-logs/stats`, { params })
|
|
3312
3368
|
.pipe(map((data) => ({ data })));
|
|
3313
3369
|
}
|
|
3314
3370
|
getOutboundPurposes(includeInactive = false) {
|
|
@@ -3425,5 +3481,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
3425
3481
|
args: [{ providedIn: 'root' }]
|
|
3426
3482
|
}] });
|
|
3427
3483
|
|
|
3428
|
-
export { AiReceptionistApiService as A, DEFAULT_PAGE_SIZE as D, WELCOME_MESSAGE_MAX as W, historyResolutionLabel as a, historyResolution as b, callerMetaLine as c, ageFromDob as d, resolveToolKey as e, resolveToolDisplayName as f,
|
|
3429
|
-
//# sourceMappingURL=edvak99-voice-receptionist-widget-ai-receptionist-api.service-
|
|
3484
|
+
export { AiReceptionistApiService as A, DEFAULT_PAGE_SIZE as D, WELCOME_MESSAGE_MAX as W, historyResolutionLabel as a, historyResolution as b, callerMetaLine as c, ageFromDob as d, resolveToolKey as e, resolveToolDisplayName as f, totalPages as g, historyResultChips as h, isUnknownCaller as i, activityTypeLabel as j, createVoiceReceptionistPaths as k, initialsFromName as l, buildAutoWelcomeTemplate as m, resolveWelcomePreview as n, DEFAULT_PLACEHOLDERS as o, resultChipIcon as r, toolEventTrackKey as t };
|
|
3485
|
+
//# sourceMappingURL=edvak99-voice-receptionist-widget-ai-receptionist-api.service-DcRiHn8q.mjs.map
|