@copilotz/admin 0.9.27 → 0.9.28

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/dist/index.cjs CHANGED
@@ -1483,73 +1483,24 @@ var PAGE_TITLES = {
1483
1483
  var AdminHeader = ({
1484
1484
  config,
1485
1485
  currentRoute,
1486
- range,
1487
- interval,
1488
- onRangeChange,
1489
- onIntervalChange,
1490
1486
  onRefresh,
1491
- isLoading
1487
+ isLoading,
1488
+ controls
1492
1489
  }) => {
1493
1490
  let pageTitle = config.labels[`${currentRoute.page}Title`] || PAGE_TITLES[currentRoute.page] || currentRoute.page;
1494
1491
  if (currentRoute.page === "collection-items" && currentRoute.collection) {
1495
1492
  pageTitle = currentRoute.collection.charAt(0).toUpperCase() + currentRoute.collection.slice(1);
1496
1493
  }
1497
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Card, { className: "py-0 border-b rounded-none relative z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CardHeader, { className: "p-2", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
1498
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1", children: [
1494
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Card, { className: "py-0 border-b rounded-none relative z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 shadow-none", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CardHeader, { className: "px-3 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex min-h-10 flex-wrap items-center gap-2", children: [
1495
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex min-w-0 items-center gap-1", children: [
1499
1496
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Tooltip, { children: [
1500
1497
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SidebarTrigger, { className: "-ml-1" }) }),
1501
1498
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipContent, { children: "Toggle Sidebar" })
1502
1499
  ] }),
1503
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h1", { className: "text-sm font-medium ml-2", children: pageTitle })
1500
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h1", { className: "ml-2 whitespace-nowrap text-sm font-medium", children: pageTitle })
1504
1501
  ] }),
