-
-
+
+
-
-
+
+
@@ -313,34 +306,70 @@ export default function KvResourcePage() {
/>
-
-
-
-
-
-
-
+
+
+ -
+
+ Key
+
+
+ {valueResult ? bytePreview(valueResult.key) : ""}
+
+
+
+ {valueResult ? formatNumber(valueResult.key.lenBytes) : "0"} bytes ·{" "}
+ {valueResult ? bytePreviewKind(valueResult.key) : "utf8"}
+
+
+
+
+
+
+ -
+
+ Value
+
+
+ {valueResult?.value ? bytePreview(valueResult.value) : ""}
+
+
+
+ {valueResult?.value ? formatNumber(valueResult.value.lenBytes) : "0"} bytes ·{" "}
+ {valueResult?.value ? bytePreviewKind(valueResult.value) : "utf8"}
+
+
+
+
+
+
+
+
-
-
- Row filters
- Filter committed rows by key prefix and page size.
-
-
+
+
+
-
+
-
+
-
-
+
+
@@ -393,30 +422,27 @@ export default function KvResourcePage() {
0}>
-
-
- Current authoritative KV rows
-
- Committed rows returned by the selected scope and filters.
-
-
-
-
- aria-label="Committed KV rows"
- class="domain-resource-virtual-table"
+
+
+
+ Scroll horizontally to inspect every row field and action.
+
+
+ ariaLabel="Committed KV rows"
+ class="domain-resource-data-table"
columns={rowColumns}
getKey={(row) => row.key.base64}
- headerHeight={44}
- overscan={6}
- rowHeight={52}
rows={rows}
- style={{ height: `${Math.min(420, Math.max(144, 44 + rows.length * 52))}px` }}
/>
-
-
+
+
-
+
First page
@@ -447,8 +473,8 @@ export default function KvResourcePage() {
-
-
+
+
);
}
diff --git a/ui/src/pages/app/kv.tsx b/ui/src/pages/app/kv.tsx
index 0485879a..fca73070 100644
--- a/ui/src/pages/app/kv.tsx
+++ b/ui/src/pages/app/kv.tsx
@@ -82,7 +82,7 @@ export default function KvPage() {
{
id: "read-latency",
header: "Read p95 ms",
- width: "9%",
+ width: "12%",
cell: (row) => formatLatency(row.readLatencyP95Ms),
sortValue: (row) => row.readLatencyP95Ms,
available: inventoryRows.some((row) => row.readLatencyP95Ms !== undefined),
@@ -90,7 +90,7 @@ export default function KvPage() {
{
id: "write-latency",
header: "Write p95 ms",
- width: "9%",
+ width: "12%",
cell: (row) => formatLatency(row.writeLatencyP95Ms),
sortValue: (row) => row.writeLatencyP95Ms,
available: inventoryRows.some((row) => row.writeLatencyP95Ms !== undefined),
diff --git a/ui/src/pages/app/notice-operation.tsx b/ui/src/pages/app/notice-operation.tsx
index 83b404c9..d5cf0b56 100644
--- a/ui/src/pages/app/notice-operation.tsx
+++ b/ui/src/pages/app/notice-operation.tsx
@@ -1,20 +1,23 @@
import { For, Show } from "@askrjs/askr/control";
import { currentRoute } from "@askrjs/askr/router";
-import { Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow } from "@askrjs/ui";
import {
- Card,
- CardContent,
- CardDescription,
- CardHeader,
- CardTitle,
- Stack,
+ Badge,
+ Block,
+ Item,
+ ItemActions,
+ ItemContent,
+ ItemDescription,
+ ItemGroup,
+ ItemTitle,
+ Text,
} from "@askrjs/themes/components";
+import DomainDataSection from "@/components/shared/domain-data-section";
import DomainHeader from "@/components/shared/domain-header";
import DomainPageFrame from "@/components/shared/domain-page-frame";
import OperatorScopeStrip from "@/components/shared/operator-scope-strip";
import { queryFreshness, queryHeaderStatus } from "@/components/shared/query-header-status";
import {
- QueryEmptyState,
+ QueryCompactEmptyState,
QueryErrorState,
QueryLoadingState,
QueryRefreshingState,
@@ -48,24 +51,55 @@ function parseLimit(value: string | null) {
return Math.max(1, Math.min(200, Math.floor(parsed)));
}
-function NoticeDeliveryTableRows(props: { rows: NoticeDeliveryRows["observations"] }) {
+function NoticeDeliveryList(props: { rows: NoticeDeliveryRows["observations"] }) {
return (
-
- `${observation.sessionId ?? "session"}:${observation.subscriptionId ?? "none"}`
- }
+
- {(observation) => (
-
- {observation.status}
- {observation.sessionId ?? "--"}
- {formatNumber(observation.notificationsReceived)}
- {formatNumber(observation.publishesPerMinute)}
- {formatNumber(observation.publishesTotal)}
-
- )}
-
+
+ `${observation.sessionId ?? "session"}:${observation.subscriptionId ?? "none"}`
+ }
+ >
+ {(observation) => (
+ -
+
+
+
+ {observation.sessionId ?? "--"}
+
+
+
+
+ {observation.subscriptionId == null ? null : (
+
+ Subscription: {formatNumber(observation.subscriptionId)}
+
+ )}
+
+ Notifications observed: {formatNumber(observation.notificationsReceived)}
+
+
+ Current publishes / min: {formatNumber(observation.publishesPerMinute)}
+
+
+ Observed publish total: {formatNumber(observation.publishesTotal)}
+
+
+
+
+
+
+ {observation.status}
+
+
+
+ )}
+
+
);
}
@@ -95,7 +129,7 @@ export default function NoticeOperationPage(props: {
const activeSubscribers = countActiveSubscribers(deliveries);
return (
-
+
{(data) => (
-
+
-
-
- Delivery evidence
-
- Live subscription observations for this operation route; not delivery
- history. The API does not report a reset scope for total counters.
-
-
-
-
-
-
-
- Status
- Session
- Notifications observed
- Current publishes / min
- Observed publish total
-
-
-
-
-
-
-
-
-
- }
+
-
-
-
+ }
+ >
+
+
+
+
)}
-
+
);
}
diff --git a/ui/src/pages/app/notice.tsx b/ui/src/pages/app/notice.tsx
index e10d7bcb..926007fe 100644
--- a/ui/src/pages/app/notice.tsx
+++ b/ui/src/pages/app/notice.tsx
@@ -1,14 +1,7 @@
import { For, Show } from "@askrjs/askr/control";
import { currentRoute, Link } from "@askrjs/askr/router";
-import { Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow } from "@askrjs/ui";
-import {
- Card,
- CardContent,
- CardDescription,
- CardHeader,
- CardTitle,
- Stack,
-} from "@askrjs/themes/components";
+import { Block, Item, ItemContent, ItemGroup, ItemTitle } from "@askrjs/themes/components";
+import DomainDataSection from "@/components/shared/domain-data-section";
import DomainHeader from "@/components/shared/domain-header";
import DomainInventoryPage from "@/components/shared/domain-inventory-page";
import type { DomainResourceMetricColumn } from "@/components/shared/domain-resource-inventory-table";
@@ -16,7 +9,7 @@ import DomainPageFrame from "@/components/shared/domain-page-frame";
import OperatorScopeStrip from "@/components/shared/operator-scope-strip";
import { queryFreshness, queryHeaderStatus } from "@/components/shared/query-header-status";
import {
- QueryEmptyState,
+ QueryCompactEmptyState,
QueryErrorState,
QueryLoadingState,
QueryRefreshingState,
@@ -156,41 +149,57 @@ function NoticeLandingPage() {
);
}
-function NoticeOperationTableRows(props: { data: NoticeResourceOperationRows }) {
+function NoticeOperationList(props: { data: NoticeResourceOperationRows }) {
return (
-
row.operation}>
- {(row) => {
- const route = row.operation.startsWith("notice://")
- ? row.operation
- : formatFitzRoute("notice", {
- area: props.data.area,
- operation: row.operation,
- realm: props.data.realm,
- resource: props.data.resource,
- });
+
+ row.operation}>
+ {(row) => {
+ const route = row.operation.startsWith("notice://")
+ ? row.operation
+ : formatFitzRoute("notice", {
+ area: props.data.area,
+ operation: row.operation,
+ realm: props.data.realm,
+ resource: props.data.resource,
+ });
- return (
-
-
-
- {route}
-
-
- {formatNumber(row.activeSubscribers)}
- {formatNumber(row.rollingMessageCount)}
-
- );
- }}
-
+ return (
+ -
+
+
+
+ {route}
+
+
+
+
+
- Active subscribers
+ - {formatNumber(row.activeSubscribers)}
+
+
+
- Publishes / min
+ - {formatNumber(row.rollingMessageCount)}
+
+
+
+
+ );
+ }}
+
+
);
}
@@ -216,10 +225,10 @@ function NoticeResourcePage(props: { realm: string; area: string; resource: stri
return (
-
+
-
+
-
-
- Notice operations
-
- Live operation routes with active subscribers and route publish rates.
-
-
-
-
-
-
-
- Route
- Active subscribers
- Publishes / min
-
-
-
-
-
-
-
-
-
- ) : null
- }
+
-
-
-
+ : null}
+ >
+
+
+
+
-
+
);
}
diff --git a/ui/src/pages/app/route-family.tsx b/ui/src/pages/app/route-family.tsx
index bf1c187d..d4d1a3a4 100644
--- a/ui/src/pages/app/route-family.tsx
+++ b/ui/src/pages/app/route-family.tsx
@@ -2,7 +2,7 @@ import { For } from "@askrjs/askr/control";
import { task } from "@askrjs/askr/resources";
import { Link } from "@askrjs/askr/router";
import { NetworkIcon } from "@askrjs/lucide";
-import { Button, Main, PageHeader, Stack } from "@askrjs/themes/components";
+import { Button, Main, PageHeader, Block } from "@askrjs/themes/components";
import { pathWithRouteFamily } from "@/shared/navigation/domains";
import { manageRoutePageContext } from "@/components/shared/domain-page-frame";
import {
@@ -54,18 +54,20 @@ export function RouteFamilyNotFoundPage() {
-
+
-
+
);
}
@@ -79,13 +81,15 @@ export default function RouteFamilySelectorPage() {
-
+
{operator.routeFamilyState === "loading" ? (
@@ -107,7 +111,7 @@ export default function RouteFamilySelectorPage() {
{operator.routeFamilyState === "ready" ? (
) : null}
-
+
);
}
diff --git a/ui/src/pages/app/rpc-operation.tsx b/ui/src/pages/app/rpc-operation.tsx
index c5cdc734..9d748056 100644
--- a/ui/src/pages/app/rpc-operation.tsx
+++ b/ui/src/pages/app/rpc-operation.tsx
@@ -1,21 +1,24 @@
import { For, Show } from "@askrjs/askr/control";
import { currentRoute } from "@askrjs/askr/router";
-import { Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow } from "@askrjs/ui";
import {
- Card,
- CardContent,
- CardDescription,
- CardHeader,
- CardTitle,
- Stack,
+ Badge,
+ Block,
+ Item,
+ ItemActions,
+ ItemContent,
+ ItemDescription,
+ ItemGroup,
+ ItemTitle,
+ Text,
} from "@askrjs/themes/components";
+import DomainDataSection from "@/components/shared/domain-data-section";
import DomainHeader from "@/components/shared/domain-header";
-import DomainMetricTable from "@/components/shared/domain-metric-table";
import DomainPageFrame from "@/components/shared/domain-page-frame";
+import DomainSummaryStrip from "@/components/shared/domain-summary-strip";
import OperatorScopeStrip from "@/components/shared/operator-scope-strip";
import { queryFreshness, queryHeaderStatus } from "@/components/shared/query-header-status";
import {
- QueryEmptyState,
+ QueryCompactEmptyState,
QueryErrorState,
QueryLoadingState,
QueryRefreshingState,
@@ -51,22 +54,44 @@ function formatObservationState(value: string) {
.join(" ");
}
-function RpcCallEvidenceRows(props: { rows: RpcCallObservation[] }) {
+function RpcCallEvidenceList(props: { rows: RpcCallObservation[] }) {
return (
-
row.correlation_id ?? `${row.worker_session_id}:${index}`}
- >
- {(row) => (
-
- {formatObservationState(row.state)}
- {row.worker_session_id ?? "--"}
- {row.correlation_id ?? "--"}
- {formatNumber(row.requests_handled ?? 0)}
- {formatLatency(row.average_latency_ms)}
-
- )}
-
+
+ row.correlation_id ?? `${row.worker_session_id}:${index}`}
+ >
+ {(row) => (
+ -
+
+
+
+ {row.correlation_id ?? row.worker_session_id ?? "--"}
+
+
+
+
+
+ Worker: {row.worker_session_id ?? "--"}
+
+
+ Observed handled total: {formatNumber(row.requests_handled ?? 0)}
+
+
+ Latency: {formatLatency(row.average_latency_ms)}
+
+
+
+
+
+
+ {formatObservationState(row.state)}
+
+
+
+ )}
+
+
);
}
@@ -84,7 +109,7 @@ export default function RpcOperationPage() {
return (
-
+
{(detail) => (
-
+
-
-
-
- Live call evidence
-
- Broker-local worker registrations, pending calls, and correlation rows.
-
-
-
-
-
-
-
- State
- Worker
- Correlation
- Observed handled total
- Latency
-
-
-
-
-
-
-
- }
- >
-