Adopt shared WebUI structural primitives

This commit is contained in:
2026-08-18 13:17:32 +02:00
parent 3800ad4662
commit e7ee0b8017
2 changed files with 13 additions and 56 deletions
+11 -11
View File
@@ -21,12 +21,15 @@ import { DialogForm, ActionToolbar,
Dialog,
DismissibleAlert,
DocumentationHelpLink,
FilterBar,
FormField,
i18nMessage,
LoadingIndicator,
PageScrollViewport,
StatePanel,
StatusBadge,
useTemporalDataContext,
WorkspaceFrame,
type DataGridColumn,
type PlatformRouteContext
} from "@govoplan/core-webui";
@@ -232,8 +235,8 @@ export default function RecordsPage({ settings, auth }: PlatformRouteContext) {
return (
<main className="records-page" data-help-context-id="records.workspace">
<div className="records-shell">
<ActionToolbar className="records-toolbar">
<WorkspaceFrame className="records-shell" label="Records workspace" interfaceId="records.workspace" helpContextId="records.workspace" helpModuleId="records">
<ActionToolbar surface="panel-header" className="records-toolbar">
<Button
type="button"
variant="primary"
@@ -254,7 +257,7 @@ export default function RecordsPage({ settings, auth }: PlatformRouteContext) {
Catalog
</Button>
)}
<form className="records-search" onSubmit={submitSearch}>
<FilterBar as="form" surface="control" wrap="never" width="compact" className="records-search" onSubmit={submitSearch}>
<Search size={17} aria-hidden="true" />
<input
value={query}
@@ -262,7 +265,7 @@ export default function RecordsPage({ settings, auth }: PlatformRouteContext) {
aria-label="Search records"
placeholder="Search records"
/>
</form>
</FilterBar>
<span className="records-result-count">
{i18nMessage("i18n:govoplan-records.record_count", { value0: total })}
</span>
@@ -319,7 +322,7 @@ export default function RecordsPage({ settings, auth }: PlatformRouteContext) {
</button>
))}
{!loading && catalog.file_plan.length === 0 && (
<p className="records-empty-note">No file-plan nodes are configured.</p>
<StatePanel size="inline" description="No file-plan nodes are configured." />
)}
</PageScrollViewport>
</aside>
@@ -360,10 +363,7 @@ export default function RecordsPage({ settings, auth }: PlatformRouteContext) {
{detailLoading && <LoadingIndicator label="Loading record" />}
{detailError && <DismissibleAlert tone="danger" resetKey={detailError}>{detailError}</DismissibleAlert>}
{!detailLoading && !detailError && !detail && (
<div className="records-detail-empty">
<Archive size={28} aria-hidden="true" />
<p>Select a record to inspect its contents and chronology.</p>
</div>
<StatePanel size="fill" icon={<Archive size={28} />} title="Records" description="Select a record to inspect its contents and chronology." />
)}
{!detailLoading && detail && (
<RecordDetailPanel
@@ -381,7 +381,7 @@ export default function RecordsPage({ settings, auth }: PlatformRouteContext) {
)}
</section>
</div>
</div>
</WorkspaceFrame>
<RecordDialog
open={createOpen}
@@ -508,7 +508,7 @@ function RecordDetailPanel({
<span>{detail.items.length}</span>
</div>
{detail.items.length === 0 ? (
<p className="records-empty-note">No items have been filed in this temporal view.</p>
<StatePanel size="inline" description="No items have been filed in this temporal view." />
) : (
<div className="records-item-list">
{detail.items.map((item) => (
+2 -45
View File
@@ -1,40 +1,14 @@
.records-page,
.records-shell {
.records-page {
height: 100%;
min-height: 0;
overflow: hidden;
}
.records-shell {
display: flex;
flex-direction: column;
background: var(--panel);
}
.records-toolbar {
display: flex;
align-items: center;
gap: 10px;
min-height: 58px;
padding: 9px 14px;
border-bottom: var(--border-line-dark);
background: var(--panel-header);
}
.records-search {
display: flex;
align-items: center;
gap: 8px;
width: min(420px, 100%);
flex: 1 1 420px;
margin-left: 8px;
}
.records-search input {
min-width: 130px;
height: 36px;
flex: 1;
}
.records-result-count {
margin-left: auto;
color: var(--muted);
@@ -205,17 +179,6 @@
padding: 18px 20px 32px;
}
.records-detail-empty {
display: grid;
place-items: center;
align-content: center;
gap: 10px;
height: 100%;
color: var(--muted);
padding: 30px;
text-align: center;
}
.records-detail-header,
.records-detail-actions,
.records-section-heading {
@@ -529,12 +492,6 @@
font-weight: 700;
}
.records-empty-note {
margin: 12px;
color: var(--muted);
font-size: var(--font-size-sm);
}
.records-dialog {
width: min(760px, calc(100vw - 32px));
}