1505
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex-1" }),
1506
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1", children: [
1507
- currentRoute.page === "dashboard" && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1508
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1509
- Button,
1510
- {
1511
- variant: range === "24h" ? "default" : "ghost",
1512
- size: "sm",
1513
- className: "h-7 text-xs",
1514
- onClick: () => onRangeChange("24h"),
1515
- children: config.labels.range24h
1516
- }
1517
- ),
1518
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1519
- Button,
1520
- {
1521
- variant: range === "7d" ? "default" : "ghost",
1522
- size: "sm",
1523
- className: "h-7 text-xs",
1524
- onClick: () => onRangeChange("7d"),
1525
- children: config.labels.range7d
1526
- }
1527
- ),
1528
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1529
- Button,
1530
- {
1531
- variant: range === "30d" ? "default" : "ghost",
1532
- size: "sm",
1533
- className: "h-7 text-xs",
1534
- onClick: () => onRangeChange("30d"),
1535
- children: config.labels.range30d
1536
- }
1537
- ),
1538
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1539
- Select,
1540
- {
1541
- value: interval,
1542
- onValueChange: (v) => onIntervalChange(v),
1543
- children: [
1544
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SelectTrigger, { className: "h-7 w-[90px] text-xs", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SelectValue, {}) }),
1545
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(SelectContent, { children: [
1546
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SelectItem, { value: "hour", children: config.labels.intervalHour }),
1547
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SelectItem, { value: "day", children: config.labels.intervalDay })
1548
- ] })
1549
- ]
1550
- }
1551
- )
1552
- ] }),
1502
+ controls && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex min-w-[240px] flex-1 items-center justify-end gap-2 overflow-x-auto", children: controls }),
1503
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "ml-auto flex items-center gap-1", children: [
1553
1504
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Tooltip, { children: [
1554
1505
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1555
1506
  Button,
@@ -1749,7 +1700,9 @@ var DashboardView = ({
1749
1700
  onParticipantSearchChange,
1750
1701
  onAgentSearchChange,
1751
1702
  onThreadClick,
1752
- namespace
1703
+ namespace,
1704
+ setHeaderControls,
1705
+ setHeaderRefresh
1753
1706
  }) => {
1754
1707
  void overview;
1755
1708
  void activity;
@@ -1777,13 +1730,17 @@ var DashboardView = ({
1777
1730
  UsageDashboard,
1778
1731
  {
1779
1732
  config,
1780
- namespace
1733
+ namespace,
1734
+ setHeaderControls,
1735
+ setHeaderRefresh
1781
1736
  }
1782
1737
  );
1783
1738
  };
1784
1739
  function UsageDashboard({
1785
1740
  config,
1786
- namespace
1741
+ namespace,
1742
+ setHeaderControls,
1743
+ setHeaderRefresh
1787
1744
  }) {
1788
1745
  const [period, setPeriod] = import_react2.default.useState("7d");
1789
1746
  const [bucket, setBucket] = import_react2.default.useState("day");
@@ -1881,243 +1838,109 @@ function UsageDashboard({
1881
1838
  period === "custom" ? customFrom : "",
1882
1839
  period === "custom" ? customTo : ""
1883
1840
  ].filter((value) => value.trim().length > 0).length;
1884
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-4", children: [
1885
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between", children: [
1886
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
1887
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h2", { className: "text-2xl font-semibold tracking-tight", children: config.labels.llmUsageTitle }),
1888
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "mt-2 flex flex-wrap items-center gap-2", children: [
1889
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Badge, { variant: "outline", children: formatUsageRangeLabel(period, range) }),
1890
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Badge, { variant: "secondary", children: getGroupByLabel(groupBy) }),
1891
- groupBy === "participant" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Badge, { variant: "outline", children: attribution === "initiatedBy" ? "Initiated by sender" : "Generated by caller" })
1892
- ] })
1893
- ] }),
1894
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1895
- Button,
1896
- {
1897
- className: "w-full sm:w-auto",
1898
- disabled: isLoading,
1899
- onClick: () => void loadUsage(),
1900
- size: "sm",
1901
- variant: "outline",
1902
- children: [
1903
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.RefreshCw, { className: cn("size-4", isLoading && "animate-spin") }),
1904
- config.labels.refresh
1905
- ]
1906
- }
1907
- )
1908
- ] }),
1909
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1910
- UsageSummary,
1911
- {
1912
- dimension,
1913
- labels: config.labels,
1914
- metricKind,
1915
- totals
1916
- }
1917
- ),
1918
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Card, { className: "gap-4 overflow-hidden py-4", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(CardContent, { className: "space-y-4 px-4 lg:px-5", children: [
1919
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid gap-2 md:grid-cols-2 xl:grid-cols-6", children: [
1920
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1921
- UsageSelect,
1922
- {
1923
- label: "Period",
1924
- onValueChange: (value) => setPeriod(value),
1925
- options: [
1926
- ["24h", config.labels.range24h],
1927
- ["7d", config.labels.range7d],
1928
- ["30d", config.labels.range30d],
1929
- ["custom", "Custom"]
1930
- ],
1931
- value: period
1932
- }
1933
- ),
1934
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1935
- UsageSelect,
1936
- {
1937
- label: "Bucket",
1938
- onValueChange: (value) => setBucket(value),
1939
- options: [
1940
- ["minute", "Minute"],
1941
- ["hour", "Hour"],
1942
- ["day", "Day"],
1943
- ["week", "Week"],
1944
- ["month", "Month"]
1945
- ],
1946
- value: bucket
1947
- }
1948
- ),
1949
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1950
- UsageSelect,
1951
- {
1952
- label: config.labels.usageMetricLabel,
1953
- onValueChange: (value) => setMetricKind(value),
1954
- options: [
1955
- ["cost", config.labels.usageMetricCost],
1956
- ["tokens", config.labels.usageMetricTokens],
1957
- ["calls", "Calls"]
1958
- ],
1959
- value: metricKind
1960
- }
1961
- ),
1962
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1963
- UsageSelect,
1964
- {
1965
- label: "Group",
1966
- onValueChange: (value) => setGroupBy(value),
1967
- options: [
1968
- ["participant", "Participant"],
1969
- ["thread", "Thread"],
1970
- ["namespace", "Namespace"],
1971
- ["provider", "Provider"],
1972
- ["model", "Model"]
1973
- ],
1974
- value: groupBy
1975
- }
1976
- ),
1977
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1978
- UsageSelect,
1979
- {
1980
- label: "Attribution",
1981
- onValueChange: (value) => setAttribution(value),
1982
- options: [
1983
- ["initiatedBy", "Initiated by"],
1984
- ["generatedBy", "Generated by"]
1985
- ],
1986
- value: attribution
1987
- }
1988
- ),
1841
+ const clearFilters = import_react2.default.useCallback(() => {
1842
+ setParticipantType("all");
1843
+ setThreadId("");
1844
+ setParticipantId("");
1845
+ setProvider("");
1846
+ setModel("");
1847
+ setCustomFrom("");
1848
+ setCustomTo("");
1849
+ }, []);
1850
+ const headerControls = import_react2.default.useMemo(() => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1851
+ DashboardHeaderControls,
1852
+ {
1853
+ attribution,
1854
+ bucket,
1855
+ config,
1856
+ dimension,
1857
+ groupBy,
1858
+ metricKind,
1859
+ period,
1860
+ setAttribution,
1861
+ setBucket,
1862
+ setDimension,
1863
+ setGroupBy,
1864
+ setMetricKind,
1865
+ setPeriod
1866
+ }
1867
+ ), [
1868
+ attribution,
1869
+ bucket,
1870
+ config,
1871
+ dimension,
1872
+ groupBy,
1873
+ metricKind,
1874
+ period
1875
+ ]);
1876
+ import_react2.default.useEffect(() => {
1877
+ setHeaderControls?.(headerControls);
1878
+ return () => setHeaderControls?.(null);
1879
+ }, [headerControls, setHeaderControls]);
1880
+ import_react2.default.useEffect(() => {
1881
+ setHeaderRefresh?.(() => () => {
1882
+ void loadUsage();
1883
+ });
1884
+ return () => setHeaderRefresh?.(null);
1885
+ }, [loadUsage, setHeaderRefresh]);
1886
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid h-full min-h-0 grid-rows-[auto_minmax(0,4fr)_minmax(0,5fr)] gap-3", children: [
1887
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-3", children: [
1888
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3 xl:flex-row xl:items-end xl:justify-between", children: [
1889
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "min-w-0", children: [
1890
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h2", { className: "text-xl font-semibold tracking-tight", children: config.labels.llmUsageTitle }),
1891
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "mt-1 flex flex-wrap items-center gap-2", children: [
1892
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Badge, { variant: "outline", children: formatUsageRangeLabel(period, range) }),
1893
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Badge, { variant: "secondary", children: getGroupByLabel(groupBy) }),
1894
+ groupBy === "participant" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Badge, { variant: "outline", children: attribution === "initiatedBy" ? "Initiated by sender" : "Generated by caller" }),
1895
+ isLoading && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Badge, { variant: "outline", children: config.labels.loading })
1896
+ ] })
1897
+ ] }),
1989
1898
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1990
- UsageSelect,
1899
+ InlineFilters,
1991
1900
  {
1992
- label: config.labels.usageDimensionLabel,
1993
- onValueChange: (value) => setDimension(value),
1994
- options: USAGE_DIMENSIONS.map((nextDimension) => [
1995
- nextDimension,
1996
- getUsageDimensionLabel(config.labels, nextDimension)
1997
- ]),
1998
- value: dimension
1901
+ activeFilterCount,
1902
+ clearFilters,
1903
+ customFrom,
1904
+ customTo,
1905
+ model,
1906
+ participantId,
1907
+ participantType,
1908
+ period,
1909
+ provider,
1910
+ setCustomFrom,
1911
+ setCustomTo,
1912
+ setModel,
1913
+ setParticipantId,
1914
+ setParticipantType,
1915
+ setProvider,
1916
+ setThreadId,
1917
+ threadId
1999
1918
  }
