@elevasis/ui 2.30.0 → 2.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/dist/api/index.js +2 -2
  2. package/dist/app/index.css +38 -0
  3. package/dist/app/index.d.ts +190 -9
  4. package/dist/app/index.js +7 -6
  5. package/dist/charts/index.js +4 -5
  6. package/dist/{chunk-HXZQWMKE.js → chunk-2RJMVWFJ.js} +1 -6
  7. package/dist/{chunk-4VQ2PXMI.js → chunk-3FV6HBXS.js} +4 -4
  8. package/dist/{chunk-CW3UNAF2.js → chunk-4DYOXEH6.js} +410 -5
  9. package/dist/{chunk-JKTPRYGV.js → chunk-4MFNGNHF.js} +123 -192
  10. package/dist/{chunk-HYLERWRO.js → chunk-4QK76KIF.js} +7 -7
  11. package/dist/chunk-5FJJ72HU.js +13 -0
  12. package/dist/chunk-5J4PDX26.js +112 -0
  13. package/dist/{chunk-4SY6BTVZ.js → chunk-6DWD423K.js} +12 -9
  14. package/dist/{chunk-3GV5NHSS.js → chunk-7KZINJLP.js} +78 -232
  15. package/dist/{chunk-6WXDE5LZ.js → chunk-EPTHX4VZ.js} +1 -1
  16. package/dist/{chunk-6EFVZV6X.js → chunk-GCOQ3TBG.js} +243 -254
  17. package/dist/{chunk-LRZFLK2F.js → chunk-IQHU7O5Y.js} +4 -4
  18. package/dist/{chunk-X2SUMO3P.js → chunk-IZWTVFJ2.js} +16 -3
  19. package/dist/{chunk-IKQ42WHU.js → chunk-JFL3GRD4.js} +1 -1
  20. package/dist/{chunk-4FZYEEPK.js → chunk-LLRXA7D7.js} +5 -6
  21. package/dist/chunk-MOY4VOHF.js +347 -0
  22. package/dist/{chunk-XQQEKWTL.js → chunk-N55DVMAG.js} +6 -2
  23. package/dist/{chunk-7E3FUTND.js → chunk-ND5TDV2J.js} +1 -1
  24. package/dist/{chunk-WF227UBV.js → chunk-QQHOKTJA.js} +4 -4
  25. package/dist/{chunk-A7B7HLDF.js → chunk-QTI3KC7D.js} +5884 -515
  26. package/dist/chunk-QXCDKE2O.js +486 -0
  27. package/dist/chunk-R2XR4FCV.js +48 -0
  28. package/dist/chunk-R66W5UDG.js +26 -0
  29. package/dist/{chunk-T5Z7G2J2.js → chunk-RQA2EVN3.js} +6 -16
  30. package/dist/{chunk-SKXXT3E2.js → chunk-RQTWIXJ5.js} +4 -4
  31. package/dist/chunk-T35FWDAB.js +4342 -0
  32. package/dist/{chunk-DWK2QIAK.js → chunk-TYRUKGGD.js} +1 -1
  33. package/dist/{chunk-CN2HC4D4.js → chunk-UFTM5SZZ.js} +2 -2
  34. package/dist/{chunk-JCGD4GM6.js → chunk-UROTM5OR.js} +14 -1
  35. package/dist/{chunk-6YT4IKJ7.js → chunk-VNAZTCHA.js} +15 -0
  36. package/dist/{chunk-KVJ3LFH2.js → chunk-VNFR57DF.js} +4 -24
  37. package/dist/{chunk-SBCIB5TZ.js → chunk-VRNMNB3O.js} +6 -7
  38. package/dist/chunk-WQPX44YM.js +1626 -0
  39. package/dist/{chunk-T2PAD63Y.js → chunk-XZGSCABI.js} +1 -1
  40. package/dist/chunk-YLQEVSOR.js +299 -0
  41. package/dist/{chunk-P5WYW2GI.js → chunk-ZQOKIGZP.js} +152 -306
  42. package/dist/components/index.css +38 -0
  43. package/dist/components/index.d.ts +334 -38
  44. package/dist/components/index.js +42 -42
  45. package/dist/components/navigation/index.css +38 -0
  46. package/dist/components/navigation/index.js +3 -2
  47. package/dist/execution/index.d.ts +9 -3
  48. package/dist/features/auth/index.css +38 -0
  49. package/dist/features/auth/index.d.ts +212 -14
  50. package/dist/features/auth/index.js +41 -9
  51. package/dist/features/clients/index.css +649 -0
  52. package/dist/features/clients/index.d.ts +86 -0
  53. package/dist/features/clients/index.js +720 -0
  54. package/dist/features/crm/index.css +38 -0
  55. package/dist/features/crm/index.d.ts +228 -20
  56. package/dist/features/crm/index.js +20 -17
  57. package/dist/features/dashboard/index.css +38 -0
  58. package/dist/features/dashboard/index.d.ts +78 -3
  59. package/dist/features/dashboard/index.js +16 -16
  60. package/dist/features/delivery/index.css +38 -0
  61. package/dist/features/delivery/index.d.ts +201 -18
  62. package/dist/features/delivery/index.js +20 -18
  63. package/dist/features/knowledge/index.css +38 -0
  64. package/dist/features/knowledge/index.d.ts +20 -18
  65. package/dist/features/knowledge/index.js +116 -578
  66. package/dist/features/lead-gen/index.css +38 -0
  67. package/dist/features/lead-gen/index.d.ts +59 -51
  68. package/dist/features/lead-gen/index.js +20 -18
  69. package/dist/features/monitoring/index.css +38 -0
  70. package/dist/features/monitoring/index.d.ts +20 -18
  71. package/dist/features/monitoring/index.js +19 -18
  72. package/dist/features/monitoring/requests/index.css +38 -0
  73. package/dist/features/monitoring/requests/index.d.ts +21 -19
  74. package/dist/features/monitoring/requests/index.js +17 -15
  75. package/dist/features/operations/index.css +38 -0
  76. package/dist/features/operations/index.d.ts +945 -45
  77. package/dist/features/operations/index.js +24 -26
  78. package/dist/features/seo/index.d.ts +20 -18
  79. package/dist/features/seo/index.js +1 -1
  80. package/dist/features/settings/index.css +38 -0
  81. package/dist/features/settings/index.d.ts +201 -18
  82. package/dist/features/settings/index.js +18 -16
  83. package/dist/hooks/delivery/index.css +38 -0
  84. package/dist/hooks/delivery/index.d.ts +200 -0
  85. package/dist/hooks/delivery/index.js +2 -2
  86. package/dist/hooks/index.css +38 -0
  87. package/dist/hooks/index.d.ts +825 -47
  88. package/dist/hooks/index.js +14 -13
  89. package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +194 -3
  90. package/dist/hooks/published.css +38 -0
  91. package/dist/hooks/published.d.ts +825 -47
  92. package/dist/hooks/published.js +14 -13
  93. package/dist/index.css +38 -0
  94. package/dist/index.d.ts +1506 -1212
  95. package/dist/index.js +15 -14
  96. package/dist/initialization/index.d.ts +181 -0
  97. package/dist/knowledge/index.d.ts +813 -1068
  98. package/dist/knowledge/index.js +7370 -2869
  99. package/dist/{chunk-CLUP5H3C.js → knowledge-search-index-5KYPO746.js} +441 -963
  100. package/dist/layout/index.d.ts +6 -0
  101. package/dist/layout/index.js +4 -5
  102. package/dist/organization/index.css +38 -0
  103. package/dist/profile/index.d.ts +181 -0
  104. package/dist/provider/index.css +38 -0
  105. package/dist/provider/index.d.ts +909 -1156
  106. package/dist/provider/index.js +11 -10
  107. package/dist/provider/published.css +38 -0
  108. package/dist/provider/published.d.ts +906 -1153
  109. package/dist/provider/published.js +7 -6
  110. package/dist/supabase/index.d.ts +349 -0
  111. package/dist/test-utils/index.d.ts +16 -9
  112. package/dist/test-utils/index.js +39 -32
  113. package/dist/test-utils/setup.js +1 -1
  114. package/dist/theme/index.js +3 -3
  115. package/dist/theme/presets/index.js +1 -1
  116. package/dist/types/index.d.ts +378 -5
  117. package/dist/utils/index.d.ts +78 -3
  118. package/dist/utils/index.js +1 -1
  119. package/dist/vite/index.js +2 -2
  120. package/dist/vite-plugin-knowledge/index.js +1 -1
  121. package/package.json +47 -37
  122. package/src/provider/README.md +5 -5
  123. package/dist/chunk-2DIYILF7.js +0 -413
  124. package/dist/chunk-3MDNBHVB.js +0 -3868
  125. package/dist/chunk-6IXOKUBC.js +0 -347
  126. package/dist/chunk-AKOD52HS.js +0 -739
  127. package/dist/chunk-ECNNI3NT.js +0 -6
  128. package/dist/chunk-JDNEWB5F.js +0 -10
  129. package/dist/chunk-NITGGYH2.js +0 -476
  130. package/dist/chunk-OAVTMITG.js +0 -13
