@edvak99/voice-receptionist-widget 1.1.2 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +3 -0
  2. package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-DT9UKvQO.mjs +307 -0
  3. package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-DT9UKvQO.mjs.map +1 -0
  4. package/fesm2022/{edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-CMhknpGf.mjs → edvak99-voice-receptionist-widget-ai-receptionist-api.service-48cifVPF.mjs} +1351 -579
  5. package/fesm2022/edvak99-voice-receptionist-widget-ai-receptionist-api.service-48cifVPF.mjs.map +1 -0
  6. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-C5inEHJw.mjs +278 -0
  7. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-C5inEHJw.mjs.map +1 -0
  8. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-sYhM20CE.mjs +418 -0
  9. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-sYhM20CE.mjs.map +1 -0
  10. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-DpwajEOE.mjs +194 -0
  11. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-DpwajEOE.mjs.map +1 -0
  12. package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-AN6GcSDq.mjs → edvak99-voice-receptionist-widget-call-recording-player.component-CgkRcFOl.mjs} +5 -4
  13. package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-AN6GcSDq.mjs.map → edvak99-voice-receptionist-widget-call-recording-player.component-CgkRcFOl.mjs.map} +1 -1
  14. package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-Cy_Bf7AO.mjs → edvak99-voice-receptionist-widget-call-review.service-CIMcjGKX.mjs} +2 -2
  15. package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-Cy_Bf7AO.mjs.map → edvak99-voice-receptionist-widget-call-review.service-CIMcjGKX.mjs.map} +1 -1
  16. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-Deh3jPgo.mjs +21 -0
  17. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-Deh3jPgo.mjs.map +1 -0
  18. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-CxbO0eDS.mjs +440 -0
  19. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-CxbO0eDS.mjs.map +1 -0
  20. package/fesm2022/{edvak99-voice-receptionist-widget-eds-elapsed.pipe-ouRlPpwT.mjs → edvak99-voice-receptionist-widget-dashboard-socket.service-BX91r74O.mjs} +5 -21
  21. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-socket.service-BX91r74O.mjs.map +1 -0
  22. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-CWRiJGfv.mjs +38 -0
  23. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-CWRiJGfv.mjs.map +1 -0
  24. package/fesm2022/edvak99-voice-receptionist-widget-eds-button.component-Bg5T5BN8.mjs +27 -0
  25. package/fesm2022/edvak99-voice-receptionist-widget-eds-button.component-Bg5T5BN8.mjs.map +1 -0
  26. package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-BFCiJOT3.mjs +22 -0
  27. package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-BFCiJOT3.mjs.map +1 -0
  28. package/fesm2022/{edvak99-voice-receptionist-widget-live-calls-list.service-CDtFRW8w.mjs → edvak99-voice-receptionist-widget-eds-pulse-dot.component-BPY6xN7C.mjs} +15 -5
  29. package/fesm2022/edvak99-voice-receptionist-widget-eds-pulse-dot.component-BPY6xN7C.mjs.map +1 -0
  30. package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-BsBQIS_f.mjs +203 -0
  31. package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-BsBQIS_f.mjs.map +1 -0
  32. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-CaSDMxpV.mjs +81 -0
  33. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-CaSDMxpV.mjs.map +1 -0
  34. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-Cy3ND-c-.mjs +1070 -0
  35. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-Cy3ND-c-.mjs.map +1 -0
  36. package/fesm2022/edvak99-voice-receptionist-widget-modal.component-COfi7biN.mjs +48 -0
  37. package/fesm2022/edvak99-voice-receptionist-widget-modal.component-COfi7biN.mjs.map +1 -0
  38. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-Bdh4QfFe.mjs +127 -0
  39. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-Bdh4QfFe.mjs.map +1 -0
  40. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-fHVzpiVk.mjs +268 -0
  41. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-fHVzpiVk.mjs.map +1 -0
  42. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-Bok64X2q.mjs +968 -0
  43. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-Bok64X2q.mjs.map +1 -0
  44. package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-Bb9lPcYi.mjs +317 -0
  45. package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-Bb9lPcYi.mjs.map +1 -0
  46. package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-CJLa5pia.mjs → edvak99-voice-receptionist-widget-wizard-page.component-BZVlWLWh.mjs} +6 -4
  47. package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-CJLa5pia.mjs.map → edvak99-voice-receptionist-widget-wizard-page.component-BZVlWLWh.mjs.map} +1 -1
  48. package/fesm2022/edvak99-voice-receptionist-widget.mjs +1 -1
  49. package/lib/components/call-conversation-panel/call-conversation-panel.component.d.ts +9 -6
  50. package/lib/components/call-tasks-panel/call-tasks-panel.component.d.ts +8 -8
  51. package/lib/components/knowledge-test-modal/knowledge-test-modal.component.d.ts +28 -0
  52. package/lib/components/live-transcript-panel/live-transcript-panel.component.d.ts +7 -4
  53. package/lib/components/outbound-dial-modal/outbound-dial-modal.component.d.ts +26 -0
  54. package/lib/layout/eds-module-nav.component.d.ts +0 -3
  55. package/lib/mocks/agent-activity.seed.d.ts +2 -0
  56. package/lib/models/agent-activity.types.d.ts +54 -0
  57. package/lib/models/ai-receptionist.types.d.ts +26 -0
  58. package/lib/models/api-dto.types.d.ts +18 -0
  59. package/lib/models/live-transcript.types.d.ts +2 -1
  60. package/lib/models/outbound-patient.types.d.ts +23 -0
  61. package/lib/models/outbound-purpose.types.d.ts +2 -0
  62. package/lib/models/pagination.d.ts +11 -0
  63. package/lib/models/staff-media.types.d.ts +36 -0
  64. package/lib/pages/activities-page/activities-page.component.d.ts +57 -0
  65. package/lib/pages/analytics-page/analytics-page.component.d.ts +38 -14
  66. package/lib/pages/call-history-detail-page/call-history-detail-page.component.d.ts +2 -3
  67. package/lib/pages/call-history-page/call-history-page.component.d.ts +16 -9
  68. package/lib/pages/dashboard-page/dashboard-page.component.d.ts +12 -8
  69. package/lib/pages/live-calls-page/live-calls-page.component.d.ts +14 -24
  70. package/lib/pages/live-monitor-page/live-monitor-page.component.d.ts +34 -1
  71. package/lib/pages/settings-page/settings-fields.config.d.ts +16 -0
  72. package/lib/pages/settings-page/settings-page.component.d.ts +48 -14
  73. package/lib/pages/tasks-page/tasks-page.component.d.ts +6 -0
  74. package/lib/services/ai-receptionist-api.mock.d.ts +44 -9
  75. package/lib/services/ai-receptionist-api.service.d.ts +65 -10
  76. package/lib/services/live-transcript.service.d.ts +1 -0
  77. package/lib/services/staff-media.service.d.ts +52 -0
  78. package/lib/ui/eds-avatar.component.d.ts +5 -2
  79. package/lib/ui/eds-button.component.d.ts +1 -1
  80. package/lib/utils/call-history-display.util.d.ts +21 -0
  81. package/lib/utils/outbound-purpose.util.d.ts +19 -0
  82. package/lib/utils/transcript-timing.util.d.ts +1 -1
  83. package/lib/utils/welcome-message.util.d.ts +1 -1
  84. package/package.json +2 -1
  85. package/styles/_index.scss +5 -40
  86. package/styles/chat-ui.scss +18 -18
  87. package/styles/eds.scss +188 -119
  88. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-CW5OKmik.mjs +0 -113
  89. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-CW5OKmik.mjs.map +0 -1
  90. package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-DL1GfQyF.mjs +0 -35
  91. package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-DL1GfQyF.mjs.map +0 -1
  92. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-CTwfUHUf.mjs +0 -316
  93. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-CTwfUHUf.mjs.map +0 -1
  94. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-Cj4wxd4e.mjs +0 -138
  95. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-Cj4wxd4e.mjs.map +0 -1
  96. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-DQLIw7xb.mjs +0 -70
  97. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-DQLIw7xb.mjs.map +0 -1
  98. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-DzdIt2A7.mjs +0 -248
  99. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-DzdIt2A7.mjs.map +0 -1
  100. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-PCnIWeOA.mjs +0 -27
  101. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-PCnIWeOA.mjs.map +0 -1
  102. package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-ouRlPpwT.mjs.map +0 -1
  103. package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-CMhknpGf.mjs.map +0 -1
  104. package/fesm2022/edvak99-voice-receptionist-widget-knowledge-hub.page-cZqBuull.mjs +0 -575
  105. package/fesm2022/edvak99-voice-receptionist-widget-knowledge-hub.page-cZqBuull.mjs.map +0 -1
  106. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-list.service-CDtFRW8w.mjs.map +0 -1
  107. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-DrYzXJQW.mjs +0 -115
  108. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-DrYzXJQW.mjs.map +0 -1
  109. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-D7dlk0y2.mjs +0 -574
  110. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-D7dlk0y2.mjs.map +0 -1
  111. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-BQECIuJu.mjs +0 -54
  112. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-BQECIuJu.mjs.map +0 -1
  113. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-CJ8NEjcj.mjs +0 -265
  114. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-CJ8NEjcj.mjs.map +0 -1
  115. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-Bo3XNK3b.mjs +0 -509
  116. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-Bo3XNK3b.mjs.map +0 -1
  117. package/fesm2022/edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs +0 -52
  118. package/fesm2022/edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs.map +0 -1
  119. package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-CBwl15NP.mjs +0 -237
  120. package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-CBwl15NP.mjs.map +0 -1
  121. package/lib/knowledge/components/faq-empty-state/faq-empty-state.component.d.ts +0 -22
  122. package/lib/knowledge/components/faq-form/faq-form.component.d.ts +0 -27
  123. package/lib/knowledge/components/faq-search-tester/faq-search-tester.component.d.ts +0 -17
  124. package/lib/knowledge/mocks/practice-faq.seed.d.ts +0 -2
  125. package/lib/knowledge/models/practice-faq.model.d.ts +0 -47
  126. package/lib/knowledge/pages/knowledge-hub.page.d.ts +0 -47
  127. package/lib/knowledge/services/practice-faq-api.mock.d.ts +0 -16
  128. package/lib/knowledge/services/practice-faq-api.service.d.ts +0 -22
  129. package/lib/knowledge/utils/faq.util.d.ts +0 -3
  130. package/lib/layout/eds-topbar.component.d.ts +0 -29
  131. package/lib/pages/audit-page/audit-page.component.d.ts +0 -14
  132. package/lib/ui/eds-waveform.component.d.ts +0 -8
