@edvak99/voice-receptionist-widget 1.1.1 → 1.1.2

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 (40) hide show
  1. package/README.md +1 -0
  2. package/fesm2022/{edvak99-voice-receptionist-widget-analytics-page.component-Cg15RZEY.mjs → edvak99-voice-receptionist-widget-analytics-page.component-CW5OKmik.mjs} +2 -2
  3. package/fesm2022/{edvak99-voice-receptionist-widget-analytics-page.component-Cg15RZEY.mjs.map → edvak99-voice-receptionist-widget-analytics-page.component-CW5OKmik.mjs.map} +1 -1
  4. package/fesm2022/{edvak99-voice-receptionist-widget-audit-page.component-DVQyKh_n.mjs → edvak99-voice-receptionist-widget-audit-page.component-DL1GfQyF.mjs} +2 -2
  5. package/fesm2022/{edvak99-voice-receptionist-widget-audit-page.component-DVQyKh_n.mjs.map → edvak99-voice-receptionist-widget-audit-page.component-DL1GfQyF.mjs.map} +1 -1
  6. package/fesm2022/{edvak99-voice-receptionist-widget-call-history-detail-page.component-CbMLabcp.mjs → edvak99-voice-receptionist-widget-call-history-detail-page.component-CTwfUHUf.mjs} +4 -4
  7. package/fesm2022/{edvak99-voice-receptionist-widget-call-history-detail-page.component-CbMLabcp.mjs.map → edvak99-voice-receptionist-widget-call-history-detail-page.component-CTwfUHUf.mjs.map} +1 -1
  8. package/fesm2022/{edvak99-voice-receptionist-widget-call-history-page.component-DfX0pJIR.mjs → edvak99-voice-receptionist-widget-call-history-page.component-Cj4wxd4e.mjs} +3 -3
  9. package/fesm2022/{edvak99-voice-receptionist-widget-call-history-page.component-DfX0pJIR.mjs.map → edvak99-voice-receptionist-widget-call-history-page.component-Cj4wxd4e.mjs.map} +1 -1
  10. package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-BDJmnxUF.mjs → edvak99-voice-receptionist-widget-call-recording-player.component-AN6GcSDq.mjs} +2 -2
  11. package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-BDJmnxUF.mjs.map → edvak99-voice-receptionist-widget-call-recording-player.component-AN6GcSDq.mjs.map} +1 -1
  12. package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-D6P-ojFa.mjs → edvak99-voice-receptionist-widget-call-review.service-Cy_Bf7AO.mjs} +2 -2
  13. package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-D6P-ojFa.mjs.map → edvak99-voice-receptionist-widget-call-review.service-Cy_Bf7AO.mjs.map} +1 -1
  14. package/fesm2022/{edvak99-voice-receptionist-widget-dashboard-page.component-Yr8Fx4Tj.mjs → edvak99-voice-receptionist-widget-dashboard-page.component-DzdIt2A7.mjs} +4 -4
  15. package/fesm2022/{edvak99-voice-receptionist-widget-dashboard-page.component-Yr8Fx4Tj.mjs.map → edvak99-voice-receptionist-widget-dashboard-page.component-DzdIt2A7.mjs.map} +1 -1
  16. package/fesm2022/{edvak99-voice-receptionist-widget-eds-elapsed.pipe-KzX82V6L.mjs → edvak99-voice-receptionist-widget-eds-elapsed.pipe-ouRlPpwT.mjs} +2 -2
  17. package/fesm2022/{edvak99-voice-receptionist-widget-eds-elapsed.pipe-KzX82V6L.mjs.map → edvak99-voice-receptionist-widget-eds-elapsed.pipe-ouRlPpwT.mjs.map} +1 -1
  18. package/fesm2022/{edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-DvJ2Ygc1.mjs → edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-CMhknpGf.mjs} +19 -15
  19. package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-CMhknpGf.mjs.map +1 -0
  20. package/fesm2022/{edvak99-voice-receptionist-widget-knowledge-hub.page-DHFkyA6s.mjs → edvak99-voice-receptionist-widget-knowledge-hub.page-cZqBuull.mjs} +2 -2
  21. package/fesm2022/{edvak99-voice-receptionist-widget-knowledge-hub.page-DHFkyA6s.mjs.map → edvak99-voice-receptionist-widget-knowledge-hub.page-cZqBuull.mjs.map} +1 -1
  22. package/fesm2022/{edvak99-voice-receptionist-widget-live-calls-list.service-D5jeLPo9.mjs → edvak99-voice-receptionist-widget-live-calls-list.service-CDtFRW8w.mjs} +3 -3
  23. package/fesm2022/{edvak99-voice-receptionist-widget-live-calls-list.service-D5jeLPo9.mjs.map → edvak99-voice-receptionist-widget-live-calls-list.service-CDtFRW8w.mjs.map} +1 -1
  24. package/fesm2022/{edvak99-voice-receptionist-widget-live-calls-page.component-Do_-sipd.mjs → edvak99-voice-receptionist-widget-live-calls-page.component-DrYzXJQW.mjs} +4 -4
  25. package/fesm2022/{edvak99-voice-receptionist-widget-live-calls-page.component-Do_-sipd.mjs.map → edvak99-voice-receptionist-widget-live-calls-page.component-DrYzXJQW.mjs.map} +1 -1
  26. package/fesm2022/{edvak99-voice-receptionist-widget-live-monitor-page.component-pTwlznGI.mjs → edvak99-voice-receptionist-widget-live-monitor-page.component-D7dlk0y2.mjs} +4 -4
  27. package/fesm2022/{edvak99-voice-receptionist-widget-live-monitor-page.component-pTwlznGI.mjs.map → edvak99-voice-receptionist-widget-live-monitor-page.component-D7dlk0y2.mjs.map} +1 -1
  28. package/fesm2022/{edvak99-voice-receptionist-widget-outbound-purposes-page.component-CteOwr16.mjs → edvak99-voice-receptionist-widget-outbound-purposes-page.component-CJ8NEjcj.mjs} +2 -2
  29. package/fesm2022/{edvak99-voice-receptionist-widget-outbound-purposes-page.component-CteOwr16.mjs.map → edvak99-voice-receptionist-widget-outbound-purposes-page.component-CJ8NEjcj.mjs.map} +1 -1
  30. package/fesm2022/{edvak99-voice-receptionist-widget-settings-page.component-k-1Z4CXg.mjs → edvak99-voice-receptionist-widget-settings-page.component-Bo3XNK3b.mjs} +2 -2
  31. package/fesm2022/{edvak99-voice-receptionist-widget-settings-page.component-k-1Z4CXg.mjs.map → edvak99-voice-receptionist-widget-settings-page.component-Bo3XNK3b.mjs.map} +1 -1
  32. package/fesm2022/{edvak99-voice-receptionist-widget-tasks-page.component-BgL50G-i.mjs → edvak99-voice-receptionist-widget-tasks-page.component-CBwl15NP.mjs} +2 -2
  33. package/fesm2022/{edvak99-voice-receptionist-widget-tasks-page.component-BgL50G-i.mjs.map → edvak99-voice-receptionist-widget-tasks-page.component-CBwl15NP.mjs.map} +1 -1
  34. package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-BOEnzklB.mjs → edvak99-voice-receptionist-widget-wizard-page.component-CJLa5pia.mjs} +2 -2
  35. package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-BOEnzklB.mjs.map → edvak99-voice-receptionist-widget-wizard-page.component-CJLa5pia.mjs.map} +1 -1
  36. package/fesm2022/edvak99-voice-receptionist-widget.mjs +1 -1
  37. package/lib/config.d.ts +5 -0
  38. package/lib/layout/eds-app-shell.component.d.ts +2 -0
  39. package/package.json +1 -1
  40. package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-DvJ2Ygc1.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"edvak99-voice-receptionist-widget-live-monitor-page.component-pTwlznGI.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/models/live-transcript.types.ts","../../../projects/voice-receptionist-widget/src/lib/services/live-transcript.service.ts","../../../projects/voice-receptionist-widget/src/lib/ui/eds-waveform.component.ts","../../../projects/voice-receptionist-widget/src/lib/components/live-transcript-panel/live-transcript-panel.component.ts","../../../projects/voice-receptionist-widget/src/lib/components/live-transcript-panel/live-transcript-panel.component.html","../../../projects/voice-receptionist-widget/src/lib/pages/live-monitor-page/live-monitor-page.component.ts","../../../projects/voice-receptionist-widget/src/lib/pages/live-monitor-page/live-monitor-page.component.html"],"sourcesContent":["import { ToolEvent, TranscriptLine } from './ai-receptionist.types';\nimport { resolveToolDisplayName, resolveToolKey } from '../utils/tool-labels.util';\n\n/** Socket.io `new_chunk` payload from /dashboard namespace */\nexport interface TranscriptChunk {\n role: 'user' | 'assistant';\n text: string;\n isFinal: boolean;\n timestamp: string;\n}\n\n/** Socket.io `call_event` payload — tools + lifecycle */\nexport interface CallEventStreamPayload {\n eventType: string;\n occurredAt: string;\n payload: Record<string, unknown>;\n}\n\nexport interface LiveTranscriptState {\n lines: TranscriptLine[];\n patientInterim: string | null;\n aiInterim: string | null;\n connected: boolean;\n error: string | null;\n}\n\nexport function mapChunkToLine(chunk: TranscriptChunk): TranscriptLine {\n const at = Date.parse(chunk.timestamp);\n return {\n who: chunk.role === 'assistant' ? 'ai' : 'patient',\n text: chunk.text,\n at: Number.isFinite(at) ? at : Date.now(),\n };\n}\n\nexport function formatEventTime(iso: string): string {\n return new Date(iso).toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n hour12: false,\n });\n}\n\nexport function mapCallEventToTool(event: CallEventStreamPayload): ToolEvent {\n const p = event.payload;\n const state = p['state'];\n const rawName = String(p['name'] ?? event.eventType.replace(/^tool_/, ''));\n const tech = String(p['tech'] ?? event.eventType);\n const key = resolveToolKey(\n p['key'] != null ? String(p['key']) : undefined,\n rawName,\n tech,\n );\n return {\n t: formatEventTime(event.occurredAt),\n key,\n name: resolveToolDisplayName(key, rawName),\n tech,\n result: String(p['result'] ?? ''),\n state:\n state === 'ok' || state === 'warn' || state === 'error' || state === 'active'\n ? state\n : 'ok',\n };\n}\n\nexport function mapLifecycleEventToTool(event: CallEventStreamPayload): ToolEvent {\n const p = event.payload;\n return {\n t: formatEventTime(event.occurredAt),\n name: event.eventType.replace(/_/g, ' '),\n tech: event.eventType,\n result: String(p['detail'] ?? p['message'] ?? p['result'] ?? ''),\n state: 'ok',\n };\n}\n\nexport function isDuplicateTranscriptLine(lines: TranscriptLine[], line: TranscriptLine): boolean {\n return lines.some((l) => l.who === line.who && l.text.trim() === line.text.trim());\n}\n","import { Injectable, inject, signal } from '@angular/core';\n\nimport { VOICE_RECEPTIONIST_CONFIG } from '../config';\nimport { ToolEvent, TranscriptLine } from '../models/ai-receptionist.types';\nimport {\n CallEventStreamPayload,\n isDuplicateTranscriptLine,\n mapCallEventToTool,\n mapChunkToLine,\n mapLifecycleEventToTool,\n TranscriptChunk,\n} from '../models/live-transcript.types';\nimport { DashboardSocketService } from './dashboard-socket.service';\n\n/**\n * Live call stream over shared Socket.io (`/dashboard` namespace).\n * REST seeds transcript/tools once; socket delivers `new_chunk` + `call_event`.\n */\n@Injectable({ providedIn: 'root' })\nexport class LiveTranscriptService {\n private readonly socket = inject(DashboardSocketService);\n private readonly config = inject(VOICE_RECEPTIONIST_CONFIG);\n\n readonly lines = signal<TranscriptLine[]>([]);\n readonly patientInterim = signal<string | null>(null);\n readonly aiInterim = signal<string | null>(null);\n readonly tools = signal<ToolEvent[]>([]);\n readonly connected = this.socket.connected;\n readonly error = signal<string | null>(null);\n readonly callEnded = signal(false);\n readonly summaryRequested = signal(false);\n\n private activeCallId: string | null = null;\n private watching = false;\n private mockTimer: ReturnType<typeof setInterval> | null = null;\n private mockIndex = 0;\n\n private readonly chunkHandler = (chunk: TranscriptChunk) => this.handleChunk(chunk);\n private readonly eventHandler = (event: CallEventStreamPayload) => this.handleCallEvent(event);\n private readonly onSocketConnect = () => {\n if (this.activeCallId) {\n this.socket.emit('watch_call', { callId: this.activeCallId });\n }\n };\n\n seed(transcript: TranscriptLine[], toolEvents: ToolEvent[]): void {\n this.lines.set(transcript.map((line) => ({ ...line })));\n this.tools.set(toolEvents.map((tool) => ({ ...tool })));\n }\n\n watch(callId: string, live = true): void {\n const id = callId.trim();\n if (!id || !live) return;\n\n const switchingCall = this.activeCallId !== id;\n if (switchingCall) {\n this.unsubscribeSocketEvents();\n this.clearInterim();\n this.callEnded.set(false);\n this.summaryRequested.set(false);\n this.activeCallId = id;\n } else if (this.watching) {\n return;\n }\n\n if (this.config.useMockApi) {\n this.watching = true;\n this.startMockStream(id);\n return;\n }\n\n if (!this.watching) {\n this.socket.acquire();\n this.socket.on('new_chunk', this.chunkHandler);\n this.socket.on('call_event', this.eventHandler);\n this.socket.onConnect(this.onSocketConnect);\n this.watching = true;\n }\n\n if (this.socket.connected()) {\n this.socket.emit('watch_call', { callId: id });\n }\n }\n\n stop(): void {\n this.activeCallId = null;\n this.unsubscribeSocketEvents();\n this.resetStreamState();\n }\n\n markCompleted(): void {\n this.callEnded.set(true);\n this.unsubscribeSocketEvents();\n this.clearInterim();\n }\n\n private unsubscribeSocketEvents(): void {\n this.stopMockStream();\n if (!this.watching) return;\n\n this.socket.off('new_chunk', this.chunkHandler);\n this.socket.off('call_event', this.eventHandler);\n this.socket.offConnect(this.onSocketConnect);\n this.socket.release();\n this.watching = false;\n }\n\n private handleChunk(chunk: TranscriptChunk): void {\n if (!chunk?.text?.trim()) return;\n\n if (chunk.role === 'user') {\n if (chunk.isFinal) {\n this.patientInterim.set(null);\n this.appendLineIfNew(mapChunkToLine(chunk));\n } else {\n this.patientInterim.set(chunk.text);\n }\n return;\n }\n\n if (chunk.isFinal) {\n this.aiInterim.set(null);\n this.appendLineIfNew(mapChunkToLine(chunk));\n } else {\n this.aiInterim.set(chunk.text);\n }\n }\n\n private handleCallEvent(event: CallEventStreamPayload): void {\n if (!event?.eventType) return;\n\n if (event.eventType.startsWith('tool_')) {\n this.tools.update((prev) => [...prev, mapCallEventToTool(event)]);\n return;\n }\n\n if (event.eventType === 'call_completed') {\n this.markCompleted();\n return;\n }\n\n if (event.eventType === 'summary_generated') {\n this.summaryRequested.set(true);\n return;\n }\n\n this.tools.update((prev) => [...prev, mapLifecycleEventToTool(event)]);\n }\n\n private appendLineIfNew(line: TranscriptLine): void {\n this.lines.update((prev) => {\n if (isDuplicateTranscriptLine(prev, line)) return prev;\n return [...prev, line];\n });\n }\n\n private startMockStream(callId: string): void {\n this.stopMockStream();\n this.mockIndex = 0;\n\n const mockChunks: TranscriptChunk[] = [\n {\n role: 'user',\n text: 'Hi, I need to schedule an appointment.',\n isFinal: false,\n timestamp: new Date().toISOString(),\n },\n {\n role: 'user',\n text: 'Hi, I need to schedule an appointment.',\n isFinal: true,\n timestamp: new Date().toISOString(),\n },\n {\n role: 'assistant',\n text: 'Of course — I can help with that. Which provider would you prefer?',\n isFinal: true,\n timestamp: new Date().toISOString(),\n },\n ];\n\n const mockEvents: CallEventStreamPayload[] = [\n {\n eventType: 'tool_check_doctor_availability',\n occurredAt: new Date().toISOString(),\n payload: {\n key: 'check_doctor_availability',\n name: 'Checked Doctor Availability',\n tech: 'tool_check_doctor_availability',\n result: 'Found 3 available time slots',\n state: 'ok',\n },\n },\n ];\n\n this.mockTimer = setInterval(() => {\n if (this.activeCallId !== callId) {\n this.stopMockStream();\n return;\n }\n if (this.mockIndex < mockChunks.length) {\n this.handleChunk(mockChunks[this.mockIndex]);\n this.mockIndex++;\n return;\n }\n if (this.mockIndex === mockChunks.length) {\n this.handleCallEvent(mockEvents[0]);\n this.mockIndex++;\n }\n }, 1500);\n }\n\n private stopMockStream(): void {\n if (this.mockTimer) {\n clearInterval(this.mockTimer);\n this.mockTimer = null;\n }\n }\n\n private clearInterim(): void {\n this.patientInterim.set(null);\n this.aiInterim.set(null);\n }\n\n private resetStreamState(): void {\n this.lines.set([]);\n this.tools.set([]);\n this.clearInterim();\n this.error.set(null);\n this.callEnded.set(false);\n this.summaryRequested.set(false);\n }\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\n@Component({\n selector: 'eds-waveform',\n standalone: true,\n template: `\n <div\n class=\"eds-waveform\"\n [class.eds-waveform--inactive]=\"!active()\"\n [attr.data-tone]=\"tone()\"\n aria-hidden=\"true\"\n >\n @for (i of bars; track i) {\n <span class=\"eds-waveform__bar\" [style.animation-delay.ms]=\"i * 70\"></span>\n }\n </div>\n `,\n styleUrl: './eds-waveform.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class EdsWaveformComponent {\n readonly active = input(true);\n readonly tone = input<'brand' | 'violet'>('brand');\n\n protected readonly bars = Array.from({ length: 28 }, (_, i) => i);\n}\n","import {\n AfterViewChecked,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewChild,\n effect,\n inject,\n input,\n output,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { TranscriptWho } from '../../models/ai-receptionist.types';\nimport { LiveTranscriptService } from '../../services/live-transcript.service';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\nimport { EdsWaveformComponent } from '../../ui/eds-waveform.component';\n\n@Component({\n selector: 'eds-live-transcript-panel',\n imports: [FormsModule, EdsIconComponent, EdsWaveformComponent],\n templateUrl: './live-transcript-panel.component.html',\n styleUrl: './live-transcript-panel.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class LiveTranscriptPanelComponent implements AfterViewChecked {\n readonly live = input(true);\n readonly paused = input(false);\n readonly humanTakeover = input(false);\n readonly showStaffInput = input(false);\n readonly staffMessage = input('');\n readonly staffMessageChange = output<string>();\n readonly sendMessage = output<void>();\n\n private readonly stream = inject(LiveTranscriptService);\n\n @ViewChild('scrollHost') private scrollHost?: ElementRef<HTMLElement>;\n\n protected readonly lines = this.stream.lines;\n protected readonly patientInterim = this.stream.patientInterim;\n protected readonly aiInterim = this.stream.aiInterim;\n protected readonly connected = this.stream.connected;\n protected readonly error = this.stream.error;\n\n private shouldScroll = false;\n\n constructor() {\n effect(() => {\n this.lines();\n this.patientInterim();\n this.aiInterim();\n this.requestScroll();\n });\n }\n\n ngAfterViewChecked(): void {\n if (this.shouldScroll && this.scrollHost) {\n const el = this.scrollHost.nativeElement;\n el.scrollTop = el.scrollHeight;\n this.shouldScroll = false;\n }\n }\n\n protected waveformActive(): boolean {\n return this.live() && this.connected() && !this.paused();\n }\n\n protected waveformTone(): 'brand' | 'violet' {\n return this.humanTakeover() ? 'violet' : 'brand';\n }\n\n protected recLabel(): string {\n if (this.paused()) return 'PAUSED';\n if (this.live() && this.connected()) return 'REC';\n if (this.error()) return 'ERROR';\n return this.live() ? 'CONNECT' : 'LOG';\n }\n\n protected roleLabel(who: TranscriptWho): string {\n switch (who) {\n case 'ai':\n return 'Ava · AI';\n case 'patient':\n return 'Patient';\n case 'staff':\n return 'Staff';\n default:\n return 'System';\n }\n }\n\n protected speakerIcon(who: TranscriptWho): string {\n switch (who) {\n case 'ai':\n return 'graphic_eq';\n case 'staff':\n return 'support_agent';\n case 'patient':\n return 'person';\n default:\n return 'info';\n }\n }\n\n protected systemIcon(flag?: string): string {\n if (flag === 'verify') return 'verified_user';\n if (flag === 'fail' || flag === 'escalate') return 'bolt';\n return 'info';\n }\n\n protected systemClass(flag?: string): string {\n if (flag === 'verify') return 'live-transcript-panel__system--verify';\n if (flag === 'fail' || flag === 'escalate') return 'live-transcript-panel__system--warn';\n return 'live-transcript-panel__system--info';\n }\n\n protected msgClass(who: TranscriptWho): string {\n return `live-transcript-panel__msg--${who}`;\n }\n\n protected avatarClass(who: TranscriptWho): string {\n return `live-transcript-panel__avatar--${who}`;\n }\n\n protected onStaffInput(value: string): void {\n this.staffMessageChange.emit(value);\n }\n\n protected onSend(): void {\n this.sendMessage.emit();\n }\n\n private requestScroll(): void {\n this.shouldScroll = true;\n }\n}\n","<section class=\"live-transcript-panel\" aria-labelledby=\"live-transcript-title\">\n <header class=\"live-transcript-panel__header\">\n <h2 id=\"live-transcript-title\" class=\"live-transcript-panel__title\">Live transcript</h2>\n <div class=\"live-transcript-panel__rec\">\n <eds-waveform [active]=\"waveformActive()\" [tone]=\"waveformTone()\" />\n <span class=\"live-transcript-panel__rec-label\">{{ recLabel() }}</span>\n </div>\n </header>\n\n <div #scrollHost class=\"live-transcript-panel__scroll\" role=\"log\" aria-live=\"polite\">\n @for (line of lines(); track $index) {\n @if (line.who === 'system') {\n <div class=\"live-transcript-panel__system eds-animate-fade-up\" [class]=\"systemClass(line.flag)\">\n <eds-icon [name]=\"systemIcon(line.flag)\" [size]=\"14\" />\n <span>{{ line.text }}</span>\n </div>\n } @else {\n <article class=\"live-transcript-panel__msg eds-animate-fade-up\" [class]=\"msgClass(line.who)\">\n <div class=\"live-transcript-panel__avatar\" [class]=\"avatarClass(line.who)\">\n <eds-icon [name]=\"speakerIcon(line.who)\" [size]=\"16\" />\n </div>\n <div class=\"live-transcript-panel__content\">\n <span class=\"live-transcript-panel__label\">{{ roleLabel(line.who) }}</span>\n <div class=\"live-transcript-panel__bubble\">\n <p>{{ line.text }}</p>\n </div>\n </div>\n </article>\n }\n }\n\n @if (patientInterim(); as interim) {\n <article class=\"live-transcript-panel__msg live-transcript-panel__msg--patient eds-animate-fade-up\">\n <div class=\"live-transcript-panel__avatar live-transcript-panel__avatar--patient\">\n <eds-icon name=\"person\" [size]=\"16\" />\n </div>\n <div class=\"live-transcript-panel__content\">\n <span class=\"live-transcript-panel__label\">Patient · listening</span>\n <div class=\"live-transcript-panel__bubble live-transcript-panel__bubble--interim\">\n <p>{{ interim }}</p>\n </div>\n </div>\n </article>\n }\n\n @if (aiInterim(); as interim) {\n <article class=\"live-transcript-panel__msg live-transcript-panel__msg--ai eds-animate-fade-up\">\n <div class=\"live-transcript-panel__avatar live-transcript-panel__avatar--ai\">\n <eds-icon name=\"graphic_eq\" [size]=\"16\" />\n </div>\n <div class=\"live-transcript-panel__content\">\n <span class=\"live-transcript-panel__label\">Ava · AI</span>\n <div class=\"live-transcript-panel__bubble live-transcript-panel__bubble--interim\">\n <p>{{ interim }}<span class=\"live-transcript-panel__caret\" aria-hidden=\"true\"></span></p>\n </div>\n </div>\n </article>\n }\n\n @if (lines().length === 0 && !patientInterim() && !aiInterim()) {\n <p class=\"live-transcript-panel__empty\">Waiting for conversation…</p>\n }\n </div>\n\n @if (showStaffInput()) {\n <footer class=\"live-transcript-panel__footer\">\n <input\n type=\"text\"\n class=\"live-transcript-panel__input\"\n placeholder=\"Type to speak as staff…\"\n [ngModel]=\"staffMessage()\"\n (ngModelChange)=\"onStaffInput($event)\"\n (keyup.enter)=\"onSend()\"\n />\n <button type=\"button\" class=\"live-transcript-panel__send\" (click)=\"onSend()\">\n <eds-icon name=\"send\" [size]=\"18\" />\n Send\n </button>\n </footer>\n }\n</section>\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n effect,\n inject,\n OnDestroy,\n OnInit,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute, RouterLink } from '@angular/router';\nimport { FormsModule } from '@angular/forms';\n\nimport { LiveTranscriptPanelComponent } from '../../components/live-transcript-panel/live-transcript-panel.component';\nimport { CallRecordingPlayerComponent } from '../../components/call-recording-player/call-recording-player.component';\nimport { LiveCall, Sentiment } from '../../models/ai-receptionist.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { LiveTranscriptService } from '../../services/live-transcript.service';\nimport { toolEventTrackKey } from '../../utils/tool-labels.util';\nimport { EdsElapsedPipe } from '../../pipes/eds-elapsed.pipe';\nimport { EdsAvatarComponent } from '../../ui/eds-avatar.component';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\n\n@Component({\n selector: 'eds-live-monitor-page',\n imports: [\n RouterLink,\n FormsModule,\n EdsAvatarComponent,\n EdsIconComponent,\n EdsElapsedPipe,\n LiveTranscriptPanelComponent,\n CallRecordingPlayerComponent,\n ],\n templateUrl: './live-monitor-page.component.html',\n styleUrl: './live-monitor-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class LiveMonitorPageComponent implements OnInit, OnDestroy {\n private readonly api = inject(AiReceptionistApiService);\n private readonly route = inject(ActivatedRoute);\n private readonly stream = inject(LiveTranscriptService);\n private readonly destroyRef = inject(DestroyRef);\n\n protected readonly call = signal<LiveCall | null>(null);\n protected readonly staffMessage = signal('');\n protected readonly loading = signal(true);\n protected readonly callId = signal('');\n protected readonly summary = signal<string | null>(null);\n protected readonly summaryLoading = signal(false);\n\n protected readonly liveTools = this.stream.tools;\n protected readonly callEnded = this.stream.callEnded;\n\n private summaryLoaded = false;\n\n constructor() {\n effect(() => {\n if (this.stream.callEnded()) {\n this.loadCallMetadataOnce();\n }\n });\n\n effect(() => {\n if (this.stream.summaryRequested() && !this.summaryLoaded) {\n this.loadPostCallSummary();\n }\n });\n }\n\n ngOnInit(): void {\n this.route.paramMap.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((params) => {\n const id = params.get('id') ?? '';\n this.callId.set(id);\n this.loading.set(true);\n this.summary.set(null);\n this.summaryLoaded = false;\n this.stream.stop();\n this.loadCallMetadata();\n });\n }\n\n ngOnDestroy(): void {\n this.stream.stop();\n }\n\n protected isTakeover(): boolean {\n const c = this.call();\n return c?.status === 'takeover' || !!c?.assigned;\n }\n\n protected isPaused(): boolean {\n return !!this.call()?.aiPaused;\n }\n\n protected isLive(): boolean {\n return !!this.call() && !this.callEnded();\n }\n\n protected confidenceLevel(confidence: number): 'high' | 'low' | 'mid' {\n if (confidence >= 70) return 'high';\n if (confidence < 50) return 'low';\n return 'mid';\n }\n\n protected sentimentPercent(sentiment: Sentiment): number {\n const map: Record<Sentiment, number> = {\n calm: 85,\n neutral: 60,\n frustrated: 35,\n urgent: 15,\n };\n return map[sentiment];\n }\n\n protected toolStateClass(state: string): string {\n return `live-monitor-page__tool--${state}`;\n }\n\n protected readonly toolTrackKey = toolEventTrackKey;\n\n protected takeover(): void {\n this.api.postTakeover(this.callId()).subscribe(() => this.refreshMetadata());\n }\n\n protected resumeAi(): void {\n this.api.postResumeAi(this.callId()).subscribe(() => this.refreshMetadata());\n }\n\n protected transfer(): void {\n this.api.postTransfer(this.callId()).subscribe(() => this.refreshMetadata());\n }\n\n protected endCall(): void {\n const id = this.callId();\n this.api.postEnd(id).subscribe(() => {\n this.stream.markCompleted();\n this.loadCallMetadataOnce();\n this.loadPostCallSummary();\n });\n }\n\n protected sendMessage(): void {\n const text = this.staffMessage().trim();\n if (!text) return;\n this.api.postMessage(this.callId(), text).subscribe(() => {\n this.staffMessage.set('');\n this.refreshMetadata();\n });\n }\n\n /** Initial load — seeds transcript/tools from REST, then starts socket. */\n private loadCallMetadata(): void {\n const id = this.callId();\n if (!id) return;\n this.api.getLiveCall(id).subscribe(({ data }) => {\n this.call.set(data);\n this.loading.set(false);\n if (data) {\n this.stream.seed(data.transcript, data.tools);\n if (!this.callEnded()) {\n this.stream.watch(id, true);\n }\n }\n });\n }\n\n /** Metadata-only refresh after staff actions — does not overwrite live transcript/tools. */\n private refreshMetadata(): void {\n const id = this.callId();\n if (!id) return;\n this.api.getLiveCall(id).subscribe(({ data }) => {\n if (data) this.call.set(data);\n });\n }\n\n /** One-time metadata refresh after call ends (no socket). */\n private loadCallMetadataOnce(): void {\n const id = this.callId();\n if (!id) return;\n this.api.getLiveCall(id).subscribe(({ data }) => {\n if (data) {\n this.call.set(data);\n }\n });\n }\n\n private loadPostCallSummary(): void {\n const id = this.callId();\n if (!id || this.summaryLoaded) return;\n this.summaryLoading.set(true);\n this.api.getCallSummary(id).subscribe(({ data }) => {\n this.summaryLoading.set(false);\n this.summaryLoaded = true;\n if (!data) return;\n this.summary.set(data.summary);\n this.stream.seed(data.transcript, data.tools);\n });\n }\n}\n","<div class=\"eds-page eds-page--dark live-monitor-page\">\n @if (loading()) {\n <p class=\"live-monitor-page__loading\">Loading call…</p>\n } @else {\n @if (call(); as c) {\n <header class=\"live-monitor-page__header\">\n <a routerLink=\"../live\" class=\"live-monitor-page__back\" aria-label=\"Back to live calls\">\n <eds-icon name=\"arrow_back\" [size]=\"19\" />\n </a>\n\n <div class=\"live-monitor-page__header-main\">\n <eds-avatar\n [initials]=\"c.initials\"\n tone=\"brand\"\n [gradient]=\"c.matched\"\n [class.live-monitor-page__avatar--ring]=\"c.matched\"\n />\n\n <div class=\"live-monitor-page__caller\">\n <div class=\"live-monitor-page__name-row\">\n <h1 class=\"live-monitor-page__name\">{{ c.name }}</h1>\n <span class=\"live-monitor-page__patient-tag\" [attr.data-kind]=\"c.matched ? 'registered' : 'new'\">\n <eds-icon [name]=\"c.matched ? 'person_check' : 'person_add'\" [size]=\"14\" />\n {{ c.matched ? 'Registered' : 'New' }}\n </span>\n </div>\n <div class=\"live-monitor-page__meta-row\">\n <eds-icon [name]=\"c.direction === 'inbound' ? 'call_received' : 'call_made'\" [size]=\"14\" />\n <span>{{ c.phone }}</span>\n <span class=\"live-monitor-page__sep\">·</span>\n <span>{{ c.reason }}</span>\n </div>\n </div>\n\n <div class=\"live-monitor-page__header-right\">\n <span class=\"live-monitor-page__duration\">\n <span class=\"live-monitor-page__duration-dot\" aria-hidden=\"true\"></span>\n {{ c.started | edsElapsed }}\n </span>\n </div>\n </div>\n </header>\n\n @if (callEnded()) {\n <div class=\"live-monitor-page__completed-banner\" role=\"status\">\n <eds-icon name=\"check_circle\" [size]=\"18\" />\n Call ended\n </div>\n }\n\n <div class=\"live-monitor-page__grid\">\n <div class=\"live-monitor-page__main\">\n <eds-live-transcript-panel\n [live]=\"isLive()\"\n [paused]=\"isPaused()\"\n [humanTakeover]=\"isTakeover()\"\n [showStaffInput]=\"isTakeover() && !callEnded()\"\n [staffMessage]=\"staffMessage()\"\n (staffMessageChange)=\"staffMessage.set($event)\"\n (sendMessage)=\"sendMessage()\"\n />\n\n @if (callEnded()) {\n <section class=\"live-monitor-page__post-call\">\n <div class=\"live-monitor-page__summary\">\n <h2 class=\"live-monitor-page__section-title\">Call summary</h2>\n @if (summaryLoading()) {\n <p class=\"live-monitor-page__muted\">Generating summary…</p>\n } @else if (summary()) {\n <p>{{ summary() }}</p>\n } @else {\n <p class=\"live-monitor-page__muted\">Summary will appear when processing completes.</p>\n }\n </div>\n <eds-call-recording-player [callId]=\"callId()\" />\n </section>\n }\n </div>\n\n <aside class=\"live-monitor-page__sidebar\">\n @if (!callEnded()) {\n <div class=\"live-monitor-page__orb-wrap\" [attr.data-mode]=\"c.status === 'transferring' ? 'transfer' : 'ai'\">\n <span class=\"live-monitor-page__ring live-monitor-page__ring--1\"></span>\n <span class=\"live-monitor-page__ring live-monitor-page__ring--2\"></span>\n <span class=\"live-monitor-page__orb\">\n <eds-icon name=\"smart_toy\" [size]=\"28\" />\n </span>\n <span class=\"live-monitor-page__confidence\" [attr.data-level]=\"confidenceLevel(c.confidence)\">\n AI confidence {{ c.confidence }}%\n </span>\n </div>\n\n <section class=\"live-monitor-page__sidebar-block\">\n <h3 class=\"live-monitor-page__section-title\">Patient sentiment</h3>\n <div class=\"live-monitor-page__sentiment-bar\">\n <span\n class=\"live-monitor-page__sentiment-fill\"\n [style.width.%]=\"sentimentPercent(c.sentiment)\"\n [attr.data-sentiment]=\"c.sentiment\"\n ></span>\n </div>\n <span class=\"live-monitor-page__sentiment-label\">{{ c.sentiment }}</span>\n </section>\n }\n\n <section class=\"live-monitor-page__sidebar-block\">\n <h3 class=\"live-monitor-page__section-title\">Tools used</h3>\n <ul class=\"live-monitor-page__tools\">\n @for (tool of liveTools(); track toolTrackKey(tool, $index)) {\n <li [class]=\"toolStateClass(tool.state)\">\n <span class=\"live-monitor-page__tool-time\">{{ tool.t }}</span>\n <div class=\"live-monitor-page__tool-body\">\n <span class=\"live-monitor-page__tool-name\">{{ tool.name }}</span>\n <span class=\"live-monitor-page__tool-result\">{{ tool.result }}</span>\n </div>\n @if (tool.state === 'active') {\n <eds-icon name=\"sync\" [size]=\"16\" class=\"live-monitor-page__tool-spin\" />\n }\n </li>\n } @empty {\n <li class=\"live-monitor-page__tools-empty\">No tool activity yet.</li>\n }\n </ul>\n </section>\n\n <section class=\"live-monitor-page__sidebar-block\">\n <h3 class=\"live-monitor-page__section-title\">Goal</h3>\n <p class=\"live-monitor-page__goal\">{{ c.goal }}</p>\n </section>\n </aside>\n </div>\n\n @if (!callEnded()) {\n <footer class=\"live-monitor-page__control-bar\">\n <div class=\"live-monitor-page__control-group\">\n @if (isTakeover()) {\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--violet\" (click)=\"resumeAi()\">\n <eds-icon name=\"smart_toy\" [size]=\"18\" /> Resume AI\n </button>\n } @else {\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--primary\" (click)=\"takeover()\">\n <eds-icon name=\"pan_tool_alt\" [size]=\"18\" /> Take over\n </button>\n }\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--neutral\" disabled title=\"Coming soon\">\n <eds-icon name=\"hearing\" [size]=\"18\" /> Listen\n </button>\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--neutral\" (click)=\"transfer()\">\n <eds-icon name=\"phone_forwarded\" [size]=\"18\" /> Transfer\n </button>\n </div>\n\n <span class=\"live-monitor-page__divider\" aria-hidden=\"true\"></span>\n\n <div class=\"live-monitor-page__control-group\">\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--neutral\" disabled title=\"Coming soon\">\n <eds-icon name=\"person_search\" [size]=\"18\" /> Open chart\n </button>\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--neutral\" disabled title=\"Coming soon\">\n <eds-icon name=\"add_task\" [size]=\"18\" /> Create task\n </button>\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--neutral\" disabled title=\"Coming soon\">\n <eds-icon name=\"edit_note\" [size]=\"18\" /> Add note\n </button>\n </div>\n\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--danger\" (click)=\"endCall()\">\n <eds-icon name=\"call_end\" [size]=\"18\" /> End call\n </button>\n </footer>\n }\n } @else {\n <p class=\"live-monitor-page__loading\">Call ended or not found.</p>\n }\n }\n</div>\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"edvak99-voice-receptionist-widget-live-monitor-page.component-D7dlk0y2.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/models/live-transcript.types.ts","../../../projects/voice-receptionist-widget/src/lib/services/live-transcript.service.ts","../../../projects/voice-receptionist-widget/src/lib/ui/eds-waveform.component.ts","../../../projects/voice-receptionist-widget/src/lib/components/live-transcript-panel/live-transcript-panel.component.ts","../../../projects/voice-receptionist-widget/src/lib/components/live-transcript-panel/live-transcript-panel.component.html","../../../projects/voice-receptionist-widget/src/lib/pages/live-monitor-page/live-monitor-page.component.ts","../../../projects/voice-receptionist-widget/src/lib/pages/live-monitor-page/live-monitor-page.component.html"],"sourcesContent":["import { ToolEvent, TranscriptLine } from './ai-receptionist.types';\nimport { resolveToolDisplayName, resolveToolKey } from '../utils/tool-labels.util';\n\n/** Socket.io `new_chunk` payload from /dashboard namespace */\nexport interface TranscriptChunk {\n role: 'user' | 'assistant';\n text: string;\n isFinal: boolean;\n timestamp: string;\n}\n\n/** Socket.io `call_event` payload — tools + lifecycle */\nexport interface CallEventStreamPayload {\n eventType: string;\n occurredAt: string;\n payload: Record<string, unknown>;\n}\n\nexport interface LiveTranscriptState {\n lines: TranscriptLine[];\n patientInterim: string | null;\n aiInterim: string | null;\n connected: boolean;\n error: string | null;\n}\n\nexport function mapChunkToLine(chunk: TranscriptChunk): TranscriptLine {\n const at = Date.parse(chunk.timestamp);\n return {\n who: chunk.role === 'assistant' ? 'ai' : 'patient',\n text: chunk.text,\n at: Number.isFinite(at) ? at : Date.now(),\n };\n}\n\nexport function formatEventTime(iso: string): string {\n return new Date(iso).toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n hour12: false,\n });\n}\n\nexport function mapCallEventToTool(event: CallEventStreamPayload): ToolEvent {\n const p = event.payload;\n const state = p['state'];\n const rawName = String(p['name'] ?? event.eventType.replace(/^tool_/, ''));\n const tech = String(p['tech'] ?? event.eventType);\n const key = resolveToolKey(\n p['key'] != null ? String(p['key']) : undefined,\n rawName,\n tech,\n );\n return {\n t: formatEventTime(event.occurredAt),\n key,\n name: resolveToolDisplayName(key, rawName),\n tech,\n result: String(p['result'] ?? ''),\n state:\n state === 'ok' || state === 'warn' || state === 'error' || state === 'active'\n ? state\n : 'ok',\n };\n}\n\nexport function mapLifecycleEventToTool(event: CallEventStreamPayload): ToolEvent {\n const p = event.payload;\n return {\n t: formatEventTime(event.occurredAt),\n name: event.eventType.replace(/_/g, ' '),\n tech: event.eventType,\n result: String(p['detail'] ?? p['message'] ?? p['result'] ?? ''),\n state: 'ok',\n };\n}\n\nexport function isDuplicateTranscriptLine(lines: TranscriptLine[], line: TranscriptLine): boolean {\n return lines.some((l) => l.who === line.who && l.text.trim() === line.text.trim());\n}\n","import { Injectable, inject, signal } from '@angular/core';\n\nimport { VOICE_RECEPTIONIST_CONFIG } from '../config';\nimport { ToolEvent, TranscriptLine } from '../models/ai-receptionist.types';\nimport {\n CallEventStreamPayload,\n isDuplicateTranscriptLine,\n mapCallEventToTool,\n mapChunkToLine,\n mapLifecycleEventToTool,\n TranscriptChunk,\n} from '../models/live-transcript.types';\nimport { DashboardSocketService } from './dashboard-socket.service';\n\n/**\n * Live call stream over shared Socket.io (`/dashboard` namespace).\n * REST seeds transcript/tools once; socket delivers `new_chunk` + `call_event`.\n */\n@Injectable({ providedIn: 'root' })\nexport class LiveTranscriptService {\n private readonly socket = inject(DashboardSocketService);\n private readonly config = inject(VOICE_RECEPTIONIST_CONFIG);\n\n readonly lines = signal<TranscriptLine[]>([]);\n readonly patientInterim = signal<string | null>(null);\n readonly aiInterim = signal<string | null>(null);\n readonly tools = signal<ToolEvent[]>([]);\n readonly connected = this.socket.connected;\n readonly error = signal<string | null>(null);\n readonly callEnded = signal(false);\n readonly summaryRequested = signal(false);\n\n private activeCallId: string | null = null;\n private watching = false;\n private mockTimer: ReturnType<typeof setInterval> | null = null;\n private mockIndex = 0;\n\n private readonly chunkHandler = (chunk: TranscriptChunk) => this.handleChunk(chunk);\n private readonly eventHandler = (event: CallEventStreamPayload) => this.handleCallEvent(event);\n private readonly onSocketConnect = () => {\n if (this.activeCallId) {\n this.socket.emit('watch_call', { callId: this.activeCallId });\n }\n };\n\n seed(transcript: TranscriptLine[], toolEvents: ToolEvent[]): void {\n this.lines.set(transcript.map((line) => ({ ...line })));\n this.tools.set(toolEvents.map((tool) => ({ ...tool })));\n }\n\n watch(callId: string, live = true): void {\n const id = callId.trim();\n if (!id || !live) return;\n\n const switchingCall = this.activeCallId !== id;\n if (switchingCall) {\n this.unsubscribeSocketEvents();\n this.clearInterim();\n this.callEnded.set(false);\n this.summaryRequested.set(false);\n this.activeCallId = id;\n } else if (this.watching) {\n return;\n }\n\n if (this.config.useMockApi) {\n this.watching = true;\n this.startMockStream(id);\n return;\n }\n\n if (!this.watching) {\n this.socket.acquire();\n this.socket.on('new_chunk', this.chunkHandler);\n this.socket.on('call_event', this.eventHandler);\n this.socket.onConnect(this.onSocketConnect);\n this.watching = true;\n }\n\n if (this.socket.connected()) {\n this.socket.emit('watch_call', { callId: id });\n }\n }\n\n stop(): void {\n this.activeCallId = null;\n this.unsubscribeSocketEvents();\n this.resetStreamState();\n }\n\n markCompleted(): void {\n this.callEnded.set(true);\n this.unsubscribeSocketEvents();\n this.clearInterim();\n }\n\n private unsubscribeSocketEvents(): void {\n this.stopMockStream();\n if (!this.watching) return;\n\n this.socket.off('new_chunk', this.chunkHandler);\n this.socket.off('call_event', this.eventHandler);\n this.socket.offConnect(this.onSocketConnect);\n this.socket.release();\n this.watching = false;\n }\n\n private handleChunk(chunk: TranscriptChunk): void {\n if (!chunk?.text?.trim()) return;\n\n if (chunk.role === 'user') {\n if (chunk.isFinal) {\n this.patientInterim.set(null);\n this.appendLineIfNew(mapChunkToLine(chunk));\n } else {\n this.patientInterim.set(chunk.text);\n }\n return;\n }\n\n if (chunk.isFinal) {\n this.aiInterim.set(null);\n this.appendLineIfNew(mapChunkToLine(chunk));\n } else {\n this.aiInterim.set(chunk.text);\n }\n }\n\n private handleCallEvent(event: CallEventStreamPayload): void {\n if (!event?.eventType) return;\n\n if (event.eventType.startsWith('tool_')) {\n this.tools.update((prev) => [...prev, mapCallEventToTool(event)]);\n return;\n }\n\n if (event.eventType === 'call_completed') {\n this.markCompleted();\n return;\n }\n\n if (event.eventType === 'summary_generated') {\n this.summaryRequested.set(true);\n return;\n }\n\n this.tools.update((prev) => [...prev, mapLifecycleEventToTool(event)]);\n }\n\n private appendLineIfNew(line: TranscriptLine): void {\n this.lines.update((prev) => {\n if (isDuplicateTranscriptLine(prev, line)) return prev;\n return [...prev, line];\n });\n }\n\n private startMockStream(callId: string): void {\n this.stopMockStream();\n this.mockIndex = 0;\n\n const mockChunks: TranscriptChunk[] = [\n {\n role: 'user',\n text: 'Hi, I need to schedule an appointment.',\n isFinal: false,\n timestamp: new Date().toISOString(),\n },\n {\n role: 'user',\n text: 'Hi, I need to schedule an appointment.',\n isFinal: true,\n timestamp: new Date().toISOString(),\n },\n {\n role: 'assistant',\n text: 'Of course — I can help with that. Which provider would you prefer?',\n isFinal: true,\n timestamp: new Date().toISOString(),\n },\n ];\n\n const mockEvents: CallEventStreamPayload[] = [\n {\n eventType: 'tool_check_doctor_availability',\n occurredAt: new Date().toISOString(),\n payload: {\n key: 'check_doctor_availability',\n name: 'Checked Doctor Availability',\n tech: 'tool_check_doctor_availability',\n result: 'Found 3 available time slots',\n state: 'ok',\n },\n },\n ];\n\n this.mockTimer = setInterval(() => {\n if (this.activeCallId !== callId) {\n this.stopMockStream();\n return;\n }\n if (this.mockIndex < mockChunks.length) {\n this.handleChunk(mockChunks[this.mockIndex]);\n this.mockIndex++;\n return;\n }\n if (this.mockIndex === mockChunks.length) {\n this.handleCallEvent(mockEvents[0]);\n this.mockIndex++;\n }\n }, 1500);\n }\n\n private stopMockStream(): void {\n if (this.mockTimer) {\n clearInterval(this.mockTimer);\n this.mockTimer = null;\n }\n }\n\n private clearInterim(): void {\n this.patientInterim.set(null);\n this.aiInterim.set(null);\n }\n\n private resetStreamState(): void {\n this.lines.set([]);\n this.tools.set([]);\n this.clearInterim();\n this.error.set(null);\n this.callEnded.set(false);\n this.summaryRequested.set(false);\n }\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\n@Component({\n selector: 'eds-waveform',\n standalone: true,\n template: `\n <div\n class=\"eds-waveform\"\n [class.eds-waveform--inactive]=\"!active()\"\n [attr.data-tone]=\"tone()\"\n aria-hidden=\"true\"\n >\n @for (i of bars; track i) {\n <span class=\"eds-waveform__bar\" [style.animation-delay.ms]=\"i * 70\"></span>\n }\n </div>\n `,\n styleUrl: './eds-waveform.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class EdsWaveformComponent {\n readonly active = input(true);\n readonly tone = input<'brand' | 'violet'>('brand');\n\n protected readonly bars = Array.from({ length: 28 }, (_, i) => i);\n}\n","import {\n AfterViewChecked,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewChild,\n effect,\n inject,\n input,\n output,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { TranscriptWho } from '../../models/ai-receptionist.types';\nimport { LiveTranscriptService } from '../../services/live-transcript.service';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\nimport { EdsWaveformComponent } from '../../ui/eds-waveform.component';\n\n@Component({\n selector: 'eds-live-transcript-panel',\n imports: [FormsModule, EdsIconComponent, EdsWaveformComponent],\n templateUrl: './live-transcript-panel.component.html',\n styleUrl: './live-transcript-panel.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class LiveTranscriptPanelComponent implements AfterViewChecked {\n readonly live = input(true);\n readonly paused = input(false);\n readonly humanTakeover = input(false);\n readonly showStaffInput = input(false);\n readonly staffMessage = input('');\n readonly staffMessageChange = output<string>();\n readonly sendMessage = output<void>();\n\n private readonly stream = inject(LiveTranscriptService);\n\n @ViewChild('scrollHost') private scrollHost?: ElementRef<HTMLElement>;\n\n protected readonly lines = this.stream.lines;\n protected readonly patientInterim = this.stream.patientInterim;\n protected readonly aiInterim = this.stream.aiInterim;\n protected readonly connected = this.stream.connected;\n protected readonly error = this.stream.error;\n\n private shouldScroll = false;\n\n constructor() {\n effect(() => {\n this.lines();\n this.patientInterim();\n this.aiInterim();\n this.requestScroll();\n });\n }\n\n ngAfterViewChecked(): void {\n if (this.shouldScroll && this.scrollHost) {\n const el = this.scrollHost.nativeElement;\n el.scrollTop = el.scrollHeight;\n this.shouldScroll = false;\n }\n }\n\n protected waveformActive(): boolean {\n return this.live() && this.connected() && !this.paused();\n }\n\n protected waveformTone(): 'brand' | 'violet' {\n return this.humanTakeover() ? 'violet' : 'brand';\n }\n\n protected recLabel(): string {\n if (this.paused()) return 'PAUSED';\n if (this.live() && this.connected()) return 'REC';\n if (this.error()) return 'ERROR';\n return this.live() ? 'CONNECT' : 'LOG';\n }\n\n protected roleLabel(who: TranscriptWho): string {\n switch (who) {\n case 'ai':\n return 'Ava · AI';\n case 'patient':\n return 'Patient';\n case 'staff':\n return 'Staff';\n default:\n return 'System';\n }\n }\n\n protected speakerIcon(who: TranscriptWho): string {\n switch (who) {\n case 'ai':\n return 'graphic_eq';\n case 'staff':\n return 'support_agent';\n case 'patient':\n return 'person';\n default:\n return 'info';\n }\n }\n\n protected systemIcon(flag?: string): string {\n if (flag === 'verify') return 'verified_user';\n if (flag === 'fail' || flag === 'escalate') return 'bolt';\n return 'info';\n }\n\n protected systemClass(flag?: string): string {\n if (flag === 'verify') return 'live-transcript-panel__system--verify';\n if (flag === 'fail' || flag === 'escalate') return 'live-transcript-panel__system--warn';\n return 'live-transcript-panel__system--info';\n }\n\n protected msgClass(who: TranscriptWho): string {\n return `live-transcript-panel__msg--${who}`;\n }\n\n protected avatarClass(who: TranscriptWho): string {\n return `live-transcript-panel__avatar--${who}`;\n }\n\n protected onStaffInput(value: string): void {\n this.staffMessageChange.emit(value);\n }\n\n protected onSend(): void {\n this.sendMessage.emit();\n }\n\n private requestScroll(): void {\n this.shouldScroll = true;\n }\n}\n","<section class=\"live-transcript-panel\" aria-labelledby=\"live-transcript-title\">\n <header class=\"live-transcript-panel__header\">\n <h2 id=\"live-transcript-title\" class=\"live-transcript-panel__title\">Live transcript</h2>\n <div class=\"live-transcript-panel__rec\">\n <eds-waveform [active]=\"waveformActive()\" [tone]=\"waveformTone()\" />\n <span class=\"live-transcript-panel__rec-label\">{{ recLabel() }}</span>\n </div>\n </header>\n\n <div #scrollHost class=\"live-transcript-panel__scroll\" role=\"log\" aria-live=\"polite\">\n @for (line of lines(); track $index) {\n @if (line.who === 'system') {\n <div class=\"live-transcript-panel__system eds-animate-fade-up\" [class]=\"systemClass(line.flag)\">\n <eds-icon [name]=\"systemIcon(line.flag)\" [size]=\"14\" />\n <span>{{ line.text }}</span>\n </div>\n } @else {\n <article class=\"live-transcript-panel__msg eds-animate-fade-up\" [class]=\"msgClass(line.who)\">\n <div class=\"live-transcript-panel__avatar\" [class]=\"avatarClass(line.who)\">\n <eds-icon [name]=\"speakerIcon(line.who)\" [size]=\"16\" />\n </div>\n <div class=\"live-transcript-panel__content\">\n <span class=\"live-transcript-panel__label\">{{ roleLabel(line.who) }}</span>\n <div class=\"live-transcript-panel__bubble\">\n <p>{{ line.text }}</p>\n </div>\n </div>\n </article>\n }\n }\n\n @if (patientInterim(); as interim) {\n <article class=\"live-transcript-panel__msg live-transcript-panel__msg--patient eds-animate-fade-up\">\n <div class=\"live-transcript-panel__avatar live-transcript-panel__avatar--patient\">\n <eds-icon name=\"person\" [size]=\"16\" />\n </div>\n <div class=\"live-transcript-panel__content\">\n <span class=\"live-transcript-panel__label\">Patient · listening</span>\n <div class=\"live-transcript-panel__bubble live-transcript-panel__bubble--interim\">\n <p>{{ interim }}</p>\n </div>\n </div>\n </article>\n }\n\n @if (aiInterim(); as interim) {\n <article class=\"live-transcript-panel__msg live-transcript-panel__msg--ai eds-animate-fade-up\">\n <div class=\"live-transcript-panel__avatar live-transcript-panel__avatar--ai\">\n <eds-icon name=\"graphic_eq\" [size]=\"16\" />\n </div>\n <div class=\"live-transcript-panel__content\">\n <span class=\"live-transcript-panel__label\">Ava · AI</span>\n <div class=\"live-transcript-panel__bubble live-transcript-panel__bubble--interim\">\n <p>{{ interim }}<span class=\"live-transcript-panel__caret\" aria-hidden=\"true\"></span></p>\n </div>\n </div>\n </article>\n }\n\n @if (lines().length === 0 && !patientInterim() && !aiInterim()) {\n <p class=\"live-transcript-panel__empty\">Waiting for conversation…</p>\n }\n </div>\n\n @if (showStaffInput()) {\n <footer class=\"live-transcript-panel__footer\">\n <input\n type=\"text\"\n class=\"live-transcript-panel__input\"\n placeholder=\"Type to speak as staff…\"\n [ngModel]=\"staffMessage()\"\n (ngModelChange)=\"onStaffInput($event)\"\n (keyup.enter)=\"onSend()\"\n />\n <button type=\"button\" class=\"live-transcript-panel__send\" (click)=\"onSend()\">\n <eds-icon name=\"send\" [size]=\"18\" />\n Send\n </button>\n </footer>\n }\n</section>\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n effect,\n inject,\n OnDestroy,\n OnInit,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute, RouterLink } from '@angular/router';\nimport { FormsModule } from '@angular/forms';\n\nimport { LiveTranscriptPanelComponent } from '../../components/live-transcript-panel/live-transcript-panel.component';\nimport { CallRecordingPlayerComponent } from '../../components/call-recording-player/call-recording-player.component';\nimport { LiveCall, Sentiment } from '../../models/ai-receptionist.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { LiveTranscriptService } from '../../services/live-transcript.service';\nimport { toolEventTrackKey } from '../../utils/tool-labels.util';\nimport { EdsElapsedPipe } from '../../pipes/eds-elapsed.pipe';\nimport { EdsAvatarComponent } from '../../ui/eds-avatar.component';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\n\n@Component({\n selector: 'eds-live-monitor-page',\n imports: [\n RouterLink,\n FormsModule,\n EdsAvatarComponent,\n EdsIconComponent,\n EdsElapsedPipe,\n LiveTranscriptPanelComponent,\n CallRecordingPlayerComponent,\n ],\n templateUrl: './live-monitor-page.component.html',\n styleUrl: './live-monitor-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class LiveMonitorPageComponent implements OnInit, OnDestroy {\n private readonly api = inject(AiReceptionistApiService);\n private readonly route = inject(ActivatedRoute);\n private readonly stream = inject(LiveTranscriptService);\n private readonly destroyRef = inject(DestroyRef);\n\n protected readonly call = signal<LiveCall | null>(null);\n protected readonly staffMessage = signal('');\n protected readonly loading = signal(true);\n protected readonly callId = signal('');\n protected readonly summary = signal<string | null>(null);\n protected readonly summaryLoading = signal(false);\n\n protected readonly liveTools = this.stream.tools;\n protected readonly callEnded = this.stream.callEnded;\n\n private summaryLoaded = false;\n\n constructor() {\n effect(() => {\n if (this.stream.callEnded()) {\n this.loadCallMetadataOnce();\n }\n });\n\n effect(() => {\n if (this.stream.summaryRequested() && !this.summaryLoaded) {\n this.loadPostCallSummary();\n }\n });\n }\n\n ngOnInit(): void {\n this.route.paramMap.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((params) => {\n const id = params.get('id') ?? '';\n this.callId.set(id);\n this.loading.set(true);\n this.summary.set(null);\n this.summaryLoaded = false;\n this.stream.stop();\n this.loadCallMetadata();\n });\n }\n\n ngOnDestroy(): void {\n this.stream.stop();\n }\n\n protected isTakeover(): boolean {\n const c = this.call();\n return c?.status === 'takeover' || !!c?.assigned;\n }\n\n protected isPaused(): boolean {\n return !!this.call()?.aiPaused;\n }\n\n protected isLive(): boolean {\n return !!this.call() && !this.callEnded();\n }\n\n protected confidenceLevel(confidence: number): 'high' | 'low' | 'mid' {\n if (confidence >= 70) return 'high';\n if (confidence < 50) return 'low';\n return 'mid';\n }\n\n protected sentimentPercent(sentiment: Sentiment): number {\n const map: Record<Sentiment, number> = {\n calm: 85,\n neutral: 60,\n frustrated: 35,\n urgent: 15,\n };\n return map[sentiment];\n }\n\n protected toolStateClass(state: string): string {\n return `live-monitor-page__tool--${state}`;\n }\n\n protected readonly toolTrackKey = toolEventTrackKey;\n\n protected takeover(): void {\n this.api.postTakeover(this.callId()).subscribe(() => this.refreshMetadata());\n }\n\n protected resumeAi(): void {\n this.api.postResumeAi(this.callId()).subscribe(() => this.refreshMetadata());\n }\n\n protected transfer(): void {\n this.api.postTransfer(this.callId()).subscribe(() => this.refreshMetadata());\n }\n\n protected endCall(): void {\n const id = this.callId();\n this.api.postEnd(id).subscribe(() => {\n this.stream.markCompleted();\n this.loadCallMetadataOnce();\n this.loadPostCallSummary();\n });\n }\n\n protected sendMessage(): void {\n const text = this.staffMessage().trim();\n if (!text) return;\n this.api.postMessage(this.callId(), text).subscribe(() => {\n this.staffMessage.set('');\n this.refreshMetadata();\n });\n }\n\n /** Initial load — seeds transcript/tools from REST, then starts socket. */\n private loadCallMetadata(): void {\n const id = this.callId();\n if (!id) return;\n this.api.getLiveCall(id).subscribe(({ data }) => {\n this.call.set(data);\n this.loading.set(false);\n if (data) {\n this.stream.seed(data.transcript, data.tools);\n if (!this.callEnded()) {\n this.stream.watch(id, true);\n }\n }\n });\n }\n\n /** Metadata-only refresh after staff actions — does not overwrite live transcript/tools. */\n private refreshMetadata(): void {\n const id = this.callId();\n if (!id) return;\n this.api.getLiveCall(id).subscribe(({ data }) => {\n if (data) this.call.set(data);\n });\n }\n\n /** One-time metadata refresh after call ends (no socket). */\n private loadCallMetadataOnce(): void {\n const id = this.callId();\n if (!id) return;\n this.api.getLiveCall(id).subscribe(({ data }) => {\n if (data) {\n this.call.set(data);\n }\n });\n }\n\n private loadPostCallSummary(): void {\n const id = this.callId();\n if (!id || this.summaryLoaded) return;\n this.summaryLoading.set(true);\n this.api.getCallSummary(id).subscribe(({ data }) => {\n this.summaryLoading.set(false);\n this.summaryLoaded = true;\n if (!data) return;\n this.summary.set(data.summary);\n this.stream.seed(data.transcript, data.tools);\n });\n }\n}\n","<div class=\"eds-page eds-page--dark live-monitor-page\">\n @if (loading()) {\n <p class=\"live-monitor-page__loading\">Loading call…</p>\n } @else {\n @if (call(); as c) {\n <header class=\"live-monitor-page__header\">\n <a routerLink=\"../live\" class=\"live-monitor-page__back\" aria-label=\"Back to live calls\">\n <eds-icon name=\"arrow_back\" [size]=\"19\" />\n </a>\n\n <div class=\"live-monitor-page__header-main\">\n <eds-avatar\n [initials]=\"c.initials\"\n tone=\"brand\"\n [gradient]=\"c.matched\"\n [class.live-monitor-page__avatar--ring]=\"c.matched\"\n />\n\n <div class=\"live-monitor-page__caller\">\n <div class=\"live-monitor-page__name-row\">\n <h1 class=\"live-monitor-page__name\">{{ c.name }}</h1>\n <span class=\"live-monitor-page__patient-tag\" [attr.data-kind]=\"c.matched ? 'registered' : 'new'\">\n <eds-icon [name]=\"c.matched ? 'person_check' : 'person_add'\" [size]=\"14\" />\n {{ c.matched ? 'Registered' : 'New' }}\n </span>\n </div>\n <div class=\"live-monitor-page__meta-row\">\n <eds-icon [name]=\"c.direction === 'inbound' ? 'call_received' : 'call_made'\" [size]=\"14\" />\n <span>{{ c.phone }}</span>\n <span class=\"live-monitor-page__sep\">·</span>\n <span>{{ c.reason }}</span>\n </div>\n </div>\n\n <div class=\"live-monitor-page__header-right\">\n <span class=\"live-monitor-page__duration\">\n <span class=\"live-monitor-page__duration-dot\" aria-hidden=\"true\"></span>\n {{ c.started | edsElapsed }}\n </span>\n </div>\n </div>\n </header>\n\n @if (callEnded()) {\n <div class=\"live-monitor-page__completed-banner\" role=\"status\">\n <eds-icon name=\"check_circle\" [size]=\"18\" />\n Call ended\n </div>\n }\n\n <div class=\"live-monitor-page__grid\">\n <div class=\"live-monitor-page__main\">\n <eds-live-transcript-panel\n [live]=\"isLive()\"\n [paused]=\"isPaused()\"\n [humanTakeover]=\"isTakeover()\"\n [showStaffInput]=\"isTakeover() && !callEnded()\"\n [staffMessage]=\"staffMessage()\"\n (staffMessageChange)=\"staffMessage.set($event)\"\n (sendMessage)=\"sendMessage()\"\n />\n\n @if (callEnded()) {\n <section class=\"live-monitor-page__post-call\">\n <div class=\"live-monitor-page__summary\">\n <h2 class=\"live-monitor-page__section-title\">Call summary</h2>\n @if (summaryLoading()) {\n <p class=\"live-monitor-page__muted\">Generating summary…</p>\n } @else if (summary()) {\n <p>{{ summary() }}</p>\n } @else {\n <p class=\"live-monitor-page__muted\">Summary will appear when processing completes.</p>\n }\n </div>\n <eds-call-recording-player [callId]=\"callId()\" />\n </section>\n }\n </div>\n\n <aside class=\"live-monitor-page__sidebar\">\n @if (!callEnded()) {\n <div class=\"live-monitor-page__orb-wrap\" [attr.data-mode]=\"c.status === 'transferring' ? 'transfer' : 'ai'\">\n <span class=\"live-monitor-page__ring live-monitor-page__ring--1\"></span>\n <span class=\"live-monitor-page__ring live-monitor-page__ring--2\"></span>\n <span class=\"live-monitor-page__orb\">\n <eds-icon name=\"smart_toy\" [size]=\"28\" />\n </span>\n <span class=\"live-monitor-page__confidence\" [attr.data-level]=\"confidenceLevel(c.confidence)\">\n AI confidence {{ c.confidence }}%\n </span>\n </div>\n\n <section class=\"live-monitor-page__sidebar-block\">\n <h3 class=\"live-monitor-page__section-title\">Patient sentiment</h3>\n <div class=\"live-monitor-page__sentiment-bar\">\n <span\n class=\"live-monitor-page__sentiment-fill\"\n [style.width.%]=\"sentimentPercent(c.sentiment)\"\n [attr.data-sentiment]=\"c.sentiment\"\n ></span>\n </div>\n <span class=\"live-monitor-page__sentiment-label\">{{ c.sentiment }}</span>\n </section>\n }\n\n <section class=\"live-monitor-page__sidebar-block\">\n <h3 class=\"live-monitor-page__section-title\">Tools used</h3>\n <ul class=\"live-monitor-page__tools\">\n @for (tool of liveTools(); track toolTrackKey(tool, $index)) {\n <li [class]=\"toolStateClass(tool.state)\">\n <span class=\"live-monitor-page__tool-time\">{{ tool.t }}</span>\n <div class=\"live-monitor-page__tool-body\">\n <span class=\"live-monitor-page__tool-name\">{{ tool.name }}</span>\n <span class=\"live-monitor-page__tool-result\">{{ tool.result }}</span>\n </div>\n @if (tool.state === 'active') {\n <eds-icon name=\"sync\" [size]=\"16\" class=\"live-monitor-page__tool-spin\" />\n }\n </li>\n } @empty {\n <li class=\"live-monitor-page__tools-empty\">No tool activity yet.</li>\n }\n </ul>\n </section>\n\n <section class=\"live-monitor-page__sidebar-block\">\n <h3 class=\"live-monitor-page__section-title\">Goal</h3>\n <p class=\"live-monitor-page__goal\">{{ c.goal }}</p>\n </section>\n </aside>\n </div>\n\n @if (!callEnded()) {\n <footer class=\"live-monitor-page__control-bar\">\n <div class=\"live-monitor-page__control-group\">\n @if (isTakeover()) {\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--violet\" (click)=\"resumeAi()\">\n <eds-icon name=\"smart_toy\" [size]=\"18\" /> Resume AI\n </button>\n } @else {\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--primary\" (click)=\"takeover()\">\n <eds-icon name=\"pan_tool_alt\" [size]=\"18\" /> Take over\n </button>\n }\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--neutral\" disabled title=\"Coming soon\">\n <eds-icon name=\"hearing\" [size]=\"18\" /> Listen\n </button>\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--neutral\" (click)=\"transfer()\">\n <eds-icon name=\"phone_forwarded\" [size]=\"18\" /> Transfer\n </button>\n </div>\n\n <span class=\"live-monitor-page__divider\" aria-hidden=\"true\"></span>\n\n <div class=\"live-monitor-page__control-group\">\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--neutral\" disabled title=\"Coming soon\">\n <eds-icon name=\"person_search\" [size]=\"18\" /> Open chart\n </button>\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--neutral\" disabled title=\"Coming soon\">\n <eds-icon name=\"add_task\" [size]=\"18\" /> Create task\n </button>\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--neutral\" disabled title=\"Coming soon\">\n <eds-icon name=\"edit_note\" [size]=\"18\" /> Add note\n </button>\n </div>\n\n <button type=\"button\" class=\"live-monitor-page__ctrl live-monitor-page__ctrl--danger\" (click)=\"endCall()\">\n <eds-icon name=\"call_end\" [size]=\"18\" /> End call\n </button>\n </footer>\n }\n } @else {\n <p class=\"live-monitor-page__loading\">Call ended or not found.</p>\n }\n }\n</div>\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { inject, EventEmitter, signal, ViewChild, Output, Input, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { RouterLink } from '@angular/router';
4
- import { A as AiReceptionistApiService, D as DEFAULT_PLACEHOLDERS, M as ModalComponent, E as EdsButtonComponent, a as EdsBadgeComponent, b as EdsIconComponent } from './edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-DvJ2Ygc1.mjs';
4
+ import { A as AiReceptionistApiService, D as DEFAULT_PLACEHOLDERS, M as ModalComponent, E as EdsButtonComponent, a as EdsBadgeComponent, b as EdsIconComponent } from './edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-CMhknpGf.mjs';
5
5
  import { R as REQUIRED_FIELD_OPTIONS, a as renderOpeningPreview, f as formatRequiredFields } from './edvak99-voice-receptionist-widget-outbound-purpose.util-BQECIuJu.mjs';
6
6
  import * as i1 from '@angular/forms';
7
7
  import { FormsModule } from '@angular/forms';
@@ -262,4 +262,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
262
262
  }] });