@@ -1,9 +1,40 @@
1
- import { useMemo, useState, useEffect } from 'react';
2
- import { useComputedColorScheme, Group, Text, Box, Stack } from '@mantine/core';
1
+ import { useErrorTrends } from './chunk-VNAZTCHA.js';
2
+ import { CardHeader, CenteredErrorState, TrendIndicator, EmptyState, StatCard } from './chunk-EPTHX4VZ.js';
3
+ import { getTimeRangeLabel, getTimeRangeDates, formatBucketTime } from './chunk-2RJMVWFJ.js';
4
+ import { useRef, useState, useLayoutEffect, useEffect, useMemo, useCallback } from 'react';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
+ import { useComputedColorScheme, Group, Text, Box, Stack, Center, Loader, Paper, Button, NumberFormatter, Badge, Space, Tooltip as Tooltip$1, SimpleGrid, Alert, SegmentedControl } from '@mantine/core';
3
7
  import { ResponsiveContainer, AreaChart, CartesianGrid, XAxis, YAxis, Tooltip, ReferenceLine as ReferenceLine$1, Area, PieChart, Pie, Cell } from 'recharts';
4
- import { jsxs, jsx } from 'react/jsx-runtime';
8
+ import { IconActivity, IconDownload, IconChartLine, IconInfoCircle, IconApps, IconPlayerPlay, IconChartBar, IconAlertTriangle, IconRocket, IconAlertCircle } from '@tabler/icons-react';
5
9
 