@@ -1 +0,0 @@
1
- {"version":3,"file":"edvak99-voice-receptionist-widget-settings-page.component-Bo3XNK3b.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/pages/settings-page/tts-voice-presets.ts","../../../projects/voice-receptionist-widget/src/lib/pages/settings-page/settings-fields.config.ts","../../../projects/voice-receptionist-widget/src/lib/pages/settings-page/settings-page.component.ts","../../../projects/voice-receptionist-widget/src/lib/pages/settings-page/settings-page.component.html"],"sourcesContent":["/** Curated ElevenLabs voices — keep in sync with backend `tts-voice-presets.ts`. */\n\nexport interface TtsVoicePreset {\n id: string;\n label: string;\n}\n\nexport const DEFAULT_TTS_VOICE_ID = '7EzWGsX10sAS4c9m9cPf';\n\nexport const TTS_VOICE_PRESETS: readonly TtsVoicePreset[] = [\n {\n id: '7EzWGsX10sAS4c9m9cPf',\n label: 'Jack John – Conversational and Upbeat',\n },\n {\n id: 'NUjosfEayZAdRcDmcHM8',\n label: 'Madison – Cool, Calm & Conversational',\n },\n {\n id: 'gE0owC0H9C8SzfDyIUtB',\n label: 'Ivanna – Sassy, Condescending and Clear',\n },\n {\n id: 'Uc7anshoV8mdBhDnEZEX',\n label: 'Cecily – Clear and Warm',\n },\n] as const;\n","import { AgentSettings } from '../../models/ai-receptionist.types';\nimport { TTS_VOICE_PRESETS } from './tts-voice-presets';\n\nexport type SettingsSection = Exclude<keyof AgentSettings, 'safety' | 'effectiveWelcomeMessage'>;\n\nexport interface SettingsFieldOption {\n value: string;\n label: string;\n}\n\nexport interface SettingsFieldMeta {\n key: string;\n label: string;\n description: string;\n type: 'text' | 'number' | 'boolean' | 'select';\n options?: SettingsFieldOption[];\n readOnly?: boolean;\n}\n\nexport interface SettingsSectionMeta {\n title: string;\n description: string;\n}\n\nexport const SETTINGS_SECTION_META: Record<SettingsSection, SettingsSectionMeta> = {\n general: {\n title: 'General',\n description: 'Practice identity and how the AI introduces itself on calls.',\n },\n phone: {\n title: 'Phone',\n description: 'Inbound routing, after-hours behavior, and ring timing.',\n },\n tasks: {\n title: 'Tasks & follow-ups',\n description: 'When the AI should create staff tasks after a call.',\n },\n scheduling: {\n title: 'Scheduling',\n description: 'Rules for booking and rescheduling appointments.',\n },\n refill: {\n title: 'Medication refills',\n description: 'Refill approval windows and staff review requirements.',\n },\n verify: {\n title: 'Patient verification',\n description: 'Identity checks before accessing chart or scheduling data.',\n },\n escalation: {\n title: 'Escalation',\n description: 'When to offer a human or transfer to reception.',\n },\n outbound: {\n title: 'Outbound calling',\n description: 'Outbound dialer defaults. Purpose templates are managed separately.',\n },\n transcripts: {\n title: 'Transcripts & recording',\n description: 'Retention and PHI handling for call transcripts.',\n },\n advanced: {\n title: 'Advanced',\n description: 'Model and debug options — read-only. Contact Edvak support to change.',\n },\n};\n\n/** Entire sections where every field is read-only (including unknown API fields). */\nexport const READ_ONLY_SECTIONS = new Set<SettingsSection>(['advanced', 'verify']);\n\n/** Settings tabs that stay visible but cannot be selected/edited. */\nexport const DISABLED_SETTINGS_TABS = new Set<SettingsSection>(['verify']);\n\n/** Individual fields locked for compliance, telephony, or core agent identity. */\nexport const READ_ONLY_FIELD_KEYS: ReadonlyArray<{ section: SettingsSection; key: string; reason: string }> = [\n { section: 'general', key: 'practiceName', reason: 'Core practice identity' },\n { section: 'general', key: 'agentName', reason: 'AI agent identity' },\n { section: 'general', key: 'timezone', reason: 'Practice timezone' },\n { section: 'general', key: 'language', reason: 'Default language' },\n { section: 'phone', key: 'mainNumber', reason: 'Inbound phone routing' },\n { section: 'outbound', key: 'callerId', reason: 'Outbound caller ID' },\n { section: 'transcripts', key: 'retainDays', reason: 'Recording retention policy' },\n { section: 'transcripts', key: 'redactPhi', reason: 'PHI redaction policy' },\n { section: 'advanced', key: 'modelVersion', reason: 'Voice AI model profile' },\n { section: 'advanced', key: 'debugMode', reason: 'Debug logging' },\n];\n\nconst READ_ONLY_LOOKUP = new Set(\n READ_ONLY_FIELD_KEYS.map(({ section, key }) => `${section}.${key}`),\n);\n\nexport function isFieldReadOnly(section: SettingsSection, key: string): boolean {\n if (READ_ONLY_SECTIONS.has(section)) return true;\n return READ_ONLY_LOOKUP.has(`${section}.${key}`);\n}\n\nexport function readOnlyFieldReason(section: SettingsSection, key: string): string | undefined {\n return READ_ONLY_FIELD_KEYS.find((f) => f.section === section && f.key === key)?.reason;\n}\n\nexport const SETTINGS_FIELDS: Record<SettingsSection, SettingsFieldMeta[]> = {\n general: [\n {\n key: 'practiceName',\n label: 'Practice name',\n description: 'Spoken on greetings and confirmations.',\n type: 'text',\n },\n {\n key: 'agentName',\n label: 'AI agent name',\n description: 'How the assistant introduces itself (e.g. “Ava”).',\n type: 'text',\n },\n {\n key: 'timezone',\n label: 'Timezone',\n description: 'Used for hours, scheduling, and call timestamps.',\n type: 'text',\n },\n {\n key: 'language',\n label: 'Default language',\n description: 'Primary language for the AI receptionist.',\n type: 'text',\n },\n {\n key: 'ttsVoiceId',\n label: 'Voice',\n description: 'Spoken voice used on phone calls for this practice.',\n type: 'select',\n options: TTS_VOICE_PRESETS.map((p) => ({ value: p.id, label: p.label })),\n },\n ],\n phone: [\n {\n key: 'mainNumber',\n label: 'Main phone number',\n description: 'Primary inbound number patients call.',\n type: 'text',\n },\n {\n key: 'afterHours',\n label: 'After-hours mode',\n description: 'Use after-hours greeting and routing outside business hours.',\n type: 'boolean',\n },\n {\n key: 'ringTimeout',\n label: 'Ring timeout (seconds)',\n description: 'How long to ring before the AI answers.',\n type: 'number',\n },\n ],\n tasks: [\n {\n key: 'autoCreate',\n label: 'Auto-create tasks',\n description: 'Create a staff task when the AI cannot fully resolve a request.',\n type: 'boolean',\n },\n {\n key: 'defaultAssignee',\n label: 'Default assignee',\n description: 'Team or role new tasks are routed to.',\n type: 'text',\n },\n ],\n scheduling: [\n {\n key: 'leadTimeHours',\n label: 'Minimum lead time (hours)',\n description: 'Earliest bookable slot from now.',\n type: 'number',\n },\n {\n key: 'allowSameDay',\n label: 'Allow same-day booking',\n description: 'Let patients book appointments later today.',\n type: 'boolean',\n },\n ],\n refill: [\n {\n key: 'autoApproveDays',\n label: 'Auto-approve within (days)',\n description: 'Refills due within this window may be auto-approved.',\n type: 'number',\n },\n {\n key: 'requireStaffReview',\n label: 'Require staff review',\n description: 'All refill requests need staff approval before sending to pharmacy.',\n type: 'boolean',\n },\n ],\n verify: [\n {\n key: 'requireDob',\n label: 'Require date of birth',\n description: 'Ask for DOB before lookup or scheduling.',\n type: 'boolean',\n },\n {\n key: 'requireName',\n label: 'Require full name',\n description: 'Ask for patient name during verification.',\n type: 'boolean',\n },\n {\n key: 'maxAttempts',\n label: 'Max verification attempts',\n description: 'After this many failures, offer transfer to staff.',\n type: 'number',\n },\n ],\n escalation: [\n {\n key: 'sentimentThreshold',\n label: 'Sentiment threshold',\n description: 'Escalate when caller sentiment reaches this level (e.g. frustrated).',\n type: 'text',\n },\n {\n key: 'urgentKeywords',\n label: 'Urgent keywords',\n description: 'Comma-separated phrases that trigger immediate escalation.',\n type: 'text',\n },\n ],\n outbound: [\n {\n key: 'enabled',\n label: 'Outbound calls enabled',\n description: 'Allow staff to place outbound calls from the dashboard.',\n type: 'boolean',\n },\n {\n key: 'callerId',\n label: 'Outbound caller ID',\n description: 'Number shown to patients on outbound calls.',\n type: 'text',\n },\n ],\n transcripts: [\n {\n key: 'retainDays',\n label: 'Retention (days)',\n description: 'How long transcripts and recordings are kept.',\n type: 'number',\n },\n {\n key: 'redactPhi',\n label: 'Redact PHI in transcripts',\n description: 'Mask sensitive identifiers in stored transcripts.',\n type: 'boolean',\n },\n ],\n advanced: [\n {\n key: 'modelVersion',\n label: 'Model version',\n description: 'Voice AI model profile (set by Edvak support).',\n type: 'text',\n },\n {\n key: 'debugMode',\n label: 'Debug mode',\n description: 'Verbose logging for troubleshooting — not for production.',\n type: 'boolean',\n },\n ],\n};\n\n/** Fallback label for API fields not listed in config. */\nexport function humanizeFieldKey(key: string): string {\n return key\n .replace(/([A-Z])/g, ' $1')\n .replace(/_/g, ' ')\n .trim()\n .replace(/^\\w/, (c) => c.toUpperCase());\n}\n\nexport function resolveFieldMeta(\n section: SettingsSection,\n key: string,\n value: string | boolean | number,\n): SettingsFieldMeta {\n const known = SETTINGS_FIELDS[section]?.find((f) => f.key === key);\n if (known) return known;\n return {\n key,\n label: humanizeFieldKey(key),\n description: '',\n type: typeof value === 'boolean' ? 'boolean' : typeof value === 'number' ? 'number' : 'text',\n };\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, OnInit, signal } from '@angular/core';\n\nimport { FormsModule } from '@angular/forms';\n\nimport { RouterLink } from '@angular/router';\n\n\n\nimport { AgentSettings } from '../../models/ai-receptionist.types';\n\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\n\nimport { EdsBadgeComponent } from '../../ui/eds-badge.component';\n\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\n\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\n\nimport { ToastService } from '../../shared/toast.service';\n\nimport {\n\n buildAutoWelcomeTemplate,\n\n resolveWelcomePreview,\n\n WELCOME_MESSAGE_MAX,\n\n} from '../../utils/welcome-message.util';\n\nimport {\n DISABLED_SETTINGS_TABS,\n isFieldReadOnly,\n READ_ONLY_SECTIONS,\n resolveFieldMeta,\n SETTINGS_FIELDS,\n SETTINGS_SECTION_META,\n SettingsFieldMeta,\n SettingsSection,\n} from './settings-fields.config';\n\n\n\ntype SettingsTab = keyof AgentSettings;\n\n\n\nconst GENERAL_IDENTITY_KEYS = new Set(['practiceName', 'agentName']);\n\nconst GENERAL_OTHER_KEYS = new Set(['timezone', 'language', 'ttsVoiceId']);\n\n\n\n@Component({\n selector: 'eds-settings-page',\n imports: [FormsModule, RouterLink, EdsBadgeComponent, EdsButtonComponent, EdsIconComponent],\n templateUrl: './settings-page.component.html',\n styleUrl: './settings-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\n\nexport class SettingsPageComponent implements OnInit {\n\n private readonly api = inject(AiReceptionistApiService);\n\n private readonly toast = inject(ToastService);\n\n private originalSettings: AgentSettings | null = null;\n\n protected readonly isFieldReadOnly = isFieldReadOnly;\n\n protected readonly readOnlySections = READ_ONLY_SECTIONS;\n\n protected readonly disabledTabs = DISABLED_SETTINGS_TABS;\n\n\n\n protected readonly settings = signal<AgentSettings | null>(null);\n\n protected readonly tab = signal<SettingsTab>('general');\n\n protected readonly loading = signal(true);\n\n protected readonly saving = signal(false);\n\n protected readonly saved = signal(false);\n\n\n\n protected readonly welcomeMax = WELCOME_MESSAGE_MAX;\n\n protected readonly previewingVoice = signal(false);\n\n private voicePreviewAudio: HTMLAudioElement | null = null;\n\n\n\n protected readonly tabs: { id: SettingsTab; label: string; icon: string }[] = [\n\n { id: 'general', label: 'General', icon: 'business' },\n\n { id: 'phone', label: 'Phone', icon: 'call' },\n\n { id: 'tasks', label: 'Tasks', icon: 'task_alt' },\n\n { id: 'scheduling', label: 'Scheduling', icon: 'calendar_month' },\n\n { id: 'refill', label: 'Refills', icon: 'medication' },\n\n { id: 'verify', label: 'Verification', icon: 'verified_user' },\n\n { id: 'escalation', label: 'Escalation', icon: 'warning' },\n\n { id: 'outbound', label: 'Outbound', icon: 'call_made' },\n\n { id: 'transcripts', label: 'Transcripts', icon: 'transcribe' },\n\n { id: 'advanced', label: 'Advanced', icon: 'tune' },\n\n { id: 'safety', label: 'Safety', icon: 'health_and_safety' },\n\n ];\n\n\n\n protected readonly sectionMeta = computed(() => {\n\n const id = this.tab();\n\n if (id === 'safety') {\n\n return { title: 'Safety checklist', description: '' };\n\n }\n\n return SETTINGS_SECTION_META[id as SettingsSection];\n\n });\n\n\n\n protected readonly fieldsForTab = computed((): SettingsFieldMeta[] => {\n\n const s = this.settings();\n\n const id = this.tab();\n\n if (!s || id === 'safety') return [];\n\n\n\n const section = s[id] as Record<string, string | boolean | number>;\n\n const configured = SETTINGS_FIELDS[id as SettingsSection] ?? [];\n\n const configuredKeys = new Set(configured.map((f) => f.key));\n\n\n\n const extras = Object.keys(section)\n\n .filter((key) => key !== 'welcomeMessage' && !configuredKeys.has(key))\n\n .map((key) => resolveFieldMeta(id as SettingsSection, key, section[key]));\n\n\n\n return [...configured, ...extras];\n\n });\n\n\n\n protected readonly generalIdentityFields = computed(() =>\n\n this.fieldsForTab().filter((f) => GENERAL_IDENTITY_KEYS.has(f.key)),\n\n );\n\n\n\n protected readonly generalOtherFields = computed(() =>\n\n this.fieldsForTab().filter((f) => GENERAL_OTHER_KEYS.has(f.key)),\n\n );\n\n\n\n protected readonly welcomeMessage = computed(() =>\n\n String(this.settings()?.general['welcomeMessage'] ?? ''),\n\n );\n\n\n\n protected readonly welcomePlaceholder = computed(() => {\n\n const s = this.settings();\n\n if (!s) return '';\n\n return buildAutoWelcomeTemplate(\n\n String(s.general['practiceName'] ?? ''),\n\n String(s.general['agentName'] ?? ''),\n\n );\n\n });\n\n\n\n protected readonly welcomePreview = computed(() => {\n\n const s = this.settings();\n\n if (!s) return '';\n\n return resolveWelcomePreview(\n\n String(s.general['welcomeMessage'] ?? ''),\n\n String(s.general['practiceName'] ?? ''),\n\n String(s.general['agentName'] ?? ''),\n\n );\n\n });\n\n\n\n protected readonly usingDefaultWelcome = computed(() => !this.welcomeMessage().trim());\n\n\n\n protected readonly showRecordingConsentHint = computed(() => {\n\n const t = this.settings()?.transcripts;\n\n if (!t) return false;\n\n const retain = Number(t['retainDays'] ?? 0);\n\n return retain > 0 || t['redactPhi'] === true;\n\n });\n\n\n\n ngOnInit(): void {\n\n this.api.getSettings().subscribe({\n\n next: ({ data }) => {\n\n this.originalSettings = structuredClone(data);\n\n this.settings.set(structuredClone(data));\n\n this.loading.set(false);\n\n },\n\n error: () => {\n\n this.loading.set(false);\n\n this.toast.show('Failed to load agent settings', 'error');\n\n },\n\n });\n\n }\n\n\n\n protected fieldIsReadOnly(section: SettingsTab, key: string): boolean {\n if (section === 'safety' || section === 'effectiveWelcomeMessage') return true;\n return isFieldReadOnly(section, key);\n }\n\n protected sectionIsReadOnly(section: SettingsTab): boolean {\n if (section === 'safety' || section === 'effectiveWelcomeMessage') return true;\n return READ_ONLY_SECTIONS.has(section);\n }\n\n protected isTabDisabled(id: SettingsTab): boolean {\n return id !== 'safety' && id !== 'effectiveWelcomeMessage' && DISABLED_SETTINGS_TABS.has(id);\n }\n\n protected setTab(id: SettingsTab): void {\n if (this.isTabDisabled(id)) return;\n this.tab.set(id);\n }\n\n\n\n protected updateField(section: SettingsTab, key: string, value: string | boolean | number): void {\n\n const current = this.settings();\n\n if (!current || section === 'safety' || isFieldReadOnly(section as SettingsSection, key)) return;\n\n const sectionData = { ...(current[section] as Record<string, string | boolean | number>) };\n\n sectionData[key] = value;\n\n this.settings.set({ ...current, [section]: sectionData });\n\n }\n\n\n\n protected updateWelcomeMessage(value: string): void {\n\n this.updateField('general', 'welcomeMessage', value.slice(0, WELCOME_MESSAGE_MAX));\n\n }\n\n\n\n protected resetWelcomeMessage(): void {\n\n this.updateField('general', 'welcomeMessage', '');\n\n }\n\n protected previewSelectedVoice(): void {\n const voiceId = String(this.fieldValue('general', 'ttsVoiceId') ?? '').trim();\n if (!voiceId || this.previewingVoice()) return;\n\n this.previewingVoice.set(true);\n this.api.previewVoice(voiceId).subscribe({\n next: (blob) => {\n this.previewingVoice.set(false);\n if (this.voicePreviewAudio) {\n this.voicePreviewAudio.pause();\n URL.revokeObjectURL(this.voicePreviewAudio.src);\n this.voicePreviewAudio = null;\n }\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n this.voicePreviewAudio = audio;\n audio.onended = () => {\n URL.revokeObjectURL(url);\n if (this.voicePreviewAudio === audio) this.voicePreviewAudio = null;\n };\n void audio.play().catch(() => {\n this.toast.show('Could not play voice preview in this browser.', 'error');\n URL.revokeObjectURL(url);\n });\n },\n error: () => {\n this.previewingVoice.set(false);\n this.toast.show('Could not generate voice preview. Try again.', 'error');\n },\n });\n }\n\n\n\n protected fieldValue(section: SettingsTab, key: string): string | boolean | number {\n\n const s = this.settings();\n\n if (!s || section === 'safety') return '';\n\n return (s[section] as Record<string, string | boolean | number>)[key];\n\n }\n\n\n\n protected save(): void {\n\n const s = this.settings();\n\n const orig = this.originalSettings;\n\n if (!s || !orig) return;\n\n\n\n const payload = structuredClone(s);\n\n const wm = String(payload.general['welcomeMessage'] ?? '').trim();\n\n payload.general['welcomeMessage'] = wm;\n\n this.restoreReadOnlyFields(payload, orig);\n\n\n\n this.saving.set(true);\n\n this.api.putSettings(payload).subscribe({\n\n next: ({ data }) => {\n\n this.originalSettings = structuredClone(data);\n\n this.settings.set(structuredClone(data));\n\n this.saving.set(false);\n\n this.saved.set(true);\n\n this.toast.show('Agent settings saved', 'success');\n\n setTimeout(() => this.saved.set(false), 2000);\n\n },\n\n error: () => {\n\n this.saving.set(false);\n\n this.toast.show('Failed to save agent settings', 'error');\n\n },\n\n });\n\n }\n\n private restoreReadOnlyFields(payload: AgentSettings, orig: AgentSettings): void {\n const editableSections: SettingsSection[] = [\n 'general',\n 'phone',\n 'tasks',\n 'scheduling',\n 'refill',\n 'verify',\n 'escalation',\n 'outbound',\n 'transcripts',\n 'advanced',\n ];\n\n for (const sectionKey of editableSections) {\n if (READ_ONLY_SECTIONS.has(sectionKey)) {\n payload[sectionKey] = structuredClone(orig[sectionKey]);\n continue;\n }\n\n const payloadSection = payload[sectionKey] as Record<string, string | boolean | number>;\n const origSection = orig[sectionKey] as Record<string, string | boolean | number>;\n for (const key of Object.keys(payloadSection)) {\n if (isFieldReadOnly(sectionKey, key)) {\n payloadSection[key] = origSection[key];\n }\n }\n }\n }\n\n}\n\n\n","<div class=\"eds-page settings-page\">\n <header class=\"settings-page__header\">\n <div>\n <h1 class=\"eds-h1\">Agent settings</h1>\n <p class=\"settings-page__subtitle\">Configure AI receptionist behavior and safety</p>\n </div>\n <div class=\"settings-page__save-row\">\n @if (saved()) {\n <span class=\"settings-page__saved\">Saved</span>\n }\n <eds-button variant=\"primary\" [disabled]=\"saving()\" (click)=\"save()\">\n <eds-icon name=\"save\" [size]=\"18\" />\n {{ saving() ? 'Saving…' : 'Save changes' }}\n </eds-button>\n </div>\n </header>\n\n @if (loading()) {\n <p class=\"settings-page__loading\">Loading settings…</p>\n } @else if (settings()) {\n <div class=\"settings-page__layout\">\n <nav class=\"eds-card settings-page__sidebar\" aria-label=\"Settings sections\">\n @for (t of tabs; track t.id) {\n <button\n type=\"button\"\n class=\"settings-page__nav-item\"\n [class.settings-page__nav-item--active]=\"tab() === t.id\"\n [class.settings-page__nav-item--disabled]=\"isTabDisabled(t.id)\"\n [disabled]=\"isTabDisabled(t.id)\"\n [attr.title]=\"isTabDisabled(t.id) ? 'This section is currently disabled' : null\"\n (click)=\"setTab(t.id)\"\n >\n <eds-icon [name]=\"t.icon\" [size]=\"18\" />\n {{ t.label }}\n @if (isTabDisabled(t.id)) {\n <span class=\"settings-page__nav-disabled-badge\">Disabled</span>\n }\n </button>\n }\n </nav>\n\n <article class=\"eds-card settings-page__panel\">\n @if (tab() === 'safety') {\n <header class=\"settings-page__panel-head\">\n <h2 class=\"settings-page__panel-title\">Safety checklist</h2>\n <p class=\"settings-page__panel-desc\">\n Read-only compliance status. Contact Edvak support to change safety configuration.\n </p>\n </header>\n <ul class=\"settings-page__safety\">\n @for (item of settings()!.safety; track item.id) {\n <li>\n <eds-icon\n [name]=\"item.status === 'ok' ? 'check_circle' : 'error'\"\n [size]=\"22\"\n />\n <span class=\"settings-page__safety-label\">{{ item.label }}</span>\n <eds-badge [tone]=\"item.status === 'ok' ? 'pos' : 'notice'\">\n {{ item.status === 'ok' ? 'Pass' : 'Needs attention' }}\n </eds-badge>\n </li>\n }\n </ul>\n } @else {\n <header class=\"settings-page__panel-head\">\n <h2 class=\"settings-page__panel-title\">{{ sectionMeta().title }}</h2>\n <p class=\"settings-page__panel-desc\">{{ sectionMeta().description }}</p>\n </header>\n\n @if (sectionIsReadOnly(tab())) {\n <p class=\"settings-page__readonly-banner\">\n <eds-icon name=\"lock\" [size]=\"18\" />\n These settings are managed by Edvak. Contact support to request changes.\n </p>\n }\n\n @if (tab() === 'general') {\n <a routerLink=\"../knowledge\" class=\"settings-page__quick-link\">\n <eds-icon name=\"menu_book\" [size]=\"22\" />\n <div>\n <span class=\"settings-page__quick-link-title\">Practice Knowledge Base</span>\n <span class=\"settings-page__quick-link-desc\">FAQ answers your AI uses on phone calls</span>\n </div>\n <eds-icon name=\"chevron_right\" [size]=\"20\" />\n </a>\n\n <div class=\"settings-page__fields settings-page__fields--general\">\n @for (field of generalIdentityFields(); track field.key) {\n <label\n class=\"settings-page__field\"\n [class.settings-page__field--readonly]=\"isFieldReadOnly('general', field.key)\"\n >\n <span class=\"settings-page__field-label\">\n {{ field.label }}\n @if (isFieldReadOnly('general', field.key)) {\n <span class=\"settings-page__readonly-badge\">Read-only</span>\n }\n </span>\n @if (field.description) {\n <span class=\"settings-page__field-desc\">{{ field.description }}</span>\n }\n <input\n type=\"text\"\n class=\"settings-page__input\"\n [class.settings-page__input--readonly]=\"isFieldReadOnly('general', field.key)\"\n [disabled]=\"isFieldReadOnly('general', field.key)\"\n [ngModel]=\"fieldValue('general', field.key)\"\n (ngModelChange)=\"updateField('general', field.key, $event)\"\n />\n </label>\n }\n\n <section class=\"settings-page__welcome\">\n <label class=\"settings-page__field settings-page__field--full\">\n <span class=\"settings-page__field-label\">Welcome message</span>\n <span class=\"settings-page__field-desc\">\n Spoken automatically when a caller connects. Leave blank to use the default template.\n </span>\n <textarea\n class=\"settings-page__textarea\"\n rows=\"4\"\n [maxlength]=\"welcomeMax\"\n [placeholder]=\"welcomePlaceholder()\"\n [ngModel]=\"welcomeMessage()\"\n (ngModelChange)=\"updateWelcomeMessage($event)\"\n ></textarea>\n <span class=\"settings-page__char-count\">\n {{ welcomeMessage().length }}/{{ welcomeMax }}\n </span>\n @if (showRecordingConsentHint()) {\n <p class=\"settings-page__recording-hint\">\n Call recording is enabled — consider mentioning that the call may be recorded or monitored.\n </p>\n }\n </label>\n\n <div class=\"settings-page__welcome-preview eds-card\">\n <div class=\"settings-page__welcome-preview-head\">\n <eds-icon name=\"record_voice_over\" [size]=\"20\" />\n <span class=\"settings-page__field-label\">Live preview</span>\n @if (usingDefaultWelcome()) {\n <eds-badge tone=\"gray\">Default template</eds-badge>\n }\n </div>\n <p class=\"settings-page__welcome-preview-text\">“{{ welcomePreview() }}”</p>\n </div>\n\n @if (!usingDefaultWelcome()) {\n <eds-button variant=\"secondary\" type=\"button\" (click)=\"resetWelcomeMessage()\">\n Reset to default\n </eds-button>\n }\n </section>\n\n @for (field of generalOtherFields(); track field.key) {\n <label\n class=\"settings-page__field\"\n [class.settings-page__field--readonly]=\"isFieldReadOnly('general', field.key)\"\n >\n <span class=\"settings-page__field-label\">\n {{ field.label }}\n @if (isFieldReadOnly('general', field.key)) {\n <span class=\"settings-page__readonly-badge\">Read-only</span>\n }\n </span>\n @if (field.description) {\n <span class=\"settings-page__field-desc\">{{ field.description }}</span>\n }\n @if (field.type === 'select' && field.options?.length) {\n <select\n class=\"settings-page__input settings-page__select\"\n [class.settings-page__input--readonly]=\"isFieldReadOnly('general', field.key)\"\n [disabled]=\"isFieldReadOnly('general', field.key)\"\n [ngModel]=\"fieldValue('general', field.key)\"\n (ngModelChange)=\"updateField('general', field.key, $event)\"\n >\n @for (opt of field.options; track opt.value) {\n <option [ngValue]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n @if (field.key === 'ttsVoiceId') {\n <div class=\"settings-page__voice-preview-row\">\n <eds-button\n variant=\"secondary\"\n type=\"button\"\n [disabled]=\"previewingVoice()\"\n (click)=\"previewSelectedVoice()\"\n >\n {{ previewingVoice() ? 'Generating…' : 'Preview voice' }}\n </eds-button>\n <span class=\"settings-page__field-desc\">\n Plays a short sample in the browser — save to use on phone calls.\n </span>\n </div>\n }\n } @else {\n <input\n type=\"text\"\n class=\"settings-page__input\"\n [class.settings-page__input--readonly]=\"isFieldReadOnly('general', field.key)\"\n [disabled]=\"isFieldReadOnly('general', field.key)\"\n [ngModel]=\"fieldValue('general', field.key)\"\n (ngModelChange)=\"updateField('general', field.key, $event)\"\n />\n }\n </label>\n }\n </div>\n } @else {\n @if (tab() === 'outbound') {\n <a [routerLink]=\"['../settings/outbound-purposes']\" class=\"settings-page__quick-link\">\n <eds-icon name=\"call_made\" [size]=\"22\" />\n <div>\n <span class=\"settings-page__quick-link-title\">Outbound Call Purposes</span>\n <span class=\"settings-page__quick-link-desc\">Templates, required fields, and opening scripts</span>\n </div>\n <eds-icon name=\"chevron_right\" [size]=\"20\" />\n </a>\n }\n\n <div class=\"settings-page__fields\">\n @for (field of fieldsForTab(); track field.key) {\n @if (field.type === 'boolean') {\n <label\n class=\"settings-page__toggle-row\"\n [class.settings-page__toggle-row--readonly]=\"fieldIsReadOnly(tab(), field.key)\"\n >\n <div class=\"settings-page__toggle-copy\">\n <span class=\"settings-page__field-label\">\n {{ field.label }}\n @if (fieldIsReadOnly(tab(), field.key)) {\n <span class=\"settings-page__readonly-badge\">Read-only</span>\n }\n </span>\n @if (field.description) {\n <span class=\"settings-page__field-desc\">{{ field.description }}</span>\n }\n </div>\n <input\n type=\"checkbox\"\n class=\"settings-page__checkbox\"\n [disabled]=\"fieldIsReadOnly(tab(), field.key)\"\n [ngModel]=\"fieldValue(tab(), field.key)\"\n (ngModelChange)=\"updateField(tab(), field.key, $event)\"\n />\n </label>\n } @else {\n <label\n class=\"settings-page__field\"\n [class.settings-page__field--readonly]=\"fieldIsReadOnly(tab(), field.key)\"\n >\n <span class=\"settings-page__field-label\">\n {{ field.label }}\n @if (fieldIsReadOnly(tab(), field.key)) {\n <span class=\"settings-page__readonly-badge\">Read-only</span>\n }\n </span>\n @if (field.description) {\n <span class=\"settings-page__field-desc\">{{ field.description }}</span>\n }\n @if (field.type === 'number') {\n <input\n type=\"number\"\n class=\"settings-page__input\"\n [class.settings-page__input--readonly]=\"fieldIsReadOnly(tab(), field.key)\"\n [disabled]=\"fieldIsReadOnly(tab(), field.key)\"\n [ngModel]=\"fieldValue(tab(), field.key)\"\n (ngModelChange)=\"updateField(tab(), field.key, +$event)\"\n />\n } @else if (field.type === 'select' && field.options?.length) {\n <select\n class=\"settings-page__input settings-page__select\"\n [class.settings-page__input--readonly]=\"fieldIsReadOnly(tab(), field.key)\"\n [disabled]=\"fieldIsReadOnly(tab(), field.key)\"\n [ngModel]=\"fieldValue(tab(), field.key)\"\n (ngModelChange)=\"updateField(tab(), field.key, $event)\"\n >\n @for (opt of field.options; track opt.value) {\n <option [ngValue]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n } @else {\n <input\n type=\"text\"\n class=\"settings-page__input\"\n [class.settings-page__input--readonly]=\"fieldIsReadOnly(tab(), field.key)\"\n [disabled]=\"fieldIsReadOnly(tab(), field.key)\"\n [ngModel]=\"fieldValue(tab(), field.key)\"\n (ngModelChange)=\"updateField(tab(), field.key, $event)\"\n />\n }\n </label>\n }\n }\n </div>\n }\n }\n </article>\n </div>\n }\n</div>\n"],"names":[],"mappings":"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"}
@@ -1,52 +0,0 @@
1
- const TASK_TYPE_OPTIONS = [
2
- 'Refill request',
3
- 'Callback',
4
- 'Billing',
5
- 'Scheduling',
6
- 'Clinical',
7
- 'Other',
8
- ];
9
- function taskStatusLabel(status) {
10
- if (status === 'in_progress')
11
- return 'In progress';
12
- if (status === 'done')
13
- return 'Done';
14
- return 'Open';
15
- }
16
- function taskStatusTone(status) {
17
- const map = {
18
- open: 'brand',
19
- in_progress: 'notice',
20
- done: 'pos',
21
- };
22
- return map[status];
23
- }
24
- function taskPriorityTone(priority) {
25
- return priority === 'urgent' ? 'neg' : 'gray';
26
- }
27
- function taskPriorityLabel(priority) {
28
- return priority === 'urgent' ? 'Urgent' : 'Normal';
29
- }
30
- function taskSourceLabel(source) {
31
- if (source === 'voice')
32
- return 'Voice';
33
- if (source === 'sync')
34
- return 'Sync';
35
- return 'Manual';
36
- }
37
- function taskTypeTone(type) {
38
- const key = type.toLowerCase();
39
- if (key.includes('refill'))
40
- return 'violet';
41
- if (key.includes('callback'))
42
- return 'brand';
43
- if (key.includes('billing'))
44
- return 'notice';
45
- return 'gray';
46
- }
47
- function taskCallRoute(callId) {
48
- return callId.startsWith('LC') ? ['../live', callId] : ['../history', callId];
49
- }
50
-
51
- export { TASK_TYPE_OPTIONS as T, taskStatusTone as a, taskTypeTone as b, taskPriorityLabel as c, taskPriorityTone as d, taskSourceLabel as e, taskCallRoute as f, taskStatusLabel as t };
52
- //# sourceMappingURL=edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/utils/task.util.ts"],"sourcesContent":["import { BadgeTone } from '../ui/eds-badge.component';\nimport { TaskPriority, TaskSource, TaskStatus } from '../models/ai-receptionist.types';\n\nexport const TASK_TYPE_OPTIONS = [\n 'Refill request',\n 'Callback',\n 'Billing',\n 'Scheduling',\n 'Clinical',\n 'Other',\n] as const;\n\nexport function taskStatusLabel(status: TaskStatus): string {\n if (status === 'in_progress') return 'In progress';\n if (status === 'done') return 'Done';\n return 'Open';\n}\n\nexport function taskStatusTone(status: TaskStatus): BadgeTone {\n const map: Record<TaskStatus, BadgeTone> = {\n open: 'brand',\n in_progress: 'notice',\n done: 'pos',\n };\n return map[status];\n}\n\nexport function taskPriorityTone(priority: TaskPriority): BadgeTone {\n return priority === 'urgent' ? 'neg' : 'gray';\n}\n\nexport function taskPriorityLabel(priority: TaskPriority): string {\n return priority === 'urgent' ? 'Urgent' : 'Normal';\n}\n\nexport function taskSourceLabel(source: TaskSource): string {\n if (source === 'voice') return 'Voice';\n if (source === 'sync') return 'Sync';\n return 'Manual';\n}\n\nexport function taskTypeTone(type: string): BadgeTone {\n const key = type.toLowerCase();\n if (key.includes('refill')) return 'violet';\n if (key.includes('callback')) return 'brand';\n if (key.includes('billing')) return 'notice';\n return 'gray';\n}\n\nexport function taskCallRoute(callId: string): string[] {\n return callId.startsWith('LC') ? ['../live', callId] : ['../history', callId];\n}\n"],"names":[],"mappings":"AAGO,MAAM,iBAAiB,GAAG;IAC/B,gBAAgB;IAChB,UAAU;IACV,SAAS;IACT,YAAY;IACZ,UAAU;IACV,OAAO;;AAGH,SAAU,eAAe,CAAC,MAAkB,EAAA;IAChD,IAAI,MAAM,KAAK,aAAa;AAAE,QAAA,OAAO,aAAa;IAClD,IAAI,MAAM,KAAK,MAAM;AAAE,QAAA,OAAO,MAAM;AACpC,IAAA,OAAO,MAAM;AACf;AAEM,SAAU,cAAc,CAAC,MAAkB,EAAA;AAC/C,IAAA,MAAM,GAAG,GAAkC;AACzC,QAAA,IAAI,EAAE,OAAO;AACb,QAAA,WAAW,EAAE,QAAQ;AACrB,QAAA,IAAI,EAAE,KAAK;KACZ;AACD,IAAA,OAAO,GAAG,CAAC,MAAM,CAAC;AACpB;AAEM,SAAU,gBAAgB,CAAC,QAAsB,EAAA;IACrD,OAAO,QAAQ,KAAK,QAAQ,GAAG,KAAK,GAAG,MAAM;AAC/C;AAEM,SAAU,iBAAiB,CAAC,QAAsB,EAAA;IACtD,OAAO,QAAQ,KAAK,QAAQ,GAAG,QAAQ,GAAG,QAAQ;AACpD;AAEM,SAAU,eAAe,CAAC,MAAkB,EAAA;IAChD,IAAI,MAAM,KAAK,OAAO;AAAE,QAAA,OAAO,OAAO;IACtC,IAAI,MAAM,KAAK,MAAM;AAAE,QAAA,OAAO,MAAM;AACpC,IAAA,OAAO,QAAQ;AACjB;AAEM,SAAU,YAAY,CAAC,IAAY,EAAA;AACvC,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE;AAC9B,IAAA,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;AAAE,QAAA,OAAO,QAAQ;AAC3C,IAAA,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC;AAAE,QAAA,OAAO,OAAO;AAC5C,IAAA,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC;AAAE,QAAA,OAAO,QAAQ;AAC5C,IAAA,OAAO,MAAM;AACf;AAEM,SAAU,aAAa,CAAC,MAAc,EAAA;IAC1C,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC;AAC/E;;;;"}
@@ -1,237 +0,0 @@
1
- import { DatePipe } from '@angular/common';
2
- import * as i0 from '@angular/core';
3
- import { inject, signal, Input, ChangeDetectionStrategy, Component, input, output, computed } from '@angular/core';
4
- import { RouterLink, ActivatedRoute } from '@angular/router';
5
- import { T as ToastService, a as EdsBadgeComponent, E as EdsButtonComponent, b as EdsIconComponent, A as AiReceptionistApiService } from './edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-CMhknpGf.mjs';
6
- import { t as taskStatusLabel, a as taskStatusTone, c as taskPriorityLabel, d as taskPriorityTone, e as taskSourceLabel, b as taskTypeTone, f as taskCallRoute, T as TASK_TYPE_OPTIONS } from './edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs';
7
-
8
- class CopyButtonComponent {
9
- constructor() {
10
- /** Raw value to copy (full ID / phone / etc.) */
11
- this.value = '';
12
- /** Accessible label, e.g. "patient ID" */
13
- this.label = 'value';
14
- this.toast = inject(ToastService);
15
- this.copied = signal(false);
16
- }
17
- get copyValue() {
18
- const v = this.value?.trim();
19
- return v && v !== '—' ? v : '';
20
- }
21
- get ariaLabel() {
22
- return this.copied() ? 'Copied' : `Copy ${this.label}`;
23
- }
24
- async onCopy(event) {
25
- event.stopPropagation();
26
- const text = this.copyValue;
27
- if (!text)
28
- return;
29
- try {
30
- await navigator.clipboard.writeText(text);
31
- this.copied.set(true);
32
- setTimeout(() => this.copied.set(false), 1500);
33
- }
34
- catch {
35
- this.toast.show('Could not copy — clipboard unavailable', 'error', 2500);
36
- }
37
- }
38
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: CopyButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
39
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: CopyButtonComponent, isStandalone: true, selector: "app-copy-btn", inputs: { value: "value", label: "label" }, ngImport: i0, template: `
40
- @if (copyValue) {
41
- <button
42
- type="button"
43
- class="copy-btn"
44
- (click)="onCopy($event)"
45
- [attr.aria-label]="ariaLabel"
46
- [title]="copied() ? 'Copied' : 'Copy to clipboard'"
47
- >
48
- @if (copied()) {
49
- <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor"
50
- stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
51
- <polyline points="20 6 9 17 4 12" />
52
- </svg>
53
- } @else {
54
- <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor"
55
- stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
56
- <rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
57
- <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
58
- </svg>
59
- }
60
- </button>
61
- }
62
- `, isInline: true, styles: [".copy-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:22px;height:22px;padding:0;border:1px solid var(--color-border);border-radius:4px;background:var(--color-surface);color:var(--color-text-muted);cursor:pointer;transition:background .1s ease,color .1s ease,border-color .1s ease}.copy-btn:hover{background:var(--color-surface-alt);color:var(--color-primary);border-color:var(--color-border-strong)}.copy-btn:focus-visible{outline:2px solid var(--color-primary);outline-offset:1px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
63
- }
64
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: CopyButtonComponent, decorators: [{
65
- type: Component,
66
- args: [{ selector: 'app-copy-btn', standalone: true, template: `
67
- @if (copyValue) {
68
- <button
69
- type="button"
70
- class="copy-btn"
71
- (click)="onCopy($event)"
72
- [attr.aria-label]="ariaLabel"
73
- [title]="copied() ? 'Copied' : 'Copy to clipboard'"
74
- >
75
- @if (copied()) {
76
- <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor"
77
- stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
78
- <polyline points="20 6 9 17 4 12" />
79
- </svg>
80
- } @else {
81
- <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor"
82
- stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
83
- <rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
84
- <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
85
- </svg>
86
- }
87
- </button>
88
- }
89
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".copy-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:22px;height:22px;padding:0;border:1px solid var(--color-border);border-radius:4px;background:var(--color-surface);color:var(--color-text-muted);cursor:pointer;transition:background .1s ease,color .1s ease,border-color .1s ease}.copy-btn:hover{background:var(--color-surface-alt);color:var(--color-primary);border-color:var(--color-border-strong)}.copy-btn:focus-visible{outline:2px solid var(--color-primary);outline-offset:1px}\n"] }]
90
- }], propDecorators: { value: [{
91
- type: Input
92
- }], label: [{
93
- type: Input
94
- }] } });
95
-
96
- class TaskDetailDrawerComponent {
97
- constructor() {
98
- this.task = input.required();
99
- this.closed = output();
100
- this.statusChange = output();
101
- this.taskStatusLabel = taskStatusLabel;
102
- this.taskStatusTone = taskStatusTone;
103
- this.taskPriorityLabel = taskPriorityLabel;
104
- this.taskPriorityTone = taskPriorityTone;
105
- this.taskSourceLabel = taskSourceLabel;
106
- this.taskTypeTone = taskTypeTone;
107
- this.taskCallRoute = taskCallRoute;
108
- }
109
- close() {
110
- this.closed.emit();
111
- }
112
- markDone() {
113
- const t = this.task();
114
- this.statusChange.emit(t.status === 'done' ? 'open' : 'done');
115
- }
116
- onBackdropClick(event) {
117
- if (event.target === event.currentTarget)
118
- this.close();
119
- }
120
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TaskDetailDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
121
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: TaskDetailDrawerComponent, isStandalone: true, selector: "eds-task-detail-drawer", inputs: { task: { classPropertyName: "task", publicName: "task", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { closed: "closed", statusChange: "statusChange" }, ngImport: i0, template: "<div class=\"task-drawer__backdrop\" (click)=\"onBackdropClick($event)\">\n <aside class=\"task-drawer\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"task().title\">\n <header class=\"task-drawer__head\">\n <div>\n <eds-badge [tone]=\"taskTypeTone(task().type)\">{{ task().type }}</eds-badge>\n <h2 class=\"task-drawer__title\">{{ task().title }}</h2>\n </div>\n <button type=\"button\" class=\"task-drawer__close\" (click)=\"close()\" aria-label=\"Close\">\n <eds-icon name=\"close\" [size]=\"22\" />\n </button>\n </header>\n\n <div class=\"task-drawer__body\">\n <section class=\"task-drawer__section\">\n <h3 class=\"eds-label\">Description</h3>\n <p class=\"task-drawer__description\">{{ task().description || '\u2014' }}</p>\n </section>\n\n <dl class=\"task-drawer__meta\">\n <div>\n <dt class=\"eds-label\">Patient</dt>\n <dd>{{ task().patient }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Assignee</dt>\n <dd>{{ task().assignee }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Status</dt>\n <dd><eds-badge [tone]=\"taskStatusTone(task().status)\">{{ taskStatusLabel(task().status) }}</eds-badge></dd>\n </div>\n <div>\n <dt class=\"eds-label\">Priority</dt>\n <dd><eds-badge [tone]=\"taskPriorityTone(task().priority)\">{{ taskPriorityLabel(task().priority) }}</eds-badge></dd>\n </div>\n <div>\n <dt class=\"eds-label\">Source</dt>\n <dd>{{ taskSourceLabel(task().source) }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Created</dt>\n <dd>{{ task().created | date: 'medium' }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Call</dt>\n <dd>\n @if (task().callId) {\n <a [routerLink]=\"taskCallRoute(task().callId!)\" class=\"task-drawer__link\">{{ task().callId }}</a>\n } @else {\n \u2014\n }\n </dd>\n </div>\n </dl>\n\n @if (task().edvakTaskId || task().edvakStatus || task().medicationName || task().medicationId) {\n <section class=\"task-drawer__section task-drawer__section--edvak\">\n <h3 class=\"eds-label\">Edvak / refill details</h3>\n <dl class=\"task-drawer__meta\">\n @if (task().edvakTaskId) {\n <div>\n <dt class=\"eds-label\">Edvak task ID</dt>\n <dd class=\"task-drawer__copy-row\">\n <code>{{ task().edvakTaskId }}</code>\n <app-copy-btn [value]=\"task().edvakTaskId\" label=\"Edvak task ID\" />\n </dd>\n </div>\n }\n @if (task().edvakStatus) {\n <div>\n <dt class=\"eds-label\">Edvak status</dt>\n <dd><eds-badge tone=\"brand\">{{ task().edvakStatus }}</eds-badge></dd>\n </div>\n }\n @if (task().medicationName) {\n <div>\n <dt class=\"eds-label\">Medication</dt>\n <dd>{{ task().medicationName }}</dd>\n </div>\n }\n @if (task().medicationId) {\n <div>\n <dt class=\"eds-label\">Medication ID</dt>\n <dd class=\"task-drawer__copy-row\">\n <code>{{ task().medicationId }}</code>\n <app-copy-btn [value]=\"task().medicationId\" label=\"medication ID\" />\n </dd>\n </div>\n }\n </dl>\n </section>\n }\n </div>\n\n <footer class=\"task-drawer__foot\">\n <eds-button variant=\"secondary\" type=\"button\" (click)=\"markDone()\">\n {{ task().status === 'done' ? 'Reopen task' : 'Mark done' }}\n </eds-button>\n </footer>\n </aside>\n</div>\n", styles: [".task-drawer__backdrop{position:fixed;inset:0;z-index:200;background:#0f172a66;display:flex;justify-content:flex-end}.task-drawer{width:min(440px,100%);height:100%;background:#fff;box-shadow:-8px 0 32px #0f172a1f;display:flex;flex-direction:column;animation:task-drawer-in .2s ease}.task-drawer__head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:20px 24px;border-bottom:1px solid var(--color-border, #e2e8f0)}.task-drawer__title{margin:8px 0 0;font-size:20px;font-weight:600;line-height:1.3;color:var(--color-text, #0f172a)}.task-drawer__close{border:none;background:none;padding:4px;cursor:pointer;color:var(--color-text-muted, #64748b);border-radius:6px}.task-drawer__close:hover{background:var(--color-surface-alt, #f1f5f9)}.task-drawer__body{flex:1;overflow-y:auto;padding:20px 24px;display:flex;flex-direction:column;gap:24px}.task-drawer__section--edvak{padding:14px;border-radius:8px;background:var(--color-surface-alt, #f8fafc);border:1px solid var(--color-border, #e2e8f0)}.task-drawer__description{margin:8px 0 0;font-size:15px;line-height:1.55;color:var(--color-text, #0f172a);white-space:pre-wrap}.task-drawer__meta{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:0}.task-drawer__meta dt{margin:0 0 4px}.task-drawer__meta dd{margin:0;font-size:14px;color:var(--color-text, #0f172a)}.task-drawer__copy-row{display:inline-flex;align-items:center;gap:6px}.task-drawer__copy-row code{font-family:ui-monospace,monospace;font-size:12px;background:var(--color-surface-alt, #f1f5f9);padding:2px 6px;border-radius:4px}.task-drawer__link{color:var(--color-primary, #3681f4);text-decoration:none;font-weight:500}.task-drawer__link:hover{text-decoration:underline}.task-drawer__foot{padding:16px 24px;border-top:1px solid var(--color-border, #e2e8f0)}@keyframes task-drawer-in{0%{transform:translate(100%)}to{transform:translate(0)}}\n"], dependencies: [{ kind: "pipe", type: DatePipe, name: "date" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: CopyButtonComponent, selector: "app-copy-btn", inputs: ["value", "label"] }, { kind: "component", type: EdsBadgeComponent, selector: "eds-badge", inputs: ["tone"] }, { kind: "component", type: EdsButtonComponent, selector: "eds-button", inputs: ["variant", "type", "disabled"] }, { kind: "component", type: EdsIconComponent, selector: "eds-icon", inputs: ["name", "size", "fill", "weight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
122
- }
123
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TaskDetailDrawerComponent, decorators: [{
124
- type: Component,
125
- args: [{ selector: 'eds-task-detail-drawer', imports: [
126
- DatePipe,
127
- RouterLink,
128
- CopyButtonComponent,
129
- EdsBadgeComponent,
130
- EdsButtonComponent,
131
- EdsIconComponent,
132
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"task-drawer__backdrop\" (click)=\"onBackdropClick($event)\">\n <aside class=\"task-drawer\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"task().title\">\n <header class=\"task-drawer__head\">\n <div>\n <eds-badge [tone]=\"taskTypeTone(task().type)\">{{ task().type }}</eds-badge>\n <h2 class=\"task-drawer__title\">{{ task().title }}</h2>\n </div>\n <button type=\"button\" class=\"task-drawer__close\" (click)=\"close()\" aria-label=\"Close\">\n <eds-icon name=\"close\" [size]=\"22\" />\n </button>\n </header>\n\n <div class=\"task-drawer__body\">\n <section class=\"task-drawer__section\">\n <h3 class=\"eds-label\">Description</h3>\n <p class=\"task-drawer__description\">{{ task().description || '\u2014' }}</p>\n </section>\n\n <dl class=\"task-drawer__meta\">\n <div>\n <dt class=\"eds-label\">Patient</dt>\n <dd>{{ task().patient }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Assignee</dt>\n <dd>{{ task().assignee }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Status</dt>\n <dd><eds-badge [tone]=\"taskStatusTone(task().status)\">{{ taskStatusLabel(task().status) }}</eds-badge></dd>\n </div>\n <div>\n <dt class=\"eds-label\">Priority</dt>\n <dd><eds-badge [tone]=\"taskPriorityTone(task().priority)\">{{ taskPriorityLabel(task().priority) }}</eds-badge></dd>\n </div>\n <div>\n <dt class=\"eds-label\">Source</dt>\n <dd>{{ taskSourceLabel(task().source) }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Created</dt>\n <dd>{{ task().created | date: 'medium' }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Call</dt>\n <dd>\n @if (task().callId) {\n <a [routerLink]=\"taskCallRoute(task().callId!)\" class=\"task-drawer__link\">{{ task().callId }}</a>\n } @else {\n \u2014\n }\n </dd>\n </div>\n </dl>\n\n @if (task().edvakTaskId || task().edvakStatus || task().medicationName || task().medicationId) {\n <section class=\"task-drawer__section task-drawer__section--edvak\">\n <h3 class=\"eds-label\">Edvak / refill details</h3>\n <dl class=\"task-drawer__meta\">\n @if (task().edvakTaskId) {\n <div>\n <dt class=\"eds-label\">Edvak task ID</dt>\n <dd class=\"task-drawer__copy-row\">\n <code>{{ task().edvakTaskId }}</code>\n <app-copy-btn [value]=\"task().edvakTaskId\" label=\"Edvak task ID\" />\n </dd>\n </div>\n }\n @if (task().edvakStatus) {\n <div>\n <dt class=\"eds-label\">Edvak status</dt>\n <dd><eds-badge tone=\"brand\">{{ task().edvakStatus }}</eds-badge></dd>\n </div>\n }\n @if (task().medicationName) {\n <div>\n <dt class=\"eds-label\">Medication</dt>\n <dd>{{ task().medicationName }}</dd>\n </div>\n }\n @if (task().medicationId) {\n <div>\n <dt class=\"eds-label\">Medication ID</dt>\n <dd class=\"task-drawer__copy-row\">\n <code>{{ task().medicationId }}</code>\n <app-copy-btn [value]=\"task().medicationId\" label=\"medication ID\" />\n </dd>\n </div>\n }\n </dl>\n </section>\n }\n </div>\n\n <footer class=\"task-drawer__foot\">\n <eds-button variant=\"secondary\" type=\"button\" (click)=\"markDone()\">\n {{ task().status === 'done' ? 'Reopen task' : 'Mark done' }}\n </eds-button>\n </footer>\n </aside>\n</div>\n", styles: [".task-drawer__backdrop{position:fixed;inset:0;z-index:200;background:#0f172a66;display:flex;justify-content:flex-end}.task-drawer{width:min(440px,100%);height:100%;background:#fff;box-shadow:-8px 0 32px #0f172a1f;display:flex;flex-direction:column;animation:task-drawer-in .2s ease}.task-drawer__head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:20px 24px;border-bottom:1px solid var(--color-border, #e2e8f0)}.task-drawer__title{margin:8px 0 0;font-size:20px;font-weight:600;line-height:1.3;color:var(--color-text, #0f172a)}.task-drawer__close{border:none;background:none;padding:4px;cursor:pointer;color:var(--color-text-muted, #64748b);border-radius:6px}.task-drawer__close:hover{background:var(--color-surface-alt, #f1f5f9)}.task-drawer__body{flex:1;overflow-y:auto;padding:20px 24px;display:flex;flex-direction:column;gap:24px}.task-drawer__section--edvak{padding:14px;border-radius:8px;background:var(--color-surface-alt, #f8fafc);border:1px solid var(--color-border, #e2e8f0)}.task-drawer__description{margin:8px 0 0;font-size:15px;line-height:1.55;color:var(--color-text, #0f172a);white-space:pre-wrap}.task-drawer__meta{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:0}.task-drawer__meta dt{margin:0 0 4px}.task-drawer__meta dd{margin:0;font-size:14px;color:var(--color-text, #0f172a)}.task-drawer__copy-row{display:inline-flex;align-items:center;gap:6px}.task-drawer__copy-row code{font-family:ui-monospace,monospace;font-size:12px;background:var(--color-surface-alt, #f1f5f9);padding:2px 6px;border-radius:4px}.task-drawer__link{color:var(--color-primary, #3681f4);text-decoration:none;font-weight:500}.task-drawer__link:hover{text-decoration:underline}.task-drawer__foot{padding:16px 24px;border-top:1px solid var(--color-border, #e2e8f0)}@keyframes task-drawer-in{0%{transform:translate(100%)}to{transform:translate(0)}}\n"] }]
133
- }] });
134
-
135
- class TasksPageComponent {
136
- constructor() {
137
- this.api = inject(AiReceptionistApiService);
138
- this.route = inject(ActivatedRoute);
139
- this.tasks = signal([]);
140
- this.loading = signal(true);
141
- this.selectedTask = signal(null);
142
- this.statusFilter = signal('');
143
- this.typeFilter = signal('');
144
- this.sourceFilter = signal('');
145
- this.callIdFilter = signal('');
146
- this.typeOptions = TASK_TYPE_OPTIONS;
147
- this.taskStatusLabel = taskStatusLabel;
148
- this.taskStatusTone = taskStatusTone;
149
- this.taskPriorityTone = taskPriorityTone;
150
- this.taskSourceLabel = taskSourceLabel;
151
- this.taskTypeTone = taskTypeTone;
152
- this.taskCallRoute = taskCallRoute;
153
- this.hasActiveFilters = computed(() => !!this.statusFilter() ||
154
- !!this.typeFilter() ||
155
- !!this.sourceFilter() ||
156
- !!this.callIdFilter());
157
- }
158
- ngOnInit() {
159
- const callId = this.route.snapshot.queryParamMap.get('callId') ?? '';
160
- if (callId)
161
- this.callIdFilter.set(callId);
162
- this.load();
163
- }
164
- setStatusFilter(value) {
165
- this.statusFilter.set(value);
166
- this.load();
167
- }
168
- setTypeFilter(value) {
169
- this.typeFilter.set(value);
170
- this.load();
171
- }
172
- setSourceFilter(value) {
173
- this.sourceFilter.set(value);
174
- this.load();
175
- }
176
- setCallIdFilter(value) {
177
- this.callIdFilter.set(value);
178
- this.load();
179
- }
180
- clearFilters() {
181
- this.statusFilter.set('');
182
- this.typeFilter.set('');
183
- this.sourceFilter.set('');
184
- this.callIdFilter.set('');
185
- this.load();
186
- }
187
- openTask(task) {
188
- this.selectedTask.set(task);
189
- }
190
- closeDrawer() {
191
- this.selectedTask.set(null);
192
- }
193
- onStatusChange(status) {
194
- const task = this.selectedTask();
195
- if (!task)
196
- return;
197
- this.api.patchTask(task.id, status).subscribe(({ data }) => {
198
- if (data) {
199
- this.selectedTask.set(data);
200
- this.tasks.update((rows) => rows.map((r) => (r.id === data.id ? data : r)));
201
- }
202
- });
203
- }
204
- load() {
205
- this.loading.set(true);
206
- const filters = {};
207
- if (this.statusFilter())
208
- filters.status = this.statusFilter();
209
- if (this.typeFilter())
210
- filters.type = this.typeFilter();
211
- if (this.sourceFilter())
212
- filters.source = this.sourceFilter();
213
- if (this.callIdFilter().trim())
214
- filters.callId = this.callIdFilter().trim();
215
- this.api.getTasks(filters).subscribe({
216
- next: ({ data }) => {
217
- this.tasks.set(data);
218
- this.loading.set(false);
219
- },
220
- error: () => this.loading.set(false),
221
- });
222
- }
223
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TasksPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
224
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: TasksPageComponent, isStandalone: true, selector: "eds-tasks-page", ngImport: i0, template: "<div class=\"eds-page tasks-page\">\n <header class=\"tasks-page__header\">\n <div>\n <h1 class=\"eds-h1\">Tasks & follow-ups</h1>\n <p class=\"eds-body-sm\">Action items from calls \u2014 all types, not just refills</p>\n </div>\n </header>\n\n <section class=\"list-section\">\n <div class=\"list-toolbar\">\n <div class=\"filter-group\">\n <label for=\"task-status\">Status</label>\n <select\n id=\"task-status\"\n class=\"filter-input\"\n [value]=\"statusFilter()\"\n (change)=\"setStatusFilter($any($event.target).value)\"\n >\n <option value=\"\">All</option>\n <option value=\"open\">Open</option>\n <option value=\"in_progress\">In progress</option>\n <option value=\"done\">Done</option>\n </select>\n </div>\n <div class=\"filter-group\">\n <label for=\"task-type\">Type</label>\n <select\n id=\"task-type\"\n class=\"filter-input\"\n [value]=\"typeFilter()\"\n (change)=\"setTypeFilter($any($event.target).value)\"\n >\n <option value=\"\">All types</option>\n @for (t of typeOptions; track t) {\n <option [value]=\"t\">{{ t }}</option>\n }\n </select>\n </div>\n <div class=\"filter-group\">\n <label for=\"task-source\">Source</label>\n <select\n id=\"task-source\"\n class=\"filter-input\"\n [value]=\"sourceFilter()\"\n (change)=\"setSourceFilter($any($event.target).value)\"\n >\n <option value=\"\">All sources</option>\n <option value=\"voice\">Voice</option>\n <option value=\"sync\">Sync</option>\n <option value=\"manual\">Manual</option>\n </select>\n </div>\n <div class=\"filter-group\">\n <label for=\"task-call\">Call ID</label>\n <input\n id=\"task-call\"\n type=\"text\"\n class=\"filter-input\"\n [value]=\"callIdFilter()\"\n placeholder=\"Filter by call\"\n (change)=\"setCallIdFilter($any($event.target).value)\"\n />\n </div>\n @if (hasActiveFilters()) {\n <button type=\"button\" class=\"link-btn\" (click)=\"clearFilters()\">Clear filters</button>\n }\n </div>\n\n @if (loading()) {\n <p class=\"eds-body-sm tasks-page__loading\">Loading tasks\u2026</p>\n } @else {\n <div class=\"table-wrap\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Created</th>\n <th>Title</th>\n <th>Type</th>\n <th>Patient</th>\n <th>Priority</th>\n <th>Status</th>\n <th>Source</th>\n <th>Call</th>\n </tr>\n </thead>\n <tbody>\n @for (task of tasks(); track task.id) {\n <tr class=\"tasks-page__row\" (click)=\"openTask(task)\">\n <td class=\"cell-muted\">{{ task.created | date: 'MM/dd/yy, h:mm a' }}</td>\n <td class=\"tasks-page__title-cell\">{{ task.title }}</td>\n <td><eds-badge [tone]=\"taskTypeTone(task.type)\">{{ task.type }}</eds-badge></td>\n <td>{{ task.patient }}</td>\n <td>\n <eds-badge [tone]=\"taskPriorityTone(task.priority)\">\n {{ task.priority === 'urgent' ? 'Urgent' : 'Normal' }}\n </eds-badge>\n </td>\n <td><eds-badge [tone]=\"taskStatusTone(task.status)\">{{ taskStatusLabel(task.status) }}</eds-badge></td>\n <td class=\"cell-muted\">{{ taskSourceLabel(task.source) }}</td>\n <td (click)=\"$event.stopPropagation()\">\n @if (task.callId) {\n <a [routerLink]=\"taskCallRoute(task.callId)\" class=\"link-btn\">{{ task.callId }}</a>\n } @else {\n <span class=\"cell-muted\">\u2014</span>\n }\n </td>\n </tr>\n } @empty {\n <tr>\n <td colspan=\"8\" class=\"empty-state\">No tasks match these filters.</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </section>\n</div>\n\n@if (selectedTask(); as task) {\n <eds-task-detail-drawer\n [task]=\"task\"\n (closed)=\"closeDrawer()\"\n (statusChange)=\"onStatusChange($event)\"\n />\n}", styles: [".list-section{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-card);overflow:hidden}.list-toolbar{padding:18px 24px;display:flex;flex-wrap:wrap;align-items:flex-end;gap:14px;border-bottom:1px solid var(--color-border)}.filter-group{display:flex;flex-direction:column;gap:5px}.filter-group label{font-size:12px;font-weight:500;color:var(--color-text-muted)}.filter-input{padding:8px 10px;font-size:13px;min-width:140px}.toolbar-actions{display:flex;align-items:center;gap:8px;margin-left:auto}.result-meta{font-size:12.5px;color:var(--color-text-soft);width:100%;margin-top:4px}.api-banner{margin:0 24px 12px;padding:10px 14px;border-radius:var(--radius-md);font-size:13px}.api-banner-error{background:var(--color-danger-soft);color:var(--color-danger);border:1px solid rgba(231,111,111,.25)}.table-wrap{overflow-x:auto}.data-table{width:100%;border-collapse:collapse;min-width:720px}.data-table thead th{text-align:left;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--color-text-muted);padding:12px 18px;background:var(--color-surface-alt);border-bottom:1px solid var(--color-border);white-space:nowrap}.data-table tbody tr{transition:background .1s ease}.data-table tbody tr:hover{background:var(--color-surface-alt)}.data-table tbody tr+tr{border-top:1px solid var(--color-border)}.data-table tbody td{padding:14px 18px;font-size:13.5px;color:var(--color-text);vertical-align:middle}.cell-muted{color:var(--color-text-muted)}.cell-mono code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:12px;color:var(--color-text-muted);background:var(--color-surface-alt);padding:3px 7px;border-radius:4px}.cell-with-copy{display:inline-flex;align-items:center;gap:6px;max-width:100%}.cell-with-copy .cell-value{min-width:0;overflow:hidden;text-overflow:ellipsis}.empty-state{padding:48px 18px!important;text-align:center;color:var(--color-text-soft);font-size:13px}.pagination{display:flex;align-items:center;justify-content:space-between;padding:14px 24px;border-top:1px solid var(--color-border);font-size:13px;color:var(--color-text-muted)}.pagination-btns{display:flex;gap:8px}.link-btn{background:none;border:none;padding:0;color:var(--color-primary);font-size:13px;font-weight:500;cursor:pointer;text-decoration:none}.link-btn:hover{text-decoration:underline}.advanced-panel{width:100%;display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:12px;padding-top:4px}@media(max-width:920px){.list-toolbar{padding:16px 18px}}.tasks-page__header{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:20px}.tasks-page__loading{padding:24px;margin:0}.tasks-page__row{cursor:pointer}.tasks-page__title-cell{font-weight:500;max-width:280px}\n"], dependencies: [{ kind: "pipe", type: DatePipe, name: "date" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: EdsBadgeComponent, selector: "eds-badge", inputs: ["tone"] }, { kind: "component", type: TaskDetailDrawerComponent, selector: "eds-task-detail-drawer", inputs: ["task"], outputs: ["closed", "statusChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
225
- }
226
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TasksPageComponent, decorators: [{
227
- type: Component,
228
- args: [{ selector: 'eds-tasks-page', imports: [
229
- DatePipe,
230
- RouterLink,
231
- EdsBadgeComponent,
232
- TaskDetailDrawerComponent,
233
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"eds-page tasks-page\">\n <header class=\"tasks-page__header\">\n <div>\n <h1 class=\"eds-h1\">Tasks & follow-ups</h1>\n <p class=\"eds-body-sm\">Action items from calls \u2014 all types, not just refills</p>\n </div>\n </header>\n\n <section class=\"list-section\">\n <div class=\"list-toolbar\">\n <div class=\"filter-group\">\n <label for=\"task-status\">Status</label>\n <select\n id=\"task-status\"\n class=\"filter-input\"\n [value]=\"statusFilter()\"\n (change)=\"setStatusFilter($any($event.target).value)\"\n >\n <option value=\"\">All</option>\n <option value=\"open\">Open</option>\n <option value=\"in_progress\">In progress</option>\n <option value=\"done\">Done</option>\n </select>\n </div>\n <div class=\"filter-group\">\n <label for=\"task-type\">Type</label>\n <select\n id=\"task-type\"\n class=\"filter-input\"\n [value]=\"typeFilter()\"\n (change)=\"setTypeFilter($any($event.target).value)\"\n >\n <option value=\"\">All types</option>\n @for (t of typeOptions; track t) {\n <option [value]=\"t\">{{ t }}</option>\n }\n </select>\n </div>\n <div class=\"filter-group\">\n <label for=\"task-source\">Source</label>\n <select\n id=\"task-source\"\n class=\"filter-input\"\n [value]=\"sourceFilter()\"\n (change)=\"setSourceFilter($any($event.target).value)\"\n >\n <option value=\"\">All sources</option>\n <option value=\"voice\">Voice</option>\n <option value=\"sync\">Sync</option>\n <option value=\"manual\">Manual</option>\n </select>\n </div>\n <div class=\"filter-group\">\n <label for=\"task-call\">Call ID</label>\n <input\n id=\"task-call\"\n type=\"text\"\n class=\"filter-input\"\n [value]=\"callIdFilter()\"\n placeholder=\"Filter by call\"\n (change)=\"setCallIdFilter($any($event.target).value)\"\n />\n </div>\n @if (hasActiveFilters()) {\n <button type=\"button\" class=\"link-btn\" (click)=\"clearFilters()\">Clear filters</button>\n }\n </div>\n\n @if (loading()) {\n <p class=\"eds-body-sm tasks-page__loading\">Loading tasks\u2026</p>\n } @else {\n <div class=\"table-wrap\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Created</th>\n <th>Title</th>\n <th>Type</th>\n <th>Patient</th>\n <th>Priority</th>\n <th>Status</th>\n <th>Source</th>\n <th>Call</th>\n </tr>\n </thead>\n <tbody>\n @for (task of tasks(); track task.id) {\n <tr class=\"tasks-page__row\" (click)=\"openTask(task)\">\n <td class=\"cell-muted\">{{ task.created | date: 'MM/dd/yy, h:mm a' }}</td>\n <td class=\"tasks-page__title-cell\">{{ task.title }}</td>\n <td><eds-badge [tone]=\"taskTypeTone(task.type)\">{{ task.type }}</eds-badge></td>\n <td>{{ task.patient }}</td>\n <td>\n <eds-badge [tone]=\"taskPriorityTone(task.priority)\">\n {{ task.priority === 'urgent' ? 'Urgent' : 'Normal' }}\n </eds-badge>\n </td>\n <td><eds-badge [tone]=\"taskStatusTone(task.status)\">{{ taskStatusLabel(task.status) }}</eds-badge></td>\n <td class=\"cell-muted\">{{ taskSourceLabel(task.source) }}</td>\n <td (click)=\"$event.stopPropagation()\">\n @if (task.callId) {\n <a [routerLink]=\"taskCallRoute(task.callId)\" class=\"link-btn\">{{ task.callId }}</a>\n } @else {\n <span class=\"cell-muted\">\u2014</span>\n }\n </td>\n </tr>\n } @empty {\n <tr>\n <td colspan=\"8\" class=\"empty-state\">No tasks match these filters.</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </section>\n</div>\n\n@if (selectedTask(); as task) {\n <eds-task-detail-drawer\n [task]=\"task\"\n (closed)=\"closeDrawer()\"\n (statusChange)=\"onStatusChange($event)\"\n />\n}", styles: [".list-section{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-card);overflow:hidden}.list-toolbar{padding:18px 24px;display:flex;flex-wrap:wrap;align-items:flex-end;gap:14px;border-bottom:1px solid var(--color-border)}.filter-group{display:flex;flex-direction:column;gap:5px}.filter-group label{font-size:12px;font-weight:500;color:var(--color-text-muted)}.filter-input{padding:8px 10px;font-size:13px;min-width:140px}.toolbar-actions{display:flex;align-items:center;gap:8px;margin-left:auto}.result-meta{font-size:12.5px;color:var(--color-text-soft);width:100%;margin-top:4px}.api-banner{margin:0 24px 12px;padding:10px 14px;border-radius:var(--radius-md);font-size:13px}.api-banner-error{background:var(--color-danger-soft);color:var(--color-danger);border:1px solid rgba(231,111,111,.25)}.table-wrap{overflow-x:auto}.data-table{width:100%;border-collapse:collapse;min-width:720px}.data-table thead th{text-align:left;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--color-text-muted);padding:12px 18px;background:var(--color-surface-alt);border-bottom:1px solid var(--color-border);white-space:nowrap}.data-table tbody tr{transition:background .1s ease}.data-table tbody tr:hover{background:var(--color-surface-alt)}.data-table tbody tr+tr{border-top:1px solid var(--color-border)}.data-table tbody td{padding:14px 18px;font-size:13.5px;color:var(--color-text);vertical-align:middle}.cell-muted{color:var(--color-text-muted)}.cell-mono code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:12px;color:var(--color-text-muted);background:var(--color-surface-alt);padding:3px 7px;border-radius:4px}.cell-with-copy{display:inline-flex;align-items:center;gap:6px;max-width:100%}.cell-with-copy .cell-value{min-width:0;overflow:hidden;text-overflow:ellipsis}.empty-state{padding:48px 18px!important;text-align:center;color:var(--color-text-soft);font-size:13px}.pagination{display:flex;align-items:center;justify-content:space-between;padding:14px 24px;border-top:1px solid var(--color-border);font-size:13px;color:var(--color-text-muted)}.pagination-btns{display:flex;gap:8px}.link-btn{background:none;border:none;padding:0;color:var(--color-primary);font-size:13px;font-weight:500;cursor:pointer;text-decoration:none}.link-btn:hover{text-decoration:underline}.advanced-panel{width:100%;display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:12px;padding-top:4px}@media(max-width:920px){.list-toolbar{padding:16px 18px}}.tasks-page__header{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:20px}.tasks-page__loading{padding:24px;margin:0}.tasks-page__row{cursor:pointer}.tasks-page__title-cell{font-weight:500;max-width:280px}\n"] }]
234
- }] });
235
-
236
- export { TasksPageComponent };
237
- //# sourceMappingURL=edvak99-voice-receptionist-widget-tasks-page.component-CBwl15NP.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"edvak99-voice-receptionist-widget-tasks-page.component-CBwl15NP.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/shared/copy-button.component.ts","../../../projects/voice-receptionist-widget/src/lib/components/task-detail-drawer/task-detail-drawer.component.ts","../../../projects/voice-receptionist-widget/src/lib/components/task-detail-drawer/task-detail-drawer.component.html","../../../projects/voice-receptionist-widget/src/lib/pages/tasks-page/tasks-page.component.ts","../../../projects/voice-receptionist-widget/src/lib/pages/tasks-page/tasks-page.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n Input,\n inject,\n signal,\n} from '@angular/core';\n\nimport { ToastService } from './toast.service';\n\n@Component({\n selector: 'app-copy-btn',\n standalone: true,\n template: `\n @if (copyValue) {\n <button\n type=\"button\"\n class=\"copy-btn\"\n (click)=\"onCopy($event)\"\n [attr.aria-label]=\"ariaLabel\"\n [title]=\"copied() ? 'Copied' : 'Copy to clipboard'\"\n >\n @if (copied()) {\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n } @else {\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n }\n </button>\n }\n `,\n styleUrl: './copy-button.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CopyButtonComponent {\n /** Raw value to copy (full ID / phone / etc.) */\n @Input() value: string | null | undefined = '';\n /** Accessible label, e.g. \"patient ID\" */\n @Input() label = 'value';\n\n private readonly toast = inject(ToastService);\n\n protected readonly copied = signal(false);\n\n protected get copyValue(): string {\n const v = this.value?.trim();\n return v && v !== '—' ? v : '';\n }\n\n protected get ariaLabel(): string {\n return this.copied() ? 'Copied' : `Copy ${this.label}`;\n }\n\n async onCopy(event: MouseEvent): Promise<void> {\n event.stopPropagation();\n const text = this.copyValue;\n if (!text) return;\n\n try {\n await navigator.clipboard.writeText(text);\n this.copied.set(true);\n setTimeout(() => this.copied.set(false), 1500);\n } catch {\n this.toast.show('Could not copy — clipboard unavailable', 'error', 2500);\n }\n }\n}\n","import { DatePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n input,\n output,\n} from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nimport { TaskItem, TaskStatus } from '../../models/ai-receptionist.types';\nimport { CopyButtonComponent } from '../../shared/copy-button.component';\nimport { EdsBadgeComponent } from '../../ui/eds-badge.component';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\nimport {\n taskCallRoute,\n taskPriorityLabel,\n taskPriorityTone,\n taskSourceLabel,\n taskStatusLabel,\n taskStatusTone,\n taskTypeTone,\n} from '../../utils/task.util';\n\n@Component({\n selector: 'eds-task-detail-drawer',\n imports: [\n DatePipe,\n RouterLink,\n CopyButtonComponent,\n EdsBadgeComponent,\n EdsButtonComponent,\n EdsIconComponent,\n ],\n templateUrl: './task-detail-drawer.component.html',\n styleUrl: './task-detail-drawer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class TaskDetailDrawerComponent {\n readonly task = input.required<TaskItem>();\n\n readonly closed = output<void>();\n readonly statusChange = output<TaskStatus>();\n\n protected readonly taskStatusLabel = taskStatusLabel;\n protected readonly taskStatusTone = taskStatusTone;\n protected readonly taskPriorityLabel = taskPriorityLabel;\n protected readonly taskPriorityTone = taskPriorityTone;\n protected readonly taskSourceLabel = taskSourceLabel;\n protected readonly taskTypeTone = taskTypeTone;\n protected readonly taskCallRoute = taskCallRoute;\n\n protected close(): void {\n this.closed.emit();\n }\n\n protected markDone(): void {\n const t = this.task();\n this.statusChange.emit(t.status === 'done' ? 'open' : 'done');\n }\n\n protected onBackdropClick(event: MouseEvent): void {\n if (event.target === event.currentTarget) this.close();\n }\n}\n","<div class=\"task-drawer__backdrop\" (click)=\"onBackdropClick($event)\">\n <aside class=\"task-drawer\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"task().title\">\n <header class=\"task-drawer__head\">\n <div>\n <eds-badge [tone]=\"taskTypeTone(task().type)\">{{ task().type }}</eds-badge>\n <h2 class=\"task-drawer__title\">{{ task().title }}</h2>\n </div>\n <button type=\"button\" class=\"task-drawer__close\" (click)=\"close()\" aria-label=\"Close\">\n <eds-icon name=\"close\" [size]=\"22\" />\n </button>\n </header>\n\n <div class=\"task-drawer__body\">\n <section class=\"task-drawer__section\">\n <h3 class=\"eds-label\">Description</h3>\n <p class=\"task-drawer__description\">{{ task().description || '—' }}</p>\n </section>\n\n <dl class=\"task-drawer__meta\">\n <div>\n <dt class=\"eds-label\">Patient</dt>\n <dd>{{ task().patient }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Assignee</dt>\n <dd>{{ task().assignee }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Status</dt>\n <dd><eds-badge [tone]=\"taskStatusTone(task().status)\">{{ taskStatusLabel(task().status) }}</eds-badge></dd>\n </div>\n <div>\n <dt class=\"eds-label\">Priority</dt>\n <dd><eds-badge [tone]=\"taskPriorityTone(task().priority)\">{{ taskPriorityLabel(task().priority) }}</eds-badge></dd>\n </div>\n <div>\n <dt class=\"eds-label\">Source</dt>\n <dd>{{ taskSourceLabel(task().source) }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Created</dt>\n <dd>{{ task().created | date: 'medium' }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Call</dt>\n <dd>\n @if (task().callId) {\n <a [routerLink]=\"taskCallRoute(task().callId!)\" class=\"task-drawer__link\">{{ task().callId }}</a>\n } @else {\n —\n }\n </dd>\n </div>\n </dl>\n\n @if (task().edvakTaskId || task().edvakStatus || task().medicationName || task().medicationId) {\n <section class=\"task-drawer__section task-drawer__section--edvak\">\n <h3 class=\"eds-label\">Edvak / refill details</h3>\n <dl class=\"task-drawer__meta\">\n @if (task().edvakTaskId) {\n <div>\n <dt class=\"eds-label\">Edvak task ID</dt>\n <dd class=\"task-drawer__copy-row\">\n <code>{{ task().edvakTaskId }}</code>\n <app-copy-btn [value]=\"task().edvakTaskId\" label=\"Edvak task ID\" />\n </dd>\n </div>\n }\n @if (task().edvakStatus) {\n <div>\n <dt class=\"eds-label\">Edvak status</dt>\n <dd><eds-badge tone=\"brand\">{{ task().edvakStatus }}</eds-badge></dd>\n </div>\n }\n @if (task().medicationName) {\n <div>\n <dt class=\"eds-label\">Medication</dt>\n <dd>{{ task().medicationName }}</dd>\n </div>\n }\n @if (task().medicationId) {\n <div>\n <dt class=\"eds-label\">Medication ID</dt>\n <dd class=\"task-drawer__copy-row\">\n <code>{{ task().medicationId }}</code>\n <app-copy-btn [value]=\"task().medicationId\" label=\"medication ID\" />\n </dd>\n </div>\n }\n </dl>\n </section>\n }\n </div>\n\n <footer class=\"task-drawer__foot\">\n <eds-button variant=\"secondary\" type=\"button\" (click)=\"markDone()\">\n {{ task().status === 'done' ? 'Reopen task' : 'Mark done' }}\n </eds-button>\n </footer>\n </aside>\n</div>\n","import { DatePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n OnInit,\n signal,\n} from '@angular/core';\nimport { ActivatedRoute, RouterLink } from '@angular/router';\n\nimport { TaskDetailDrawerComponent } from '../../components/task-detail-drawer/task-detail-drawer.component';\nimport {\n TaskFilters,\n TaskItem,\n TaskSource,\n TaskStatus,\n} from '../../models/ai-receptionist.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { EdsBadgeComponent } from '../../ui/eds-badge.component';\nimport {\n TASK_TYPE_OPTIONS,\n taskCallRoute,\n taskPriorityTone,\n taskSourceLabel,\n taskStatusLabel,\n taskStatusTone,\n taskTypeTone,\n} from '../../utils/task.util';\n\n@Component({\n selector: 'eds-tasks-page',\n imports: [\n DatePipe,\n RouterLink,\n EdsBadgeComponent,\n TaskDetailDrawerComponent,\n ],\n templateUrl: './tasks-page.component.html',\n styleUrl: './tasks-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class TasksPageComponent implements OnInit {\n private readonly api = inject(AiReceptionistApiService);\n private readonly route = inject(ActivatedRoute);\n\n protected readonly tasks = signal<TaskItem[]>([]);\n protected readonly loading = signal(true);\n protected readonly selectedTask = signal<TaskItem | null>(null);\n\n protected readonly statusFilter = signal<'' | TaskStatus>('');\n protected readonly typeFilter = signal('');\n protected readonly sourceFilter = signal<'' | TaskSource>('');\n protected readonly callIdFilter = signal('');\n\n protected readonly typeOptions = TASK_TYPE_OPTIONS;\n protected readonly taskStatusLabel = taskStatusLabel;\n protected readonly taskStatusTone = taskStatusTone;\n protected readonly taskPriorityTone = taskPriorityTone;\n protected readonly taskSourceLabel = taskSourceLabel;\n protected readonly taskTypeTone = taskTypeTone;\n protected readonly taskCallRoute = taskCallRoute;\n\n protected readonly hasActiveFilters = computed(\n () =>\n !!this.statusFilter() ||\n !!this.typeFilter() ||\n !!this.sourceFilter() ||\n !!this.callIdFilter(),\n );\n\n ngOnInit(): void {\n const callId = this.route.snapshot.queryParamMap.get('callId') ?? '';\n if (callId) this.callIdFilter.set(callId);\n this.load();\n }\n\n protected setStatusFilter(value: string): void {\n this.statusFilter.set(value as '' | TaskStatus);\n this.load();\n }\n\n protected setTypeFilter(value: string): void {\n this.typeFilter.set(value);\n this.load();\n }\n\n protected setSourceFilter(value: string): void {\n this.sourceFilter.set(value as '' | TaskSource);\n this.load();\n }\n\n protected setCallIdFilter(value: string): void {\n this.callIdFilter.set(value);\n this.load();\n }\n\n protected clearFilters(): void {\n this.statusFilter.set('');\n this.typeFilter.set('');\n this.sourceFilter.set('');\n this.callIdFilter.set('');\n this.load();\n }\n\n protected openTask(task: TaskItem): void {\n this.selectedTask.set(task);\n }\n\n protected closeDrawer(): void {\n this.selectedTask.set(null);\n }\n\n protected onStatusChange(status: TaskStatus): void {\n const task = this.selectedTask();\n if (!task) return;\n this.api.patchTask(task.id, status).subscribe(({ data }) => {\n if (data) {\n this.selectedTask.set(data);\n this.tasks.update((rows) => rows.map((r) => (r.id === data.id ? data : r)));\n }\n });\n }\n\n private load(): void {\n this.loading.set(true);\n const filters: TaskFilters = {};\n if (this.statusFilter()) filters.status = this.statusFilter() as TaskStatus;\n if (this.typeFilter()) filters.type = this.typeFilter();\n if (this.sourceFilter()) filters.source = this.sourceFilter() as TaskSource;\n if (this.callIdFilter().trim()) filters.callId = this.callIdFilter().trim();\n\n this.api.getTasks(filters).subscribe({\n next: ({ data }) => {\n this.tasks.set(data);\n this.loading.set(false);\n },\n error: () => this.loading.set(false),\n });\n }\n}\n","<div class=\"eds-page tasks-page\">\n <header class=\"tasks-page__header\">\n <div>\n <h1 class=\"eds-h1\">Tasks & follow-ups</h1>\n <p class=\"eds-body-sm\">Action items from calls — all types, not just refills</p>\n </div>\n </header>\n\n <section class=\"list-section\">\n <div class=\"list-toolbar\">\n <div class=\"filter-group\">\n <label for=\"task-status\">Status</label>\n <select\n id=\"task-status\"\n class=\"filter-input\"\n [value]=\"statusFilter()\"\n (change)=\"setStatusFilter($any($event.target).value)\"\n >\n <option value=\"\">All</option>\n <option value=\"open\">Open</option>\n <option value=\"in_progress\">In progress</option>\n <option value=\"done\">Done</option>\n </select>\n </div>\n <div class=\"filter-group\">\n <label for=\"task-type\">Type</label>\n <select\n id=\"task-type\"\n class=\"filter-input\"\n [value]=\"typeFilter()\"\n (change)=\"setTypeFilter($any($event.target).value)\"\n >\n <option value=\"\">All types</option>\n @for (t of typeOptions; track t) {\n <option [value]=\"t\">{{ t }}</option>\n }\n </select>\n </div>\n <div class=\"filter-group\">\n <label for=\"task-source\">Source</label>\n <select\n id=\"task-source\"\n class=\"filter-input\"\n [value]=\"sourceFilter()\"\n (change)=\"setSourceFilter($any($event.target).value)\"\n >\n <option value=\"\">All sources</option>\n <option value=\"voice\">Voice</option>\n <option value=\"sync\">Sync</option>\n <option value=\"manual\">Manual</option>\n </select>\n </div>\n <div class=\"filter-group\">\n <label for=\"task-call\">Call ID</label>\n <input\n id=\"task-call\"\n type=\"text\"\n class=\"filter-input\"\n [value]=\"callIdFilter()\"\n placeholder=\"Filter by call\"\n (change)=\"setCallIdFilter($any($event.target).value)\"\n />\n </div>\n @if (hasActiveFilters()) {\n <button type=\"button\" class=\"link-btn\" (click)=\"clearFilters()\">Clear filters</button>\n }\n </div>\n\n @if (loading()) {\n <p class=\"eds-body-sm tasks-page__loading\">Loading tasks…</p>\n } @else {\n <div class=\"table-wrap\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Created</th>\n <th>Title</th>\n <th>Type</th>\n <th>Patient</th>\n <th>Priority</th>\n <th>Status</th>\n <th>Source</th>\n <th>Call</th>\n </tr>\n </thead>\n <tbody>\n @for (task of tasks(); track task.id) {\n <tr class=\"tasks-page__row\" (click)=\"openTask(task)\">\n <td class=\"cell-muted\">{{ task.created | date: 'MM/dd/yy, h:mm a' }}</td>\n <td class=\"tasks-page__title-cell\">{{ task.title }}</td>\n <td><eds-badge [tone]=\"taskTypeTone(task.type)\">{{ task.type }}</eds-badge></td>\n <td>{{ task.patient }}</td>\n <td>\n <eds-badge [tone]=\"taskPriorityTone(task.priority)\">\n {{ task.priority === 'urgent' ? 'Urgent' : 'Normal' }}\n </eds-badge>\n </td>\n <td><eds-badge [tone]=\"taskStatusTone(task.status)\">{{ taskStatusLabel(task.status) }}</eds-badge></td>\n <td class=\"cell-muted\">{{ taskSourceLabel(task.source) }}</td>\n <td (click)=\"$event.stopPropagation()\">\n @if (task.callId) {\n <a [routerLink]=\"taskCallRoute(task.callId)\" class=\"link-btn\">{{ task.callId }}</a>\n } @else {\n <span class=\"cell-muted\">—</span>\n }\n </td>\n </tr>\n } @empty {\n <tr>\n <td colspan=\"8\" class=\"empty-state\">No tasks match these filters.</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </section>\n</div>\n\n@if (selectedTask(); as task) {\n <eds-task-detail-drawer\n [task]=\"task\"\n (closed)=\"closeDrawer()\"\n (statusChange)=\"onStatusChange($event)\"\n />\n}"],"names":[],"mappings":"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"}
@@ -1,22 +0,0 @@
1
- import { EventEmitter } from '@angular/core';
2
- import { FAQ_STARTER_TEMPLATES } from '../../models/practice-faq.model';
3
- import * as i0 from "@angular/core";
4
- export declare class FaqEmptyStateComponent {
5
- protected readonly starters: {
6
- label: string;
7
- question: string;
8
- answer: string;
9
- category: string;
10
- }[];
11
- readonly add: EventEmitter<void>;
12
- readonly useTemplate: EventEmitter<{
13
- label: string;
14
- question: string;
15
- answer: string;
16
- category: string;
17
- }>;
18
- protected onAdd(): void;
19
- protected onTemplate(t: (typeof FAQ_STARTER_TEMPLATES)[number]): void;
20
- static ɵfac: i0.ɵɵFactoryDeclaration<FaqEmptyStateComponent, never>;
21
- static ɵcmp: i0.ɵɵComponentDeclaration<FaqEmptyStateComponent, "eds-faq-empty-state", never, {}, { "add": "add"; "useTemplate": "useTemplate"; }, never, never, true, never>;
22
- }