2000
1919
  )
2001
1920
  ] }),
2002
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "rounded-lg border bg-muted/30 p-3", children: [
2003
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "mb-3 flex items-center justify-between gap-3", children: [
2004
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2 text-sm font-medium", children: [
2005
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Filter, { className: "size-4" }),
2006
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Filters" }),
2007
- activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Badge, { variant: "secondary", children: activeFilterCount })
2008
- ] }),
2009
- activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2010
- Button,
2011
- {
2012
- onClick: () => {
2013
- setParticipantType("all");
2014
- setThreadId("");
2015
- setParticipantId("");
2016
- setProvider("");
2017
- setModel("");
2018
- setCustomFrom("");
2019
- setCustomTo("");
2020
- },
2021
- size: "sm",
2022
- variant: "ghost",
2023
- children: "Clear"
2024
- }
2025
- )
2026
- ] }),
2027
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid gap-2 md:grid-cols-2 xl:grid-cols-6", children: [
2028
- period === "custom" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
2029
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2030
- FilterInput,
2031
- {
2032
- label: "From",
2033
- onChange: setCustomFrom,
2034
- type: "datetime-local",
2035
- value: customFrom
2036
- }
2037
- ),
2038
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2039
- FilterInput,
2040
- {
2041
- label: "To",
2042
- onChange: setCustomTo,
2043
- type: "datetime-local",
2044
- value: customTo
2045
- }
2046
- )
2047
- ] }),
2048
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2049
- UsageSelect,
2050
- {
2051
- label: "Type",
2052
- onValueChange: (value) => setParticipantType(
2053
- value
2054
- ),
2055
- options: [
2056
- ["all", "All"],
2057
- ["human", "Human"],
2058
- ["agent", "Agent"],
2059
- ["job", "Job"]
2060
- ],
2061
- value: participantType
2062
- }
2063
- ),
2064
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2065
- FilterInput,
2066
- {
2067
- icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Search, { className: "size-3.5" }),
2068
- label: "Thread",
2069
- onChange: setThreadId,
2070
- value: threadId
2071
- }
2072
- ),
2073
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2074
- FilterInput,
2075
- {
2076
- icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Users, { className: "size-3.5" }),
2077
- label: "Participant",
2078
- onChange: setParticipantId,
2079
- value: participantId
2080
- }
2081
- ),
2082
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2083
- FilterInput,
2084
- {
2085
- icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Database, { className: "size-3.5" }),
2086
- label: "Provider",
2087
- onChange: setProvider,
2088
- value: provider
2089
- }
1921
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1922
+ UsageSummary,
1923
+ {
1924
+ labels: config.labels,
1925
+ totals
1926
+ }
1927
+ )
1928
+ ] }),
1929
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Card, { className: "min-h-0 gap-2 overflow-hidden py-3", children: [
1930
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardHeader, { className: "px-4", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex flex-col gap-2 md:flex-row md:items-start md:justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
1931
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardTitle, { className: "text-base", children: getUsageSummaryLabel(config.labels, metricKind, dimension) }),
1932
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { className: "mt-1 text-sm text-muted-foreground", children: [
1933
+ formatMetricValue(
1934
+ getUsageTotalValue(totals, metricKind, dimension),
1935
+ metricKind
2090
1936
  ),
2091
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2092
- FilterInput,
2093
- {
2094
- icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Sparkles, { className: "size-3.5" }),
2095
- label: "Model",
2096
- onChange: setModel,
2097
- value: model
2098
- }
2099
- )
1937
+ " ",
1938
+ "across ",
1939
+ formatNumber(totals.totalCalls),
1940
+ " calls"
2100
1941
  ] })