6
- // src/components/charts/cyber-theme.ts
10
+ function ChartFrame({ h, debounceMs = 150, children }) {
11
+ const ref = useRef(null);
12
+ const [width, setWidth] = useState(0);
13
+ useLayoutEffect(() => {
14
+ const el = ref.current;
15
+ if (!el) return;
16
+ const w = el.getBoundingClientRect().width;
17
+ if (w > 0) setWidth(w);
18
+ }, []);
19
+ useEffect(() => {
20
+ const el = ref.current;
21
+ if (!el) return;
22
+ let timeout;
23
+ const ro = new ResizeObserver((entries) => {
24
+ if (timeout !== void 0) window.clearTimeout(timeout);
25
+ const nextWidth = entries[0]?.contentRect.width ?? 0;
26
+ timeout = window.setTimeout(() => {
27
+ if (nextWidth > 0) setWidth(nextWidth);
28
+ }, debounceMs);
29
+ });
30
+ ro.observe(el);
31
+ return () => {
32
+ ro.disconnect();
33
+ if (timeout !== void 0) window.clearTimeout(timeout);
34
+ };
35
+ }, [debounceMs]);
36
+ return /* @__PURE__ */ jsx("div", { ref, style: { width: "100%", height: h, position: "relative" }, children: width > 0 && /* @__PURE__ */ jsx("div", { style: { width, height: h }, children }) });
37
+ }
7
38
  var THEME_DERIVED = {
8
39
  grid: "var(--color-border)",
9
40
  gridLine: "var(--color-border)",
@@ -542,5 +573,379 @@ function CyberDonut({
542
573
  ] }, seg.name)) })
543
574
  ] });
544
575
  }
