diff --git a/webui/src/features/datasources/DatasourcesPage.tsx b/webui/src/features/datasources/DatasourcesPage.tsx index 44dcfe0..0e54ec1 100644 --- a/webui/src/features/datasources/DatasourcesPage.tsx +++ b/webui/src/features/datasources/DatasourcesPage.tsx @@ -23,14 +23,24 @@ import { FormGrid, DialogSection, ToolbarGroup, ActionToolbar, ActionBlockerHint, Button, ConfirmDialog, + ContentSection, Dialog, DocumentationHelpLink, DismissibleAlert, + FilterBar, FormField, IconButton, LoadingFrame, + MetricCard, + MetricGrid, SegmentedControl, + SelectionList, + SelectionListItem, + SelectionListItemContent, + StatePanel, StatusBadge, + WorkspaceFrame, + WorkspaceLayout, hasScope, isApiError, useUnsavedChanges, @@ -284,10 +294,18 @@ export default function DatasourcesPage({ }; return ( -
-
-
-
+ -
+ -
+ {view === "catalogue" ? visibleDatasources.map((item) => ( - + )) : null} {view === "staging" ? visibleStages.map((item) => ( - + )) : null} {view === "origins" ? visibleOrigins.map((item) => ( - + )) : null} {view === "catalogue" && !visibleDatasources.length ? ( -
No datasources
+ ) : null} {view === "staging" && !visibleStages.length ? ( -
No staged data
+ ) : null} {view === "origins" && !visibleOrigins.length ? ( -
- {originsAvailable ? "No connector origins" : "Connectors unavailable"} -
+ ) : null} -
+
- - -
- + } + > + {view === "catalogue" ? : view === "staging" ? @@ -522,8 +525,7 @@ export default function DatasourcesPage({ ) : null} {working ?
Working...
: null} -
- + setRetireOpen(false)} onConfirm={() => void retireSelected()} /> -
+ ); } @@ -624,24 +626,24 @@ function DatasourceDetail({ }) { return ( <> -
- - - - - -
+ + + + + + + {datasource.description ? (
{datasource.description}
) : null} -
-
+ + Governance -
+
Authority{readableToken(datasource.governance.authority_mode)} Classification{datasource.governance.classification} @@ -653,25 +655,25 @@ function DatasourceDetail({ {datasource.governance.semantic_definition ? (

{datasource.governance.semantic_definition}

) : null} -
-
-
+ + + Preview {preview ? `${formatNumber(preview.total_rows)} total rows` : ""} -
+ {loading ? (
Loading preview...
) : preview ? ( ) : ( -
No preview available
+ )} -
-
-
+ + + Materializations Immutable revisions -
+
@@ -708,14 +710,14 @@ function DatasourceDetail({
-
-
-
+ + + Schema Version {datasource.schema_version} -
+ -
+ ); } @@ -727,21 +729,21 @@ function StageDetail({ stage }: { stage: DatasourceStage }) { const schemaClassification = stage.validation.schema_change?.classification ?? "new"; return ( <> -
- - - - - -
-
-
+ + + + + + + + + Validation -
+
Fingerprint{shortFingerprint(stage.fingerprint)} Target{stage.target_datasource_ref || "New datasource"} @@ -770,27 +772,27 @@ function StageDetail({ stage }: { stage: DatasourceStage }) { All configured quality rules passed and no blocking schema change was detected.
)} -
+ {schemaChanges.length ? ( -
-
+ + Schema comparison -
+ -
+ ) : null} -
-
+ + Detected schema {stage.shape} -
+ -
+ ); } @@ -834,22 +836,22 @@ function SchemaChangeItem({ change }: { change: DatasourceSchemaChange }) { function OriginDetail({ origin }: { origin: DatasourceOrigin }) { return ( <> -
- - - - - - -
+ + + + + + + + {origin.description ? (
{origin.description}
) : null} -
-
+ + Registration options {origin.supported_modes.join(", ")} -
+
Origin reference{origin.ref} Kind{readableToken(origin.kind)} @@ -858,14 +860,14 @@ function OriginDetail({ origin }: { origin: DatasourceOrigin }) { Health{origin.health.summary} Pushdown{pushdownSummary(origin)}
-
-
-
+ + + Discovered schema Version {origin.schema_version} -
+ -
+ ); } @@ -1479,17 +1481,8 @@ function SchemaTable({ fields }: { fields: Datasource["schema"] }) { ); } -function Metric({ label, value }: { label: string; value: string }) { - return ( - - {label} - {value} - - ); -} - function EmptyWorkspace({ icon, label }: { icon: React.ReactNode; label: string }) { - return
{icon}{label}
; + return ; } function filterItems( diff --git a/webui/src/styles/datasources.css b/webui/src/styles/datasources.css index 60d7ef7..ef5b15e 100644 --- a/webui/src/styles/datasources.css +++ b/webui/src/styles/datasources.css @@ -1,65 +1,9 @@ -.datasources-page { - position: relative; - height: calc(100vh - 115px); - min-width: 0; - min-height: 0; - padding: 0; - overflow: hidden; - color: var(--text); - background: var(--bg); -} - -.datasources-page *, -.datasources-page *::before, -.datasources-page *::after { - box-sizing: border-box; -} - -.datasources-shell { - display: grid; - grid-template-columns: minmax(250px, 300px) minmax(0, 1fr); - width: 100%; - height: 100%; - min-width: 0; - min-height: 0; - overflow: hidden; - border: var(--border-line); - background: var(--panel); -} - -.datasources-sidebar, -.datasources-workspace, .datasources-content, .datasources-list-frame { min-width: 0; min-height: 0; } -.datasources-sidebar { - display: flex; - flex-direction: column; - overflow: hidden; - border-right: var(--border-line); - background: var(--panel-soft); -} - -.datasources-sidebar-toolbar, -.datasources-workspace-toolbar, -.datasources-section-heading { - display: flex; - align-items: center; - justify-content: space-between; - gap: 10px; - flex: 0 0 auto; - border-bottom: var(--border-line); - background: var(--panel-header); -} - -.datasources-sidebar-toolbar { - min-height: 52px; - padding: 8px 10px 8px 14px; -} - .datasources-toolbar-actions, .datasources-current-title, .datasources-current-title > span, @@ -75,80 +19,11 @@ background: var(--panel); } -.datasources-search { - padding: 9px; - border-bottom: var(--border-line); -} - -.datasources-search input { - width: 100%; - min-height: 34px; - padding: 7px 9px; -} - .datasources-list-frame { flex: 1 1 auto; overflow: hidden; } -.datasources-list { - height: 100%; - overflow: auto; - padding: 6px; -} - -.datasources-list > button { - display: grid; - grid-template-columns: minmax(0, 1fr) auto; - align-items: center; - gap: 8px; - width: 100%; - min-height: 56px; - padding: 8px 9px; - border: 0; - border-radius: var(--radius-sm); - background: transparent; - color: var(--text); - cursor: pointer; - text-align: left; -} - -.datasources-list > button:hover, -.datasources-list > button:focus-visible { - background: var(--primary-soft); - outline: none; -} - -.datasources-list > button.is-selected { - background: var(--primary-soft-strong); - box-shadow: inset 3px 0 0 var(--accent); -} - -.datasources-list > button > span:first-child { - min-width: 0; -} - -.datasources-list strong, -.datasources-list small { - display: block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.datasources-list strong { - color: var(--text-strong); - font-size: 13px; -} - -.datasources-list small { - margin-top: 4px; - color: var(--muted); - font-size: 11px; -} - -.datasources-list-empty, -.datasources-inline-empty, .datasources-inline-loading { display: grid; place-items: center; @@ -158,17 +33,8 @@ text-align: center; } -.datasources-workspace { - position: relative; - display: flex; - flex-direction: column; - overflow: hidden; - background: var(--bg); -} - .datasources-workspace-toolbar { - min-height: 58px; - padding: 8px 10px 8px 14px; + min-width: 0; } .datasources-current-title { @@ -218,43 +84,6 @@ padding: 14px; } -.datasources-metrics { - display: grid; - grid-template-columns: repeat(5, minmax(100px, 1fr)); - gap: 8px; - margin-bottom: 14px; -} - -.datasources-metrics > span { - min-width: 0; - min-height: 61px; - padding: 9px 10px; - border: var(--border-line); - border-radius: var(--radius-sm); - background: var(--panel); -} - -.datasources-metrics small, -.datasources-metrics strong { - display: block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.datasources-metrics small { - color: var(--muted); - font-size: 10px; - text-transform: uppercase; -} - -.datasources-metrics strong { - margin-top: 6px; - color: var(--text-strong); - font-size: 14px; - text-transform: capitalize; -} - .datasources-description { margin-bottom: 14px; padding: 10px 12px; @@ -265,18 +94,6 @@ line-height: 1.45; } -.datasources-detail-section { - min-width: 0; - margin-bottom: 14px; - border: var(--border-line); - background: var(--panel); -} - -.datasources-section-heading { - min-height: 42px; - padding: 7px 10px; -} - .datasources-section-heading > span { color: var(--text-strong); font-size: 13px; @@ -501,26 +318,10 @@ overflow: auto; } - .datasources-shell { - grid-template-columns: 1fr; - height: auto; - overflow: visible; - } - - .datasources-sidebar { - max-height: 42vh; - border-right: 0; - border-bottom: var(--border-line); - } - .datasources-workspace { min-height: 58vh; } - .datasources-metrics { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - .datasources-workspace-toolbar { align-items: flex-start; flex-wrap: wrap; @@ -532,7 +333,6 @@ } @media (max-width: 560px) { - .datasources-metrics, .datasources-key-values { grid-template-columns: 1fr; }