2101
- ] })
2102
- ] }) }),
2103
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Card, { className: "gap-3 overflow-hidden py-4", children: [
2104
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardHeader, { className: "px-4 lg:px-5", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-2 md:flex-row md:items-start md:justify-between", children: [
2105
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
2106
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardTitle, { className: "text-base", children: getUsageSummaryLabel(config.labels, metricKind, dimension) }),
2107
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { className: "mt-1 text-sm text-muted-foreground", children: [
2108
- formatMetricValue(
2109
- getUsageTotalValue(totals, metricKind, dimension),
2110
- metricKind
2111
- ),
2112
- " ",
2113
- "across ",
2114
- formatNumber(totals.totalCalls),
2115
- " calls"
2116
- ] })
2117
- ] }),
2118
- isLoading && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Badge, { variant: "outline", children: config.labels.loading })
2119
- ] }) }),
2120
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardContent, { className: "px-2 lg:px-4", children: error ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "rounded-lg border border-destructive/30 bg-destructive/10 p-4 text-sm text-destructive", children: error }) : chartState.data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1942
+ ] }) }) }),
1943
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardContent, { className: "min-h-0 flex-1 px-2 lg:px-4", children: error ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "rounded-lg border border-destructive/30 bg-destructive/10 p-4 text-sm text-destructive", children: error }) : chartState.data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2121
1944
  EmptyDashboard,