263
263
 
264
264
  export { OutboundPurposesPageComponent };
265
- //# sourceMappingURL=edvak99-voice-receptionist-widget-outbound-purposes-page.component-CteOwr16.mjs.map
265
+ //# sourceMappingURL=edvak99-voice-receptionist-widget-outbound-purposes-page.component-CJ8NEjcj.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"edvak99-voice-receptionist-widget-outbound-purposes-page.component-CteOwr16.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/components/outbound-purpose-form-modal/outbound-purpose-form-modal.component.ts","../../../projects/voice-receptionist-widget/src/lib/components/outbound-purpose-form-modal/outbound-purpose-form-modal.component.html","../../../projects/voice-receptionist-widget/src/lib/pages/outbound-purposes-page/outbound-purposes-page.component.ts","../../../projects/voice-receptionist-widget/src/lib/pages/outbound-purposes-page/outbound-purposes-page.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n EventEmitter,\n Input,\n OnChanges,\n Output,\n SimpleChanges,\n ViewChild,\n inject,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport {\n CreateOutboundPurposeRequest,\n OutboundPurpose,\n OutboundPurposePlaceholder,\n OutboundRequiredField,\n UpdateOutboundPurposeRequest,\n} from '../../models/outbound-purpose.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport {\n REQUIRED_FIELD_OPTIONS,\n renderOpeningPreview,\n} from '../../utils/outbound-purpose.util';\nimport { DEFAULT_PLACEHOLDERS } from '../../mocks/outbound-purpose.seed';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport { ModalComponent } from '../../shared/modal.component';\n\n@Component({\n selector: 'eds-outbound-purpose-form-modal',\n imports: [FormsModule, ModalComponent, EdsButtonComponent],\n templateUrl: './outbound-purpose-form-modal.component.html',\n styleUrl: './outbound-purpose-form-modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class OutboundPurposeFormModalComponent implements OnChanges {\n private readonly api = inject(AiReceptionistApiService);\n\n @Input() open = false;\n @Input() purpose: OutboundPurpose | null = null;\n @Output() readonly closed = new EventEmitter<void>();\n @Output() readonly saved = new EventEmitter<OutboundPurpose>();\n\n @ViewChild('templateInput') templateInput?: ElementRef<HTMLTextAreaElement>;\n\n protected readonly fieldOptions = REQUIRED_FIELD_OPTIONS;\n protected readonly saving = signal(false);\n protected readonly error = signal<string | null>(null);\n\n protected label = '';\n protected description = '';\n protected sampleOpening = '';\n protected openingTemplate = '';\n protected agentContextHint = '';\n protected requiredFields = new Set<OutboundRequiredField>();\n protected allowsCustomScript = false;\n protected sortOrder = 1;\n protected isActive = true;\n protected placeholders: OutboundPurposePlaceholder[] = DEFAULT_PLACEHOLDERS;\n\n protected get isEdit(): boolean {\n return !!this.purpose;\n }\n\n protected get previewText(): string {\n return renderOpeningPreview(this.sampleOpening, this.openingTemplate, this.placeholders);\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['open']?.currentValue || changes['purpose']) {\n this.resetForm();\n }\n }\n\n protected close(): void {\n this.closed.emit();\n }\n\n protected toggleRequired(field: OutboundRequiredField): void {\n const next = new Set(this.requiredFields);\n if (next.has(field)) next.delete(field);\n else next.add(field);\n this.requiredFields = next;\n }\n\n protected isRequiredSelected(field: OutboundRequiredField): boolean {\n return this.requiredFields.has(field);\n }\n\n protected insertPlaceholder(token: string): void {\n const el = this.templateInput?.nativeElement;\n if (!el) {\n this.openingTemplate += token;\n return;\n }\n const start = el.selectionStart ?? this.openingTemplate.length;\n const end = el.selectionEnd ?? start;\n this.openingTemplate =\n this.openingTemplate.slice(0, start) + token + this.openingTemplate.slice(end);\n const pos = start + token.length;\n requestAnimationFrame(() => {\n el.focus();\n el.setSelectionRange(pos, pos);\n });\n }\n\n protected submit(): void {\n this.error.set(null);\n const trimmedLabel = this.label.trim();\n const trimmedTemplate = this.openingTemplate.trim();\n if (!trimmedLabel) {\n this.error.set('Label is required.');\n return;\n }\n if (!trimmedTemplate) {\n this.error.set('Opening template is required.');\n return;\n }\n if (this.sampleOpening.length > 500) {\n this.error.set('Sample opening must be 500 characters or fewer.');\n return;\n }\n\n this.saving.set(true);\n const fields = [...this.requiredFields];\n\n if (this.isEdit && this.purpose) {\n const body: UpdateOutboundPurposeRequest = {\n label: trimmedLabel,\n description: this.description.trim(),\n sampleOpening: this.sampleOpening.trim(),\n openingTemplate: trimmedTemplate,\n agentContextHint: this.agentContextHint.trim() || null,\n requiredFields: fields,\n allowsCustomScript: this.allowsCustomScript,\n sortOrder: this.sortOrder,\n isActive: this.isActive,\n };\n this.api.updateOutboundPurpose(this.purpose.purposeId, body).subscribe({\n next: (updated) => {\n this.saving.set(false);\n this.saved.emit(updated);\n this.close();\n },\n error: () => {\n this.saving.set(false);\n this.error.set('Failed to save purpose template.');\n },\n });\n return;\n }\n\n const body: CreateOutboundPurposeRequest = {\n label: trimmedLabel,\n description: this.description.trim(),\n sampleOpening: this.sampleOpening.trim(),\n openingTemplate: trimmedTemplate,\n agentContextHint: this.agentContextHint.trim() || null,\n requiredFields: fields,\n allowsCustomScript: this.allowsCustomScript,\n sortOrder: this.sortOrder,\n };\n this.api.createOutboundPurpose(body).subscribe({\n next: (created) => {\n this.saving.set(false);\n this.saved.emit(created);\n this.close();\n },\n error: () => {\n this.saving.set(false);\n this.error.set('Failed to create purpose template.');\n },\n });\n }\n\n private resetForm(): void {\n this.error.set(null);\n this.saving.set(false);\n if (this.purpose) {\n this.label = this.purpose.label;\n this.description = this.purpose.description;\n this.sampleOpening = this.purpose.sampleOpening;\n this.openingTemplate = this.purpose.openingTemplate;\n this.agentContextHint = this.purpose.agentContextHint ?? '';\n this.requiredFields = new Set(this.purpose.requiredFields);\n this.allowsCustomScript = this.purpose.allowsCustomScript;\n this.sortOrder = this.purpose.sortOrder;\n this.isActive = this.purpose.isActive;\n this.placeholders = this.purpose.placeholders?.length\n ? [...this.purpose.placeholders]\n : [...DEFAULT_PLACEHOLDERS];\n } else {\n this.label = '';\n this.description = '';\n this.sampleOpening = '';\n this.openingTemplate = 'Hi {{patientName}}, this is {{practiceName}}.';\n this.agentContextHint = '';\n this.requiredFields = new Set();\n this.allowsCustomScript = false;\n this.sortOrder = 1;\n this.isActive = true;\n this.placeholders = [...DEFAULT_PLACEHOLDERS];\n }\n }\n}\n","@if (open) {\n <app-modal\n [title]=\"isEdit ? 'Edit outbound purpose' : 'New outbound purpose'\"\n subtitle=\"Configure dialer fields and AI opening script\"\n maxWidth=\"720px\"\n (closed)=\"close()\"\n >\n <form class=\"purpose-form\" (ngSubmit)=\"submit()\" novalidate>\n <div class=\"purpose-form__grid\">\n <label class=\"purpose-form__field purpose-form__field--full\">\n <span class=\"eds-label\">Label <span class=\"purpose-form__req\">*</span></span>\n <input type=\"text\" class=\"purpose-form__input\" [(ngModel)]=\"label\" name=\"label\" required />\n </label>\n\n <label class=\"purpose-form__field purpose-form__field--full\">\n <span class=\"eds-label\">Description</span>\n <input type=\"text\" class=\"purpose-form__input\" [(ngModel)]=\"description\" name=\"description\" />\n </label>\n\n <label class=\"purpose-form__field purpose-form__field--full\">\n <span class=\"eds-label\">Sample opening (plain preview, max 500)</span>\n <textarea\n class=\"purpose-form__textarea\"\n rows=\"3\"\n maxlength=\"500\"\n [(ngModel)]=\"sampleOpening\"\n name=\"sampleOpening\"\n ></textarea>\n <span class=\"purpose-form__hint\">{{ sampleOpening.length }}/500</span>\n </label>\n\n <div class=\"purpose-form__field purpose-form__field--full\">\n <span class=\"eds-label\">Opening template <span class=\"purpose-form__req\">*</span></span>\n <div class=\"purpose-form__chips\">\n @for (chip of placeholders; track chip.token) {\n <button type=\"button\" class=\"purpose-form__chip\" (click)=\"insertPlaceholder(chip.token)\">\n {{ chip.label }}\n </button>\n }\n </div>\n <textarea\n #templateInput\n class=\"purpose-form__textarea\"\n rows=\"4\"\n [(ngModel)]=\"openingTemplate\"\n name=\"openingTemplate\"\n required\n ></textarea>\n </div>\n\n <label class=\"purpose-form__field purpose-form__field--full\">\n <span class=\"eds-label\">Agent context hint</span>\n <textarea\n class=\"purpose-form__textarea\"\n rows=\"2\"\n [(ngModel)]=\"agentContextHint\"\n name=\"agentContextHint\"\n placeholder=\"Optional guidance for the AI after the opening\"\n ></textarea>\n </label>\n\n <fieldset class=\"purpose-form__field purpose-form__field--full\">\n <legend class=\"eds-label\">Required fields</legend>\n <div class=\"purpose-form__checks\">\n @for (opt of fieldOptions; track opt.value) {\n <label class=\"purpose-form__check\">\n <input\n type=\"checkbox\"\n [checked]=\"isRequiredSelected(opt.value)\"\n (change)=\"toggleRequired(opt.value)\"\n />\n {{ opt.label }}\n </label>\n }\n </div>\n </fieldset>\n\n <label class=\"purpose-form__check purpose-form__field--full\">\n <input type=\"checkbox\" [(ngModel)]=\"allowsCustomScript\" name=\"allowsCustomScript\" />\n Allows custom script (dialer shows free-text script field)\n </label>\n\n <label class=\"purpose-form__field\">\n <span class=\"eds-label\">Sort order</span>\n <input type=\"number\" class=\"purpose-form__input\" [(ngModel)]=\"sortOrder\" name=\"sortOrder\" min=\"0\" />\n </label>\n\n @if (isEdit) {\n <label class=\"purpose-form__check\">\n <input type=\"checkbox\" [(ngModel)]=\"isActive\" name=\"isActive\" />\n Active\n </label>\n }\n </div>\n\n <section class=\"purpose-form__preview eds-card\">\n <h3 class=\"eds-label\">Live preview</h3>\n <p class=\"purpose-form__preview-text\">{{ previewText }}</p>\n </section>\n\n @if (error()) {\n <p class=\"purpose-form__error\" role=\"alert\">{{ error() }}</p>\n }\n\n <footer class=\"purpose-form__footer\">\n <eds-button variant=\"secondary\" type=\"button\" (click)=\"close()\" [disabled]=\"saving()\">\n Cancel\n </eds-button>\n <eds-button variant=\"primary\" type=\"submit\" [disabled]=\"saving()\">\n {{ saving() ? 'Saving…' : isEdit ? 'Save changes' : 'Create purpose' }}\n </eds-button>\n </footer>\n </form>\n </app-modal>\n}\n","import { ChangeDetectionStrategy, Component, inject, OnInit, signal } from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nimport { OutboundPurpose } from '../../models/outbound-purpose.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { formatRequiredFields } from '../../utils/outbound-purpose.util';\nimport { OutboundPurposeFormModalComponent } from '../../components/outbound-purpose-form-modal/outbound-purpose-form-modal.component';\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-outbound-purposes-page',\n imports: [\n RouterLink,\n EdsBadgeComponent,\n EdsButtonComponent,\n EdsIconComponent,\n OutboundPurposeFormModalComponent,\n ],\n templateUrl: './outbound-purposes-page.component.html',\n styleUrl: './outbound-purposes-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class OutboundPurposesPageComponent implements OnInit {\n private readonly api = inject(AiReceptionistApiService);\n\n protected readonly purposes = signal<OutboundPurpose[]>([]);\n protected readonly loading = signal(true);\n protected readonly error = signal<string | null>(null);\n protected readonly modalOpen = signal(false);\n protected readonly editing = signal<OutboundPurpose | null>(null);\n\n protected formatRequiredFields = formatRequiredFields;\n\n ngOnInit(): void {\n this.load();\n }\n\n protected load(): void {\n this.loading.set(true);\n this.error.set(null);\n this.api.getOutboundPurposes(true).subscribe({\n next: ({ purposes }) => {\n this.purposes.set(purposes);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.error.set('Failed to load outbound purposes.');\n },\n });\n }\n\n protected openCreate(): void {\n this.editing.set(null);\n this.modalOpen.set(true);\n }\n\n protected openEdit(purpose: OutboundPurpose): void {\n this.editing.set(purpose);\n this.modalOpen.set(true);\n }\n\n protected closeModal(): void {\n this.modalOpen.set(false);\n this.editing.set(null);\n }\n\n protected onSaved(): void {\n this.load();\n }\n\n protected toggleActive(purpose: OutboundPurpose, active: boolean): void {\n this.api.updateOutboundPurpose(purpose.purposeId, { isActive: active }).subscribe({\n next: (updated) => {\n this.purposes.update((list) =>\n list.map((p) => (p.purposeId === updated.purposeId ? updated : p)),\n );\n },\n error: () => this.load(),\n });\n }\n\n protected deletePurpose(purpose: OutboundPurpose): void {\n if (purpose.isSystem) {\n this.toggleActive(purpose, false);\n return;\n }\n if (!confirm(`Delete \"${purpose.label}\"? This cannot be undone.`)) return;\n this.api.deleteOutboundPurpose(purpose.purposeId).subscribe({\n next: () => this.load(),\n error: () => this.error.set('Failed to delete purpose.'),\n });\n }\n\n protected actionLabel(purpose: OutboundPurpose): string {\n return purpose.isSystem ? 'Deactivate' : 'Delete';\n }\n}\n","<div class=\"eds-page outbound-purposes-page\">\n <header class=\"outbound-purposes-page__header\">\n <div>\n <a routerLink=\"../settings\" class=\"outbound-purposes-page__back eds-body-sm\">\n <eds-icon name=\"arrow_back\" [size]=\"16\" /> Settings\n </a>\n <h1 class=\"eds-h1\">Outbound Call Purposes</h1>\n <p class=\"eds-body-sm\">Templates that drive outbound dialer fields and AI opening scripts</p>\n </div>\n <eds-button variant=\"primary\" (click)=\"openCreate()\">\n <eds-icon name=\"add\" [size]=\"18\" /> New purpose\n </eds-button>\n </header>\n\n @if (loading()) {\n <p class=\"eds-body-sm\">Loading purposes…</p>\n } @else if (error()) {\n <p class=\"outbound-purposes-page__error eds-body-sm\" role=\"alert\">{{ error() }}</p>\n } @else {\n <article class=\"eds-card outbound-purposes-page__table-card\">\n <table class=\"eds-table\">\n <thead>\n <tr>\n <th>Label</th>\n <th>Description</th>\n <th>Required fields</th>\n <th>System</th>\n <th>Active</th>\n <th>Sort</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (p of purposes(); track p.purposeId) {\n <tr>\n <td class=\"eds-body-sm-bold\">{{ p.label }}</td>\n <td class=\"eds-body-sm\">{{ p.description || '—' }}</td>\n <td class=\"eds-body-sm\">{{ formatRequiredFields(p.requiredFields) }}</td>\n <td>\n @if (p.isSystem) {\n <eds-badge tone=\"brand\">System</eds-badge>\n } @else {\n <span class=\"eds-body-sm\">—</span>\n }\n </td>\n <td>\n <label class=\"outbound-purposes-page__toggle\">\n <input\n type=\"checkbox\"\n [checked]=\"p.isActive\"\n (change)=\"toggleActive(p, $any($event.target).checked)\"\n />\n </label>\n </td>\n <td class=\"eds-mono-sm\">{{ p.sortOrder }}</td>\n <td class=\"outbound-purposes-page__actions\">\n <button type=\"button\" class=\"outbound-purposes-page__link\" (click)=\"openEdit(p)\">\n Edit\n </button>\n <button type=\"button\" class=\"outbound-purposes-page__link\" (click)=\"deletePurpose(p)\">\n {{ actionLabel(p) }}\n </button>\n </td>\n </tr>\n } @empty {\n <tr>\n <td colspan=\"7\" class=\"eds-body-sm\">No outbound purposes configured.</td>\n </tr>\n }\n </tbody>\n </table>\n </article>\n }\n\n <eds-outbound-purpose-form-modal\n [open]=\"modalOpen()\"\n [purpose]=\"editing()\"\n (closed)=\"closeModal()\"\n (saved)=\"onSaved()\"\n />\n</div>\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"edvak99-voice-receptionist-widget-outbound-purposes-page.component-CJ8NEjcj.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/components/outbound-purpose-form-modal/outbound-purpose-form-modal.component.ts","../../../projects/voice-receptionist-widget/src/lib/components/outbound-purpose-form-modal/outbound-purpose-form-modal.component.html","../../../projects/voice-receptionist-widget/src/lib/pages/outbound-purposes-page/outbound-purposes-page.component.ts","../../../projects/voice-receptionist-widget/src/lib/pages/outbound-purposes-page/outbound-purposes-page.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n EventEmitter,\n Input,\n OnChanges,\n Output,\n SimpleChanges,\n ViewChild,\n inject,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport {\n CreateOutboundPurposeRequest,\n OutboundPurpose,\n OutboundPurposePlaceholder,\n OutboundRequiredField,\n UpdateOutboundPurposeRequest,\n} from '../../models/outbound-purpose.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport {\n REQUIRED_FIELD_OPTIONS,\n renderOpeningPreview,\n} from '../../utils/outbound-purpose.util';\nimport { DEFAULT_PLACEHOLDERS } from '../../mocks/outbound-purpose.seed';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport { ModalComponent } from '../../shared/modal.component';\n\n@Component({\n selector: 'eds-outbound-purpose-form-modal',\n imports: [FormsModule, ModalComponent, EdsButtonComponent],\n templateUrl: './outbound-purpose-form-modal.component.html',\n styleUrl: './outbound-purpose-form-modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class OutboundPurposeFormModalComponent implements OnChanges {\n private readonly api = inject(AiReceptionistApiService);\n\n @Input() open = false;\n @Input() purpose: OutboundPurpose | null = null;\n @Output() readonly closed = new EventEmitter<void>();\n @Output() readonly saved = new EventEmitter<OutboundPurpose>();\n\n @ViewChild('templateInput') templateInput?: ElementRef<HTMLTextAreaElement>;\n\n protected readonly fieldOptions = REQUIRED_FIELD_OPTIONS;\n protected readonly saving = signal(false);\n protected readonly error = signal<string | null>(null);\n\n protected label = '';\n protected description = '';\n protected sampleOpening = '';\n protected openingTemplate = '';\n protected agentContextHint = '';\n protected requiredFields = new Set<OutboundRequiredField>();\n protected allowsCustomScript = false;\n protected sortOrder = 1;\n protected isActive = true;\n protected placeholders: OutboundPurposePlaceholder[] = DEFAULT_PLACEHOLDERS;\n\n protected get isEdit(): boolean {\n return !!this.purpose;\n }\n\n protected get previewText(): string {\n return renderOpeningPreview(this.sampleOpening, this.openingTemplate, this.placeholders);\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['open']?.currentValue || changes['purpose']) {\n this.resetForm();\n }\n }\n\n protected close(): void {\n this.closed.emit();\n }\n\n protected toggleRequired(field: OutboundRequiredField): void {\n const next = new Set(this.requiredFields);\n if (next.has(field)) next.delete(field);\n else next.add(field);\n this.requiredFields = next;\n }\n\n protected isRequiredSelected(field: OutboundRequiredField): boolean {\n return this.requiredFields.has(field);\n }\n\n protected insertPlaceholder(token: string): void {\n const el = this.templateInput?.nativeElement;\n if (!el) {\n this.openingTemplate += token;\n return;\n }\n const start = el.selectionStart ?? this.openingTemplate.length;\n const end = el.selectionEnd ?? start;\n this.openingTemplate =\n this.openingTemplate.slice(0, start) + token + this.openingTemplate.slice(end);\n const pos = start + token.length;\n requestAnimationFrame(() => {\n el.focus();\n el.setSelectionRange(pos, pos);\n });\n }\n\n protected submit(): void {\n this.error.set(null);\n const trimmedLabel = this.label.trim();\n const trimmedTemplate = this.openingTemplate.trim();\n if (!trimmedLabel) {\n this.error.set('Label is required.');\n return;\n }\n if (!trimmedTemplate) {\n this.error.set('Opening template is required.');\n return;\n }\n if (this.sampleOpening.length > 500) {\n this.error.set('Sample opening must be 500 characters or fewer.');\n return;\n }\n\n this.saving.set(true);\n const fields = [...this.requiredFields];\n\n if (this.isEdit && this.purpose) {\n const body: UpdateOutboundPurposeRequest = {\n label: trimmedLabel,\n description: this.description.trim(),\n sampleOpening: this.sampleOpening.trim(),\n openingTemplate: trimmedTemplate,\n agentContextHint: this.agentContextHint.trim() || null,\n requiredFields: fields,\n allowsCustomScript: this.allowsCustomScript,\n sortOrder: this.sortOrder,\n isActive: this.isActive,\n };\n this.api.updateOutboundPurpose(this.purpose.purposeId, body).subscribe({\n next: (updated) => {\n this.saving.set(false);\n this.saved.emit(updated);\n this.close();\n },\n error: () => {\n this.saving.set(false);\n this.error.set('Failed to save purpose template.');\n },\n });\n return;\n }\n\n const body: CreateOutboundPurposeRequest = {\n label: trimmedLabel,\n description: this.description.trim(),\n sampleOpening: this.sampleOpening.trim(),\n openingTemplate: trimmedTemplate,\n agentContextHint: this.agentContextHint.trim() || null,\n requiredFields: fields,\n allowsCustomScript: this.allowsCustomScript,\n sortOrder: this.sortOrder,\n };\n this.api.createOutboundPurpose(body).subscribe({\n next: (created) => {\n this.saving.set(false);\n this.saved.emit(created);\n this.close();\n },\n error: () => {\n this.saving.set(false);\n this.error.set('Failed to create purpose template.');\n },\n });\n }\n\n private resetForm(): void {\n this.error.set(null);\n this.saving.set(false);\n if (this.purpose) {\n this.label = this.purpose.label;\n this.description = this.purpose.description;\n this.sampleOpening = this.purpose.sampleOpening;\n this.openingTemplate = this.purpose.openingTemplate;\n this.agentContextHint = this.purpose.agentContextHint ?? '';\n this.requiredFields = new Set(this.purpose.requiredFields);\n this.allowsCustomScript = this.purpose.allowsCustomScript;\n this.sortOrder = this.purpose.sortOrder;\n this.isActive = this.purpose.isActive;\n this.placeholders = this.purpose.placeholders?.length\n ? [...this.purpose.placeholders]\n : [...DEFAULT_PLACEHOLDERS];\n } else {\n this.label = '';\n this.description = '';\n this.sampleOpening = '';\n this.openingTemplate = 'Hi {{patientName}}, this is {{practiceName}}.';\n this.agentContextHint = '';\n this.requiredFields = new Set();\n this.allowsCustomScript = false;\n this.sortOrder = 1;\n this.isActive = true;\n this.placeholders = [...DEFAULT_PLACEHOLDERS];\n }\n }\n}\n","@if (open) {\n <app-modal\n [title]=\"isEdit ? 'Edit outbound purpose' : 'New outbound purpose'\"\n subtitle=\"Configure dialer fields and AI opening script\"\n maxWidth=\"720px\"\n (closed)=\"close()\"\n >\n <form class=\"purpose-form\" (ngSubmit)=\"submit()\" novalidate>\n <div class=\"purpose-form__grid\">\n <label class=\"purpose-form__field purpose-form__field--full\">\n <span class=\"eds-label\">Label <span class=\"purpose-form__req\">*</span></span>\n <input type=\"text\" class=\"purpose-form__input\" [(ngModel)]=\"label\" name=\"label\" required />\n </label>\n\n <label class=\"purpose-form__field purpose-form__field--full\">\n <span class=\"eds-label\">Description</span>\n <input type=\"text\" class=\"purpose-form__input\" [(ngModel)]=\"description\" name=\"description\" />\n </label>\n\n <label class=\"purpose-form__field purpose-form__field--full\">\n <span class=\"eds-label\">Sample opening (plain preview, max 500)</span>\n <textarea\n class=\"purpose-form__textarea\"\n rows=\"3\"\n maxlength=\"500\"\n [(ngModel)]=\"sampleOpening\"\n name=\"sampleOpening\"\n ></textarea>\n <span class=\"purpose-form__hint\">{{ sampleOpening.length }}/500</span>\n </label>\n\n <div class=\"purpose-form__field purpose-form__field--full\">\n <span class=\"eds-label\">Opening template <span class=\"purpose-form__req\">*</span></span>\n <div class=\"purpose-form__chips\">\n @for (chip of placeholders; track chip.token) {\n <button type=\"button\" class=\"purpose-form__chip\" (click)=\"insertPlaceholder(chip.token)\">\n {{ chip.label }}\n </button>\n }\n </div>\n <textarea\n #templateInput\n class=\"purpose-form__textarea\"\n rows=\"4\"\n [(ngModel)]=\"openingTemplate\"\n name=\"openingTemplate\"\n required\n ></textarea>\n </div>\n\n <label class=\"purpose-form__field purpose-form__field--full\">\n <span class=\"eds-label\">Agent context hint</span>\n <textarea\n class=\"purpose-form__textarea\"\n rows=\"2\"\n [(ngModel)]=\"agentContextHint\"\n name=\"agentContextHint\"\n placeholder=\"Optional guidance for the AI after the opening\"\n ></textarea>\n </label>\n\n <fieldset class=\"purpose-form__field purpose-form__field--full\">\n <legend class=\"eds-label\">Required fields</legend>\n <div class=\"purpose-form__checks\">\n @for (opt of fieldOptions; track opt.value) {\n <label class=\"purpose-form__check\">\n <input\n type=\"checkbox\"\n [checked]=\"isRequiredSelected(opt.value)\"\n (change)=\"toggleRequired(opt.value)\"\n />\n {{ opt.label }}\n </label>\n }\n </div>\n </fieldset>\n\n <label class=\"purpose-form__check purpose-form__field--full\">\n <input type=\"checkbox\" [(ngModel)]=\"allowsCustomScript\" name=\"allowsCustomScript\" />\n Allows custom script (dialer shows free-text script field)\n </label>\n\n <label class=\"purpose-form__field\">\n <span class=\"eds-label\">Sort order</span>\n <input type=\"number\" class=\"purpose-form__input\" [(ngModel)]=\"sortOrder\" name=\"sortOrder\" min=\"0\" />\n </label>\n\n @if (isEdit) {\n <label class=\"purpose-form__check\">\n <input type=\"checkbox\" [(ngModel)]=\"isActive\" name=\"isActive\" />\n Active\n </label>\n }\n </div>\n\n <section class=\"purpose-form__preview eds-card\">\n <h3 class=\"eds-label\">Live preview</h3>\n <p class=\"purpose-form__preview-text\">{{ previewText }}</p>\n </section>\n\n @if (error()) {\n <p class=\"purpose-form__error\" role=\"alert\">{{ error() }}</p>\n }\n\n <footer class=\"purpose-form__footer\">\n <eds-button variant=\"secondary\" type=\"button\" (click)=\"close()\" [disabled]=\"saving()\">\n Cancel\n </eds-button>\n <eds-button variant=\"primary\" type=\"submit\" [disabled]=\"saving()\">\n {{ saving() ? 'Saving…' : isEdit ? 'Save changes' : 'Create purpose' }}\n </eds-button>\n </footer>\n </form>\n </app-modal>\n}\n","import { ChangeDetectionStrategy, Component, inject, OnInit, signal } from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nimport { OutboundPurpose } from '../../models/outbound-purpose.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { formatRequiredFields } from '../../utils/outbound-purpose.util';\nimport { OutboundPurposeFormModalComponent } from '../../components/outbound-purpose-form-modal/outbound-purpose-form-modal.component';\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-outbound-purposes-page',\n imports: [\n RouterLink,\n EdsBadgeComponent,\n EdsButtonComponent,\n EdsIconComponent,\n OutboundPurposeFormModalComponent,\n ],\n templateUrl: './outbound-purposes-page.component.html',\n styleUrl: './outbound-purposes-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class OutboundPurposesPageComponent implements OnInit {\n private readonly api = inject(AiReceptionistApiService);\n\n protected readonly purposes = signal<OutboundPurpose[]>([]);\n protected readonly loading = signal(true);\n protected readonly error = signal<string | null>(null);\n protected readonly modalOpen = signal(false);\n protected readonly editing = signal<OutboundPurpose | null>(null);\n\n protected formatRequiredFields = formatRequiredFields;\n\n ngOnInit(): void {\n this.load();\n }\n\n protected load(): void {\n this.loading.set(true);\n this.error.set(null);\n this.api.getOutboundPurposes(true).subscribe({\n next: ({ purposes }) => {\n this.purposes.set(purposes);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.error.set('Failed to load outbound purposes.');\n },\n });\n }\n\n protected openCreate(): void {\n this.editing.set(null);\n this.modalOpen.set(true);\n }\n\n protected openEdit(purpose: OutboundPurpose): void {\n this.editing.set(purpose);\n this.modalOpen.set(true);\n }\n\n protected closeModal(): void {\n this.modalOpen.set(false);\n this.editing.set(null);\n }\n\n protected onSaved(): void {\n this.load();\n }\n\n protected toggleActive(purpose: OutboundPurpose, active: boolean): void {\n this.api.updateOutboundPurpose(purpose.purposeId, { isActive: active }).subscribe({\n next: (updated) => {\n this.purposes.update((list) =>\n list.map((p) => (p.purposeId === updated.purposeId ? updated : p)),\n );\n },\n error: () => this.load(),\n });\n }\n\n protected deletePurpose(purpose: OutboundPurpose): void {\n if (purpose.isSystem) {\n this.toggleActive(purpose, false);\n return;\n }\n if (!confirm(`Delete \"${purpose.label}\"? This cannot be undone.`)) return;\n this.api.deleteOutboundPurpose(purpose.purposeId).subscribe({\n next: () => this.load(),\n error: () => this.error.set('Failed to delete purpose.'),\n });\n }\n\n protected actionLabel(purpose: OutboundPurpose): string {\n return purpose.isSystem ? 'Deactivate' : 'Delete';\n }\n}\n","<div class=\"eds-page outbound-purposes-page\">\n <header class=\"outbound-purposes-page__header\">\n <div>\n <a routerLink=\"../settings\" class=\"outbound-purposes-page__back eds-body-sm\">\n <eds-icon name=\"arrow_back\" [size]=\"16\" /> Settings\n </a>\n <h1 class=\"eds-h1\">Outbound Call Purposes</h1>\n <p class=\"eds-body-sm\">Templates that drive outbound dialer fields and AI opening scripts</p>\n </div>\n <eds-button variant=\"primary\" (click)=\"openCreate()\">\n <eds-icon name=\"add\" [size]=\"18\" /> New purpose\n </eds-button>\n </header>\n\n @if (loading()) {\n <p class=\"eds-body-sm\">Loading purposes…</p>\n } @else if (error()) {\n <p class=\"outbound-purposes-page__error eds-body-sm\" role=\"alert\">{{ error() }}</p>\n } @else {\n <article class=\"eds-card outbound-purposes-page__table-card\">\n <table class=\"eds-table\">\n <thead>\n <tr>\n <th>Label</th>\n <th>Description</th>\n <th>Required fields</th>\n <th>System</th>\n <th>Active</th>\n <th>Sort</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (p of purposes(); track p.purposeId) {\n <tr>\n <td class=\"eds-body-sm-bold\">{{ p.label }}</td>\n <td class=\"eds-body-sm\">{{ p.description || '—' }}</td>\n <td class=\"eds-body-sm\">{{ formatRequiredFields(p.requiredFields) }}</td>\n <td>\n @if (p.isSystem) {\n <eds-badge tone=\"brand\">System</eds-badge>\n } @else {\n <span class=\"eds-body-sm\">—</span>\n }\n </td>\n <td>\n <label class=\"outbound-purposes-page__toggle\">\n <input\n type=\"checkbox\"\n [checked]=\"p.isActive\"\n (change)=\"toggleActive(p, $any($event.target).checked)\"\n />\n </label>\n </td>\n <td class=\"eds-mono-sm\">{{ p.sortOrder }}</td>\n <td class=\"outbound-purposes-page__actions\">\n <button type=\"button\" class=\"outbound-purposes-page__link\" (click)=\"openEdit(p)\">\n Edit\n </button>\n <button type=\"button\" class=\"outbound-purposes-page__link\" (click)=\"deletePurpose(p)\">\n {{ actionLabel(p) }}\n </button>\n </td>\n </tr>\n } @empty {\n <tr>\n <td colspan=\"7\" class=\"eds-body-sm\">No outbound purposes configured.</td>\n </tr>\n }\n </tbody>\n </table>\n </article>\n }\n\n <eds-outbound-purpose-form-modal\n [open]=\"modalOpen()\"\n [purpose]=\"editing()\"\n (closed)=\"closeModal()\"\n (saved)=\"onSaved()\"\n />\n</div>\n"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import { inject, signal, computed, ChangeDetectionStrategy, Component } from '@a
3
3
  import * as i1 from '@angular/forms';
