@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
|
@@ -1,8 +1,227 @@
|
|
|
1
|
-
import { HttpClient, HttpParams } from '@angular/common/http';
|
|
2
1
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { signal, Injectable,
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { InjectionToken, makeEnvironmentProviders, inject, signal, Injectable, ChangeDetectionStrategy, Component, input, computed, DestroyRef } from '@angular/core';
|
|
3
|
+
import { Router, RouterLink, RouterLinkActive, NavigationStart, NavigationEnd, NavigationCancel, NavigationError, RouterOutlet } from '@angular/router';
|
|
4
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
|
+
import { filter } from 'rxjs/operators';
|
|
6
|
+
import { of, delay, throwError, map, catchError, forkJoin, switchMap, interval, filter as filter$1 } from 'rxjs';
|
|
7
|
+
import { HttpClient, HttpParams } from '@angular/common/http';
|
|
8
|
+
import { io } from 'socket.io-client';
|
|
9
|
+
|
|
10
|
+
const VOICE_RECEPTIONIST_CONFIG = new InjectionToken('VOICE_RECEPTIONIST_CONFIG');
|
|
11
|
+
const VOICE_RECEPTIONIST_SESSION = new InjectionToken('VOICE_RECEPTIONIST_SESSION', { factory: () => null });
|
|
12
|
+
|
|
13
|
+
function provideVoiceReceptionist(options) {
|
|
14
|
+
const { session, ...config } = options;
|
|
15
|
+
const providers = [
|
|
16
|
+
{ provide: VOICE_RECEPTIONIST_CONFIG, useValue: config },
|
|
17
|
+
];
|
|
18
|
+
// Only set SESSION when the host passes one — otherwise leave the token
|
|
19
|
+
// unset so a separate host factory (or the token default) can provide it.
|
|
20
|
+
if (session !== undefined) {
|
|
21
|
+
providers.push({ provide: VOICE_RECEPTIONIST_SESSION, useValue: session });
|
|
22
|
+
}
|
|
23
|
+
return makeEnvironmentProviders(providers);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* API Logs is standalone-dashboard only.
|
|
28
|
+
* EHR embeds leave `showModuleNav` unset/false — redirect to dashboard.
|
|
29
|
+
*/
|
|
30
|
+
const apiLogsStandaloneGuard = () => {
|
|
31
|
+
const config = inject(VOICE_RECEPTIONIST_CONFIG);
|
|
32
|
+
const router = inject(Router);
|
|
33
|
+
if (config.showModuleNav)
|
|
34
|
+
return true;
|
|
35
|
+
const url = router.url.split('?')[0];
|
|
36
|
+
const base = url.replace(/\/api-logs(?:\/.*)?$/, '') || '';
|
|
37
|
+
const target = `${base.replace(/\/$/, '')}/dashboard` || '/dashboard';
|
|
38
|
+
return router.parseUrl(target);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
class ToastService {
|
|
42
|
+
constructor() {
|
|
43
|
+
this.nextId = 1;
|
|
44
|
+
this.timers = new Map();
|
|
45
|
+
this._toasts = signal([]);
|
|
46
|
+
this.toasts = this._toasts.asReadonly();
|
|
47
|
+
}
|
|
48
|
+
show(text, variant = 'info', durationMs = 3500) {
|
|
49
|
+
const id = this.nextId++;
|
|
50
|
+
this._toasts.update((list) => [...list, { id, text, variant }]);
|
|
51
|
+
const timer = setTimeout(() => this.dismiss(id), durationMs);
|
|
52
|
+
this.timers.set(id, timer);
|
|
53
|
+
}
|
|
54
|
+
dismiss(id) {
|
|
55
|
+
const timer = this.timers.get(id);
|
|
56
|
+
if (timer) {
|
|
57
|
+
clearTimeout(timer);
|
|
58
|
+
this.timers.delete(id);
|
|
59
|
+
}
|
|
60
|
+
this._toasts.update((list) => list.filter((t) => t.id !== id));
|
|
61
|
+
}
|
|
62
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
63
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ToastService, providedIn: 'root' }); }
|
|
64
|
+
}
|
|
65
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ToastService, decorators: [{
|
|
66
|
+
type: Injectable,
|
|
67
|
+
args: [{ providedIn: 'root' }]
|
|
68
|
+
}] });
|
|
69
|
+
|
|
70
|
+
class ToastContainerComponent {
|
|
71
|
+
constructor() {
|
|
72
|
+
this.toastService = inject(ToastService);
|
|
73
|
+
}
|
|
74
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ToastContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
75
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: ToastContainerComponent, isStandalone: true, selector: "app-toast-container", ngImport: i0, template: "<div class=\"fixed bottom-6 right-6 z-[1100] flex max-w-[380px] flex-col gap-3 pointer-events-none\" aria-live=\"polite\" aria-atomic=\"false\">\n @for (toast of toastService.toasts(); track toast.id) {\n <div\n class=\"toast pointer-events-auto flex items-start gap-3 rounded-[var(--eds-radius-md)] border border-[var(--eds-color-border)] bg-[var(--eds-color-surface)] px-4 py-3 text-[13px] text-[var(--eds-color-text)] shadow-[0_6px_24px_rgba(20,30,50,0.12)]\"\n role=\"status\"\n >\n <span\n class=\"inline-flex h-[22px] w-[22px] shrink-0 items-center justify-center rounded-full\"\n [class]=\"toast.variant === 'success' ? 'bg-[var(--eds-color-success-soft)] text-[var(--eds-color-success)]' : toast.variant === 'error' ? 'bg-[var(--eds-color-danger-soft)] text-[var(--eds-color-danger)]' : 'bg-[var(--eds-color-primary-soft)] text-[var(--eds-color-primary)]'\"\n aria-hidden=\"true\"\n >\n @switch (toast.variant) {\n @case ('success') {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n }\n @case ('error') {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>\n }\n @default {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>\n }\n }\n </span>\n <span class=\"flex-1 leading-snug\">{{ toast.text }}</span>\n <button\n type=\"button\"\n class=\"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-none bg-transparent text-[var(--eds-color-text-soft)] transition-colors duration-150 hover:bg-[var(--eds-color-surface-alt)] hover:text-[var(--eds-color-text)]\"\n (click)=\"toastService.dismiss(toast.id)\"\n aria-label=\"Dismiss notification\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n }\n</div>\n", styles: [".toast{animation:slide-in .16s ease}@keyframes slide-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76
|
+
}
|
|
77
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ToastContainerComponent, decorators: [{
|
|
78
|
+
type: Component,
|
|
79
|
+
args: [{ selector: 'app-toast-container', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fixed bottom-6 right-6 z-[1100] flex max-w-[380px] flex-col gap-3 pointer-events-none\" aria-live=\"polite\" aria-atomic=\"false\">\n @for (toast of toastService.toasts(); track toast.id) {\n <div\n class=\"toast pointer-events-auto flex items-start gap-3 rounded-[var(--eds-radius-md)] border border-[var(--eds-color-border)] bg-[var(--eds-color-surface)] px-4 py-3 text-[13px] text-[var(--eds-color-text)] shadow-[0_6px_24px_rgba(20,30,50,0.12)]\"\n role=\"status\"\n >\n <span\n class=\"inline-flex h-[22px] w-[22px] shrink-0 items-center justify-center rounded-full\"\n [class]=\"toast.variant === 'success' ? 'bg-[var(--eds-color-success-soft)] text-[var(--eds-color-success)]' : toast.variant === 'error' ? 'bg-[var(--eds-color-danger-soft)] text-[var(--eds-color-danger)]' : 'bg-[var(--eds-color-primary-soft)] text-[var(--eds-color-primary)]'\"\n aria-hidden=\"true\"\n >\n @switch (toast.variant) {\n @case ('success') {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n }\n @case ('error') {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>\n }\n @default {\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>\n }\n }\n </span>\n <span class=\"flex-1 leading-snug\">{{ toast.text }}</span>\n <button\n type=\"button\"\n class=\"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border-none bg-transparent text-[var(--eds-color-text-soft)] transition-colors duration-150 hover:bg-[var(--eds-color-surface-alt)] hover:text-[var(--eds-color-text)]\"\n (click)=\"toastService.dismiss(toast.id)\"\n aria-label=\"Dismiss notification\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n }\n</div>\n", styles: [".toast{animation:slide-in .16s ease}@keyframes slide-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
80
|
+
}] });
|
|
81
|
+
|
|
82
|
+
class EdsIconComponent {
|
|
83
|
+
constructor() {
|
|
84
|
+
this.name = input.required();
|
|
85
|
+
this.size = input(20);
|
|
86
|
+
this.fill = input(0);
|
|
87
|
+
this.weight = input(400);
|
|
88
|
+
this.variation = computed(() => `'FILL' ${this.fill()}, 'wght' ${this.weight()}, 'GRAD' 0, 'opsz' ${this.size()}`);
|
|
89
|
+
}
|
|
90
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
91
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.17", type: EdsIconComponent, isStandalone: true, selector: "eds-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fill: { classPropertyName: "fill", publicName: "fill", isSignal: true, isRequired: false, transformFunction: null }, weight: { classPropertyName: "weight", publicName: "weight", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `<span class="eds-icon" [style.font-size.px]="size()" [style.font-variation-settings]="variation()">{{ name() }}</span>`, isInline: true, styles: [":host{display:inline-flex;line-height:0}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
92
|
+
}
|
|
93
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsIconComponent, decorators: [{
|
|
94
|
+
type: Component,
|
|
95
|
+
args: [{ selector: 'eds-icon', standalone: true, template: `<span class="eds-icon" [style.font-size.px]="size()" [style.font-variation-settings]="variation()">{{ name() }}</span>`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-flex;line-height:0}\n"] }]
|
|
96
|
+
}] });
|
|
97
|
+
|
|
98
|
+
class EdsModuleNavComponent {
|
|
99
|
+
constructor() {
|
|
100
|
+
this.config = inject(VOICE_RECEPTIONIST_CONFIG);
|
|
101
|
+
this.session = inject(VOICE_RECEPTIONIST_SESSION);
|
|
102
|
+
this.includePracticeNav = !!this.config.includePracticeNav;
|
|
103
|
+
/** Standalone Voice Hub only — never show logout in EHR embed (no module nav there). */
|
|
104
|
+
this.showLogout = computed(() => !!this.session);
|
|
105
|
+
this.userEmail = computed(() => this.session?.email() ?? null);
|
|
106
|
+
this.receptionistNav = [
|
|
107
|
+
{ id: 'dashboard', label: 'Home', icon: 'home', route: 'dashboard' },
|
|
108
|
+
{ id: 'live', label: 'Live Calls', icon: 'phone_in_talk', route: 'live' },
|
|
109
|
+
{ id: 'history', label: 'Call History', icon: 'history', route: 'history' },
|
|
110
|
+
{ id: 'activities', label: 'Activities', icon: 'format_list_bulleted', route: 'activities' },
|
|
111
|
+
{ id: 'analytics', label: 'Analytics', icon: 'show_chart', route: 'analytics' },
|
|
112
|
+
{ id: 'api-logs', label: 'API Logs', icon: 'terminal', route: 'api-logs' },
|
|
113
|
+
{ id: 'settings', label: 'Agent Setting', icon: 'settings', route: 'settings' },
|
|
114
|
+
];
|
|
115
|
+
this.practiceNav = [
|
|
116
|
+
{ id: 'patients', label: 'Patients', icon: 'groups', route: 'patients' },
|
|
117
|
+
{ id: 'providers', label: 'Providers', icon: 'medical_services', route: 'providers' },
|
|
118
|
+
{ id: 'appointments', label: 'Appointments', icon: 'calendar_month', route: 'appointments' },
|
|
119
|
+
{ id: 'admin', label: 'Admin', icon: 'admin_panel_settings', route: 'admin', adminOnly: true },
|
|
120
|
+
];
|
|
121
|
+
}
|
|
122
|
+
showNavItem(item) {
|
|
123
|
+
if (!item.adminOnly)
|
|
124
|
+
return true;
|
|
125
|
+
return !!this.session?.isAdmin() || !!this.session?.isSuperAdmin?.();
|
|
126
|
+
}
|
|
127
|
+
logout() {
|
|
128
|
+
this.session?.logout();
|
|
129
|
+
}
|
|
130
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsModuleNavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
131
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: EdsModuleNavComponent, isStandalone: true, selector: "eds-module-nav", host: { classAttribute: "block shrink-0" }, ngImport: i0, template: "<nav\n class=\"flex h-screen min-h-screen w-[var(--eds-nav-width)] flex-col overflow-y-auto sticky top-0 border-r border-[var(--eds-border-default)] bg-white py-5 px-4\"\n aria-label=\"AI Receptionist\"\n>\n <div class=\"mb-4 flex items-center gap-3 border-b border-[var(--eds-border-default)] px-1 pb-4 pt-1\">\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)]\" aria-hidden=\"true\">\n <eds-icon name=\"auto_awesome\" [size]=\"20\" [fill]=\"1\" />\n </span>\n <div class=\"flex min-w-0 flex-col gap-1\">\n <span class=\"text-[15px] font-semibold leading-tight tracking-tight text-[var(--eds-text-primary)]\">AI Receptionist</span>\n </div>\n </div>\n\n <div class=\"flex flex-col gap-1\">\n @for (item of receptionistNav; track item.id) {\n <a\n class=\"group/link relative flex items-center gap-3 rounded-[10px] px-3 py-3 text-sm font-medium leading-tight text-slate-700 no-underline transition-colors duration-150 hover:bg-slate-50 hover:text-slate-900 [&.active]:bg-slate-100 [&.active]:font-semibold [&.active]:text-slate-900\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: item.route === 'dashboard' }\"\n >\n <eds-icon class=\"shrink-0 text-slate-600 group-hover/link:text-slate-900 group-[.active]/link:text-slate-900\" [name]=\"item.icon\" [size]=\"24\" />\n <span class=\"min-w-0 flex-1\">{{ item.label }}</span>\n </a>\n }\n </div>\n\n @if (includePracticeNav) {\n <p class=\"mx-3 mb-2 mt-4 text-sm font-semibold text-[var(--eds-text-table-header,#4d5573)]\">Practice</p>\n <div class=\"mb-3 flex flex-col gap-1\">\n @for (item of practiceNav; track item.id) {\n @if (showNavItem(item)) {\n <a\n class=\"group/link relative flex items-center gap-3 rounded-[10px] px-3 py-3 text-sm font-medium leading-tight text-slate-700 no-underline transition-colors duration-150 hover:bg-slate-50 hover:text-slate-900 [&.active]:bg-slate-100 [&.active]:font-semibold [&.active]:text-slate-900\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n >\n <eds-icon class=\"shrink-0 text-slate-600 group-hover/link:text-slate-900 group-[.active]/link:text-slate-900\" [name]=\"item.icon\" [size]=\"24\" />\n <span class=\"min-w-0 flex-1\">{{ item.label }}</span>\n </a>\n }\n }\n </div>\n }\n\n @if (showLogout()) {\n <div class=\"mt-auto border-t border-[var(--eds-border-default)] pt-3\">\n @if (userEmail(); as email) {\n <p class=\"mb-2 truncate px-3 text-xs text-slate-500\" [title]=\"email\">{{ email }}</p>\n }\n <button\n type=\"button\"\n class=\"group/link relative flex w-full cursor-pointer items-center gap-3 rounded-[10px] border-0 bg-transparent px-3 py-3 text-left text-sm font-medium leading-tight text-slate-700 transition-colors duration-150 hover:bg-slate-50 hover:text-slate-900\"\n (click)=\"logout()\"\n aria-label=\"Log out\"\n title=\"Log out\"\n >\n <eds-icon class=\"shrink-0 text-slate-600 group-hover/link:text-slate-900\" name=\"logout\" [size]=\"24\" />\n <span class=\"min-w-0 flex-1\">Log out</span>\n </button>\n </div>\n }\n</nav>\n", dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: EdsIconComponent, selector: "eds-icon", inputs: ["name", "size", "fill", "weight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
132
|
+
}
|
|
133
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsModuleNavComponent, decorators: [{
|
|
134
|
+
type: Component,
|
|
135
|
+
args: [{ selector: 'eds-module-nav', imports: [RouterLink, RouterLinkActive, EdsIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'block shrink-0' }, template: "<nav\n class=\"flex h-screen min-h-screen w-[var(--eds-nav-width)] flex-col overflow-y-auto sticky top-0 border-r border-[var(--eds-border-default)] bg-white py-5 px-4\"\n aria-label=\"AI Receptionist\"\n>\n <div class=\"mb-4 flex items-center gap-3 border-b border-[var(--eds-border-default)] px-1 pb-4 pt-1\">\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)]\" aria-hidden=\"true\">\n <eds-icon name=\"auto_awesome\" [size]=\"20\" [fill]=\"1\" />\n </span>\n <div class=\"flex min-w-0 flex-col gap-1\">\n <span class=\"text-[15px] font-semibold leading-tight tracking-tight text-[var(--eds-text-primary)]\">AI Receptionist</span>\n </div>\n </div>\n\n <div class=\"flex flex-col gap-1\">\n @for (item of receptionistNav; track item.id) {\n <a\n class=\"group/link relative flex items-center gap-3 rounded-[10px] px-3 py-3 text-sm font-medium leading-tight text-slate-700 no-underline transition-colors duration-150 hover:bg-slate-50 hover:text-slate-900 [&.active]:bg-slate-100 [&.active]:font-semibold [&.active]:text-slate-900\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: item.route === 'dashboard' }\"\n >\n <eds-icon class=\"shrink-0 text-slate-600 group-hover/link:text-slate-900 group-[.active]/link:text-slate-900\" [name]=\"item.icon\" [size]=\"24\" />\n <span class=\"min-w-0 flex-1\">{{ item.label }}</span>\n </a>\n }\n </div>\n\n @if (includePracticeNav) {\n <p class=\"mx-3 mb-2 mt-4 text-sm font-semibold text-[var(--eds-text-table-header,#4d5573)]\">Practice</p>\n <div class=\"mb-3 flex flex-col gap-1\">\n @for (item of practiceNav; track item.id) {\n @if (showNavItem(item)) {\n <a\n class=\"group/link relative flex items-center gap-3 rounded-[10px] px-3 py-3 text-sm font-medium leading-tight text-slate-700 no-underline transition-colors duration-150 hover:bg-slate-50 hover:text-slate-900 [&.active]:bg-slate-100 [&.active]:font-semibold [&.active]:text-slate-900\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n >\n <eds-icon class=\"shrink-0 text-slate-600 group-hover/link:text-slate-900 group-[.active]/link:text-slate-900\" [name]=\"item.icon\" [size]=\"24\" />\n <span class=\"min-w-0 flex-1\">{{ item.label }}</span>\n </a>\n }\n }\n </div>\n }\n\n @if (showLogout()) {\n <div class=\"mt-auto border-t border-[var(--eds-border-default)] pt-3\">\n @if (userEmail(); as email) {\n <p class=\"mb-2 truncate px-3 text-xs text-slate-500\" [title]=\"email\">{{ email }}</p>\n }\n <button\n type=\"button\"\n class=\"group/link relative flex w-full cursor-pointer items-center gap-3 rounded-[10px] border-0 bg-transparent px-3 py-3 text-left text-sm font-medium leading-tight text-slate-700 transition-colors duration-150 hover:bg-slate-50 hover:text-slate-900\"\n (click)=\"logout()\"\n aria-label=\"Log out\"\n title=\"Log out\"\n >\n <eds-icon class=\"shrink-0 text-slate-600 group-hover/link:text-slate-900\" name=\"logout\" [size]=\"24\" />\n <span class=\"min-w-0 flex-1\">Log out</span>\n </button>\n </div>\n }\n</nav>\n" }]
|
|
136
|
+
}] });
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Thin top progress bar + soft content veil while Angular navigates
|
|
140
|
+
* (lazy chunks, guards). Use once at the host root or app shell.
|
|
141
|
+
*/
|
|
142
|
+
class EdsRouteProgressComponent {
|
|
143
|
+
constructor() {
|
|
144
|
+
this.router = inject(Router);
|
|
145
|
+
this.destroyRef = inject(DestroyRef);
|
|
146
|
+
this.hideTimer = null;
|
|
147
|
+
this.active = signal(false);
|
|
148
|
+
this.router.events
|
|
149
|
+
.pipe(filter((e) => e instanceof NavigationStart ||
|
|
150
|
+
e instanceof NavigationEnd ||
|
|
151
|
+
e instanceof NavigationCancel ||
|
|
152
|
+
e instanceof NavigationError), takeUntilDestroyed(this.destroyRef))
|
|
153
|
+
.subscribe((e) => {
|
|
154
|
+
if (e instanceof NavigationStart) {
|
|
155
|
+
this.clearHideTimer();
|
|
156
|
+
this.active.set(true);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
// Keep visible briefly so fast navigations still feel intentional.
|
|
160
|
+
this.clearHideTimer();
|
|
161
|
+
this.hideTimer = setTimeout(() => this.active.set(false), 180);
|
|
162
|
+
});
|
|
163
|
+
this.destroyRef.onDestroy(() => this.clearHideTimer());
|
|
164
|
+
}
|
|
165
|
+
clearHideTimer() {
|
|
166
|
+
if (this.hideTimer) {
|
|
167
|
+
clearTimeout(this.hideTimer);
|
|
168
|
+
this.hideTimer = null;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsRouteProgressComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
172
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: EdsRouteProgressComponent, isStandalone: true, selector: "eds-route-progress", ngImport: i0, template: `
|
|
173
|
+
@if (active()) {
|
|
174
|
+
<div class="eds-route-progress" role="progressbar" aria-busy="true" aria-label="Loading page">
|
|
175
|
+
<div class="eds-route-progress__bar"></div>
|
|
176
|
+
</div>
|
|
177
|
+
<div class="eds-route-progress__veil" aria-hidden="true">
|
|
178
|
+
<div class="eds-route-progress__panel">
|
|
179
|
+
<span class="eds-route-progress__spinner"></span>
|
|
180
|
+
<span class="eds-route-progress__label">Loading…</span>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
}
|
|
184
|
+
`, isInline: true, styles: [":host{display:contents}.eds-route-progress{position:fixed;inset:0 0 auto;z-index:9999;height:3px;overflow:hidden;pointer-events:none;background:transparent}.eds-route-progress__bar{height:100%;width:40%;border-radius:0 2px 2px 0;background:linear-gradient(90deg,#2162f0,#8e51ff);animation:eds-route-progress-slide 1.05s ease-in-out infinite}.eds-route-progress__veil{position:fixed;inset:0;z-index:9998;display:flex;align-items:center;justify-content:center;pointer-events:all;background:#f7faff8c;backdrop-filter:blur(1px)}.eds-route-progress__panel{display:inline-flex;align-items:center;gap:.75rem;padding:.75rem 1.1rem;border:1px solid #e2e8f0;border-radius:.75rem;background:#fff;box-shadow:0 8px 24px #0f172a14;color:#334155;font-family:Inter,system-ui,sans-serif;font-size:.875rem;font-weight:500}.eds-route-progress__spinner{width:1.1rem;height:1.1rem;border:2px solid #dbeafe;border-top-color:#2162f0;border-radius:999px;animation:eds-route-progress-spin .7s linear infinite}.eds-route-progress__label{letter-spacing:-.01em}@keyframes eds-route-progress-slide{0%{transform:translate(-120%)}to{transform:translate(320%)}}@keyframes eds-route-progress-spin{to{transform:rotate(360deg)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
185
|
+
}
|
|
186
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsRouteProgressComponent, decorators: [{
|
|
187
|
+
type: Component,
|
|
188
|
+
args: [{ selector: 'eds-route-progress', standalone: true, template: `
|
|
189
|
+
@if (active()) {
|
|
190
|
+
<div class="eds-route-progress" role="progressbar" aria-busy="true" aria-label="Loading page">
|
|
191
|
+
<div class="eds-route-progress__bar"></div>
|
|
192
|
+
</div>
|
|
193
|
+
<div class="eds-route-progress__veil" aria-hidden="true">
|
|
194
|
+
<div class="eds-route-progress__panel">
|
|
195
|
+
<span class="eds-route-progress__spinner"></span>
|
|
196
|
+
<span class="eds-route-progress__label">Loading…</span>
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
}
|
|
200
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:contents}.eds-route-progress{position:fixed;inset:0 0 auto;z-index:9999;height:3px;overflow:hidden;pointer-events:none;background:transparent}.eds-route-progress__bar{height:100%;width:40%;border-radius:0 2px 2px 0;background:linear-gradient(90deg,#2162f0,#8e51ff);animation:eds-route-progress-slide 1.05s ease-in-out infinite}.eds-route-progress__veil{position:fixed;inset:0;z-index:9998;display:flex;align-items:center;justify-content:center;pointer-events:all;background:#f7faff8c;backdrop-filter:blur(1px)}.eds-route-progress__panel{display:inline-flex;align-items:center;gap:.75rem;padding:.75rem 1.1rem;border:1px solid #e2e8f0;border-radius:.75rem;background:#fff;box-shadow:0 8px 24px #0f172a14;color:#334155;font-family:Inter,system-ui,sans-serif;font-size:.875rem;font-weight:500}.eds-route-progress__spinner{width:1.1rem;height:1.1rem;border:2px solid #dbeafe;border-top-color:#2162f0;border-radius:999px;animation:eds-route-progress-spin .7s linear infinite}.eds-route-progress__label{letter-spacing:-.01em}@keyframes eds-route-progress-slide{0%{transform:translate(-120%)}to{transform:translate(320%)}}@keyframes eds-route-progress-spin{to{transform:rotate(360deg)}}\n"] }]
|
|
201
|
+
}], ctorParameters: () => [] });
|
|
202
|
+
|
|
203
|
+
class EdsAppShellComponent {
|
|
204
|
+
constructor() {
|
|
205
|
+
/** EHR embed: false (default). Standalone Voice Hub: set showModuleNav: true. */
|
|
206
|
+
this.showModuleNav = !!inject(VOICE_RECEPTIONIST_CONFIG).showModuleNav;
|
|
207
|
+
/**
|
|
208
|
+
* Standalone Voice Hub mounts progress on app-root. EHR embeds that only use
|
|
209
|
+
* this shell still need a nav loader — enable when host nav is hidden.
|
|
210
|
+
*/
|
|
211
|
+
this.showRouteProgress = !this.showModuleNav;
|
|
212
|
+
}
|
|
213
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsAppShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
214
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: EdsAppShellComponent, isStandalone: true, selector: "eds-app-shell", ngImport: i0, template: "<div class=\"eds-layout flex min-h-screen\">\n @if (showRouteProgress) {\n <eds-route-progress />\n }\n @if (showModuleNav) {\n <eds-module-nav />\n }\n <div class=\"eds-main flex min-w-0 flex-1 flex-col\">\n <div class=\"eds-content flex-1 overflow-auto\">\n <router-outlet />\n </div>\n </div>\n <app-toast-container />\n</div>\n", styles: [":host{display:block}.eds-layout{background:var(--eds-surface-l1);font-family:var(--eds-font-inter, \"Inter\", sans-serif);font-size:var(--eds-font-size-base, 13px);font-weight:var(--eds-font-weight-regular, 400);color:var(--eds-text-primary, #41464c)}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: EdsModuleNavComponent, selector: "eds-module-nav" }, { kind: "component", type: ToastContainerComponent, selector: "app-toast-container" }, { kind: "component", type: EdsRouteProgressComponent, selector: "eds-route-progress" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
215
|
+
}
|
|
216
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsAppShellComponent, decorators: [{
|
|
217
|
+
type: Component,
|
|
218
|
+
args: [{ selector: 'eds-app-shell', imports: [
|
|
219
|
+
RouterOutlet,
|
|
220
|
+
EdsModuleNavComponent,
|
|
221
|
+
ToastContainerComponent,
|
|
222
|
+
EdsRouteProgressComponent,
|
|
223
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"eds-layout flex min-h-screen\">\n @if (showRouteProgress) {\n <eds-route-progress />\n }\n @if (showModuleNav) {\n <eds-module-nav />\n }\n <div class=\"eds-main flex min-w-0 flex-1 flex-col\">\n <div class=\"eds-content flex-1 overflow-auto\">\n <router-outlet />\n </div>\n </div>\n <app-toast-container />\n</div>\n", styles: [":host{display:block}.eds-layout{background:var(--eds-surface-l1);font-family:var(--eds-font-inter, \"Inter\", sans-serif);font-size:var(--eds-font-size-base, 13px);font-weight:var(--eds-font-weight-regular, 400);color:var(--eds-text-primary, #41464c)}\n"] }]
|
|
224
|
+
}] });
|
|
6
225
|
|
|
7
226
|
/** Build URL helpers from a config (or raw base URL). Safe outside injection context. */
|
|
8
227
|
function createVoiceReceptionistPaths(configOrBase) {
|
|
@@ -434,8 +653,15 @@ function computeEffectiveWelcomeMessage(settings) {
|
|
|
434
653
|
function historyResolution(input) {
|
|
435
654
|
if (input.risk === 'urgent' || input.risk === 'review')
|
|
436
655
|
return 'needs_attention';
|
|
656
|
+
const r = String(input.resolution ?? '').trim().toLowerCase();
|
|
657
|
+
if (r === 'resolved')
|
|
658
|
+
return 'resolved';
|
|
659
|
+
if (r === 'unresolved' || r.includes('needs') || r.includes('attention')) {
|
|
660
|
+
return 'needs_attention';
|
|
661
|
+
}
|
|
437
662
|
const o = String(input.outcome ?? '').toLowerCase();
|
|
438
|
-
if (o.includes('
|
|
663
|
+
if (o.includes('unresolved') ||
|
|
664
|
+
o.includes('fail') ||
|
|
439
665
|
o.includes('escalat') ||
|
|
440
666
|
o.includes('abandon') ||
|
|
441
667
|
o.includes('attention') ||
|
|
@@ -443,6 +669,8 @@ function historyResolution(input) {
|
|
|
443
669
|
o === 'transferred') {
|
|
444
670
|
return 'needs_attention';
|
|
445
671
|
}
|
|
672
|
+
if (o === 'completed' || o.includes('completed'))
|
|
673
|
+
return 'resolved';
|
|
446
674
|
return 'resolved';
|
|
447
675
|
}
|
|
448
676
|
function historyResolutionLabel(resolution) {
|
|
@@ -770,6 +998,7 @@ function mapHistoryCallDto(dto) {
|
|
|
770
998
|
phone: dto.phone,
|
|
771
999
|
direction: dto.dir,
|
|
772
1000
|
outcome: dto.outcome,
|
|
1001
|
+
resolution: dto.resolution ?? null,
|
|
773
1002
|
reason: dto.reason,
|
|
774
1003
|
duration: parseDurToSeconds(dto.dur),
|
|
775
1004
|
durationLabel: dto.dur,
|
|
@@ -1205,7 +1434,11 @@ function asHistoryList(body) {
|
|
|
1205
1434
|
function asLiveCallList(body) {
|
|
1206
1435
|
if (Array.isArray(body))
|
|
1207
1436
|
return body;
|
|
1208
|
-
|
|
1437
|
+
if (!body || typeof body !== 'object')
|
|
1438
|
+
return [];
|
|
1439
|
+
const o = body;
|
|
1440
|
+
const list = o['items'] ?? o['data'] ?? o['calls'] ?? o['liveCalls'];
|
|
1441
|
+
return Array.isArray(list) ? list : [];
|
|
1209
1442
|
}
|
|
1210
1443
|
function asTaskList(body) {
|
|
1211
1444
|
if (Array.isArray(body))
|
|
@@ -3481,5 +3714,376 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
3481
3714
|
args: [{ providedIn: 'root' }]
|
|
3482
3715
|
}] });
|
|
3483
3716
|
|
|
3484
|
-
|
|
3485
|
-
|
|
3717
|
+
/**
|
|
3718
|
+
* Single shared Socket.io connection to the `/dashboard` namespace.
|
|
3719
|
+
* Used by live calls list + per-call transcript stream.
|
|
3720
|
+
*/
|
|
3721
|
+
class DashboardSocketService {
|
|
3722
|
+
constructor() {
|
|
3723
|
+
this.config = inject(VOICE_RECEPTIONIST_CONFIG);
|
|
3724
|
+
this.paths = createVoiceReceptionistPaths(this.config);
|
|
3725
|
+
this.connected = signal(false);
|
|
3726
|
+
this.socket = null;
|
|
3727
|
+
this.refCount = 0;
|
|
3728
|
+
this.handlers = new Map();
|
|
3729
|
+
this.connectCallbacks = new Set();
|
|
3730
|
+
}
|
|
3731
|
+
acquire() {
|
|
3732
|
+
this.refCount++;
|
|
3733
|
+
if (this.refCount === 1) {
|
|
3734
|
+
this.connect();
|
|
3735
|
+
}
|
|
3736
|
+
}
|
|
3737
|
+
release() {
|
|
3738
|
+
this.refCount = Math.max(0, this.refCount - 1);
|
|
3739
|
+
if (this.refCount === 0) {
|
|
3740
|
+
this.disconnect();
|
|
3741
|
+
}
|
|
3742
|
+
}
|
|
3743
|
+
onConnect(callback) {
|
|
3744
|
+
this.connectCallbacks.add(callback);
|
|
3745
|
+
if (this.connected()) {
|
|
3746
|
+
callback();
|
|
3747
|
+
}
|
|
3748
|
+
}
|
|
3749
|
+
offConnect(callback) {
|
|
3750
|
+
this.connectCallbacks.delete(callback);
|
|
3751
|
+
}
|
|
3752
|
+
on(event, handler) {
|
|
3753
|
+
const wrapped = (payload) => handler(payload);
|
|
3754
|
+
if (!this.handlers.has(event)) {
|
|
3755
|
+
this.handlers.set(event, new Map());
|
|
3756
|
+
}
|
|
3757
|
+
this.handlers.get(event).set(handler, wrapped);
|
|
3758
|
+
if (this.socket) {
|
|
3759
|
+
this.socket.on(event, wrapped);
|
|
3760
|
+
}
|
|
3761
|
+
}
|
|
3762
|
+
off(event, handler) {
|
|
3763
|
+
const eventHandlers = this.handlers.get(event);
|
|
3764
|
+
const wrapped = eventHandlers?.get(handler);
|
|
3765
|
+
if (wrapped) {
|
|
3766
|
+
this.socket?.off(event, wrapped);
|
|
3767
|
+
eventHandlers.delete(handler);
|
|
3768
|
+
}
|
|
3769
|
+
}
|
|
3770
|
+
emit(event, payload) {
|
|
3771
|
+
this.socket?.emit(event, payload);
|
|
3772
|
+
}
|
|
3773
|
+
connect() {
|
|
3774
|
+
if (this.config.useMockApi) {
|
|
3775
|
+
this.connected.set(true);
|
|
3776
|
+
this.fireConnectCallbacks();
|
|
3777
|
+
return;
|
|
3778
|
+
}
|
|
3779
|
+
this.socket = io(`${this.paths.apiRoot()}/dashboard`, {
|
|
3780
|
+
path: '/socket.io',
|
|
3781
|
+
transports: ['websocket'],
|
|
3782
|
+
autoConnect: false,
|
|
3783
|
+
});
|
|
3784
|
+
this.socket.on('connect', () => {
|
|
3785
|
+
this.connected.set(true);
|
|
3786
|
+
this.fireConnectCallbacks();
|
|
3787
|
+
});
|
|
3788
|
+
this.socket.on('disconnect', () => {
|
|
3789
|
+
this.connected.set(false);
|
|
3790
|
+
});
|
|
3791
|
+
this.socket.io.on('reconnect', () => {
|
|
3792
|
+
this.fireConnectCallbacks();
|
|
3793
|
+
});
|
|
3794
|
+
for (const [event, handlerMap] of this.handlers) {
|
|
3795
|
+
for (const wrapped of handlerMap.values()) {
|
|
3796
|
+
this.socket.on(event, wrapped);
|
|
3797
|
+
}
|
|
3798
|
+
}
|
|
3799
|
+
this.socket.connect();
|
|
3800
|
+
}
|
|
3801
|
+
disconnect() {
|
|
3802
|
+
if (!this.socket) {
|
|
3803
|
+
this.connected.set(false);
|
|
3804
|
+
return;
|
|
3805
|
+
}
|
|
3806
|
+
for (const [event, handlerMap] of this.handlers) {
|
|
3807
|
+
for (const wrapped of handlerMap.values()) {
|
|
3808
|
+
this.socket.off(event, wrapped);
|
|
3809
|
+
}
|
|
3810
|
+
}
|
|
3811
|
+
this.socket.removeAllListeners();
|
|
3812
|
+
this.socket.disconnect();
|
|
3813
|
+
this.socket = null;
|
|
3814
|
+
this.connected.set(false);
|
|
3815
|
+
}
|
|
3816
|
+
fireConnectCallbacks() {
|
|
3817
|
+
for (const cb of this.connectCallbacks) {
|
|
3818
|
+
cb();
|
|
3819
|
+
}
|
|
3820
|
+
}
|
|
3821
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: DashboardSocketService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3822
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: DashboardSocketService, providedIn: 'root' }); }
|
|
3823
|
+
}
|
|
3824
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: DashboardSocketService, decorators: [{
|
|
3825
|
+
type: Injectable,
|
|
3826
|
+
args: [{ providedIn: 'root' }]
|
|
3827
|
+
}] });
|
|
3828
|
+
|
|
3829
|
+
const DEFAULT_POLL_MS = 12_000;
|
|
3830
|
+
/**
|
|
3831
|
+
* Shared live calls list — REST + `live_calls_updated` socket + fallback poll.
|
|
3832
|
+
*/
|
|
3833
|
+
class LiveCallsListService {
|
|
3834
|
+
constructor() {
|
|
3835
|
+
this.api = inject(AiReceptionistApiService);
|
|
3836
|
+
this.socket = inject(DashboardSocketService);
|
|
3837
|
+
this.config = inject(VOICE_RECEPTIONIST_CONFIG);
|
|
3838
|
+
this.calls = signal([]);
|
|
3839
|
+
this.loading = signal(false);
|
|
3840
|
+
this.error = signal(null);
|
|
3841
|
+
this.lastUpdated = signal(null);
|
|
3842
|
+
this.subscriberCount = 0;
|
|
3843
|
+
this.refreshId = 0;
|
|
3844
|
+
this.mockPollTimer = null;
|
|
3845
|
+
this.onLiveCallsUpdated = () => this.refresh(false);
|
|
3846
|
+
this.onSocketConnect = () => this.refresh(false);
|
|
3847
|
+
}
|
|
3848
|
+
start() {
|
|
3849
|
+
this.subscriberCount++;
|
|
3850
|
+
if (this.subscriberCount > 1) {
|
|
3851
|
+
this.refresh(false);
|
|
3852
|
+
return;
|
|
3853
|
+
}
|
|
3854
|
+
this.socket.acquire();
|
|
3855
|
+
this.socket.on('live_calls_updated', this.onLiveCallsUpdated);
|
|
3856
|
+
this.socket.onConnect(this.onSocketConnect);
|
|
3857
|
+
this.bindVisibility();
|
|
3858
|
+
this.refresh(true);
|
|
3859
|
+
this.startFallbackPoll();
|
|
3860
|
+
}
|
|
3861
|
+
stop() {
|
|
3862
|
+
this.subscriberCount = Math.max(0, this.subscriberCount - 1);
|
|
3863
|
+
if (this.subscriberCount > 0) {
|
|
3864
|
+
return;
|
|
3865
|
+
}
|
|
3866
|
+
this.refreshId++;
|
|
3867
|
+
this.refreshSub?.unsubscribe();
|
|
3868
|
+
this.refreshSub = undefined;
|
|
3869
|
+
this.stopFallbackPoll();
|
|
3870
|
+
this.unbindVisibility();
|
|
3871
|
+
this.socket.off('live_calls_updated', this.onLiveCallsUpdated);
|
|
3872
|
+
this.socket.offConnect(this.onSocketConnect);
|
|
3873
|
+
this.socket.release();
|
|
3874
|
+
}
|
|
3875
|
+
refresh(showLoading = true) {
|
|
3876
|
+
const requestId = ++this.refreshId;
|
|
3877
|
+
if (showLoading && this.calls().length === 0) {
|
|
3878
|
+
this.loading.set(true);
|
|
3879
|
+
}
|
|
3880
|
+
this.refreshSub?.unsubscribe();
|
|
3881
|
+
this.refreshSub = this.api.getLiveCalls().subscribe({
|
|
3882
|
+
next: ({ data }) => {
|
|
3883
|
+
if (requestId !== this.refreshId)
|
|
3884
|
+
return;
|
|
3885
|
+
this.calls.set(data);
|
|
3886
|
+
this.lastUpdated.set(Date.now());
|
|
3887
|
+
this.loading.set(false);
|
|
3888
|
+
this.error.set(null);
|
|
3889
|
+
},
|
|
3890
|
+
error: (err) => {
|
|
3891
|
+
if (requestId !== this.refreshId)
|
|
3892
|
+
return;
|
|
3893
|
+
this.loading.set(false);
|
|
3894
|
+
const message = err instanceof Error ? err.message : 'Could not load live calls.';
|
|
3895
|
+
this.error.set(message);
|
|
3896
|
+
},
|
|
3897
|
+
});
|
|
3898
|
+
}
|
|
3899
|
+
startFallbackPoll() {
|
|
3900
|
+
const pollMs = this.config.liveCallsPollIntervalMs ?? DEFAULT_POLL_MS;
|
|
3901
|
+
if (this.config.useMockApi) {
|
|
3902
|
+
this.mockPollTimer = setInterval(() => {
|
|
3903
|
+
if (!document.hidden) {
|
|
3904
|
+
this.refresh(false);
|
|
3905
|
+
}
|
|
3906
|
+
}, pollMs);
|
|
3907
|
+
return;
|
|
3908
|
+
}
|
|
3909
|
+
this.pollSub = interval(pollMs)
|
|
3910
|
+
.pipe(filter$1(() => !document.hidden))
|
|
3911
|
+
.subscribe(() => this.refresh(false));
|
|
3912
|
+
}
|
|
3913
|
+
stopFallbackPoll() {
|
|
3914
|
+
this.pollSub?.unsubscribe();
|
|
3915
|
+
this.pollSub = undefined;
|
|
3916
|
+
if (this.mockPollTimer) {
|
|
3917
|
+
clearInterval(this.mockPollTimer);
|
|
3918
|
+
this.mockPollTimer = null;
|
|
3919
|
+
}
|
|
3920
|
+
}
|
|
3921
|
+
bindVisibility() {
|
|
3922
|
+
this.visibilityHandler = () => {
|
|
3923
|
+
if (!document.hidden) {
|
|
3924
|
+
this.refresh(false);
|
|
3925
|
+
}
|
|
3926
|
+
};
|
|
3927
|
+
document.addEventListener('visibilitychange', this.visibilityHandler);
|
|
3928
|
+
}
|
|
3929
|
+
unbindVisibility() {
|
|
3930
|
+
if (this.visibilityHandler) {
|
|
3931
|
+
document.removeEventListener('visibilitychange', this.visibilityHandler);
|
|
3932
|
+
this.visibilityHandler = undefined;
|
|
3933
|
+
}
|
|
3934
|
+
}
|
|
3935
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: LiveCallsListService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3936
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: LiveCallsListService, providedIn: 'root' }); }
|
|
3937
|
+
}
|
|
3938
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: LiveCallsListService, decorators: [{
|
|
3939
|
+
type: Injectable,
|
|
3940
|
+
args: [{ providedIn: 'root' }]
|
|
3941
|
+
}] });
|
|
3942
|
+
|
|
3943
|
+
/**
|
|
3944
|
+
* Owns live-calls polling/socket for both the list and the per-call monitor
|
|
3945
|
+
* so navigating list → detail → back does not tear down the shared list.
|
|
3946
|
+
*/
|
|
3947
|
+
class LiveCallsShellComponent {
|
|
3948
|
+
constructor() {
|
|
3949
|
+
this.liveCallsList = inject(LiveCallsListService);
|
|
3950
|
+
}
|
|
3951
|
+
ngOnInit() {
|
|
3952
|
+
this.liveCallsList.start();
|
|
3953
|
+
}
|
|
3954
|
+
ngOnDestroy() {
|
|
3955
|
+
this.liveCallsList.stop();
|
|
3956
|
+
}
|
|
3957
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: LiveCallsShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3958
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: LiveCallsShellComponent, isStandalone: true, selector: "eds-live-calls-shell", ngImport: i0, template: '<router-outlet />', isInline: true, styles: [":host{display:contents}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3959
|
+
}
|
|
3960
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: LiveCallsShellComponent, decorators: [{
|
|
3961
|
+
type: Component,
|
|
3962
|
+
args: [{ selector: 'eds-live-calls-shell', imports: [RouterOutlet], template: '<router-outlet />', changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:contents}\n"] }]
|
|
3963
|
+
}] });
|
|
3964
|
+
|
|
3965
|
+
/** Feature child routes (under the embed shell). */
|
|
3966
|
+
const VOICE_RECEPTIONIST_FEATURE_ROUTES = [
|
|
3967
|
+
{ path: '', pathMatch: 'full', redirectTo: 'dashboard' },
|
|
3968
|
+
{
|
|
3969
|
+
path: 'dashboard',
|
|
3970
|
+
loadComponent: () => import('./edvak99-voice-receptionist-widget-dashboard-page.component-B_EYljRs.mjs').then((m) => m.DashboardPageComponent),
|
|
3971
|
+
},
|
|
3972
|
+
{
|
|
3973
|
+
path: 'live',
|
|
3974
|
+
component: LiveCallsShellComponent,
|
|
3975
|
+
children: [
|
|
3976
|
+
{
|
|
3977
|
+
path: '',
|
|
3978
|
+
pathMatch: 'full',
|
|
3979
|
+
loadComponent: () => import('./edvak99-voice-receptionist-widget-live-calls-page.component-1woGuh0J.mjs').then((m) => m.LiveCallsPageComponent),
|
|
3980
|
+
},
|
|
3981
|
+
{
|
|
3982
|
+
path: ':id',
|
|
3983
|
+
loadComponent: () => import('./edvak99-voice-receptionist-widget-live-monitor-page.component-ihwm1LNn.mjs').then((m) => m.LiveMonitorPageComponent),
|
|
3984
|
+
},
|
|
3985
|
+
],
|
|
3986
|
+
},
|
|
3987
|
+
{
|
|
3988
|
+
path: 'history',
|
|
3989
|
+
loadComponent: () => import('./edvak99-voice-receptionist-widget-call-history-page.component-DoYJFpSa.mjs').then((m) => m.CallHistoryPageComponent),
|
|
3990
|
+
},
|
|
3991
|
+
{
|
|
3992
|
+
path: 'history/:id',
|
|
3993
|
+
loadComponent: () => import('./edvak99-voice-receptionist-widget-call-history-detail-page.component-ENq2c-sm.mjs').then((m) => m.CallHistoryDetailPageComponent),
|
|
3994
|
+
},
|
|
3995
|
+
{
|
|
3996
|
+
path: 'activities',
|
|
3997
|
+
loadComponent: () => import('./edvak99-voice-receptionist-widget-activities-page.component-Br2Vi1Im.mjs').then((m) => m.ActivitiesPageComponent),
|
|
3998
|
+
},
|
|
3999
|
+
{
|
|
4000
|
+
path: 'tasks',
|
|
4001
|
+
loadComponent: () => import('./edvak99-voice-receptionist-widget-tasks-page.component-Cf76XyCz.mjs').then((m) => m.TasksPageComponent),
|
|
4002
|
+
},
|
|
4003
|
+
{
|
|
4004
|
+
path: 'analytics',
|
|
4005
|
+
loadComponent: () => import('./edvak99-voice-receptionist-widget-analytics-page.component-CglgGV6H.mjs').then((m) => m.AnalyticsPageComponent),
|
|
4006
|
+
},
|
|
4007
|
+
{
|
|
4008
|
+
path: 'api-logs',
|
|
4009
|
+
canActivate: [apiLogsStandaloneGuard],
|
|
4010
|
+
loadComponent: () => import('./edvak99-voice-receptionist-widget-api-logs-page.component-DPJiuNjk.mjs').then((m) => m.ApiLogsPageComponent),
|
|
4011
|
+
},
|
|
4012
|
+
{
|
|
4013
|
+
path: 'settings',
|
|
4014
|
+
loadComponent: () => import('./edvak99-voice-receptionist-widget-settings-page.component-C6F-Hgmk.mjs').then((m) => m.SettingsPageComponent),
|
|
4015
|
+
},
|
|
4016
|
+
{
|
|
4017
|
+
path: 'settings/outbound-purposes',
|
|
4018
|
+
loadComponent: () => import('./edvak99-voice-receptionist-widget-outbound-purposes-page.component-B2koBFU3.mjs').then((m) => m.OutboundPurposesPageComponent),
|
|
4019
|
+
},
|
|
4020
|
+
{
|
|
4021
|
+
path: 'knowledge',
|
|
4022
|
+
loadComponent: () => import('./edvak99-voice-receptionist-widget-settings-page.component-C6F-Hgmk.mjs').then((m) => m.SettingsPageComponent),
|
|
4023
|
+
data: { settingsTab: 'knowledge' },
|
|
4024
|
+
},
|
|
4025
|
+
{
|
|
4026
|
+
path: 'wizard',
|
|
4027
|
+
loadComponent: () => import('./edvak99-voice-receptionist-widget-wizard-page.component-BQTlz2F5.mjs').then((m) => m.WizardPageComponent),
|
|
4028
|
+
},
|
|
4029
|
+
];
|
|
4030
|
+
/**
|
|
4031
|
+
* Lazy-loadable routes for EHR (and standalone hosts).
|
|
4032
|
+
* Mount under a host path, e.g. `{ path: 'ai-receptionist', children: VOICE_RECEPTIONIST_ROUTES }`.
|
|
4033
|
+
*/
|
|
4034
|
+
const VOICE_RECEPTIONIST_ROUTES = [
|
|
4035
|
+
{
|
|
4036
|
+
path: '',
|
|
4037
|
+
component: EdsAppShellComponent,
|
|
4038
|
+
children: VOICE_RECEPTIONIST_FEATURE_ROUTES,
|
|
4039
|
+
},
|
|
4040
|
+
];
|
|
4041
|
+
|
|
4042
|
+
class EdsBadgeComponent {
|
|
4043
|
+
constructor() {
|
|
4044
|
+
this.tone = input('gray');
|
|
4045
|
+
}
|
|
4046
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4047
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.17", type: EdsBadgeComponent, isStandalone: true, selector: "eds-badge", inputs: { tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `<span class="eds-badge inline-flex items-center gap-2 py-1 px-2" [attr.data-tone]="tone()"><ng-content /></span>`, isInline: true, styles: [".eds-badge{border-radius:var(--eds-radius-sm);font-family:var(--eds-font-inter);font-size:12px;font-weight:500;line-height:1.4;white-space:nowrap}.eds-badge[data-tone=brand]{background:#3681f41f;color:var(--eds-brand-600)}.eds-badge[data-tone=pos]{background:#0abf521f;color:var(--eds-green-500)}.eds-badge[data-tone=notice]{background:#ffb90026;color:#b45309}.eds-badge[data-tone=neg]{background:#f037401f;color:var(--eds-red-500)}.eds-badge[data-tone=violet]{background:#8e51ff1f;color:var(--eds-violet-500)}.eds-badge[data-tone=gray]{background:var(--eds-gray-100);color:var(--eds-gray-600)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4048
|
+
}
|
|
4049
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsBadgeComponent, decorators: [{
|
|
4050
|
+
type: Component,
|
|
4051
|
+
args: [{ selector: 'eds-badge', standalone: true, template: `<span class="eds-badge inline-flex items-center gap-2 py-1 px-2" [attr.data-tone]="tone()"><ng-content /></span>`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".eds-badge{border-radius:var(--eds-radius-sm);font-family:var(--eds-font-inter);font-size:12px;font-weight:500;line-height:1.4;white-space:nowrap}.eds-badge[data-tone=brand]{background:#3681f41f;color:var(--eds-brand-600)}.eds-badge[data-tone=pos]{background:#0abf521f;color:var(--eds-green-500)}.eds-badge[data-tone=notice]{background:#ffb90026;color:#b45309}.eds-badge[data-tone=neg]{background:#f037401f;color:var(--eds-red-500)}.eds-badge[data-tone=violet]{background:#8e51ff1f;color:var(--eds-violet-500)}.eds-badge[data-tone=gray]{background:var(--eds-gray-100);color:var(--eds-gray-600)}\n"] }]
|
|
4052
|
+
}] });
|
|
4053
|
+
|
|
4054
|
+
class EdsButtonComponent {
|
|
4055
|
+
constructor() {
|
|
4056
|
+
this.variant = input('secondary');
|
|
4057
|
+
this.type = input('button');
|
|
4058
|
+
this.disabled = input(false);
|
|
4059
|
+
}
|
|
4060
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4061
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.17", type: EdsButtonComponent, isStandalone: true, selector: "eds-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
4062
|
+
<button [type]="type()" [disabled]="disabled()" [attr.data-variant]="variant()" class="eds-btn inline-flex items-center justify-center gap-2 py-2 px-4">
|
|
4063
|
+
<ng-content />
|
|
4064
|
+
</button>
|
|
4065
|
+
`, isInline: true, styles: [".eds-btn{border-radius:var(--eds-radius-md);border:1px solid transparent;font-family:var(--eds-font-inter);font-size:13px;font-weight:500;cursor:pointer;transition:background .12s ease,border-color .12s ease,color .12s ease}.eds-btn:disabled{opacity:.5;cursor:not-allowed}.eds-btn[data-variant=primary]{background:var(--eds-brand-600);color:#fff}.eds-btn[data-variant=primary]:hover:not(:disabled){background:var(--eds-brand-500)}.eds-btn[data-variant=secondary]{background:var(--eds-surface-l0);color:var(--eds-text-primary);border-color:var(--eds-border-default)}.eds-btn[data-variant=secondary]:hover:not(:disabled){background:var(--eds-surface-l1)}.eds-btn[data-variant=ghost]{background:transparent;color:var(--eds-text-secondary)}.eds-btn[data-variant=ghost]:hover:not(:disabled){background:var(--eds-gray-100);color:var(--eds-text-primary)}.eds-btn[data-variant=danger]{background:#f037401a;color:var(--eds-red-500);border-color:#f0374040}.eds-btn[data-variant=positive]{background:#0abf521f;color:var(--eds-green-500);border-color:#0abf5240}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4066
|
+
}
|
|
4067
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EdsButtonComponent, decorators: [{
|
|
4068
|
+
type: Component,
|
|
4069
|
+
args: [{ selector: 'eds-button', standalone: true, template: `
|
|
4070
|
+
<button [type]="type()" [disabled]="disabled()" [attr.data-variant]="variant()" class="eds-btn inline-flex items-center justify-center gap-2 py-2 px-4">
|
|
4071
|
+
<ng-content />
|
|
4072
|
+
</button>
|
|
4073
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".eds-btn{border-radius:var(--eds-radius-md);border:1px solid transparent;font-family:var(--eds-font-inter);font-size:13px;font-weight:500;cursor:pointer;transition:background .12s ease,border-color .12s ease,color .12s ease}.eds-btn:disabled{opacity:.5;cursor:not-allowed}.eds-btn[data-variant=primary]{background:var(--eds-brand-600);color:#fff}.eds-btn[data-variant=primary]:hover:not(:disabled){background:var(--eds-brand-500)}.eds-btn[data-variant=secondary]{background:var(--eds-surface-l0);color:var(--eds-text-primary);border-color:var(--eds-border-default)}.eds-btn[data-variant=secondary]:hover:not(:disabled){background:var(--eds-surface-l1)}.eds-btn[data-variant=ghost]{background:transparent;color:var(--eds-text-secondary)}.eds-btn[data-variant=ghost]:hover:not(:disabled){background:var(--eds-gray-100);color:var(--eds-text-primary)}.eds-btn[data-variant=danger]{background:#f037401a;color:var(--eds-red-500);border-color:#f0374040}.eds-btn[data-variant=positive]{background:#0abf521f;color:var(--eds-green-500);border-color:#0abf5240}\n"] }]
|
|
4074
|
+
}] });
|
|
4075
|
+
|
|
4076
|
+
/*
|
|
4077
|
+
* Public API Surface of @edvak99/voice-receptionist-widget
|
|
4078
|
+
*
|
|
4079
|
+
* Only export host-facing symbols here. Internal pages/services stay private
|
|
4080
|
+
* and are reached via VOICE_RECEPTIONIST_ROUTES / FEATURE_ROUTES.
|
|
4081
|
+
*/
|
|
4082
|
+
// Config & DI
|
|
4083
|
+
|
|
4084
|
+
/**
|
|
4085
|
+
* Generated bundle index. Do not edit.
|
|
4086
|
+
*/
|
|
4087
|
+
|
|
4088
|
+
export { AiReceptionistApiService as A, DashboardSocketService as D, EdsButtonComponent as E, LiveCallsListService as L, ToastService as T, VOICE_RECEPTIONIST_CONFIG as V, WELCOME_MESSAGE_MAX as W, historyResolutionLabel as a, historyResolution as b, callerMetaLine as c, EdsIconComponent as d, ageFromDob as e, resolveToolKey as f, resolveToolDisplayName as g, historyResultChips as h, isUnknownCaller as i, DEFAULT_PAGE_SIZE as j, totalPages as k, EdsBadgeComponent as l, activityTypeLabel as m, initialsFromName as n, VOICE_RECEPTIONIST_SESSION as o, buildAutoWelcomeTemplate as p, resolveWelcomePreview as q, resultChipIcon as r, DEFAULT_PLACEHOLDERS as s, toolEventTrackKey as t, EdsAppShellComponent as u, EdsRouteProgressComponent as v, ToastContainerComponent as w, VOICE_RECEPTIONIST_FEATURE_ROUTES as x, VOICE_RECEPTIONIST_ROUTES as y, provideVoiceReceptionist as z };
|
|
4089
|
+
//# sourceMappingURL=edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-pS2jeB4x.mjs.map
|