2122
1945
  {
2123
1946
  description: config.labels.noResults,
@@ -2151,9 +1974,7 @@ function UsageDashboard({
2151
1974
  ] });
2152
1975
  }
2153
1976
  function UsageSummary({
2154
- dimension,
2155
1977
  labels,
2156
- metricKind,
2157
1978
  totals
2158
1979
  }) {
2159
1980
  const summary = [
@@ -2170,28 +1991,19 @@ function UsageSummary({
2170
1991
  icon: import_lucide_react6.Activity
2171
1992
  },
2172
1993
  {
2173
- label: labels.usageCacheRead,
2174
- value: formatMetricValue(totals.cacheReadInputCostUsd, "cost"),
2175
- detail: `${formatMetricValue(totals.cacheReadInputTokens, "tokens")} tokens`,
2176
- icon: import_lucide_react6.Database
2177
- },
2178
- {
2179
- label: getUsageSummaryLabel(labels, metricKind, dimension),
2180
- value: formatMetricValue(
2181
- getUsageTotalValue(totals, metricKind, dimension),
2182
- metricKind
2183
- ),
2184
- detail: labels.usageTotal,
1994
+ label: "Calls",
1995
+ value: formatMetricValue(totals.totalCalls, "calls"),
1996
+ detail: totals.totalCalls > 0 ? `${formatMetricValue(totals.totalCostUsd / totals.totalCalls, "cost")} avg` : "No calls",
2185
1997
  icon: import_lucide_react6.Sparkles
2186
1998
  }
2187
1999
  ];
2188
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-4", children: summary.map((item) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Card, { className: "gap-3 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardContent, { className: "px-4", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
2000
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "grid gap-2 md:grid-cols-3", children: summary.map((item) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Card, { className: "gap-0 rounded-lg py-2 shadow-xs", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardContent, { className: "px-3", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
2189
2001
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "min-w-0", children: [
2190
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "truncate text-sm text-muted-foreground", children: item.label }),
2191
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "mt-1 truncate text-2xl font-semibold tracking-tight", children: item.value }),
2192
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "mt-1 truncate text-xs text-muted-foreground", children: item.detail })
2002
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "truncate text-xs text-muted-foreground", children: item.label }),
2003
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "truncate text-lg font-semibold tracking-tight", children: item.value }),
2004
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "truncate text-[11px] text-muted-foreground", children: item.detail })
2193
2005
  ] }),
2194
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "rounded-md border bg-muted/50 p-2 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(item.icon, { className: "size-4" }) })
2006
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "rounded-md border bg-muted/50 p-1.5 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(item.icon, { className: "size-4" }) })
2195
2007
  ] }) }) }, item.label)) });
2196
2008
  }
