@zerotal/admin 1.8.1 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/api-surface.md +0 -55
- package/package.json +9 -9
- package/src/Cluster.ts +5 -1
- package/src/PanelInstance.ts +2 -0
- package/src/Resource.ts +1 -0
- package/src/actions/Action.ts +5 -1
- package/src/actions/render.tsx +9 -1
- package/src/auth/AuthLayout.tsx +1 -0
- package/src/form/ResourceForm.ts +1 -0
- package/src/pages/AdminPage.ts +2 -0
- package/src/pages/ConsolePage.tsx +3 -0
- package/src/pages/DashboardPage.tsx +5 -1
- package/src/pages/MediaPage.tsx +6 -1
- package/src/pages/NotificationsPage.tsx +6 -1
- package/src/pages/RecordViewPage.tsx +3 -0
- package/src/pages/ResourceFormPage.tsx +6 -1
- package/src/pages/ResourceListPage.tsx +3 -0
- package/src/pages/RolesPage.tsx +6 -1
- package/src/pages/SearchPage.tsx +5 -1
- package/src/plugin.ts +4 -0
- package/src/table/Column.ts +1 -0
- package/src/ui/AdminLayout.tsx +3 -0
- package/src/widgets/render.tsx +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,28 @@ follows the Zerotal monorepo's unified versioning.
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [1.9.0] — 2026-08-29
|
|
12
|
+
|
|
13
|
+
### Documented
|
|
14
|
+
|
|
15
|
+
- **Every promised export is documented.** The `docs-coverage` gate reads `maturity: stable` as a
|
|
16
|
+
promise about a package's exports, and measures how much of that promise is written down. It
|
|
17
|
+
was 798 gaps across the suite; it is now zero. This package's share is covered on its own
|
|
18
|
+
pages — types named, options shapes described, and the decisions behind them recorded where
|
|
19
|
+
somebody looking for them will find them.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **INTERNAL: the panel's own page machinery is marked `@internal`.** The `make*Page` factories,
|
|
24
|
+
the page classes they produce (`ResourceListPage`, `RecordViewPage`, `ResourceFormPage`,
|
|
25
|
+
`RolesPage`, `MediaPage`, `NotificationsPage`, `ConsolePage`, …), the action and widget
|
|
26
|
+
renderers, and `AdminPanelHost`.
|
|
27
|
+
|
|
28
|
+
**Nothing is removed and nothing breaks** — they are still exported and still work. An app
|
|
29
|
+
declares a `Resource` and the panel builds these pages from it; none of them has a caller
|
|
30
|
+
outside `@zerotal/admin` or a line in the guide, because writing one was never the way to use
|
|
31
|
+
this package.
|
|
32
|
+
|
|
11
33
|
## [1.6.0] — 2026-08-15
|
|
12
34
|
|
|
13
35
|
### Fixed
|
package/api-surface.md
CHANGED
|
@@ -1114,12 +1114,6 @@ interface ActionContext = {
|
|
|
1114
1114
|
slug: string
|
|
1115
1115
|
}
|
|
1116
1116
|
|
|
1117
|
-
interface ActionPage = {
|
|
1118
|
-
download?: (filename: string, content: string | Uint8Array, mime?: string) => unknown
|
|
1119
|
-
flash: (message: string, level?: string) => unknown
|
|
1120
|
-
redirect: (url: string) => { withSuccess(message: string): unknown;}
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
1117
|
interface AdminAuthConfig = {
|
|
1124
1118
|
authMiddleware?: MiddlewareClass[]
|
|
1125
1119
|
authenticateWhen?: (user: unknown) => boolean | Promise<boolean>
|
|
@@ -1170,18 +1164,6 @@ interface AdminNotification = {
|
|
|
1170
1164
|
title: string
|
|
1171
1165
|
}
|
|
1172
1166
|
|
|
1173
|
-
interface AdminPanelHost = {
|
|
1174
|
-
console: (contribution: ConsoleContribution) => void
|
|
1175
|
-
enabled: (id: string) => boolean
|
|
1176
|
-
navItem: (contribution: NavContribution) => void
|
|
1177
|
-
page: (contribution: PageContribution) => void
|
|
1178
|
-
renderHook: (name: string, hook: (context: RenderHookContext) => HtmlNode | string | null) => void
|
|
1179
|
-
searchProvider: (provider: PanelSearchProvider) => void
|
|
1180
|
-
topbarSlot: (slot: TopbarSlot) => void
|
|
1181
|
-
userMenuItem: (item: UserMenuContribution) => void
|
|
1182
|
-
widget: (contribution: WidgetContribution) => void
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
1167
|
interface AdminPlugin = {
|
|
1186
1168
|
id: string
|
|
1187
1169
|
install: (panel: AdminPanelHost) => void | Promise<void>
|
|
@@ -1492,22 +1474,6 @@ interface PageContribution = {
|
|
|
1492
1474
|
title: string
|
|
1493
1475
|
}
|
|
1494
1476
|
|
|
1495
|
-
interface PanelPage = {
|
|
1496
|
-
ability: string | undefined
|
|
1497
|
-
cluster?: typeof Cluster | undefined
|
|
1498
|
-
navigationBadge?: (() => Promise<string | number | null> | string | number | null) | undefined
|
|
1499
|
-
navigationBadgeColor?: BadgeTone | undefined
|
|
1500
|
-
navigationGroup: string | undefined
|
|
1501
|
-
navigationIcon: string
|
|
1502
|
-
navigationLabel: string
|
|
1503
|
-
navigationSort: number
|
|
1504
|
-
page: PanelPageClass
|
|
1505
|
-
routeParams: string[]
|
|
1506
|
-
showInNavigation: boolean
|
|
1507
|
-
slug: string
|
|
1508
|
-
title: string
|
|
1509
|
-
}
|
|
1510
|
-
|
|
1511
1477
|
interface PanelSearchProvider = {
|
|
1512
1478
|
ability: string
|
|
1513
1479
|
icon?: string
|
|
@@ -1527,19 +1493,6 @@ interface PivotColumn = {
|
|
|
1527
1493
|
label?: string
|
|
1528
1494
|
}
|
|
1529
1495
|
|
|
1530
|
-
interface RecordPage = {
|
|
1531
|
-
lastPage: number
|
|
1532
|
-
page: number
|
|
1533
|
-
perPage: number
|
|
1534
|
-
rows: Record<string, unknown>[]
|
|
1535
|
-
total: number
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1538
|
-
interface RenderableCell = {
|
|
1539
|
-
badge?: BadgeTone | undefined
|
|
1540
|
-
text: string
|
|
1541
|
-
}
|
|
1542
|
-
|
|
1543
1496
|
interface RenderHookContext = {
|
|
1544
1497
|
page?: 'list' | 'record' | 'form' | 'dashboard' | undefined
|
|
1545
1498
|
recordId?: string | undefined
|
|
@@ -1663,8 +1616,6 @@ type ActionVisible = (record: AdminRecord | undefined, ctx: ActionContext) => bo
|
|
|
1663
1616
|
|
|
1664
1617
|
type AdminAuthorizer = (ability: string) => boolean | Promise<boolean>
|
|
1665
1618
|
|
|
1666
|
-
type AdminPageClass = typeof AdminPage & (new () => AdminPage)
|
|
1667
|
-
|
|
1668
1619
|
type BadgeTone = 'default' | 'primary' | 'success' | 'muted' | 'destructive'
|
|
1669
1620
|
|
|
1670
1621
|
type CalloutTone = 'default' | 'primary' | 'success' | 'warning' | 'destructive'
|
|
@@ -1675,8 +1626,6 @@ type ChartResolver = () => Promise<ChartData> | ChartData
|
|
|
1675
1626
|
|
|
1676
1627
|
type ChartType = 'line' | 'bar' | 'doughnut' | 'pie'
|
|
1677
1628
|
|
|
1678
|
-
type ClusterClass = typeof Cluster
|
|
1679
|
-
|
|
1680
1629
|
type ColumnKind = 'text' | 'toggle' | 'select' | 'input' | 'image' | 'color' | 'icon'
|
|
1681
1630
|
|
|
1682
1631
|
type Conjunction = 'and' | 'or'
|
|
@@ -1711,8 +1660,6 @@ type FormComponent = FormSection | FormTabs | Wizard | FormSplit | Callout | Pri
|
|
|
1711
1660
|
|
|
1712
1661
|
type InfolistComponent = Section | Entry
|
|
1713
1662
|
|
|
1714
|
-
type PanelPageClass = new () => object
|
|
1715
|
-
|
|
1716
1663
|
type PrimeKind = 'text' | 'html' | 'image'
|
|
1717
1664
|
|
|
1718
1665
|
type QueryModifier = (query: AdminQuery) => AdminQuery
|
|
@@ -1727,8 +1674,6 @@ type RenderHookName = 'body.start' | 'body.end' | 'sidebar.start' | 'sidebar.end
|
|
|
1727
1674
|
|
|
1728
1675
|
type ResourceClass = typeof Resource
|
|
1729
1676
|
|
|
1730
|
-
type ResourceFormClass = new () => Form & Record<string, unknown>
|
|
1731
|
-
|
|
1732
1677
|
type StatsResolver = () => Promise<Stat[]> | Stat[]
|
|
1733
1678
|
|
|
1734
1679
|
type SummaryKind = 'sum' | 'avg' | 'count' | 'min' | 'max' | 'range'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zerotal/admin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"maturity": "stable",
|
|
6
6
|
"private": false,
|
|
@@ -32,16 +32,16 @@
|
|
|
32
32
|
"typecheck": "tsc --noEmit"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@zerotal/cache": "1.
|
|
36
|
-
"@zerotal/core": "1.
|
|
37
|
-
"@zerotal/flow": "1.
|
|
38
|
-
"@zerotal/flow-ui": "1.
|
|
39
|
-
"@zerotal/validator": "1.
|
|
35
|
+
"@zerotal/cache": "1.9.0",
|
|
36
|
+
"@zerotal/core": "1.9.0",
|
|
37
|
+
"@zerotal/flow": "1.9.0",
|
|
38
|
+
"@zerotal/flow-ui": "1.9.0",
|
|
39
|
+
"@zerotal/validator": "1.9.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@zerotal/orm": "1.
|
|
43
|
-
"@zerotal/auth": "1.
|
|
44
|
-
"@zerotal/queue": "1.
|
|
42
|
+
"@zerotal/orm": "1.9.0",
|
|
43
|
+
"@zerotal/auth": "1.9.0",
|
|
44
|
+
"@zerotal/queue": "1.9.0"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@zerotal/orm": "^1.0.0",
|
package/src/Cluster.ts
CHANGED
|
@@ -46,5 +46,9 @@ export abstract class Cluster {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* A Cluster subclass (used by its static surface — never instantiated).
|
|
51
|
+
*
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
50
54
|
export type ClusterClass = typeof Cluster;
|
package/src/PanelInstance.ts
CHANGED
|
@@ -72,6 +72,8 @@ export interface NavGroup {
|
|
|
72
72
|
* A registered custom page, normalized from either door — an {@link AdminPage}
|
|
73
73
|
* subclass registered by the app, or a {@link PageContribution} pushed in by a
|
|
74
74
|
* package.
|
|
75
|
+
*
|
|
76
|
+
* @internal
|
|
75
77
|
*/
|
|
76
78
|
export interface PanelPage {
|
|
77
79
|
slug: string;
|
package/src/Resource.ts
CHANGED
package/src/actions/Action.ts
CHANGED
|
@@ -25,7 +25,11 @@ import { flattenFields } from "../form/index.ts";
|
|
|
25
25
|
|
|
26
26
|
export type ActionColor = "default" | "primary" | "success" | "muted" | "destructive";
|
|
27
27
|
|
|
28
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Minimal view of the host page an action handler can drive (flash/redirect).
|
|
30
|
+
*
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
29
33
|
export interface ActionPage {
|
|
30
34
|
flash(message: string, level?: string): unknown;
|
|
31
35
|
redirect(url: string): { withSuccess(message: string): unknown };
|
package/src/actions/render.tsx
CHANGED
|
@@ -27,7 +27,11 @@ export interface RenderActionOptions {
|
|
|
27
27
|
args?: unknown[];
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* Render a single action. Link actions become `<a navigate>`, callbacks `<button>`.
|
|
32
|
+
*
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
31
35
|
export function renderAction(
|
|
32
36
|
a: Action,
|
|
33
37
|
ctx: ActionContext,
|
|
@@ -92,6 +96,8 @@ export function renderAction(
|
|
|
92
96
|
* Returns `null` when nothing inside is visible, so an empty menu never appears.
|
|
93
97
|
* `argsFor` builds each member's handler arguments, since those carry the
|
|
94
98
|
* action's own key.
|
|
99
|
+
*
|
|
100
|
+
* @internal
|
|
95
101
|
*/
|
|
96
102
|
export function renderActionGroup(
|
|
97
103
|
group: ActionGroup,
|
|
@@ -128,6 +134,8 @@ export function renderActionGroup(
|
|
|
128
134
|
/**
|
|
129
135
|
* Render an action as a full-width dropdown menu row (icon + label). Used by the
|
|
130
136
|
* row-action overflow menu when a row has more actions than fit inline.
|
|
137
|
+
*
|
|
138
|
+
* @internal
|
|
131
139
|
*/
|
|
132
140
|
export function renderActionMenuItem(
|
|
133
141
|
a: Action,
|
package/src/auth/AuthLayout.tsx
CHANGED
package/src/form/ResourceForm.ts
CHANGED
|
@@ -16,6 +16,7 @@ import type { RuleBuilder, FieldRule } from "@zerotal/validator";
|
|
|
16
16
|
import type { Field, FieldMode } from "./Field.ts";
|
|
17
17
|
import { type FormComponent, flattenFields } from "./Section.ts";
|
|
18
18
|
|
|
19
|
+
/** @internal */
|
|
19
20
|
export type ResourceFormClass = new () => Form & Record<string, unknown>;
|
|
20
21
|
|
|
21
22
|
/** @internal */
|
package/src/pages/AdminPage.ts
CHANGED
|
@@ -96,5 +96,7 @@ export abstract class AdminPage extends Component {
|
|
|
96
96
|
/**
|
|
97
97
|
* A concrete {@link AdminPage} subclass — the static metadata above, plus the
|
|
98
98
|
* zero-argument constructor Flow builds the page with.
|
|
99
|
+
*
|
|
100
|
+
* @internal
|
|
99
101
|
*/
|
|
100
102
|
export type AdminPageClass = typeof AdminPage & (new () => AdminPage);
|
|
@@ -36,6 +36,7 @@ const ALIGN: Record<string, string> = {
|
|
|
36
36
|
end: "text-right tabular-nums",
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
+
/** @internal */
|
|
39
40
|
export class ConsolePage extends Component {
|
|
40
41
|
static layout = AdminLayout;
|
|
41
42
|
|
|
@@ -304,6 +305,8 @@ function cell(c: ConsoleColumn, row: ConsoleRow): HtmlNode | string {
|
|
|
304
305
|
* shared class resolving itself from the route — keeps the console on a static
|
|
305
306
|
* and matches how resource list pages are generated. The explicit name matters:
|
|
306
307
|
* Flow's component registry is keyed by constructor name.
|
|
308
|
+
*
|
|
309
|
+
* @internal
|
|
307
310
|
*/
|
|
308
311
|
export function makeConsolePage(
|
|
309
312
|
console: ConsoleContribution,
|
|
@@ -253,7 +253,11 @@ export class DashboardPage extends Component {
|
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
/**
|
|
256
|
+
/**
|
|
257
|
+
* The dashboard for one panel, showing only that panel's resources and widgets.
|
|
258
|
+
*
|
|
259
|
+
* @internal
|
|
260
|
+
*/
|
|
257
261
|
export function makeDashboardPage(panel: PanelInstance = Panel.default()): typeof DashboardPage {
|
|
258
262
|
const Page = class extends DashboardPage {
|
|
259
263
|
static override panel = panel;
|
package/src/pages/MediaPage.tsx
CHANGED
|
@@ -15,6 +15,7 @@ import { deleteMedia, formatSize, isImage, isUpload, mediaUrl, storeMedia } from
|
|
|
15
15
|
/** How many files the grid shows before the "load more" step. */
|
|
16
16
|
const PAGE_SIZE = 60;
|
|
17
17
|
|
|
18
|
+
/** @internal */
|
|
18
19
|
export class MediaPage extends Component {
|
|
19
20
|
static layout = AdminLayout;
|
|
20
21
|
/** The panel this page belongs to — set by each generated subclass. */
|
|
@@ -338,7 +339,11 @@ export class MediaPage extends Component {
|
|
|
338
339
|
}
|
|
339
340
|
}
|
|
340
341
|
|
|
341
|
-
/**
|
|
342
|
+
/**
|
|
343
|
+
* Build a MediaPage bound to one panel.
|
|
344
|
+
*
|
|
345
|
+
* @internal
|
|
346
|
+
*/
|
|
342
347
|
export function makeMediaPage(panel: PanelInstance = Panel.default()): typeof MediaPage {
|
|
343
348
|
return class BoundMediaPage extends MediaPage {
|
|
344
349
|
static override panel = panel;
|
|
@@ -10,6 +10,7 @@ import { Icon } from "../ui/icons.tsx";
|
|
|
10
10
|
import { Panel } from "../Panel.ts";
|
|
11
11
|
import type { PanelInstance } from "../PanelInstance.ts";
|
|
12
12
|
|
|
13
|
+
/** @internal */
|
|
13
14
|
export class NotificationsPage extends Component {
|
|
14
15
|
static layout = AdminLayout;
|
|
15
16
|
/** The panel this page belongs to — set by each generated subclass. */
|
|
@@ -142,7 +143,11 @@ export class NotificationsPage extends Component {
|
|
|
142
143
|
}
|
|
143
144
|
}
|
|
144
145
|
|
|
145
|
-
/**
|
|
146
|
+
/**
|
|
147
|
+
* The notification centre for one panel, reading that panel's provider.
|
|
148
|
+
*
|
|
149
|
+
* @internal
|
|
150
|
+
*/
|
|
146
151
|
export function makeNotificationsPage(
|
|
147
152
|
panel: PanelInstance = Panel.default(),
|
|
148
153
|
): typeof NotificationsPage {
|
|
@@ -95,6 +95,7 @@ interface PivotProxy {
|
|
|
95
95
|
all?: () => unknown;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
/** @internal */
|
|
98
99
|
export class RecordViewPage extends Component {
|
|
99
100
|
static layout = AdminLayout;
|
|
100
101
|
/** Set by each generated subclass. */
|
|
@@ -925,6 +926,8 @@ export class RecordViewPage extends Component {
|
|
|
925
926
|
/**
|
|
926
927
|
* Build a uniquely-named View page subclass bound to a resource — mirrors
|
|
927
928
|
* {@link makeResourceListPage} so Flow keeps component identity stable.
|
|
929
|
+
*
|
|
930
|
+
* @internal
|
|
928
931
|
*/
|
|
929
932
|
export function makeRecordViewPage(
|
|
930
933
|
resource: ResourceClass,
|
|
@@ -63,7 +63,11 @@ const _formRegistry = new Map<string, FormMeta>();
|
|
|
63
63
|
|
|
64
64
|
const formKey = (panelId: string, slug: string): string => `${panelId}:${slug}`;
|
|
65
65
|
|
|
66
|
-
/**
|
|
66
|
+
/**
|
|
67
|
+
* Register a resource's form config so the shared page can resolve it.
|
|
68
|
+
*
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
67
71
|
export function registerResourceForm(panelId: string, slug: string, meta: FormMeta): void {
|
|
68
72
|
_formRegistry.set(formKey(panelId, slug), meta);
|
|
69
73
|
}
|
|
@@ -72,6 +76,7 @@ const SPAN_CLASS = ["", "", "sm:col-span-2", "sm:col-span-3", "sm:col-span-4"];
|
|
|
72
76
|
const INPUT_CLASS =
|
|
73
77
|
"mt-1.5 block w-full rounded-lg border border-input bg-background px-3 py-2 text-sm text-foreground shadow-sm outline-none transition placeholder:text-muted-foreground focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background disabled:cursor-not-allowed disabled:opacity-60";
|
|
74
78
|
|
|
79
|
+
/** @internal */
|
|
75
80
|
export class ResourceFormPage extends Component {
|
|
76
81
|
@locked slug = "";
|
|
77
82
|
@locked mode: FieldMode = "create";
|
|
@@ -104,6 +104,7 @@ function parseFilters(s: string): Record<string, string> {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
/** @internal */
|
|
107
108
|
export class ResourceListPage extends Component {
|
|
108
109
|
static layout = AdminLayout;
|
|
109
110
|
/** Set by each generated subclass. */
|
|
@@ -2535,6 +2536,8 @@ export class ResourceListPage extends Component {
|
|
|
2535
2536
|
/**
|
|
2536
2537
|
* Build a uniquely-named List page subclass bound to a resource. The distinct
|
|
2537
2538
|
* class name keeps Flow's snapshot/component identity stable per resource.
|
|
2539
|
+
*
|
|
2540
|
+
* @internal
|
|
2538
2541
|
*/
|
|
2539
2542
|
export function makeResourceListPage(
|
|
2540
2543
|
resource: ResourceClass,
|
package/src/pages/RolesPage.tsx
CHANGED
|
@@ -12,6 +12,7 @@ import type { PanelInstance } from "../PanelInstance.ts";
|
|
|
12
12
|
import type { Permission, Role } from "../roles.ts";
|
|
13
13
|
import { groupPermissions, panelPermissions, roleHas } from "../roles.ts";
|
|
14
14
|
|
|
15
|
+
/** @internal */
|
|
15
16
|
export class RolesPage extends Component {
|
|
16
17
|
static layout = AdminLayout;
|
|
17
18
|
/** The panel this page belongs to — set by each generated subclass. */
|
|
@@ -317,7 +318,11 @@ export class RolesPage extends Component {
|
|
|
317
318
|
}
|
|
318
319
|
}
|
|
319
320
|
|
|
320
|
-
/**
|
|
321
|
+
/**
|
|
322
|
+
* Build a RolesPage bound to one panel.
|
|
323
|
+
*
|
|
324
|
+
* @internal
|
|
325
|
+
*/
|
|
321
326
|
export function makeRolesPage(panel: PanelInstance = Panel.default()): typeof RolesPage {
|
|
322
327
|
return class BoundRolesPage extends RolesPage {
|
|
323
328
|
static override panel = panel;
|
package/src/pages/SearchPage.tsx
CHANGED
|
@@ -158,7 +158,11 @@ export class SearchPage extends Component {
|
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
/**
|
|
161
|
+
/**
|
|
162
|
+
* The search page for one panel, searching only that panel's resources.
|
|
163
|
+
*
|
|
164
|
+
* @internal
|
|
165
|
+
*/
|
|
162
166
|
export function makeSearchPage(panel: PanelInstance = Panel.default()): typeof SearchPage {
|
|
163
167
|
const Page = class extends SearchPage {
|
|
164
168
|
static override panel = panel;
|
package/src/plugin.ts
CHANGED
|
@@ -40,6 +40,8 @@ import type { RenderHookContext } from "./renderHooks.ts";
|
|
|
40
40
|
* over without importing anything from `@zerotal/admin`. The panel gives the page
|
|
41
41
|
* its own layout when it mounts the route, so a contributed page renders only its
|
|
42
42
|
* content and inherits the panel's chrome.
|
|
43
|
+
*
|
|
44
|
+
* @internal
|
|
43
45
|
*/
|
|
44
46
|
export type PanelPageClass = new () => object;
|
|
45
47
|
|
|
@@ -245,6 +247,8 @@ export interface UserMenuContribution {
|
|
|
245
247
|
* Contributors should declare their own minimal copy of the members they use
|
|
246
248
|
* rather than importing this type, so they depend on the admin package at build
|
|
247
249
|
* time not at all.
|
|
250
|
+
*
|
|
251
|
+
* @internal
|
|
248
252
|
*/
|
|
249
253
|
export interface AdminPanelHost {
|
|
250
254
|
/**
|
package/src/table/Column.ts
CHANGED
package/src/ui/AdminLayout.tsx
CHANGED
|
@@ -15,6 +15,7 @@ import { Icon } from "./icons.tsx";
|
|
|
15
15
|
import { Command, Toaster, Sidebar } from "@zerotal/flow-ui";
|
|
16
16
|
import type { CommandItem, SidebarItem, SidebarGroup } from "@zerotal/flow-ui";
|
|
17
17
|
|
|
18
|
+
/** @internal */
|
|
18
19
|
export class AdminLayout extends Layout {
|
|
19
20
|
/**
|
|
20
21
|
* The panel this shell belongs to. The base class serves whichever panel owns
|
|
@@ -335,6 +336,8 @@ export class AdminLayout extends Layout {
|
|
|
335
336
|
* The router keys shell persistence on the layout class name, so each panel needs
|
|
336
337
|
* a class of its own: without that, navigating from one panel to another would
|
|
337
338
|
* swap the content while leaving the previous panel's sidebar in place.
|
|
339
|
+
*
|
|
340
|
+
* @internal
|
|
338
341
|
*/
|
|
339
342
|
export function makeAdminLayout(panel: PanelInstance): typeof AdminLayout {
|
|
340
343
|
const cached = LAYOUTS.get(panel);
|
package/src/widgets/render.tsx
CHANGED
|
@@ -45,6 +45,8 @@ export function chartInitScript(configs: unknown[]): string {
|
|
|
45
45
|
*
|
|
46
46
|
* Returns `null` when there is nothing to draw, so a caller can drop the whole
|
|
47
47
|
* block rather than leaving an empty gap above its table.
|
|
48
|
+
*
|
|
49
|
+
* @internal
|
|
48
50
|
*/
|
|
49
51
|
export async function renderWidgets(
|
|
50
52
|
widgets: DashboardWidget[],
|