@edvak99/voice-receptionist-widget 1.1.11 → 1.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -14
- package/fesm2022/{edvak99-voice-receptionist-widget-activities-page.component-CACfxM4x.mjs → edvak99-voice-receptionist-widget-activities-page.component-Br2Vi1Im.mjs} +3 -4
- package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-Br2Vi1Im.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-analytics-page.component-Dj9vw97B.mjs → edvak99-voice-receptionist-widget-analytics-page.component-CglgGV6H.mjs} +2 -3
- package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-CglgGV6H.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-api-log.util-C0TOKF1q.mjs.map +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-api-logs-page.component-jKBA1N2A.mjs → edvak99-voice-receptionist-widget-api-logs-page.component-DPJiuNjk.mjs} +7 -6
- package/fesm2022/edvak99-voice-receptionist-widget-api-logs-page.component-DPJiuNjk.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-api-logs-table.component-CEf4NPe5.mjs → edvak99-voice-receptionist-widget-api-logs-table.component-CiNc65dO.mjs} +2 -3
- package/fesm2022/edvak99-voice-receptionist-widget-api-logs-table.component-CiNc65dO.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-call-history-detail-page.component-DEplWBbz.mjs → edvak99-voice-receptionist-widget-call-history-detail-page.component-ENq2c-sm.mjs} +5 -7
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-ENq2c-sm.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-DoYJFpSa.mjs +200 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-DoYJFpSa.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-j1mY5wU0.mjs → edvak99-voice-receptionist-widget-call-recording-player.component-GVg1g-Vq.mjs} +2 -3
- package/fesm2022/edvak99-voice-receptionist-widget-call-recording-player.component-GVg1g-Vq.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-DQ4TT_Su.mjs → edvak99-voice-receptionist-widget-call-review.service-WG30w6Jl.mjs} +2 -2
- package/fesm2022/edvak99-voice-receptionist-widget-call-review.service-WG30w6Jl.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-Deh3jPgo.mjs.map +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-dashboard-page.component-DPxQ-wst.mjs → edvak99-voice-receptionist-widget-dashboard-page.component-B_EYljRs.mjs} +4 -5
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-B_EYljRs.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-BJs_TH8X.mjs.map +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-BFCiJOT3.mjs.map +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget-eds-pulse-dot.component-B8yxY-7p.mjs +14 -0
- package/fesm2022/edvak99-voice-receptionist-widget-eds-pulse-dot.component-B8yxY-7p.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-eds-search-field.component-OGRDvYBp.mjs +83 -0
- package/fesm2022/edvak99-voice-receptionist-widget-eds-search-field.component-OGRDvYBp.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-ai-receptionist-api.service-DcRiHn8q.mjs → edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-pS2jeB4x.mjs} +612 -8
- package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-pS2jeB4x.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-1woGuh0J.mjs +74 -0
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-1woGuh0J.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-live-monitor-page.component-BOQeTD3P.mjs → edvak99-voice-receptionist-widget-live-monitor-page.component-ihwm1LNn.mjs} +5 -7
- package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-ihwm1LNn.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-modal.component-uYApl1KF.mjs.map +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-outbound-purposes-page.component-D407n7l0.mjs → edvak99-voice-receptionist-widget-outbound-purposes-page.component-B2koBFU3.mjs} +2 -3
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-B2koBFU3.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-settings-page.component-YAvQ_XV6.mjs → edvak99-voice-receptionist-widget-settings-page.component-C6F-Hgmk.mjs} +2 -3
- package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-C6F-Hgmk.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-task-detail-drawer.component-B3KmFJNH.mjs → edvak99-voice-receptionist-widget-task-detail-drawer.component-BojdiNNx.mjs} +2 -2
- package/fesm2022/edvak99-voice-receptionist-widget-task-detail-drawer.component-BojdiNNx.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-tasks-page.component-BIOGiTgM.mjs → edvak99-voice-receptionist-widget-tasks-page.component-Cf76XyCz.mjs} +3 -4
- package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-Cf76XyCz.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-DpF6y1go.mjs → edvak99-voice-receptionist-widget-wizard-page.component-BQTlz2F5.mjs} +2 -3
- package/fesm2022/edvak99-voice-receptionist-widget-wizard-page.component-BQTlz2F5.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget.mjs +1 -262
- package/fesm2022/edvak99-voice-receptionist-widget.mjs.map +1 -1
- package/lib/layout/eds-app-shell.component.d.ts +5 -0
- package/lib/layout/eds-route-progress.component.d.ts +15 -0
- package/lib/models/ai-receptionist.types.d.ts +2 -0
- package/lib/models/api-dto.types.d.ts +2 -0
- package/lib/pages/live-calls-page/live-calls-page.component.d.ts +1 -4
- package/lib/pages/live-calls-page/live-calls-shell.component.d.ts +13 -0
- package/lib/services/live-calls-list.service.d.ts +2 -0
- package/lib/ui/eds-search-field.component.d.ts +22 -0
- package/lib/utils/call-history-display.util.d.ts +1 -0
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-CACfxM4x.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-ai-receptionist-api.service-DcRiHn8q.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-Dj9vw97B.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-api-logs-page.component-jKBA1N2A.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-api-logs-table.component-CEf4NPe5.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-DEplWBbz.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-CkjKCteR.mjs +0 -193
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-CkjKCteR.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-recording-player.component-j1mY5wU0.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-review.service-DQ4TT_Su.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-DPxQ-wst.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-socket.service-tTQIsZO6.mjs +0 -120
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-socket.service-tTQIsZO6.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-eds-pulse-dot.component-CUWZfYRR.mjs +0 -130
- package/fesm2022/edvak99-voice-receptionist-widget-eds-pulse-dot.component-CUWZfYRR.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-BG9cB3zW.mjs +0 -81
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-BG9cB3zW.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-BOQeTD3P.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-D407n7l0.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-YAvQ_XV6.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-task-detail-drawer.component-B3KmFJNH.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-BIOGiTgM.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-wizard-page.component-DpF6y1go.mjs.map +0 -1
package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-B2koBFU3.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edvak99-voice-receptionist-widget-outbound-purposes-page.component-B2koBFU3.mjs","sources":["../../../src/lib/utils/outbound-purpose.util.ts","../../../src/lib/components/outbound-purpose-form-modal/outbound-purpose-form-modal.component.ts","../../../src/lib/components/outbound-purpose-form-modal/outbound-purpose-form-modal.component.html","../../../src/lib/pages/outbound-purposes-page/outbound-purposes-page.component.ts","../../../src/lib/pages/outbound-purposes-page/outbound-purposes-page.component.html"],"sourcesContent":["import {\n OutboundPurpose,\n OutboundPurposePlaceholder,\n OutboundRequiredField,\n} from '../models/outbound-purpose.types';\n\nexport const REQUIRED_FIELD_OPTIONS: { value: OutboundRequiredField; label: string }[] = [\n { value: 'appointmentDate', label: 'Appointment Date' },\n { value: 'appointmentTime', label: 'Appointment Time' },\n { value: 'providerName', label: 'Provider Name' },\n { value: 'customScript', label: 'Custom Script' },\n];\n\n/** Live dialer values used to fill opening-template tokens. */\nexport interface OpeningPreviewValues {\n patientName?: string;\n appointmentDate?: string;\n appointmentTime?: string;\n providerName?: string;\n practiceName?: string;\n locationName?: string;\n visitType?: string;\n customScript?: string;\n}\n\nconst TOKEN_KEYS: { token: string; key: keyof OpeningPreviewValues; label: string }[] = [\n { token: '{{patientName}}', key: 'patientName', label: 'Patient name' },\n { token: '{{appointmentDate}}', key: 'appointmentDate', label: 'Appointment date' },\n { token: '{{appointmentTime}}', key: 'appointmentTime', label: 'Appointment time' },\n { token: '{{providerName}}', key: 'providerName', label: 'Provider name' },\n { token: '{{practiceName}}', key: 'practiceName', label: 'Practice name' },\n { token: '{{locationName}}', key: 'locationName', label: 'Location' },\n { token: '{{visitType}}', key: 'visitType', label: 'Visit type' },\n { token: '{{customScript}}', key: 'customScript', label: 'Custom script' },\n];\n\nexport function requiredFieldLabel(field: OutboundRequiredField): string {\n return REQUIRED_FIELD_OPTIONS.find((o) => o.value === field)?.label ?? field;\n}\n\nexport function formatRequiredFields(fields: OutboundRequiredField[]): string {\n if (!fields.length) return '—';\n return fields.map(requiredFieldLabel).join(', ');\n}\n\n/** Substitute placeholder tokens with sample values. */\nexport function substitutePlaceholders(\n text: string,\n placeholders: OutboundPurposePlaceholder[],\n): string {\n let result = text;\n for (const p of placeholders) {\n result = result.split(p.token).join(p.sampleValue);\n }\n return result;\n}\n\n/** Live preview: sampleOpening if set, else openingTemplate with substitutions. */\nexport function renderOpeningPreview(\n sampleOpening: string,\n openingTemplate: string,\n placeholders: OutboundPurposePlaceholder[],\n): string {\n const source = sampleOpening?.trim() ? sampleOpening : openingTemplate;\n if (!source?.trim()) return '—';\n return substitutePlaceholders(source, placeholders);\n}\n\n/**\n * Dialer preview: prefer openingTemplate and fill with live patient/appointment values.\n * Unfilled tokens show as [Label] so staff see what is still missing.\n */\nexport function renderLiveOpeningPreview(\n purpose: Pick<OutboundPurpose, 'openingTemplate' | 'sampleOpening' | 'placeholders'>,\n live: OpeningPreviewValues,\n): string {\n const source = purpose.openingTemplate?.trim() || purpose.sampleOpening?.trim() || '';\n if (!source) return '—';\n\n const byToken = new Map<string, string>();\n for (const meta of TOKEN_KEYS) {\n const liveVal = String(live[meta.key] ?? '').trim();\n byToken.set(meta.token, liveVal || `[${meta.label}]`);\n }\n for (const p of purpose.placeholders ?? []) {\n if (!byToken.has(p.token)) {\n byToken.set(p.token, p.sampleValue?.trim() || `[${p.label}]`);\n }\n }\n\n let result = source;\n for (const [token, value] of byToken) {\n result = result.split(token).join(value);\n }\n return result;\n}\n\n/** Human-friendly date/time for opening lines (from ISO or form fields). */\nexport function formatOpeningDate(isoOrYmd: string | null | undefined): string {\n const raw = String(isoOrYmd ?? '').trim();\n if (!raw) return '';\n const d = raw.includes('T') || raw.includes('Z') ? new Date(raw) : parseLocalYmd(raw);\n if (!d || Number.isNaN(d.getTime())) return raw;\n return d.toLocaleDateString(undefined, {\n weekday: 'short',\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n });\n}\n\nexport function formatOpeningTime(\n isoOrHm: string | null | undefined,\n fallbackIso?: string | null,\n): string {\n const raw = String(isoOrHm ?? '').trim();\n if (raw.includes('T') || raw.includes('Z')) {\n const d = new Date(raw);\n if (!Number.isNaN(d.getTime())) {\n return d.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n }\n }\n if (/^\\d{1,2}:\\d{2}/.test(raw)) {\n const [h, m] = raw.split(':').map(Number);\n const d = new Date();\n d.setHours(h, m, 0, 0);\n return d.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n }\n if (fallbackIso) return formatOpeningTime(fallbackIso);\n return raw;\n}\n\nfunction parseLocalYmd(ymd: string): Date | null {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(ymd);\n if (!m) return null;\n return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));\n}\n\nexport function purposeShowsCustomScript(purpose: OutboundPurpose): boolean {\n return purpose.allowsCustomScript || purpose.requiredFields.includes('customScript');\n}\n\nexport function isCustomScriptRequired(purpose: OutboundPurpose): boolean {\n return purpose.requiredFields.includes('customScript');\n}\n\nexport function isPurposeFormValid(\n purpose: OutboundPurpose | null,\n values: Record<string, string>,\n): boolean {\n if (!purpose) return false;\n if (!values['phone']?.trim() || !values['name']?.trim()) return false;\n\n for (const field of purpose.requiredFields) {\n if (field === 'customScript') {\n if (!values['customScript']?.trim()) return false;\n } else if (!values[field]?.trim()) {\n return false;\n }\n }\n return true;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n EventEmitter,\n Input,\n OnChanges,\n Output,\n SimpleChanges,\n ViewChild,\n inject,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport {\n CreateOutboundPurposeRequest,\n OutboundPurpose,\n OutboundPurposePlaceholder,\n OutboundRequiredField,\n UpdateOutboundPurposeRequest,\n} from '../../models/outbound-purpose.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport {\n REQUIRED_FIELD_OPTIONS,\n renderOpeningPreview,\n} from '../../utils/outbound-purpose.util';\nimport { DEFAULT_PLACEHOLDERS } from '../../mocks/outbound-purpose.seed';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport { ModalComponent } from '../../shared/modal.component';\n\n@Component({\n selector: 'eds-outbound-purpose-form-modal',\n imports: [FormsModule, ModalComponent, EdsButtonComponent],\n templateUrl: './outbound-purpose-form-modal.component.html',\n styleUrl: './outbound-purpose-form-modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class OutboundPurposeFormModalComponent implements OnChanges {\n private readonly api = inject(AiReceptionistApiService);\n\n @Input() open = false;\n @Input() purpose: OutboundPurpose | null = null;\n @Output() readonly closed = new EventEmitter<void>();\n @Output() readonly saved = new EventEmitter<OutboundPurpose>();\n\n @ViewChild('templateInput') templateInput?: ElementRef<HTMLTextAreaElement>;\n\n protected readonly fieldOptions = REQUIRED_FIELD_OPTIONS;\n protected readonly saving = signal(false);\n protected readonly error = signal<string | null>(null);\n\n protected label = '';\n protected description = '';\n protected sampleOpening = '';\n protected openingTemplate = '';\n protected agentContextHint = '';\n protected requiredFields = new Set<OutboundRequiredField>();\n protected allowsCustomScript = false;\n protected sortOrder = 1;\n protected isActive = true;\n protected placeholders: OutboundPurposePlaceholder[] = DEFAULT_PLACEHOLDERS;\n\n protected get isEdit(): boolean {\n return !!this.purpose;\n }\n\n protected get previewText(): string {\n return renderOpeningPreview(this.sampleOpening, this.openingTemplate, this.placeholders);\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['open']?.currentValue || changes['purpose']) {\n this.resetForm();\n }\n }\n\n protected close(): void {\n this.closed.emit();\n }\n\n protected toggleRequired(field: OutboundRequiredField): void {\n const next = new Set(this.requiredFields);\n if (next.has(field)) next.delete(field);\n else next.add(field);\n this.requiredFields = next;\n }\n\n protected isRequiredSelected(field: OutboundRequiredField): boolean {\n return this.requiredFields.has(field);\n }\n\n protected insertPlaceholder(token: string): void {\n const el = this.templateInput?.nativeElement;\n if (!el) {\n this.openingTemplate += token;\n return;\n }\n const start = el.selectionStart ?? this.openingTemplate.length;\n const end = el.selectionEnd ?? start;\n this.openingTemplate =\n this.openingTemplate.slice(0, start) + token + this.openingTemplate.slice(end);\n const pos = start + token.length;\n requestAnimationFrame(() => {\n el.focus();\n el.setSelectionRange(pos, pos);\n });\n }\n\n protected submit(): void {\n this.error.set(null);\n const trimmedLabel = this.label.trim();\n const trimmedTemplate = this.openingTemplate.trim();\n if (!trimmedLabel) {\n this.error.set('Label is required.');\n return;\n }\n if (!trimmedTemplate) {\n this.error.set('Opening template is required.');\n return;\n }\n if (this.sampleOpening.length > 500) {\n this.error.set('Sample opening must be 500 characters or fewer.');\n return;\n }\n\n this.saving.set(true);\n const fields = [...this.requiredFields];\n\n if (this.isEdit && this.purpose) {\n const body: UpdateOutboundPurposeRequest = {\n label: trimmedLabel,\n description: this.description.trim(),\n sampleOpening: this.sampleOpening.trim(),\n openingTemplate: trimmedTemplate,\n agentContextHint: this.agentContextHint.trim() || null,\n requiredFields: fields,\n allowsCustomScript: this.allowsCustomScript,\n sortOrder: this.sortOrder,\n isActive: this.isActive,\n };\n this.api.updateOutboundPurpose(this.purpose.purposeId, body).subscribe({\n next: (updated) => {\n this.saving.set(false);\n this.saved.emit(updated);\n this.close();\n },\n error: () => {\n this.saving.set(false);\n this.error.set('Failed to save purpose template.');\n },\n });\n return;\n }\n\n const body: CreateOutboundPurposeRequest = {\n label: trimmedLabel,\n description: this.description.trim(),\n sampleOpening: this.sampleOpening.trim(),\n openingTemplate: trimmedTemplate,\n agentContextHint: this.agentContextHint.trim() || null,\n requiredFields: fields,\n allowsCustomScript: this.allowsCustomScript,\n sortOrder: this.sortOrder,\n };\n this.api.createOutboundPurpose(body).subscribe({\n next: (created) => {\n this.saving.set(false);\n this.saved.emit(created);\n this.close();\n },\n error: () => {\n this.saving.set(false);\n this.error.set('Failed to create purpose template.');\n },\n });\n }\n\n private resetForm(): void {\n this.error.set(null);\n this.saving.set(false);\n if (this.purpose) {\n this.label = this.purpose.label;\n this.description = this.purpose.description;\n this.sampleOpening = this.purpose.sampleOpening;\n this.openingTemplate = this.purpose.openingTemplate;\n this.agentContextHint = this.purpose.agentContextHint ?? '';\n this.requiredFields = new Set(this.purpose.requiredFields);\n this.allowsCustomScript = this.purpose.allowsCustomScript;\n this.sortOrder = this.purpose.sortOrder;\n this.isActive = this.purpose.isActive;\n this.placeholders = this.purpose.placeholders?.length\n ? [...this.purpose.placeholders]\n : [...DEFAULT_PLACEHOLDERS];\n } else {\n this.label = '';\n this.description = '';\n this.sampleOpening = '';\n this.openingTemplate = 'Hi {{patientName}}, this is {{practiceName}}.';\n this.agentContextHint = '';\n this.requiredFields = new Set();\n this.allowsCustomScript = false;\n this.sortOrder = 1;\n this.isActive = true;\n this.placeholders = [...DEFAULT_PLACEHOLDERS];\n }\n }\n}\n","@if (open) {\n <app-modal\n [title]=\"isEdit ? 'Edit outbound purpose' : 'New outbound purpose'\"\n subtitle=\"Configure dialer fields and AI opening script\"\n maxWidth=\"720px\"\n (closed)=\"close()\"\n >\n <form class=\"flex flex-col gap-4\" (ngSubmit)=\"submit()\" novalidate autocomplete=\"off\">\n <div class=\"grid grid-cols-2 gap-3\">\n <label class=\"col-span-full flex flex-col gap-2\">\n <span class=\"eds-label\">Label <span class=\"text-[#dc2626]\">*</span></span>\n <input type=\"text\" class=\"purpose-form__input rounded-lg border px-3 py-2 font-[inherit]\" [(ngModel)]=\"label\" name=\"label\" required autocomplete=\"off\" />\n </label>\n\n <label class=\"col-span-full flex flex-col gap-2\">\n <span class=\"eds-label\">Description</span>\n <input type=\"text\" class=\"purpose-form__input rounded-lg border px-3 py-2 font-[inherit]\" [(ngModel)]=\"description\" name=\"description\" autocomplete=\"off\" />\n </label>\n\n <label class=\"col-span-full flex flex-col gap-2\">\n <span class=\"eds-label\">Sample opening (plain preview, max 500)</span>\n <textarea\n class=\"purpose-form__textarea min-h-[72px] resize-y rounded-lg border px-3 py-2 font-[inherit]\"\n rows=\"3\"\n maxlength=\"500\"\n [(ngModel)]=\"sampleOpening\"\n name=\"sampleOpening\" autocomplete=\"off\"></textarea>\n <span class=\"purpose-form__hint text-xs\">{{ sampleOpening.length }}/500</span>\n </label>\n\n <div class=\"col-span-full flex flex-col gap-2\">\n <span class=\"eds-label\">Opening template <span class=\"text-[#dc2626]\">*</span></span>\n <div class=\"mb-2 flex flex-wrap gap-2\">\n @for (chip of placeholders; track chip.token) {\n <button type=\"button\" class=\"purpose-form__chip cursor-pointer rounded-full border px-3 py-1 text-xs\" (click)=\"insertPlaceholder(chip.token)\">\n {{ chip.label }}\n </button>\n }\n </div>\n <textarea\n #templateInput\n class=\"purpose-form__textarea min-h-[72px] resize-y rounded-lg border px-3 py-2 font-[inherit]\"\n rows=\"4\"\n [(ngModel)]=\"openingTemplate\"\n name=\"openingTemplate\"\n required autocomplete=\"off\"></textarea>\n </div>\n\n <label class=\"col-span-full flex flex-col gap-2\">\n <span class=\"eds-label\">Agent context hint</span>\n <textarea\n class=\"purpose-form__textarea min-h-[72px] resize-y rounded-lg border px-3 py-2 font-[inherit]\"\n rows=\"2\"\n [(ngModel)]=\"agentContextHint\"\n name=\"agentContextHint\"\n placeholder=\"Optional guidance for the AI after the opening\" autocomplete=\"off\"></textarea>\n </label>\n\n <fieldset class=\"col-span-full flex flex-col gap-2\">\n <legend class=\"eds-label\">Required fields</legend>\n <div class=\"grid grid-cols-2 gap-2\">\n @for (opt of fieldOptions; track opt.value) {\n <label class=\"flex items-center gap-2 text-[13px]\">\n <input\n type=\"checkbox\"\n [checked]=\"isRequiredSelected(opt.value)\"\n (change)=\"toggleRequired(opt.value)\" autocomplete=\"off\" />\n {{ opt.label }}\n </label>\n }\n </div>\n </fieldset>\n\n <label class=\"col-span-full flex items-center gap-2 text-[13px]\">\n <input type=\"checkbox\" [(ngModel)]=\"allowsCustomScript\" name=\"allowsCustomScript\" autocomplete=\"off\" />\n Allows custom script (dialer shows free-text script field)\n </label>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"eds-label\">Sort order</span>\n <input type=\"number\" class=\"purpose-form__input rounded-lg border px-3 py-2 font-[inherit]\" [(ngModel)]=\"sortOrder\" name=\"sortOrder\" min=\"0\" autocomplete=\"off\" />\n </label>\n\n @if (isEdit) {\n <label class=\"flex items-center gap-2 text-[13px]\">\n <input type=\"checkbox\" [(ngModel)]=\"isActive\" name=\"isActive\" autocomplete=\"off\" />\n Active\n </label>\n }\n </div>\n\n <section class=\"purpose-form__preview eds-card rounded-lg p-3 shadow-sm\">\n <h3 class=\"eds-label\">Live preview</h3>\n <p class=\"purpose-form__preview-text mt-2 whitespace-pre-wrap text-sm leading-normal\">{{ previewText }}</p>\n </section>\n\n @if (error()) {\n <p class=\"m-0 text-[13px] text-[#b91c1c]\" role=\"alert\">{{ error() }}</p>\n }\n\n <footer class=\"flex justify-end gap-2\">\n <eds-button variant=\"secondary\" type=\"button\" (click)=\"close()\" [disabled]=\"saving()\">\n Cancel\n </eds-button>\n <eds-button variant=\"primary\" type=\"submit\" [disabled]=\"saving()\">\n {{ saving() ? 'Saving…' : isEdit ? 'Save changes' : 'Create purpose' }}\n </eds-button>\n </footer>\n </form>\n </app-modal>\n}\n","import { ChangeDetectionStrategy, Component, inject, OnInit, signal } from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nimport { OutboundPurpose } from '../../models/outbound-purpose.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { formatRequiredFields } from '../../utils/outbound-purpose.util';\nimport { OutboundPurposeFormModalComponent } from '../../components/outbound-purpose-form-modal/outbound-purpose-form-modal.component';\nimport { EdsBadgeComponent } from '../../ui/eds-badge.component';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\n\n@Component({\n selector: 'eds-outbound-purposes-page',\n imports: [\n RouterLink,\n EdsBadgeComponent,\n EdsButtonComponent,\n EdsIconComponent,\n OutboundPurposeFormModalComponent,\n ],\n templateUrl: './outbound-purposes-page.component.html',\n styleUrl: './outbound-purposes-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class OutboundPurposesPageComponent implements OnInit {\n private readonly api = inject(AiReceptionistApiService);\n\n protected readonly purposes = signal<OutboundPurpose[]>([]);\n protected readonly loading = signal(true);\n protected readonly error = signal<string | null>(null);\n protected readonly modalOpen = signal(false);\n protected readonly editing = signal<OutboundPurpose | null>(null);\n\n protected formatRequiredFields = formatRequiredFields;\n\n ngOnInit(): void {\n this.load();\n }\n\n protected load(): void {\n this.loading.set(true);\n this.error.set(null);\n this.api.getOutboundPurposes(true).subscribe({\n next: ({ purposes }) => {\n this.purposes.set(purposes);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.error.set('Failed to load outbound purposes.');\n },\n });\n }\n\n protected openCreate(): void {\n this.editing.set(null);\n this.modalOpen.set(true);\n }\n\n protected openEdit(purpose: OutboundPurpose): void {\n this.editing.set(purpose);\n this.modalOpen.set(true);\n }\n\n protected closeModal(): void {\n this.modalOpen.set(false);\n this.editing.set(null);\n }\n\n protected onSaved(): void {\n this.load();\n }\n\n protected toggleActive(purpose: OutboundPurpose, active: boolean): void {\n this.api.updateOutboundPurpose(purpose.purposeId, { isActive: active }).subscribe({\n next: (updated) => {\n this.purposes.update((list) =>\n list.map((p) => (p.purposeId === updated.purposeId ? updated : p)),\n );\n },\n error: () => this.load(),\n });\n }\n\n protected deletePurpose(purpose: OutboundPurpose): void {\n if (purpose.isSystem) {\n this.toggleActive(purpose, false);\n return;\n }\n if (!confirm(`Delete \"${purpose.label}\"? This cannot be undone.`)) return;\n this.api.deleteOutboundPurpose(purpose.purposeId).subscribe({\n next: () => this.load(),\n error: () => this.error.set('Failed to delete purpose.'),\n });\n }\n\n protected actionLabel(purpose: OutboundPurpose): string {\n return purpose.isSystem ? 'Deactivate' : 'Delete';\n }\n}\n","<div class=\"eds-page outbound-purposes-page\">\n <header class=\"mb-5 flex items-start justify-between gap-4\">\n <div>\n <a routerLink=\"../settings\" class=\"outbound-purposes-page__back eds-body-sm mb-2 inline-flex items-center gap-1 no-underline\">\n <eds-icon name=\"arrow_back\" [size]=\"16\" /> Settings\n </a>\n <h1 class=\"eds-h1\">Outbound Call Purposes</h1>\n <p class=\"eds-body-sm\">Templates that drive outbound dialer fields and AI opening scripts</p>\n </div>\n <eds-button variant=\"primary\" (click)=\"openCreate()\">\n <eds-icon name=\"add\" [size]=\"18\" /> New purpose\n </eds-button>\n </header>\n\n @if (loading()) {\n <p class=\"eds-body-sm\">Loading purposes…</p>\n } @else if (error()) {\n <p class=\"eds-body-sm text-red-700\" role=\"alert\">{{ error() }}</p>\n } @else {\n <article class=\"eds-card overflow-x-auto p-4 shadow-sm\">\n <table class=\"eds-table\">\n <thead>\n <tr>\n <th>Label</th>\n <th>Description</th>\n <th>Required fields</th>\n <th>System</th>\n <th>Active</th>\n <th>Sort</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (p of purposes(); track p.purposeId) {\n <tr>\n <td class=\"eds-body-sm-bold\">{{ p.label }}</td>\n <td class=\"eds-body-sm\">{{ p.description || '—' }}</td>\n <td class=\"eds-body-sm\">{{ formatRequiredFields(p.requiredFields) }}</td>\n <td>\n @if (p.isSystem) {\n <eds-badge tone=\"brand\">System</eds-badge>\n } @else {\n <span class=\"eds-body-sm\">—</span>\n }\n </td>\n <td>\n <label>\n <input\n type=\"checkbox\"\n class=\"h-4 w-4\"\n [checked]=\"p.isActive\"\n (change)=\"toggleActive(p, $any($event.target).checked)\" autocomplete=\"off\" />\n </label>\n </td>\n <td class=\"eds-mono-sm\">{{ p.sortOrder }}</td>\n <td class=\"flex gap-3 whitespace-nowrap\">\n <button type=\"button\" class=\"outbound-purposes-page__link cursor-pointer border-none bg-transparent p-0\" (click)=\"openEdit(p)\">\n Edit\n </button>\n <button type=\"button\" class=\"outbound-purposes-page__link cursor-pointer border-none bg-transparent p-0\" (click)=\"deletePurpose(p)\">\n {{ actionLabel(p) }}\n </button>\n </td>\n </tr>\n } @empty {\n <tr>\n <td colspan=\"7\" class=\"eds-body-sm\">No outbound purposes configured.</td>\n </tr>\n }\n </tbody>\n </table>\n </article>\n }\n\n <eds-outbound-purpose-form-modal\n [open]=\"modalOpen()\"\n [purpose]=\"editing()\"\n (closed)=\"closeModal()\"\n (saved)=\"onSaved()\"\n />\n</div>\n"],"names":[],"mappings":";;;;;;;;AAMO,MAAM,sBAAsB,GAAsD;AACvF,IAAA,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,kBAAkB,EAAE;AACvD,IAAA,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,kBAAkB,EAAE;AACvD,IAAA,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE;AACjD,IAAA,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE;CAClD;AAcD,MAAM,UAAU,GAAwE;IACtF,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,cAAc,EAAE;IACvE,EAAE,KAAK,EAAE,qBAAqB,EAAE,GAAG,EAAE,iBAAiB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACnF,EAAE,KAAK,EAAE,qBAAqB,EAAE,GAAG,EAAE,iBAAiB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACnF,EAAE,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE;IAC1E,EAAE,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE;IAC1E,EAAE,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE;IACrE,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE;IACjE,EAAE,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE;CAC3E;AAEK,SAAU,kBAAkB,CAAC,KAA4B,EAAA;AAC7D,IAAA,OAAO,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,KAAK,IAAI,KAAK;AAC9E;AAEM,SAAU,oBAAoB,CAAC,MAA+B,EAAA;IAClE,IAAI,CAAC,MAAM,CAAC,MAAM;AAAE,QAAA,OAAO,GAAG;IAC9B,OAAO,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;AAClD;AAEA;AACM,SAAU,sBAAsB,CACpC,IAAY,EACZ,YAA0C,EAAA;IAE1C,IAAI,MAAM,GAAG,IAAI;AACjB,IAAA,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE;AAC5B,QAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC;IACpD;AACA,IAAA,OAAO,MAAM;AACf;AAEA;SACgB,oBAAoB,CAClC,aAAqB,EACrB,eAAuB,EACvB,YAA0C,EAAA;AAE1C,IAAA,MAAM,MAAM,GAAG,aAAa,EAAE,IAAI,EAAE,GAAG,aAAa,GAAG,eAAe;AACtE,IAAA,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE;AAAE,QAAA,OAAO,GAAG;AAC/B,IAAA,OAAO,sBAAsB,CAAC,MAAM,EAAE,YAAY,CAAC;AACrD;AAEA;;;AAGG;AACG,SAAU,wBAAwB,CACtC,OAAoF,EACpF,IAA0B,EAAA;AAE1B,IAAA,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE;AACrF,IAAA,IAAI,CAAC,MAAM;AAAE,QAAA,OAAO,GAAG;AAEvB,IAAA,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB;AACzC,IAAA,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE;AAC7B,QAAA,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;AACnD,QAAA,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,IAAI,IAAI,CAAC,KAAK,CAAA,CAAA,CAAG,CAAC;IACvD;IACA,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,YAAY,IAAI,EAAE,EAAE;QAC1C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;YACzB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAA,CAAA,EAAI,CAAC,CAAC,KAAK,CAAA,CAAA,CAAG,CAAC;QAC/D;IACF;IAEA,IAAI,MAAM,GAAG,MAAM;IACnB,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE;AACpC,QAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IAC1C;AACA,IAAA,OAAO,MAAM;AACf;AAEA;AACM,SAAU,iBAAiB,CAAC,QAAmC,EAAA;IACnE,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;AACzC,IAAA,IAAI,CAAC,GAAG;AAAE,QAAA,OAAO,EAAE;AACnB,IAAA,MAAM,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC;IACrF,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;AAAE,QAAA,OAAO,GAAG;AAC/C,IAAA,OAAO,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE;AACrC,QAAA,OAAO,EAAE,OAAO;AAChB,QAAA,KAAK,EAAE,MAAM;AACb,QAAA,GAAG,EAAE,SAAS;AACd,QAAA,IAAI,EAAE,SAAS;AAChB,KAAA,CAAC;AACJ;AAEM,SAAU,iBAAiB,CAC/B,OAAkC,EAClC,WAA2B,EAAA;IAE3B,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;AACxC,IAAA,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC1C,QAAA,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE;AAC9B,YAAA,OAAO,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAChF;IACF;AACA,IAAA,IAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AAC9B,QAAA,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;AACzC,QAAA,MAAM,CAAC,GAAG,IAAI,IAAI,EAAE;QACpB,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AACtB,QAAA,OAAO,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAChF;AACA,IAAA,IAAI,WAAW;AAAE,QAAA,OAAO,iBAAiB,CAAC,WAAW,CAAC;AACtD,IAAA,OAAO,GAAG;AACZ;AAEA,SAAS,aAAa,CAAC,GAAW,EAAA;IAChC,MAAM,CAAC,GAAG,2BAA2B,CAAC,IAAI,CAAC,GAAG,CAAC;AAC/C,IAAA,IAAI,CAAC,CAAC;AAAE,QAAA,OAAO,IAAI;AACnB,IAAA,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D;AAEM,SAAU,wBAAwB,CAAC,OAAwB,EAAA;AAC/D,IAAA,OAAO,OAAO,CAAC,kBAAkB,IAAI,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,cAAc,CAAC;AACtF;AAEM,SAAU,sBAAsB,CAAC,OAAwB,EAAA;IAC7D,OAAO,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,cAAc,CAAC;AACxD;AAEM,SAAU,kBAAkB,CAChC,OAA+B,EAC/B,MAA8B,EAAA;AAE9B,IAAA,IAAI,CAAC,OAAO;AAAE,QAAA,OAAO,KAAK;AAC1B,IAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE;AAAE,QAAA,OAAO,KAAK;AAErE,IAAA,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,cAAc,EAAE;AAC1C,QAAA,IAAI,KAAK,KAAK,cAAc,EAAE;AAC5B,YAAA,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE;AAAE,gBAAA,OAAO,KAAK;QACnD;aAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE;AACjC,YAAA,OAAO,KAAK;QACd;IACF;AACA,IAAA,OAAO,IAAI;AACb;;MC3Ha,iCAAiC,CAAA;AAP9C,IAAA,WAAA,GAAA;AAQmB,QAAA,IAAA,CAAA,GAAG,GAAG,MAAM,CAAC,wBAAwB,CAAC;QAE9C,IAAA,CAAA,IAAI,GAAG,KAAK;QACZ,IAAA,CAAA,OAAO,GAA2B,IAAI;AAC5B,QAAA,IAAA,CAAA,MAAM,GAAG,IAAI,YAAY,EAAQ;AACjC,QAAA,IAAA,CAAA,KAAK,GAAG,IAAI,YAAY,EAAmB;QAI3C,IAAA,CAAA,YAAY,GAAG,sBAAsB;AACrC,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;AACtB,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAgB,IAAI,CAAC;QAE5C,IAAA,CAAA,KAAK,GAAG,EAAE;QACV,IAAA,CAAA,WAAW,GAAG,EAAE;QAChB,IAAA,CAAA,aAAa,GAAG,EAAE;QAClB,IAAA,CAAA,eAAe,GAAG,EAAE;QACpB,IAAA,CAAA,gBAAgB,GAAG,EAAE;AACrB,QAAA,IAAA,CAAA,cAAc,GAAG,IAAI,GAAG,EAAyB;QACjD,IAAA,CAAA,kBAAkB,GAAG,KAAK;QAC1B,IAAA,CAAA,SAAS,GAAG,CAAC;QACb,IAAA,CAAA,QAAQ,GAAG,IAAI;QACf,IAAA,CAAA,YAAY,GAAiC,oBAAoB;AAkJ5E,IAAA;AAhJC,IAAA,IAAc,MAAM,GAAA;AAClB,QAAA,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO;IACvB;AAEA,IAAA,IAAc,WAAW,GAAA;AACvB,QAAA,OAAO,oBAAoB,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,YAAY,CAAC;IAC1F;AAEA,IAAA,WAAW,CAAC,OAAsB,EAAA;AAChC,QAAA,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC,EAAE;YACvD,IAAI,CAAC,SAAS,EAAE;QAClB;IACF;IAEU,KAAK,GAAA;AACb,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;IACpB;AAEU,IAAA,cAAc,CAAC,KAA4B,EAAA;QACnD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC;AACzC,QAAA,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;AAAE,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;;AAClC,YAAA,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;AACpB,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI;IAC5B;AAEU,IAAA,kBAAkB,CAAC,KAA4B,EAAA;QACvD,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC;IACvC;AAEU,IAAA,iBAAiB,CAAC,KAAa,EAAA;AACvC,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,aAAa;QAC5C,IAAI,CAAC,EAAE,EAAE;AACP,YAAA,IAAI,CAAC,eAAe,IAAI,KAAK;YAC7B;QACF;QACA,MAAM,KAAK,GAAG,EAAE,CAAC,cAAc,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM;AAC9D,QAAA,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,IAAI,KAAK;AACpC,QAAA,IAAI,CAAC,eAAe;YAClB,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC;AAChF,QAAA,MAAM,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC,MAAM;QAChC,qBAAqB,CAAC,MAAK;YACzB,EAAE,CAAC,KAAK,EAAE;AACV,YAAA,EAAE,CAAC,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC;AAChC,QAAA,CAAC,CAAC;IACJ;IAEU,MAAM,GAAA;AACd,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;QACpB,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;QACtC,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE;QACnD,IAAI,CAAC,YAAY,EAAE;AACjB,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC;YACpC;QACF;QACA,IAAI,CAAC,eAAe,EAAE;AACpB,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,+BAA+B,CAAC;YAC/C;QACF;QACA,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG,EAAE;AACnC,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,iDAAiD,CAAC;YACjE;QACF;AAEA,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;QACrB,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC;QAEvC,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE;AAC/B,YAAA,MAAM,IAAI,GAAiC;AACzC,gBAAA,KAAK,EAAE,YAAY;AACnB,gBAAA,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE;AACpC,gBAAA,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE;AACxC,gBAAA,eAAe,EAAE,eAAe;gBAChC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,IAAI;AACtD,gBAAA,cAAc,EAAE,MAAM;gBACtB,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;gBAC3C,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB;AACD,YAAA,IAAI,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC;AACrE,gBAAA,IAAI,EAAE,CAAC,OAAO,KAAI;AAChB,oBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AACtB,oBAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;oBACxB,IAAI,CAAC,KAAK,EAAE;gBACd,CAAC;gBACD,KAAK,EAAE,MAAK;AACV,oBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AACtB,oBAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,kCAAkC,CAAC;gBACpD,CAAC;AACF,aAAA,CAAC;YACF;QACF;AAEA,QAAA,MAAM,IAAI,GAAiC;AACzC,YAAA,KAAK,EAAE,YAAY;AACnB,YAAA,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE;AACpC,YAAA,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE;AACxC,YAAA,eAAe,EAAE,eAAe;YAChC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,IAAI;AACtD,YAAA,cAAc,EAAE,MAAM;YACtB,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;YAC3C,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B;QACD,IAAI,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC;AAC7C,YAAA,IAAI,EAAE,CAAC,OAAO,KAAI;AAChB,gBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AACtB,gBAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;gBACxB,IAAI,CAAC,KAAK,EAAE;YACd,CAAC;YACD,KAAK,EAAE,MAAK;AACV,gBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AACtB,gBAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,oCAAoC,CAAC;YACtD,CAAC;AACF,SAAA,CAAC;IACJ;IAEQ,SAAS,GAAA;AACf,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;AACpB,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AACtB,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK;YAC/B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW;YAC3C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa;YAC/C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe;YACnD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,IAAI,EAAE;AAC3D,YAAA,IAAI,CAAC,cAAc,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;YAC1D,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB;YACzD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS;YACvC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ;YACrC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE;kBAC3C,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY;AAC/B,kBAAE,CAAC,GAAG,oBAAoB,CAAC;QAC/B;aAAO;AACL,YAAA,IAAI,CAAC,KAAK,GAAG,EAAE;AACf,YAAA,IAAI,CAAC,WAAW,GAAG,EAAE;AACrB,YAAA,IAAI,CAAC,aAAa,GAAG,EAAE;AACvB,YAAA,IAAI,CAAC,eAAe,GAAG,+CAA+C;AACtE,YAAA,IAAI,CAAC,gBAAgB,GAAG,EAAE;AAC1B,YAAA,IAAI,CAAC,cAAc,GAAG,IAAI,GAAG,EAAE;AAC/B,YAAA,IAAI,CAAC,kBAAkB,GAAG,KAAK;AAC/B,YAAA,IAAI,CAAC,SAAS,GAAG,CAAC;AAClB,YAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;AACpB,YAAA,IAAI,CAAC,YAAY,GAAG,CAAC,GAAG,oBAAoB,CAAC;QAC/C;IACF;+GAxKW,iCAAiC,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAjC,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,iCAAiC,6TCtC9C,8oKA+GA,EAAA,MAAA,EAAA,CAAA,yYAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,ED9Ec,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,8CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,iGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,4BAAA,EAAA,QAAA,EAAA,uGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,0FAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,wIAAA,EAAA,MAAA,EAAA,CAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,4EAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,YAAA,EAAA,QAAA,EAAA,gHAAA,EAAA,MAAA,EAAA,CAAA,KAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,wDAAA,EAAA,MAAA,EAAA,CAAA,eAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,cAAc,sHAAE,kBAAkB,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,MAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAKhD,iCAAiC,EAAA,UAAA,EAAA,CAAA;kBAP7C,SAAS;+BACI,iCAAiC,EAAA,OAAA,EAClC,CAAC,WAAW,EAAE,cAAc,EAAE,kBAAkB,CAAC,EAAA,eAAA,EAGzC,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,8oKAAA,EAAA,MAAA,EAAA,CAAA,yYAAA,CAAA,EAAA;8BAKxC,IAAI,EAAA,CAAA;sBAAZ;gBACQ,OAAO,EAAA,CAAA;sBAAf;gBACkB,MAAM,EAAA,CAAA;sBAAxB;gBACkB,KAAK,EAAA,CAAA;sBAAvB;gBAE2B,aAAa,EAAA,CAAA;sBAAxC,SAAS;uBAAC,eAAe;;;MEtBf,6BAA6B,CAAA;AAb1C,IAAA,WAAA,GAAA;AAcmB,QAAA,IAAA,CAAA,GAAG,GAAG,MAAM,CAAC,wBAAwB,CAAC;AAEpC,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAoB,EAAE,CAAC;AACxC,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC;AACtB,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAgB,IAAI,CAAC;AACnC,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC;AACzB,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAAyB,IAAI,CAAC;QAEvD,IAAA,CAAA,oBAAoB,GAAG,oBAAoB;AAkEtD,IAAA;IAhEC,QAAQ,GAAA;QACN,IAAI,CAAC,IAAI,EAAE;IACb;IAEU,IAAI,GAAA;AACZ,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AACtB,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC;AAC3C,YAAA,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAI;AACrB,gBAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC3B,gBAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YACzB,CAAC;YACD,KAAK,EAAE,MAAK;AACV,gBAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;AACvB,gBAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,mCAAmC,CAAC;YACrD,CAAC;AACF,SAAA,CAAC;IACJ;IAEU,UAAU,GAAA;AAClB,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AACtB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;IAC1B;AAEU,IAAA,QAAQ,CAAC,OAAwB,EAAA;AACzC,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;AACzB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;IAC1B;IAEU,UAAU,GAAA;AAClB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;AACzB,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;IACxB;IAEU,OAAO,GAAA;QACf,IAAI,CAAC,IAAI,EAAE;IACb;IAEU,YAAY,CAAC,OAAwB,EAAE,MAAe,EAAA;AAC9D,QAAA,IAAI,CAAC,GAAG,CAAC,qBAAqB,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC;AAChF,YAAA,IAAI,EAAE,CAAC,OAAO,KAAI;AAChB,gBAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,KACxB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CACnE;YACH,CAAC;AACD,YAAA,KAAK,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE;AACzB,SAAA,CAAC;IACJ;AAEU,IAAA,aAAa,CAAC,OAAwB,EAAA;AAC9C,QAAA,IAAI,OAAO,CAAC,QAAQ,EAAE;AACpB,YAAA,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC;YACjC;QACF;QACA,IAAI,CAAC,OAAO,CAAC,CAAA,QAAA,EAAW,OAAO,CAAC,KAAK,2BAA2B,CAAC;YAAE;QACnE,IAAI,CAAC,GAAG,CAAC,qBAAqB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC;AAC1D,YAAA,IAAI,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE;YACvB,KAAK,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,2BAA2B,CAAC;AACzD,SAAA,CAAC;IACJ;AAEU,IAAA,WAAW,CAAC,OAAwB,EAAA;QAC5C,OAAO,OAAO,CAAC,QAAQ,GAAG,YAAY,GAAG,QAAQ;IACnD;+GA1EW,6BAA6B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;mGAA7B,6BAA6B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,4BAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECxB1C,ikGAiFA,EAAA,MAAA,EAAA,CAAA,+IAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDnEQ,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACV,iBAAiB,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACjB,kBAAkB,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,MAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAClB,gBAAgB,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAChB,iCAAiC,EAAA,QAAA,EAAA,iCAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,OAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAM5B,6BAA6B,EAAA,UAAA,EAAA,CAAA;kBAbzC,SAAS;AACI,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,4BAA4B,EAAA,OAAA,EAC7B;wBACL,UAAU;wBACV,iBAAiB;wBACjB,kBAAkB;wBAClB,gBAAgB;wBAChB,iCAAiC;qBACpC,EAAA,eAAA,EAGgB,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,ikGAAA,EAAA,MAAA,EAAA,CAAA,+IAAA,CAAA,EAAA;;;;;"}
|
|
@@ -3,8 +3,7 @@ import { inject, EventEmitter, signal, Output, Input, ChangeDetectionStrategy, C
|
|
|
3
3
|
import * as i1 from '@angular/forms';
|
|
4
4
|
import { FormsModule } from '@angular/forms';
|
|
5
5
|
import { ActivatedRoute } from '@angular/router';
|
|
6
|
-
import { A as AiReceptionistApiService, W as WELCOME_MESSAGE_MAX,
|
|
7
|
-
import { ToastService, EdsButtonComponent, EdsIconComponent } from './edvak99-voice-receptionist-widget.mjs';
|
|
6
|
+
import { A as AiReceptionistApiService, T as ToastService, E as EdsButtonComponent, d as EdsIconComponent, W as WELCOME_MESSAGE_MAX, p as buildAutoWelcomeTemplate, q as resolveWelcomePreview } from './edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-pS2jeB4x.mjs';
|
|
8
7
|
import { M as ModalComponent } from './edvak99-voice-receptionist-widget-modal.component-uYApl1KF.mjs';
|
|
9
8
|
import { switchMap, catchError, of, tap, throwError, finalize } from 'rxjs';
|
|
10
9
|
|
|
@@ -1054,4 +1053,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
1054
1053
|
}] });
|
|
1055
1054
|
|
|
1056
1055
|
export { SettingsPageComponent };
|
|
1057
|
-
//# sourceMappingURL=edvak99-voice-receptionist-widget-settings-page.component-
|
|
1056
|
+
//# sourceMappingURL=edvak99-voice-receptionist-widget-settings-page.component-C6F-Hgmk.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edvak99-voice-receptionist-widget-settings-page.component-C6F-Hgmk.mjs","sources":["../../../src/lib/components/knowledge-test-modal/knowledge-test-modal.component.ts","../../../src/lib/components/knowledge-test-modal/knowledge-test-modal.component.html","../../../src/lib/services/agent-online.service.ts","../../../src/lib/pages/settings-page/tts-voice-presets.ts","../../../src/lib/pages/settings-page/settings-fields.config.ts","../../../src/lib/pages/settings-page/settings-page.component.ts","../../../src/lib/pages/settings-page/settings-page.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n Input,\n OnChanges,\n OnDestroy,\n Output,\n SimpleChanges,\n inject,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\nimport { ModalComponent } from '../../shared/modal.component';\nimport { ToastService } from '../../shared/toast.service';\n\nconst QUESTION_MAX = 500;\n\n@Component({\n selector: 'eds-knowledge-test-modal',\n imports: [FormsModule, ModalComponent, EdsButtonComponent, EdsIconComponent],\n templateUrl: './knowledge-test-modal.component.html',\n styleUrl: './knowledge-test-modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class KnowledgeTestModalComponent implements OnChanges, OnDestroy {\n private readonly api = inject(AiReceptionistApiService);\n private readonly toast = inject(ToastService);\n\n @Input({ required: true }) open = false;\n @Input() whatToSay = '';\n @Input() whatNotToSay = '';\n @Input() voiceId = '';\n @Output() readonly closed = new EventEmitter<void>();\n\n protected readonly questionMax = QUESTION_MAX;\n protected readonly question = signal('');\n protected readonly testing = signal(false);\n protected readonly answer = signal<string | null>(null);\n protected readonly playing = signal(false);\n\n private audio: HTMLAudioElement | null = null;\n private objectUrl: string | null = null;\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['open'] && this.open) {\n this.question.set('');\n this.answer.set(null);\n this.stopAudio();\n }\n if (changes['open'] && !this.open) {\n this.stopAudio();\n }\n }\n\n ngOnDestroy(): void {\n this.stopAudio();\n }\n\n protected close(): void {\n this.stopAudio();\n this.closed.emit();\n }\n\n protected onQuestionChange(value: string): void {\n this.question.set(value.slice(0, QUESTION_MAX));\n }\n\n protected runTest(): void {\n const q = this.question().trim();\n if (!q || this.testing()) return;\n\n const whatToSay = this.whatToSay.trim();\n const whatNotToSay = this.whatNotToSay.trim();\n if (!whatToSay || !whatNotToSay) {\n this.toast.show(\n 'Fill in both “What to say” and “What not to say” before testing.',\n 'error',\n );\n return;\n }\n\n this.testing.set(true);\n this.answer.set(null);\n this.stopAudio();\n\n this.api\n .testKnowledgeAnswer({\n question: q,\n whatToSay,\n whatNotToSay,\n voiceId: this.voiceId.trim() || undefined,\n })\n .subscribe({\n next: (result) => {\n this.testing.set(false);\n this.answer.set(result.answer);\n this.playAudio(result.audioBlob);\n },\n error: (err: unknown) => {\n this.testing.set(false);\n const message =\n err instanceof Error && err.message.trim()\n ? err.message\n : 'Could not generate a test answer.';\n this.toast.show(message, 'error');\n },\n });\n }\n\n protected replay(): void {\n if (!this.audio) return;\n this.audio.currentTime = 0;\n this.playing.set(true);\n void this.audio.play().catch(() => {\n this.playing.set(false);\n this.toast.show('Could not play audio in this browser.', 'error');\n });\n }\n\n private playAudio(blob: Blob): void {\n this.stopAudio();\n this.objectUrl = URL.createObjectURL(blob);\n const audio = new Audio(this.objectUrl);\n this.audio = audio;\n this.playing.set(true);\n audio.onended = () => this.playing.set(false);\n audio.onerror = () => {\n this.playing.set(false);\n this.toast.show('Could not play audio in this browser.', 'error');\n };\n void audio.play().catch(() => {\n this.playing.set(false);\n this.toast.show('Could not play audio in this browser.', 'error');\n });\n }\n\n private stopAudio(): void {\n if (this.audio) {\n this.audio.pause();\n this.audio.onended = null;\n this.audio.onerror = null;\n this.audio = null;\n }\n if (this.objectUrl) {\n URL.revokeObjectURL(this.objectUrl);\n this.objectUrl = null;\n }\n this.playing.set(false);\n }\n}\n","@if (open) {\n <app-modal\n title=\"Test Knowledge Base\"\n subtitle=\"Ask a sample caller question — hear how the agent answers with your guidance and voice\"\n maxWidth=\"560px\"\n (closed)=\"close()\"\n >\n <form class=\"flex flex-col gap-4\" (ngSubmit)=\"runTest()\" novalidate autocomplete=\"off\">\n <label class=\"flex flex-col gap-2\">\n <span class=\"kb-test__label text-[13px] font-semibold\">\n What might a caller ask? <span class=\"text-[#dc2626]\">*</span>\n </span>\n <textarea\n class=\"kb-test__textarea box-border min-h-[84px] w-full resize-y rounded-lg border px-3 py-3 text-sm leading-[1.45]\"\n rows=\"3\"\n [maxlength]=\"questionMax\"\n [ngModel]=\"question()\"\n (ngModelChange)=\"onQuestionChange($event)\"\n name=\"question\"\n placeholder=\"e.g. What are your Saturday hours? Is parking free?\"\n [disabled]=\"testing()\"\n autocomplete=\"off\"\n ></textarea>\n <span class=\"kb-test__hint self-end text-xs\">{{ question().length }}/{{ questionMax }}</span>\n </label>\n\n @if (answer(); as spoken) {\n <div class=\"kb-test__answer rounded-lg border px-4 py-3\" role=\"status\">\n <div class=\"mb-2 flex items-center gap-2 text-xs font-semibold uppercase tracking-wide\">\n <eds-icon name=\"graphic_eq\" [size]=\"18\" />\n <span>Agent reply</span>\n @if (playing()) {\n <span class=\"kb-test__playing ml-auto font-medium normal-case tracking-normal\">Playing…</span>\n } @else {\n <button type=\"button\" class=\"kb-test__replay ml-auto cursor-pointer border-none bg-transparent px-1 py-1 text-[13px] font-semibold normal-case tracking-normal\" (click)=\"replay()\">\n Replay\n </button>\n }\n </div>\n <p class=\"m-0 text-sm leading-[1.55]\">{{ spoken }}</p>\n </div>\n }\n\n <footer class=\"flex justify-end gap-3 pt-1\">\n <eds-button type=\"button\" variant=\"secondary\" (click)=\"close()\" [disabled]=\"testing()\">\n Close\n </eds-button>\n <eds-button type=\"submit\" variant=\"primary\" [disabled]=\"testing() || !question().trim()\">\n @if (testing()) {\n Generating…\n } @else {\n <eds-icon name=\"play_arrow\" [size]=\"18\" />\n Test\n }\n </eds-button>\n </footer>\n </form>\n </app-modal>\n}\n","import { Injectable, inject, signal } from '@angular/core';\nimport { catchError, finalize, of, switchMap, tap, throwError } from 'rxjs';\n\nimport { AiReceptionistApiService } from './ai-receptionist-api.service';\n\nexport type AgentOnlineKnownState = boolean | null;\n\n/**\n * Shared source of truth for Ava online/offline across topbar + module nav.\n * Always re-fetches GET /status after mutations.\n */\n@Injectable({ providedIn: 'root' })\nexport class AgentOnlineService {\n private readonly api = inject(AiReceptionistApiService);\n\n /** true = online, false = offline, null = unknown / not loaded */\n private readonly _online = signal<AgentOnlineKnownState>(null);\n private readonly _loading = signal(false);\n private readonly _toggling = signal(false);\n private readonly _error = signal<string | null>(null);\n private readonly _readiness = signal<number | null>(null);\n\n readonly online = this._online.asReadonly();\n readonly loading = this._loading.asReadonly();\n readonly toggling = this._toggling.asReadonly();\n readonly error = this._error.asReadonly();\n readonly readiness = this._readiness.asReadonly();\n\n refresh(): void {\n this._loading.set(true);\n this._error.set(null);\n this.api.getStatus().subscribe({\n next: ({ data }) => {\n this._online.set(data.agentOn);\n this._readiness.set(data.readiness);\n this._loading.set(false);\n },\n error: (err: { message?: string }) => {\n this._online.set(null);\n this._error.set(err.message ?? 'Could not load agent status.');\n this._loading.set(false);\n },\n });\n }\n\n /**\n * PUT /agent-online then re-fetch GET /status.\n */\n setOnline(enabled: boolean) {\n this._toggling.set(true);\n this._error.set(null);\n\n return this.api.setAgentOnline(enabled).pipe(\n switchMap(() =>\n this.api.getStatus().pipe(\n catchError((err: { message?: string }) => {\n this._error.set(err.message ?? 'Status refresh failed after toggle.');\n return of(null);\n }),\n ),\n ),\n tap((result) => {\n if (result) {\n this._online.set(result.data.agentOn);\n this._readiness.set(result.data.readiness);\n } else {\n // Toggle likely succeeded; use requested value until refresh works.\n this._online.set(enabled);\n }\n }),\n catchError((err: { message?: string }) => {\n this._error.set(err.message ?? 'Failed to update agent online status.');\n return throwError(() => err);\n }),\n finalize(() => this._toggling.set(false)),\n );\n }\n}\n","/** Curated ElevenLabs voices — keep in sync with backend `tts-voice-presets.ts`. */\n\nexport interface TtsVoicePreset {\n id: string;\n label: string;\n /** Display gender hint next to the voice name. */\n gender: 'M' | 'F';\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 gender: 'M',\n },\n {\n id: 'NUjosfEayZAdRcDmcHM8',\n label: 'Madison – Cool, Calm & Conversational',\n gender: 'F',\n },\n {\n id: 'gE0owC0H9C8SzfDyIUtB',\n label: 'Ivanna – Sassy, Condescending and Clear',\n gender: 'F',\n },\n {\n id: 'Uc7anshoV8mdBhDnEZEX',\n label: 'Cecily – Clear and Warm',\n gender: 'F',\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<\n keyof AgentSettings,\n | 'safety'\n | 'effectiveWelcomeMessage'\n | 'effectiveVoiceSystemPrompt'\n | 'usingDefaultVoiceSystemPrompt'\n>;\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 AGENT_TONE_OPTIONS: SettingsFieldOption[] = [\n { value: 'warm_friendly', label: 'Warm & friendly' },\n { value: 'professional', label: 'Professional' },\n { value: 'efficient_brief', label: 'Efficient & brief' },\n { value: 'casual_friendly', label: 'Casual & friendly' },\n];\n\nexport const LANGUAGE_OPTIONS: SettingsFieldOption[] = [\n { value: 'English', label: 'English' },\n { value: 'Spanish', label: 'Spanish' },\n { value: 'Chinese', label: 'Chinese' },\n { value: 'Hindi', label: 'Hindi' },\n { value: 'French', label: 'French' },\n { value: 'German', label: 'German' },\n { value: 'Portuguese', label: 'Portuguese' },\n { value: 'Arabic', label: 'Arabic' },\n { value: 'Korean', label: 'Korean' },\n { value: 'Japanese', label: 'Japanese' },\n];\n\nexport const GREETING_VARIABLES: { key: string; label: string; token: string }[] = [\n { key: 'practiceName', label: 'Practice Name', token: '{{practiceName}}' },\n { key: 'agentName', label: 'Agent Name', token: '{{agentName}}' },\n { key: 'locationName', label: 'Location Name', token: '{{locationName}}' },\n { key: 'businessHours', label: 'Business Hours', token: '{{businessHours}}' },\n];\n\nexport const RETENTION_DAY_OPTIONS: SettingsFieldOption[] = [\n { value: '7', label: '7 days' },\n { value: '14', label: '14 days' },\n { value: '30', label: '30 days' },\n { value: '60', label: '60 days' },\n { value: '90', label: '90 days' },\n { value: '180', label: '180 days' },\n { value: '365', label: '1 year' },\n];\n\nexport const RING_TIMEOUT_OPTIONS: SettingsFieldOption[] = [\n { value: '10', label: '10 sec' },\n { value: '15', label: '15 sec' },\n { value: '20', label: '20 sec' },\n { value: '30', label: '30 sec' },\n { value: '45', label: '45 sec' },\n { value: '60', label: '60 sec' },\n];\n\nexport const MAX_CALL_DURATION_OPTIONS: SettingsFieldOption[] = [\n { value: '3', label: '3 min' },\n { value: '5', label: '5 min' },\n { value: '10', label: '10 min' },\n { value: '15', label: '15 min' },\n { value: '20', label: '20 min' },\n { value: '30', label: '30 min' },\n];\n\nexport const SILENCE_TIMEOUT_OPTIONS: SettingsFieldOption[] = [\n { value: '10', label: '10 seconds' },\n { value: '15', label: '15 seconds' },\n { value: '20', label: '20 seconds' },\n { value: '30', label: '30 seconds' },\n { value: '45', label: '45 seconds' },\n { value: '60', label: '60 seconds' },\n];\n\nexport const AI_ANSWER_MODE_OPTIONS: SettingsFieldOption[] = [\n { value: 'always_first', label: 'Always first' },\n { value: 'ring_then_ai', label: 'Ring staff, then AI' },\n { value: 'ai_backup', label: 'AI as backup only' },\n];\n\nexport const AFTER_HOURS_OPTIONS: SettingsFieldOption[] = [\n { value: 'ai_answers', label: 'AI answers' },\n { value: 'voicemail', label: 'Voicemail' },\n { value: 'transfer', label: 'Transfer to after-hours number' },\n];\n\nexport const DEFAULT_DISCLOSURE_WARNING =\n 'This call may be handled by an automated assistant and could be recorded for quality and training. You can ask to speak with a staff member at any time.';\n\nexport const SETTINGS_SECTION_META: Record<SettingsSection, SettingsSectionMeta> = {\n general: {\n title: 'AI Identity',\n description: 'Name, voice, languages, tone, and inbound greeting.',\n },\n phone: {\n title: 'Phone & Availability',\n description: 'Inbound routing, ring timing, locations, and after-hours behavior.',\n },\n tasks: {\n title: 'Task Rules',\n description: 'When the AI should create staff tasks after a call.',\n },\n scheduling: {\n title: 'Scheduling Rules',\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: 'Safety Escalation',\n description: 'When to offer a human or transfer to reception.',\n },\n outbound: {\n title: 'Outbound Purpose',\n description: 'Outbound dialer defaults. Purpose templates are managed separately.',\n },\n knowledge: {\n title: 'Knowledge Base',\n description: 'Practice information the AI should share — and topics it must avoid.',\n },\n transcripts: {\n title: 'Data & Compliance',\n description: 'Recording retention, transcripts, and disclosure warnings.',\n },\n advanced: {\n title: 'Advanced',\n description: 'Agent online status and model options.',\n },\n};\n\n/** Entire sections where every field is read-only (including unknown API fields). */\nexport const READ_ONLY_SECTIONS = new Set<SettingsSection>(['verify']);\n\n/** Settings tabs that stay visible but cannot be selected/edited. */\nexport const DISABLED_SETTINGS_TABS = new Set<SettingsSection>(['verify', 'escalation']);\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: 'timezone', reason: 'Practice timezone' },\n { section: 'phone', key: 'mainNumber', reason: 'AI phone number' },\n { section: 'phone', key: 'transferNumber', reason: 'Transfer number' },\n { section: 'tasks', key: 'defaultAssignee', reason: 'Default task assignee' },\n { section: 'outbound', key: 'callerId', reason: 'Outbound caller ID' },\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: 'agentName',\n label: 'Name',\n description: 'How the assistant introduces itself.',\n type: 'text',\n },\n {\n key: 'ttsVoiceId',\n label: 'Voice',\n description: 'Spoken voice used on phone calls.',\n type: 'select',\n options: TTS_VOICE_PRESETS.map((p) => ({\n value: p.id,\n label: `${p.gender} · ${p.label}`,\n })),\n },\n {\n key: 'languages',\n label: 'Language',\n description: 'Languages the AI can speak on calls.',\n type: 'text',\n },\n {\n key: 'tone',\n label: 'Tone',\n description: 'Conversational style for the AI.',\n type: 'select',\n options: AGENT_TONE_OPTIONS,\n },\n {\n key: 'welcomeMessage',\n label: 'Inbound Greetings',\n description: 'Spoken when a caller connects.',\n type: 'text',\n },\n ],\n phone: [\n {\n key: 'answerMode',\n label: 'AI Answer Mode',\n description: 'When the AI picks up inbound calls.',\n type: 'select',\n options: AI_ANSWER_MODE_OPTIONS,\n },\n {\n key: 'mainNumber',\n label: 'AI Phone Number',\n description: 'Number patients dial for the AI receptionist.',\n type: 'text',\n },\n {\n key: 'transferNumber',\n label: 'Transfer Number',\n description: 'Staff / front-desk number for handoff.',\n type: 'text',\n },\n {\n key: 'ringTimeout',\n label: 'Ringing Time Wait',\n description: 'How long to ring before the AI answers.',\n type: 'select',\n options: RING_TIMEOUT_OPTIONS,\n },\n {\n key: 'createFollowUpTask',\n label: 'Create Follow-up Task',\n description: 'If no one answers in time, the agent auto-creates a high priority task.',\n type: 'boolean',\n },\n {\n key: 'locationIds',\n label: 'Location Handled',\n description: 'Locations this AI receptionist covers.',\n type: 'text',\n },\n {\n key: 'maxCallDurationMin',\n label: 'Max AI Call Duration',\n description: 'Longest call the AI will stay on before wrapping up.',\n type: 'select',\n options: MAX_CALL_DURATION_OPTIONS,\n },\n {\n key: 'silenceTimeoutSec',\n label: 'Silence Timeout',\n description: 'How long silence lasts before the AI prompts or ends.',\n type: 'select',\n options: SILENCE_TIMEOUT_OPTIONS,\n },\n {\n key: 'afterHoursBehavior',\n label: 'After-Hours Behaviour',\n description: 'What happens outside business hours.',\n type: 'select',\n options: AFTER_HOURS_OPTIONS,\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 knowledge: [\n {\n key: 'whatToSay',\n label: 'What to say',\n description: 'Facts and guidance the AI may share with callers.',\n type: 'text',\n },\n {\n key: 'whatNotToSay',\n label: 'What not to say',\n description: 'Topics the AI must refuse or escalate.',\n type: 'text',\n },\n ],\n transcripts: [\n {\n key: 'recordingRetainDays',\n label: 'Keep Call Recordings',\n description: 'How long call recordings are retained.',\n type: 'select',\n options: RETENTION_DAY_OPTIONS,\n },\n {\n key: 'transcriptRetainDays',\n label: 'Keep Transcripts',\n description: 'How long call transcripts are retained.',\n type: 'select',\n options: RETENTION_DAY_OPTIONS,\n },\n {\n key: 'disclosureWarningEnabled',\n label: 'Disclosure Warning',\n description: 'Play or show a disclosure when the AI answers.',\n type: 'boolean',\n },\n {\n key: 'disclosureWarningText',\n label: 'Disclosure text',\n description: 'Spoken or shown disclosure message.',\n type: 'text',\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\nexport function parseCsvList(value: unknown): string[] {\n return String(value ?? '')\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\nexport function toCsvList(values: string[]): string {\n return values.map((v) => v.trim()).filter(Boolean).join(',');\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, OnDestroy, OnInit, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { KnowledgeTestModalComponent } from '../../components/knowledge-test-modal/knowledge-test-modal.component';\nimport { AgentSettings, LocationOption } from '../../models/ai-receptionist.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { AgentOnlineService } from '../../services/agent-online.service';\nimport { ModalComponent } from '../../shared/modal.component';\nimport { ToastService } from '../../shared/toast.service';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\nimport {\n buildAutoWelcomeTemplate,\n resolveWelcomePreview,\n WELCOME_MESSAGE_MAX,\n} from '../../utils/welcome-message.util';\nimport { TTS_VOICE_PRESETS } from './tts-voice-presets';\nimport {\n AFTER_HOURS_OPTIONS,\n AGENT_TONE_OPTIONS,\n AI_ANSWER_MODE_OPTIONS,\n DEFAULT_DISCLOSURE_WARNING,\n DISABLED_SETTINGS_TABS,\n GREETING_VARIABLES,\n isFieldReadOnly,\n MAX_CALL_DURATION_OPTIONS,\n parseCsvList,\n READ_ONLY_SECTIONS,\n resolveFieldMeta,\n RETENTION_DAY_OPTIONS,\n RING_TIMEOUT_OPTIONS,\n SETTINGS_FIELDS,\n SETTINGS_SECTION_META,\n SettingsFieldMeta,\n SettingsSection,\n SILENCE_TIMEOUT_OPTIONS,\n toCsvList,\n} from './settings-fields.config';\n\ntype SettingsTab = Exclude<\n keyof AgentSettings,\n | 'safety'\n | 'effectiveWelcomeMessage'\n | 'effectiveVoiceSystemPrompt'\n | 'usingDefaultVoiceSystemPrompt'\n>;\n\nconst CUSTOM_PANEL_TABS = new Set<SettingsTab>([\n 'general',\n 'phone',\n 'transcripts',\n 'knowledge',\n 'advanced',\n]);\nconst HIDDEN_GENERIC_KEYS = new Set([\n 'welcomeMessage',\n 'practiceName',\n 'language',\n 'languages',\n 'tone',\n 'timezone',\n 'voiceSystemPrompt',\n 'customVoiceInstructions',\n]);\nconst KNOWLEDGE_MAX = 8000;\nconst DISCLOSURE_MAX = 1000;\n\n@Component({\n selector: 'eds-settings-page',\n imports: [\n FormsModule,\n EdsButtonComponent,\n EdsIconComponent,\n KnowledgeTestModalComponent,\n ModalComponent,\n ],\n templateUrl: './settings-page.component.html',\n styleUrl: './settings-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SettingsPageComponent implements OnInit, OnDestroy {\n private readonly api = inject(AiReceptionistApiService);\n private readonly toast = inject(ToastService);\n private readonly route = inject(ActivatedRoute);\n private readonly agentOnline = inject(AgentOnlineService);\n private originalSettings: AgentSettings | null = null;\n private voiceAudio: HTMLAudioElement | null = null;\n private voiceObjectUrl: string | null = null;\n\n protected readonly isFieldReadOnly = isFieldReadOnly;\n protected readonly knowledgeMax = KNOWLEDGE_MAX;\n protected readonly disclosureMax = DISCLOSURE_MAX;\n protected readonly welcomeMax = WELCOME_MESSAGE_MAX;\n protected readonly voicePresets = TTS_VOICE_PRESETS;\n protected readonly toneOptions = AGENT_TONE_OPTIONS;\n protected readonly greetingVariables = GREETING_VARIABLES;\n protected readonly retentionOptions = RETENTION_DAY_OPTIONS;\n protected readonly ringTimeoutOptions = RING_TIMEOUT_OPTIONS;\n protected readonly maxCallDurationOptions = MAX_CALL_DURATION_OPTIONS;\n protected readonly silenceTimeoutOptions = SILENCE_TIMEOUT_OPTIONS;\n protected readonly answerModeOptions = AI_ANSWER_MODE_OPTIONS;\n protected readonly afterHoursOptions = AFTER_HOURS_OPTIONS;\n\n protected readonly settings = signal<AgentSettings | null>(null);\n protected readonly tab = signal<SettingsTab>('general');\n protected readonly loading = signal(true);\n protected readonly saving = signal(false);\n protected readonly saved = signal(false);\n protected readonly knowledgeTestOpen = signal(false);\n protected readonly locations = signal<LocationOption[]>([]);\n protected readonly locationsMenuOpen = signal(false);\n protected readonly confirmOffOpen = signal(false);\n protected readonly voicePreviewBusy = signal(false);\n protected readonly voicePreviewPlaying = signal(false);\n\n protected readonly online = this.agentOnline.online;\n protected readonly agentLoading = this.agentOnline.loading;\n protected readonly toggling = this.agentOnline.toggling;\n\n protected readonly tabs: { id: SettingsTab; label: string }[] = [\n { id: 'general', label: 'Identity & Greetings' },\n { id: 'phone', label: 'Phone & Availability' },\n { id: 'knowledge', label: 'Knowledge Base' },\n { id: 'transcripts', label: 'Data & Compliance' },\n { id: 'advanced', label: 'Advanced' },\n ];\n\n protected readonly sectionMeta = computed(() => {\n const id = this.tab();\n return SETTINGS_SECTION_META[id as SettingsSection] ?? { title: String(id), description: '' };\n });\n\n protected readonly fieldsForTab = computed((): SettingsFieldMeta[] => {\n const s = this.settings();\n const id = this.tab();\n if (!s || CUSTOM_PANEL_TABS.has(id)) return [];\n\n const section = s[id] as Record<string, string | boolean | number>;\n const configured = SETTINGS_FIELDS[id as SettingsSection] ?? [];\n const configuredKeys = new Set(configured.map((f) => f.key));\n\n const extras = Object.keys(section)\n .filter((key) => !HIDDEN_GENERIC_KEYS.has(key) && !configuredKeys.has(key))\n .map((key) => resolveFieldMeta(id as SettingsSection, key, section[key]));\n\n return [...configured, ...extras];\n });\n\n protected readonly welcomeMessage = computed(() =>\n String(this.settings()?.general['welcomeMessage'] ?? ''),\n );\n\n protected readonly welcomePlaceholder = computed(() => {\n const s = this.settings();\n if (!s) return '';\n return buildAutoWelcomeTemplate(\n String(s.general['practiceName'] ?? ''),\n String(s.general['agentName'] ?? ''),\n );\n });\n\n protected readonly welcomePreview = computed(() => {\n const s = this.settings();\n if (!s) return '';\n const raw = resolveWelcomePreview(\n String(s.general['welcomeMessage'] ?? ''),\n String(s.general['practiceName'] ?? ''),\n String(s.general['agentName'] ?? ''),\n );\n return raw\n .replaceAll('{{practiceName}}', String(s.general['practiceName'] || 'our practice'))\n .replaceAll('{{agentName}}', String(s.general['agentName'] || 'your AI receptionist'))\n .replaceAll('{{locationName}}', 'Main location')\n .replaceAll('{{businessHours}}', 'Mon–Fri 8am–5pm');\n });\n\n protected readonly whatToSay = computed(() =>\n String(this.settings()?.knowledge?.['whatToSay'] ?? ''),\n );\n\n protected readonly whatNotToSay = computed(() =>\n String(this.settings()?.knowledge?.['whatNotToSay'] ?? ''),\n );\n\n protected readonly selectedLocationIds = computed(() =>\n parseCsvList(this.settings()?.phone?.['locationIds']),\n );\n\n protected readonly locationSummary = computed(() => {\n const selected = this.selectedLocationIds();\n const all = this.locations();\n if (!all.length) return 'No locations available';\n if (!selected.length) return 'Select locations';\n const names = all.filter((l) => selected.includes(l.id)).map((l) => l.name);\n if (!names.length) return `${selected.length} selected`;\n if (names.length <= 2) return names.join(', ');\n return `${names[0]}, ${names[1]} +${names.length - 2}`;\n });\n\n protected readonly selectedTone = computed(() =>\n String(this.settings()?.general?.['tone'] ?? 'professional'),\n );\n\n protected readonly disclosureEnabled = computed(\n () => this.settings()?.transcripts?.['disclosureWarningEnabled'] !== false,\n );\n\n protected readonly disclosureText = computed(() =>\n String(this.settings()?.transcripts?.['disclosureWarningText'] ?? DEFAULT_DISCLOSURE_WARNING),\n );\n\n protected readonly agentSwitchDisabled = computed(\n () => this.agentLoading() || this.toggling() || this.online() === null,\n );\n\n ngOnInit(): void {\n this.agentOnline.refresh();\n\n const dataTab = this.route.snapshot.data['settingsTab'] as SettingsTab | undefined;\n const tabParam = this.route.snapshot.queryParamMap.get('tab');\n if (dataTab && this.tabs.some((t) => t.id === dataTab)) {\n this.tab.set(dataTab);\n } else if (tabParam && this.tabs.some((t) => t.id === tabParam)) {\n this.tab.set(tabParam as SettingsTab);\n }\n\n this.api.getSettings().subscribe({\n next: ({ data }) => {\n this.originalSettings = structuredClone(data);\n this.settings.set(structuredClone(data));\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.toast.show('Failed to load agent settings', 'error');\n },\n });\n\n this.api.getLocations().subscribe({\n next: ({ data }) => this.locations.set(data ?? []),\n error: () => this.locations.set([]),\n });\n }\n\n ngOnDestroy(): void {\n this.stopVoicePreview();\n }\n\n protected fieldIsReadOnly(section: SettingsTab, key: string): boolean {\n return isFieldReadOnly(section, key);\n }\n\n protected sectionIsReadOnly(section: SettingsTab): boolean {\n return READ_ONLY_SECTIONS.has(section);\n }\n\n protected isTabDisabled(id: SettingsTab): boolean {\n return DISABLED_SETTINGS_TABS.has(id);\n }\n\n protected setTab(id: SettingsTab): void {\n if (this.isTabDisabled(id)) return;\n this.locationsMenuOpen.set(false);\n this.tab.set(id);\n }\n\n protected updateField(section: SettingsTab, key: string, value: string | boolean | number): void {\n const current = this.settings();\n if (!current || isFieldReadOnly(section as SettingsSection, key)) return;\n const sectionData = { ...(current[section] as Record<string, string | boolean | number>) };\n sectionData[key] = value;\n this.settings.set({ ...current, [section]: sectionData });\n }\n\n protected updateWelcomeMessage(value: string): void {\n this.updateField('general', 'welcomeMessage', value.slice(0, WELCOME_MESSAGE_MAX));\n }\n\n protected insertGreetingVariable(token: string): void {\n const current = this.welcomeMessage();\n const next = `${current}${current && !/\\s$/.test(current) ? ' ' : ''}${token}`;\n this.updateWelcomeMessage(next);\n }\n\n protected updateKnowledgeField(key: 'whatToSay' | 'whatNotToSay', value: string): void {\n this.updateField('knowledge', key, value.slice(0, KNOWLEDGE_MAX));\n }\n\n protected setTone(tone: string): void {\n this.updateField('general', 'tone', tone);\n }\n\n protected toggleLocationsMenu(): void {\n if (!this.locations().length) return;\n this.locationsMenuOpen.update((open) => !open);\n }\n\n protected onLocationsDocClick(event: MouseEvent): void {\n const target = event.target as HTMLElement | null;\n if (!target?.closest('.settings-page__locations-dd')) {\n this.locationsMenuOpen.set(false);\n }\n }\n\n protected toggleLocation(id: string): void {\n const current = this.selectedLocationIds();\n const next = current.includes(id) ? current.filter((x) => x !== id) : [...current, id];\n this.updateField('phone', 'locationIds', toCsvList(next));\n }\n\n protected selectNumberField(\n section: 'phone' | 'transcripts',\n key: string,\n value: string,\n ): void {\n this.updateField(section, key, Number(value));\n }\n\n protected numberFieldAsString(section: 'phone' | 'transcripts', key: string): string {\n return String(this.fieldValue(section, key) ?? '');\n }\n\n protected setDisclosureEnabled(enabled: boolean): void {\n this.updateField('transcripts', 'disclosureWarningEnabled', enabled);\n if (enabled && !String(this.settings()?.transcripts?.['disclosureWarningText'] ?? '').trim()) {\n this.updateField('transcripts', 'disclosureWarningText', DEFAULT_DISCLOSURE_WARNING);\n }\n }\n\n protected updateDisclosureText(value: string): void {\n this.updateField('transcripts', 'disclosureWarningText', value.slice(0, DISCLOSURE_MAX));\n }\n\n protected openTestCall(): void {\n const whatToSay = this.whatToSay().trim();\n const whatNotToSay = this.whatNotToSay().trim();\n if (!whatToSay || !whatNotToSay) {\n this.toast.show(\n 'Fill in both “What to say” and “What not to say” before testing.',\n 'error',\n );\n return;\n }\n this.knowledgeTestOpen.set(true);\n }\n\n protected closeTestCall(): void {\n this.knowledgeTestOpen.set(false);\n }\n\n protected selectedVoiceId(): string {\n return String(this.settings()?.general?.['ttsVoiceId'] ?? '').trim();\n }\n\n protected onVoiceChange(voiceId: string): void {\n this.stopVoicePreview();\n this.updateField('general', 'ttsVoiceId', voiceId);\n }\n\n protected toggleVoicePreview(): void {\n if (this.voicePreviewPlaying()) {\n this.stopVoicePreview();\n return;\n }\n const voiceId = this.selectedVoiceId();\n if (!voiceId || this.voicePreviewBusy()) return;\n\n this.voicePreviewBusy.set(true);\n this.api.previewVoice(voiceId).subscribe({\n next: (blob) => {\n this.voicePreviewBusy.set(false);\n this.playVoiceBlob(blob);\n },\n error: (err: { message?: string }) => {\n this.voicePreviewBusy.set(false);\n this.toast.show(err.message ?? 'Failed to preview voice.', 'error');\n },\n });\n }\n\n private playVoiceBlob(blob: Blob): void {\n this.stopVoicePreview();\n this.voiceObjectUrl = URL.createObjectURL(blob);\n const audio = new Audio(this.voiceObjectUrl);\n this.voiceAudio = audio;\n this.voicePreviewPlaying.set(true);\n audio.onended = () => this.stopVoicePreview();\n audio.onerror = () => {\n this.stopVoicePreview();\n this.toast.show('Failed to play voice preview.', 'error');\n };\n void audio.play().catch(() => {\n this.stopVoicePreview();\n this.toast.show('Failed to play voice preview.', 'error');\n });\n }\n\n private stopVoicePreview(): void {\n if (this.voiceAudio) {\n this.voiceAudio.pause();\n this.voiceAudio.onended = null;\n this.voiceAudio.onerror = null;\n this.voiceAudio = null;\n }\n if (this.voiceObjectUrl) {\n URL.revokeObjectURL(this.voiceObjectUrl);\n this.voiceObjectUrl = null;\n }\n this.voicePreviewPlaying.set(false);\n }\n\n protected onAgentToggleClick(): void {\n if (this.agentSwitchDisabled()) return;\n if (this.online()) {\n this.confirmOffOpen.set(true);\n return;\n }\n this.applyOnline(true);\n }\n\n protected cancelConfirmOff(): void {\n this.confirmOffOpen.set(false);\n }\n\n protected confirmTurnOff(): void {\n this.confirmOffOpen.set(false);\n this.applyOnline(false);\n }\n\n private applyOnline(enabled: boolean): void {\n this.agentOnline.setOnline(enabled).subscribe({\n next: () => {\n this.toast.show(\n enabled\n ? 'AI receptionist is online — it will answer inbound calls.'\n : 'AI receptionist is offline — calls go to the front desk.',\n 'success',\n );\n },\n error: (err: { message?: string }) => {\n this.toast.show(err.message ?? 'Failed to update agent status.', 'error');\n this.agentOnline.refresh();\n },\n });\n }\n\n protected fieldValue(section: SettingsTab, key: string): string | boolean | number {\n const s = this.settings();\n if (!s) return '';\n return (s[section] as Record<string, string | boolean | number>)[key];\n }\n\n protected save(): void {\n const s = this.settings();\n const orig = this.originalSettings;\n if (!s || !orig) return;\n\n const payload = structuredClone(s);\n payload.general['welcomeMessage'] = String(payload.general['welcomeMessage'] ?? '').trim();\n payload.general['agentName'] = String(payload.general['agentName'] ?? '').trim();\n\n if (!String(payload.general['agentName'] ?? '').trim()) {\n this.tab.set('general');\n this.toast.show('Agent name is required.', 'error');\n return;\n }\n if (!String(payload.general['welcomeMessage'] ?? '').trim()) {\n this.tab.set('general');\n this.toast.show('Inbound greeting is required.', 'error');\n return;\n }\n\n const whatToSay = String(payload.knowledge?.['whatToSay'] ?? '').trim();\n const whatNotToSay = String(payload.knowledge?.['whatNotToSay'] ?? '').trim();\n if (!whatToSay || !whatNotToSay) {\n this.tab.set('knowledge');\n this.toast.show('Knowledge Base requires both “What to say” and “What not to say”.', 'error');\n return;\n }\n payload.knowledge = { whatToSay, whatNotToSay };\n\n // Keep legacy retainDays in sync for older BE consumers.\n const recDays = Number(payload.transcripts['recordingRetainDays'] ?? 30);\n const txDays = Number(payload.transcripts['transcriptRetainDays'] ?? 30);\n payload.transcripts['retainDays'] = Math.max(recDays, txDays);\n\n this.restoreReadOnlyFields(payload, orig);\n\n this.saving.set(true);\n this.api.putSettings(payload).subscribe({\n next: ({ data }) => {\n this.originalSettings = structuredClone(data);\n this.settings.set(structuredClone(data));\n this.saving.set(false);\n this.saved.set(true);\n this.toast.show('Agent settings saved', 'success');\n setTimeout(() => this.saved.set(false), 2000);\n },\n error: (err: unknown) => {\n this.saving.set(false);\n const message =\n err instanceof Error && err.message.trim()\n ? err.message\n : 'Failed to save agent settings';\n this.toast.show(message, 'error');\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 'knowledge',\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","<div class=\"eds-page settings-page\">\n <header class=\"mb-6 flex items-start justify-between gap-4\">\n <div>\n <h1 class=\"eds-h1\">Agent settings</h1>\n <p class=\"mt-2 text-base leading-normal text-zinc-500\">Configure AI receptionist behavior and safety</p>\n </div>\n <div class=\"flex shrink-0 items-center gap-3\">\n @if (saved()) {\n <span class=\"text-sm font-medium text-green-500\">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=\"mt-2 text-base leading-normal text-zinc-500\">Loading settings…</p>\n } @else if (settings()) {\n <div class=\"settings-page__layout grid items-start gap-5\">\n <nav class=\"eds-card settings-page__sidebar sticky top-4 flex max-h-[calc(100vh-120px)] flex-col gap-1 overflow-y-auto p-2 shadow-sm\" aria-label=\"Settings sections\">\n @for (t of tabs; track t.id) {\n <button\n type=\"button\"\n class=\"settings-page__nav-item flex w-full cursor-pointer items-center justify-between gap-3 rounded-md border-none bg-transparent px-4 py-3 text-left text-sm font-medium leading-snug text-zinc-600\"\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 {{ t.label }}\n @if (isTabDisabled(t.id)) {\n <span class=\"ml-auto text-xs font-medium uppercase tracking-wide text-zinc-400\">Disabled</span>\n }\n </button>\n }\n </nav>\n\n <article class=\"eds-card settings-page__panel min-h-96 px-8 py-7 shadow-sm\">\n <header class=\"mb-6 flex items-start justify-between gap-4 border-b border-zinc-200 pb-4\">\n <div class=\"min-w-0\">\n <h2 class=\"mb-2 m-0 text-xl font-medium tracking-tight text-zinc-700\">{{ sectionMeta().title }}</h2>\n @if (tab() !== 'knowledge' && tab() !== 'general' && tab() !== 'phone' && tab() !== 'transcripts') {\n <p class=\"m-0 max-w-2xl text-base leading-relaxed text-zinc-500\">{{ sectionMeta().description }}</p>\n }\n </div>\n @if (tab() === 'knowledge') {\n <eds-button variant=\"secondary\" type=\"button\" (click)=\"openTestCall()\">\n <eds-icon name=\"phone_in_talk\" [size]=\"18\" />\n Test Call\n </eds-button>\n }\n </header>\n\n @if (sectionIsReadOnly(tab())) {\n <p class=\"mb-5 flex items-center gap-3 rounded-md border border-zinc-200 bg-slate-50 px-4 py-3 text-sm leading-snug text-zinc-500\">\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() === 'knowledge') {\n <div class=\"flex max-w-4xl flex-col gap-7\">\n <label class=\"settings-page__field col-span-full flex flex-col gap-2\">\n <span class=\"flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n What to say <span class=\"font-medium text-red-600\">*</span>\n </span>\n <textarea\n class=\"settings-page__textarea min-h-56 w-full resize-y rounded-md border border-zinc-300 px-3 py-3 text-sm leading-relaxed text-zinc-700 font-inherit\"\n rows=\"10\"\n [maxlength]=\"knowledgeMax\"\n [ngModel]=\"whatToSay()\"\n (ngModelChange)=\"updateKnowledgeField('whatToSay', $event)\"\n placeholder=\"Hours, parking, payment options, arrival instructions, emergencies…\"\n autocomplete=\"off\"\n ></textarea>\n <span class=\"text-right text-xs text-zinc-500\">{{ whatToSay().length }}/{{ knowledgeMax }}</span>\n </label>\n\n <label class=\"settings-page__field col-span-full flex flex-col gap-2\">\n <span class=\"flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n What not to say <span class=\"font-medium text-red-600\">*</span>\n </span>\n <textarea\n class=\"settings-page__textarea min-h-56 w-full resize-y rounded-md border border-zinc-300 px-3 py-3 text-sm leading-relaxed text-zinc-700 font-inherit\"\n rows=\"10\"\n [maxlength]=\"knowledgeMax\"\n [ngModel]=\"whatNotToSay()\"\n (ngModelChange)=\"updateKnowledgeField('whatNotToSay', $event)\"\n placeholder=\"Clinical advice, unverified prices, PHI, promises the practice cannot keep…\"\n autocomplete=\"off\"\n ></textarea>\n <span class=\"text-right text-xs text-zinc-500\">{{ whatNotToSay().length }}/{{ knowledgeMax }}</span>\n </label>\n </div>\n } @else if (tab() === 'general') {\n <div class=\"flex max-w-3xl flex-col gap-5\">\n <label class=\"settings-page__field col-span-full flex flex-col gap-2\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n Name <span class=\"font-medium text-red-600\">*</span>\n <eds-icon name=\"info\" [size]=\"16\" class=\"ml-auto text-zinc-400\" title=\"How the AI introduces itself on calls\" />\n </span>\n <input\n type=\"text\"\n class=\"settings-page__input w-full rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\n [ngModel]=\"fieldValue('general', 'agentName')\"\n (ngModelChange)=\"updateField('general', 'agentName', $event)\"\n autocomplete=\"off\"\n />\n </label>\n\n <div class=\"flex items-end gap-3\">\n <label class=\"settings-page__field min-w-0 flex-1 flex flex-col gap-2\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n Voice <span class=\"font-medium text-red-600\">*</span>\n </span>\n <div class=\"relative w-full\">\n <select\n class=\"settings-page__input settings-page__select w-full cursor-pointer appearance-none rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\n [ngModel]=\"fieldValue('general', 'ttsVoiceId')\"\n (ngModelChange)=\"onVoiceChange($event)\"\n autocomplete=\"off\"\n >\n @for (v of voicePresets; track v.id) {\n <option [ngValue]=\"v.id\">{{ v.gender }} · {{ v.label }}</option>\n }\n </select>\n <eds-icon name=\"expand_more\" [size]=\"20\" class=\"pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-zinc-500\" />\n </div>\n </label>\n <button\n type=\"button\"\n class=\"settings-page__voice-play inline-flex h-[50px] w-[50px] shrink-0 cursor-pointer items-center justify-center rounded-md border border-zinc-300 bg-white text-zinc-700 hover:border-blue-500 hover:text-blue-600 disabled:cursor-wait disabled:opacity-60\"\n [disabled]=\"!selectedVoiceId() || voicePreviewBusy()\"\n [attr.aria-label]=\"voicePreviewPlaying() ? 'Stop voice preview' : 'Play voice preview'\"\n [title]=\"voicePreviewPlaying() ? 'Stop preview' : 'Play sample'\"\n (click)=\"toggleVoicePreview()\"\n >\n <eds-icon [name]=\"voicePreviewPlaying() ? 'stop' : 'play_arrow'\" [size]=\"24\" [fill]=\"1\" />\n </button>\n </div>\n\n <div class=\"settings-page__field col-span-full flex flex-col gap-2\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">Tone</span>\n <div class=\"flex flex-wrap gap-2\" role=\"radiogroup\" aria-label=\"Tone\">\n @for (tone of toneOptions; track tone.value) {\n <button\n type=\"button\"\n class=\"settings-page__tone h-9 cursor-pointer rounded-full border border-transparent bg-slate-100 px-4 text-sm font-medium text-zinc-500\"\n [class.settings-page__tone--active]=\"selectedTone() === tone.value\"\n (click)=\"setTone(tone.value)\"\n >\n {{ tone.label }}\n </button>\n }\n </div>\n </div>\n\n <label class=\"settings-page__field col-span-full flex flex-col gap-2\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n Inbound Greetings <span class=\"font-medium text-red-600\">*</span>\n </span>\n <textarea\n class=\"settings-page__textarea min-h-24 w-full resize-y rounded-md border border-zinc-300 px-3 py-3 text-base leading-normal text-zinc-700 font-inherit\"\n rows=\"4\"\n [maxlength]=\"welcomeMax\"\n [placeholder]=\"welcomePlaceholder()\"\n [ngModel]=\"welcomeMessage()\"\n (ngModelChange)=\"updateWelcomeMessage($event)\"\n autocomplete=\"off\"\n ></textarea>\n <span class=\"text-right text-xs text-zinc-500\">{{ welcomeMessage().length }}/{{ welcomeMax }}</span>\n <div class=\"mt-3 flex flex-wrap items-center gap-2\">\n <span class=\"text-sm text-zinc-500\">Variables</span>\n @for (v of greetingVariables; track v.key) {\n <button\n type=\"button\"\n class=\"settings-page__var-chip h-7 cursor-pointer rounded-full border border-zinc-200 bg-white px-3 text-xs font-medium text-zinc-700\"\n (click)=\"insertGreetingVariable(v.token)\"\n [title]=\"'Insert ' + v.token\"\n >\n {{ v.label }}\n </button>\n }\n </div>\n </label>\n </div>\n } @else if (tab() === 'phone') {\n <div class=\"flex max-w-3xl flex-col gap-5\">\n <label class=\"settings-page__field col-span-full flex flex-col gap-2\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n AI Answer Mode <span class=\"font-medium text-red-600\">*</span>\n <eds-icon name=\"info\" [size]=\"16\" class=\"ml-auto text-zinc-400\" title=\"When the AI picks up inbound calls\" />\n </span>\n <select\n class=\"settings-page__input settings-page__select w-full cursor-pointer appearance-none rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\n [ngModel]=\"fieldValue('phone', 'answerMode')\"\n (ngModelChange)=\"updateField('phone', 'answerMode', $event)\"\n autocomplete=\"off\"\n >\n @for (opt of answerModeOptions; track opt.value) {\n <option [ngValue]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n </label>\n\n <label\n class=\"settings-page__field col-span-full flex flex-col gap-2\"\n [class.settings-page__field--readonly]=\"isFieldReadOnly('phone', 'mainNumber')\"\n >\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n AI Phone Number <span class=\"font-medium text-red-600\">*</span>\n @if (isFieldReadOnly('phone', 'mainNumber')) {\n }\n </span>\n <input\n type=\"text\"\n class=\"settings-page__input w-full rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\n [class.settings-page__input--readonly]=\"isFieldReadOnly('phone', 'mainNumber')\"\n [disabled]=\"isFieldReadOnly('phone', 'mainNumber')\"\n [ngModel]=\"fieldValue('phone', 'mainNumber')\"\n (ngModelChange)=\"updateField('phone', 'mainNumber', $event)\"\n autocomplete=\"off\"\n />\n </label>\n\n <label\n class=\"settings-page__field col-span-full flex flex-col gap-2\"\n [class.settings-page__field--readonly]=\"isFieldReadOnly('phone', 'transferNumber')\"\n >\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n Transfer Number <span class=\"font-medium text-red-600\">*</span>\n @if (isFieldReadOnly('phone', 'transferNumber')) {\n }\n </span>\n <input\n type=\"text\"\n class=\"settings-page__input w-full rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\n [class.settings-page__input--readonly]=\"isFieldReadOnly('phone', 'transferNumber')\"\n [disabled]=\"isFieldReadOnly('phone', 'transferNumber')\"\n [ngModel]=\"fieldValue('phone', 'transferNumber')\"\n (ngModelChange)=\"updateField('phone', 'transferNumber', $event)\"\n autocomplete=\"off\"\n />\n </label>\n\n <label class=\"settings-page__field col-span-full flex flex-col gap-2\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n Ringing Time Wait <span class=\"font-medium text-red-600\">*</span>\n </span>\n <select\n class=\"settings-page__input settings-page__select w-full cursor-pointer appearance-none rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\n [ngModel]=\"numberFieldAsString('phone', 'ringTimeout')\"\n (ngModelChange)=\"selectNumberField('phone', 'ringTimeout', $event)\"\n autocomplete=\"off\"\n >\n @for (opt of ringTimeoutOptions; track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n </label>\n\n <div class=\"settings-page__feature-card flex items-center gap-4 rounded-xl border border-zinc-200 bg-white p-4\">\n <eds-icon name=\"event_available\" [size]=\"22\" class=\"shrink-0 text-blue-600\" />\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <span class=\"text-sm font-medium leading-snug text-zinc-700\">Create Follow-up Task</span>\n <span class=\"text-xs leading-snug text-zinc-500\">\n If no one answers in time, the agent auto-creates a high priority task.\n </span>\n </div>\n <button\n type=\"button\"\n class=\"settings-page__switch shrink-0\"\n [class.settings-page__switch--on]=\"!!fieldValue('phone', 'createFollowUpTask')\"\n [attr.aria-pressed]=\"!!fieldValue('phone', 'createFollowUpTask')\"\n (click)=\"updateField('phone', 'createFollowUpTask', !fieldValue('phone', 'createFollowUpTask'))\"\n >\n <span class=\"settings-page__switch-thumb\"></span>\n </button>\n </div>\n\n <div class=\"settings-page__field col-span-full flex flex-col gap-2\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n Location Handled <span class=\"font-medium text-red-600\">*</span>\n </span>\n <div class=\"settings-page__locations-dd relative\" (document:click)=\"onLocationsDocClick($event)\">\n <button\n type=\"button\"\n class=\"settings-page__input settings-page__select flex w-full cursor-pointer items-center justify-between gap-2 rounded-md border border-zinc-300 bg-white px-3 py-2.5 text-left text-base leading-snug text-zinc-700\"\n [disabled]=\"locations().length === 0\"\n [attr.aria-expanded]=\"locationsMenuOpen()\"\n aria-haspopup=\"listbox\"\n aria-label=\"Locations handled\"\n (click)=\"$event.stopPropagation(); toggleLocationsMenu()\"\n >\n <span class=\"min-w-0 truncate\">{{ locationSummary() }}</span>\n <eds-icon name=\"expand_more\" [size]=\"18\" class=\"shrink-0 text-zinc-500\" />\n </button>\n @if (locationsMenuOpen()) {\n <ul\n class=\"absolute z-20 m-0 mt-1 max-h-56 w-full list-none overflow-auto rounded-md border border-zinc-200 bg-white p-1 shadow-md\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n >\n @for (loc of locations(); track loc.id) {\n <li role=\"option\" [attr.aria-selected]=\"selectedLocationIds().includes(loc.id)\">\n <label\n class=\"flex cursor-pointer items-center gap-2.5 rounded px-2.5 py-2 text-sm text-zinc-700 hover:bg-zinc-50\"\n >\n <input\n type=\"checkbox\"\n class=\"h-4 w-4 accent-blue-600\"\n [checked]=\"selectedLocationIds().includes(loc.id)\"\n (change)=\"toggleLocation(loc.id)\"\n />\n <span class=\"min-w-0 truncate\">{{ loc.name }}</span>\n </label>\n </li>\n }\n </ul>\n }\n </div>\n @if (locations().length === 0) {\n <p class=\"m-0 text-sm text-zinc-500\">No locations available.</p>\n }\n </div>\n\n <label class=\"settings-page__field col-span-full flex flex-col gap-2\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n Max AI Call Duration <span class=\"font-medium text-red-600\">*</span>\n </span>\n <select\n class=\"settings-page__input settings-page__select w-full cursor-pointer appearance-none rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\n [ngModel]=\"numberFieldAsString('phone', 'maxCallDurationMin')\"\n (ngModelChange)=\"selectNumberField('phone', 'maxCallDurationMin', $event)\"\n autocomplete=\"off\"\n >\n @for (opt of maxCallDurationOptions; track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n </label>\n\n <label class=\"settings-page__field col-span-full flex flex-col gap-2\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n Silence Timeout <span class=\"font-medium text-red-600\">*</span>\n </span>\n <select\n class=\"settings-page__input settings-page__select w-full cursor-pointer appearance-none rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\n [ngModel]=\"numberFieldAsString('phone', 'silenceTimeoutSec')\"\n (ngModelChange)=\"selectNumberField('phone', 'silenceTimeoutSec', $event)\"\n autocomplete=\"off\"\n >\n @for (opt of silenceTimeoutOptions; track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n </label>\n\n <label class=\"settings-page__field col-span-full flex flex-col gap-2\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n After-Hours Behaviour <span class=\"font-medium text-red-600\">*</span>\n </span>\n <select\n class=\"settings-page__input settings-page__select w-full cursor-pointer appearance-none rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\n [ngModel]=\"fieldValue('phone', 'afterHoursBehavior')\"\n (ngModelChange)=\"updateField('phone', 'afterHoursBehavior', $event)\"\n autocomplete=\"off\"\n >\n @for (opt of afterHoursOptions; track opt.value) {\n <option [ngValue]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n </label>\n\n <div class=\"border-t border-zinc-200 pt-5\">\n <div class=\"flex flex-col gap-5\">\n <label class=\"settings-page__field col-span-full flex flex-col gap-1.5\">\n <span class=\"settings-page__field-label flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n Minimum lead time (hours)\n </span>\n <input\n type=\"number\"\n min=\"0\"\n class=\"settings-page__input w-full rounded-md border border-zinc-300 bg-white px-3 py-2.5 text-base leading-snug text-zinc-700\"\n [ngModel]=\"fieldValue('scheduling', 'leadTimeHours')\"\n (ngModelChange)=\"updateField('scheduling', 'leadTimeHours', +$event)\"\n autocomplete=\"off\"\n />\n <span class=\"text-xs text-zinc-500\">Earliest bookable slot from now.</span>\n </label>\n\n <div class=\"settings-page__feature-card flex items-center gap-3.5 rounded-xl border border-zinc-200 bg-white p-3.5\">\n <eds-icon name=\"today\" [size]=\"22\" class=\"shrink-0 text-blue-600\" />\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <span class=\"text-sm font-medium leading-snug text-zinc-700\">Allow same-day booking</span>\n <span class=\"text-xs leading-snug text-zinc-500\">\n Let patients book appointments later today.\n </span>\n </div>\n <button\n type=\"button\"\n class=\"settings-page__switch shrink-0\"\n [class.settings-page__switch--on]=\"!!fieldValue('scheduling', 'allowSameDay')\"\n [attr.aria-pressed]=\"!!fieldValue('scheduling', 'allowSameDay')\"\n (click)=\"updateField('scheduling', 'allowSameDay', !fieldValue('scheduling', 'allowSameDay'))\"\n >\n <span class=\"settings-page__switch-thumb\"></span>\n </button>\n </div>\n </div>\n </div>\n </div>\n } @else if (tab() === 'transcripts') {\n <div class=\"flex max-w-3xl flex-col gap-5\">\n <label class=\"settings-page__field col-span-full flex flex-col gap-2\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n Keep Call Recordings <span class=\"font-medium text-red-600\">*</span>\n </span>\n <select\n class=\"settings-page__input settings-page__select w-full cursor-pointer appearance-none rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\n [ngModel]=\"numberFieldAsString('transcripts', 'recordingRetainDays')\"\n (ngModelChange)=\"selectNumberField('transcripts', 'recordingRetainDays', $event)\"\n autocomplete=\"off\"\n >\n @for (opt of retentionOptions; track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n </label>\n\n <label class=\"settings-page__field col-span-full flex flex-col gap-2\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n Keep Transcripts <span class=\"font-medium text-red-600\">*</span>\n </span>\n <select\n class=\"settings-page__input settings-page__select w-full cursor-pointer appearance-none rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\n [ngModel]=\"numberFieldAsString('transcripts', 'transcriptRetainDays')\"\n (ngModelChange)=\"selectNumberField('transcripts', 'transcriptRetainDays', $event)\"\n autocomplete=\"off\"\n >\n @for (opt of retentionOptions; track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n </label>\n\n <div class=\"flex flex-col gap-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">Disclosure Warning</span>\n <button\n type=\"button\"\n class=\"settings-page__switch shrink-0\"\n [class.settings-page__switch--on]=\"disclosureEnabled()\"\n [attr.aria-pressed]=\"disclosureEnabled()\"\n (click)=\"setDisclosureEnabled(!disclosureEnabled())\"\n >\n <span class=\"settings-page__switch-thumb\"></span>\n </button>\n </div>\n @if (disclosureEnabled()) {\n <textarea\n class=\"settings-page__textarea min-h-24 w-full resize-y rounded-md border border-zinc-300 px-3 py-3 text-base leading-normal text-zinc-700 font-inherit\"\n rows=\"4\"\n [maxlength]=\"disclosureMax\"\n [ngModel]=\"disclosureText()\"\n (ngModelChange)=\"updateDisclosureText($event)\"\n autocomplete=\"off\"\n ></textarea>\n }\n </div>\n </div>\n } @else if (tab() === 'advanced') {\n <div class=\"flex max-w-3xl flex-col gap-5\">\n <div class=\"settings-page__feature-card flex items-center gap-4 rounded-xl border border-zinc-200 bg-white p-4\">\n <span class=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-[10px] bg-violet-500/15 text-[var(--eds-violet-500,#8b5cf6)]\" aria-hidden=\"true\">\n <eds-icon name=\"auto_awesome\" [size]=\"20\" [fill]=\"1\" />\n </span>\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <span class=\"text-sm font-medium leading-snug text-zinc-700\">\n @if (toggling()) {\n Updating…\n } @else if (online() === true) {\n Agent online\n } @else if (online() === false) {\n Agent offline\n } @else {\n Status unknown\n }\n </span>\n <span class=\"text-xs leading-snug text-zinc-500\">\n @if (online() === true) {\n AI receptionist is answering inbound calls.\n } @else if (online() === false) {\n AI is offline — calls go to the front desk.\n } @else {\n Checking agent status…\n }\n </span>\n </div>\n <button\n type=\"button\"\n class=\"settings-page__switch shrink-0\"\n [class.settings-page__switch--on]=\"online() === true\"\n [disabled]=\"agentSwitchDisabled()\"\n [attr.aria-pressed]=\"online() === true\"\n (click)=\"onAgentToggleClick()\"\n >\n <span class=\"settings-page__switch-thumb\"></span>\n </button>\n </div>\n\n <label class=\"settings-page__field col-span-full flex flex-col gap-2 settings-page__field--readonly\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n Model version\n </span>\n <input\n type=\"text\"\n class=\"settings-page__input settings-page__input--readonly w-full rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\n [ngModel]=\"fieldValue('advanced', 'modelVersion')\"\n disabled\n autocomplete=\"off\"\n />\n </label>\n\n <label class=\"settings-page__toggle-row settings-page__toggle-row--readonly col-span-full flex cursor-pointer items-center justify-between gap-4 rounded-md border border-zinc-200 bg-slate-50 px-4 py-4\">\n <div class=\"flex min-w-0 flex-col gap-1\">\n <span class=\"flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n Debug mode\n </span>\n <span class=\"settings-page__field-desc mb-1 text-sm leading-snug text-zinc-500\">Verbose logging — contact Edvak to change.</span>\n </div>\n <input\n type=\"checkbox\"\n class=\"settings-page__checkbox h-[18px] w-[18px] shrink-0 accent-blue-600\"\n [ngModel]=\"fieldValue('advanced', 'debugMode')\"\n disabled\n autocomplete=\"off\"\n />\n </label>\n\n </div>\n } @else {\n <div class=\"settings-page__fields grid grid-cols-2 gap-x-7 gap-y-5\">\n @for (field of fieldsForTab(); track field.key) {\n @if (field.type === 'boolean') {\n <label\n class=\"settings-page__toggle-row col-span-full flex cursor-pointer items-center justify-between gap-4 rounded-md border border-zinc-200 bg-slate-50 px-4 py-4\"\n [class.settings-page__toggle-row--readonly]=\"fieldIsReadOnly(tab(), field.key)\"\n >\n <div class=\"flex min-w-0 flex-col gap-1\">\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n {{ field.label }}\n </span>\n @if (field.description) {\n <span class=\"settings-page__field-desc mb-1 text-sm leading-snug text-zinc-500\">{{ field.description }}</span>\n }\n </div>\n <input\n type=\"checkbox\"\n class=\"settings-page__checkbox h-[18px] w-[18px] shrink-0 accent-blue-600\"\n [disabled]=\"fieldIsReadOnly(tab(), field.key)\"\n [ngModel]=\"fieldValue(tab(), field.key)\"\n (ngModelChange)=\"updateField(tab(), field.key, $event)\"\n autocomplete=\"off\"\n />\n </label>\n } @else {\n <label\n class=\"settings-page__field flex flex-col gap-2\"\n [class.settings-page__field--readonly]=\"fieldIsReadOnly(tab(), field.key)\"\n >\n <span class=\" flex flex-wrap items-center gap-2 text-sm font-medium leading-snug text-zinc-700\">\n {{ field.label }}\n </span>\n @if (field.description) {\n <span class=\"settings-page__field-desc mb-1 text-sm leading-snug text-zinc-500\">{{ field.description }}</span>\n }\n @if (field.type === 'number') {\n <input\n type=\"number\"\n class=\"settings-page__input w-full rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\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 autocomplete=\"off\"\n />\n } @else if (field.type === 'select' && field.options?.length) {\n <select\n class=\"settings-page__input settings-page__select w-full cursor-pointer appearance-none rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\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 autocomplete=\"off\"\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 w-full rounded-md border border-zinc-300 bg-white px-3 py-3 text-base leading-snug text-zinc-700\"\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 autocomplete=\"off\"\n />\n }\n </label>\n }\n }\n </div>\n }\n </article>\n </div>\n }\n</div>\n\n<eds-knowledge-test-modal\n [open]=\"knowledgeTestOpen()\"\n [whatToSay]=\"whatToSay()\"\n [whatNotToSay]=\"whatNotToSay()\"\n [voiceId]=\"selectedVoiceId()\"\n (closed)=\"closeTestCall()\"\n/>\n\n@if (confirmOffOpen()) {\n <app-modal\n title=\"Turn off AI receptionist?\"\n subtitle=\"Inbound callers will be transferred to the front desk instead of the AI.\"\n maxWidth=\"480px\"\n (closed)=\"cancelConfirmOff()\"\n >\n <p class=\"mb-4 m-0 text-sm leading-normal text-zinc-500\">While offline, the AI will not answer calls. Callers are routed to the human receptionist.</p>\n <div class=\"flex justify-end gap-2\">\n <eds-button variant=\"secondary\" type=\"button\" (click)=\"cancelConfirmOff()\">Cancel</eds-button>\n <eds-button variant=\"danger\" type=\"button\" [disabled]=\"toggling()\" (click)=\"confirmTurnOff()\">\n Turn off\n </eds-button>\n </div>\n </app-modal>\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { DatePipe } from '@angular/common';
|
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { inject, signal, Input, ChangeDetectionStrategy, Component, input, output } from '@angular/core';
|
|
4
4
|
import { RouterLink } from '@angular/router';
|
|
5
|
-
import { ToastService, EdsBadgeComponent, EdsButtonComponent, EdsIconComponent } from './edvak99-voice-receptionist-widget.mjs';
|
|
5
|
+
import { T as ToastService, l as EdsBadgeComponent, E as EdsButtonComponent, d as EdsIconComponent } from './edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-pS2jeB4x.mjs';
|
|
6
6
|
|
|
7
7
|
class CopyButtonComponent {
|
|
8
8
|
constructor() {
|
|
@@ -191,4 +191,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
191
191
|
}] });
|
|
192
192
|
|
|
193
193
|
export { TaskDetailDrawerComponent as T, TASK_TYPE_OPTIONS as a, taskStatusTone as b, taskPriorityTone as c, taskSourceLabel as d, taskTypeTone as e, taskCallRoute as f, taskStatusLabel as t };
|
|
194
|
-
//# sourceMappingURL=edvak99-voice-receptionist-widget-task-detail-drawer.component-
|
|
194
|
+
//# sourceMappingURL=edvak99-voice-receptionist-widget-task-detail-drawer.component-BojdiNNx.mjs.map
|
package/fesm2022/edvak99-voice-receptionist-widget-task-detail-drawer.component-BojdiNNx.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edvak99-voice-receptionist-widget-task-detail-drawer.component-BojdiNNx.mjs","sources":["../../../src/lib/shared/copy-button.component.ts","../../../src/lib/utils/task.util.ts","../../../src/lib/components/task-detail-drawer/task-detail-drawer.component.ts","../../../src/lib/components/task-detail-drawer/task-detail-drawer.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 inline-flex shrink-0 items-center justify-center p-0\"\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 { 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","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 assigneeInitials(): string {\n const name = this.task().assignee?.trim();\n if (!name || name === '—') return '?';\n const parts = name.split(/\\s+/).filter(Boolean);\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();\n return `${parts[0][0] ?? ''}${parts[parts.length - 1][0] ?? ''}`.toUpperCase();\n }\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=\"fixed inset-0 z-[200] flex justify-end bg-[rgba(15,23,42,0.4)]\" (click)=\"onBackdropClick($event)\">\n <aside\n class=\"task-drawer flex h-full w-[min(520px,100%)] flex-col bg-[#f7f8fa] shadow-[-8px_0_32px_rgba(15,23,42,0.12)]\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"task().title\"\n >\n <header class=\"flex items-center gap-3 border-b border-zinc-200 bg-white px-4 py-3\">\n <eds-button\n variant=\"primary\"\n type=\"button\"\n class=\"mr-auto\"\n (click)=\"markDone()\"\n >\n <eds-icon name=\"check\" [size]=\"18\" />\n {{ task().status === 'done' ? 'Reopen task' : 'Mark as completed' }}\n </eds-button>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-9 cursor-pointer items-center justify-center rounded-md border-none bg-transparent text-zinc-500 hover:bg-zinc-100 hover:text-zinc-800\"\n (click)=\"close()\"\n aria-label=\"Close\"\n >\n <eds-icon name=\"close\" [size]=\"22\" />\n </button>\n </header>\n\n <div class=\"flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-4\">\n <section class=\"rounded-xl border border-zinc-200 bg-white p-4\">\n <h2 class=\"m-0 text-xl font-semibold leading-snug text-zinc-900\">{{ task().title }}</h2>\n\n <div class=\"mt-4\">\n <h3 class=\"m-0 text-sm font-semibold text-zinc-800\">Description</h3>\n <p class=\"mt-2 mb-0 whitespace-pre-wrap text-sm leading-relaxed text-zinc-600\">\n {{ task().description || '—' }}\n </p>\n </div>\n\n <div class=\"mt-5 flex flex-wrap items-center gap-x-5 gap-y-3 border-t border-zinc-100 pt-4 text-sm\">\n <div class=\"inline-flex items-center gap-2 font-medium\" [class.text-red-600]=\"task().priority === 'urgent'\" [class.text-zinc-700]=\"task().priority !== 'urgent'\">\n <span\n class=\"h-2.5 w-2.5 shrink-0 rotate-45 rounded-sm\"\n [class.bg-red-600]=\"task().priority === 'urgent'\"\n [class.bg-amber-500]=\"task().priority !== 'urgent'\"\n aria-hidden=\"true\"\n ></span>\n {{ task().priority === 'urgent' ? 'High Priority' : taskPriorityLabel(task().priority) }}\n </div>\n\n <div class=\"inline-flex items-center gap-2 text-zinc-700\">\n <span class=\"inline-flex h-7 w-7 items-center justify-center rounded-full bg-teal-100 text-[11px] font-bold text-teal-800\">\n {{ assigneeInitials() }}\n </span>\n <span class=\"text-zinc-500\">{{ task().assignee || 'Unassigned' }}</span>\n </div>\n\n <div class=\"inline-flex items-center gap-1.5 text-zinc-500\">\n <eds-icon name=\"schedule\" [size]=\"16\" />\n Created: {{ task().created | date: 'MM-dd-yyyy' }}\n </div>\n </div>\n </section>\n\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Patient</span>\n <span class=\"text-sm text-zinc-600\">{{ task().patient || '—' }}</span>\n </div>\n </section>\n\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Status</span>\n <eds-badge [tone]=\"taskStatusTone(task().status)\">{{ taskStatusLabel(task().status) }}</eds-badge>\n </div>\n </section>\n\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Source</span>\n <span class=\"text-sm text-zinc-600\">{{ taskSourceLabel(task().source) }}</span>\n </div>\n </section>\n\n @if (task().callId) {\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Call</span>\n <a\n [routerLink]=\"taskCallRoute(task().callId!)\"\n class=\"text-sm font-medium text-blue-600 no-underline hover:underline\"\n >\n {{ task().callId }}\n </a>\n </div>\n </section>\n }\n\n @if (task().edvakTaskId || task().edvakStatus || task().medicationName || task().medicationId) {\n <section class=\"rounded-xl border border-zinc-200 bg-white p-4\">\n <h3 class=\"m-0 mb-3 text-sm font-semibold text-zinc-800\">Edvak / refill details</h3>\n <dl class=\"m-0 grid grid-cols-2 gap-4\">\n @if (task().edvakTaskId) {\n <div>\n <dt class=\"eds-label mb-1\">Edvak task ID</dt>\n <dd class=\"inline-flex items-center gap-2 text-sm\">\n <code class=\"rounded bg-zinc-100 px-2 py-1 font-mono text-xs\">{{ 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 mb-1\">Edvak status</dt>\n <dd class=\"m-0 text-sm\"><eds-badge tone=\"brand\">{{ task().edvakStatus }}</eds-badge></dd>\n </div>\n }\n @if (task().medicationName) {\n <div>\n <dt class=\"eds-label mb-1\">Medication</dt>\n <dd class=\"m-0 text-sm text-zinc-700\">{{ task().medicationName }}</dd>\n </div>\n }\n @if (task().medicationId) {\n <div>\n <dt class=\"eds-label mb-1\">Medication ID</dt>\n <dd class=\"inline-flex items-center gap-2 text-sm\">\n <code class=\"rounded bg-zinc-100 px-2 py-1 font-mono text-xs\">{{ 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 </aside>\n</div>\n"],"names":[],"mappings":"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"}
|
|
@@ -2,9 +2,8 @@ import { DatePipe } from '@angular/common';
|
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { inject, signal, computed, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
4
|
import { ActivatedRoute, RouterLink } from '@angular/router';
|
|
5
|
-
import { a as TASK_TYPE_OPTIONS, t as taskStatusLabel, b as taskStatusTone, c as taskPriorityTone, d as taskSourceLabel, e as taskTypeTone, f as taskCallRoute, T as TaskDetailDrawerComponent } from './edvak99-voice-receptionist-widget-task-detail-drawer.component-
|
|
6
|
-
import { A as AiReceptionistApiService,
|
|
7
|
-
import { EdsBadgeComponent, EdsButtonComponent } from './edvak99-voice-receptionist-widget.mjs';
|
|
5
|
+
import { a as TASK_TYPE_OPTIONS, t as taskStatusLabel, b as taskStatusTone, c as taskPriorityTone, d as taskSourceLabel, e as taskTypeTone, f as taskCallRoute, T as TaskDetailDrawerComponent } from './edvak99-voice-receptionist-widget-task-detail-drawer.component-BojdiNNx.mjs';
|
|
6
|
+
import { A as AiReceptionistApiService, j as DEFAULT_PAGE_SIZE, k as totalPages, l as EdsBadgeComponent, E as EdsButtonComponent } from './edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-pS2jeB4x.mjs';
|
|
8
7
|
|
|
9
8
|
class TasksPageComponent {
|
|
10
9
|
constructor() {
|
|
@@ -144,4 +143,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
144
143
|
}] });
|
|
145
144
|
|
|
146
145
|
export { TasksPageComponent };
|
|
147
|
-
//# sourceMappingURL=edvak99-voice-receptionist-widget-tasks-page.component-
|
|
146
|
+
//# sourceMappingURL=edvak99-voice-receptionist-widget-tasks-page.component-Cf76XyCz.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edvak99-voice-receptionist-widget-tasks-page.component-Cf76XyCz.mjs","sources":["../../../src/lib/pages/tasks-page/tasks-page.component.ts","../../../src/lib/pages/tasks-page/tasks-page.component.html"],"sourcesContent":["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 { DEFAULT_PAGE_SIZE, totalPages as calcTotalPages } from '../../models/pagination';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { EdsBadgeComponent } from '../../ui/eds-badge.component';\nimport { EdsButtonComponent } from '../../ui/eds-button.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 EdsButtonComponent,\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 pageSize = DEFAULT_PAGE_SIZE;\n protected readonly tasks = signal<TaskItem[]>([]);\n protected readonly total = signal(0);\n protected readonly page = signal(1);\n protected readonly loading = signal(true);\n protected readonly selectedTask = signal<TaskItem | null>(null);\n\n /** Default to Open so staff see actionable work; Done tab for completed. */\n protected readonly statusFilter = signal<'' | TaskStatus>('open');\n protected readonly typeFilter = signal('');\n protected readonly sourceFilter = signal<'' | TaskSource>('');\n protected readonly callIdFilter = signal('');\n\n protected readonly statusTabs: { id: '' | TaskStatus; label: string }[] = [\n { id: 'open', label: 'Open' },\n { id: 'in_progress', label: 'In progress' },\n { id: 'done', label: 'Done' },\n { id: '', label: 'All' },\n ];\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.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.page.set(1);\n this.load();\n }\n\n protected setTypeFilter(value: string): void {\n this.typeFilter.set(value);\n this.page.set(1);\n this.load();\n }\n\n protected setSourceFilter(value: string): void {\n this.sourceFilter.set(value as '' | TaskSource);\n this.page.set(1);\n this.load();\n }\n\n protected setCallIdFilter(value: string): void {\n this.callIdFilter.set(value);\n this.page.set(1);\n this.load();\n }\n\n protected clearFilters(): void {\n this.statusFilter.set('open');\n this.typeFilter.set('');\n this.sourceFilter.set('');\n this.callIdFilter.set('');\n this.page.set(1);\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 // Refresh list so Open/Done tabs stay accurate after status change.\n this.load();\n }\n });\n }\n\n protected totalPages(): number {\n return calcTotalPages(this.total(), DEFAULT_PAGE_SIZE);\n }\n\n protected prevPage(): void {\n if (this.page() <= 1) return;\n this.page.update((p) => p - 1);\n this.load();\n }\n\n protected nextPage(): void {\n if (this.page() >= this.totalPages()) return;\n this.page.update((p) => p + 1);\n this.load();\n }\n\n private load(): void {\n this.loading.set(true);\n const filters: TaskFilters = {\n page: this.page(),\n limit: DEFAULT_PAGE_SIZE,\n };\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: ({ items, total, page }) => {\n this.tasks.set(items);\n this.total.set(total);\n this.page.set(page);\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=\"mb-5 flex items-start justify-between gap-4\">\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 <nav class=\"mb-4 flex flex-wrap gap-2\" aria-label=\"Task status\">\n @for (tab of statusTabs; track tab.id) {\n <button\n type=\"button\"\n [class]=\"\n statusFilter() === tab.id\n ? 'cursor-pointer rounded-full border-none bg-blue-50 px-4 py-2 text-sm font-medium text-blue-600 transition-colors'\n : 'cursor-pointer rounded-full border-none bg-transparent px-4 py-2 text-sm font-medium text-zinc-500 transition-colors hover:bg-white hover:text-zinc-700'\n \"\n (click)=\"setStatusFilter(tab.id)\"\n >\n {{ tab.label }}\n </button>\n }\n </nav>\n\n <section class=\"eds-card overflow-hidden shadow-sm\">\n <div class=\"flex flex-wrap items-end gap-4 border-b border-zinc-200 px-6 py-4 max-[920px]:px-4 max-[920px]:py-4\">\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-xs font-medium text-zinc-500\" for=\"task-type\">Type</label>\n <select\n id=\"task-type\"\n class=\"min-w-36 rounded-md border border-zinc-200 bg-white px-3 py-2 text-sm\"\n [value]=\"typeFilter()\"\n (change)=\"setTypeFilter($any($event.target).value)\" autocomplete=\"off\">\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=\"flex flex-col gap-1\">\n <label class=\"text-xs font-medium text-zinc-500\" for=\"task-source\">Source</label>\n <select\n id=\"task-source\"\n class=\"min-w-36 rounded-md border border-zinc-200 bg-white px-3 py-2 text-sm\"\n [value]=\"sourceFilter()\"\n (change)=\"setSourceFilter($any($event.target).value)\" autocomplete=\"off\">\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=\"flex flex-col gap-1\">\n <label class=\"text-xs font-medium text-zinc-500\" for=\"task-call\">Call ID</label>\n <input\n id=\"task-call\"\n type=\"text\"\n class=\"min-w-36 rounded-md border border-zinc-200 bg-white px-3 py-2 text-sm\"\n [value]=\"callIdFilter()\"\n placeholder=\"Filter by call\"\n (change)=\"setCallIdFilter($any($event.target).value)\" autocomplete=\"off\" />\n </div>\n @if (hasActiveFilters()) {\n <button\n type=\"button\"\n class=\"cursor-pointer border-none bg-transparent p-0 text-sm font-medium text-blue-600 hover:underline\"\n (click)=\"clearFilters()\"\n >\n Clear filters\n </button>\n }\n </div>\n\n @if (loading()) {\n <p class=\"eds-body-sm m-0 p-6\">Loading tasks…</p>\n } @else {\n <div class=\"overflow-x-auto\">\n <table class=\"w-full min-w-3xl border-collapse\">\n <thead>\n <tr>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-5 py-3 text-left text-sm font-semibold text-zinc-600\">Created</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-5 py-3 text-left text-sm font-semibold text-zinc-600\">Title</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-5 py-3 text-left text-sm font-semibold text-zinc-600\">Type</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-5 py-3 text-left text-sm font-semibold text-zinc-600\">Patient</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-5 py-3 text-left text-sm font-semibold text-zinc-600\">Priority</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-5 py-3 text-left text-sm font-semibold text-zinc-600\">Status</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-5 py-3 text-left text-sm font-semibold text-zinc-600\">Source</th>\n <th class=\"whitespace-nowrap border-b border-zinc-200 bg-zinc-100 px-5 py-3 text-left text-sm font-semibold text-zinc-600\">Call</th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-zinc-200\">\n @for (task of tasks(); track task.id) {\n <tr class=\"cursor-pointer transition-colors hover:bg-zinc-50\" (click)=\"openTask(task)\">\n <td class=\"px-5 py-4 align-middle text-sm text-zinc-500\">{{ task.created | date: 'MM/dd/yy, h:mm a' }}</td>\n <td class=\"max-w-72 px-5 py-4 align-middle text-sm font-medium text-zinc-900\">{{ task.title }}</td>\n <td class=\"px-5 py-4 align-middle text-sm text-zinc-900\"><eds-badge [tone]=\"taskTypeTone(task.type)\">{{ task.type }}</eds-badge></td>\n <td class=\"px-5 py-4 align-middle text-sm text-zinc-900\">{{ task.patient }}</td>\n <td class=\"px-5 py-4 align-middle text-sm text-zinc-900\">\n <eds-badge [tone]=\"taskPriorityTone(task.priority)\">\n {{ task.priority === 'urgent' ? 'Urgent' : 'Normal' }}\n </eds-badge>\n </td>\n <td class=\"px-5 py-4 align-middle text-sm text-zinc-900\"><eds-badge [tone]=\"taskStatusTone(task.status)\">{{ taskStatusLabel(task.status) }}</eds-badge></td>\n <td class=\"px-5 py-4 align-middle text-sm text-zinc-500\">{{ taskSourceLabel(task.source) }}</td>\n <td class=\"px-5 py-4 align-middle text-sm text-zinc-900\" (click)=\"$event.stopPropagation()\">\n @if (task.callId) {\n <a\n [routerLink]=\"taskCallRoute(task.callId)\"\n class=\"text-sm font-medium text-blue-600 no-underline hover:underline\"\n >{{ task.callId }}</a>\n } @else {\n <span class=\"text-zinc-500\">—</span>\n }\n </td>\n </tr>\n } @empty {\n <tr>\n <td colspan=\"8\" class=\"px-5 py-12 text-center text-sm text-zinc-400\">No tasks match these filters.</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n <footer class=\"flex items-center justify-between border-t border-zinc-200 px-6 py-4 text-sm text-zinc-500\">\n <span>Page {{ page() }} of {{ totalPages() }} · {{ total() }} total</span>\n <div class=\"flex gap-2\">\n <eds-button variant=\"secondary\" [disabled]=\"page() <= 1\" (click)=\"prevPage()\">Previous</eds-button>\n <eds-button variant=\"secondary\" [disabled]=\"page() >= totalPages()\" (click)=\"nextPage()\">Next</eds-button>\n </div>\n </footer>\n </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}\n"],"names":["calcTotalPages"],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { inject, signal, computed, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
-
import { A as AiReceptionistApiService } from './edvak99-voice-receptionist-widget-
|
|
4
|
-
import { EdsBadgeComponent, EdsButtonComponent, EdsIconComponent } from './edvak99-voice-receptionist-widget.mjs';
|
|
3
|
+
import { A as AiReceptionistApiService, l as EdsBadgeComponent, E as EdsButtonComponent, d as EdsIconComponent } from './edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-pS2jeB4x.mjs';
|
|
5
4
|
|
|
6
5
|
class WizardPageComponent {
|
|
7
6
|
constructor() {
|
|
@@ -43,4 +42,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
43
42
|
}] });
|
|
44
43
|
|
|
45
44
|
export { WizardPageComponent };
|
|
46
|
-
//# sourceMappingURL=edvak99-voice-receptionist-widget-wizard-page.component-
|
|
45
|
+
//# sourceMappingURL=edvak99-voice-receptionist-widget-wizard-page.component-BQTlz2F5.mjs.map
|