2197
2009
  function UsageChart({
@@ -2201,7 +2013,7 @@ function UsageChart({
2201
2013
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2202
2014
  ChartContainer,
2203
2015
  {
2204
- className: "h-[320px] w-full",
2016
+ className: "h-full min-h-[220px] w-full",
2205
2017
  config: chartState.config,
2206
2018
  children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2207
2019
  import_recharts.BarChart,
@@ -2275,8 +2087,8 @@ function UsageTable({
2275
2087
  }) {
2276
2088
  const totalValue = getUsageTotalValue(totals, metricKind, dimension);
2277
2089
  const filterable = groupBy !== "namespace";
2278
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Card, { className: "gap-3 py-4", children: [
2279
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardHeader, { className: "px-4 lg:px-5", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: [
2090
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Card, { className: "min-h-0 gap-2 overflow-hidden py-3", children: [
2091
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardHeader, { className: "px-4", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: [
2280
2092
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardTitle, { className: "text-base", children: "Usage detail" }),
2281
2093
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Badge, { variant: "outline", children: [
2282
2094
  formatNumber(rows.length),
@@ -2284,8 +2096,8 @@ function UsageTable({
2284
2096
  getGroupByLabel(groupBy).toLowerCase()
2285
2097
  ] })
2286
2098
  ] }) }),
2287
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardContent, { className: "px-0", children: rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "px-5 py-4 text-sm text-muted-foreground", children: labels.noResults }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("table", { className: "w-full min-w-[940px] text-sm", children: [
2288
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("tr", { className: "border-b text-left text-xs uppercase tracking-[0.12em] text-muted-foreground", children: [
2099
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardContent, { className: "min-h-0 flex-1 overflow-hidden px-0", children: rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "px-5 py-4 text-sm text-muted-foreground", children: labels.noResults }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-full overflow-auto", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("table", { className: "w-full min-w-[940px] text-sm", children: [
2100
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("thead", { className: "sticky top-0 z-10 bg-card", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("tr", { className: "border-b text-left text-xs uppercase tracking-[0.12em] text-muted-foreground", children: [
2289
2101
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("th", { className: "px-5 py-2.5 font-medium", children: getGroupByLabel(groupBy) }),
2290
2102
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("th", { className: "px-3 py-2.5 text-right font-medium", children: getUsageSummaryLabel(labels, metricKind, dimension) }),
2291
2103
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("th", { className: "px-3 py-2.5 text-right font-medium", children: "Share" }),
@@ -2342,24 +2154,271 @@ function UsageTable({
2342
2154
  ] }) }) })
2343
2155
  ] });
2344
2156
  }
2157
+ function DashboardHeaderControls({
2158
+ attribution,
2159
+ bucket,
2160
+ config,
2161
+ dimension,
2162
+ groupBy,
2163
+ metricKind,
2164
+ period,
2165
+ setAttribution,
2166
+ setBucket,
2167
+ setDimension,
2168
+ setGroupBy,
2169
+ setMetricKind,
2170
+ setPeriod
2171
+ }) {
2172
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-1.5", children: [
2173
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2174
+ HeaderSelect,
2175
+ {
2176
+ label: "Period",
2177
+ onValueChange: (value) => setPeriod(value),
2178
+ options: [
2179
+ ["24h", config.labels.range24h],
2180
+ ["7d", config.labels.range7d],
2181
+ ["30d", config.labels.range30d],
2182
+ ["custom", "Custom"]
2183
+ ],
2184
+ value: period,
2185
+ width: "w-[86px]"
2186
+ }
2187
+ ),
2188
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2189
+ HeaderSelect,
2190
+ {
2191
+ label: "Bucket",
2192
+ onValueChange: (value) => setBucket(value),
2193
+ options: [
2194
+ ["minute", "Minute"],
2195
+ ["hour", "Hour"],
2196
+ ["day", "Day"],
2197
+ ["week", "Week"],
2198
+ ["month", "Month"]
2199
+ ],
2200
+ value: bucket,
2201
+ width: "w-[92px]"
2202
+ }
2203
+ ),
2204
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2205
+ HeaderSelect,
2206
+ {
2207
+ label: config.labels.usageMetricLabel,
2208
+ onValueChange: (value) => setMetricKind(value),
2209
+ options: [
2210
+ ["cost", config.labels.usageMetricCost],
2211
+ ["tokens", config.labels.usageMetricTokens],
2212
+ ["calls", "Calls"]
2213
+ ],
2214
+ value: metricKind,
2215
+ width: "w-[94px]"
2216
+ }
2217
+ ),
2218
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2219
+ HeaderSelect,
2220
+ {
2221
+ label: "Group",
2222
+ onValueChange: (value) => setGroupBy(value),
2223
+ options: [
2224
+ ["participant", "Participant"],
2225
+ ["thread", "Thread"],
2226
+ ["namespace", "Namespace"],
2227
+ ["provider", "Provider"],
2228
+ ["model", "Model"]
2229
+ ],
2230
+ value: groupBy,
2231
+ width: "w-[128px]"
2232
+ }
2233
+ ),
2234
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2235
+ HeaderSelect,
2236
+ {
2237
+ label: "Attribution",
2238
+ onValueChange: (value) => setAttribution(value),
2239
+ options: [
2240
+ ["initiatedBy", "Initiated by"],
2241
+ ["generatedBy", "Generated by"]
2242
+ ],
2243
+ value: attribution,
2244
+ width: "w-[132px]"
2245
+ }
2246
+ ),
2247
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2248
+ HeaderSelect,
2249
+ {
2250
+ label: config.labels.usageDimensionLabel,
2251
+ onValueChange: (value) => setDimension(value),
2252
+ options: USAGE_DIMENSIONS.map((nextDimension) => [
2253
+ nextDimension,
2254
+ getUsageDimensionLabel(config.labels, nextDimension)
2255
+ ]),
2256
+ value: dimension,
2257
+ width: "w-[116px]"
2258
+ }
2259
+ )
2260
+ ] });
2261
+ }
2262
+ function InlineFilters({
2263
+ activeFilterCount,
2264
+ clearFilters,
2265
+ customFrom,
2266
+ customTo,
2267
+ model,
2268
+ participantId,
2269
+ participantType,
2270
+ period,
2271
+ provider,
2272
+ setCustomFrom,
2273
+ setCustomTo,
2274
+ setModel,
2275
+ setParticipantId,
2276
+ setParticipantType,
2277
+ setProvider,
2278
+ setThreadId,
2279
+ threadId
2280
+ }) {
2281
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex max-w-full flex-wrap items-end justify-end gap-2", children: [
2282
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2 pb-1 text-xs font-medium text-muted-foreground", children: [
2283
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Filter, { className: "size-3.5" }),
2284
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Filters" }),
2285
+ activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Badge, { variant: "secondary", children: activeFilterCount })
2286
+ ] }),
2287
+ period === "custom" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
2288
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2289
+ FilterInput,
2290
+ {
2291
+ compact: true,
2292
+ label: "From",
2293
+ onChange: setCustomFrom,
2294
+ type: "datetime-local",
2295
+ value: customFrom
2296
+ }
2297
+ ),
2298
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2299
+ FilterInput,
2300
+ {
2301
+ compact: true,
2302
+ label: "To",
2303
+ onChange: setCustomTo,
2304
+ type: "datetime-local",
2305
+ value: customTo
2306
+ }
2307
+ )
2308
+ ] }),
2309
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2310
+ UsageSelect,
2311
+ {
2312
+ compact: true,
2313
+ label: "Type",
2314
+ onValueChange: (value) => setParticipantType(value),
2315
+ options: [
2316
+ ["all", "All"],
2317
+ ["human", "Human"],
2318
+ ["agent", "Agent"],
2319
+ ["job", "Job"]
2320
+ ],
2321
+ value: participantType
2322
+ }
2323
+ ),
2324
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2325
+ FilterInput,
2326
+ {
2327
+ compact: true,
2328
+ icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Search, { className: "size-3.5" }),
2329
+ label: "Thread",
2330
+ onChange: setThreadId,
2331
+ value: threadId
2332
+ }
2333
+ ),
2334
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2335
+ FilterInput,
2336
+ {
2337
+ compact: true,
2338
+ icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Users, { className: "size-3.5" }),
2339
+ label: "Participant",
2340
+ onChange: setParticipantId,
2341
+ value: participantId
2342
+ }
2343
+ ),
2344
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2345
+ FilterInput,
2346
+ {
2347
+ compact: true,
2348
+ icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Database, { className: "size-3.5" }),
2349
+ label: "Provider",
2350
+ onChange: setProvider,
2351
+ value: provider
2352
+ }
2353
+ ),
2354
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2355
+ FilterInput,
2356
+ {
2357
+ compact: true,
2358
+ icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Sparkles, { className: "size-3.5" }),
2359
+ label: "Model",
2360
+ onChange: setModel,
2361
+ value: model
2362
+ }
2363
+ ),
2364
+ activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2365
+ Button,
2366
+ {
2367
+ className: "h-8",
2368
+ onClick: clearFilters,
2369
+ size: "sm",
2370
+ variant: "ghost",
2371
+ children: "Clear"
2372
+ }
2373
+ )
2374
+ ] });
2375
+ }
2376
+ function HeaderSelect(props) {
2377
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Select, { value: props.value, onValueChange: props.onValueChange, children: [
2378
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2379
+ SelectTrigger,
2380
+ {
2381
+ "aria-label": props.label,
2382
+ className: cn("h-8 bg-background text-xs", props.width),
2383
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SelectValue, {})
2384
+ }
2385
+ ),
2386
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SelectContent, { children: props.options.map(([value, label]) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SelectItem, { value, children: label }, value)) })
2387
+ ] });
2388
+ }
2345
2389
  function UsageSelect(props) {
2346
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "space-y-1", children: [
2347
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-[11px] font-medium uppercase tracking-[0.16em] text-muted-foreground", children: props.label }),
2390
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: cn("space-y-1", props.compact && "w-[116px]"), children: [
2391
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sr-only", children: props.label }),
2348
2392
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Select, { value: props.value, onValueChange: props.onValueChange, children: [
2349
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SelectTrigger, { className: "h-9 w-full min-w-0 bg-background", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SelectValue, {}) }),
2393
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2394
+ SelectTrigger,
2395
+ {
2396
+ "aria-label": props.label,
2397
+ className: cn(
2398
+ "w-full min-w-0 bg-background",
2399
+ props.compact ? "h-8 text-xs" : "h-9"
2400
+ ),
2401
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SelectValue, {})
2402
+ }
2403
+ ),
2350
2404
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SelectContent, { children: props.options.map(([value, label]) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SelectItem, { value, children: label }, value)) })
2351
2405
  ] })
