@edvak99/voice-receptionist-widget 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-DT9UKvQO.mjs +307 -0
- package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-DT9UKvQO.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-CMhknpGf.mjs → edvak99-voice-receptionist-widget-ai-receptionist-api.service-48cifVPF.mjs} +1351 -579
- package/fesm2022/edvak99-voice-receptionist-widget-ai-receptionist-api.service-48cifVPF.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-C5inEHJw.mjs +278 -0
- package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-C5inEHJw.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-sYhM20CE.mjs +418 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-sYhM20CE.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-DpwajEOE.mjs +194 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-DpwajEOE.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-AN6GcSDq.mjs → edvak99-voice-receptionist-widget-call-recording-player.component-CgkRcFOl.mjs} +5 -4
- package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-AN6GcSDq.mjs.map → edvak99-voice-receptionist-widget-call-recording-player.component-CgkRcFOl.mjs.map} +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-Cy_Bf7AO.mjs → edvak99-voice-receptionist-widget-call-review.service-CIMcjGKX.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-Cy_Bf7AO.mjs.map → edvak99-voice-receptionist-widget-call-review.service-CIMcjGKX.mjs.map} +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-Deh3jPgo.mjs +21 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-Deh3jPgo.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-CxbO0eDS.mjs +440 -0
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-CxbO0eDS.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-eds-elapsed.pipe-ouRlPpwT.mjs → edvak99-voice-receptionist-widget-dashboard-socket.service-BX91r74O.mjs} +5 -21
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-socket.service-BX91r74O.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-CWRiJGfv.mjs +38 -0
- package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-CWRiJGfv.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-eds-button.component-Bg5T5BN8.mjs +27 -0
- package/fesm2022/edvak99-voice-receptionist-widget-eds-button.component-Bg5T5BN8.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-BFCiJOT3.mjs +22 -0
- package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-BFCiJOT3.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-live-calls-list.service-CDtFRW8w.mjs → edvak99-voice-receptionist-widget-eds-pulse-dot.component-BPY6xN7C.mjs} +15 -5
- package/fesm2022/edvak99-voice-receptionist-widget-eds-pulse-dot.component-BPY6xN7C.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-BsBQIS_f.mjs +203 -0
- package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-BsBQIS_f.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-CaSDMxpV.mjs +81 -0
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-CaSDMxpV.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-Cy3ND-c-.mjs +1070 -0
- package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-Cy3ND-c-.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-modal.component-COfi7biN.mjs +48 -0
- package/fesm2022/edvak99-voice-receptionist-widget-modal.component-COfi7biN.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-Bdh4QfFe.mjs +127 -0
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-Bdh4QfFe.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-fHVzpiVk.mjs +268 -0
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-fHVzpiVk.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-Bok64X2q.mjs +968 -0
- package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-Bok64X2q.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-Bb9lPcYi.mjs +317 -0
- package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-Bb9lPcYi.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-CJLa5pia.mjs → edvak99-voice-receptionist-widget-wizard-page.component-BZVlWLWh.mjs} +6 -4
- package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-CJLa5pia.mjs.map → edvak99-voice-receptionist-widget-wizard-page.component-BZVlWLWh.mjs.map} +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget.mjs +1 -1
- package/lib/components/call-conversation-panel/call-conversation-panel.component.d.ts +9 -6
- package/lib/components/call-tasks-panel/call-tasks-panel.component.d.ts +8 -8
- package/lib/components/knowledge-test-modal/knowledge-test-modal.component.d.ts +28 -0
- package/lib/components/live-transcript-panel/live-transcript-panel.component.d.ts +7 -4
- package/lib/components/outbound-dial-modal/outbound-dial-modal.component.d.ts +26 -0
- package/lib/layout/eds-module-nav.component.d.ts +0 -3
- package/lib/mocks/agent-activity.seed.d.ts +2 -0
- package/lib/models/agent-activity.types.d.ts +54 -0
- package/lib/models/ai-receptionist.types.d.ts +26 -0
- package/lib/models/api-dto.types.d.ts +18 -0
- package/lib/models/live-transcript.types.d.ts +2 -1
- package/lib/models/outbound-patient.types.d.ts +23 -0
- package/lib/models/outbound-purpose.types.d.ts +2 -0
- package/lib/models/pagination.d.ts +11 -0
- package/lib/models/staff-media.types.d.ts +36 -0
- package/lib/pages/activities-page/activities-page.component.d.ts +57 -0
- package/lib/pages/analytics-page/analytics-page.component.d.ts +38 -14
- package/lib/pages/call-history-detail-page/call-history-detail-page.component.d.ts +2 -3
- package/lib/pages/call-history-page/call-history-page.component.d.ts +16 -9
- package/lib/pages/dashboard-page/dashboard-page.component.d.ts +12 -8
- package/lib/pages/live-calls-page/live-calls-page.component.d.ts +14 -24
- package/lib/pages/live-monitor-page/live-monitor-page.component.d.ts +34 -1
- package/lib/pages/settings-page/settings-fields.config.d.ts +16 -0
- package/lib/pages/settings-page/settings-page.component.d.ts +48 -14
- package/lib/pages/tasks-page/tasks-page.component.d.ts +6 -0
- package/lib/services/ai-receptionist-api.mock.d.ts +44 -9
- package/lib/services/ai-receptionist-api.service.d.ts +65 -10
- package/lib/services/live-transcript.service.d.ts +1 -0
- package/lib/services/staff-media.service.d.ts +52 -0
- package/lib/ui/eds-avatar.component.d.ts +5 -2
- package/lib/ui/eds-button.component.d.ts +1 -1
- package/lib/utils/call-history-display.util.d.ts +21 -0
- package/lib/utils/outbound-purpose.util.d.ts +19 -0
- package/lib/utils/transcript-timing.util.d.ts +1 -1
- package/lib/utils/welcome-message.util.d.ts +1 -1
- package/package.json +2 -1
- package/styles/_index.scss +5 -40
- package/styles/chat-ui.scss +18 -18
- package/styles/eds.scss +188 -119
- package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-CW5OKmik.mjs +0 -113
- package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-CW5OKmik.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-DL1GfQyF.mjs +0 -35
- package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-DL1GfQyF.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-CTwfUHUf.mjs +0 -316
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-CTwfUHUf.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-Cj4wxd4e.mjs +0 -138
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-Cj4wxd4e.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-DQLIw7xb.mjs +0 -70
- package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-DQLIw7xb.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-DzdIt2A7.mjs +0 -248
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-DzdIt2A7.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-PCnIWeOA.mjs +0 -27
- package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-PCnIWeOA.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-ouRlPpwT.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-CMhknpGf.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-knowledge-hub.page-cZqBuull.mjs +0 -575
- package/fesm2022/edvak99-voice-receptionist-widget-knowledge-hub.page-cZqBuull.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-list.service-CDtFRW8w.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-DrYzXJQW.mjs +0 -115
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-DrYzXJQW.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-D7dlk0y2.mjs +0 -574
- package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-D7dlk0y2.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-BQECIuJu.mjs +0 -54
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-BQECIuJu.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-CJ8NEjcj.mjs +0 -265
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-CJ8NEjcj.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-Bo3XNK3b.mjs +0 -509
- package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-Bo3XNK3b.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs +0 -52
- package/fesm2022/edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-CBwl15NP.mjs +0 -237
- package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-CBwl15NP.mjs.map +0 -1
- package/lib/knowledge/components/faq-empty-state/faq-empty-state.component.d.ts +0 -22
- package/lib/knowledge/components/faq-form/faq-form.component.d.ts +0 -27
- package/lib/knowledge/components/faq-search-tester/faq-search-tester.component.d.ts +0 -17
- package/lib/knowledge/mocks/practice-faq.seed.d.ts +0 -2
- package/lib/knowledge/models/practice-faq.model.d.ts +0 -47
- package/lib/knowledge/pages/knowledge-hub.page.d.ts +0 -47
- package/lib/knowledge/services/practice-faq-api.mock.d.ts +0 -16
- package/lib/knowledge/services/practice-faq-api.service.d.ts +0 -22
- package/lib/knowledge/utils/faq.util.d.ts +0 -3
- package/lib/layout/eds-topbar.component.d.ts +0 -29
- package/lib/pages/audit-page/audit-page.component.d.ts +0 -14
- package/lib/ui/eds-waveform.component.d.ts +0 -8
package/styles/eds.scss
CHANGED
|
@@ -1,163 +1,221 @@
|
|
|
1
|
-
/* EDS Design System — AI Receptionist
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/* EDS Design System — AI Receptionist
|
|
2
|
+
*
|
|
3
|
+
* Tokens are scoped to eds-app-shell / .voice-receptionist-host only.
|
|
4
|
+
* Never set unprefixed --color-primary / --gray-* / --text-primary on :root —
|
|
5
|
+
* those collide with host apps (e.g. EHR Tailwind hsl(var(--color-primary))).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
eds-app-shell,
|
|
9
|
+
.voice-receptionist-host {
|
|
4
10
|
/* Brand */
|
|
5
|
-
--brand-500: #
|
|
6
|
-
--brand-600: #2162f0;
|
|
7
|
-
--
|
|
8
|
-
--
|
|
9
|
-
--
|
|
10
|
-
--
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
--
|
|
14
|
-
--
|
|
15
|
-
--
|
|
16
|
-
--
|
|
17
|
-
--
|
|
18
|
-
--
|
|
19
|
-
--
|
|
20
|
-
--
|
|
21
|
-
--
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
--
|
|
25
|
-
--
|
|
26
|
-
--
|
|
27
|
-
--
|
|
28
|
-
--
|
|
29
|
-
--
|
|
30
|
-
--
|
|
31
|
-
--
|
|
32
|
-
--
|
|
33
|
-
--
|
|
34
|
-
--
|
|
35
|
-
--
|
|
36
|
-
--
|
|
37
|
-
--
|
|
38
|
-
--
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
--
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
--
|
|
45
|
-
--
|
|
46
|
-
--
|
|
47
|
-
--
|
|
48
|
-
--
|
|
49
|
-
--
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
--surface-
|
|
53
|
-
--
|
|
54
|
-
--
|
|
55
|
-
--text
|
|
56
|
-
--text-
|
|
57
|
-
--text-
|
|
58
|
-
--border
|
|
59
|
-
--
|
|
60
|
-
|
|
61
|
-
|
|
11
|
+
--eds-brand-500: #2162f0;
|
|
12
|
+
--eds-brand-600: #2162f0;
|
|
13
|
+
--eds-brand-400: #4b82f3;
|
|
14
|
+
--eds-brand-300: #8aaff8;
|
|
15
|
+
--eds-brand: var(--eds-brand-600);
|
|
16
|
+
--eds-violet-500: #8e51ff;
|
|
17
|
+
--eds-violet-400: #a684ff;
|
|
18
|
+
--eds-green-500: #0abf52;
|
|
19
|
+
--eds-green-400: #34d399;
|
|
20
|
+
--eds-green-600: #16a34a;
|
|
21
|
+
--eds-red-500: #f03740;
|
|
22
|
+
--eds-red-400: #f87171;
|
|
23
|
+
--eds-red-300: #fca5a5;
|
|
24
|
+
--eds-amber-500: #f59e0b;
|
|
25
|
+
--eds-amber-400: #ffb900;
|
|
26
|
+
--eds-amber-300: #fcd34d;
|
|
27
|
+
--eds-purple-300: #c4b5fd;
|
|
28
|
+
|
|
29
|
+
/* Gray / slate */
|
|
30
|
+
--eds-gray-50: #f7f9fa;
|
|
31
|
+
--eds-gray-100: #f7f9fa;
|
|
32
|
+
--eds-gray-200: #e5e5e5;
|
|
33
|
+
--eds-gray-300: #d4d4d8;
|
|
34
|
+
--eds-gray-400: #a1a1aa;
|
|
35
|
+
--eds-gray-500: #767676;
|
|
36
|
+
--eds-gray-600: #53575c;
|
|
37
|
+
--eds-gray-700: #41464c;
|
|
38
|
+
--eds-gray-800: #2f3338;
|
|
39
|
+
--eds-gray-900: #1f2328;
|
|
40
|
+
--eds-slate-950: #030717;
|
|
41
|
+
--eds-slate-900: #121828;
|
|
42
|
+
--eds-slate-800: #212a39;
|
|
43
|
+
--eds-slate-700: #384251;
|
|
44
|
+
--eds-slate-600: #4e5763;
|
|
45
|
+
--eds-slate-500: #63748b;
|
|
46
|
+
--eds-slate-400: #99a2b0;
|
|
47
|
+
--eds-slate-300: #cad5e2;
|
|
48
|
+
|
|
49
|
+
/* App color tokens (legacy names → eds-prefixed) */
|
|
50
|
+
--eds-color-primary: #2162f0;
|
|
51
|
+
--eds-color-primary-hover: #1a52d4;
|
|
52
|
+
--eds-color-primary-light: #eaf1fe;
|
|
53
|
+
--eds-color-primary-soft: var(--eds-color-primary-light);
|
|
54
|
+
--eds-color-accent: #4b82f3;
|
|
55
|
+
--eds-color-accent-light: #dce8fd;
|
|
56
|
+
--eds-color-bg: #f7f9fa;
|
|
57
|
+
--eds-color-surface: #ffffff;
|
|
58
|
+
--eds-color-surface-alt: #f7f9fa;
|
|
59
|
+
--eds-color-sidebar-bg: #0f172a;
|
|
60
|
+
--eds-color-chat-ai: #f1f5f9;
|
|
61
|
+
--eds-color-text: #41464c;
|
|
62
|
+
--eds-color-text-muted: #53575c;
|
|
63
|
+
--eds-color-text-soft: #767676;
|
|
64
|
+
--eds-color-border: #e5e5e5;
|
|
65
|
+
--eds-color-border-strong: #d4d4d8;
|
|
66
|
+
--eds-color-success: #22c55e;
|
|
67
|
+
--eds-color-success-soft: #ecfdf3;
|
|
68
|
+
--eds-color-warning: #f59e0b;
|
|
69
|
+
--eds-color-warning-soft: #fffbeb;
|
|
70
|
+
--eds-color-danger: #ef4444;
|
|
71
|
+
--eds-color-danger-soft: #fef2f2;
|
|
72
|
+
--eds-color-info: #2162f0;
|
|
73
|
+
--eds-color-info-soft: #eaf1fe;
|
|
74
|
+
|
|
75
|
+
/* Surfaces / text / borders — product palette */
|
|
76
|
+
--eds-surface-l0: #ffffff; /* Primary BG */
|
|
77
|
+
--eds-surface-l1: #f7f9fa; /* Secondary BG */
|
|
78
|
+
--eds-surface-l2: #f7f9fa;
|
|
79
|
+
--eds-surface-card: var(--eds-surface-l0);
|
|
80
|
+
--eds-surface-muted: var(--eds-surface-l1);
|
|
81
|
+
--eds-surface-hover: var(--eds-surface-l1);
|
|
82
|
+
--eds-text-primary: #41464c;
|
|
83
|
+
--eds-text-secondary: #53575c;
|
|
84
|
+
--eds-text-tertiary: #767676;
|
|
85
|
+
--eds-text-brand: #2162f0;
|
|
86
|
+
--eds-border-default: #e5e5e5;
|
|
87
|
+
--eds-border-subtle: #e5e5e5;
|
|
88
|
+
--eds-bg-brand: #2162f0;
|
|
89
|
+
|
|
90
|
+
/* Radius / space / shadow */
|
|
62
91
|
--eds-radius-sm: 4px;
|
|
63
92
|
--eds-radius-md: 6px;
|
|
64
93
|
--eds-radius-lg: 8px;
|
|
65
|
-
|
|
66
|
-
|
|
94
|
+
--eds-radius-xl: 16px;
|
|
95
|
+
--eds-radius-pill: 999px;
|
|
96
|
+
--eds-space-sm: 16px;
|
|
97
|
+
--eds-space-md: 24px;
|
|
98
|
+
--eds-space-lg: 32px;
|
|
99
|
+
--eds-space-4: 16px;
|
|
100
|
+
--eds-space-5: 20px;
|
|
67
101
|
--eds-shadow-sm: 0 1px 2px rgba(17, 24, 39, 0.04);
|
|
68
102
|
--eds-shadow-md: 0 2px 8px rgba(17, 24, 39, 0.06);
|
|
103
|
+
--eds-shadow-card: 0 2px 6px rgba(0, 0, 0, 0.05);
|
|
104
|
+
--eds-shadow-modal: 0 6px 16px rgba(0, 0, 0, 0.08);
|
|
69
105
|
|
|
70
106
|
/* Layout */
|
|
71
107
|
--eds-rail-width: 64px;
|
|
72
108
|
--eds-nav-width: 244px;
|
|
73
|
-
--eds-topbar-height:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
--font-
|
|
79
|
-
--font-
|
|
109
|
+
--eds-topbar-height: 0px;
|
|
110
|
+
--eds-sidebar-width: 240px;
|
|
111
|
+
--eds-monitor-text: var(--eds-text-primary);
|
|
112
|
+
|
|
113
|
+
/* Fonts — Inter only (EHR dashboard parity; no DM Sans / Figtree) */
|
|
114
|
+
--eds-font-inter: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
115
|
+
--eds-font-dm: var(--eds-font-inter);
|
|
116
|
+
--eds-font-figtree: var(--eds-font-inter);
|
|
117
|
+
--eds-font-mono: 'IBM Plex Mono', ui-monospace, monospace;
|
|
118
|
+
--eds-font-sans: var(--eds-font-inter);
|
|
119
|
+
--eds-font-body: var(--eds-font-inter);
|
|
120
|
+
--eds-font-display: var(--eds-font-inter);
|
|
121
|
+
|
|
122
|
+
/* Type scale — match EHR Tailwind utilities */
|
|
123
|
+
--eds-font-size-xs: 10px; /* fs-xs */
|
|
124
|
+
--eds-font-size-sm: 12px; /* fs-sm */
|
|
125
|
+
--eds-font-size-base: 13px; /* fs-base */
|
|
126
|
+
--eds-font-size-md: 15px; /* fs-md */
|
|
127
|
+
--eds-font-size-lg: 18px;
|
|
128
|
+
--eds-font-size-xl: 24px;
|
|
129
|
+
--eds-font-weight-regular: 400;
|
|
130
|
+
--eds-font-weight-medium: 500;
|
|
131
|
+
--eds-font-weight-semibold: 600;
|
|
132
|
+
--eds-font-weight-bold: 700;
|
|
133
|
+
/* EHR table-default header muted */
|
|
134
|
+
--eds-text-table-header: #4d5573;
|
|
80
135
|
}
|
|
81
136
|
|
|
82
|
-
/* Typography */
|
|
137
|
+
/* Typography — EHR weight scale: body 400, medium 500, semibold 600, bold 700 */
|
|
83
138
|
.eds-h1 {
|
|
84
|
-
font-family: var(--font-inter);
|
|
85
|
-
font-size:
|
|
86
|
-
font-weight:
|
|
139
|
+
font-family: var(--eds-font-inter);
|
|
140
|
+
font-size: var(--eds-font-size-xl);
|
|
141
|
+
font-weight: var(--eds-font-weight-bold);
|
|
87
142
|
letter-spacing: -0.02em;
|
|
88
|
-
color: var(--text-primary);
|
|
143
|
+
color: var(--eds-text-primary);
|
|
89
144
|
margin: 0;
|
|
90
145
|
}
|
|
91
146
|
|
|
92
147
|
.eds-h2 {
|
|
93
|
-
font-family: var(--font-inter);
|
|
94
|
-
font-size:
|
|
95
|
-
font-weight:
|
|
148
|
+
font-family: var(--eds-font-inter);
|
|
149
|
+
font-size: var(--eds-font-size-lg);
|
|
150
|
+
font-weight: var(--eds-font-weight-bold);
|
|
96
151
|
letter-spacing: -0.01em;
|
|
97
|
-
color: var(--text-primary);
|
|
152
|
+
color: var(--eds-text-primary);
|
|
98
153
|
margin: 0;
|
|
99
154
|
}
|
|
100
155
|
|
|
101
156
|
.eds-h3 {
|
|
102
|
-
font-family: var(--font-inter);
|
|
103
|
-
font-size:
|
|
104
|
-
font-weight:
|
|
105
|
-
color: var(--text-primary);
|
|
157
|
+
font-family: var(--eds-font-inter);
|
|
158
|
+
font-size: var(--eds-font-size-md);
|
|
159
|
+
font-weight: var(--eds-font-weight-semibold);
|
|
160
|
+
color: var(--eds-text-primary);
|
|
106
161
|
margin: 0;
|
|
107
162
|
}
|
|
108
163
|
|
|
109
164
|
.eds-h4 {
|
|
110
|
-
font-family: var(--font-inter);
|
|
111
|
-
font-size:
|
|
112
|
-
font-weight:
|
|
113
|
-
color: var(--text-primary);
|
|
165
|
+
font-family: var(--eds-font-inter);
|
|
166
|
+
font-size: var(--eds-font-size-base);
|
|
167
|
+
font-weight: var(--eds-font-weight-semibold);
|
|
168
|
+
color: var(--eds-text-primary);
|
|
114
169
|
margin: 0;
|
|
115
170
|
}
|
|
116
171
|
|
|
117
172
|
.eds-body {
|
|
118
|
-
font-family: var(--font-
|
|
119
|
-
font-size:
|
|
173
|
+
font-family: var(--eds-font-inter);
|
|
174
|
+
font-size: var(--eds-font-size-base);
|
|
175
|
+
font-weight: var(--eds-font-weight-regular);
|
|
120
176
|
line-height: 1.5;
|
|
121
|
-
color: var(--text-primary);
|
|
177
|
+
color: var(--eds-text-primary);
|
|
122
178
|
}
|
|
123
179
|
|
|
124
180
|
.eds-body-bold {
|
|
125
181
|
@extend .eds-body;
|
|
126
|
-
font-weight:
|
|
182
|
+
font-weight: var(--eds-font-weight-semibold);
|
|
127
183
|
}
|
|
128
184
|
|
|
129
185
|
.eds-body-sm {
|
|
130
|
-
font-family: var(--font-
|
|
131
|
-
font-size:
|
|
186
|
+
font-family: var(--eds-font-inter);
|
|
187
|
+
font-size: var(--eds-font-size-sm);
|
|
188
|
+
font-weight: var(--eds-font-weight-regular);
|
|
132
189
|
line-height: 1.45;
|
|
133
|
-
color: var(--text-secondary);
|
|
190
|
+
color: var(--eds-text-secondary);
|
|
134
191
|
}
|
|
135
192
|
|
|
136
193
|
.eds-body-sm-bold {
|
|
137
194
|
@extend .eds-body-sm;
|
|
138
|
-
font-weight:
|
|
139
|
-
color: var(--text-primary);
|
|
195
|
+
font-weight: var(--eds-font-weight-semibold);
|
|
196
|
+
color: var(--eds-text-primary);
|
|
140
197
|
}
|
|
141
198
|
|
|
142
199
|
.eds-mono {
|
|
143
|
-
font-family: var(--font-mono);
|
|
144
|
-
font-size:
|
|
145
|
-
color: var(--text-secondary);
|
|
200
|
+
font-family: var(--eds-font-mono);
|
|
201
|
+
font-size: var(--eds-font-size-base);
|
|
202
|
+
color: var(--eds-text-secondary);
|
|
146
203
|
}
|
|
147
204
|
|
|
148
205
|
.eds-mono-sm {
|
|
149
|
-
font-family: var(--font-mono);
|
|
150
|
-
font-size:
|
|
151
|
-
color: var(--text-secondary);
|
|
206
|
+
font-family: var(--eds-font-mono);
|
|
207
|
+
font-size: var(--eds-font-size-sm);
|
|
208
|
+
color: var(--eds-text-secondary);
|
|
152
209
|
}
|
|
153
210
|
|
|
211
|
+
/* Section / field labels — EHR table-default style (not 11px uppercase) */
|
|
154
212
|
.eds-label {
|
|
155
|
-
font-family: var(--font-inter);
|
|
156
|
-
font-size:
|
|
157
|
-
font-weight:
|
|
158
|
-
letter-spacing:
|
|
159
|
-
text-transform:
|
|
160
|
-
color: var(--
|
|
213
|
+
font-family: var(--eds-font-inter);
|
|
214
|
+
font-size: var(--eds-font-size-base);
|
|
215
|
+
font-weight: var(--eds-font-weight-semibold);
|
|
216
|
+
letter-spacing: normal;
|
|
217
|
+
text-transform: none;
|
|
218
|
+
color: var(--eds-text-table-header, #4d5573);
|
|
161
219
|
}
|
|
162
220
|
|
|
163
221
|
.eds-icon {
|
|
@@ -277,17 +335,21 @@
|
|
|
277
335
|
}
|
|
278
336
|
|
|
279
337
|
.eds-gradient-brand {
|
|
280
|
-
background: linear-gradient(135deg, var(--brand-500), var(--violet-500));
|
|
338
|
+
background: linear-gradient(135deg, var(--eds-brand-500), var(--eds-violet-500));
|
|
281
339
|
}
|
|
282
340
|
|
|
283
341
|
.eds-page {
|
|
284
342
|
min-height: calc(100vh - var(--eds-topbar-height));
|
|
285
|
-
background: var(--surface-l1);
|
|
343
|
+
background: var(--eds-surface-l1);
|
|
286
344
|
padding: 24px;
|
|
345
|
+
font-family: var(--eds-font-inter);
|
|
346
|
+
font-size: var(--eds-font-size-base, 13px);
|
|
347
|
+
font-weight: var(--eds-font-weight-regular, 400);
|
|
348
|
+
color: var(--eds-text-primary);
|
|
287
349
|
}
|
|
288
350
|
|
|
289
351
|
.eds-page--dark {
|
|
290
|
-
background: var(--slate-950);
|
|
352
|
+
background: var(--eds-slate-950);
|
|
291
353
|
color: #e4e4e7;
|
|
292
354
|
}
|
|
293
355
|
|
|
@@ -296,28 +358,35 @@
|
|
|
296
358
|
border-collapse: collapse;
|
|
297
359
|
|
|
298
360
|
thead th {
|
|
299
|
-
|
|
361
|
+
font-family: var(--eds-font-inter);
|
|
362
|
+
font-size: var(--eds-font-size-base, 13px);
|
|
363
|
+
font-weight: var(--eds-font-weight-semibold, 600);
|
|
364
|
+
letter-spacing: normal;
|
|
365
|
+
text-transform: none;
|
|
366
|
+
color: var(--eds-text-table-header, #4d5573);
|
|
300
367
|
text-align: left;
|
|
301
368
|
padding: 10px 16px;
|
|
302
|
-
border-bottom: 1px solid var(--border-default);
|
|
303
|
-
background: var(--surface-l0);
|
|
369
|
+
border-bottom: 1px solid var(--eds-border-default);
|
|
370
|
+
background: var(--eds-surface-l0);
|
|
304
371
|
}
|
|
305
372
|
|
|
306
373
|
tbody td {
|
|
307
374
|
padding: 12px 16px;
|
|
308
|
-
font-
|
|
309
|
-
|
|
310
|
-
|
|
375
|
+
font-family: var(--eds-font-inter);
|
|
376
|
+
font-size: var(--eds-font-size-base, 13px);
|
|
377
|
+
font-weight: var(--eds-font-weight-regular, 400);
|
|
378
|
+
color: var(--eds-text-primary);
|
|
379
|
+
border-bottom: 1px solid var(--eds-border-default);
|
|
311
380
|
}
|
|
312
381
|
|
|
313
382
|
tbody tr:hover td {
|
|
314
|
-
background: var(--surface-l1);
|
|
383
|
+
background: var(--eds-surface-l1);
|
|
315
384
|
}
|
|
316
385
|
}
|
|
317
386
|
|
|
318
387
|
.eds-card {
|
|
319
|
-
background: var(--surface-l0);
|
|
320
|
-
border: 1px solid var(--border-default);
|
|
388
|
+
background: var(--eds-surface-l0);
|
|
389
|
+
border: 1px solid var(--eds-border-default);
|
|
321
390
|
border-radius: var(--eds-radius-lg);
|
|
322
391
|
box-shadow: var(--eds-shadow-sm);
|
|
323
392
|
transition: box-shadow 150ms ease;
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, signal, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
-
import { A as AiReceptionistApiService, b as EdsIconComponent } from './edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-CMhknpGf.mjs';
|
|
4
|
-
|
|
5
|
-
class AnalyticsPageComponent {
|
|
6
|
-
constructor() {
|
|
7
|
-
this.api = inject(AiReceptionistApiService);
|
|
8
|
-
this.data = signal(null);
|
|
9
|
-
this.range = signal('30d');
|
|
10
|
-
this.loading = signal(true);
|
|
11
|
-
this.ranges = [
|
|
12
|
-
{ id: '7d', label: '7 days' },
|
|
13
|
-
{ id: '30d', label: '30 days' },
|
|
14
|
-
{ id: '90d', label: '90 days' },
|
|
15
|
-
];
|
|
16
|
-
}
|
|
17
|
-
ngOnInit() {
|
|
18
|
-
this.load();
|
|
19
|
-
}
|
|
20
|
-
setRange(id) {
|
|
21
|
-
this.range.set(id);
|
|
22
|
-
this.load();
|
|
23
|
-
}
|
|
24
|
-
maxCount(items) {
|
|
25
|
-
return Math.max(...items.map((i) => i.count), 1);
|
|
26
|
-
}
|
|
27
|
-
barHeightPercent(point, points) {
|
|
28
|
-
if (point.count <= 0)
|
|
29
|
-
return 0;
|
|
30
|
-
return (point.count / this.maxCount(points)) * 100;
|
|
31
|
-
}
|
|
32
|
-
/** Hide inline counts when bars are too narrow to stay readable. */
|
|
33
|
-
showBarValue(point, points) {
|
|
34
|
-
return point.count > 0 && points.length <= 21;
|
|
35
|
-
}
|
|
36
|
-
maxValue(items) {
|
|
37
|
-
return Math.max(...items.map((i) => i.value), 1);
|
|
38
|
-
}
|
|
39
|
-
volumeTooltip(point) {
|
|
40
|
-
const datePart = point.date ? this.formatChartDate(point.date) : point.label;
|
|
41
|
-
return `${datePart}: ${point.count} call${point.count === 1 ? '' : 's'}`;
|
|
42
|
-
}
|
|
43
|
-
peakTooltip(point) {
|
|
44
|
-
return `${point.label}: ${point.count} call${point.count === 1 ? '' : 's'}`;
|
|
45
|
-
}
|
|
46
|
-
/** ISO or YYYY-MM-DD → MM/DD (zero-padded). */
|
|
47
|
-
formatChartDate(date) {
|
|
48
|
-
const iso = /^(\d{4})-(\d{2})-(\d{2})/.exec(date.trim());
|
|
49
|
-
if (iso) {
|
|
50
|
-
return `${iso[2]}/${iso[3]}`;
|
|
51
|
-
}
|
|
52
|
-
return date;
|
|
53
|
-
}
|
|
54
|
-
/** Compact x-axis for volume — full labels on 7d, sparse dates on longer ranges. */
|
|
55
|
-
volumeAxisLabel(point, index, total) {
|
|
56
|
-
if (point.date) {
|
|
57
|
-
if (total <= 7)
|
|
58
|
-
return this.formatChartDate(point.date);
|
|
59
|
-
const step = total <= 14 ? 2 : total <= 31 ? 5 : 7;
|
|
60
|
-
if (index % step !== 0 && index !== total - 1)
|
|
61
|
-
return '';
|
|
62
|
-
return this.formatChartDate(point.date);
|
|
63
|
-
}
|
|
64
|
-
if (total <= 7)
|
|
65
|
-
return point.day;
|
|
66
|
-
const step = total <= 14 ? 2 : total <= 31 ? 5 : 7;
|
|
67
|
-
if (index % step !== 0 && index !== total - 1)
|
|
68
|
-
return '';
|
|
69
|
-
return point.day;
|
|
70
|
-
}
|
|
71
|
-
showPeakAxisLabel(index, total) {
|
|
72
|
-
if (total <= 12)
|
|
73
|
-
return true;
|
|
74
|
-
const step = total <= 24 ? 3 : 4;
|
|
75
|
-
return index % step === 0 || index === total - 1;
|
|
76
|
-
}
|
|
77
|
-
volumeRangeLabel() {
|
|
78
|
-
const vol = this.data()?.volume;
|
|
79
|
-
if (!vol?.startDate || !vol?.endDate)
|
|
80
|
-
return 'Calls per day';
|
|
81
|
-
const start = this.formatChartDate(vol.startDate);
|
|
82
|
-
const end = this.formatChartDate(vol.endDate);
|
|
83
|
-
return `${start} – ${end}${vol.timezone ? ` (${vol.timezone})` : ''}`;
|
|
84
|
-
}
|
|
85
|
-
kpiIcon(label) {
|
|
86
|
-
const key = label.toLowerCase();
|
|
87
|
-
if (key.includes('call') || key.includes('handled'))
|
|
88
|
-
return 'call';
|
|
89
|
-
if (key.includes('time') || key.includes('duration'))
|
|
90
|
-
return 'schedule';
|
|
91
|
-
if (key.includes('resolution') || key.includes('book'))
|
|
92
|
-
return 'event_available';
|
|
93
|
-
if (key.includes('transfer'))
|
|
94
|
-
return 'phone_forwarded';
|
|
95
|
-
return 'monitoring';
|
|
96
|
-
}
|
|
97
|
-
load() {
|
|
98
|
-
this.loading.set(true);
|
|
99
|
-
this.api.getAnalytics(this.range()).subscribe(({ data }) => {
|
|
100
|
-
this.data.set(data);
|
|
101
|
-
this.loading.set(false);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: AnalyticsPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
105
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: AnalyticsPageComponent, isStandalone: true, selector: "eds-analytics-page", ngImport: i0, template: "<div class=\"eds-page analytics-page\">\n <header class=\"analytics-page__header\">\n <div>\n <h1 class=\"eds-h1\">Analytics</h1>\n <p class=\"eds-body-sm\">Call volume, outcomes, and performance KPIs</p>\n </div>\n <div class=\"analytics-page__range\">\n @for (r of ranges; track r.id) {\n <button\n type=\"button\"\n class=\"analytics-page__range-btn\"\n [class.analytics-page__range-btn--active]=\"range() === r.id\"\n (click)=\"setRange(r.id)\"\n >\n {{ r.label }}\n </button>\n }\n </div>\n </header>\n\n @if (loading()) {\n <p class=\"eds-body-sm\">Loading analytics\u2026</p>\n } @else if (data()) {\n <section class=\"analytics-page__kpis\">\n @for (kpi of data()!.kpiCards; track kpi.label) {\n <article class=\"eds-card analytics-page__kpi\">\n <eds-icon [name]=\"kpiIcon(kpi.label)\" [size]=\"22\" />\n <span class=\"eds-label\">{{ kpi.label }}</span>\n <span class=\"analytics-page__kpi-value\">{{ kpi.value }}</span>\n @if (kpi.delta) {\n <span class=\"analytics-page__kpi-delta\" [attr.data-tone]=\"kpi.tone\">{{ kpi.delta }}</span>\n }\n @if (kpi.sub) {\n <span class=\"analytics-page__kpi-sub\">{{ kpi.sub }}</span>\n }\n </article>\n }\n </section>\n\n <div class=\"analytics-page__charts\">\n <article class=\"eds-card analytics-page__chart\">\n <div class=\"analytics-page__chart-head\">\n <h2 class=\"eds-h2\">Call volume</h2>\n <span class=\"eds-label\">{{ volumeRangeLabel() }}</span>\n </div>\n <div class=\"analytics-page__volume-chart\">\n <div class=\"analytics-page__plot\">\n <div class=\"analytics-page__grid\" aria-hidden=\"true\"></div>\n <div class=\"analytics-page__bars\" role=\"list\" aria-label=\"Call volume by day\">\n @for (point of data()!.volume.points; track point.date || point.label; let i = $index) {\n <div\n class=\"analytics-page__bar-col\"\n role=\"listitem\"\n [attr.aria-label]=\"volumeTooltip(point)\"\n >\n <div class=\"analytics-page__bar-wrap\">\n @if (point.count > 0) {\n <div\n class=\"analytics-page__bar-stack\"\n [style.height.%]=\"barHeightPercent(point, data()!.volume.points)\"\n >\n @if (showBarValue(point, data()!.volume.points)) {\n <span class=\"analytics-page__bar-value eds-mono-sm\">{{ point.count }}</span>\n }\n <div class=\"analytics-page__bar\"></div>\n </div>\n }\n <span class=\"analytics-page__tooltip\">{{ volumeTooltip(point) }}</span>\n </div>\n <span class=\"eds-mono-sm analytics-page__bar-axis\">\n {{ volumeAxisLabel(point, i, data()!.volume.points.length) }}\n </span>\n </div>\n }\n </div>\n </div>\n </div>\n <!-- <p class=\"analytics-page__axis-note eds-label\">(MM/DD)/calls per day</p> -->\n </article>\n\n <article class=\"eds-card analytics-page__chart\">\n <h2 class=\"eds-h2\">Outcomes</h2>\n <div class=\"analytics-page__bars analytics-page__bars--horizontal\">\n @for (item of data()!.outcomes; track item.label) {\n <div class=\"analytics-page__hbar-row\">\n <span class=\"eds-body-sm\">{{ item.label }}</span>\n <div class=\"analytics-page__hbar-track\">\n <span\n class=\"analytics-page__hbar-fill\"\n [style.width.%]=\"(item.value / maxValue(data()!.outcomes)) * 100\"\n [style.background]=\"item.color\"\n ></span>\n </div>\n <span class=\"eds-mono-sm\">{{ item.value }}%</span>\n </div>\n }\n </div>\n </article>\n\n <article class=\"eds-card analytics-page__chart\">\n <h2 class=\"eds-h2\">Top reasons</h2>\n <div class=\"analytics-page__bars analytics-page__bars--horizontal\">\n @for (item of data()!.reasons; track item.label) {\n <div class=\"analytics-page__hbar-row\">\n <span class=\"eds-body-sm\">{{ item.label }}</span>\n <div class=\"analytics-page__hbar-track\">\n <span\n class=\"analytics-page__hbar-fill\"\n [style.width.%]=\"(item.value / maxValue(data()!.reasons)) * 100\"\n ></span>\n </div>\n <span class=\"eds-mono-sm\">{{ item.value }}%</span>\n </div>\n }\n </div>\n </article>\n\n <article class=\"eds-card analytics-page__chart\">\n <div class=\"analytics-page__chart-head\">\n <h2 class=\"eds-h2\">Peak hours</h2>\n <span class=\"eds-label\">\n @if (data()!.peakHours.timezone) {\n {{ data()!.peakHours.timezone }}\n } @else {\n Calls per hour\n }\n </span>\n </div>\n <div class=\"analytics-page__volume-chart analytics-page__volume-chart--peak\">\n <div class=\"analytics-page__plot\">\n <div class=\"analytics-page__grid\" aria-hidden=\"true\"></div>\n <div class=\"analytics-page__bars analytics-page__bars--peak\" role=\"list\" aria-label=\"Call volume by hour\">\n @for (point of data()!.peakHours.points; track point.hour) {\n <div\n class=\"analytics-page__bar-col analytics-page__bar-col--peak\"\n role=\"listitem\"\n [attr.aria-label]=\"peakTooltip(point)\"\n >\n <div class=\"analytics-page__bar-wrap\">\n @if (point.count > 0) {\n <div\n class=\"analytics-page__bar-stack\"\n [style.height.%]=\"barHeightPercent(point, data()!.peakHours.points)\"\n >\n <div class=\"analytics-page__bar\"></div>\n </div>\n }\n <span class=\"analytics-page__tooltip\">{{ peakTooltip(point) }}</span>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n <div class=\"analytics-page__peak-axis\">\n @for (point of data()!.peakHours.points; track point.hour; let i = $index) {\n <span class=\"analytics-page__peak-tick eds-mono-sm\">\n @if (showPeakAxisLabel(i, data()!.peakHours.points.length)) {\n {{ point.label }}\n }\n </span>\n }\n </div>\n </article>\n </div>\n }\n</div>\n", styles: [".analytics-page__header{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:20px}.analytics-page__range{display:flex;gap:4px;background:var(--surface-l0);border:1px solid var(--border-default);border-radius:var(--eds-radius-md);padding:4px}.analytics-page__range-btn{padding:6px 12px;border:none;background:none;font-size:13px;border-radius:var(--eds-radius-sm);cursor:pointer;color:var(--text-secondary)}.analytics-page__range-btn--active{background:var(--brand-500);color:#fff}.analytics-page__kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:20px}.analytics-page__kpi{display:flex;flex-direction:column;gap:6px;padding:16px}.analytics-page__kpi-value{font-size:24px;font-weight:600;color:var(--text-primary)}.analytics-page__kpi-delta{font-size:12px;font-weight:600}.analytics-page__kpi-delta[data-tone=pos]{color:var(--green-500, #16a34a)}.analytics-page__kpi-delta[data-tone=warn]{color:var(--amber-500, #d97706)}.analytics-page__kpi-delta[data-tone=neutral]{color:var(--text-secondary)}.analytics-page__kpi-sub{font-size:12px;color:var(--text-secondary)}.analytics-page__charts{display:grid;grid-template-columns:1fr 1fr;gap:16px}.analytics-page__chart{padding:16px}.analytics-page__chart .eds-h2{margin-bottom:0}.analytics-page__chart-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:16px;flex-wrap:wrap}.analytics-page__volume-chart--peak .analytics-page__grid{inset:0}.analytics-page__plot{position:relative;width:100%;min-width:0}.analytics-page__grid{position:absolute;inset:0 0 24px;pointer-events:none;background-image:linear-gradient(to top,var(--border-default) 1px,transparent 1px);background-size:100% 25%;opacity:.45}.analytics-page__bars{display:flex;align-items:flex-end;justify-content:space-between;gap:8px;height:160px;position:relative;z-index:1}.analytics-page__bars--horizontal{flex-direction:column;height:auto;align-items:stretch;gap:10px}.analytics-page__bars--peak{height:100px}.analytics-page__bars--peak .analytics-page__bar{max-width:100%}.analytics-page__bar-col{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;height:100%;min-width:0;cursor:default}.analytics-page__bar-col:hover .analytics-page__tooltip,.analytics-page__bar-col:focus-within .analytics-page__tooltip{opacity:1}.analytics-page__bar-col--peak{min-width:0}.analytics-page__bar-value{flex-shrink:0;color:var(--text-primary);font-size:11px;font-weight:600;line-height:1}.analytics-page__bar-wrap{position:relative;width:100%;flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;min-height:0}.analytics-page__bar-stack{width:100%;max-width:32px;display:flex;flex-direction:column;justify-content:flex-end;align-items:stretch;gap:4px;min-height:0}.analytics-page__bar-axis{flex-shrink:0;min-height:16px;color:var(--text-secondary);font-size:10px;text-align:center;line-height:1.2}.analytics-page__tooltip{position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%);padding:4px 8px;background:var(--gray-900, #18181b);color:#fafafa;font-size:11px;font-weight:500;line-height:1.3;border-radius:4px;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s ease;z-index:2;box-shadow:0 2px 8px #00000026}.analytics-page__tooltip:after{content:\"\";position:absolute;top:100%;left:50%;transform:translate(-50%);border:4px solid transparent;border-top-color:var(--gray-900, #18181b)}.analytics-page__peak-axis{display:flex;justify-content:space-between;gap:2px;margin-top:8px}.analytics-page__peak-tick{flex:1;text-align:center;min-height:16px;color:var(--text-secondary);font-size:10px}.analytics-page__bar{width:100%;flex:1 1 auto;min-height:3px;background:linear-gradient(180deg,var(--brand-500),var(--violet-500));border-radius:4px 4px 0 0;animation:eds-bar-grow .5s ease forwards;transform-origin:bottom}.analytics-page__hbar-row{display:grid;grid-template-columns:120px 1fr 40px;align-items:center;gap:10px}.analytics-page__hbar-track{height:8px;background:var(--surface-l2);border-radius:4px;overflow:hidden}.analytics-page__hbar-fill{display:block;height:100%;background:var(--brand-500);border-radius:4px;animation:eds-bar-grow .5s ease forwards;transform-origin:left}@media(max-width:1000px){.analytics-page__kpis{grid-template-columns:repeat(2,1fr)}.analytics-page__charts{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "component", type: EdsIconComponent, selector: "eds-icon", inputs: ["name", "size", "fill", "weight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
106
|
-
}
|
|
107
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: AnalyticsPageComponent, decorators: [{
|
|
108
|
-
type: Component,
|
|
109
|
-
args: [{ selector: 'eds-analytics-page', imports: [EdsIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"eds-page analytics-page\">\n <header class=\"analytics-page__header\">\n <div>\n <h1 class=\"eds-h1\">Analytics</h1>\n <p class=\"eds-body-sm\">Call volume, outcomes, and performance KPIs</p>\n </div>\n <div class=\"analytics-page__range\">\n @for (r of ranges; track r.id) {\n <button\n type=\"button\"\n class=\"analytics-page__range-btn\"\n [class.analytics-page__range-btn--active]=\"range() === r.id\"\n (click)=\"setRange(r.id)\"\n >\n {{ r.label }}\n </button>\n }\n </div>\n </header>\n\n @if (loading()) {\n <p class=\"eds-body-sm\">Loading analytics\u2026</p>\n } @else if (data()) {\n <section class=\"analytics-page__kpis\">\n @for (kpi of data()!.kpiCards; track kpi.label) {\n <article class=\"eds-card analytics-page__kpi\">\n <eds-icon [name]=\"kpiIcon(kpi.label)\" [size]=\"22\" />\n <span class=\"eds-label\">{{ kpi.label }}</span>\n <span class=\"analytics-page__kpi-value\">{{ kpi.value }}</span>\n @if (kpi.delta) {\n <span class=\"analytics-page__kpi-delta\" [attr.data-tone]=\"kpi.tone\">{{ kpi.delta }}</span>\n }\n @if (kpi.sub) {\n <span class=\"analytics-page__kpi-sub\">{{ kpi.sub }}</span>\n }\n </article>\n }\n </section>\n\n <div class=\"analytics-page__charts\">\n <article class=\"eds-card analytics-page__chart\">\n <div class=\"analytics-page__chart-head\">\n <h2 class=\"eds-h2\">Call volume</h2>\n <span class=\"eds-label\">{{ volumeRangeLabel() }}</span>\n </div>\n <div class=\"analytics-page__volume-chart\">\n <div class=\"analytics-page__plot\">\n <div class=\"analytics-page__grid\" aria-hidden=\"true\"></div>\n <div class=\"analytics-page__bars\" role=\"list\" aria-label=\"Call volume by day\">\n @for (point of data()!.volume.points; track point.date || point.label; let i = $index) {\n <div\n class=\"analytics-page__bar-col\"\n role=\"listitem\"\n [attr.aria-label]=\"volumeTooltip(point)\"\n >\n <div class=\"analytics-page__bar-wrap\">\n @if (point.count > 0) {\n <div\n class=\"analytics-page__bar-stack\"\n [style.height.%]=\"barHeightPercent(point, data()!.volume.points)\"\n >\n @if (showBarValue(point, data()!.volume.points)) {\n <span class=\"analytics-page__bar-value eds-mono-sm\">{{ point.count }}</span>\n }\n <div class=\"analytics-page__bar\"></div>\n </div>\n }\n <span class=\"analytics-page__tooltip\">{{ volumeTooltip(point) }}</span>\n </div>\n <span class=\"eds-mono-sm analytics-page__bar-axis\">\n {{ volumeAxisLabel(point, i, data()!.volume.points.length) }}\n </span>\n </div>\n }\n </div>\n </div>\n </div>\n <!-- <p class=\"analytics-page__axis-note eds-label\">(MM/DD)/calls per day</p> -->\n </article>\n\n <article class=\"eds-card analytics-page__chart\">\n <h2 class=\"eds-h2\">Outcomes</h2>\n <div class=\"analytics-page__bars analytics-page__bars--horizontal\">\n @for (item of data()!.outcomes; track item.label) {\n <div class=\"analytics-page__hbar-row\">\n <span class=\"eds-body-sm\">{{ item.label }}</span>\n <div class=\"analytics-page__hbar-track\">\n <span\n class=\"analytics-page__hbar-fill\"\n [style.width.%]=\"(item.value / maxValue(data()!.outcomes)) * 100\"\n [style.background]=\"item.color\"\n ></span>\n </div>\n <span class=\"eds-mono-sm\">{{ item.value }}%</span>\n </div>\n }\n </div>\n </article>\n\n <article class=\"eds-card analytics-page__chart\">\n <h2 class=\"eds-h2\">Top reasons</h2>\n <div class=\"analytics-page__bars analytics-page__bars--horizontal\">\n @for (item of data()!.reasons; track item.label) {\n <div class=\"analytics-page__hbar-row\">\n <span class=\"eds-body-sm\">{{ item.label }}</span>\n <div class=\"analytics-page__hbar-track\">\n <span\n class=\"analytics-page__hbar-fill\"\n [style.width.%]=\"(item.value / maxValue(data()!.reasons)) * 100\"\n ></span>\n </div>\n <span class=\"eds-mono-sm\">{{ item.value }}%</span>\n </div>\n }\n </div>\n </article>\n\n <article class=\"eds-card analytics-page__chart\">\n <div class=\"analytics-page__chart-head\">\n <h2 class=\"eds-h2\">Peak hours</h2>\n <span class=\"eds-label\">\n @if (data()!.peakHours.timezone) {\n {{ data()!.peakHours.timezone }}\n } @else {\n Calls per hour\n }\n </span>\n </div>\n <div class=\"analytics-page__volume-chart analytics-page__volume-chart--peak\">\n <div class=\"analytics-page__plot\">\n <div class=\"analytics-page__grid\" aria-hidden=\"true\"></div>\n <div class=\"analytics-page__bars analytics-page__bars--peak\" role=\"list\" aria-label=\"Call volume by hour\">\n @for (point of data()!.peakHours.points; track point.hour) {\n <div\n class=\"analytics-page__bar-col analytics-page__bar-col--peak\"\n role=\"listitem\"\n [attr.aria-label]=\"peakTooltip(point)\"\n >\n <div class=\"analytics-page__bar-wrap\">\n @if (point.count > 0) {\n <div\n class=\"analytics-page__bar-stack\"\n [style.height.%]=\"barHeightPercent(point, data()!.peakHours.points)\"\n >\n <div class=\"analytics-page__bar\"></div>\n </div>\n }\n <span class=\"analytics-page__tooltip\">{{ peakTooltip(point) }}</span>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n <div class=\"analytics-page__peak-axis\">\n @for (point of data()!.peakHours.points; track point.hour; let i = $index) {\n <span class=\"analytics-page__peak-tick eds-mono-sm\">\n @if (showPeakAxisLabel(i, data()!.peakHours.points.length)) {\n {{ point.label }}\n }\n </span>\n }\n </div>\n </article>\n </div>\n }\n</div>\n", styles: [".analytics-page__header{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:20px}.analytics-page__range{display:flex;gap:4px;background:var(--surface-l0);border:1px solid var(--border-default);border-radius:var(--eds-radius-md);padding:4px}.analytics-page__range-btn{padding:6px 12px;border:none;background:none;font-size:13px;border-radius:var(--eds-radius-sm);cursor:pointer;color:var(--text-secondary)}.analytics-page__range-btn--active{background:var(--brand-500);color:#fff}.analytics-page__kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:20px}.analytics-page__kpi{display:flex;flex-direction:column;gap:6px;padding:16px}.analytics-page__kpi-value{font-size:24px;font-weight:600;color:var(--text-primary)}.analytics-page__kpi-delta{font-size:12px;font-weight:600}.analytics-page__kpi-delta[data-tone=pos]{color:var(--green-500, #16a34a)}.analytics-page__kpi-delta[data-tone=warn]{color:var(--amber-500, #d97706)}.analytics-page__kpi-delta[data-tone=neutral]{color:var(--text-secondary)}.analytics-page__kpi-sub{font-size:12px;color:var(--text-secondary)}.analytics-page__charts{display:grid;grid-template-columns:1fr 1fr;gap:16px}.analytics-page__chart{padding:16px}.analytics-page__chart .eds-h2{margin-bottom:0}.analytics-page__chart-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:16px;flex-wrap:wrap}.analytics-page__volume-chart--peak .analytics-page__grid{inset:0}.analytics-page__plot{position:relative;width:100%;min-width:0}.analytics-page__grid{position:absolute;inset:0 0 24px;pointer-events:none;background-image:linear-gradient(to top,var(--border-default) 1px,transparent 1px);background-size:100% 25%;opacity:.45}.analytics-page__bars{display:flex;align-items:flex-end;justify-content:space-between;gap:8px;height:160px;position:relative;z-index:1}.analytics-page__bars--horizontal{flex-direction:column;height:auto;align-items:stretch;gap:10px}.analytics-page__bars--peak{height:100px}.analytics-page__bars--peak .analytics-page__bar{max-width:100%}.analytics-page__bar-col{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;height:100%;min-width:0;cursor:default}.analytics-page__bar-col:hover .analytics-page__tooltip,.analytics-page__bar-col:focus-within .analytics-page__tooltip{opacity:1}.analytics-page__bar-col--peak{min-width:0}.analytics-page__bar-value{flex-shrink:0;color:var(--text-primary);font-size:11px;font-weight:600;line-height:1}.analytics-page__bar-wrap{position:relative;width:100%;flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;min-height:0}.analytics-page__bar-stack{width:100%;max-width:32px;display:flex;flex-direction:column;justify-content:flex-end;align-items:stretch;gap:4px;min-height:0}.analytics-page__bar-axis{flex-shrink:0;min-height:16px;color:var(--text-secondary);font-size:10px;text-align:center;line-height:1.2}.analytics-page__tooltip{position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%);padding:4px 8px;background:var(--gray-900, #18181b);color:#fafafa;font-size:11px;font-weight:500;line-height:1.3;border-radius:4px;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s ease;z-index:2;box-shadow:0 2px 8px #00000026}.analytics-page__tooltip:after{content:\"\";position:absolute;top:100%;left:50%;transform:translate(-50%);border:4px solid transparent;border-top-color:var(--gray-900, #18181b)}.analytics-page__peak-axis{display:flex;justify-content:space-between;gap:2px;margin-top:8px}.analytics-page__peak-tick{flex:1;text-align:center;min-height:16px;color:var(--text-secondary);font-size:10px}.analytics-page__bar{width:100%;flex:1 1 auto;min-height:3px;background:linear-gradient(180deg,var(--brand-500),var(--violet-500));border-radius:4px 4px 0 0;animation:eds-bar-grow .5s ease forwards;transform-origin:bottom}.analytics-page__hbar-row{display:grid;grid-template-columns:120px 1fr 40px;align-items:center;gap:10px}.analytics-page__hbar-track{height:8px;background:var(--surface-l2);border-radius:4px;overflow:hidden}.analytics-page__hbar-fill{display:block;height:100%;background:var(--brand-500);border-radius:4px;animation:eds-bar-grow .5s ease forwards;transform-origin:left}@media(max-width:1000px){.analytics-page__kpis{grid-template-columns:repeat(2,1fr)}.analytics-page__charts{grid-template-columns:1fr}}\n"] }]
|
|
110
|
-
}] });
|
|
111
|
-
|
|
112
|
-
export { AnalyticsPageComponent };
|
|
113
|
-
//# sourceMappingURL=edvak99-voice-receptionist-widget-analytics-page.component-CW5OKmik.mjs.map
|
package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-CW5OKmik.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"edvak99-voice-receptionist-widget-analytics-page.component-CW5OKmik.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/pages/analytics-page/analytics-page.component.ts","../../../projects/voice-receptionist-widget/src/lib/pages/analytics-page/analytics-page.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, inject, OnInit, signal } from '@angular/core';\n\nimport {\n AnalyticsData,\n AnalyticsPeakPoint,\n AnalyticsVolumePoint,\n} from '../../models/ai-receptionist.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\n\n@Component({\n selector: 'eds-analytics-page',\n imports: [EdsIconComponent],\n templateUrl: './analytics-page.component.html',\n styleUrl: './analytics-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AnalyticsPageComponent implements OnInit {\n private readonly api = inject(AiReceptionistApiService);\n\n protected readonly data = signal<AnalyticsData | null>(null);\n protected readonly range = signal('30d');\n protected readonly loading = signal(true);\n\n protected readonly ranges = [\n { id: '7d', label: '7 days' },\n { id: '30d', label: '30 days' },\n { id: '90d', label: '90 days' },\n ];\n\n ngOnInit(): void {\n this.load();\n }\n\n protected setRange(id: string): void {\n this.range.set(id);\n this.load();\n }\n\n protected maxCount(items: { count: number }[]): number {\n return Math.max(...items.map((i) => i.count), 1);\n }\n\n protected barHeightPercent(point: { count: number }, points: { count: number }[]): number {\n if (point.count <= 0) return 0;\n return (point.count / this.maxCount(points)) * 100;\n }\n\n /** Hide inline counts when bars are too narrow to stay readable. */\n protected showBarValue(point: { count: number }, points: { count: number }[]): boolean {\n return point.count > 0 && points.length <= 21;\n }\n\n protected maxValue(items: { value: number }[]): number {\n return Math.max(...items.map((i) => i.value), 1);\n }\n\n protected volumeTooltip(point: AnalyticsVolumePoint): string {\n const datePart = point.date ? this.formatChartDate(point.date) : point.label;\n return `${datePart}: ${point.count} call${point.count === 1 ? '' : 's'}`;\n }\n\n protected peakTooltip(point: AnalyticsPeakPoint): string {\n return `${point.label}: ${point.count} call${point.count === 1 ? '' : 's'}`;\n }\n\n /** ISO or YYYY-MM-DD → MM/DD (zero-padded). */\n protected formatChartDate(date: string): string {\n const iso = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(date.trim());\n if (iso) {\n return `${iso[2]}/${iso[3]}`;\n }\n return date;\n }\n\n /** Compact x-axis for volume — full labels on 7d, sparse dates on longer ranges. */\n protected volumeAxisLabel(point: AnalyticsVolumePoint, index: number, total: number): string {\n if (point.date) {\n if (total <= 7) return this.formatChartDate(point.date);\n const step = total <= 14 ? 2 : total <= 31 ? 5 : 7;\n if (index % step !== 0 && index !== total - 1) return '';\n return this.formatChartDate(point.date);\n }\n if (total <= 7) return point.day;\n const step = total <= 14 ? 2 : total <= 31 ? 5 : 7;\n if (index % step !== 0 && index !== total - 1) return '';\n return point.day;\n }\n\n protected showPeakAxisLabel(index: number, total: number): boolean {\n if (total <= 12) return true;\n const step = total <= 24 ? 3 : 4;\n return index % step === 0 || index === total - 1;\n }\n\n protected volumeRangeLabel(): string {\n const vol = this.data()?.volume;\n if (!vol?.startDate || !vol?.endDate) return 'Calls per day';\n const start = this.formatChartDate(vol.startDate);\n const end = this.formatChartDate(vol.endDate);\n return `${start} – ${end}${vol.timezone ? ` (${vol.timezone})` : ''}`;\n }\n\n protected kpiIcon(label: string): string {\n const key = label.toLowerCase();\n if (key.includes('call') || key.includes('handled')) return 'call';\n if (key.includes('time') || key.includes('duration')) return 'schedule';\n if (key.includes('resolution') || key.includes('book')) return 'event_available';\n if (key.includes('transfer')) return 'phone_forwarded';\n return 'monitoring';\n }\n\n private load(): void {\n this.loading.set(true);\n this.api.getAnalytics(this.range()).subscribe(({ data }) => {\n this.data.set(data);\n this.loading.set(false);\n });\n }\n}\n","<div class=\"eds-page analytics-page\">\n <header class=\"analytics-page__header\">\n <div>\n <h1 class=\"eds-h1\">Analytics</h1>\n <p class=\"eds-body-sm\">Call volume, outcomes, and performance KPIs</p>\n </div>\n <div class=\"analytics-page__range\">\n @for (r of ranges; track r.id) {\n <button\n type=\"button\"\n class=\"analytics-page__range-btn\"\n [class.analytics-page__range-btn--active]=\"range() === r.id\"\n (click)=\"setRange(r.id)\"\n >\n {{ r.label }}\n </button>\n }\n </div>\n </header>\n\n @if (loading()) {\n <p class=\"eds-body-sm\">Loading analytics…</p>\n } @else if (data()) {\n <section class=\"analytics-page__kpis\">\n @for (kpi of data()!.kpiCards; track kpi.label) {\n <article class=\"eds-card analytics-page__kpi\">\n <eds-icon [name]=\"kpiIcon(kpi.label)\" [size]=\"22\" />\n <span class=\"eds-label\">{{ kpi.label }}</span>\n <span class=\"analytics-page__kpi-value\">{{ kpi.value }}</span>\n @if (kpi.delta) {\n <span class=\"analytics-page__kpi-delta\" [attr.data-tone]=\"kpi.tone\">{{ kpi.delta }}</span>\n }\n @if (kpi.sub) {\n <span class=\"analytics-page__kpi-sub\">{{ kpi.sub }}</span>\n }\n </article>\n }\n </section>\n\n <div class=\"analytics-page__charts\">\n <article class=\"eds-card analytics-page__chart\">\n <div class=\"analytics-page__chart-head\">\n <h2 class=\"eds-h2\">Call volume</h2>\n <span class=\"eds-label\">{{ volumeRangeLabel() }}</span>\n </div>\n <div class=\"analytics-page__volume-chart\">\n <div class=\"analytics-page__plot\">\n <div class=\"analytics-page__grid\" aria-hidden=\"true\"></div>\n <div class=\"analytics-page__bars\" role=\"list\" aria-label=\"Call volume by day\">\n @for (point of data()!.volume.points; track point.date || point.label; let i = $index) {\n <div\n class=\"analytics-page__bar-col\"\n role=\"listitem\"\n [attr.aria-label]=\"volumeTooltip(point)\"\n >\n <div class=\"analytics-page__bar-wrap\">\n @if (point.count > 0) {\n <div\n class=\"analytics-page__bar-stack\"\n [style.height.%]=\"barHeightPercent(point, data()!.volume.points)\"\n >\n @if (showBarValue(point, data()!.volume.points)) {\n <span class=\"analytics-page__bar-value eds-mono-sm\">{{ point.count }}</span>\n }\n <div class=\"analytics-page__bar\"></div>\n </div>\n }\n <span class=\"analytics-page__tooltip\">{{ volumeTooltip(point) }}</span>\n </div>\n <span class=\"eds-mono-sm analytics-page__bar-axis\">\n {{ volumeAxisLabel(point, i, data()!.volume.points.length) }}\n </span>\n </div>\n }\n </div>\n </div>\n </div>\n <!-- <p class=\"analytics-page__axis-note eds-label\">(MM/DD)/calls per day</p> -->\n </article>\n\n <article class=\"eds-card analytics-page__chart\">\n <h2 class=\"eds-h2\">Outcomes</h2>\n <div class=\"analytics-page__bars analytics-page__bars--horizontal\">\n @for (item of data()!.outcomes; track item.label) {\n <div class=\"analytics-page__hbar-row\">\n <span class=\"eds-body-sm\">{{ item.label }}</span>\n <div class=\"analytics-page__hbar-track\">\n <span\n class=\"analytics-page__hbar-fill\"\n [style.width.%]=\"(item.value / maxValue(data()!.outcomes)) * 100\"\n [style.background]=\"item.color\"\n ></span>\n </div>\n <span class=\"eds-mono-sm\">{{ item.value }}%</span>\n </div>\n }\n </div>\n </article>\n\n <article class=\"eds-card analytics-page__chart\">\n <h2 class=\"eds-h2\">Top reasons</h2>\n <div class=\"analytics-page__bars analytics-page__bars--horizontal\">\n @for (item of data()!.reasons; track item.label) {\n <div class=\"analytics-page__hbar-row\">\n <span class=\"eds-body-sm\">{{ item.label }}</span>\n <div class=\"analytics-page__hbar-track\">\n <span\n class=\"analytics-page__hbar-fill\"\n [style.width.%]=\"(item.value / maxValue(data()!.reasons)) * 100\"\n ></span>\n </div>\n <span class=\"eds-mono-sm\">{{ item.value }}%</span>\n </div>\n }\n </div>\n </article>\n\n <article class=\"eds-card analytics-page__chart\">\n <div class=\"analytics-page__chart-head\">\n <h2 class=\"eds-h2\">Peak hours</h2>\n <span class=\"eds-label\">\n @if (data()!.peakHours.timezone) {\n {{ data()!.peakHours.timezone }}\n } @else {\n Calls per hour\n }\n </span>\n </div>\n <div class=\"analytics-page__volume-chart analytics-page__volume-chart--peak\">\n <div class=\"analytics-page__plot\">\n <div class=\"analytics-page__grid\" aria-hidden=\"true\"></div>\n <div class=\"analytics-page__bars analytics-page__bars--peak\" role=\"list\" aria-label=\"Call volume by hour\">\n @for (point of data()!.peakHours.points; track point.hour) {\n <div\n class=\"analytics-page__bar-col analytics-page__bar-col--peak\"\n role=\"listitem\"\n [attr.aria-label]=\"peakTooltip(point)\"\n >\n <div class=\"analytics-page__bar-wrap\">\n @if (point.count > 0) {\n <div\n class=\"analytics-page__bar-stack\"\n [style.height.%]=\"barHeightPercent(point, data()!.peakHours.points)\"\n >\n <div class=\"analytics-page__bar\"></div>\n </div>\n }\n <span class=\"analytics-page__tooltip\">{{ peakTooltip(point) }}</span>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n <div class=\"analytics-page__peak-axis\">\n @for (point of data()!.peakHours.points; track point.hour; let i = $index) {\n <span class=\"analytics-page__peak-tick eds-mono-sm\">\n @if (showPeakAxisLabel(i, data()!.peakHours.points.length)) {\n {{ point.label }}\n }\n </span>\n }\n </div>\n </article>\n </div>\n }\n</div>\n"],"names":[],"mappings":"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"}
|