@navette-js/tables 0.0.0-stage → 1.0.0-beta.2
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/LICENSE +21 -0
- package/README.md +8 -2
- package/lib/index.d.ts +787 -0
- package/lib/index.js +1308 -0
- package/lib/query-builder.d.ts +302 -0
- package/lib/query-builder.js +869 -0
- package/package.json +49 -4
- package/views/asset.ejs +1 -0
- package/views/column-manager.ejs +146 -0
- package/views/index.ejs +790 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,787 @@
|
|
|
1
|
+
import type { DataAdapter, ListQuery, Page as RecordPage, SortDirection } from '@navette-js/database';
|
|
2
|
+
import { Attributes, type ColorManager } from '@navette-js/support';
|
|
3
|
+
export * from './query-builder.ts';
|
|
4
|
+
/** Render hook slots of a table. */
|
|
5
|
+
export declare const TablesRenderHook: {
|
|
6
|
+
readonly CONTENT_AFTER: "tables::content.after";
|
|
7
|
+
readonly CONTENT_BEFORE: "tables::content.before";
|
|
8
|
+
readonly SELECTION_INDICATOR_ACTIONS_AFTER: "tables::selection.indicator.actions.after";
|
|
9
|
+
readonly SELECTION_INDICATOR_ACTIONS_BEFORE: "tables::selection.indicator.actions.before";
|
|
10
|
+
readonly HEADER_AFTER: "tables::header.after";
|
|
11
|
+
readonly HEADER_BEFORE: "tables::header.before";
|
|
12
|
+
readonly TOOLBAR_AFTER: "tables::toolbar.after";
|
|
13
|
+
readonly TOOLBAR_BEFORE: "tables::toolbar.before";
|
|
14
|
+
readonly TOOLBAR_COLUMN_MANAGER_TRIGGER_AFTER: "tables::toolbar.toggle-column-trigger.after";
|
|
15
|
+
readonly TOOLBAR_COLUMN_MANAGER_TRIGGER_BEFORE: "tables::toolbar.toggle-column-trigger.before";
|
|
16
|
+
readonly TOOLBAR_END: "tables::toolbar.end";
|
|
17
|
+
readonly TOOLBAR_GROUPING_SELECTOR_AFTER: "tables::toolbar.grouping-selector.after";
|
|
18
|
+
readonly TOOLBAR_GROUPING_SELECTOR_BEFORE: "tables::toolbar.grouping-selector.before";
|
|
19
|
+
readonly TOOLBAR_REORDER_TRIGGER_AFTER: "tables::toolbar.reorder-trigger.after";
|
|
20
|
+
readonly TOOLBAR_REORDER_TRIGGER_BEFORE: "tables::toolbar.reorder-trigger.before";
|
|
21
|
+
readonly TOOLBAR_SEARCH_AFTER: "tables::toolbar.search.after";
|
|
22
|
+
readonly TOOLBAR_SEARCH_BEFORE: "tables::toolbar.search.before";
|
|
23
|
+
readonly TOOLBAR_START: "tables::toolbar.start";
|
|
24
|
+
readonly FILTER_INDICATORS: "tables::filter.indicators";
|
|
25
|
+
readonly HEADER_CELL: "tables::header.cell";
|
|
26
|
+
/** Legacy aliases of the column manager trigger slots. */
|
|
27
|
+
readonly TOOLBAR_TOGGLE_COLUMN_TRIGGER_AFTER: "tables::toolbar.toggle-column-trigger.after";
|
|
28
|
+
readonly TOOLBAR_TOGGLE_COLUMN_TRIGGER_BEFORE: "tables::toolbar.toggle-column-trigger.before";
|
|
29
|
+
};
|
|
30
|
+
/** Methods and properties that trigger the table's loading state (`wire:target`). */
|
|
31
|
+
export declare const LOADING_TARGETS = "activeTab,applyTableFilters,gotoPage,nextPage,previousPage,removeTableFilter,removeTableFilters,reorderTable,resetTableColumnSearch,resetTableFiltersForm,resetTableSearch,setPage,sortTable,tableColumnSearches,tableFilters,tableGrouping,tableRecordsPerPage,tableSearch,tableSort,toggleTableReordering";
|
|
32
|
+
type StateResolver<R> = (ctx: {
|
|
33
|
+
record: R;
|
|
34
|
+
}) => unknown | Promise<unknown>;
|
|
35
|
+
/** Base class of table columns. */
|
|
36
|
+
export declare abstract class Column<R = any> {
|
|
37
|
+
/** Default setup for every instance created afterwards by `make()`, e.g. `TextColumn.configureUsing((column) => column.sortable())`. */
|
|
38
|
+
static configureUsing<T>(this: abstract new (...args: any[]) => T, configure: (instance: T) => void): void;
|
|
39
|
+
readonly name: string;
|
|
40
|
+
protected _label: string | null;
|
|
41
|
+
protected _sortable: boolean;
|
|
42
|
+
protected _searchable: boolean;
|
|
43
|
+
protected _individuallySearchable: boolean;
|
|
44
|
+
protected _toggleable: boolean;
|
|
45
|
+
protected _toggledHiddenByDefault: boolean;
|
|
46
|
+
protected _alignment: string | null;
|
|
47
|
+
protected _state: StateResolver<R> | null;
|
|
48
|
+
protected _sortColumn: string | null;
|
|
49
|
+
protected _searchColumn: string | null;
|
|
50
|
+
protected _url: ((record: R) => string | null) | null;
|
|
51
|
+
/** Label of the column group this column belongs to (set by ColumnGroup). */
|
|
52
|
+
_group: string | null;
|
|
53
|
+
constructor(name: string);
|
|
54
|
+
label(label: string): this;
|
|
55
|
+
/** `column`: column (or query alias) to sort by when it differs from the name, e.g. for a relationship. */
|
|
56
|
+
sortable(condition?: boolean | {
|
|
57
|
+
column: string;
|
|
58
|
+
inverted?: boolean;
|
|
59
|
+
}): this;
|
|
60
|
+
getSortColumn(): string;
|
|
61
|
+
private _sortInverted;
|
|
62
|
+
/** `inverted`: the sort column runs opposite to the displayed value (e.g. an age sorted by birth date). */
|
|
63
|
+
isSortInverted(): boolean;
|
|
64
|
+
/** Link on the cell; takes precedence over the row action. */
|
|
65
|
+
url(resolver: (record: R) => string | null): this;
|
|
66
|
+
getUrl(record: R): string | null;
|
|
67
|
+
/** `isGlobal: false` excludes the column from the global search; `isIndividual` adds a search field for this column. */
|
|
68
|
+
getSearchColumn(): string;
|
|
69
|
+
searchable(options?: boolean | {
|
|
70
|
+
isIndividual?: boolean;
|
|
71
|
+
isGlobal?: boolean;
|
|
72
|
+
column?: string;
|
|
73
|
+
}): this;
|
|
74
|
+
/** Lets the user hide the column from the column manager. */
|
|
75
|
+
toggleable(condition?: boolean, options?: {
|
|
76
|
+
isToggledHiddenByDefault?: boolean;
|
|
77
|
+
}): this;
|
|
78
|
+
alignment(alignment: 'start' | 'center' | 'end' | null): this;
|
|
79
|
+
alignEnd(): this;
|
|
80
|
+
alignLeft(): this;
|
|
81
|
+
alignCenter(): this;
|
|
82
|
+
getStateUsing(resolver: StateResolver<R>): this;
|
|
83
|
+
getLabel(): string;
|
|
84
|
+
isSortable(): boolean;
|
|
85
|
+
isGloballySearchable(): boolean;
|
|
86
|
+
isIndividuallySearchable(): boolean;
|
|
87
|
+
isToggleable(): boolean;
|
|
88
|
+
isToggledHiddenByDefault(): boolean;
|
|
89
|
+
getAlignment(): string | null;
|
|
90
|
+
/** Suffix of the `fi-ta-header-cell-…` / `fi-ta-cell-…` classes: underscores become dashes, dots are kept. */
|
|
91
|
+
getCssName(): string;
|
|
92
|
+
getState(record: R): Promise<unknown>;
|
|
93
|
+
/** True for editable cells: they are not wrapped in a link or button to the record. */
|
|
94
|
+
isClickDisabled(): boolean;
|
|
95
|
+
abstract toHtml(record: R, recordKey?: string | number): Promise<string>;
|
|
96
|
+
}
|
|
97
|
+
export declare class TextColumn<R = any> extends Column<R> {
|
|
98
|
+
private _weight;
|
|
99
|
+
private _copyable;
|
|
100
|
+
private _money;
|
|
101
|
+
private _placeholder;
|
|
102
|
+
private _badge;
|
|
103
|
+
private _color;
|
|
104
|
+
private _icon;
|
|
105
|
+
private _format;
|
|
106
|
+
private _date;
|
|
107
|
+
private _numeric;
|
|
108
|
+
private _summarizers;
|
|
109
|
+
private _limit;
|
|
110
|
+
private _tooltip;
|
|
111
|
+
static make<R = any>(name: string): TextColumn<R>;
|
|
112
|
+
/** Displays the value in a badge. */
|
|
113
|
+
badge(condition?: boolean): this;
|
|
114
|
+
color(color: string | ((record: R) => string)): this;
|
|
115
|
+
icon(resolver: (record: R) => string | null): this;
|
|
116
|
+
/** Text displayed instead of the raw value (e.g. an enum label). */
|
|
117
|
+
formatStateUsing(formatter: (ctx: {
|
|
118
|
+
state: unknown;
|
|
119
|
+
record: R;
|
|
120
|
+
}) => string): this;
|
|
121
|
+
/** Short date, e.g. "Nov 9, 2026". */
|
|
122
|
+
date(condition?: boolean): this;
|
|
123
|
+
private _dateTime;
|
|
124
|
+
/** Date and time, e.g. "Nov 9, 2026 14:30:00". */
|
|
125
|
+
dateTime(condition?: boolean): this;
|
|
126
|
+
/** Number formatted with thousands separators. */
|
|
127
|
+
private _decimals;
|
|
128
|
+
/** `numeric(1)`: fixed number of decimals. */
|
|
129
|
+
numeric(condition?: boolean | number): this;
|
|
130
|
+
/** Summary row below the table. */
|
|
131
|
+
summarize(summarizer: Summarizer | Summarizer[]): this;
|
|
132
|
+
getSummarizers(): Summarizer[];
|
|
133
|
+
weight(weight: string): this;
|
|
134
|
+
/** Truncates the displayed text to `length` characters, followed by "...". */
|
|
135
|
+
limit(length: number | null): this;
|
|
136
|
+
/** Tooltip on hover; `null` for none. */
|
|
137
|
+
tooltip(tooltip: ((record: R) => string | null) | string | null): this;
|
|
138
|
+
copyable(condition?: boolean): this;
|
|
139
|
+
/** Amount formatted in the given currency, e.g. `money('usd')`. */
|
|
140
|
+
money(currency?: string | ((record: R) => string)): this;
|
|
141
|
+
/** Text displayed when the value is empty. */
|
|
142
|
+
placeholder(text: string | null): this;
|
|
143
|
+
/** Cell content: a short markup for plain text, a full markup as soon as an option (badge, icon, color…) is set. */
|
|
144
|
+
toHtml(record: R): Promise<string>;
|
|
145
|
+
}
|
|
146
|
+
/** Values a summarizer works from: aggregates over the query (all records) or over the displayed page. */
|
|
147
|
+
export type SummaryValues = {
|
|
148
|
+
count: number;
|
|
149
|
+
sum: Record<string, number>;
|
|
150
|
+
avg: Record<string, number>;
|
|
151
|
+
min: Record<string, unknown>;
|
|
152
|
+
max: Record<string, unknown>;
|
|
153
|
+
};
|
|
154
|
+
export type SummaryItem = {
|
|
155
|
+
type: 'text' | 'range';
|
|
156
|
+
label: string | null;
|
|
157
|
+
value: string;
|
|
158
|
+
};
|
|
159
|
+
/** Column summary below the table: sum, average, count or range. */
|
|
160
|
+
export declare abstract class Summarizer {
|
|
161
|
+
abstract readonly kind: 'sum' | 'avg' | 'count' | 'range';
|
|
162
|
+
protected _label: string | null;
|
|
163
|
+
protected _money: string | null;
|
|
164
|
+
label(label: string | null): this;
|
|
165
|
+
money(currency?: string): this;
|
|
166
|
+
getLabel(): string | null;
|
|
167
|
+
format(value: number): string;
|
|
168
|
+
abstract summarize(column: string, values: SummaryValues): SummaryItem | null;
|
|
169
|
+
}
|
|
170
|
+
/** Column total. */
|
|
171
|
+
export declare class Sum extends Summarizer {
|
|
172
|
+
readonly kind = "sum";
|
|
173
|
+
static make(): Sum;
|
|
174
|
+
getLabel(): string;
|
|
175
|
+
summarize(column: string, values: SummaryValues): SummaryItem;
|
|
176
|
+
}
|
|
177
|
+
/** Column average. */
|
|
178
|
+
export declare class Average extends Summarizer {
|
|
179
|
+
readonly kind = "avg";
|
|
180
|
+
static make(): Average;
|
|
181
|
+
getLabel(): string;
|
|
182
|
+
summarize(column: string, values: SummaryValues): SummaryItem;
|
|
183
|
+
}
|
|
184
|
+
/** Record count. */
|
|
185
|
+
export declare class Count extends Summarizer {
|
|
186
|
+
readonly kind = "count";
|
|
187
|
+
static make(): Count;
|
|
188
|
+
getLabel(): string;
|
|
189
|
+
summarize(_column: string, values: SummaryValues): SummaryItem;
|
|
190
|
+
}
|
|
191
|
+
/** Smallest and largest value of a column. */
|
|
192
|
+
export declare class Range extends Summarizer {
|
|
193
|
+
readonly kind = "range";
|
|
194
|
+
private _minimalDateTime;
|
|
195
|
+
static make(): Range;
|
|
196
|
+
/** Dates: day only when the bounds fall on different days, day and time otherwise; a single value when both are equal. */
|
|
197
|
+
minimalDateTimeDifference(condition?: boolean): this;
|
|
198
|
+
summarize(column: string, values: SummaryValues): SummaryItem | null;
|
|
199
|
+
}
|
|
200
|
+
/** Row grouping: rows are sorted by the column and each group gets a header row. */
|
|
201
|
+
export declare class Group<R = any> {
|
|
202
|
+
private id;
|
|
203
|
+
private _label;
|
|
204
|
+
private _column;
|
|
205
|
+
private _title;
|
|
206
|
+
private _description;
|
|
207
|
+
private _collapsible;
|
|
208
|
+
private _date;
|
|
209
|
+
private _titlePrefixedWithLabel;
|
|
210
|
+
constructor(id: string);
|
|
211
|
+
static make<R = any>(id: string): Group<R>;
|
|
212
|
+
label(label: string | null): this;
|
|
213
|
+
/** Query column holding the group value, when it differs from the id (relationship). */
|
|
214
|
+
column(column: string | null): this;
|
|
215
|
+
/** Group title computed from the record (e.g. an enum label). */
|
|
216
|
+
getTitleUsing(resolver: ((record: R) => string | null) | null): this;
|
|
217
|
+
getDescriptionUsing(resolver: ((record: R) => string | null) | null): this;
|
|
218
|
+
/** Aliases using the `get…FromRecordUsing` naming. */
|
|
219
|
+
getTitleFromRecordUsing(resolver: ((record: R) => string | null) | null): this;
|
|
220
|
+
getDescriptionFromRecordUsing(resolver: ((record: R) => string | null) | null): this;
|
|
221
|
+
/** Groups collapse when their header is clicked. */
|
|
222
|
+
collapsible(condition?: boolean): this;
|
|
223
|
+
/** The column is a date: rows from the same day form one group. */
|
|
224
|
+
date(condition?: boolean): this;
|
|
225
|
+
titlePrefixedWithLabel(condition?: boolean): this;
|
|
226
|
+
getId(): string;
|
|
227
|
+
getLabel(): string;
|
|
228
|
+
getColumn(): string;
|
|
229
|
+
isCollapsible(): boolean;
|
|
230
|
+
isDate(): boolean;
|
|
231
|
+
isTitlePrefixedWithLabel(): boolean;
|
|
232
|
+
/** Group value of a record, as text; `null` when empty. */
|
|
233
|
+
getStringKey(record: R): string | null;
|
|
234
|
+
getTitle(record: R): string | null;
|
|
235
|
+
getDescription(record: R): string | null;
|
|
236
|
+
/** Restricts a query to the records of the group with the given key. */
|
|
237
|
+
scope(query: any, key: string | null): void;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Column layout: as soon as a table has one, records are rendered as cards (`fi-ta-content`) instead of table rows,
|
|
241
|
+
* and sorting goes through a "Sort by" select.
|
|
242
|
+
*/
|
|
243
|
+
export declare abstract class ColumnLayout<R = any> {
|
|
244
|
+
protected _children: (Column<R> | ColumnLayout<R>)[];
|
|
245
|
+
constructor(children: (Column<R> | ColumnLayout<R>)[]);
|
|
246
|
+
getChildren(): (Column<R> | ColumnLayout<R>)[];
|
|
247
|
+
/** Leaf columns, in order: the ones the table sorts, searches and toggles. */
|
|
248
|
+
getColumns(): Column<R>[];
|
|
249
|
+
abstract getClasses(): string[];
|
|
250
|
+
}
|
|
251
|
+
/** Columns side by side, from a given breakpoint. */
|
|
252
|
+
export declare class Split<R = any> extends ColumnLayout<R> {
|
|
253
|
+
private _from;
|
|
254
|
+
static make<R = any>(children: (Column<R> | ColumnLayout<R>)[]): Split<R>;
|
|
255
|
+
from(breakpoint: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | null): this;
|
|
256
|
+
getClasses(): string[];
|
|
257
|
+
}
|
|
258
|
+
/** Columns stacked vertically. */
|
|
259
|
+
export declare class Stack<R = any> extends ColumnLayout<R> {
|
|
260
|
+
private _space;
|
|
261
|
+
private _alignment;
|
|
262
|
+
static make<R = any>(children: (Column<R> | ColumnLayout<R>)[]): Stack<R>;
|
|
263
|
+
/** Gap between columns: 1 (small), 2 (medium) or 3 (large). */
|
|
264
|
+
space(space?: 1 | 2 | 3 | null): this;
|
|
265
|
+
alignment(alignment: 'start' | 'center' | 'end'): this;
|
|
266
|
+
getClasses(): string[];
|
|
267
|
+
}
|
|
268
|
+
/** Column group: a shared label above the column headers. */
|
|
269
|
+
export declare class ColumnGroup<R = any> {
|
|
270
|
+
private label;
|
|
271
|
+
private _columns;
|
|
272
|
+
constructor(label: string);
|
|
273
|
+
static make<R = any>(label: string): ColumnGroup<R>;
|
|
274
|
+
columns(columns: Column<R>[]): this;
|
|
275
|
+
getColumns(): Column<R>[];
|
|
276
|
+
}
|
|
277
|
+
/** Color swatch column. */
|
|
278
|
+
export declare class ColorColumn<R = any> extends Column<R> {
|
|
279
|
+
static make<R = any>(name: string): ColorColumn<R>;
|
|
280
|
+
toHtml(record: R): Promise<string>;
|
|
281
|
+
}
|
|
282
|
+
/** Image column: the state is the image URL. Only local or http(s) URLs are rendered. */
|
|
283
|
+
export declare class ImageColumn<R = any> extends Column<R> {
|
|
284
|
+
private _alt;
|
|
285
|
+
private _height;
|
|
286
|
+
private _circular;
|
|
287
|
+
static make<R = any>(name: string): ImageColumn<R>;
|
|
288
|
+
alt(resolver: (record: R) => string | null): this;
|
|
289
|
+
/** CSS height of the image (`2.5rem` by default). */
|
|
290
|
+
imageHeight(height: string): this;
|
|
291
|
+
circular(condition?: boolean): this;
|
|
292
|
+
toHtml(record: R): Promise<string>;
|
|
293
|
+
}
|
|
294
|
+
/** Icon depending on the value; `boolean()` shows a green check or a red cross. */
|
|
295
|
+
export declare class IconColumn<R = any> extends Column<R> {
|
|
296
|
+
private _boolean;
|
|
297
|
+
static make<R = any>(name: string): IconColumn<R>;
|
|
298
|
+
boolean(condition?: boolean): this;
|
|
299
|
+
toHtml(record: R): Promise<string>;
|
|
300
|
+
}
|
|
301
|
+
/** Application-defined validation rule of an editable column: synchronous check and message (`:attribute` already replaced). */
|
|
302
|
+
export type ColumnValidationRule = {
|
|
303
|
+
name: string;
|
|
304
|
+
passes: (value: unknown) => boolean;
|
|
305
|
+
message: (attribute: string) => string;
|
|
306
|
+
};
|
|
307
|
+
type StateHook<R> = (ctx: {
|
|
308
|
+
state: unknown;
|
|
309
|
+
record: R;
|
|
310
|
+
}) => unknown | Promise<unknown>;
|
|
311
|
+
/**
|
|
312
|
+
* Base class of in-cell editable columns. The browser calls `updateTableColumnState(column, key, value)` on the host component:
|
|
313
|
+
* the column must be declared, visible and enabled for this record, and the value must pass the rules; only then do
|
|
314
|
+
* `beforeStateUpdated`, the write and `afterStateUpdated` run. The write does not check model permissions: use `disabled()`
|
|
315
|
+
* to restrict editing.
|
|
316
|
+
*/
|
|
317
|
+
export declare abstract class EditableColumn<R = any> extends Column<R> {
|
|
318
|
+
protected _disabled: ((record: R) => boolean | Promise<boolean>) | boolean;
|
|
319
|
+
protected _rules: (string | ColumnValidationRule)[];
|
|
320
|
+
protected _validationAttribute: string | null;
|
|
321
|
+
protected _validationMessages: Record<string, string>;
|
|
322
|
+
protected _updateStateUsing: StateHook<R> | null;
|
|
323
|
+
protected _beforeStateUpdated: StateHook<R> | null;
|
|
324
|
+
protected _afterStateUpdated: StateHook<R> | null;
|
|
325
|
+
protected _tooltip: ((record: R) => string | null) | string | null;
|
|
326
|
+
disabled(condition?: ((record: R) => boolean | Promise<boolean>) | boolean): this;
|
|
327
|
+
isDisabledFor(record: R): Promise<boolean>;
|
|
328
|
+
/** An editable cell is neither a link nor a button to the record. */
|
|
329
|
+
isClickDisabled(): boolean;
|
|
330
|
+
isEditable(): boolean;
|
|
331
|
+
/** Rules applied to the received value: strings (`required`, `max:255`, `in:a,b`…) or `{ name, passes, message }` objects. */
|
|
332
|
+
rules(rules: (string | ColumnValidationRule)[]): this;
|
|
333
|
+
getRules(): (string | ColumnValidationRule)[];
|
|
334
|
+
/** Same as adding `required` to the rules. */
|
|
335
|
+
required(condition?: boolean): this;
|
|
336
|
+
isRequired(): boolean;
|
|
337
|
+
/** Column name used in messages (defaults to the label with a lowercase first letter). */
|
|
338
|
+
validationAttribute(label: string | null): this;
|
|
339
|
+
/** Custom messages by rule name, e.g. `{ max: 'Too long.' }`. */
|
|
340
|
+
validationMessages(messages: Record<string, string>): this;
|
|
341
|
+
getValidationAttribute(): string;
|
|
342
|
+
/** Rules specific to the column type (e.g. select options). */
|
|
343
|
+
protected getImplicitRules(): ColumnValidationRule[];
|
|
344
|
+
/**
|
|
345
|
+
* Error message, or `null` if the value is valid. An empty value is only checked by `required`, and several errors
|
|
346
|
+
* produce the first message followed by "(and N more errors)".
|
|
347
|
+
*/
|
|
348
|
+
validate(input: unknown): string | null;
|
|
349
|
+
/** Custom write, replacing the update of the record's column. Its return value is sent back to the browser. */
|
|
350
|
+
updateStateUsing(callback: StateHook<R> | null): this;
|
|
351
|
+
beforeStateUpdated(callback: StateHook<R> | null): this;
|
|
352
|
+
afterStateUpdated(callback: StateHook<R> | null): this;
|
|
353
|
+
/** Tooltip on the control, shown while no error is displayed. */
|
|
354
|
+
tooltip(tooltip: ((record: R) => string | null) | string | null): this;
|
|
355
|
+
getUpdateStateMessages(): Record<'saving' | 'saved' | 'failure', string>;
|
|
356
|
+
/** Value written from a validated value: blank values become `null`. */
|
|
357
|
+
castState(input: unknown): unknown;
|
|
358
|
+
/**
|
|
359
|
+
* Saves an already validated value. Only the column's declared name is written: a relationship column (`author.name`)
|
|
360
|
+
* can only be edited with `updateStateUsing()`.
|
|
361
|
+
*/
|
|
362
|
+
updateState(record: R, input: unknown, adapter: Pick<DataAdapter<R>, 'getKey' | 'update'>): Promise<unknown>;
|
|
363
|
+
/** `x-tooltip` expression of editable controls: the column tooltip, replaced by the validation error when there is one. */
|
|
364
|
+
protected tooltipExpression(record: R): string;
|
|
365
|
+
/** Shared opening markup of editable cells: lazily loaded Alpine component, server state and record key. */
|
|
366
|
+
protected editableAttributes(component: string, asset: string, recordKey: string | number, state: unknown): Attributes;
|
|
367
|
+
protected static readonly STATUS_HTML = "<p x-cloak x-show=\"error\" x-bind:id=\"$id('table-column-error')\" x-ref=\"error\" x-text=\"error\" class=\"fi-sr-only\"></p><p role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" x-text=\"status\" class=\"fi-sr-only\"></p>";
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* In-cell editable select (native select only). The received value must be one of the declared options.
|
|
371
|
+
*/
|
|
372
|
+
export declare class SelectColumn<R = any> extends EditableColumn<R> {
|
|
373
|
+
private _options;
|
|
374
|
+
private _selectablePlaceholder;
|
|
375
|
+
static make<R = any>(name: string): SelectColumn<R>;
|
|
376
|
+
options(options: [string, string][] | Record<string, string>): this;
|
|
377
|
+
getOptions(): [string, string][];
|
|
378
|
+
selectablePlaceholder(condition?: boolean): this;
|
|
379
|
+
protected getImplicitRules(): ColumnValidationRule[];
|
|
380
|
+
toHtml(record: R, recordKey?: string | number): Promise<string>;
|
|
381
|
+
}
|
|
382
|
+
/** In-cell editable toggle. The received value must be a boolean (`boolean` rule by default). */
|
|
383
|
+
export declare class ToggleColumn<R = any> extends EditableColumn<R> {
|
|
384
|
+
private _onColor;
|
|
385
|
+
private _offColor;
|
|
386
|
+
private _onIcon;
|
|
387
|
+
private _offIcon;
|
|
388
|
+
constructor(name: string);
|
|
389
|
+
static make<R = any>(name: string): ToggleColumn<R>;
|
|
390
|
+
/** Toggle color when on (`primary` by default) and off (`gray`). */
|
|
391
|
+
onColor(color: string | null): this;
|
|
392
|
+
offColor(color: string | null): this;
|
|
393
|
+
/** Icons shown inside the toggle's thumb. */
|
|
394
|
+
onIcon(icon: string | null): this;
|
|
395
|
+
offIcon(icon: string | null): this;
|
|
396
|
+
castState(input: unknown): unknown;
|
|
397
|
+
toHtml(record: R, recordKey?: string | number): Promise<string>;
|
|
398
|
+
}
|
|
399
|
+
/** In-cell editable checkbox. The received value must be a boolean (`boolean` rule by default). */
|
|
400
|
+
export declare class CheckboxColumn<R = any> extends EditableColumn<R> {
|
|
401
|
+
constructor(name: string);
|
|
402
|
+
static make<R = any>(name: string): CheckboxColumn<R>;
|
|
403
|
+
castState(input: unknown): unknown;
|
|
404
|
+
toHtml(record: R, recordKey?: string | number): Promise<string>;
|
|
405
|
+
}
|
|
406
|
+
/** In-cell editable text input. Only a string or a number is accepted from the browser. */
|
|
407
|
+
export declare class TextInputColumn<R = any> extends EditableColumn<R> {
|
|
408
|
+
private _type;
|
|
409
|
+
private _mask;
|
|
410
|
+
private _inputMode;
|
|
411
|
+
private _step;
|
|
412
|
+
private _placeholder;
|
|
413
|
+
private _prefix;
|
|
414
|
+
private _suffix;
|
|
415
|
+
private _prefixIcon;
|
|
416
|
+
private _suffixIcon;
|
|
417
|
+
private _prefixIconColor;
|
|
418
|
+
private _suffixIconColor;
|
|
419
|
+
private _prefixInline;
|
|
420
|
+
private _suffixInline;
|
|
421
|
+
static make<R = any>(name: string): TextInputColumn<R>;
|
|
422
|
+
/** HTML input type (`text` by default; `number`, `email`, `color`…). */
|
|
423
|
+
type(type: string | null): this;
|
|
424
|
+
/** Alpine input mask (`x-mask`); the input then becomes a text input. */
|
|
425
|
+
mask(mask: string | null): this;
|
|
426
|
+
inputMode(mode: string | null): this;
|
|
427
|
+
step(step: number | string | null): this;
|
|
428
|
+
placeholder(text: string | null): this;
|
|
429
|
+
prefix(label: string | null, isInline?: boolean): this;
|
|
430
|
+
suffix(label: string | null, isInline?: boolean): this;
|
|
431
|
+
inlinePrefix(condition?: boolean): this;
|
|
432
|
+
inlineSuffix(condition?: boolean): this;
|
|
433
|
+
prefixIcon(name: string | null, isInline?: boolean): this;
|
|
434
|
+
suffixIcon(name: string | null, isInline?: boolean): this;
|
|
435
|
+
prefixIconColor(color: string | null): this;
|
|
436
|
+
suffixIconColor(color: string | null): this;
|
|
437
|
+
protected getImplicitRules(): ColumnValidationRule[];
|
|
438
|
+
toHtml(record: R, recordKey?: string | number): Promise<string>;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Custom-rendered column: `view()` takes a function returning the cell HTML, or the name of an EJS view rendered with
|
|
442
|
+
* `{ state, record, column }`. This HTML is the application's own: data inside it must be escaped there (`e()`).
|
|
443
|
+
*/
|
|
444
|
+
export declare class ViewColumn<R = any> extends Column<R> {
|
|
445
|
+
private _view;
|
|
446
|
+
private _viewData;
|
|
447
|
+
static make<R = any>(name: string): ViewColumn<R>;
|
|
448
|
+
view(view: ((ctx: {
|
|
449
|
+
state: unknown;
|
|
450
|
+
record: R;
|
|
451
|
+
column: ViewColumn<R>;
|
|
452
|
+
}) => string | Promise<string>) | string, data?: Record<string, unknown>): this;
|
|
453
|
+
toHtml(record: R): Promise<string>;
|
|
454
|
+
}
|
|
455
|
+
/** @deprecated Use `TextColumn.make(name).badge()`. */
|
|
456
|
+
export declare class BadgeColumn<R = any> extends TextColumn<R> {
|
|
457
|
+
constructor(name: string);
|
|
458
|
+
static make<R = any>(name: string): BadgeColumn<R>;
|
|
459
|
+
}
|
|
460
|
+
/** @deprecated Use `IconColumn.make(name).boolean()`. */
|
|
461
|
+
export declare class BooleanColumn<R = any> extends IconColumn<R> {
|
|
462
|
+
constructor(name: string);
|
|
463
|
+
static make<R = any>(name: string): BooleanColumn<R>;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Writes an editable cell value received from the browser. Everything is checked again: the column must be declared, editable
|
|
467
|
+
* and visible, the record within the adapter's scope and not disabled for this column, `authorize` (the host's edit permission)
|
|
468
|
+
* must accept it, and the value must pass the column's rules.
|
|
469
|
+
*/
|
|
470
|
+
export declare function updateTableColumnState<R>(table: Table<R>, host: TableHost, adapter: DataAdapter<R>, columnName: unknown, recordKey: unknown, input: unknown, options?: {
|
|
471
|
+
authorize?: (record: R) => boolean | Promise<boolean>;
|
|
472
|
+
}): Promise<unknown>;
|
|
473
|
+
/** Filter state: the values of its form. */
|
|
474
|
+
export type FilterState = Record<string, unknown>;
|
|
475
|
+
/** Active filter indicator: its label, and the filter field cleared when it is removed. */
|
|
476
|
+
export type FilterIndicator = {
|
|
477
|
+
label: string;
|
|
478
|
+
field: string;
|
|
479
|
+
};
|
|
480
|
+
/** Filters layout: toolbar dropdown (default), or collapsible panel above the content. */
|
|
481
|
+
export type FiltersLayout = 'dropdown' | 'above-content-collapsible';
|
|
482
|
+
export interface TableFilter {
|
|
483
|
+
readonly name: string;
|
|
484
|
+
getLabel(): string;
|
|
485
|
+
/** Initial state (empty form). */
|
|
486
|
+
getDefaultState(): FilterState;
|
|
487
|
+
/** Options of the `value` field as [value, label] pairs, and the empty option's label. */
|
|
488
|
+
getFormDefinition(): {
|
|
489
|
+
placeholder: string;
|
|
490
|
+
options: [string, string][];
|
|
491
|
+
};
|
|
492
|
+
isActive(state: FilterState): boolean;
|
|
493
|
+
/** Applies the filter to the list query. Only reads known values. */
|
|
494
|
+
apply(query: Omit<ListQuery, 'page' | 'perPage'>, state: FilterState): void;
|
|
495
|
+
/** Form components of the filter, replacing the select described by `getFormDefinition()`. */
|
|
496
|
+
getFormComponents?(): unknown[];
|
|
497
|
+
getColumnSpan?(): Record<string, number | string>;
|
|
498
|
+
/** Applied state derived from the form state (received from the browser): keeps only what the filter knows. */
|
|
499
|
+
sanitizeState?(state: unknown): FilterState;
|
|
500
|
+
getIndicators?(state: FilterState): FilterIndicator[];
|
|
501
|
+
/** Select options loaded on demand (relationship), replacing those of `getFormDefinition()`. */
|
|
502
|
+
getFormOptions?(): Promise<[string, string][]>;
|
|
503
|
+
removeIndicator?(state: FilterState, field: string): FilterState;
|
|
504
|
+
/** Data loaded from the database before indicators are computed (e.g. related record labels). */
|
|
505
|
+
loadIndicatorData?(state: FilterState, host: TableHost): Promise<void>;
|
|
506
|
+
}
|
|
507
|
+
/** "Trashed" filter for soft-deletable models. */
|
|
508
|
+
export declare class TrashedFilter implements TableFilter {
|
|
509
|
+
readonly name = "trashed";
|
|
510
|
+
static make(): TrashedFilter;
|
|
511
|
+
getLabel(): string;
|
|
512
|
+
getDefaultState(): FilterState;
|
|
513
|
+
getFormDefinition(): {
|
|
514
|
+
placeholder: string;
|
|
515
|
+
options: [string, string][];
|
|
516
|
+
};
|
|
517
|
+
isActive(state: FilterState): boolean;
|
|
518
|
+
apply(query: Omit<ListQuery, 'page' | 'perPage'>, state: FilterState): void;
|
|
519
|
+
}
|
|
520
|
+
/** Filters on a column value picked from a list (single select). */
|
|
521
|
+
export declare class SelectFilter implements TableFilter {
|
|
522
|
+
readonly name: string;
|
|
523
|
+
private _label;
|
|
524
|
+
private _column;
|
|
525
|
+
private _options;
|
|
526
|
+
constructor(name: string);
|
|
527
|
+
static make(name: string): SelectFilter;
|
|
528
|
+
label(label: string): this;
|
|
529
|
+
/** Filtered column when it differs from the filter name (e.g. a relationship's foreign key). */
|
|
530
|
+
column(column: string): this;
|
|
531
|
+
/** Fixed options, or an async function (e.g. records of a relationship). */
|
|
532
|
+
options(options: [string, string][] | Record<string, string> | (() => Promise<[string, string][]>)): this;
|
|
533
|
+
getLabel(): string;
|
|
534
|
+
getDefaultState(): FilterState;
|
|
535
|
+
getFormDefinition(): {
|
|
536
|
+
placeholder: string;
|
|
537
|
+
options: [string, string][];
|
|
538
|
+
};
|
|
539
|
+
getFormOptions(): Promise<[string, string][]>;
|
|
540
|
+
/** Options are evaluated on every render, so the select gets a key derived from them (forces a re-render when they change). */
|
|
541
|
+
readonly hasDynamicOptions = true;
|
|
542
|
+
isActive(state: FilterState): boolean;
|
|
543
|
+
apply(query: Omit<ListQuery, 'page' | 'perPage'>, state: FilterState): void;
|
|
544
|
+
}
|
|
545
|
+
/** Three-state filter on a boolean column: all, yes, no. */
|
|
546
|
+
export declare class TernaryFilter implements TableFilter {
|
|
547
|
+
readonly name: string;
|
|
548
|
+
private _label;
|
|
549
|
+
constructor(name: string);
|
|
550
|
+
static make(name: string): TernaryFilter;
|
|
551
|
+
label(label: string): this;
|
|
552
|
+
getLabel(): string;
|
|
553
|
+
getDefaultState(): FilterState;
|
|
554
|
+
getFormDefinition(): {
|
|
555
|
+
placeholder: string;
|
|
556
|
+
options: [string, string][];
|
|
557
|
+
};
|
|
558
|
+
isActive(state: FilterState): boolean;
|
|
559
|
+
apply(query: Omit<ListQuery, 'page' | 'perPage'>, state: FilterState): void;
|
|
560
|
+
}
|
|
561
|
+
/** Custom form filter (`schema()`): the query and indicators are written by the application. */
|
|
562
|
+
export declare class Filter implements TableFilter {
|
|
563
|
+
readonly name: string;
|
|
564
|
+
private _label;
|
|
565
|
+
private _components;
|
|
566
|
+
private _query;
|
|
567
|
+
private _indicate;
|
|
568
|
+
constructor(name: string);
|
|
569
|
+
static make(name: string): Filter;
|
|
570
|
+
label(label: string): this;
|
|
571
|
+
/** Filter fields; their names are the only state keys accepted from the browser. */
|
|
572
|
+
schema(components: unknown[]): this;
|
|
573
|
+
/** Query condition built from the sanitized form state. */
|
|
574
|
+
query(modifier: (query: any, data: FilterState) => void): this;
|
|
575
|
+
/** Indicators of applied values as `{ field: label }`; removing one clears its field. */
|
|
576
|
+
indicateUsing(resolver: (data: FilterState) => Record<string, string>): this;
|
|
577
|
+
private fields;
|
|
578
|
+
getLabel(): string;
|
|
579
|
+
getDefaultState(): FilterState;
|
|
580
|
+
getFormDefinition(): {
|
|
581
|
+
placeholder: string;
|
|
582
|
+
options: [string, string][];
|
|
583
|
+
};
|
|
584
|
+
getFormComponents(): unknown[];
|
|
585
|
+
sanitizeState(state: unknown): FilterState;
|
|
586
|
+
isActive(state: FilterState): boolean;
|
|
587
|
+
apply(query: Omit<ListQuery, 'page' | 'perPage'>, state: FilterState): void;
|
|
588
|
+
getIndicators(state: FilterState): FilterIndicator[];
|
|
589
|
+
removeIndicator(state: FilterState, field: string): FilterState;
|
|
590
|
+
}
|
|
591
|
+
export type ColumnState = {
|
|
592
|
+
type: 'column';
|
|
593
|
+
name: string;
|
|
594
|
+
label: string;
|
|
595
|
+
isHidden: boolean;
|
|
596
|
+
isToggled: boolean;
|
|
597
|
+
isToggleable: boolean;
|
|
598
|
+
isToggledHiddenByDefault: boolean | null;
|
|
599
|
+
};
|
|
600
|
+
export declare class Table<R = any> {
|
|
601
|
+
private _columns;
|
|
602
|
+
private _recordAction;
|
|
603
|
+
private _recordActions;
|
|
604
|
+
private _heading;
|
|
605
|
+
private _headerActions;
|
|
606
|
+
private _bulkActions;
|
|
607
|
+
private _recordClasses;
|
|
608
|
+
private _filters;
|
|
609
|
+
private _filtersLayout;
|
|
610
|
+
private _defaultSort;
|
|
611
|
+
private _recordUrl;
|
|
612
|
+
private _pageOptions;
|
|
613
|
+
private _stackedOnMobile;
|
|
614
|
+
private _label;
|
|
615
|
+
private _groups;
|
|
616
|
+
private _defaultGroup;
|
|
617
|
+
private _defaultGroupDirection;
|
|
618
|
+
private _groupsOnly;
|
|
619
|
+
private _groupingSettingsHidden;
|
|
620
|
+
private _groupingDirectionSettingHidden;
|
|
621
|
+
private _groupingSettingsInDropdownOnDesktop;
|
|
622
|
+
private _collapsedGroupsByDefault;
|
|
623
|
+
/** Groupings offered in the toolbar (a column id is shorthand for `Group.make(id)`). */
|
|
624
|
+
groups(groups: (Group<R> | string)[]): this;
|
|
625
|
+
getGroups(): Group<R>[];
|
|
626
|
+
getGroup(id: string | null | undefined): Group<R> | null;
|
|
627
|
+
/**
|
|
628
|
+
* Default grouping. If it is one of `groups()`, it is only preselected when the table opens (`initializeTableGrouping`)
|
|
629
|
+
* and the user can remove it; otherwise it always applies, without a selector.
|
|
630
|
+
*/
|
|
631
|
+
defaultGroup(group: Group<R> | string | null, direction?: SortDirection): this;
|
|
632
|
+
getDefaultGroup(): Group<R> | null;
|
|
633
|
+
getDefaultGroupDirection(): SortDirection;
|
|
634
|
+
isDefaultGroupSelectable(): boolean;
|
|
635
|
+
/** Shows only group headers and summaries, without rows or pagination. */
|
|
636
|
+
groupsOnly(condition?: boolean): this;
|
|
637
|
+
isGroupsOnly(): boolean;
|
|
638
|
+
/** Hides the toolbar grouping selector. */
|
|
639
|
+
groupingSettingsHidden(condition?: boolean): this;
|
|
640
|
+
areGroupingSettingsHidden(): boolean;
|
|
641
|
+
/** Hides the grouping direction (ascending / descending) choice. */
|
|
642
|
+
groupingDirectionSettingHidden(condition?: boolean): this;
|
|
643
|
+
isGroupingDirectionSettingHidden(): boolean;
|
|
644
|
+
/** Puts the grouping selector in a dropdown on desktop too. */
|
|
645
|
+
groupingSettingsInDropdownOnDesktop(condition?: boolean): this;
|
|
646
|
+
/** @deprecated Use `groupingSettingsInDropdownOnDesktop()`. */
|
|
647
|
+
groupsInDropdownOnDesktop(condition?: boolean): this;
|
|
648
|
+
areGroupingSettingsInDropdownOnDesktop(): boolean;
|
|
649
|
+
/** Collapsible groups start collapsed. */
|
|
650
|
+
collapsedGroupsByDefault(condition?: boolean): this;
|
|
651
|
+
areGroupsCollapsedByDefault(): boolean;
|
|
652
|
+
private _columnsLayout;
|
|
653
|
+
columns(columns: (Column<R> | ColumnGroup<R> | ColumnLayout<R>)[]): this;
|
|
654
|
+
/** Column layout, or `null` for a regular table. */
|
|
655
|
+
getColumnsLayout(): (Column<R> | ColumnLayout<R>)[] | null;
|
|
656
|
+
/** Action mounted when a row is clicked (e.g. `'edit'`), instead of a URL. */
|
|
657
|
+
recordAction(name: string | null): this;
|
|
658
|
+
getRecordAction(): string | null;
|
|
659
|
+
/** Heading shown in the table header. */
|
|
660
|
+
heading(heading: string | null): this;
|
|
661
|
+
getHeading(): string | null;
|
|
662
|
+
/** Actions shown in the table header. */
|
|
663
|
+
headerActions(actions: any[]): this;
|
|
664
|
+
getHeaderActions(): any[];
|
|
665
|
+
/** Bulk actions ("Bulk actions" menu); if never called, the host provides its default ones. */
|
|
666
|
+
groupedBulkActions(actions: any[]): this;
|
|
667
|
+
getBulkActions(): any[] | null;
|
|
668
|
+
/** Row actions: `Action`s or an `ActionGroup` (dropdown). */
|
|
669
|
+
recordActions(actions: any[]): this;
|
|
670
|
+
getRecordActions(): any[];
|
|
671
|
+
/** CSS classes added to a row depending on its record. */
|
|
672
|
+
recordClasses(resolver: (record: R) => string | null): this;
|
|
673
|
+
getRecordClasses(record: R): string | null;
|
|
674
|
+
filters(filters: TableFilter[], options?: {
|
|
675
|
+
layout?: FiltersLayout;
|
|
676
|
+
}): this;
|
|
677
|
+
filtersLayout(layout: FiltersLayout): this;
|
|
678
|
+
getFiltersLayout(): FiltersLayout;
|
|
679
|
+
/** No-op kept for API compatibility: filters always wait for the "Apply" button. */
|
|
680
|
+
deferFilters(): this;
|
|
681
|
+
defaultSort(column: string, direction?: SortDirection): this;
|
|
682
|
+
recordUrl(resolver: (record: R) => string | null): this;
|
|
683
|
+
private _reorderColumn;
|
|
684
|
+
/** Lets users reorder rows by hand; `column` stores the position. */
|
|
685
|
+
reorderable(column: string | null): this;
|
|
686
|
+
getReorderColumn(): string | null;
|
|
687
|
+
paginationPageOptions(options: number[]): this;
|
|
688
|
+
private _defaultPageOption;
|
|
689
|
+
/** Rows per page when the table opens. */
|
|
690
|
+
defaultPaginationPageOption(option: number | null): this;
|
|
691
|
+
getDefaultPageOption(): number;
|
|
692
|
+
private _paginationMode;
|
|
693
|
+
/** `'simple'`: previous / next buttons only, without page numbers or total. */
|
|
694
|
+
paginationMode(mode: 'default' | 'simple'): this;
|
|
695
|
+
getPaginationMode(): 'default' | 'simple';
|
|
696
|
+
stackedOnMobile(condition?: boolean): this;
|
|
697
|
+
pluralModelLabel(label: string): this;
|
|
698
|
+
getColumns(): Column<R>[];
|
|
699
|
+
getColumn(name: string): Column<R> | undefined;
|
|
700
|
+
getFilters(): TableFilter[];
|
|
701
|
+
getDefaultSort(): {
|
|
702
|
+
column: string;
|
|
703
|
+
direction: SortDirection;
|
|
704
|
+
} | null;
|
|
705
|
+
getRecordUrl(record: R): string | null;
|
|
706
|
+
getPageOptions(): number[];
|
|
707
|
+
isStackedOnMobile(): boolean;
|
|
708
|
+
getPluralModelLabel(): string;
|
|
709
|
+
hasToggleableColumns(): boolean;
|
|
710
|
+
/** Default column manager state. */
|
|
711
|
+
getDefaultColumnState(): ColumnState[];
|
|
712
|
+
getDefaultFilterState(): Record<string, FilterState>;
|
|
713
|
+
}
|
|
714
|
+
/** Table state held by the host component. */
|
|
715
|
+
export interface TableHost {
|
|
716
|
+
readonly id: string;
|
|
717
|
+
tableSearch: string;
|
|
718
|
+
tableSort: string | null;
|
|
719
|
+
tableColumnSearches: Record<string, string>;
|
|
720
|
+
tableRecordsPerPage: number;
|
|
721
|
+
paginators: Record<string, number>;
|
|
722
|
+
tableFilters?: Record<string, FilterState>;
|
|
723
|
+
tableColumns?: ColumnState[];
|
|
724
|
+
/** Current grouping: `id` or `id:direction`. */
|
|
725
|
+
tableGrouping?: string | null;
|
|
726
|
+
/** Reordering mode: all rows, in position order, with drag handles. */
|
|
727
|
+
isTableReordering?: boolean;
|
|
728
|
+
}
|
|
729
|
+
/** Visible columns: those left checked in the column manager. Browser state can only hide columns declared toggleable. */
|
|
730
|
+
export declare function getVisibleColumns<R>(table: Table<R>, host: TableHost): Column<R>[];
|
|
731
|
+
/** Sanitizes column state from the browser: only `isToggled` of toggleable columns is kept. */
|
|
732
|
+
export declare function sanitizeColumnState<R>(table: Table<R>, state: unknown): ColumnState[];
|
|
733
|
+
/**
|
|
734
|
+
* List query (search, column searches, filters, sort) for the host's state, without pagination.
|
|
735
|
+
* Only what the table declares is accepted, whatever state the browser sends.
|
|
736
|
+
*/
|
|
737
|
+
export declare function getTableQuery<R>(table: Table<R>, host: TableHost): Omit<ListQuery, 'page' | 'perPage'>;
|
|
738
|
+
/** Current grouping: only a group declared by the table is accepted, whatever state the browser sends. */
|
|
739
|
+
export declare function getTableGrouping<R>(table: Table<R>, host: TableHost): {
|
|
740
|
+
group: Group<R>;
|
|
741
|
+
direction: SortDirection;
|
|
742
|
+
} | null;
|
|
743
|
+
/** When the table opens (host mount): preselects the default grouping when the user can change it. */
|
|
744
|
+
export declare function initializeTableGrouping<R>(table: Table<R>, host: TableHost): void;
|
|
745
|
+
export declare function countActiveFilters<R>(table: Table<R>, host: TableHost): number;
|
|
746
|
+
/** Indicators of the applied filters (only filters that declare some have them). */
|
|
747
|
+
export declare function getFilterIndicators<R>(table: Table<R>, host: TableHost): {
|
|
748
|
+
filter: string;
|
|
749
|
+
field: string;
|
|
750
|
+
label: string;
|
|
751
|
+
}[];
|
|
752
|
+
/** Cycles a column's sort: none → asc → desc → none. */
|
|
753
|
+
export declare function sortTable(host: TableHost, column?: string | null, direction?: string | null): void;
|
|
754
|
+
/** Loads the page of records matching the host's state. */
|
|
755
|
+
export declare function getTableRecords<R>(table: Table<R>, host: TableHost, adapter: DataAdapter<R>): Promise<RecordPage<R>>;
|
|
756
|
+
/** Pagination elements: the first and last pages and a window around the current page, with `...` gaps. */
|
|
757
|
+
export declare function paginationElements(current: number, last: number, onEachSide?: number): (number | '...')[];
|
|
758
|
+
export declare const useColorManager: (manager: ColorManager) => void;
|
|
759
|
+
export type RenderTableOptions<R> = {
|
|
760
|
+
rowActions?: (record: R) => {
|
|
761
|
+
label: string;
|
|
762
|
+
url: string;
|
|
763
|
+
icon: string;
|
|
764
|
+
key: string;
|
|
765
|
+
}[] | Promise<{
|
|
766
|
+
label: string;
|
|
767
|
+
url: string;
|
|
768
|
+
icon: string;
|
|
769
|
+
key: string;
|
|
770
|
+
}[]>;
|
|
771
|
+
/** `false`: reordering is not offered (user not authorized). */
|
|
772
|
+
canReorder?: boolean;
|
|
773
|
+
/** HTML placed in `.fi-ta`, after the table container (action modals). */
|
|
774
|
+
after?: string;
|
|
775
|
+
/** Already rendered HTML of the table header actions. */
|
|
776
|
+
headerActions?: string[];
|
|
777
|
+
/** Already rendered HTML of the row actions (ActionGroup…), replacing the `rowActions` links. */
|
|
778
|
+
rowActionsHtml?: (record: R) => Promise<string>;
|
|
779
|
+
bulkActions?: string[];
|
|
780
|
+
/** HTML of the filters form (`tableFiltersForm` schema), if there are filters. */
|
|
781
|
+
filtersForm?: string | null;
|
|
782
|
+
};
|
|
783
|
+
/** Maximum number of rows shown (and reorderable) in reordering mode. */
|
|
784
|
+
export declare const REORDER_LIMIT = 1000;
|
|
785
|
+
/** Maximum records read for a `groupsOnly` table (which is not paginated). */
|
|
786
|
+
export declare const GROUPS_ONLY_LIMIT = 1000;
|
|
787
|
+
export declare function renderTable<R>(table: Table<R>, host: TableHost, adapter: DataAdapter<R>, options?: RenderTableOptions<R>): Promise<string>;
|