2352
2406
  ] });
2353
2407
  }
2354
2408
  function FilterInput(props) {
2355
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "space-y-1", children: [
2356
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-[11px] font-medium uppercase tracking-[0.16em] text-muted-foreground", children: props.label }),
2409
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: cn("space-y-1", props.compact && "w-[150px]"), children: [
2410
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sr-only", children: props.label }),
2357
2411
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "relative", children: [
2358
2412
  props.icon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground", children: props.icon }),
2359
2413
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2360
2414
  Input,
2361
2415
  {
2362
- className: cn("h-9 bg-background", props.icon && "pl-8"),
2416
+ "aria-label": props.label,
2417
+ className: cn(
2418
+ "bg-background",
2419
+ props.compact ? "h-8 text-xs" : "h-9",
2420
+ props.icon && "pl-8"
2421
+ ),
2363
2422
  onChange: (event) => props.onChange(event.target.value),
2364
2423
  type: props.type ?? "text",
2365
2424
  value: props.value
@@ -3610,6 +3669,8 @@ var CopilotzAdmin = ({
3610
3669
  const [route, setRoute] = (0, import_react8.useState)({ page: config.defaultPage });
3611
3670
  const [namespace, setNamespace] = (0, import_react8.useState)(config.namespace);
3612
3671
  const [collections, setCollections] = (0, import_react8.useState)([]);
3672
+ const [headerControls, setHeaderControls] = (0, import_react8.useState)(null);
3673
+ const [headerRefresh, setHeaderRefresh] = (0, import_react8.useState)(null);
3613
3674
  const [threadSearch, setThreadSearch] = (0, import_react8.useState)("");
3614
3675
  const [participantSearch, setParticipantSearch] = (0, import_react8.useState)("");
3615
3676
  const [agentSearch, setAgentSearch] = (0, import_react8.useState)("");
@@ -3718,7 +3779,9 @@ var CopilotzAdmin = ({
3718
3779
  onThreadSearchChange: setThreadSearch,
3719
3780
  onParticipantSearchChange: setParticipantSearch,
3720
3781
  onAgentSearchChange: setAgentSearch,
3721
- onThreadClick: handleThreadClick
3782
+ onThreadClick: handleThreadClick,
3783
+ setHeaderControls,
3784
+ setHeaderRefresh
3722
3785
  }
3723
3786
  );
3724
3787
  case "threads":
@@ -3815,15 +3878,18 @@ var CopilotzAdmin = ({
3815
3878
  {
3816
3879
  config,
3817
3880
  currentRoute: route,
3818
- range: admin.filters.range,
3819
- interval: admin.filters.interval,
3820
- onRangeChange: admin.setRange,
3821
- onIntervalChange: admin.setInterval,
3822
- onRefresh: () => void admin.refresh(),
3823
- isLoading: admin.isLoading
3881
+ onRefresh: () => {
3882
+ if (route.page === "dashboard" && headerRefresh) {
3883
+ headerRefresh();
3884
+ return;
3885
+ }
3886
+ void admin.refresh();
3887
+ },
3888
+ isLoading: admin.isLoading,
3889
+ controls: route.page === "dashboard" ? headerControls : null
3824
3890
  }
3825
3891
  ),
3826
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 overflow-auto p-6", children: renderCurrentView() })
3892
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 overflow-auto p-4", children: renderCurrentView() })
3827
3893
  ] }) })
3828
3894
  ]
3829
3895
  }