@evotecit/canopyx 0.1.3 → 0.2.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/CanopyX.Html/Assets/canopyx-calendar-edit.js +113 -0
- package/CanopyX.Html/Assets/canopyx-calendar-ics.js +87 -0
- package/CanopyX.Html/Assets/canopyx-calendar-recurrence.js +36 -0
- package/CanopyX.Html/Assets/canopyx-calendar.css +279 -0
- package/CanopyX.Html/Assets/canopyx-calendar.js +307 -0
- package/CanopyX.Html/Assets/canopyx-cell-range.css +38 -0
- package/CanopyX.Html/Assets/canopyx-cell-range.js +141 -0
- package/CanopyX.Html/Assets/canopyx-column-groups.css +18 -0
- package/CanopyX.Html/Assets/canopyx-column-groups.js +51 -0
- package/CanopyX.Html/Assets/canopyx-data.js +14 -0
- package/CanopyX.Html/Assets/canopyx-detail-rows.css +18 -0
- package/CanopyX.Html/Assets/canopyx-detail-rows.js +51 -0
- package/CanopyX.Html/Assets/canopyx-editing.css +44 -0
- package/CanopyX.Html/Assets/canopyx-editing.js +134 -0
- package/CanopyX.Html/Assets/canopyx-enhance.js +126 -0
- package/CanopyX.Html/Assets/canopyx-export.js +18 -0
- package/CanopyX.Html/Assets/canopyx-facets.css +86 -0
- package/CanopyX.Html/Assets/canopyx-facets.js +65 -0
- package/CanopyX.Html/Assets/canopyx-filter-editor.css +15 -18
- package/CanopyX.Html/Assets/canopyx-filter-editor.js +23 -17
- package/CanopyX.Html/Assets/canopyx-format-editor.css +77 -0
- package/CanopyX.Html/Assets/canopyx-format-editor.js +30 -0
- package/CanopyX.Html/Assets/canopyx-formatting.css +40 -0
- package/CanopyX.Html/Assets/canopyx-formatting.js +101 -0
- package/CanopyX.Html/Assets/canopyx-grid-module.mjs +352 -246
- package/CanopyX.Html/Assets/canopyx-grid.css +139 -117
- package/CanopyX.Html/Assets/canopyx-grid.js +352 -246
- package/CanopyX.Html/Assets/canopyx-grouping.css +39 -0
- package/CanopyX.Html/Assets/canopyx-grouping.js +85 -0
- package/CanopyX.Html/Assets/canopyx-highlight.css +34 -0
- package/CanopyX.Html/Assets/canopyx-highlight.js +80 -0
- package/CanopyX.Html/Assets/canopyx-history.js +13 -0
- package/CanopyX.Html/Assets/canopyx-interactive.css +18 -6
- package/CanopyX.Html/Assets/canopyx-interactive.js +179 -100
- package/CanopyX.Html/Assets/canopyx-labels-de.js +304 -0
- package/CanopyX.Html/Assets/canopyx-labels-es.js +304 -0
- package/CanopyX.Html/Assets/canopyx-labels-fr.js +529 -0
- package/CanopyX.Html/Assets/canopyx-labels-it.js +529 -0
- package/CanopyX.Html/Assets/canopyx-labels-pl.js +304 -0
- package/CanopyX.Html/Assets/canopyx-layouts.css +48 -0
- package/CanopyX.Html/Assets/canopyx-layouts.js +39 -0
- package/CanopyX.Html/Assets/canopyx-link.css +19 -0
- package/CanopyX.Html/Assets/canopyx-link.js +38 -0
- package/CanopyX.Html/Assets/canopyx-links.js +14 -0
- package/CanopyX.Html/Assets/canopyx-live.css +24 -0
- package/CanopyX.Html/Assets/canopyx-live.js +88 -0
- package/CanopyX.Html/Assets/canopyx-module.mjs +180 -100
- package/CanopyX.Html/Assets/canopyx-pager.css +10 -0
- package/CanopyX.Html/Assets/canopyx-pager.js +14 -0
- package/CanopyX.Html/Assets/canopyx-record-panel.css +111 -0
- package/CanopyX.Html/Assets/canopyx-record-panel.js +178 -0
- package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +406 -342
- package/CanopyX.Html/Assets/canopyx-reporting.css +140 -135
- package/CanopyX.Html/Assets/canopyx-reporting.js +406 -342
- package/CanopyX.Html/Assets/canopyx-search.js +32 -0
- package/CanopyX.Html/Assets/canopyx-timeline.css +80 -0
- package/CanopyX.Html/Assets/canopyx-timeline.js +88 -0
- package/CanopyX.Html/Assets/canopyx-tree-tools.css +103 -0
- package/CanopyX.Html/Assets/canopyx-tree-tools.js +92 -0
- package/CanopyX.Html/Assets/canopyx.css +17 -5
- package/CanopyX.Html/Assets/canopyx.js +175 -96
- package/JavaScript/calendar.d.ts +362 -0
- package/JavaScript/cell-ranges.d.ts +76 -0
- package/JavaScript/column-groups.d.ts +32 -0
- package/JavaScript/editing.d.ts +257 -0
- package/JavaScript/enhance.d.ts +202 -0
- package/JavaScript/facets.d.ts +58 -0
- package/JavaScript/formatting.d.ts +88 -0
- package/JavaScript/grid.d.ts +409 -56
- package/JavaScript/hosts.d.ts +177 -2
- package/JavaScript/index.d.ts +53 -4
- package/JavaScript/live.d.ts +115 -0
- package/JavaScript/locales/de.mjs +304 -0
- package/JavaScript/locales/es.mjs +304 -0
- package/JavaScript/locales/fr.d.ts +6 -0
- package/JavaScript/locales/fr.mjs +527 -0
- package/JavaScript/locales/it.d.ts +6 -0
- package/JavaScript/locales/it.mjs +527 -0
- package/JavaScript/locales/pl.mjs +304 -0
- package/JavaScript/plugins.d.ts +113 -0
- package/JavaScript/protocol.d.ts +139 -6
- package/JavaScript/records.d.ts +136 -0
- package/README.md +61 -9
- package/README.nuget.md +1 -1
- package/package.json +99 -3
package/JavaScript/grid.d.ts
CHANGED
|
@@ -1,11 +1,42 @@
|
|
|
1
1
|
import CanopyX from "./index.js";
|
|
2
2
|
import type { TreeGrid } from "./index.js";
|
|
3
|
-
import type { CanopyColumn, CanopyLabels, Cell, CellValue, SortDirection, TimeZone } from "./protocol.js";
|
|
4
|
-
import type { HostOptions } from "./hosts.js";
|
|
3
|
+
import type { CanopyColumn, CanopyLabels, Cell, CellValue, SortDirection, TimeZone, SearchHighlightOptions, LayoutOptions, LayoutState, ViewModeMethods } from "./protocol.js";
|
|
4
|
+
import type { HostOptions, ExportFormat, ExportFormatOptions, ExportFormatResult, LinkedView } from "./hosts.js";
|
|
5
|
+
import type { CanopyPlugin } from "./plugins.js";
|
|
6
|
+
import type { GridEditorDefinition, GridValidation, GridEditingSettings, GridEditingOptions, GridEditingApi, GridCellValueChange,
|
|
7
|
+
GridRowCommit, GridCommitRowResult, GridCommitOutcome, GridCommit, GridCommitResult } from "./editing.js";
|
|
8
|
+
import type { RecordPanelDefinition, RecordLoader, RecordSectionRenderer, RecordAction, RecordOpenAll, OpenRecordOptions } from "./records.js";
|
|
9
|
+
export * from "./records.js";
|
|
5
10
|
export * from "./index.js";
|
|
11
|
+
export * from "./enhance.js";
|
|
12
|
+
import type { enhance, grid } from "./enhance.js";
|
|
13
|
+
export * from "./editing.js";
|
|
14
|
+
import type { GridExportFormat, GridFormatOptions, GridFormatRule } from "./formatting.js";
|
|
15
|
+
export * from "./formatting.js";
|
|
16
|
+
import type { GridColumnGroup, GridColumnGroupApi } from "./column-groups.js";
|
|
17
|
+
import type { GridRangeSelection, GridClipboardSettings, GridCellRange, GridPasteEvent, GridCellRangeApi } from "./cell-ranges.js";
|
|
18
|
+
export * from "./column-groups.js";
|
|
19
|
+
export * from "./cell-ranges.js";
|
|
20
|
+
import type { GridLiveDefinition, GridLiveOptions, GridLiveApi, GridLiveResult } from "./live.js";
|
|
21
|
+
import type { GridFacetPanelDefinition, GridFacetPanelOptions, GridFacetPanelApi } from "./facets.js";
|
|
22
|
+
import type { GridCalendarDefinition, GridCalendarOptions, GridCalendarApi, GridCalendarState, GridCalendarSavedState, GridOccurrenceChange, GridRangeSource, GridEventCreate, GridEventReceive, CalendarOptions } from "./calendar.js";
|
|
23
|
+
export * from "./facets.js";
|
|
24
|
+
export * from "./calendar.js";
|
|
25
|
+
export * from "./live.js";
|
|
6
26
|
|
|
7
27
|
/** A stable record identity and typed cells. Flat records have no tree fields. */
|
|
8
|
-
export interface GridRow { id: string; cells: Record<string, Cell>; tone?: string; className?: string;
|
|
28
|
+
export interface GridRow { id: string; cells: Record<string, Cell>; tone?: string; className?: string;
|
|
29
|
+
/** Reporting detail rows: the record's table, properties or trusted HTML payload, or its nested grid rows or tree roots. */
|
|
30
|
+
detail?: GridRowDetail;
|
|
31
|
+
/** Values of the view's record fields (record.fields): shown in the record drawer only, never queried, searched, sorted or exported. */
|
|
32
|
+
fields?: Record<string, Cell>; }
|
|
33
|
+
/** A record's detail payload: a table, property list or trusted HTML, or the inline data of the definition's nested view. */
|
|
34
|
+
export type GridRowDetail =
|
|
35
|
+
| { type: "table"; caption?: string; columns: string[]; widths?: number[]; rows: Cell[][] }
|
|
36
|
+
| { type: "properties"; items: { name: string; value: Cell }[] }
|
|
37
|
+
| { type: "html"; html: string }
|
|
38
|
+
| { type: "grid"; rows: GridRow[] }
|
|
39
|
+
| { type: "tree"; roots: unknown[] };
|
|
9
40
|
/** First match wins separately for the row and each condition-column cell; raw filter semantics apply. */
|
|
10
41
|
export type GridHighlightRule = GridFilter & { target?: "row" | "cell" } &
|
|
11
42
|
({ tone: string; className?: string } | { tone?: string; className: string });
|
|
@@ -15,6 +46,8 @@ export interface GridExportCell {
|
|
|
15
46
|
readonly text: string;
|
|
16
47
|
readonly tone?: string;
|
|
17
48
|
readonly link?: { readonly target: string; readonly tooltip?: string };
|
|
49
|
+
/** The cell's conditional formatting, present when the grid has rules that format it. CSV reads only value and text. */
|
|
50
|
+
readonly format?: GridExportFormat;
|
|
18
51
|
/** Unsupported presentation must be rejected by strict adapters or explicitly accepted as text-only. */
|
|
19
52
|
readonly diagnostics?: readonly string[];
|
|
20
53
|
}
|
|
@@ -22,6 +55,10 @@ export interface GridExportCell {
|
|
|
22
55
|
export interface GridExportRow {
|
|
23
56
|
readonly id: string; readonly cells: Readonly<Record<string, GridExportCell>>;
|
|
24
57
|
readonly tone?: string; readonly diagnostics?: readonly string[];
|
|
58
|
+
/** The record's row formatting, present when a row rule matched it. */
|
|
59
|
+
readonly format?: GridExportFormat;
|
|
60
|
+
/** Present when the export carries details (request.details): the record's detail as a table, properties or trusted HTML. */
|
|
61
|
+
readonly detail?: Extract<GridRowDetail, { type: "table" | "properties" | "html" }>;
|
|
25
62
|
}
|
|
26
63
|
/** Captured column intent. Hosts map semantic tones and CSS pixel widths into their output format. */
|
|
27
64
|
export interface GridExportColumn {
|
|
@@ -30,16 +67,44 @@ export interface GridExportColumn {
|
|
|
30
67
|
readonly width?: { readonly unit: "css-px"; readonly preferred: number; readonly minimum: number; readonly maximum?: number };
|
|
31
68
|
readonly wrap?: boolean; readonly alignment?: "left" | "right";
|
|
32
69
|
readonly presenter?: GridPresenter;
|
|
70
|
+
/** The column number format that produced the display text. */
|
|
71
|
+
readonly format?: GridNumberFormat;
|
|
33
72
|
readonly diagnostics?: readonly string[];
|
|
34
73
|
}
|
|
35
|
-
|
|
36
|
-
|
|
74
|
+
/**
|
|
75
|
+
* The column ids of a row type: the keys of its cells, so `createDataGrid<Server>(…)` checks column ids, facets and column
|
|
76
|
+
* methods against the row. Untyped rows (the default) take any string.
|
|
77
|
+
*/
|
|
78
|
+
export type GridColumnId<Row extends GridRow = GridRow> = string extends keyof Row["cells"] ? string : Extract<keyof Row["cells"], string>;
|
|
79
|
+
/** Fraction digits from 0 to 10 (defaults 0 and 3); a minimum above 3 requires an explicit maximum. Literal affixes have 1 to 16 code units. */
|
|
80
|
+
export interface GridNumberFormat {
|
|
81
|
+
readonly minimumFractionDigits?: number; readonly maximumFractionDigits?: number;
|
|
82
|
+
readonly prefix?: string; readonly suffix?: string;
|
|
83
|
+
}
|
|
84
|
+
export type GridColumn<Row extends GridRow = GridRow> = Omit<CanopyColumn, "id" | "editable" | "width"> & {
|
|
85
|
+
/** The column's id; for a typed row, one of its cells. */
|
|
86
|
+
id: GridColumnId<Row>;
|
|
87
|
+
/** Supports query predicates and filter controls. Default true; does not hide values, supported read-only facets, or presentation rules. */
|
|
88
|
+
filterable?: boolean;
|
|
89
|
+
/** Supports grid exports. Default true. Default export selection omits false; explicit requests reject it. */
|
|
90
|
+
exportable?: boolean;
|
|
91
|
+
/** Readers can edit the column's cells; the editing part loads with the grid (docs/editing.md). */
|
|
92
|
+
editable?: boolean;
|
|
93
|
+
/** The column's typed editor; without one the column's kind chooses text, number or datetime. */
|
|
94
|
+
editor?: GridEditorDefinition;
|
|
95
|
+
/** Checks an edited value must pass before its row commits. */
|
|
96
|
+
validation?: GridValidation;
|
|
97
|
+
wrap?: boolean;
|
|
37
98
|
/** Declarative presentation; explicit host renderers take precedence. */
|
|
38
99
|
presenter?: GridPresenter;
|
|
100
|
+
/** Number columns: display format of raw numbers without cell text, also used by summaries and selection totals. */
|
|
101
|
+
format?: GridNumberFormat;
|
|
39
102
|
/** Include selected numeric values in the optional status bar. */
|
|
40
103
|
aggregatable?: boolean;
|
|
41
104
|
/** Record drawer section label. */
|
|
42
105
|
section?: string;
|
|
106
|
+
/** false keeps the column out of the record drawer and record panel. Default true. */
|
|
107
|
+
drawer?: boolean;
|
|
43
108
|
/** Preferred width; the column grows to its header and loaded content. Omit to use the content width. Saved user widths take precedence. */
|
|
44
109
|
width?: number;
|
|
45
110
|
/** Wire documents retain a numeric width and set this flag for initial content fitting. */
|
|
@@ -52,7 +117,7 @@ export type GridColumn = Omit<CanopyColumn, "editable" | "width"> & {
|
|
|
52
117
|
/** Share of spare width (0..100), given before the identity column. */
|
|
53
118
|
flex?: number;
|
|
54
119
|
autoSize?: "content" | "header" | "none";
|
|
55
|
-
/** How the column gives way when narrow. Integers
|
|
120
|
+
/** How the column gives way when narrow. Integers: 0-1 essential, 10000+ optional, larger values hide first. */
|
|
56
121
|
priority?: GridColumnPriority;
|
|
57
122
|
/** Requested edge; null unpins. Omitted: the identity column pins left. */
|
|
58
123
|
pinned?: "left" | "right" | null;
|
|
@@ -60,6 +125,8 @@ export type GridColumn = Omit<CanopyColumn, "editable" | "width"> & {
|
|
|
60
125
|
rowHeader?: boolean;
|
|
61
126
|
/** Retain this column during responsive fitting; explicit user hiding still applies. */
|
|
62
127
|
alwaysVisible?: boolean;
|
|
128
|
+
/** Hover tooltip: "auto" shows a cell's full value while it is cut off; a declared column id shows that column's text. */
|
|
129
|
+
tooltip?: string;
|
|
63
130
|
};
|
|
64
131
|
export type GridColumnPriority = "essential" | "normal" | "optional" | number;
|
|
65
132
|
export interface GridSort { readonly column: string; readonly direction: SortDirection; }
|
|
@@ -77,12 +144,14 @@ export type GridPresenter =
|
|
|
77
144
|
| { readonly kind: "boolean"; readonly inverted?: boolean }
|
|
78
145
|
| { readonly kind: "list"; readonly separator: string; readonly limit: number }
|
|
79
146
|
| { readonly kind: "longText"; readonly mono?: boolean }
|
|
80
|
-
| { readonly kind: "enum" | "state"; readonly tones?: Readonly<Record<string,string>>; /** Tones shown as plain
|
|
147
|
+
| { readonly kind: "enum" | "state"; readonly tones?: Readonly<Record<string,string>>; /** Tones shown as plain text instead of a chip or dot. */ readonly quietTones?: readonly string[]; /** Quiet values muted (default) or in the normal text colour. */ readonly quietStyle?: "muted" | "plain" }
|
|
81
148
|
| { readonly kind: "change"; readonly deltaColumn: string; readonly higherIsGood?: boolean }
|
|
82
149
|
| { readonly kind: "statusStrip" | "missing" }
|
|
83
150
|
| ({ readonly kind: "sparklineBars" | "sparklineLine" } & GridHistoryPresentation)
|
|
84
151
|
| { readonly kind: "identifier"; readonly secondaryColumn?: string; readonly mono?: boolean }
|
|
85
|
-
| { readonly kind: "tags"; readonly separator: string; readonly limit?: 3 }
|
|
152
|
+
| { readonly kind: "tags"; readonly separator: string; readonly limit?: 3 }
|
|
153
|
+
/** A structured value's summary: a count (countText with {count}), chips (limit) or the first item and +N. The record panel shows it whole. */
|
|
154
|
+
| { readonly kind: "structured"; readonly display?: "count" | "chips" | "first"; readonly limit?: number; readonly countText?: string };
|
|
86
155
|
/** Ascending inclusive upper bounds; unmatched values use cell tones. */
|
|
87
156
|
export interface GridThreshold { readonly upperBound: number; readonly tone: string; }
|
|
88
157
|
/** Both shared scale bounds must be supplied together; otherwise each cell scales independently. */
|
|
@@ -90,10 +159,33 @@ export interface GridHistoryPresentation {
|
|
|
90
159
|
readonly minimum?: number; readonly scaleMaximum?: number; readonly thresholds?: readonly GridThreshold[];
|
|
91
160
|
readonly higherIsGood?: boolean; readonly mark?: "worst" | "last";
|
|
92
161
|
}
|
|
162
|
+
/** A page-size choice: rows per page, "all" for every row of inline data, or either with its own menu text. */
|
|
163
|
+
export type GridPageLengthChoice = number | "all" | { readonly value: number | "all"; readonly label: string };
|
|
164
|
+
/** Settings of a paged grid's pager; continuous grids ignore them (docs/paging.md). */
|
|
165
|
+
export interface GridPager {
|
|
166
|
+
/** Page-size choices in menu order (at most 16); absent keeps 10, 25, 50, 100 and, for inline data, All. */
|
|
167
|
+
readonly lengths?: readonly GridPageLengthChoice[];
|
|
168
|
+
/** The rows-per-page menu. Default true. */
|
|
169
|
+
readonly lengthMenu?: boolean;
|
|
170
|
+
/** Numbered page buttons: 0 for none (default), or 5 to 15. */
|
|
171
|
+
readonly numbers?: number;
|
|
172
|
+
/** The page number field. Absent shows it unless numbered pages show. */
|
|
173
|
+
readonly pageInput?: boolean;
|
|
174
|
+
/** The first-page and last-page buttons. Default true. */
|
|
175
|
+
readonly firstLast?: boolean;
|
|
176
|
+
/** The result text: the compact range (default), a sentence with the unfiltered total while filtered, or none. */
|
|
177
|
+
readonly info?: "range" | "sentence" | "none";
|
|
178
|
+
}
|
|
93
179
|
/** Include the reporting entry point when this optional capability set is present. */
|
|
94
180
|
export interface GridReporting {
|
|
95
181
|
/** Fixed first ordering key. Group headings and collapse never change record paging/counts/exports. */
|
|
96
182
|
readonly grouping?: GridSort;
|
|
183
|
+
/** Initial runtime grouping levels, outermost first (at most four). Not combined with grouping. */
|
|
184
|
+
readonly groupBy?: readonly GridGroupLevel[];
|
|
185
|
+
/** Readers group by sortable columns from column menus, the group-by bar and dragged headers. Not combined with grouping. */
|
|
186
|
+
readonly groupable?: boolean;
|
|
187
|
+
/** Expandable detail rows under records; content loads on first expand. */
|
|
188
|
+
readonly detail?: GridDetailDefinition;
|
|
97
189
|
/** At most 32 generic aggregates over raw full-query and full-group values. */
|
|
98
190
|
readonly aggregates?: readonly GridAggregate[];
|
|
99
191
|
/** Adds row checkboxes and explicit page/all-matching selection controls. Requires an enabled selection mode. */
|
|
@@ -149,8 +241,14 @@ export interface GridToolbarControls {
|
|
|
149
241
|
export?: boolean;
|
|
150
242
|
/** More menu: host actions, Record details and Print. */
|
|
151
243
|
more?: boolean;
|
|
244
|
+
/** Each header's column menu button; switched off, column fitting keeps no room for it. */
|
|
245
|
+
columnMenus?: boolean;
|
|
152
246
|
/** Result count shown with the query chips. */
|
|
153
247
|
count?: boolean;
|
|
248
|
+
/** The match navigator and the Highlight matches switch of a grid with searchHighlight. */
|
|
249
|
+
matches?: boolean;
|
|
250
|
+
/** The Layout menu of a grid with layout options. */
|
|
251
|
+
layout?: boolean;
|
|
154
252
|
}
|
|
155
253
|
/** Runtime switches add the search box; documents keep it in the view's search property. */
|
|
156
254
|
export interface GridToolbarOptions extends GridToolbarControls {
|
|
@@ -161,7 +259,7 @@ export interface GridToolbarOptions extends GridToolbarControls {
|
|
|
161
259
|
export type GridToolbarSlot = "start" | "afterSearch" | "afterViews" | "end";
|
|
162
260
|
/** A more-menu entry: a handler, or (reporting runtime) host content disclosed inside the menu. */
|
|
163
261
|
export type GridAction<Q extends AcceptedGridQuery = GridQuery> =
|
|
164
|
-
| { label: string; run: (event: { query: Q | null; signal: AbortSignal }) => void | PromiseLike<void>; render?: never }
|
|
262
|
+
| { label: string; run: (event: { query: Q | null; signal: AbortSignal; api: DataGrid<Q> }) => void | PromiseLike<void>; render?: never }
|
|
165
263
|
/** render fills container on the entry's first open (and again after a render that threw); close() closes the menu and
|
|
166
264
|
* focuses its button; signal aborts when the grid is destroyed. */
|
|
167
265
|
| { label: string; render: (container: HTMLElement, context: { close(): void; signal: AbortSignal }) => void; run?: never };
|
|
@@ -193,6 +291,8 @@ export interface GridQuery {
|
|
|
193
291
|
readonly filters: readonly GridFilter[];
|
|
194
292
|
/** Combined with search and flat filters using AND. */
|
|
195
293
|
readonly filterGroup?: GridFilterGroup;
|
|
294
|
+
/** Runtime grouping levels (reporting groupBy/groupable definitions); omitted input uses the declared levels, [] ungroups. */
|
|
295
|
+
readonly groupBy?: readonly GridGroupLevel[];
|
|
196
296
|
}
|
|
197
297
|
/** Sequential host query. Tokens require their issuing revision; there is no random-access offset. */
|
|
198
298
|
export interface GridCursorQuery extends Omit<GridQuery, "type" | "offset"> {
|
|
@@ -203,12 +303,12 @@ export type AcceptedGridQuery = GridQuery | GridCursorQuery;
|
|
|
203
303
|
export type GridQueryInput<Q extends AcceptedGridQuery = GridQuery> = Partial<Q>;
|
|
204
304
|
type GridCount<Q extends AcceptedGridQuery> = Q extends GridCursorQuery ? number | null : number;
|
|
205
305
|
|
|
206
|
-
interface GridDefinition<Q extends AcceptedGridQuery = GridQuery> {
|
|
306
|
+
interface GridDefinition<Q extends AcceptedGridQuery = GridQuery, Row extends GridRow = GridRow> {
|
|
207
307
|
protocol: "canopyx/2";
|
|
208
308
|
type: "grid";
|
|
209
309
|
id: string;
|
|
210
310
|
label: string;
|
|
211
|
-
columns: GridColumn[];
|
|
311
|
+
columns: GridColumn<Row>[];
|
|
212
312
|
/** Fixed CSS pixel height (20..64), or content measurement. Fixed is the default writer behavior. */
|
|
213
313
|
rowHeight?: number | "auto";
|
|
214
314
|
/** Graphite spacing; an explicit rowHeight remains authoritative. */
|
|
@@ -223,45 +323,104 @@ interface GridDefinition<Q extends AcceptedGridQuery = GridQuery> {
|
|
|
223
323
|
statusBar?: boolean;
|
|
224
324
|
/** Per-control toolbar switches (the search box is the search property). */
|
|
225
325
|
toolbar?: GridToolbarControls;
|
|
326
|
+
/** Ids of browser-registered export formats the Export menu offers after CSV, in order; an id the page does not register is skipped. */
|
|
327
|
+
exportFormats?: string[];
|
|
226
328
|
/** A grid whose rows fit is as tall as its rows (default true). */
|
|
227
329
|
autoHeight?: boolean;
|
|
228
330
|
/** What a plain row click does; it never selects (default "none"). */
|
|
229
331
|
rowAction?: "none" | "details" | "link";
|
|
230
332
|
/** Draw a row tone as a bar at the row start (default false). */
|
|
231
333
|
rowAccents?: boolean;
|
|
334
|
+
/** How editable columns edit; the host's editing option overrides these. */
|
|
335
|
+
editing?: GridEditingSettings;
|
|
336
|
+
/** Marks search and column-filter matches in cells and the drawer, with a match count and next/previous (docs/search-highlight.md). */
|
|
337
|
+
searchHighlight?: boolean | SearchHighlightOptions;
|
|
338
|
+
/** The Layout menu: fit, scroll and cards, and the density (docs/layout-modes.md); layout.density starts the grid at that density. */
|
|
339
|
+
layout?: LayoutOptions;
|
|
232
340
|
/** Wire documents retain numeric rowHeight and enable measurement with this optional flag. */
|
|
233
341
|
autoRowHeight?: boolean;
|
|
234
342
|
/** Minimum and estimate for the rowHeight: "auto" API shorthand (20..64, default 28). */
|
|
235
343
|
estimatedRowHeight?: number;
|
|
236
344
|
/** At most 64 ordered rules; a tone or className is required on each rule. */
|
|
237
345
|
highlightRules?: readonly GridHighlightRule[];
|
|
346
|
+
/** At most 64 conditional formatting rules in priority order; the formatting part evaluates them (docs/conditional-formatting.md). */
|
|
347
|
+
formatRules?: readonly GridFormatRule[];
|
|
348
|
+
/** The legend and the rule editor. */
|
|
349
|
+
formatting?: GridFormatOptions;
|
|
238
350
|
pageSize: number;
|
|
239
351
|
/** Presentation only; pageSize remains the source fetch size. */
|
|
240
352
|
presentation?: "continuous" | "paged";
|
|
241
353
|
pageLength?: number;
|
|
354
|
+
/** Pager settings of a paged view, read by the pager part (canopyx-pager.js); absent keeps the built-in pager. */
|
|
355
|
+
pager?: GridPager;
|
|
242
356
|
selection: "none" | "single" | "multiple";
|
|
243
357
|
search: boolean;
|
|
244
358
|
/** Search-input debounce (0..5000). Absent uses 0 for inline and 300 for host sources. */
|
|
245
359
|
searchDelayMs?: number;
|
|
246
360
|
/** Unique declared IDs; absent searches every column, including hidden columns. */
|
|
247
|
-
searchColumns?:
|
|
361
|
+
searchColumns?: GridColumnId<Row>[];
|
|
248
362
|
reporting?: GridReporting;
|
|
363
|
+
/** Header rows above the columns, up to three levels (docs/column-groups.md). */
|
|
364
|
+
columnGroups?: readonly GridColumnGroup[];
|
|
365
|
+
/** Cell ranges by mouse, keyboard and touch, the cell menu and the clipboard keys (docs/cell-ranges.md). */
|
|
366
|
+
rangeSelection?: GridRangeSelection;
|
|
367
|
+
/** How cell ranges copy and paste. */
|
|
368
|
+
clipboard?: GridClipboardSettings;
|
|
369
|
+
/** The record panel: record fields, sections, tabs, a pinned summary, deep links, record details on demand (records.d.ts). */
|
|
370
|
+
record?: RecordPanelDefinition;
|
|
371
|
+
/** Live data: rows that change in place, the stable order, flashing cells, batching and polling (live.d.ts). */
|
|
372
|
+
live?: GridLiveDefinition;
|
|
373
|
+
/** A facet panel beside or above the grid: value lists with counts and ranges with histograms (facets.d.ts). */
|
|
374
|
+
facets?: GridFacetPanelDefinition<Row>;
|
|
375
|
+
/** Shows the records as a calendar: month, week, day, N days, agenda, year and the resource timeline (calendar.d.ts). */
|
|
376
|
+
calendar?: GridCalendarDefinition<Row>;
|
|
377
|
+
/** Rows can be dragged out (or picked up with F2) onto a calendar that accepts drops. */
|
|
378
|
+
dragRows?: boolean;
|
|
249
379
|
stateKey?: string;
|
|
250
380
|
timeZone?: TimeZone;
|
|
251
381
|
labels?: Partial<CanopyLabels>;
|
|
382
|
+
/** Sanitizes trusted host HTML details before insertion; shares the tree host's sanitizer contract. */
|
|
383
|
+
sanitizeHtml?: HostOptions["sanitizeHtml"];
|
|
252
384
|
query?: Q;
|
|
253
385
|
}
|
|
254
|
-
export interface InlineGridView extends GridDefinition { source: { kind: "inline"; navigation?: "offset" }; rows:
|
|
255
|
-
|
|
256
|
-
|
|
386
|
+
export interface InlineGridView<Row extends GridRow = GridRow> extends GridDefinition<GridQuery, Row> { source: { kind: "inline"; navigation?: "offset" }; rows: Row[]; rowData?: never; }
|
|
387
|
+
/**
|
|
388
|
+
* A compact row: the row id (or `{ id, tone?, className? }`) followed by its cells in the order of `GridRowData.columns`.
|
|
389
|
+
* Trailing empty cells may be left out; `null` is an empty cell.
|
|
390
|
+
*/
|
|
391
|
+
export type GridCompactRow = [string | { id: string; tone?: string; className?: string }, ...Cell[]];
|
|
392
|
+
/** Compact row data of an inline grid, in place of `rows` (docs/data-protocol.md, "Row data"). */
|
|
393
|
+
export interface GridRowData {
|
|
394
|
+
/** Compact row encoding version, preserved within canopyx/2 for independently deployed readers. */
|
|
395
|
+
version: 1;
|
|
396
|
+
/** Declared column ids, unique, in the order of each compact row's cells. */
|
|
397
|
+
columns: string[];
|
|
398
|
+
/** The number of rows in all chunks. */
|
|
399
|
+
count: number;
|
|
400
|
+
/** The rows are in ordinal identity order, so the first rows show before the last chunk is decoded. */
|
|
401
|
+
ordered?: boolean;
|
|
402
|
+
/** Each string chunk is base64 text of gzip-compressed JSON, inflated with DecompressionStream. */
|
|
403
|
+
encoding?: "gzip";
|
|
404
|
+
/** Folder of the sidecar files `rows/<n>.js`, relative to the page; requires a chunk count. */
|
|
405
|
+
base?: string;
|
|
406
|
+
/**
|
|
407
|
+
* A count of `application/x-canopyx-rows` scripts inside the host element (or of sidecar files under `base`), or the chunks
|
|
408
|
+
* themselves: arrays of compact rows, or strings of chunk JSON (base64 gzip with `encoding`).
|
|
409
|
+
*/
|
|
410
|
+
chunks: number | Array<GridCompactRow[] | string>;
|
|
411
|
+
}
|
|
412
|
+
/** An inline grid whose rows the data part decodes from compact row data, chunk by chunk, after the first paint. */
|
|
413
|
+
export interface CompactGridView<Row extends GridRow = GridRow> extends GridDefinition<GridQuery, Row> { source: { kind: "inline"; navigation?: "offset" }; rowData: GridRowData; rows?: never; }
|
|
414
|
+
export interface HostGridView<Row extends GridRow = GridRow> extends GridDefinition<GridQuery, Row> { source: { kind: "host"; navigation?: "offset" }; rows?: never; }
|
|
415
|
+
export interface CursorGridView<Row extends GridRow = GridRow> extends GridDefinition<GridCursorQuery, Row> {
|
|
257
416
|
source: { kind: "host"; navigation: "cursor" };
|
|
258
417
|
presentation: "paged";
|
|
259
418
|
rows?: never;
|
|
260
419
|
}
|
|
261
|
-
export type GridView = InlineGridView | HostGridView | CursorGridView
|
|
420
|
+
export type GridView<Row extends GridRow = GridRow> = InlineGridView<Row> | CompactGridView<Row> | HostGridView<Row> | CursorGridView<Row>;
|
|
262
421
|
|
|
263
422
|
/** A complete requested window from one dataset revision, with full and matching counts. */
|
|
264
|
-
export interface GridPage {
|
|
423
|
+
export interface GridPage<Row extends GridRow = GridRow> {
|
|
265
424
|
protocol: "canopyx/2";
|
|
266
425
|
type: "gridPage";
|
|
267
426
|
view: string;
|
|
@@ -269,7 +428,7 @@ export interface GridPage {
|
|
|
269
428
|
offset: number;
|
|
270
429
|
total: number;
|
|
271
430
|
matched: number;
|
|
272
|
-
items:
|
|
431
|
+
items: Row[];
|
|
273
432
|
}
|
|
274
433
|
/** Hosts own data access, authorization and query execution; cancellation does not grant write authority. */
|
|
275
434
|
export interface GridFacetOptions { readonly search?: string; readonly limit?: number; readonly includeCurrentFilter?: boolean; readonly signal?: AbortSignal; }
|
|
@@ -287,21 +446,73 @@ export interface GridFacetPage {
|
|
|
287
446
|
export interface GridFacetSource<Q extends AcceptedGridQuery = AcceptedGridQuery> {
|
|
288
447
|
facet?(request: GridFacetQuery<Q>, options: { signal: AbortSignal }): GridFacetPage | PromiseLike<GridFacetPage>;
|
|
289
448
|
}
|
|
290
|
-
export interface GridSource extends GridFacetSource<GridQuery> {
|
|
449
|
+
export interface GridSource<Row extends GridRow = GridRow> extends GridFacetSource<GridQuery>, GridRangeSource<Row> {
|
|
291
450
|
readonly navigation?: "offset";
|
|
292
|
-
query(query: GridQuery, options: { signal: AbortSignal }): GridPage | PromiseLike<GridPage
|
|
451
|
+
query(query: GridQuery, options: { signal: AbortSignal }): GridPage<Row> | PromiseLike<GridPage<Row>>;
|
|
293
452
|
/** Complete-query metadata, echoing the normalized accepted request, revision and matched count. */
|
|
294
453
|
summary?(query: GridQuery & { readonly revision: string }, options: { signal: AbortSignal }): GridSummary | PromiseLike<GridSummary>;
|
|
295
|
-
|
|
454
|
+
/** Saves changed rows (a remote source posts the gridCommit document to its commit endpoint) and answers per row. */
|
|
455
|
+
commit?(batch: GridCommit, options: { signal: AbortSignal }): GridCommitResult | PromiseLike<GridCommitResult>;
|
|
456
|
+
/** A record's details when its drawer opens (a gridRecordQuery answered with a gridRecord), as a remote protocol client sends it. */
|
|
457
|
+
record?: RecordLoader;
|
|
458
|
+
/** A record's position in the query's result, or -1, so openRecord and deep links scroll the grid to it. */
|
|
459
|
+
position?(query: GridQuery, id: string, options: { signal: AbortSignal }): number | PromiseLike<number>;
|
|
460
|
+
}
|
|
461
|
+
/** Built-in operations, or the name of a custom aggregate a plugin registers (inline data) or the host source computes. */
|
|
462
|
+
export type GridAggregateOperation = "count" | "sum" | "average" | "minimum" | "maximum" | "distinctCount" | (string & {});
|
|
296
463
|
export interface GridAggregate {
|
|
464
|
+
/** The label is shown beside the value in group headings and the query totals row. */
|
|
297
465
|
readonly id: string; readonly column: string; readonly label: string;
|
|
298
|
-
readonly operation:
|
|
466
|
+
readonly operation: GridAggregateOperation;
|
|
467
|
+
/** Explicit value format; otherwise the column format applies, except that count and distinctCount use whole numbers. */
|
|
468
|
+
readonly format?: GridNumberFormat;
|
|
469
|
+
}
|
|
470
|
+
/** One runtime grouping level: groups order by value, or by a declared aggregate (nulls last, ties by value). */
|
|
471
|
+
export interface GridGroupLevel {
|
|
472
|
+
readonly column: string; readonly direction: "asc" | "desc"; readonly aggregate?: string;
|
|
473
|
+
}
|
|
474
|
+
/** Declared detail rows: one content source (a page template, a plugin detail renderer or a nested view), else record payloads. */
|
|
475
|
+
export interface GridDetailDefinition {
|
|
476
|
+
/** Id of a page <template>; elements with data-cx-field receive the record's cell text. */
|
|
477
|
+
readonly template?: string;
|
|
478
|
+
/** Name of a detail renderer a plugin registers in detailRenderers. */
|
|
479
|
+
readonly renderer?: string;
|
|
480
|
+
/** Nested grid or tree document whose inline data is each record's grid or tree payload. */
|
|
481
|
+
readonly view?: object;
|
|
482
|
+
/** Exports and print snapshots carry detail payloads; default true. */
|
|
483
|
+
readonly print?: boolean;
|
|
484
|
+
readonly label?: string;
|
|
485
|
+
}
|
|
486
|
+
/** The context of a detail callback. The signal aborts when the record collapses, leaves the result or the grid is destroyed. */
|
|
487
|
+
export interface GridDetailContext {
|
|
488
|
+
readonly id: string; readonly signal: AbortSignal; readonly api: unknown; readonly labels: Readonly<Record<string, string>>;
|
|
489
|
+
onDispose(cleanup: () => void): void;
|
|
490
|
+
}
|
|
491
|
+
/** A nested view a detail callback returns: a grid or tree document, an optional host source and options for createDataGrid/createTreeGrid. */
|
|
492
|
+
export interface GridNestedDetail {
|
|
493
|
+
readonly view: object; readonly source?: unknown; readonly options?: Readonly<Record<string, unknown>>;
|
|
494
|
+
}
|
|
495
|
+
/** Host detail rows (the detail option): one callback draws the content; hasDetail limits which records offer it. */
|
|
496
|
+
export interface GridDetailOptions<Row extends GridRow = GridRow> {
|
|
497
|
+
/** A host template: draws into element (the body inside the visible width). */
|
|
498
|
+
render?(row: Readonly<Row>, element: HTMLElement, context: GridDetailContext): void | PromiseLike<void>;
|
|
499
|
+
/** Trusted markup inserted as HTML: encode the record text you put into it. */
|
|
500
|
+
html?(row: Readonly<Row>, context: GridDetailContext): string | PromiseLike<string>;
|
|
501
|
+
grid?(row: Readonly<Row>, context: GridDetailContext): GridNestedDetail | PromiseLike<GridNestedDetail>;
|
|
502
|
+
tree?(row: Readonly<Row>, context: GridDetailContext): GridNestedDetail | PromiseLike<GridNestedDetail>;
|
|
503
|
+
/** A host source for the definition's nested view. */
|
|
504
|
+
source?(row: Readonly<Row>, context: GridDetailContext): unknown;
|
|
505
|
+
hasDetail?(row: Readonly<Row>): boolean;
|
|
506
|
+
/** The detail exports and print snapshots carry for a record. */
|
|
507
|
+
export?(row: Readonly<Row>): Extract<GridRowDetail, { type: "table" | "properties" | "html" }> | null;
|
|
299
508
|
}
|
|
300
509
|
export interface GridGroup {
|
|
301
510
|
readonly key: string; readonly value: CellValue; readonly offset: number; readonly count: number;
|
|
302
511
|
readonly aggregates: Readonly<Record<string, number | null>>;
|
|
303
512
|
/** Host-owned complete-group display values; rendered with column presenters, excluded from record queries and exports. */
|
|
304
513
|
readonly cells?: Readonly<Record<string, Cell>>;
|
|
514
|
+
/** The next level's groups inside this one: present on every group of an outer level. Keys are unique across levels. */
|
|
515
|
+
readonly groups?: readonly GridGroup[];
|
|
305
516
|
}
|
|
306
517
|
export interface GridSummary {
|
|
307
518
|
readonly protocol: "canopyx/2"; readonly type: "gridSummary"; readonly view: string; readonly revision: string;
|
|
@@ -309,16 +520,16 @@ export interface GridSummary {
|
|
|
309
520
|
readonly groups: readonly GridGroup[]; readonly aggregates: Readonly<Record<string, number | null>>;
|
|
310
521
|
}
|
|
311
522
|
/** One complete visible page. Null counts remain unknown; ordinal positions do not grant random access. */
|
|
312
|
-
export interface GridCursorPage extends Omit<GridPage
|
|
523
|
+
export interface GridCursorPage<Row extends GridRow = GridRow> extends Omit<GridPage<Row>, "type" | "total" | "matched"> {
|
|
313
524
|
type: "gridCursorPage";
|
|
314
525
|
total: number | null;
|
|
315
526
|
matched: number | null;
|
|
316
527
|
nextCursor?: string;
|
|
317
528
|
previousCursor?: string;
|
|
318
529
|
}
|
|
319
|
-
export interface GridCursorSource extends GridFacetSource<GridCursorQuery> {
|
|
530
|
+
export interface GridCursorSource<Row extends GridRow = GridRow> extends GridFacetSource<GridCursorQuery> {
|
|
320
531
|
readonly navigation: "cursor";
|
|
321
|
-
query(query: GridCursorQuery, options: { signal: AbortSignal }): GridCursorPage | PromiseLike<GridCursorPage
|
|
532
|
+
query(query: GridCursorQuery, options: { signal: AbortSignal }): GridCursorPage<Row> | PromiseLike<GridCursorPage<Row>>;
|
|
322
533
|
}
|
|
323
534
|
/** Accepted presentation; indices are zero based, while the visible range is one based (0–0 when empty). */
|
|
324
535
|
export interface GridPaging<Q extends AcceptedGridQuery = GridQuery> {
|
|
@@ -366,6 +577,11 @@ export interface GridExportRequest<Q extends AcceptedGridQuery = GridQuery> {
|
|
|
366
577
|
/** Reporting delivery captures the canonical locale and a safe suggested basename without a format extension. */
|
|
367
578
|
readonly locale?: string;
|
|
368
579
|
readonly fileName?: string;
|
|
580
|
+
/** Filtered exports of a grouped result: levels, totals and nested groups with record ranges for outline levels. */
|
|
581
|
+
readonly grouping?: { readonly levels: readonly (GridGroupLevel & { readonly title: string })[]; readonly aggregates: readonly GridAggregate[];
|
|
582
|
+
readonly totals: Readonly<Record<string, number | null>>; readonly groups: readonly (GridGroup & { readonly text: string })[] };
|
|
583
|
+
/** Records carry their detail payloads. */
|
|
584
|
+
readonly details?: true;
|
|
369
585
|
}
|
|
370
586
|
/** Record counts refer to the complete captured export scope, including selected-query exclusions. */
|
|
371
587
|
export interface GridExportProgress {
|
|
@@ -373,9 +589,27 @@ export interface GridExportProgress {
|
|
|
373
589
|
readonly completed: number;
|
|
374
590
|
readonly total: number | null;
|
|
375
591
|
}
|
|
592
|
+
/** The detail of canopyx:link and the argument of onLink: a link presenter cell the user follows (by click, Enter or the row's link action). */
|
|
593
|
+
export interface GridLinkActivation<Row extends GridRow = GridRow> {
|
|
594
|
+
readonly id: string;
|
|
595
|
+
/** A frozen copy of the loaded row. */
|
|
596
|
+
readonly row: Readonly<Row>;
|
|
597
|
+
/** The id of the column whose link it is. */
|
|
598
|
+
readonly column: GridColumnId<Row>;
|
|
599
|
+
/** The resolved address. */
|
|
600
|
+
readonly href: string;
|
|
601
|
+
}
|
|
602
|
+
/** The detail of canopyx:rowActivate and the argument of onRowActivate on a flat grid. */
|
|
603
|
+
export interface GridRowActivation<Row extends GridRow = GridRow> {
|
|
604
|
+
readonly id: string;
|
|
605
|
+
/** A frozen copy of the loaded row. */
|
|
606
|
+
readonly row: Readonly<Row>;
|
|
607
|
+
/** True for Enter or Ctrl/Command+Enter, false for a click or double click. */
|
|
608
|
+
readonly keyboard: boolean;
|
|
609
|
+
}
|
|
376
610
|
export interface GridExportOptions {
|
|
377
611
|
scope: GridExportRequest["scope"];
|
|
378
|
-
/** Defaults to visible columns in their current order. */
|
|
612
|
+
/** Defaults to visible exportable columns in their current order. Explicit non-exportable columns are rejected. */
|
|
379
613
|
columns?: string[];
|
|
380
614
|
values?: GridExportRequest["values"];
|
|
381
615
|
signal?: AbortSignal;
|
|
@@ -420,6 +654,16 @@ export interface GridState<Q extends AcceptedGridQuery = GridQuery> {
|
|
|
420
654
|
collapsedGroups?: string[];
|
|
421
655
|
/** Optional for compatibility with existing continuous snapshots; restored offsets clamp to current results. */
|
|
422
656
|
paging?: { pageLength: number; offset: number; allRows?: boolean };
|
|
657
|
+
/** Formatting rules edited at run time, when they differ from the view's; restored with the view. */
|
|
658
|
+
formatRules?: GridFormatRule[];
|
|
659
|
+
/** The reader's layout, in a grid with layout options. */
|
|
660
|
+
layout?: LayoutState;
|
|
661
|
+
/** The reader's Highlight matches switch, in a grid with searchHighlight. */
|
|
662
|
+
highlight?: boolean;
|
|
663
|
+
/** Whether the reader left the facet panel open, in a grid with facets. */
|
|
664
|
+
facets?: { open: boolean };
|
|
665
|
+
/** The calendar's view, date, zoom and collapsed resources, in a grid with a calendar. */
|
|
666
|
+
calendar?: GridCalendarSavedState;
|
|
423
667
|
}
|
|
424
668
|
/** Versioned, bounded preference envelope. Revisions/cursors belong to data, never durable settings. */
|
|
425
669
|
export type GridPreferenceQuery<Q extends AcceptedGridQuery = GridQuery> = Readonly<Omit<Q, "revision" | "cursor">> & {
|
|
@@ -444,53 +688,125 @@ export interface GridViewStore<Q extends AcceptedGridQuery = GridQuery> {
|
|
|
444
688
|
load(event: { key: string; view: string; signal: AbortSignal }): GridViewSettings<Q> | null | PromiseLike<GridViewSettings<Q> | null>;
|
|
445
689
|
save(event: { key: string; view: string; settings: GridViewSettings<Q>; signal: AbortSignal }): void | PromiseLike<void>;
|
|
446
690
|
}
|
|
447
|
-
interface GridHostBehavior<Q extends AcceptedGridQuery = GridQuery> {
|
|
691
|
+
interface GridHostBehavior<Q extends AcceptedGridQuery = GridQuery, Row extends GridRow = GridRow> {
|
|
448
692
|
/** False hides the whole toolbar so a host can compose controls around the same grid controller; an object switches
|
|
449
693
|
* single controls off (overriding the view's toolbar switches). Switched-off controls are not built. */
|
|
450
694
|
toolbar?: boolean | GridToolbarOptions;
|
|
451
695
|
/** Overrides the view's search-input debounce (0..5000); Enter always applies immediately. */
|
|
452
696
|
searchDelayMs?: number;
|
|
453
|
-
source?: Q extends GridCursorQuery ? GridCursorSource : GridSource
|
|
697
|
+
source?: Q extends GridCursorQuery ? GridCursorSource<Row> : GridSource<Row>;
|
|
454
698
|
labels?: Partial<CanopyLabels>;
|
|
455
|
-
renderers?: Record<string, (row:
|
|
699
|
+
renderers?: Record<string, (row: Row, element: HTMLElement, context: GridCellContext) => boolean | void>;
|
|
456
700
|
cachePageLimit?: number;
|
|
457
701
|
requestTimeoutMs?: number;
|
|
702
|
+
/** Formats the Export menu lists after CSV: ids of registered formats or provider objects, in order. Wins over the view's exportFormats; absent offers every registered format. */
|
|
703
|
+
exportFormats?: readonly (string | ExportFormat<GridExport<Q>>)[];
|
|
704
|
+
/** Safety timeout for export format writers and onExport, 1..2147483647 ms (default 600000). Page reads keep requestTimeoutMs. */
|
|
705
|
+
exportTimeoutMs?: number;
|
|
458
706
|
onQuery?: (event: GridQueryEvent<Q>) => void;
|
|
459
707
|
onSelect?: (event: { ids: string[]; selection?: GridSelection<Q> }) => void;
|
|
460
708
|
onError?: (event: { error: Error }) => void;
|
|
461
|
-
onColumnResize?: (event: { column:
|
|
462
|
-
onColumnPin?: (event: { column:
|
|
709
|
+
onColumnResize?: (event: { column: GridColumnId<Row>; width: number }) => void;
|
|
710
|
+
onColumnPin?: (event: { column: GridColumnId<Row>; pin: GridColumnPin }) => void;
|
|
463
711
|
onState?: (event: { query: Q | null; state: GridState<Q> }) => void;
|
|
464
|
-
/**
|
|
712
|
+
/** The grid's formatting rules changed (setFormatRules, the rule editor or a restored view); canopyx:format carries the same detail. */
|
|
713
|
+
onFormat?: (event: { rules: readonly GridFormatRule[] }) => void;
|
|
714
|
+
/** Hosts govern Office generation, authorization and delivery. CanopyX performs no domain write. Runs under exportTimeoutMs. */
|
|
465
715
|
onExport?: (event: { format: string; request: GridExportRequest<Q>; capture: GridExport<Q>; signal: AbortSignal;
|
|
466
716
|
/** Reporting runtime only. Monotonic record counts and phases; late calls after cancellation are ignored. */
|
|
467
717
|
reportProgress?: (phase: GridExportProgress["phase"], completed: number) => void }) => void | PromiseLike<void>;
|
|
468
718
|
/** Reporting runtime only. Render the complete snapshot through a host-owned renderer; honor cancellation before delivery. */
|
|
469
|
-
|
|
719
|
+
/** After a layout or density switch; the canopyx:layout event carries the same detail. */
|
|
720
|
+
onLayout?: (detail: LayoutState) => void | boolean;
|
|
721
|
+
/** After each finished match count and each move between matches; the canopyx:matches event carries the same detail. */
|
|
722
|
+
onMatches?: (detail: { total: number; current: number; complete: boolean }) => void | boolean;
|
|
723
|
+
/** layout asks for stacked records from a grid in the card layout and a table otherwise; print never scrolls. */
|
|
724
|
+
onPrint?: (event: { snapshot: GridExportSnapshot<Q>; signal: AbortSignal; layout: "table" | "stacked" }) => void | PromiseLike<void>;
|
|
470
725
|
/** Hosts compose a drawer or details view and restore returnFocus when it closes. */
|
|
471
|
-
onDetails?: (event: { row: Readonly<
|
|
726
|
+
onDetails?: (event: { row: Readonly<Row>; query: Q; signal: AbortSignal; returnFocus: Element | null }) => void | PromiseLike<void>;
|
|
727
|
+
/** Loads a record's details when its record panel opens; used whatever the view's record source declares. */
|
|
728
|
+
loadRecord?: RecordLoader;
|
|
729
|
+
/** Record panel section renderers by name, beside the plugins' drawerSections. */
|
|
730
|
+
recordSections?: Readonly<Record<string, RecordSectionRenderer>>;
|
|
731
|
+
/** Actions of the record actions menu, after the built-in ones. */
|
|
732
|
+
recordActions?: readonly RecordAction[];
|
|
733
|
+
/** Open all in grid of a collection; return false (or cancel canopyx:openAll) to filter the target yourself. */
|
|
734
|
+
onOpenAll?: (event: RecordOpenAll) => boolean | void;
|
|
735
|
+
/** Print one record; return false (or cancel canopyx:recordPrint) to print the sheet yourself. */
|
|
736
|
+
onRecordPrint?: (event: { readonly id: string; readonly element: HTMLElement; readonly dispose: () => void }) => boolean | void;
|
|
737
|
+
/** Row activation: a double click, Enter on a focused row, Ctrl/Command+Enter in a cell, or a click with rowAction (or on a
|
|
738
|
+
* phone). Runs before the row's own action (onDetails or the drawer, or the row's link); returning false keeps that from
|
|
739
|
+
* running, so the host can open its own view of the row. The cancelable canopyx:rowActivate event carries the same detail. */
|
|
740
|
+
onRowActivate?: (event: GridRowActivation<Row>) => boolean | void;
|
|
741
|
+
/** A link cell being followed. Returning false (or cancelling the canopyx:link event) keeps the browser from following it,
|
|
742
|
+
* so the host can route the address itself. */
|
|
743
|
+
onLink?: (event: GridLinkActivation<Row>) => boolean | void;
|
|
472
744
|
/** Adds Chart to the selection bar. The host owns chart generation. */
|
|
473
745
|
onChart?: (event: { query: Q | null; selection: GridSelection<Q>; signal: AbortSignal }) => void | PromiseLike<void>;
|
|
474
746
|
/** Host-owned secondary actions in the more menu. Content entries (render) need the reporting runtime: render fills the
|
|
475
747
|
* container on first open, focus moves to its first control, Escape folds it back, and close() closes the menu. */
|
|
476
748
|
actions?: readonly GridAction<Q>[];
|
|
749
|
+
/** Plugins for this grid only, after the page's (CanopyX.use); one replaces a page plugin of the same name. */
|
|
750
|
+
plugins?: readonly CanopyPlugin[];
|
|
751
|
+
/** Loads the link part when the grid is created and reports its selection and own conditions as canopyx:linkchange (LinkChange). */
|
|
752
|
+
linkEvents?: boolean;
|
|
753
|
+
/** Reporting detail rows drawn by the host (a template, trusted HTML or a nested grid or tree). */
|
|
754
|
+
detail?: GridDetailOptions<Row>;
|
|
755
|
+
/** Editing of editable columns: read-only rules, checks, lookups, editors and the batch writer (docs/editing.md). */
|
|
756
|
+
editing?: GridEditingOptions<Q>;
|
|
757
|
+
/** Before a value changes; returning false (or cancelling canopyx:cellValueChanging) keeps the old value. */
|
|
758
|
+
onCellValueChanging?: (event: GridCellValueChange) => boolean | void;
|
|
759
|
+
/** After a value changed. */
|
|
760
|
+
onCellValueChanged?: (event: GridCellValueChange) => void;
|
|
761
|
+
/** A row whose edits are complete and valid. Return a result (or true, or a promise) to save it, false to keep editing, nothing to leave it in the batch. */
|
|
762
|
+
onRowCommit?: (event: GridRowCommit) => GridCommitRowResult | boolean | void | PromiseLike<GridCommitRowResult | true>;
|
|
763
|
+
/** After commitChanges, with its result. */
|
|
764
|
+
onCommit?: (event: GridCommitOutcome) => void;
|
|
477
765
|
/** Optional host-governed removal of the report's fixed grouping. */
|
|
478
766
|
onUngroup?: (event: { query: Q | null; signal: AbortSignal }) => void | PromiseLike<void>;
|
|
767
|
+
/** Overrides the view's rangeSelection. */
|
|
768
|
+
rangeSelection?: GridRangeSelection;
|
|
769
|
+
/** Overrides the view's clipboard settings, switch by switch. */
|
|
770
|
+
clipboard?: GridClipboardSettings;
|
|
771
|
+
/** Live data settings, over the view's live object; true turns live data on with the defaults, false keeps the view's
|
|
772
|
+
* settings from applying while the live methods still work (live.d.ts). */
|
|
773
|
+
live?: boolean | GridLiveOptions<Row, Q>;
|
|
774
|
+
/** After rows changed in place (a transaction, a poll, a refresh); canopyx:rowsChanged carries the same detail. */
|
|
775
|
+
onRowsChanged?: (event: GridLiveResult) => void;
|
|
776
|
+
/** Facet panel settings over the view's facets, and an element the panel renders into (facets.d.ts). */
|
|
777
|
+
facets?: GridFacetPanelOptions<Row>;
|
|
778
|
+
/** After the reader opened or collapsed the facet panel; canopyx:facetPanel carries the same detail. */
|
|
779
|
+
onFacetPanel?: (event: { open: boolean }) => void;
|
|
780
|
+
/** Calendar options: the template hook that draws event content (calendar.d.ts). */
|
|
781
|
+
calendar?: GridCalendarOptions;
|
|
782
|
+
/** After the calendar painted a view or range; canopyx:calendar carries the same detail. */
|
|
783
|
+
onCalendar?: (event: GridCalendarState) => void;
|
|
784
|
+
/** Before one occurrence of a series moves; returning false (or cancelling canopyx:occurrenceChange) keeps the series. */
|
|
785
|
+
onOccurrenceChange?: (event: GridOccurrenceChange) => boolean | void;
|
|
786
|
+
/** Before the calendar proposes a new event; returning false (or cancelling canopyx:eventCreate) lets the host open its own form. */
|
|
787
|
+
onCreate?: (event: GridEventCreate) => boolean | void;
|
|
788
|
+
/** Before a dropped item becomes a record; returning false (or cancelling canopyx:eventReceive) lets the host schedule it. */
|
|
789
|
+
onReceive?: (event: GridEventReceive) => boolean | void;
|
|
790
|
+
/** Cells pasted or filled into the grid, before anything changes; returning false (or cancelling canopyx:paste) refuses them all. */
|
|
791
|
+
onPaste?: (event: GridPasteEvent) => boolean | void;
|
|
792
|
+
/** After the cell ranges changed. */
|
|
793
|
+
onCellRangeChange?: (event: { ranges: readonly GridCellRange[] }) => void;
|
|
479
794
|
}
|
|
480
795
|
/** A host store binds to an explicit keyed reporting definition; ordinary grids have no store option. */
|
|
481
|
-
export type GridHostOptions<Q extends AcceptedGridQuery = GridQuery> = GridHostBehavior<Q> & (
|
|
796
|
+
export type GridHostOptions<Q extends AcceptedGridQuery = GridQuery, Row extends GridRow = GridRow> = GridHostBehavior<Q, Row> & (
|
|
482
797
|
{ viewStore?: never } | {
|
|
483
798
|
viewStore: GridViewStore<Q>;
|
|
484
|
-
view: (Q extends GridCursorQuery ? CursorGridView : InlineGridView | HostGridView) & { stateKey: string; reporting: GridReporting };
|
|
799
|
+
view: (Q extends GridCursorQuery ? CursorGridView<Row> : InlineGridView<Row> | CompactGridView<Row> | HostGridView<Row>) & { stateKey: string; reporting: GridReporting };
|
|
485
800
|
}
|
|
486
801
|
);
|
|
487
|
-
|
|
488
|
-
export type
|
|
802
|
+
/** A flat grid's options; Row types the rows, columns, facets, events and live API (createDataGrid<Row>). */
|
|
803
|
+
export type GridOptions<Row extends GridRow = GridRow> = GridHostOptions<GridQuery, Row> & ({ view: InlineGridView<Row> | CompactGridView<Row> } | { view: HostGridView<Row>; source: GridSource<Row> });
|
|
804
|
+
export type CursorGridOptions<Row extends GridRow = GridRow> = GridHostOptions<GridCursorQuery, Row> & { view: CursorGridView<Row>; source: GridCursorSource<Row> };
|
|
489
805
|
|
|
490
|
-
/** Presentation controller. Selection uses stable IDs independently of cached or visible rows. */
|
|
491
|
-
export interface DataGrid<Q extends AcceptedGridQuery = GridQuery> {
|
|
806
|
+
/** Presentation controller. Selection uses stable IDs independently of cached or visible rows. Row (default GridRow) types its view, column methods and live API. */
|
|
807
|
+
export interface DataGrid<Q extends AcceptedGridQuery = GridQuery, Row extends GridRow = GridRow> extends GridEditingApi, LinkedView, ViewModeMethods, GridColumnGroupApi, GridCellRangeApi, GridLiveApi<Row, Q>, GridFacetPanelApi, GridCalendarApi {
|
|
492
808
|
readonly element: HTMLElement;
|
|
493
|
-
readonly view: GridView
|
|
809
|
+
readonly view: GridView<Row>;
|
|
494
810
|
readonly ready: Promise<Q>;
|
|
495
811
|
getQuery(): Q | null;
|
|
496
812
|
setQuery(query: GridQueryInput<Q>): Promise<Q>;
|
|
@@ -502,15 +818,15 @@ export interface DataGrid<Q extends AcceptedGridQuery = GridQuery> {
|
|
|
502
818
|
previousPage(): Promise<Q>;
|
|
503
819
|
nextPage(): Promise<Q>;
|
|
504
820
|
setPageLength(length: number | "all"): Promise<Q>;
|
|
505
|
-
setColumnWidth(id:
|
|
821
|
+
setColumnWidth(id: GridColumnId<Row>, width: number): void;
|
|
506
822
|
/** Samples at most 200 cached accepted-query records and 512 display code units per value, capped at 420 CSS pixels or maxWidth, and sets a sticky user width. No fetching or viewport scraping. */
|
|
507
|
-
autoFitColumn(id:
|
|
823
|
+
autoFitColumn(id: GridColumnId<Row>): Readonly<{ width: number; sampled: number; scope: "loaded" }>;
|
|
508
824
|
/** Fits every declared column from the same bounded loaded sample, including hidden columns. */
|
|
509
825
|
autoFitColumns(): Readonly<Record<string, Readonly<{ width: number; sampled: number; scope: "loaded" }>>>;
|
|
510
|
-
setColumnPinned(id:
|
|
826
|
+
setColumnPinned(id: GridColumnId<Row>, pin: GridColumnPin): void;
|
|
511
827
|
/** Drops user widths so the columns return to automatic content sizing. */
|
|
512
|
-
autoSizeColumns(ids?: readonly
|
|
513
|
-
setColumnPriority(id:
|
|
828
|
+
autoSizeColumns(ids?: readonly GridColumnId<Row>[]): void;
|
|
829
|
+
setColumnPriority(id: GridColumnId<Row>, priority: GridColumnPriority): void;
|
|
514
830
|
/** Restores the declared order, visibility, widths and pins; keeps the query. */
|
|
515
831
|
resetColumns(): void;
|
|
516
832
|
/** Reporting runtime only: effective layout for every declared column, with the reason a column is out of view. */
|
|
@@ -519,9 +835,9 @@ export interface DataGrid<Q extends AcceptedGridQuery = GridQuery> {
|
|
|
519
835
|
* data-cx-slot move into their slot when the grid mounts and return to the host element on destroy. */
|
|
520
836
|
toolbarSlot?(name: GridToolbarSlot): HTMLElement;
|
|
521
837
|
/** Reporting runtime only: revisioned, bounded full-query aggregation. Never reads the viewport cache for counts. */
|
|
522
|
-
getFacets?(column:
|
|
523
|
-
setColumnVisible(id:
|
|
524
|
-
setColumnOrder(ids:
|
|
838
|
+
getFacets?(column: GridColumnId<Row>, options?: GridFacetOptions): Promise<GridFacetPage>;
|
|
839
|
+
setColumnVisible(id: GridColumnId<Row>, visible: boolean): void;
|
|
840
|
+
setColumnOrder(ids: GridColumnId<Row>[]): void;
|
|
525
841
|
getState(): GridState<Q>;
|
|
526
842
|
setState(state: GridState<Q> | GridPreferenceState<Q>): Promise<Q>;
|
|
527
843
|
resetView(): Promise<Q>;
|
|
@@ -542,9 +858,21 @@ export interface DataGrid<Q extends AcceptedGridQuery = GridQuery> {
|
|
|
542
858
|
getSelectionDescriptor?(): GridSelection<Q>;
|
|
543
859
|
/** Reporting summary capability only; null before acceptance. */
|
|
544
860
|
getSummary?(): GridSummary | null;
|
|
545
|
-
/**
|
|
861
|
+
/** Grouped reporting grids (fixed or runtime). Keys name groups of any level. Collapse affects display; record query/selection/export scope remain intact. */
|
|
546
862
|
setGroupCollapsed?(key: string, collapsed: boolean): void;
|
|
547
863
|
getCollapsedGroups?(): string[];
|
|
864
|
+
/** Runtime grouping (groupBy or groupable): sets the levels, outermost first; [] ungroups. Resolves with the accepted query. */
|
|
865
|
+
setGroupBy?(groupBy: readonly GridGroupLevel[]): Promise<Q>;
|
|
866
|
+
getGroupBy?(): readonly GridGroupLevel[];
|
|
867
|
+
expandAllGroups?(): Promise<void>;
|
|
868
|
+
collapseAllGroups?(): Promise<void>;
|
|
869
|
+
/** Level 1 is the outermost; 0 means every level. */
|
|
870
|
+
setGroupLevelCollapsed?(level: number, collapsed: boolean): Promise<void>;
|
|
871
|
+
/** Detail rows: expanding loads the content once and resolves when it is drawn. */
|
|
872
|
+
expandDetail?(id: string): Promise<void>;
|
|
873
|
+
collapseDetail?(id: string): Promise<void>;
|
|
874
|
+
toggleDetail?(id: string): Promise<void>;
|
|
875
|
+
getExpandedDetails?(): string[];
|
|
548
876
|
/** Requires selection controls and multiple selection. Query/revision changes retire this scope; paging preserves it. */
|
|
549
877
|
selectAllMatching?(): void;
|
|
550
878
|
/** Selects/deselects the full accepted page, including records outside the mounted viewport. */
|
|
@@ -562,30 +890,55 @@ export interface DataGrid<Q extends AcceptedGridQuery = GridQuery> {
|
|
|
562
890
|
prepareExport(options: GridExportOptions): GridExport<Q>;
|
|
563
891
|
toCsv(options: GridExportOptions): Promise<string>;
|
|
564
892
|
copy(options: GridExportOptions): Promise<string>;
|
|
565
|
-
|
|
893
|
+
/** Runs onExport under the export safety timeout (timeoutMs, else exportTimeoutMs); page reads keep requestTimeoutMs. */
|
|
894
|
+
exportToHost(format: string, options: GridExportOptions & { timeoutMs?: number }): Promise<void>;
|
|
895
|
+
/** Captures now (invalid capture options throw synchronously), then runs a registered or configured export format (the same writers the Export menu lists) and downloads its file. */
|
|
896
|
+
exportAs(format: string, options: Omit<GridExportOptions, "onProgress" | "maxRows"> & ExportFormatOptions): Promise<ExportFormatResult>;
|
|
566
897
|
/** Reporting runtime only. Complete bounded record snapshot; default maxRows is 1000, never silently truncates. */
|
|
567
898
|
materializeExport?(options: GridExportOptions): Promise<GridExportSnapshot<Q>>;
|
|
568
899
|
/** Reporting runtime only. Passes the same bounded snapshot to onPrint; never prints viewport DOM. */
|
|
569
900
|
print?(options: GridExportOptions): Promise<void>;
|
|
570
901
|
/** Details are opened for loaded records, by toolbar, double click or Ctrl/Command+Enter. */
|
|
571
902
|
openDetails(id: string): Promise<void>;
|
|
903
|
+
/** The current formatting rules: the view's, or the ones set since. */
|
|
904
|
+
getFormatRules(): readonly GridFormatRule[];
|
|
905
|
+
/** Replaces the formatting rules after validating them as a whole (a bad set changes nothing); loads the formatting part on first use. */
|
|
906
|
+
setFormatRules(rules: readonly GridFormatRule[]): Promise<readonly GridFormatRule[]>;
|
|
907
|
+
/** Opens the rule editor; loads the formatting and rule editor parts on first use. */
|
|
908
|
+
openFormatRules(): Promise<void>;
|
|
909
|
+
/** Opens any record in the record drawer: a loaded row, one the grid scrolls to, or one its record source returns. */
|
|
910
|
+
openRecord(id: string, options?: OpenRecordOptions): Promise<void>;
|
|
572
911
|
focus(): void;
|
|
573
912
|
/** Reveals a zero-based position in the accepted result without taking DOM focus from a host drawer. */
|
|
574
913
|
scrollToRow(index: number): Promise<void>;
|
|
575
914
|
retry(): Promise<Q | void>;
|
|
915
|
+
/** Closes this grid's toolbar menus and column popover. To close the menus of every view, dispatch canopyx:closemenus on the document. */
|
|
916
|
+
closeMenus(): void;
|
|
576
917
|
/** Repaints the accepted data without querying the source. */
|
|
577
918
|
refresh(): void;
|
|
578
919
|
/** Requests a fresh source revision with accepted filters and ordering, or initial definition criteria before acceptance. Traversal restarts at the first page. */
|
|
579
920
|
reload(): Promise<Q>;
|
|
580
921
|
destroy(): void;
|
|
581
922
|
}
|
|
582
|
-
/**
|
|
583
|
-
|
|
584
|
-
|
|
923
|
+
/**
|
|
924
|
+
* Requires a browser DOM. The grid runtime also hosts both existing tree variants. Name a row type to check columns, rows,
|
|
925
|
+
* facets, events and the live API against it: `createDataGrid<Server>(element, { view })`, where `Server extends GridRow`.
|
|
926
|
+
*/
|
|
927
|
+
/** Keeps a type parameter from being inferred from an argument (the deferred form works on every supported compiler). */
|
|
928
|
+
type GridNamedRow<Row> = [Row][Row extends unknown ? 0 : never];
|
|
929
|
+
// The row type is named, never inferred from the options: without one, rows are plain GridRow.
|
|
930
|
+
export function createDataGrid<Row extends GridRow = GridRow>(host: HTMLElement, options: GridOptions<GridNamedRow<Row>>): DataGrid<GridQuery, Row>;
|
|
931
|
+
export function createDataGrid<Row extends GridRow = GridRow>(host: HTMLElement, options: CursorGridOptions<GridNamedRow<Row>>): DataGrid<GridCursorQuery, Row>;
|
|
932
|
+
/** A calendar from a list of events, with no grid schema to write: a preset (basic by default) and options over it (calendar.d.ts). */
|
|
933
|
+
export function createCalendar(host: HTMLElement, options?: CalendarOptions): DataGrid<GridQuery, GridRow>;
|
|
585
934
|
/** Registers options before either a tree or flat-grid fragment mounts. */
|
|
586
935
|
export function configure(viewId: string, options: HostOptions | GridHostOptions | GridHostOptions<GridCursorQuery>): () => void;
|
|
587
|
-
/**
|
|
936
|
+
/**
|
|
937
|
+
* Mounts tree and flat-grid fragments below root, or root itself when it is a fragment. Fragments marked
|
|
938
|
+
* `data-cx-mount="visible"` below root wait until they come near the viewport; passing such a fragment as root mounts it at once.
|
|
939
|
+
* Narrow a controller before using view-specific methods.
|
|
940
|
+
*/
|
|
588
941
|
export function mount(root?: ParentNode): Array<TreeGrid | DataGrid<AcceptedGridQuery>>;
|
|
589
942
|
|
|
590
|
-
declare const gridRuntime: Omit<typeof CanopyX, "configure" | "mount"> & { createDataGrid: typeof createDataGrid; configure: typeof configure; mount: typeof mount };
|
|
943
|
+
declare const gridRuntime: Omit<typeof CanopyX, "configure" | "mount"> & { createDataGrid: typeof createDataGrid; createCalendar: typeof createCalendar; enhance: typeof enhance; grid: typeof grid; configure: typeof configure; mount: typeof mount };
|
|
591
944
|
export default gridRuntime;
|