Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ui/consumer/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v24
1 change: 1 addition & 0 deletions ui/provider/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v24
6 changes: 3 additions & 3 deletions ui/provider/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ Built for a staff member fielding "why isn't my workload starting" / "what's
wrong with this workload" from a customer, not for general browsing —
Overview and Instances surface raw conditions (type/status/reason/message),
placements, network assignments, and scheduling gates, not just a coarse
health enum. Events/Logs/Metrics are honest "Coming Soon" placeholders (no
data source wired up for any of the three yet); YAML dumps the raw resource
(minus `metadata.managedFields`) as an escape hatch. All data is read client-side, polled via
health enum. The Logs tab mounts the empty datum-ui explorer until a Loki
query is wired; Events/Metrics stay honest "Coming Soon" placeholders. YAML
dumps the raw resource (minus `metadata.managedFields`) as an escape hatch. All data is read client-side, polled via
`refetchInterval` (`src/lib/api.ts`) through staff-portal's own same-origin
proxy — no new credential, no plugin-owned backend.

Expand Down
23 changes: 21 additions & 2 deletions ui/provider/bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion ui/provider/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@datum-cloud/datum-ui": "^1.7.1",
"@datum-cloud/datum-ui": "^2.3.0",
"@monaco-editor/react": "^4.7.0",
"@tanstack/react-query": "5.101.4",
"@tanstack/react-virtual": "^3",
"lucide-react": "^1.21.0",
"monaco-editor": "^0.55.0",
"motion": "^12",
"react": "19.2.8",
"react-day-picker": "^10",
"react-dom": "19.2.8",
"date-fns": "^4.1.0",
"date-fns-tz": "^3.2.0",
Expand Down
55 changes: 55 additions & 0 deletions ui/provider/src/components/workload-logs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Workload log explorer built on `@datum-cloud/datum-ui/logs`.
*
* Full explorer for the Workload Logs tab. No log backend yet — entries stay
* empty until a Loki query is wired.
*/
import {
lastThirtyMinutes,
Logs,
type LogFilters,
type LogTimeRange,
} from '@datum-cloud/datum-ui/logs';
import { cn } from '@datum-cloud/datum-ui/utils';
import { useCallback, useState } from 'react';

const COLUMNS = ['time', 'severity', 'message'] as const;

/** Full log explorer for the Workload Logs tab. */
export function WorkloadLogsExplorer({ className }: { className?: string }) {
const [filters, setFilters] = useState<LogFilters>({});
const [search, setSearch] = useState('');
const [live, setLive] = useState(false);
const [timeRange, setTimeRange] = useState<LogTimeRange>(() => lastThirtyMinutes());

const handleRefresh = useCallback(() => {
setTimeRange(lastThirtyMinutes());
}, []);

return (
<div
className={cn(
'border-border bg-card flex flex-col overflow-hidden rounded-xl border',
className
)}
style={{ minHeight: '32rem' }}
data-testid="provider-plugin-workload-logs-explorer">
<Logs.Root
entries={[]}
facets={[{ name: 'severity', label: 'Severity', options: [] }]}
timeRange={timeRange}
filters={filters}
search={search}
live={live}
columns={[...COLUMNS]}
onTimeRangeChange={setTimeRange}
onFiltersChange={setFilters}
onSearchChange={setSearch}
onLiveChange={setLive}
onRefresh={handleRefresh}
className="bg-card flex min-h-0 flex-1 flex-col">
<Logs.Explorer />
</Logs.Root>
</div>
);
}
15 changes: 6 additions & 9 deletions ui/provider/src/pages/workload-detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
* "what's wrong with this workload" from a customer: Overview surfaces raw
* conditions (not just a coarse health enum), Instances is the direct
* per-instance drill-down (image pull failures, crash loops, scheduling
* gates, quota), Events/Logs/Metrics are honest "Coming Soon" placeholders
* since none of those have a data source wired up yet, and YAML gives an
* escape hatch to the raw resource for anything the tabs don't surface.
* gates, quota), Logs mounts the empty datum-ui explorer until Loki is
* wired, Events/Metrics stay honest "Coming Soon" placeholders, and YAML
* gives an escape hatch to the raw resource for anything the tabs don't
* surface.
*
* `projectName` comes from `useParams()` resolving the ancestor route param
* from staff-portal's project-scoped plugin mount
Expand All @@ -21,6 +22,7 @@ import { ConditionsTable } from '../components/conditions-table';
import { DetailList, StatusBadge } from '../components/detail-list';
import { StatStrip, type Stat } from '../components/stat-strip';
import { ErrorOrRestrictedState, LoadingSkeleton } from '../components/states';
import { WorkloadLogsExplorer } from '../components/workload-logs';
import { useWorkload, useWorkloadInstances, useWorkloadRaw } from '../lib/api';
import {
healthToBadgeType,
Expand Down Expand Up @@ -336,12 +338,7 @@ export default function WorkloadDetail() {
/>
</TabsContent>
<TabsContent value="Logs">
<EmptyContent
title="logs aren't available yet"
subtitle="Instance log aggregation isn't wired up in this view yet."
size="sm"
variant="dashed"
/>
<WorkloadLogsExplorer />
</TabsContent>
<TabsContent value="Metrics">
<EmptyContent
Expand Down
3 changes: 3 additions & 0 deletions ui/provider/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ export default defineConfig({
'@datum-cloud/datum-ui/button': { singleton: true, requiredVersion: false },
'@datum-cloud/datum-ui/card': { singleton: true, requiredVersion: false },
'@datum-cloud/datum-ui/icons': { singleton: true, requiredVersion: false },
// Do not share `logs`: MF colocates lucide-react / date-fns into the
// logs loadShare chunk, so a host-provided logs module replaces those
// exports and crashes WorkloadDetail / related pages.
'@datum-cloud/datum-ui/skeleton': { singleton: true, requiredVersion: false },
},
}),
Expand Down
Loading