4
4
  import { FormsModule } from '@angular/forms';
5
5
  import { RouterLink } from '@angular/router';
6
- import { A as AiReceptionistApiService, T as ToastService, W as WELCOME_MESSAGE_MAX, f as buildAutoWelcomeTemplate, g as resolveWelcomePreview, a as EdsBadgeComponent, E as EdsButtonComponent, b as EdsIconComponent } from './edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-DvJ2Ygc1.mjs';
6
+ import { A as AiReceptionistApiService, T as ToastService, W as WELCOME_MESSAGE_MAX, f as buildAutoWelcomeTemplate, g as resolveWelcomePreview, a as EdsBadgeComponent, E as EdsButtonComponent, b as EdsIconComponent } from './edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-CMhknpGf.mjs';
7
7
 
8
8
  /** Curated ElevenLabs voices — keep in sync with backend `tts-voice-presets.ts`. */
9
9
  const DEFAULT_TTS_VOICE_ID = '7EzWGsX10sAS4c9m9cPf';
@@ -506,4 +506,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
506
506
  }] });
507
507
 
508
508
  export { SettingsPageComponent };
509
- //# sourceMappingURL=edvak99-voice-receptionist-widget-settings-page.component-k-1Z4CXg.mjs.map
509
+ //# sourceMappingURL=edvak99-voice-receptionist-widget-settings-page.component-Bo3XNK3b.mjs.map