576
+ var GRANULARITY_MAP = {
577
+ "1h": "hour",
578
+ "24h": "hour",
579
+ "7d": "day",
580
+ "30d": "day"
581
+ };
582
+ var BUCKET_CONFIG = {
583
+ "1h": { size: 5 * 60 * 1e3, count: 12 },
584
+ "24h": { size: 60 * 60 * 1e3, count: 24 },
585
+ "7d": { size: 24 * 60 * 60 * 1e3, count: 7 },
586
+ "30d": { size: 24 * 60 * 60 * 1e3, count: 30 }
587
+ };
588
+ function groupTimestampsByTime(timestamps, timeRange) {
589
+ const { size: bucketSize, count: bucketCount } = BUCKET_CONFIG[timeRange];
590
+ const granularity = GRANULARITY_MAP[timeRange];
591
+ const now = /* @__PURE__ */ new Date();
592
+ const flooredNow = new Date(now.getTime() - now.getTime() % bucketSize);
593
+ const buckets = /* @__PURE__ */ new Map();
594
+ for (let i = bucketCount - 1; i >= 0; i--) {
595
+ const bucketTime = new Date(flooredNow.getTime() - i * bucketSize);
596
+ const label = formatBucketTime(bucketTime.toISOString(), granularity);
597
+ buckets.set(label, 0);
598
+ }
599
+ timestamps.forEach((occurredAt) => {
600
+ const timeDiff = flooredNow.getTime() - occurredAt.getTime();
601
+ const bucketIndex = Math.floor(timeDiff / bucketSize);
602
+ if (bucketIndex >= 0 && bucketIndex < bucketCount) {
603
+ const bucketTime = new Date(flooredNow.getTime() - bucketIndex * bucketSize);
604
+ const label = formatBucketTime(bucketTime.toISOString(), granularity);
605
+ buckets.set(label, (buckets.get(label) || 0) + 1);
606
+ }
607
+ });
608
+ return Array.from(buckets.entries()).map(([time, count]) => ({
609
+ time,
610
+ "Activity Count": count
611
+ }));
612
+ }
613
+ function ActivityTrendChart({ timestamps, total, isLoading, timeRange }) {
614
+ const chartData = useMemo(() => {
615
+ return groupTimestampsByTime(timestamps, timeRange);
616
+ }, [timestamps, timeRange]);
617
+ if (isLoading) {
618
+ return /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) });
619
+ }
620
+ return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
621
+ /* @__PURE__ */ jsx(
622
+ CardHeader,
623
+ {
624
+ icon: /* @__PURE__ */ jsx(IconActivity, { size: 18 }),
625
+ title: "Activity Trend",
626
+ subtitle: `${total} activities in ${getTimeRangeLabel(timeRange)}`
627
+ }
628
+ ),
629
+ /* @__PURE__ */ jsx(
630
+ CyberAreaChart,
631
+ {
632
+ data: chartData,
633
+ series: [{ dataKey: "Activity Count", color: "blue" }],
634
+ height: 200,
635
+ yAxisLabel: "Count",
636
+ yDomain: [0, "auto"]
637
+ }
638
+ )
639
+ ] });
640
+ }
641
+ function formatDollar(value) {
642
+ return `$${value.toFixed(2)}`;
643
+ }
644
+ function CostTrendChart({ data, summaryData, isLoading, error }) {
645
+ const todayCost = summaryData?.current.totalCostUsd ?? 0;
646
+ const previousCost = summaryData?.previous.totalCostUsd ?? 0;
647
+ const mtdCost = summaryData?.mtd.totalCostUsd ?? 0;
648
+ const projectedMonthlyCost = summaryData?.projection.monthlyCostUsd ?? 0;
649
+ const confidence = summaryData?.projection.confidence ?? "low";
650
+ const budget = 1500;
651
+ const budgetStatus = projectedMonthlyCost <= budget ? "green" : projectedMonthlyCost <= budget * 1.1 ? "yellow" : "red";
652
+ const budgetLabel = projectedMonthlyCost <= budget ? "On Budget" : projectedMonthlyCost <= budget * 1.1 ? "Warning" : "Over Budget";
653
+ const chartData = data?.trendData.map((point) => {
654
+ const date = new Date(point.time);
655
+ const timeLabel = data.granularity === "hour" ? date.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit" }) : date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
656
+ return {
657
+ time: timeLabel,
658
+ "Total Cost": point.totalCostUsd
659
+ };
660
+ }) ?? [];
661
+ const handleExport = () => {
662
+ if (!data) return;
663
+ const csvContent = [
664
+ ["Time", "Total Cost ($)", "Executions", "Avg Cost/Execution ($)"],
665
+ ...data.trendData.map((d) => [
666
+ d.time,
667
+ d.totalCostUsd.toFixed(4),
668
+ d.executionCount,
669
+ d.avgCostPerExecution.toFixed(4)
670
+ ])
671
+ ].map((row) => row.join(",")).join("\n");
672
+ const blob = new Blob([csvContent], { type: "text/csv" });
673
+ const url = URL.createObjectURL(blob);
674
+ const link = document.createElement("a");
675
+ link.href = url;
676
+ link.download = `cost-trends-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.csv`;
677
+ link.click();
678
+ URL.revokeObjectURL(url);
679
+ };
680
+ if (error) {
681
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(CenteredErrorState, { error, title: "Failed to load cost trends" }) });
682
+ }
683
+ if (isLoading) {
684
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) });
685
+ }
686
+ const granularityLabel = data?.granularity === "hour" ? "Hourly" : "Daily";
687
+ return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
688
+ /* @__PURE__ */ jsx(
689
+ CardHeader,
690
+ {
691
+ icon: /* @__PURE__ */ jsx(IconChartLine, { size: 18 }),
692
+ title: `Cost Trend (${granularityLabel})`,
693
+ rightSection: /* @__PURE__ */ jsx(Button, { variant: "subtle", size: "xs", leftSection: /* @__PURE__ */ jsx(IconDownload, { size: 14 }), onClick: handleExport, children: "Export CSV" })
694
+ }
695
+ ),
696
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", mb: "md", children: [
697
+ /* @__PURE__ */ jsxs(Group, { gap: "lg", children: [
698
+ /* @__PURE__ */ jsxs(Group, { gap: 6, align: "baseline", children: [
699
+ /* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, style: { fontFamily: "var(--mantine-font-family-headings)" }, children: /* @__PURE__ */ jsx(NumberFormatter, { prefix: "$", value: todayCost, decimalScale: 2 }) }),
700
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "period" }),
701
+ /* @__PURE__ */ jsx(TrendIndicator, { current: todayCost, previous: previousCost, inverse: true })
702
+ ] }),
703
+ /* @__PURE__ */ jsxs(Group, { gap: 6, align: "baseline", children: [
704
+ /* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, style: { fontFamily: "var(--mantine-font-family-headings)" }, children: /* @__PURE__ */ jsx(NumberFormatter, { prefix: "$", value: mtdCost, thousandSeparator: true, decimalScale: 2 }) }),
705
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "MTD" })
706
+ ] })
707
+ ] }),
708
+ /* @__PURE__ */ jsx(Badge, { size: "md", variant: "dot", color: budgetStatus, children: budgetLabel })
709
+ ] }),
710
+ chartData.length > 0 ? /* @__PURE__ */ jsx(
711
+ CyberAreaChart,
712
+ {
713
+ data: chartData,
714
+ series: [{ dataKey: "Total Cost", color: "blue", name: "Total Cost" }],
715
+ height: 200,
716
+ yDomain: [0, (max) => Math.max(max * 1.1, 0.01)],
717
+ yTickFormatter: formatDollar,
718
+ tooltipFormatter: formatDollar,
719
+ baselineColor: "blue"
720
+ }
721
+ ) : /* @__PURE__ */ jsx(EmptyState, { icon: IconChartLine, title: "No cost data available for this time period" }),
722
+ /* @__PURE__ */ jsx(Space, { h: "lg" }),
723
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
724
+ /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
725
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
726
+ "Projected monthly:",
727
+ " ",
728
+ /* @__PURE__ */ jsx(NumberFormatter, { prefix: "$", value: projectedMonthlyCost, thousandSeparator: true, decimalScale: 2 })
729
+ ] }),
730
+ /* @__PURE__ */ jsx(Tooltip$1, { label: `Projection confidence: ${confidence}`, children: /* @__PURE__ */ jsx(IconInfoCircle, { size: 12, color: "var(--color-text-subtle)" }) })
731
+ ] }),
732
+ /* @__PURE__ */ jsxs(
733
+ Text,
734
+ {
735
+ size: "xs",
736
+ fw: 600,
737
+ c: projectedMonthlyCost > budget ? "red" : "dimmed",
738
+ style: { fontFamily: "var(--mantine-font-family-headings)" },
739
+ children: [
740
+ "Budget: ",
741
+ /* @__PURE__ */ jsx(NumberFormatter, { prefix: "$", value: budget, thousandSeparator: true, decimalScale: 2 })
742
+ ]
743
+ }
744
+ )
745
+ ] })
746
+ ] });
747
+ }
748
+ var EM_DASH = "\u2014";
749
+ function getSuccessRateColor(rate) {
750
+ if (rate >= 95) return "var(--mantine-color-teal-6)";
751
+ if (rate >= 80) return "var(--mantine-color-yellow-6)";
752
+ return "var(--mantine-color-red-6)";
753
+ }
754
+ function getErrorCountColor(count) {
755
+ if (count === 0) return "var(--mantine-color-teal-6)";
756
+ if (count <= 5) return "var(--mantine-color-yellow-6)";
757
+ return "var(--mantine-color-red-6)";
758
+ }
759
+ function HeroStatsRow({
760
+ resourcesData,
761
+ resourcesLoading,
762
+ dashboardData,
763
+ dashboardLoading,
764
+ unresolvedErrorCount,
765
+ errorsLoading
766
+ }) {
767
+ const health = dashboardData?.executionHealth;
768
+ const resourceCount = resourcesData?.total ?? null;
769
+ const totalExecutions = health?.totalExecutions ?? null;
770
+ const successRate = totalExecutions ? health?.successRate ?? null : null;
771
+ return /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 2, sm: 5 }, children: [
772
+ /* @__PURE__ */ jsx(
773
+ StatCard,
774
+ {
775
+ variant: "hero",
776
+ icon: IconApps,
777
+ value: resourceCount ?? EM_DASH,
778
+ label: "Resources",
779
+ isLoading: resourcesLoading
780
+ }
781
+ ),
782
+ /* @__PURE__ */ jsx(
783
+ StatCard,
784
+ {
785
+ variant: "hero",
786
+ icon: IconPlayerPlay,
787
+ value: totalExecutions ?? EM_DASH,
788
+ label: "Executions",
789
+ isLoading: dashboardLoading
790
+ }
791
+ ),
792
+ /* @__PURE__ */ jsx(
793
+ StatCard,
794
+ {
795
+ variant: "hero",
796
+ icon: IconChartBar,
797
+ value: successRate != null ? `${Math.round(successRate)}%` : EM_DASH,
798
+ label: "Success Rate",
799
+ valueColor: successRate != null ? getSuccessRateColor(successRate) : void 0,
800
+ isLoading: dashboardLoading
801
+ }
802
+ ),
803
+ /* @__PURE__ */ jsx(
804
+ StatCard,
805
+ {
806
+ variant: "hero",
807
+ icon: IconAlertTriangle,
808
+ value: errorsLoading ? EM_DASH : unresolvedErrorCount ?? EM_DASH,
809
+ label: "Errors",
810
+ valueColor: unresolvedErrorCount != null ? getErrorCountColor(unresolvedErrorCount) : void 0
811
+ }
812
+ ),
813
+ /* @__PURE__ */ jsx(
814
+ StatCard,
815
+ {
816
+ variant: "hero",
817
+ icon: IconRocket,
818
+ value: dashboardData?.activeDeploymentVersion ?? EM_DASH,
819
+ label: "Deployment",
820
+ isLoading: dashboardLoading
821
+ }
822
+ )
823
+ ] });
824
+ }
825
+ function getGranularityFromTimeRange(timeRange) {
826
+ return ["1h", "24h"].includes(timeRange) ? "hour" : "day";
827
+ }
828
+ function formatPeakPeriod(peakPeriod, granularity) {
829
+ if (!peakPeriod) return "N/A";
830
+ const date = new Date(peakPeriod);
831
+ if (granularity === "hour") {
832
+ return date.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit", hour12: true });
833
+ } else {
834
+ return date.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
835
+ }
836
+ }
837
+ function CombinedTrendChart({
838
+ healthData,
839
+ errorData: _errorData,
840
+ isLoading,
841
+ error,
842
+ timeRange,
843
+ navigationAction,
844
+ compact = false
845
+ }) {
846
+ const [activeTab, setActiveTab] = useState("success");
847
+ const colors = useCyberColors();
848
+ const { startDate: start, endDate: end } = useMemo(() => getTimeRangeDates(timeRange), [timeRange]);
849
+ const granularity = getGranularityFromTimeRange(timeRange);
850
+ const { data: errorTrends } = useErrorTrends({
851
+ startDate: start,
852
+ endDate: end,
853
+ granularity
854
+ });
855
+ const xTickFormatter = useCallback((value) => formatBucketTime(value, granularity), [granularity]);
856
+ if (error) {
857
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(CenteredErrorState, { error, title: "Failed to load trend data" }) });
858
+ }
859
+ if (isLoading) {
860
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) });
861
+ }
862
+ const errorTrendsMap = new Map(errorTrends?.map((trend) => [trend.time, trend.errorCount]) || []);
863
+ const successErrorData = healthData?.trendData.length ? healthData.trendData.map((d) => {
864
+ const errorCount = errorTrendsMap.get(d.time) || 0;
865
+ return {
866
+ time: d.time,
867
+ "Success Count": d.successCount,
868
+ "Error Count": errorCount
869
+ };
870
+ }) : [];
871
+ const throughputData = healthData?.trendData.length ? healthData.trendData.map((d) => ({
872
+ time: d.time,
873
+ Executions: d.executionCount
874
+ })) : [];
875
+ const totalExecutions = healthData?.totalExecutions ?? 0;
876
+ const peakPeriod = healthData?.peakPeriod ?? "";
877
+ const dataGranularity = healthData?.granularity ?? granularity;
878
+ if (!successErrorData.length) {
879
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(Center, { h: 300, children: /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconAlertCircle, {}), color: "gray", variant: "light", children: "No trend data available for the selected time range" }) }) });
880
+ }
881
+ return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
882
+ /* @__PURE__ */ jsx(
883
+ CardHeader,
884
+ {
885
+ icon: /* @__PURE__ */ jsx(IconChartLine, { size: 18 }),
886
+ title: "Execution Trends",
887
+ subtitle: `${getTimeRangeLabel(timeRange)} - ${dataGranularity === "hour" ? "Hourly" : "Daily"} data`,
888
+ rightSection: /* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
889
+ /* @__PURE__ */ jsx(
890
+ SegmentedControl,
891
+ {
892
+ value: activeTab ?? "success",
893
+ onChange: setActiveTab,
894
+ size: "xs",
895
+ data: [
896
+ { label: "Success & Errors", value: "success" },
897
+ { label: "Throughput", value: "throughput" }
898
+ ]
899
+ }
900
+ ),
901
+ navigationAction
902
+ ] })
903
+ }
904
+ ),
905
+ activeTab === "success" && /* @__PURE__ */ jsxs(Box, { style: { height: compact ? 180 : 280 }, children: [
906
+ /* @__PURE__ */ jsxs(Group, { gap: "lg", justify: "center", mb: "xs", h: 24, align: "center", children: [
907
+ /* @__PURE__ */ jsx(CyberLegendItem, { color: colors.green, label: "Success Count" }),
908
+ /* @__PURE__ */ jsx(CyberLegendItem, { color: colors.red, label: "Error Count" })
909
+ ] }),
910
+ /* @__PURE__ */ jsx(
911
+ CyberAreaChart,
912
+ {
913
+ data: successErrorData,
914
+ series: [
915
+ { dataKey: "Error Count", color: "red" },
916
+ { dataKey: "Success Count", color: "green", animationDuration: 1400 }
917
+ ],
918
+ height: compact ? 150 : 250,
919
+ yAxisLabel: "Count",
920
+ baselineColor: "green",
921
+ xTickFormatter
922
+ }
923
+ )
924
+ ] }),
925
+ activeTab === "throughput" && /* @__PURE__ */ jsxs(Box, { style: { height: compact ? 180 : 280 }, children: [
926
+ /* @__PURE__ */ jsxs(Group, { gap: "lg", justify: "center", mb: "xs", h: 24, align: "center", children: [
927
+ /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
928
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, style: { color: colors.blue, fontVariantNumeric: "tabular-nums" }, children: totalExecutions.toLocaleString() }),
929
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "executions" })
930
+ ] }),
931
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "|" }),
932
+ /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
933
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "peak" }),
934
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, style: { color: colors.blue, fontVariantNumeric: "tabular-nums" }, children: formatPeakPeriod(peakPeriod, dataGranularity) })
935
+ ] }),
936
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "dot", color: "green", children: "Normal" })
937
+ ] }),
938
+ /* @__PURE__ */ jsx(
939
+ CyberAreaChart,
940
+ {
941
+ data: throughputData,
942
+ series: [{ dataKey: "Executions", color: "blue" }],
943
+ height: compact ? 150 : 250,
944
+ xTickFormatter
945
+ }
946
+ )
947
+ ] })
948
+ ] });
949
+ }
545
950
 
546
- export { CyberAreaChart, CyberDonut, CyberDonutTooltip, CyberLegendItem, getSeriesColor, useCyberColors };
951
+ export { ActivityTrendChart, ChartFrame, CombinedTrendChart, CostTrendChart, CyberAreaChart, CyberDonut, CyberDonutTooltip, CyberLegendItem, HeroStatsRow, getSeriesColor, useCyberColors };