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
63 changes: 63 additions & 0 deletions .github/workflows/ui-plugins.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: UI Plugins

# Typechecks and unit-tests the portal plugins under ui/. Each is its own npm
# project with its own lockfile, so this runs per plugin. Their images are
# built by publish.yaml, which never ran either check.
#
# No Go toolchain: the consumer plugin's shell wasm client is optional at build
# time and the tests don't load it.

on:
push:
branches: [main]
paths:
- 'ui/**'
- '.github/workflows/ui-plugins.yml'
pull_request:
paths:
- 'ui/**'
- '.github/workflows/ui-plugins.yml'

concurrency:
group: ui-plugins-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
check:
name: ${{ matrix.plugin }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- plugin: consumer
test: true
# ui/provider has no tests yet.
- plugin: provider
test: false
defaults:
run:
working-directory: ui/${{ matrix.plugin }}
steps:
- name: Clone the code
uses: actions/checkout@v7

- name: Setup Node
uses: actions/setup-node@v7
with:
node-version-file: ui/${{ matrix.plugin }}/.nvmrc
cache: npm
cache-dependency-path: ui/${{ matrix.plugin }}/package-lock.json

- name: Install dependencies
run: npm ci --ignore-scripts --no-audit --no-fund

- name: Typecheck
run: npm run typecheck

- name: Unit tests
if: matrix.test
run: npm test
50 changes: 30 additions & 20 deletions ui/consumer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ parts that depended on portal internals:
| `runDetailLoader`/`runListLoader` server-side RBAC gate | Client-side catch of a non-ok/403 `fetch()` response → inline restricted state |
| `paths.config.ts` + `getPathWithParams` | `useParams()` / `useLocation()` / `useNavigate()` from the shared `react-router` singleton |

`workload.schema.ts`/`instance.schema.ts` (combined into `src/schema.ts`),
`workload.schema.ts`/`instance.schema.ts` (combined into `src/schema.ts`, as
plain types rather than Zod schemas),
`workload.adapter.ts`/`instance.adapter.ts` (combined into `src/adapter.ts`),
`cli-section.tsx`, and `compute.helper.ts` (as `src/lib/format.ts`) ported
over near-verbatim — they were already free of portal internals (aside from
Expand Down Expand Up @@ -202,8 +203,15 @@ Three things stay in lockstep, same as the sample plugin:

The host provides `react`, `react-dom`, `react-router`, and
`@tanstack/react-query` as shared singletons (host's exact instances — see
`vite.config.ts`). This plugin bundles its own copy of `@datum-cloud/datum-ui`
(not shared as a singleton in v1), so its CSS ships with the bundle.
`vite.config.ts`). It also shares a curated set of `@datum-cloud/datum-ui`
subpaths (cloud-portal's `federation-host.ts`, `DATUM_UI_SHARED`); the ones
listed in this plugin's `shared` config resolve to the host's copy, and any
other datum-ui subpath the plugin imports is bundled into the remote.

Keep the plugin's versions of these packages at the host's resolved versions
(cloud-portal's `package-lock.json`), not npm's latest: the host's copy is
what runs, so a newer local version only lets the plugin type-check against
APIs the host doesn't have.

## Network interface traffic

Expand All @@ -224,29 +232,31 @@ values of `network` on the receive metric. If no value matches the instance's
interfaces, the page keeps showing "Not collected yet". The charts appear
when series exist for the instance's interfaces.

## Serving

`vite build` minifies and emits source maps; the browser fetches a map only
when devtools is open. `serve.ts` sends a weak `ETag` and `Last-Modified` and
answers conditional requests with `304`. The portal's asset proxy serves
`remoteEntry.js` and the manifests as `no-cache`, so every page load
revalidates them; hashed chunks under `assets/` are cached for a year.

## File layout

```
ui/consumer/
vite.config.ts MF container "workload.compute.datumapis.com"
serve.ts static HTTPS server for dist/ (the image's entrypoint)
public/plugin-manifest.json
src/
lib/api.ts fetch wrappers + useQuery hooks (workloads/instances/HTTPProxy)
lib/prometheus.ts queryapi metric queries + useQuery hooks
lib/prometheus-format.ts Prometheus results → chart series / card values
lib/o11y-logs.ts Loki query_range + ALB LogQL
schema.ts view-model types for Workload / Instance
adapter.ts raw K8s JSON → view models
pages/ exposed pages and the tabs they nest
cards/ project-home column
components/ shared UI (tables, topology, charts, shell, dialogs)
lib/api.ts fetch wrappers + useQuery hooks (workloads/instances/HTTPProxy)
lib/prometheus*.ts queryapi metric queries and result formatting
lib/metrics-queries.ts PromQL builders + instance identity discovery
lib/network-interface-metrics.ts probe for network interface metric labels
lib/format.ts formatUptime / splitSlashValue (ported as-is)
schema.ts Zod schemas for Workload / Instance
adapter.ts raw K8s JSON → schema mappers
components/cli-section.tsx CommandBlock / SectionCard / CliBanner
components/states.tsx Loading / Error / Restricted state components
pages/workload-list.tsx
pages/workload-detail.tsx
pages/instance-detail.tsx
pages/instance-overview.tsx
pages/instance-logs.tsx
pages/instance-metrics.tsx
main.tsx standalone preview harness only
lib/o11y-logs.ts Loki query_range + ALB LogQL
lib/console-client/ shell Web Worker and wasm client adapter
main.tsx standalone preview harness only
```
Loading
Loading