Release govoplan-templates v0.1.22: bound rendering and improve dialog layout
This commit is contained in:
+3
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@govoplan/templates-webui",
|
||||
"version": "0.1.21",
|
||||
"version": "0.1.22",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
@@ -14,10 +14,11 @@
|
||||
"./styles/templates.css": "./src/styles/templates.css"
|
||||
},
|
||||
"scripts": {
|
||||
"test:dialog-layout": "node scripts/test-dialog-layout.mjs",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@govoplan/core-webui": "^0.1.18",
|
||||
"@govoplan/core-webui": "^0.1.45",
|
||||
"lucide-react": "^1.23.0",
|
||||
"react": ">=19.2.7 <20",
|
||||
"react-dom": ">=19.2.7 <20",
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
|
||||
const page = readFileSync(new URL("../src/features/templates/TemplatesPage.tsx", import.meta.url), "utf8");
|
||||
const styles = readFileSync(new URL("../src/styles/templates.css", import.meta.url), "utf8");
|
||||
assert.match(page, /<Dialog open=\{createOpen\}[^]*?<FormGrid columns=\{2\} collapseAt="standard">/);
|
||||
assert.doesNotMatch(page, /templates-dialog-form/);
|
||||
assert.doesNotMatch(styles, /templates-dialog-form/);
|
||||
console.log("Templates dialog uses the shared shrinking form layout.");
|
||||
@@ -9,13 +9,14 @@ import {
|
||||
X
|
||||
} from "lucide-react";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { DialogSection, ActionToolbar,
|
||||
import { FormGrid, ActionToolbar,
|
||||
ApiError,
|
||||
ActionBlockerHint,
|
||||
Button,
|
||||
ConfirmDialog,
|
||||
ContentSection,
|
||||
Dialog,
|
||||
DialogSection,
|
||||
DocumentationHelpLink,
|
||||
DismissibleAlert,
|
||||
FilterBar,
|
||||
@@ -302,6 +303,14 @@ export default function TemplatesPage({ settings, auth }: Props) {
|
||||
|
||||
return (
|
||||
<WorkspaceFrame as="main" height="viewport" surface="plain" className="templates-page" label="Template workspace">
|
||||
<WorkspaceActionBar
|
||||
scope="workspace"
|
||||
variant="collection"
|
||||
refreshable
|
||||
reloadAction={{ onReload: () => void reload(selectedId), loading: loading || busy }}
|
||||
contextActions={<strong>Template library</strong>}
|
||||
createAction={<IconButton label="Add template" icon={<Plus size={17} />} variant="primary" disabled={!canWrite} disabledReason={!canWrite ? TEMPLATES_I18N.writeReason : undefined} onClick={() => requestDiscard(() => setCreateOpen(true))} />}
|
||||
/>
|
||||
<WorkspaceLayout
|
||||
variant="split"
|
||||
primarySize="compact"
|
||||
@@ -312,14 +321,6 @@ export default function TemplatesPage({ settings, auth }: Props) {
|
||||
contentLabel="Template workspace"
|
||||
contentClassName="templates-workspace"
|
||||
primary={<>
|
||||
<WorkspaceActionBar
|
||||
scope="collection-pane"
|
||||
variant="collection"
|
||||
refreshable
|
||||
reloadAction={{ onReload: () => void reload(selectedId), loading: loading || busy }}
|
||||
contextActions={<strong>Template library</strong>}
|
||||
createAction={<IconButton label="Add template" icon={<Plus size={17} />} variant="primary" disabled={!canWrite} disabledReason={!canWrite ? TEMPLATES_I18N.writeReason : undefined} onClick={() => requestDiscard(() => setCreateOpen(true))} />}
|
||||
/>
|
||||
<FilterBar surface="panel"><input value={search} onChange={(event) => setSearch(event.target.value)} placeholder="Search templates" /></FilterBar>
|
||||
<SelectionList variant="navigation" label="Templates">
|
||||
{visibleItems.map((item) => (
|
||||
@@ -418,9 +419,11 @@ export default function TemplatesPage({ settings, auth }: Props) {
|
||||
</WorkspaceLayout>
|
||||
|
||||
<Dialog open={createOpen} title="Add template" onClose={closeCreate} closeDisabled={busy} footer={<><Button onClick={closeCreate} disabled={busy} disabledReason={busy ? TEMPLATES_I18N.busy : undefined}>Cancel</Button><Button variant="primary" disabled={!createName.trim() || busy} disabledReason={busy ? TEMPLATES_I18N.busy : !createName.trim() ? TEMPLATES_I18N.incomplete : undefined} onClick={() => void create()}>Create</Button></>}>
|
||||
<DialogSection className="templates-dialog-form">
|
||||
<FormField label="Name" documentation={TEMPLATE_FIELDS_DOCUMENTATION}><input autoFocus value={createName} onChange={(event) => setCreateName(event.target.value)} /></FormField>
|
||||
<FormField label="Type" documentation={TEMPLATE_FIELDS_DOCUMENTATION}><select value={createType} onChange={(event) => setCreateType(event.target.value as TemplateType)}>{TEMPLATE_TYPES.map((item) => <option key={item.value} value={item.value}>{item.label}</option>)}</select></FormField>
|
||||
<DialogSection>
|
||||
<FormGrid columns={2} collapseAt="standard">
|
||||
<FormField label="Name" documentation={TEMPLATE_FIELDS_DOCUMENTATION}><input autoFocus value={createName} onChange={(event) => setCreateName(event.target.value)} /></FormField>
|
||||
<FormField label="Type" documentation={TEMPLATE_FIELDS_DOCUMENTATION}><select value={createType} onChange={(event) => setCreateType(event.target.value as TemplateType)}>{TEMPLATE_TYPES.map((item) => <option key={item.value} value={item.value}>{item.label}</option>)}</select></FormField>
|
||||
</FormGrid>
|
||||
</DialogSection>
|
||||
</Dialog>
|
||||
<ConfirmDialog open={publishOpen} title="i18n:govoplan-templates.publish_title" message="i18n:govoplan-templates.publish_message" confirmLabel="Publish" busy={busy} onCancel={() => setPublishOpen(false)} onConfirm={() => void publish()} />
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
.templates-content { height: 100%; min-width: 0; min-height: 0; overflow: auto; padding: 14px; }
|
||||
.templates-definition-fields { display: grid; grid-template-columns: minmax(220px, 1.4fr) repeat(3, minmax(130px, .7fr)); gap: 12px; margin-bottom: 14px; }
|
||||
.templates-definition-fields .form-field:nth-child(5) { grid-column: span 2; }
|
||||
.templates-definition-fields input, .templates-definition-fields select, .templates-dialog-form input, .templates-dialog-form select, .templates-layout-fields input, .templates-layout-fields select, .templates-preview-controls select { width: 100%; }
|
||||
.templates-definition-fields input, .templates-definition-fields select, .templates-layout-fields input, .templates-layout-fields select, .templates-preview-controls select { width: 100%; }
|
||||
|
||||
.templates-section-heading small { color: var(--muted); font-weight: 400; }
|
||||
.templates-section-heading .btn { display: inline-flex; align-items: center; gap: 6px; }
|
||||
@@ -39,7 +39,6 @@
|
||||
.templates-history-list small { margin-top: 3px; color: var(--muted); font-size: 11px; }
|
||||
.templates-history-list .btn { display: inline-flex; align-items: center; gap: 6px; }
|
||||
.templates-history-badges { display: flex; align-items: center; gap: 6px; }
|
||||
.templates-dialog-form { display: grid; grid-template-columns: minmax(220px, 1fr) minmax(180px, .7fr); gap: 12px; min-width: min(560px, 80vw); }
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
.templates-definition-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||||
@@ -54,5 +53,5 @@
|
||||
.templates-workspace-toolbar { align-items: flex-start; flex-wrap: wrap; }
|
||||
.templates-toolbar-actions { flex-wrap: wrap; }
|
||||
.templates-content { height: auto; overflow: visible; }
|
||||
.templates-definition-fields, .templates-dialog-form, .templates-render-result dl { grid-template-columns: 1fr; }
|
||||
.templates-definition-fields, .templates-render-result dl { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user