@navette-js/tables 1.0.0-beta.3 → 1.0.0-beta.5
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/lib/index.d.ts +761 -85
- package/lib/index.js +1377 -236
- package/lib/query-builder.d.ts +92 -2
- package/lib/query-builder.js +164 -23
- package/package.json +6 -6
- package/views/filters.ejs +44 -0
- package/views/index.ejs +129 -106
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DataAdapter, ListQuery, Page as RecordPage, SortDirection } from '@navette-js/database';
|
|
2
2
|
import { Attributes, type ColorManager } from '@navette-js/support';
|
|
3
|
+
import { type RelationshipQueryModifier } from './query-builder.ts';
|
|
3
4
|
export * from './query-builder.ts';
|
|
4
5
|
/** Render hook slots of a table. */
|
|
5
6
|
export declare const TablesRenderHook: {
|
|
@@ -27,7 +28,6 @@ export declare const TablesRenderHook: {
|
|
|
27
28
|
readonly TOOLBAR_TOGGLE_COLUMN_TRIGGER_AFTER: "tables::toolbar.toggle-column-trigger.after";
|
|
28
29
|
readonly TOOLBAR_TOGGLE_COLUMN_TRIGGER_BEFORE: "tables::toolbar.toggle-column-trigger.before";
|
|
29
30
|
};
|
|
30
|
-
/** Methods and properties that trigger the table's loading state (`wire:target`). */
|
|
31
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
32
|
type StateResolver<R> = (ctx: {
|
|
33
33
|
record: R;
|
|
@@ -63,6 +63,20 @@ export declare abstract class Column<R = any> {
|
|
|
63
63
|
isSortInverted(): boolean;
|
|
64
64
|
/** Link on the cell; takes precedence over the row action. */
|
|
65
65
|
url(resolver: (record: R) => string | null): this;
|
|
66
|
+
protected _cellAction: string | {
|
|
67
|
+
getName(): string;
|
|
68
|
+
} | null;
|
|
69
|
+
/**
|
|
70
|
+
* Clicking the cell runs an action on its record: the name of a record action of the table, or an `Action` (checked and
|
|
71
|
+
* authorized like record actions when it is mounted). A column `url()` takes precedence; the action takes precedence over the row's link and action.
|
|
72
|
+
*/
|
|
73
|
+
action(action: string | {
|
|
74
|
+
getName(): string;
|
|
75
|
+
} | null): this;
|
|
76
|
+
getAction(): {
|
|
77
|
+
getName(): string;
|
|
78
|
+
} | null;
|
|
79
|
+
getActionName(): string | null;
|
|
66
80
|
getUrl(record: R): string | null;
|
|
67
81
|
/** `isGlobal: false` excludes the column from the global search; `isIndividual` adds a search field for this column. */
|
|
68
82
|
getSearchColumn(): string;
|
|
@@ -76,10 +90,42 @@ export declare abstract class Column<R = any> {
|
|
|
76
90
|
isToggledHiddenByDefault?: boolean;
|
|
77
91
|
}): this;
|
|
78
92
|
alignment(alignment: 'start' | 'center' | 'end' | null): this;
|
|
93
|
+
protected _visibleFrom: string | null;
|
|
94
|
+
protected _hiddenFrom: string | null;
|
|
95
|
+
protected _columnWidth: string | null;
|
|
96
|
+
protected _grow: boolean | null;
|
|
97
|
+
protected _wrapHeader: boolean;
|
|
98
|
+
/** Shows the column only from this screen size up (`sm`, `md`, `lg`, `xl`, `2xl`). */
|
|
99
|
+
visibleFrom(breakpoint: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | null): this;
|
|
100
|
+
/** Hides the column from this screen size up. */
|
|
101
|
+
hiddenFrom(breakpoint: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | null): this;
|
|
102
|
+
/** Classes hiding the header and cells on some screen sizes. */
|
|
103
|
+
getResponsiveClasses(): string[];
|
|
104
|
+
/** Width of the column, as a CSS length (`200px`, `20%`...). */
|
|
105
|
+
width(width: string | number | null): this;
|
|
106
|
+
getWidth(): string | null;
|
|
107
|
+
/** The column takes the remaining width of the table (when it has no `width()`). */
|
|
108
|
+
grow(condition?: boolean): this;
|
|
109
|
+
/** In a table, columns do not grow unless told to; in a layout (split), they do. */
|
|
110
|
+
canGrow(defaultValue?: boolean): boolean;
|
|
111
|
+
/** Lets a long label wrap in the header. */
|
|
112
|
+
wrapHeader(condition?: boolean): this;
|
|
113
|
+
canHeaderWrap(): boolean;
|
|
79
114
|
alignEnd(): this;
|
|
80
115
|
alignLeft(): this;
|
|
81
116
|
alignCenter(): this;
|
|
82
117
|
getStateUsing(resolver: StateResolver<R>): this;
|
|
118
|
+
/** Fixed state, or a function of the record (alias of `getStateUsing()` for a value). */
|
|
119
|
+
state(state: unknown | ((record: R) => unknown)): this;
|
|
120
|
+
protected _default: unknown;
|
|
121
|
+
/** Value used when the state is empty. */
|
|
122
|
+
default(value: unknown): this;
|
|
123
|
+
protected _hidden: boolean | (() => boolean);
|
|
124
|
+
protected _visible: boolean | (() => boolean);
|
|
125
|
+
/** Removes the column from the table (header, cells, search, sort and column manager). */
|
|
126
|
+
hidden(condition?: boolean | (() => boolean)): this;
|
|
127
|
+
visible(condition?: boolean | (() => boolean)): this;
|
|
128
|
+
isHidden(): boolean;
|
|
83
129
|
getLabel(): string;
|
|
84
130
|
isSortable(): boolean;
|
|
85
131
|
isGloballySearchable(): boolean;
|
|
@@ -94,53 +140,136 @@ export declare abstract class Column<R = any> {
|
|
|
94
140
|
isClickDisabled(): boolean;
|
|
95
141
|
abstract toHtml(record: R, recordKey?: string | number): Promise<string>;
|
|
96
142
|
}
|
|
143
|
+
/** Value of an option that may depend on the record and the state item. */
|
|
144
|
+
type PerItem<R, T> = T | ((record: R, state: unknown) => T);
|
|
145
|
+
/** Date in a PHP-style format (`M j, Y`, `d/m/Y H:i`…), in UTC or in the given IANA time zone. Database values without a zone are read as UTC. */
|
|
146
|
+
export declare function formatDate(value: unknown, format: string, timeZone?: string | null): string;
|
|
97
147
|
export declare class TextColumn<R = any> extends Column<R> {
|
|
98
148
|
private _weight;
|
|
99
149
|
private _copyable;
|
|
150
|
+
private _copyableState;
|
|
151
|
+
private _copyMessage;
|
|
152
|
+
private _copyMessageDuration;
|
|
100
153
|
private _money;
|
|
101
154
|
private _placeholder;
|
|
102
155
|
private _badge;
|
|
103
156
|
private _color;
|
|
104
157
|
private _icon;
|
|
158
|
+
private _iconColor;
|
|
159
|
+
private _iconPosition;
|
|
105
160
|
private _format;
|
|
106
161
|
private _date;
|
|
162
|
+
private _timeZone;
|
|
163
|
+
private _since;
|
|
107
164
|
private _numeric;
|
|
165
|
+
private _decimals;
|
|
108
166
|
private _summarizers;
|
|
109
167
|
private _limit;
|
|
168
|
+
private _words;
|
|
169
|
+
private _prefix;
|
|
170
|
+
private _suffix;
|
|
110
171
|
private _tooltip;
|
|
172
|
+
private _size;
|
|
173
|
+
private _fontFamily;
|
|
174
|
+
private _wrap;
|
|
175
|
+
private _lineClamp;
|
|
176
|
+
private _inline;
|
|
177
|
+
private _descriptionAbove;
|
|
178
|
+
private _descriptionBelow;
|
|
179
|
+
private _listWithLineBreaks;
|
|
180
|
+
private _bulleted;
|
|
181
|
+
private _listLimit;
|
|
182
|
+
private _expandableLimitedList;
|
|
183
|
+
private _separator;
|
|
111
184
|
static make<R = any>(name: string): TextColumn<R>;
|
|
112
185
|
/** Displays the value in a badge. */
|
|
113
186
|
badge(condition?: boolean): this;
|
|
114
|
-
color(color:
|
|
115
|
-
|
|
187
|
+
/** Text color (or badge color): a color name, or a function of the record and the state item. */
|
|
188
|
+
color(color: PerItem<R, string | null>): this;
|
|
189
|
+
/** Icon next to the text: a name, or a function of the record and the state item returning a name or `null`. */
|
|
190
|
+
icon(icon: PerItem<R, string | null> | null): this;
|
|
191
|
+
iconColor(color: PerItem<R, string | null>): this;
|
|
192
|
+
iconPosition(position: 'before' | 'after'): this;
|
|
116
193
|
/** Text displayed instead of the raw value (e.g. an enum label). */
|
|
117
194
|
formatStateUsing(formatter: (ctx: {
|
|
118
195
|
state: unknown;
|
|
119
196
|
record: R;
|
|
120
197
|
}) => string): this;
|
|
121
|
-
/**
|
|
122
|
-
date(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
198
|
+
/** Date in a PHP-style format, `M j, Y` by default ("Nov 9, 2026"). `timeZone`: IANA zone to display the date in. */
|
|
199
|
+
date(format?: string | boolean, timeZone?: string | null): this;
|
|
200
|
+
/** Date and time, `M j, Y H:i:s` by default. */
|
|
201
|
+
dateTime(format?: string | boolean, timeZone?: string | null): this;
|
|
202
|
+
/** Time only, `H:i:s` by default. */
|
|
203
|
+
time(format?: string, timeZone?: string | null): this;
|
|
204
|
+
/** Relative date, e.g. "2 days ago". */
|
|
205
|
+
since(condition?: boolean): this;
|
|
206
|
+
/** Time zone used by `date()`, `dateTime()` and `time()`. */
|
|
207
|
+
timezone(timeZone: string | null): this;
|
|
208
|
+
/** Number formatted with thousands separators; `numeric(1)`: fixed number of decimals. */
|
|
129
209
|
numeric(condition?: boolean | number): this;
|
|
130
210
|
/** Summary row below the table. */
|
|
131
211
|
summarize(summarizer: Summarizer | Summarizer[]): this;
|
|
132
212
|
getSummarizers(): Summarizer[];
|
|
133
|
-
weight
|
|
213
|
+
/** Font weight: `thin`, `light`, `medium`, `semibold`, `bold`… */
|
|
214
|
+
weight(weight: PerItem<R, string | null>): this;
|
|
215
|
+
/** Text size: `xs`, `sm` (default), `md` or `lg`. */
|
|
216
|
+
size(size: PerItem<R, string | null>): this;
|
|
217
|
+
/** Font family: `sans`, `serif` or `mono`. */
|
|
218
|
+
fontFamily(family: PerItem<R, string | null>): this;
|
|
219
|
+
/** Lets long text wrap onto several lines instead of overflowing. */
|
|
220
|
+
wrap(condition?: boolean): this;
|
|
221
|
+
/** Clamps the text to this number of lines. */
|
|
222
|
+
lineClamp(lines: number | null): this;
|
|
223
|
+
/** Renders inline (without a block layout), e.g. inside a stacked layout. */
|
|
224
|
+
inline(condition?: boolean): this;
|
|
134
225
|
/** Truncates the displayed text to `length` characters, followed by "...". */
|
|
135
226
|
limit(length: number | null): this;
|
|
227
|
+
/** Truncates the displayed text to this number of words, followed by "...". */
|
|
228
|
+
words(count: number | null): this;
|
|
229
|
+
prefix(prefix: string | null): this;
|
|
230
|
+
suffix(suffix: string | null): this;
|
|
136
231
|
/** Tooltip on hover; `null` for none. */
|
|
137
|
-
tooltip(tooltip:
|
|
138
|
-
copyable(condition?: boolean): this;
|
|
232
|
+
tooltip(tooltip: PerItem<R, string | null>): this;
|
|
233
|
+
copyable(condition?: PerItem<R, boolean>): this;
|
|
234
|
+
/** Value copied to the clipboard, when it differs from the displayed text. */
|
|
235
|
+
copyableState(state: PerItem<R, string | null>): this;
|
|
236
|
+
copyMessage(message: string | null): this;
|
|
237
|
+
copyMessageDuration(milliseconds: number): this;
|
|
139
238
|
/** Amount formatted in the given currency, e.g. `money('usd')`. */
|
|
140
239
|
money(currency?: string | ((record: R) => string)): this;
|
|
141
240
|
/** Text displayed when the value is empty. */
|
|
142
241
|
placeholder(text: string | null): this;
|
|
143
|
-
/**
|
|
242
|
+
/** Secondary text below the value (`'below'`, the default) or above it. */
|
|
243
|
+
description(text: ((record: R) => string | null) | string | null, position?: 'above' | 'below'): this;
|
|
244
|
+
/** One value per line, for a state that is a list (or a string split by `separator()`). */
|
|
245
|
+
listWithLineBreaks(condition?: boolean): this;
|
|
246
|
+
/** Bulleted list. */
|
|
247
|
+
bulleted(condition?: boolean): this;
|
|
248
|
+
/** Shows only the first values of a list; `expandable`: a link reveals the others. */
|
|
249
|
+
limitList(count: number | null, expandable?: boolean): this;
|
|
250
|
+
expandableLimitedList(condition?: boolean): this;
|
|
251
|
+
/** Splits a string state into a list on this separator. */
|
|
252
|
+
separator(separator?: string | null): this;
|
|
253
|
+
private _html;
|
|
254
|
+
private _markdown;
|
|
255
|
+
/**
|
|
256
|
+
* Renders the state as HTML. It is sanitized first: only formatting elements (paragraphs, emphasis, lists, links with safe
|
|
257
|
+
* URLs...) are kept, without any attribute that could run scripts or change the page's styles.
|
|
258
|
+
*/
|
|
259
|
+
html(condition?: PerItem<R, boolean>): this;
|
|
260
|
+
/** Renders the state as Markdown. Raw HTML in it is shown as text, and links only keep safe URLs. */
|
|
261
|
+
markdown(condition?: PerItem<R, boolean>): this;
|
|
262
|
+
/** Item text as HTML: Markdown, sanitized HTML, or escaped text. */
|
|
263
|
+
private renderItemText;
|
|
264
|
+
/** Displayed text of one state item, escaped by the caller. */
|
|
265
|
+
private formatItem;
|
|
266
|
+
private stateItems;
|
|
267
|
+
private hasDescriptions;
|
|
268
|
+
/** Plain value without per-item options: Filament's short markup. */
|
|
269
|
+
private canRenderOptimized;
|
|
270
|
+
private alignClass;
|
|
271
|
+
private containerClasses;
|
|
272
|
+
/** Cell content, as Filament renders it: a short markup for a plain value, the full markup as soon as an item option is set. */
|
|
144
273
|
toHtml(record: R): Promise<string>;
|
|
145
274
|
}
|
|
146
275
|
/** Values a summarizer works from: aggregates over the query (all records) or over the displayed page. */
|
|
@@ -152,41 +281,94 @@ export type SummaryValues = {
|
|
|
152
281
|
max: Record<string, unknown>;
|
|
153
282
|
};
|
|
154
283
|
export type SummaryItem = {
|
|
155
|
-
type: 'text' | 'range';
|
|
284
|
+
type: 'text' | 'range' | 'values';
|
|
156
285
|
label: string | null;
|
|
157
286
|
value: string;
|
|
287
|
+
labelHidden?: boolean;
|
|
288
|
+
values?: string[];
|
|
289
|
+
bulleted?: boolean;
|
|
290
|
+
};
|
|
291
|
+
/** Records a custom summarizer works on: all records, the displayed page, or a group. */
|
|
292
|
+
export type SummaryDataset = {
|
|
293
|
+
column: string;
|
|
294
|
+
records: () => Promise<any[]>;
|
|
158
295
|
};
|
|
159
|
-
/**
|
|
160
|
-
|
|
161
|
-
|
|
296
|
+
/**
|
|
297
|
+
* Column summary below the table: sum, average, count, range, distinct values, or your own with `Summarizer.make().using()`.
|
|
298
|
+
*/
|
|
299
|
+
export declare class Summarizer {
|
|
300
|
+
readonly kind: 'sum' | 'avg' | 'count' | 'range' | 'values' | 'custom';
|
|
162
301
|
protected _label: string | null;
|
|
163
302
|
protected _money: string | null;
|
|
303
|
+
protected _decimals: number | null;
|
|
304
|
+
protected _prefix: string | null;
|
|
305
|
+
protected _suffix: string | null;
|
|
306
|
+
protected _formatStateUsing: ((state: unknown) => string | null) | null;
|
|
307
|
+
protected _labelHidden: boolean;
|
|
308
|
+
protected _hidden: boolean | (() => boolean);
|
|
309
|
+
protected _using: ((dataset: SummaryDataset) => unknown) | null;
|
|
310
|
+
protected _scope: ((query: any) => void) | null;
|
|
311
|
+
/**
|
|
312
|
+
* Restricts the records summarized by this summarizer (all records, the page, or a group), e.g.
|
|
313
|
+
* `Count.make().query((query) => query.where('is_published', 1))`. The function receives the data adapter's query builder.
|
|
314
|
+
*/
|
|
315
|
+
query(scope: ((query: any) => void) | null): this;
|
|
316
|
+
getQueryScope(): ((query: any) => void) | null;
|
|
317
|
+
static make(): Summarizer;
|
|
164
318
|
label(label: string | null): this;
|
|
165
319
|
money(currency?: string): this;
|
|
320
|
+
/** Number formatting, with a fixed number of decimals. */
|
|
321
|
+
numeric(decimals?: number | null): this;
|
|
322
|
+
prefix(prefix: string | null): this;
|
|
323
|
+
suffix(suffix: string | null): this;
|
|
324
|
+
/** Formats the value yourself (the result is escaped). */
|
|
325
|
+
formatStateUsing(callback: ((state: unknown) => string | null) | null): this;
|
|
326
|
+
/** Keeps the label for screen readers only. */
|
|
327
|
+
hiddenLabel(condition?: boolean): this;
|
|
328
|
+
isLabelHidden(): boolean;
|
|
329
|
+
hidden(condition?: boolean | (() => boolean)): this;
|
|
330
|
+
visible(condition?: boolean | (() => boolean)): this;
|
|
331
|
+
isHidden(): boolean;
|
|
332
|
+
/** Computes the value from the summarized records (`records()` loads them: keep the dataset small). */
|
|
333
|
+
using(callback: ((dataset: SummaryDataset) => unknown) | null): this;
|
|
334
|
+
hasCustomCalculation(): boolean;
|
|
335
|
+
compute(dataset: SummaryDataset): Promise<unknown>;
|
|
166
336
|
getLabel(): string | null;
|
|
167
|
-
|
|
168
|
-
|
|
337
|
+
/** Formatted value: `formatStateUsing()`, money or number, then the prefix and suffix. */
|
|
338
|
+
format(value: unknown): string;
|
|
339
|
+
protected item(value: unknown, type?: SummaryItem['type']): SummaryItem;
|
|
340
|
+
/** Summary item from the aggregates (or from `customValue`, computed by `using()`). */
|
|
341
|
+
summarize(_column: string, _values: SummaryValues, customValue?: unknown): SummaryItem | null;
|
|
169
342
|
}
|
|
170
343
|
/** Column total. */
|
|
171
344
|
export declare class Sum extends Summarizer {
|
|
172
345
|
readonly kind = "sum";
|
|
173
346
|
static make(): Sum;
|
|
174
347
|
getLabel(): string;
|
|
175
|
-
summarize(column: string, values: SummaryValues): SummaryItem;
|
|
348
|
+
summarize(column: string, values: SummaryValues, customValue?: unknown): SummaryItem;
|
|
176
349
|
}
|
|
177
350
|
/** Column average. */
|
|
178
351
|
export declare class Average extends Summarizer {
|
|
179
352
|
readonly kind = "avg";
|
|
180
353
|
static make(): Average;
|
|
181
354
|
getLabel(): string;
|
|
182
|
-
summarize(column: string, values: SummaryValues): SummaryItem;
|
|
355
|
+
summarize(column: string, values: SummaryValues, customValue?: unknown): SummaryItem;
|
|
183
356
|
}
|
|
184
357
|
/** Record count. */
|
|
185
358
|
export declare class Count extends Summarizer {
|
|
186
359
|
readonly kind = "count";
|
|
187
360
|
static make(): Count;
|
|
188
361
|
getLabel(): string;
|
|
189
|
-
summarize(_column: string, values: SummaryValues): SummaryItem;
|
|
362
|
+
summarize(_column: string, values: SummaryValues, customValue?: unknown): SummaryItem;
|
|
363
|
+
}
|
|
364
|
+
/** Distinct values of the column, as a (bulleted) list. */
|
|
365
|
+
export declare class Values extends Summarizer {
|
|
366
|
+
readonly kind = "values";
|
|
367
|
+
private _bulleted;
|
|
368
|
+
static make(): Values;
|
|
369
|
+
bulleted(condition?: boolean): this;
|
|
370
|
+
constructor();
|
|
371
|
+
summarize(_column: string, _values: SummaryValues, customValue?: unknown): SummaryItem;
|
|
190
372
|
}
|
|
191
373
|
/** Smallest and largest value of a column. */
|
|
192
374
|
export declare class Range extends Summarizer {
|
|
@@ -195,7 +377,7 @@ export declare class Range extends Summarizer {
|
|
|
195
377
|
static make(): Range;
|
|
196
378
|
/** Dates: day only when the bounds fall on different days, day and time otherwise; a single value when both are equal. */
|
|
197
379
|
minimalDateTimeDifference(condition?: boolean): this;
|
|
198
|
-
summarize(column: string, values: SummaryValues): SummaryItem | null;
|
|
380
|
+
summarize(column: string, values: SummaryValues, _customValue?: unknown): SummaryItem | null;
|
|
199
381
|
}
|
|
200
382
|
/** Row grouping: rows are sorted by the column and each group gets a header row. */
|
|
201
383
|
export declare class Group<R = any> {
|
|
@@ -207,7 +389,17 @@ export declare class Group<R = any> {
|
|
|
207
389
|
private _collapsible;
|
|
208
390
|
private _date;
|
|
209
391
|
private _titlePrefixedWithLabel;
|
|
392
|
+
private _keyUsing;
|
|
393
|
+
private _scopeUsing;
|
|
394
|
+
private _orderUsing;
|
|
210
395
|
constructor(id: string);
|
|
396
|
+
/** Group key of a record, when it is not the column value (records with the same key form a group). Use with `scopeQueryByKeyUsing()`. */
|
|
397
|
+
getKeyFromRecordUsing(resolver: ((record: R) => string | null) | null): this;
|
|
398
|
+
/** Restricts the query to one group (summaries, "select the group"): needed when `getKeyFromRecordUsing()` is not the column value. */
|
|
399
|
+
scopeQueryByKeyUsing(scope: ((query: any, key: string | null) => void) | null): this;
|
|
400
|
+
/** Orders the query by group, when ordering by the column is not right (e.g. a status with a custom order). */
|
|
401
|
+
orderQueryUsing(order: ((query: any, direction: SortDirection) => void) | null): this;
|
|
402
|
+
getOrderQueryUsing(): ((query: any, direction: SortDirection) => void) | null;
|
|
211
403
|
static make<R = any>(id: string): Group<R>;
|
|
212
404
|
label(label: string | null): this;
|
|
213
405
|
/** Query column holding the group value, when it differs from the id (relationship). */
|
|
@@ -242,11 +434,41 @@ export declare class Group<R = any> {
|
|
|
242
434
|
*/
|
|
243
435
|
export declare abstract class ColumnLayout<R = any> {
|
|
244
436
|
protected _children: (Column<R> | ColumnLayout<R>)[];
|
|
437
|
+
protected _grow: boolean | null;
|
|
438
|
+
protected _visibleFrom: string | null;
|
|
439
|
+
protected _hiddenFrom: string | null;
|
|
440
|
+
protected _columnSpan: Record<string, number | string>;
|
|
441
|
+
protected _collapsible: boolean;
|
|
442
|
+
protected _collapsed: boolean;
|
|
443
|
+
protected _hidden: boolean | (() => boolean);
|
|
245
444
|
constructor(children: (Column<R> | ColumnLayout<R>)[]);
|
|
246
445
|
getChildren(): (Column<R> | ColumnLayout<R>)[];
|
|
247
446
|
/** Leaf columns, in order: the ones the table sorts, searches and toggles. */
|
|
248
447
|
getColumns(): Column<R>[];
|
|
249
448
|
abstract getClasses(): string[];
|
|
449
|
+
/** `false`: the component takes only the width it needs in a split, instead of sharing the remaining space. */
|
|
450
|
+
grow(condition?: boolean): this;
|
|
451
|
+
canGrow(): boolean;
|
|
452
|
+
visibleFrom(breakpoint: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | null): this;
|
|
453
|
+
hiddenFrom(breakpoint: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | null): this;
|
|
454
|
+
getResponsiveClasses(): string[];
|
|
455
|
+
/** Columns of a parent `Grid` taken by the component: a number, `'full'`, or one per breakpoint. */
|
|
456
|
+
columnSpan(span: number | string | Record<string, number | string>): this;
|
|
457
|
+
columnSpanFull(): this;
|
|
458
|
+
getColumnSpan(): Record<string, number | string>;
|
|
459
|
+
/**
|
|
460
|
+
* Content hidden behind a toggle button at the bottom of the record. Only one top-level component of the layout can
|
|
461
|
+
* be collapsible. It starts collapsed; `collapsed(false)` shows it open.
|
|
462
|
+
*/
|
|
463
|
+
collapsible(condition?: boolean): this;
|
|
464
|
+
collapsed(condition?: boolean): this;
|
|
465
|
+
isCollapsible(): boolean;
|
|
466
|
+
isCollapsed(): boolean;
|
|
467
|
+
hidden(condition?: boolean | (() => boolean)): this;
|
|
468
|
+
visible(condition?: boolean | (() => boolean)): this;
|
|
469
|
+
isHidden(): boolean;
|
|
470
|
+
/** Inner markup of the component, around the already rendered children. */
|
|
471
|
+
renderContent(children: string[], _record: R, _key: string): Promise<string>;
|
|
250
472
|
}
|
|
251
473
|
/** Columns side by side, from a given breakpoint. */
|
|
252
474
|
export declare class Split<R = any> extends ColumnLayout<R> {
|
|
@@ -265,6 +487,46 @@ export declare class Stack<R = any> extends ColumnLayout<R> {
|
|
|
265
487
|
alignment(alignment: 'start' | 'center' | 'end'): this;
|
|
266
488
|
getClasses(): string[];
|
|
267
489
|
}
|
|
490
|
+
/** Responsive grid of columns: `Grid.make(2)` (2 columns from `lg`) or `Grid.make({ default: 1, md: 2, xl: 3 })`. */
|
|
491
|
+
export declare class Grid<R = any> extends ColumnLayout<R> {
|
|
492
|
+
private _gridColumns;
|
|
493
|
+
constructor(columns?: number | Record<string, number> | null);
|
|
494
|
+
static make<R = any>(columns?: number | Record<string, number> | null): Grid<R>;
|
|
495
|
+
/** Number of columns, or one per breakpoint (\`default\`, \`sm\`, \`md\`, \`lg\`, \`xl\`, \`2xl\`). */
|
|
496
|
+
columns(columns?: number | Record<string, number> | null): this;
|
|
497
|
+
/** Components of the grid. */
|
|
498
|
+
schema(children: (Column<R> | ColumnLayout<R>)[]): this;
|
|
499
|
+
getGridColumns(): Record<string, number>;
|
|
500
|
+
getClasses(): string[];
|
|
501
|
+
renderContent(children: string[]): Promise<string>;
|
|
502
|
+
}
|
|
503
|
+
/** Plain container, styled as a panel: often made collapsible. */
|
|
504
|
+
export declare class Panel<R = any> extends ColumnLayout<R> {
|
|
505
|
+
static make<R = any>(children: (Column<R> | ColumnLayout<R>)[]): Panel<R>;
|
|
506
|
+
getClasses(): string[];
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Your own markup inside the record: a function returning HTML, or the name of an EJS view rendered with `record` and
|
|
510
|
+
* `recordKey`. The HTML is inserted as it is: escape record data with `e()` (EJS's `<%= %>` does it).
|
|
511
|
+
*/
|
|
512
|
+
export declare class View<R = any> extends ColumnLayout<R> {
|
|
513
|
+
private _view;
|
|
514
|
+
private _viewData;
|
|
515
|
+
constructor(view: string | ((ctx: {
|
|
516
|
+
record: R;
|
|
517
|
+
recordKey: string;
|
|
518
|
+
}) => string | Promise<string>));
|
|
519
|
+
static make<R = any>(view: string | ((ctx: {
|
|
520
|
+
record: R;
|
|
521
|
+
recordKey: string;
|
|
522
|
+
}) => string | Promise<string>)): View<R>;
|
|
523
|
+
/** Extra data passed to the EJS view. */
|
|
524
|
+
viewData(data: Record<string, unknown>): this;
|
|
525
|
+
/** Columns rendered inside the view are not part of the table: the view has no children. */
|
|
526
|
+
components(children: (Column<R> | ColumnLayout<R>)[]): this;
|
|
527
|
+
getClasses(): string[];
|
|
528
|
+
renderContent(children: string[], record: R, key: string): Promise<string>;
|
|
529
|
+
}
|
|
268
530
|
/** Column group: a shared label above the column headers. */
|
|
269
531
|
export declare class ColumnGroup<R = any> {
|
|
270
532
|
private label;
|
|
@@ -274,28 +536,108 @@ export declare class ColumnGroup<R = any> {
|
|
|
274
536
|
columns(columns: Column<R>[]): this;
|
|
275
537
|
getColumns(): Column<R>[];
|
|
276
538
|
}
|
|
277
|
-
/** Color swatch
|
|
539
|
+
/** Color swatch per state (a color, or a list of colors). */
|
|
278
540
|
export declare class ColorColumn<R = any> extends Column<R> {
|
|
541
|
+
private _copyable;
|
|
542
|
+
private _copyMessage;
|
|
543
|
+
private _copyMessageDuration;
|
|
544
|
+
private _tooltip;
|
|
545
|
+
private _placeholder;
|
|
546
|
+
private _wrap;
|
|
547
|
+
private _inline;
|
|
279
548
|
static make<R = any>(name: string): ColorColumn<R>;
|
|
549
|
+
/** Clicking the swatch copies the color. Browsers only expose the clipboard on HTTPS or `localhost`. */
|
|
550
|
+
copyable(condition?: PerItem<R, boolean>): this;
|
|
551
|
+
copyMessage(message: string | null): this;
|
|
552
|
+
copyMessageDuration(milliseconds: number): this;
|
|
553
|
+
tooltip(tooltip: PerItem<R, string | null>): this;
|
|
554
|
+
placeholder(text: string | null): this;
|
|
555
|
+
/** Lets several swatches wrap onto more lines. */
|
|
556
|
+
wrap(condition?: boolean): this;
|
|
557
|
+
inline(condition?: boolean): this;
|
|
280
558
|
toHtml(record: R): Promise<string>;
|
|
281
559
|
}
|
|
282
|
-
/** Image
|
|
560
|
+
/** Image per state (an image URL, or a list of URLs). Only local or http(s) URLs are rendered. */
|
|
283
561
|
export declare class ImageColumn<R = any> extends Column<R> {
|
|
284
562
|
private _alt;
|
|
285
563
|
private _height;
|
|
564
|
+
private _width;
|
|
286
565
|
private _circular;
|
|
566
|
+
private _square;
|
|
567
|
+
private _stacked;
|
|
568
|
+
private _ring;
|
|
569
|
+
private _overlap;
|
|
570
|
+
private _limit;
|
|
571
|
+
private _limitedRemainingText;
|
|
572
|
+
private _limitedRemainingTextSize;
|
|
573
|
+
private _defaultImageUrl;
|
|
574
|
+
private _tooltip;
|
|
575
|
+
private _placeholder;
|
|
576
|
+
private _wrap;
|
|
577
|
+
private _inline;
|
|
287
578
|
static make<R = any>(name: string): ImageColumn<R>;
|
|
288
|
-
alt(
|
|
289
|
-
/** CSS height of the
|
|
290
|
-
imageHeight(height: string): this;
|
|
579
|
+
alt(alt: PerItem<R, string | null>): this;
|
|
580
|
+
/** CSS height of the images (`2.5rem` by default, `2rem` when stacked). */
|
|
581
|
+
imageHeight(height: string | number | null): this;
|
|
582
|
+
imageWidth(width: string | number | null): this;
|
|
583
|
+
/** Same width and height. */
|
|
584
|
+
imageSize(size: string | number | null): this;
|
|
291
585
|
circular(condition?: boolean): this;
|
|
586
|
+
square(condition?: boolean): this;
|
|
587
|
+
/** Overlapping images, with a `ring` (border width, 0 to 8) and an `overlap` (0 to 8). */
|
|
588
|
+
stacked(condition?: boolean): this;
|
|
589
|
+
ring(width: number | null): this;
|
|
590
|
+
overlap(overlap: number | null): this;
|
|
591
|
+
/** Shows only the first images; `limitedRemainingText()` adds "+3" for the others. */
|
|
592
|
+
limit(count: number | null): this;
|
|
593
|
+
limitedRemainingText(condition?: boolean, size?: string | null): this;
|
|
594
|
+
/** Image shown when the state is empty. */
|
|
595
|
+
defaultImageUrl(url: string | ((record: R) => string | null) | null): this;
|
|
596
|
+
tooltip(tooltip: PerItem<R, string | null>): this;
|
|
597
|
+
placeholder(text: string | null): this;
|
|
598
|
+
wrap(condition?: boolean): this;
|
|
599
|
+
inline(condition?: boolean): this;
|
|
292
600
|
toHtml(record: R): Promise<string>;
|
|
293
601
|
}
|
|
294
602
|
/** Icon depending on the value; `boolean()` shows a green check or a red cross. */
|
|
603
|
+
/**
|
|
604
|
+
* Icon per state. `boolean()` shows a green check or a red cross; `icon()` and `color()` choose the icon and color from the
|
|
605
|
+
* record and the state, e.g. `IconColumn.make('status').icon((record) => STATUSES[record.status].icon)`.
|
|
606
|
+
*/
|
|
295
607
|
export declare class IconColumn<R = any> extends Column<R> {
|
|
296
608
|
private _boolean;
|
|
609
|
+
private _icon;
|
|
610
|
+
private _color;
|
|
611
|
+
private _size;
|
|
612
|
+
private _trueIcon;
|
|
613
|
+
private _falseIcon;
|
|
614
|
+
private _trueColor;
|
|
615
|
+
private _falseColor;
|
|
616
|
+
private _tooltip;
|
|
617
|
+
private _placeholder;
|
|
618
|
+
private _listWithLineBreaks;
|
|
619
|
+
private _wrap;
|
|
620
|
+
private _inline;
|
|
297
621
|
static make<R = any>(name: string): IconColumn<R>;
|
|
298
622
|
boolean(condition?: boolean): this;
|
|
623
|
+
icon(icon: PerItem<R, string | null> | null): this;
|
|
624
|
+
color(color: PerItem<R, string | null> | null): this;
|
|
625
|
+
/** Icon size: `xs`, `sm`, `md`, `lg` (default), `xl` or `2xl`. */
|
|
626
|
+
size(size: PerItem<R, string | null>): this;
|
|
627
|
+
/** Icons and colors of a boolean column; `false` shows no icon for that value. */
|
|
628
|
+
trueIcon(icon: string | false | null): this;
|
|
629
|
+
falseIcon(icon: string | false | null): this;
|
|
630
|
+
trueColor(color: string | null): this;
|
|
631
|
+
falseColor(color: string | null): this;
|
|
632
|
+
tooltip(tooltip: PerItem<R, string | null>): this;
|
|
633
|
+
placeholder(text: string | null): this;
|
|
634
|
+
/** One icon per line, for a state that is a list. */
|
|
635
|
+
listWithLineBreaks(condition?: boolean): this;
|
|
636
|
+
wrap(condition?: boolean): this;
|
|
637
|
+
inline(condition?: boolean): this;
|
|
638
|
+
private isBooleanItem;
|
|
639
|
+
private iconOf;
|
|
640
|
+
private colorOf;
|
|
299
641
|
toHtml(record: R): Promise<string>;
|
|
300
642
|
}
|
|
301
643
|
/** Application-defined validation rule of an editable column: synchronous check and message (`:attribute` already replaced). */
|
|
@@ -345,6 +687,8 @@ export declare abstract class EditableColumn<R = any> extends Column<R> {
|
|
|
345
687
|
* Error message, or `null` if the value is valid. An empty value is only checked by `required`, and several errors
|
|
346
688
|
* produce the first message followed by "(and N more errors)".
|
|
347
689
|
*/
|
|
690
|
+
/** Validation of a value for a given record (column types whose rules depend on the record override it). */
|
|
691
|
+
validateFor(_record: R, input: unknown): Promise<string | null>;
|
|
348
692
|
validate(input: unknown): string | null;
|
|
349
693
|
/** Custom write, replacing the update of the record's column. Its return value is sent back to the browser. */
|
|
350
694
|
updateStateUsing(callback: StateHook<R> | null): this;
|
|
@@ -361,7 +705,7 @@ export declare abstract class EditableColumn<R = any> extends Column<R> {
|
|
|
361
705
|
*/
|
|
362
706
|
updateState(record: R, input: unknown, adapter: Pick<DataAdapter<R>, 'getKey' | 'update'>): Promise<unknown>;
|
|
363
707
|
/** `x-tooltip` expression of editable controls: the column tooltip, replaced by the validation error when there is one. */
|
|
364
|
-
protected tooltipExpression(record: R): string;
|
|
708
|
+
protected tooltipExpression(record: R, extra?: string | null): string;
|
|
365
709
|
/** Shared opening markup of editable cells: lazily loaded Alpine component, server state and record key. */
|
|
366
710
|
protected editableAttributes(component: string, asset: string, recordKey: string | number, state: unknown): Attributes;
|
|
367
711
|
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>";
|
|
@@ -369,14 +713,56 @@ export declare abstract class EditableColumn<R = any> extends Column<R> {
|
|
|
369
713
|
/**
|
|
370
714
|
* In-cell editable select (native select only). The received value must be one of the declared options.
|
|
371
715
|
*/
|
|
716
|
+
export type SelectColumnOptions = [string, string][] | Record<string, string>;
|
|
372
717
|
export declare class SelectColumn<R = any> extends EditableColumn<R> {
|
|
373
718
|
private _options;
|
|
374
719
|
private _selectablePlaceholder;
|
|
720
|
+
private _native;
|
|
721
|
+
private _searchable;
|
|
722
|
+
private _disabledOptions;
|
|
723
|
+
private _placeholder;
|
|
724
|
+
private _optionsLimit;
|
|
725
|
+
private _canOptionLabelsWrap;
|
|
726
|
+
private _position;
|
|
727
|
+
private _inline;
|
|
375
728
|
static make<R = any>(name: string): SelectColumn<R>;
|
|
376
|
-
|
|
729
|
+
/** `{ value: label }` pairs, `[value, label]` pairs, or a function of the record returning either. */
|
|
730
|
+
options(options: SelectColumnOptions | ((record: R) => SelectColumnOptions | Promise<SelectColumnOptions>)): this;
|
|
731
|
+
/** Static options (empty when they depend on the record: use `getOptionsFor()`). */
|
|
377
732
|
getOptions(): [string, string][];
|
|
733
|
+
getOptionsFor(record: R): Promise<[string, string][]>;
|
|
734
|
+
private _optionsRelationship;
|
|
735
|
+
private _relationshipOptions;
|
|
736
|
+
/**
|
|
737
|
+
* Options from the records of a relationship of the record's model (an Objection model with `relationMappings`): the
|
|
738
|
+
* column stores the picked record's key, e.g. `SelectColumn.make('author_id').optionsRelationship('author', 'name')`.
|
|
739
|
+
* Up to 1,000 options are listed; any related record's key is accepted when saving.
|
|
740
|
+
*/
|
|
741
|
+
optionsRelationship(name: string, titleAttribute?: string | null, modifyQueryUsing?: RelationshipQueryModifier | null): this;
|
|
378
742
|
selectablePlaceholder(condition?: boolean): this;
|
|
743
|
+
/** `false`: a JavaScript select instead of the browser's native one. */
|
|
744
|
+
native(condition?: boolean): this;
|
|
745
|
+
private _allowHtml;
|
|
746
|
+
/** Option labels are HTML, sanitized on the server (JavaScript select only; the native select shows their text). */
|
|
747
|
+
allowHtml(condition?: boolean): this;
|
|
748
|
+
private labelForDisplay;
|
|
749
|
+
/** A search field in the select (implies a JavaScript select). */
|
|
750
|
+
searchableOptions(condition?: boolean): this;
|
|
751
|
+
isNative(): boolean;
|
|
752
|
+
/** Options that cannot be chosen. A disabled option is also refused on the server. */
|
|
753
|
+
disableOptionWhen(callback: (value: string, label: string, record: R) => boolean): this;
|
|
754
|
+
isOptionDisabled(value: string, label: string, record: R): boolean;
|
|
755
|
+
placeholder(text: string | null): this;
|
|
756
|
+
/** Maximum number of options listed by the JavaScript select (50 by default). */
|
|
757
|
+
optionsLimit(limit: number): this;
|
|
758
|
+
/** `false`: long option labels are truncated in the JavaScript select instead of wrapping. */
|
|
759
|
+
allowOptionsLabelsWrap(condition?: boolean): this;
|
|
760
|
+
/** Side where the JavaScript select's dropdown opens (automatic by default). */
|
|
761
|
+
position(position: 'top' | 'bottom' | null): this;
|
|
762
|
+
inline(condition?: boolean): this;
|
|
379
763
|
protected getImplicitRules(): ColumnValidationRule[];
|
|
764
|
+
/** The value must be one of the record's options, and not a disabled one. */
|
|
765
|
+
validateFor(record: R, input: unknown): Promise<string | null>;
|
|
380
766
|
toHtml(record: R, recordKey?: string | number): Promise<string>;
|
|
381
767
|
}
|
|
382
768
|
/** In-cell editable toggle. The received value must be a boolean (`boolean` rule by default). */
|
|
@@ -473,17 +859,22 @@ export declare function updateTableColumnState<R>(table: Table<R>, host: TableHo
|
|
|
473
859
|
/** Filter state: the values of its form. */
|
|
474
860
|
export type FilterState = Record<string, unknown>;
|
|
475
861
|
/** Active filter indicator: its label, and the filter field cleared when it is removed. */
|
|
862
|
+
/** Active filter indicator: its label, the filter field cleared when it is removed (`''`: the whole filter), whether it can be removed, and its badge color. */
|
|
476
863
|
export type FilterIndicator = {
|
|
477
864
|
label: string;
|
|
478
865
|
field: string;
|
|
866
|
+
removable?: boolean;
|
|
867
|
+
color?: string | null;
|
|
479
868
|
};
|
|
480
|
-
/**
|
|
481
|
-
export type FiltersLayout = 'dropdown' | 'above-content-collapsible';
|
|
869
|
+
/** Where the filters form is shown: in a toolbar dropdown (default) or modal, or in a panel around the table content. */
|
|
870
|
+
export type FiltersLayout = 'dropdown' | 'modal' | 'above-content' | 'above-content-collapsible' | 'below-content' | 'before-content' | 'before-content-collapsible' | 'after-content' | 'after-content-collapsible';
|
|
482
871
|
export interface TableFilter {
|
|
483
872
|
readonly name: string;
|
|
484
873
|
getLabel(): string;
|
|
485
874
|
/** Initial state (empty form). */
|
|
486
875
|
getDefaultState(): FilterState;
|
|
876
|
+
/** State after the filter is removed (its indicator or "remove all"); `getDefaultState()` when absent. */
|
|
877
|
+
getResetState?(): FilterState;
|
|
487
878
|
/** Options of the `value` field as [value, label] pairs, and the empty option's label. */
|
|
488
879
|
getFormDefinition(): {
|
|
489
880
|
placeholder: string;
|
|
@@ -504,88 +895,204 @@ export interface TableFilter {
|
|
|
504
895
|
/** Data loaded from the database before indicators are computed (e.g. related record labels). */
|
|
505
896
|
loadIndicatorData?(state: FilterState, host: TableHost): Promise<void>;
|
|
506
897
|
}
|
|
507
|
-
/**
|
|
508
|
-
export declare class
|
|
509
|
-
|
|
510
|
-
|
|
898
|
+
/** Badge shown above the table for an applied filter. */
|
|
899
|
+
export declare class Indicator {
|
|
900
|
+
private _label;
|
|
901
|
+
private _removeField;
|
|
902
|
+
private _removable;
|
|
903
|
+
private _color;
|
|
904
|
+
constructor(label: string);
|
|
905
|
+
static make(label: string): Indicator;
|
|
906
|
+
label(label: string): this;
|
|
511
907
|
getLabel(): string;
|
|
512
|
-
|
|
908
|
+
/** Field of the filter form cleared when the indicator is removed (by default, the whole filter is reset). */
|
|
909
|
+
removeField(field: string | null): this;
|
|
910
|
+
getRemoveField(): string | null;
|
|
911
|
+
/** `false`: no remove button. A forged removal is refused on the server too. */
|
|
912
|
+
removable(condition?: boolean): this;
|
|
913
|
+
isRemovable(): boolean;
|
|
914
|
+
color(color: string | null): this;
|
|
915
|
+
getColor(): string | null;
|
|
916
|
+
}
|
|
917
|
+
/** What `indicateUsing()` may return: a label, an `Indicator`, a list of them, or `{ field: label }` pairs. */
|
|
918
|
+
export type IndicatorResult = string | Indicator | null | undefined | (string | Indicator)[] | Record<string, string | Indicator>;
|
|
919
|
+
/** Shared options of the built-in filters: label, default state, indicators and custom query. */
|
|
920
|
+
declare abstract class BaseFilter implements TableFilter {
|
|
921
|
+
readonly name: string;
|
|
922
|
+
protected _label: string | null;
|
|
923
|
+
protected _default: unknown;
|
|
924
|
+
protected _indicator: string | Indicator | null;
|
|
925
|
+
protected _indicateUsing: ((data: FilterState) => IndicatorResult) | null;
|
|
926
|
+
protected _query: ((query: any, data: FilterState) => void) | null;
|
|
927
|
+
protected _columnSpan: Record<string, number | string>;
|
|
928
|
+
constructor(name: string);
|
|
929
|
+
label(label: string): this;
|
|
930
|
+
getLabel(): string;
|
|
931
|
+
/** State applied when the table opens and when the user clicks "Reset". */
|
|
932
|
+
default(value?: unknown): this;
|
|
933
|
+
/** Label of the indicator (the filter label by default). */
|
|
934
|
+
indicator(indicator: string | Indicator | null): this;
|
|
935
|
+
getIndicator(): string | Indicator;
|
|
936
|
+
/** Indicators of the applied state, replacing the default one. */
|
|
937
|
+
indicateUsing(callback: ((data: FilterState) => IndicatorResult) | null): this;
|
|
938
|
+
/** Query condition built from the sanitized state, replacing the default one. */
|
|
939
|
+
query(modifier: (query: any, data: FilterState) => void): this;
|
|
940
|
+
/** Width of the filter in the filters form grid. */
|
|
941
|
+
columnSpan(span: number | string | Record<string, number | string>): this;
|
|
942
|
+
columnSpanFull(): this;
|
|
943
|
+
getColumnSpan(): Record<string, number | string>;
|
|
944
|
+
/** State after removing the filter: blank, whatever the default. */
|
|
945
|
+
abstract getResetState(): FilterState;
|
|
946
|
+
abstract getDefaultState(): FilterState;
|
|
947
|
+
abstract sanitizeState(state: unknown): FilterState;
|
|
948
|
+
abstract isActive(state: FilterState): boolean;
|
|
949
|
+
abstract apply(query: Omit<ListQuery, 'page' | 'perPage'>, state: FilterState): void;
|
|
513
950
|
getFormDefinition(): {
|
|
514
951
|
placeholder: string;
|
|
515
952
|
options: [string, string][];
|
|
516
953
|
};
|
|
517
|
-
|
|
518
|
-
|
|
954
|
+
protected defaultIndicators(_data: FilterState): IndicatorResult;
|
|
955
|
+
getIndicators(state: FilterState): FilterIndicator[];
|
|
956
|
+
/** Prefixes a value label with the indicator, unless the indicator is a ready-made `Indicator`. */
|
|
957
|
+
protected labelled(valueLabel: string): string | Indicator;
|
|
519
958
|
}
|
|
520
|
-
/** Filters on a column value picked from a list
|
|
521
|
-
export declare class SelectFilter
|
|
522
|
-
readonly name: string;
|
|
523
|
-
private _label;
|
|
959
|
+
/** Filters on a column value picked from a list. */
|
|
960
|
+
export declare class SelectFilter extends BaseFilter {
|
|
524
961
|
private _column;
|
|
525
962
|
private _options;
|
|
526
|
-
|
|
963
|
+
private _multiple;
|
|
964
|
+
private _searchable;
|
|
965
|
+
private _selectablePlaceholder;
|
|
966
|
+
private _placeholder;
|
|
967
|
+
private _optionLabels;
|
|
527
968
|
static make(name: string): SelectFilter;
|
|
528
|
-
label(label: string): this;
|
|
529
969
|
/** Filtered column when it differs from the filter name (e.g. a relationship's foreign key). */
|
|
530
970
|
column(column: string): this;
|
|
971
|
+
attribute(column: string): this;
|
|
972
|
+
getColumn(): string;
|
|
531
973
|
/** Fixed options, or an async function (e.g. records of a relationship). */
|
|
532
974
|
options(options: [string, string][] | Record<string, string> | (() => Promise<[string, string][]>)): this;
|
|
533
|
-
|
|
534
|
-
|
|
975
|
+
/** Several values can be picked: records matching any of them are shown. */
|
|
976
|
+
multiple(condition?: boolean): this;
|
|
977
|
+
isMultiple(): boolean;
|
|
978
|
+
searchable(condition?: boolean): this;
|
|
979
|
+
/** `false`: the empty option cannot be picked again once a value is chosen. */
|
|
980
|
+
selectablePlaceholder(condition?: boolean): this;
|
|
981
|
+
placeholder(placeholder: string | null): this;
|
|
982
|
+
/** No-op: options are always loaded with the form. */
|
|
983
|
+
preload(): this;
|
|
984
|
+
private _relationship;
|
|
985
|
+
private _emptyOptionLabel;
|
|
986
|
+
private _host;
|
|
987
|
+
/**
|
|
988
|
+
* Options from the records of a relationship of the table's model (an Objection model with `relationMappings`); records
|
|
989
|
+
* related to the picked ones are shown. `hasEmptyOption` adds a "None" option for records without related records.
|
|
990
|
+
*/
|
|
991
|
+
relationship(name: string, titleAttribute?: string | null, modifyQueryUsing?: RelationshipQueryModifier | null, hasEmptyOption?: boolean): this;
|
|
992
|
+
hasRelationship(): boolean;
|
|
993
|
+
/** Label of the "None" option of `relationship(..., hasEmptyOption: true)`. */
|
|
994
|
+
emptyRelationshipOptionLabel(label: string | null): this;
|
|
995
|
+
getEmptyRelationshipOptionLabel(): string;
|
|
535
996
|
getFormDefinition(): {
|
|
536
997
|
placeholder: string;
|
|
537
998
|
options: [string, string][];
|
|
538
999
|
};
|
|
539
|
-
getFormOptions(): Promise<[string, string][]>;
|
|
1000
|
+
getFormOptions(host?: unknown): Promise<[string, string][]>;
|
|
1001
|
+
private loadRelationshipOptions;
|
|
540
1002
|
/** Options are evaluated on every render, so the select gets a key derived from them (forces a re-render when they change). */
|
|
541
1003
|
readonly hasDynamicOptions = true;
|
|
1004
|
+
getFormComponents(): unknown[];
|
|
1005
|
+
private defaultValues;
|
|
1006
|
+
getResetState(): FilterState;
|
|
1007
|
+
getDefaultState(): FilterState;
|
|
1008
|
+
sanitizeState(state: unknown): FilterState;
|
|
1009
|
+
/** Values that can filter: with fixed options, only offered values; loaded options are bound parameters (an unknown value matches nothing). */
|
|
1010
|
+
private values;
|
|
542
1011
|
isActive(state: FilterState): boolean;
|
|
543
1012
|
apply(query: Omit<ListQuery, 'page' | 'perPage'>, state: FilterState): void;
|
|
1013
|
+
/** Labels of the applied values, loaded before the indicators are computed. */
|
|
1014
|
+
loadIndicatorData(state: FilterState, host?: TableHost): Promise<void>;
|
|
1015
|
+
protected defaultIndicators(data: FilterState): IndicatorResult;
|
|
544
1016
|
}
|
|
545
|
-
/** Three-state filter on a boolean column
|
|
546
|
-
export declare class TernaryFilter
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
1017
|
+
/** Three-state filter: all, yes, no. By default on a boolean column; `nullable()` checks whether the column is filled. */
|
|
1018
|
+
export declare class TernaryFilter extends BaseFilter {
|
|
1019
|
+
private _column;
|
|
1020
|
+
protected _trueLabel: string | null;
|
|
1021
|
+
protected _falseLabel: string | null;
|
|
1022
|
+
protected _placeholder: string | null;
|
|
1023
|
+
protected _nullable: boolean;
|
|
1024
|
+
protected _queries: {
|
|
1025
|
+
true: (query: any) => void;
|
|
1026
|
+
false: (query: any) => void;
|
|
1027
|
+
blank?: (query: any) => void;
|
|
1028
|
+
} | null;
|
|
550
1029
|
static make(name: string): TernaryFilter;
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
1030
|
+
attribute(column: string): this;
|
|
1031
|
+
column(column: string): this;
|
|
1032
|
+
getColumn(): string;
|
|
1033
|
+
trueLabel(label: string | null): this;
|
|
1034
|
+
falseLabel(label: string | null): this;
|
|
1035
|
+
placeholder(label: string | null): this;
|
|
1036
|
+
getTrueLabel(): string;
|
|
1037
|
+
getFalseLabel(): string;
|
|
1038
|
+
/** "Yes" shows records where the column is filled, "No" those where it is empty. */
|
|
1039
|
+
nullable(condition?: boolean): this;
|
|
1040
|
+
/** Custom conditions for "yes", "no" and, optionally, the empty choice. */
|
|
1041
|
+
queries(queries: {
|
|
1042
|
+
true: (query: any) => void;
|
|
1043
|
+
false: (query: any) => void;
|
|
1044
|
+
blank?: (query: any) => void;
|
|
1045
|
+
}): this;
|
|
554
1046
|
getFormDefinition(): {
|
|
555
1047
|
placeholder: string;
|
|
556
1048
|
options: [string, string][];
|
|
557
1049
|
};
|
|
1050
|
+
getFormComponents(): unknown[];
|
|
1051
|
+
getResetState(): FilterState;
|
|
1052
|
+
getDefaultState(): FilterState;
|
|
1053
|
+
sanitizeState(state: unknown): FilterState;
|
|
558
1054
|
isActive(state: FilterState): boolean;
|
|
559
1055
|
apply(query: Omit<ListQuery, 'page' | 'perPage'>, state: FilterState): void;
|
|
1056
|
+
protected defaultIndicators(data: FilterState): IndicatorResult;
|
|
560
1057
|
}
|
|
561
|
-
/**
|
|
562
|
-
export declare class
|
|
563
|
-
|
|
564
|
-
|
|
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;
|
|
1058
|
+
/** "Trashed" filter for soft-deletable models: without (default), with, or only deleted records. */
|
|
1059
|
+
export declare class TrashedFilter extends TernaryFilter {
|
|
1060
|
+
constructor(name?: string);
|
|
1061
|
+
static make(name?: string): TrashedFilter;
|
|
578
1062
|
getLabel(): string;
|
|
579
|
-
|
|
1063
|
+
getTrueLabel(): string;
|
|
1064
|
+
getFalseLabel(): string;
|
|
580
1065
|
getFormDefinition(): {
|
|
581
1066
|
placeholder: string;
|
|
582
1067
|
options: [string, string][];
|
|
583
1068
|
};
|
|
1069
|
+
apply(query: Omit<ListQuery, 'page' | 'perPage'>, state: FilterState): void;
|
|
1070
|
+
protected defaultIndicators(data: FilterState): IndicatorResult;
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Custom filter. Without `schema()`, it is a checkbox (or a toggle with `toggle()`) and `query()` runs when it is checked.
|
|
1074
|
+
* With `schema()`, the query and indicators are written by the application.
|
|
1075
|
+
*/
|
|
1076
|
+
export declare class Filter extends BaseFilter {
|
|
1077
|
+
private _components;
|
|
1078
|
+
private _toggle;
|
|
1079
|
+
private _formComponents;
|
|
1080
|
+
static make(name: string): Filter;
|
|
1081
|
+
/** Filter fields; their names are the only state keys accepted from the browser. */
|
|
1082
|
+
schema(components: unknown[]): this;
|
|
1083
|
+
/** Form fields of a filter without `schema()`: a toggle instead of a checkbox. */
|
|
1084
|
+
toggle(condition?: boolean): this;
|
|
1085
|
+
checkbox(): this;
|
|
1086
|
+
private hasSchema;
|
|
584
1087
|
getFormComponents(): unknown[];
|
|
1088
|
+
private fields;
|
|
1089
|
+
getResetState(): FilterState;
|
|
1090
|
+
getDefaultState(): FilterState;
|
|
585
1091
|
sanitizeState(state: unknown): FilterState;
|
|
1092
|
+
/** A field left empty, or an unchecked checkbox, does not filter. */
|
|
586
1093
|
isActive(state: FilterState): boolean;
|
|
587
1094
|
apply(query: Omit<ListQuery, 'page' | 'perPage'>, state: FilterState): void;
|
|
588
|
-
|
|
1095
|
+
protected defaultIndicators(data: FilterState): IndicatorResult;
|
|
589
1096
|
removeIndicator(state: FilterState, field: string): FilterState;
|
|
590
1097
|
}
|
|
591
1098
|
export type ColumnState = {
|
|
@@ -597,9 +1104,59 @@ export type ColumnState = {
|
|
|
597
1104
|
isToggleable: boolean;
|
|
598
1105
|
isToggledHiddenByDefault: boolean | null;
|
|
599
1106
|
};
|
|
1107
|
+
/** Look of a filters action (trigger, apply, reset), changed with `filtersTriggerAction()`, `filtersApplyAction()` and `filtersResetAction()`. */
|
|
1108
|
+
export declare class FiltersAction {
|
|
1109
|
+
private _label;
|
|
1110
|
+
private _icon;
|
|
1111
|
+
private _color;
|
|
1112
|
+
private _view;
|
|
1113
|
+
private _hidden;
|
|
1114
|
+
label(label: string | null): this;
|
|
1115
|
+
icon(icon: string | null): this;
|
|
1116
|
+
color(color: string | null): this;
|
|
1117
|
+
/** Labeled button. */
|
|
1118
|
+
button(): this;
|
|
1119
|
+
link(): this;
|
|
1120
|
+
/** Icon only, the label becomes the tooltip and accessible name. */
|
|
1121
|
+
iconButton(): this;
|
|
1122
|
+
hidden(condition?: boolean): this;
|
|
1123
|
+
resolve(defaults: {
|
|
1124
|
+
label: string;
|
|
1125
|
+
icon: string | null;
|
|
1126
|
+
color: string;
|
|
1127
|
+
view: 'button' | 'link' | 'icon-button';
|
|
1128
|
+
}): {
|
|
1129
|
+
label: string;
|
|
1130
|
+
icon: string;
|
|
1131
|
+
color: string;
|
|
1132
|
+
view: "link" | "button" | "icon-button";
|
|
1133
|
+
hidden: boolean;
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1136
|
+
type FiltersActionView = ReturnType<FiltersAction['resolve']> & {
|
|
1137
|
+
customized: boolean;
|
|
1138
|
+
};
|
|
1139
|
+
/** Bulk actions grouped in the "Bulk actions" dropdown of the toolbar (`toolbarActions([BulkActionGroup.make([...])])`). */
|
|
1140
|
+
export declare class BulkActionGroup {
|
|
1141
|
+
private _actions;
|
|
1142
|
+
constructor(actions: any[]);
|
|
1143
|
+
static make(actions: any[]): BulkActionGroup;
|
|
1144
|
+
getActions(): any[];
|
|
1145
|
+
}
|
|
1146
|
+
/** Upper bound on the rows loaded by an unpaginated table or the `'all'` page option. */
|
|
1147
|
+
export declare const MAX_UNPAGINATED_RECORDS = 10000;
|
|
600
1148
|
export declare class Table<R = any> {
|
|
1149
|
+
/** Default setup for every table, e.g. `Table.configureUsing((table) => table.paginationPageOptions([10, 25]))`. */
|
|
1150
|
+
static configureUsing(configure: (table: Table<any>) => void): void;
|
|
1151
|
+
constructor();
|
|
601
1152
|
private _columns;
|
|
602
1153
|
private _recordAction;
|
|
1154
|
+
private _pageSummary;
|
|
1155
|
+
private _allTableSummary;
|
|
1156
|
+
/** Which summary rows to show: "this page" (`pageCondition`) and the whole table (`allTableCondition`); group summaries are not affected. */
|
|
1157
|
+
summaries(pageCondition?: boolean, allTableCondition?: boolean): this;
|
|
1158
|
+
hasPageSummary(): boolean;
|
|
1159
|
+
hasAllTableSummary(): boolean;
|
|
603
1160
|
private _recordActions;
|
|
604
1161
|
private _heading;
|
|
605
1162
|
private _headerActions;
|
|
@@ -610,6 +1167,12 @@ export declare class Table<R = any> {
|
|
|
610
1167
|
private _defaultSort;
|
|
611
1168
|
private _recordUrl;
|
|
612
1169
|
private _pageOptions;
|
|
1170
|
+
private _paginated;
|
|
1171
|
+
private _emptyStateHeading;
|
|
1172
|
+
private _emptyStateDescription;
|
|
1173
|
+
private _emptyStateIcon;
|
|
1174
|
+
private _emptyStateActions;
|
|
1175
|
+
private _emptyState;
|
|
613
1176
|
private _stackedOnMobile;
|
|
614
1177
|
private _label;
|
|
615
1178
|
private _groups;
|
|
@@ -651,8 +1214,14 @@ export declare class Table<R = any> {
|
|
|
651
1214
|
areGroupsCollapsedByDefault(): boolean;
|
|
652
1215
|
private _columnsLayout;
|
|
653
1216
|
columns(columns: (Column<R> | ColumnGroup<R> | ColumnLayout<R>)[]): this;
|
|
654
|
-
/** Column layout, or `null` for a regular table. */
|
|
1217
|
+
/** Column layout, or `null` for a regular table. The collapsible component is left out (see `getCollapsibleColumnsLayout()`). */
|
|
655
1218
|
getColumnsLayout(): (Column<R> | ColumnLayout<R>)[] | null;
|
|
1219
|
+
/** The first top-level layout component marked `collapsible()`, shown behind a toggle button. */
|
|
1220
|
+
getCollapsibleColumnsLayout(): ColumnLayout<R> | null;
|
|
1221
|
+
private _contentGrid;
|
|
1222
|
+
/** Arranges the record cards of a column layout in a grid: `contentGrid({ md: 2, xl: 3 })`. */
|
|
1223
|
+
contentGrid(columns: Record<string, number> | number | null): this;
|
|
1224
|
+
getContentGrid(): Record<string, number> | null;
|
|
656
1225
|
/** Action mounted when a row is clicked (e.g. `'edit'`), instead of a URL. */
|
|
657
1226
|
recordAction(name: string | null): this;
|
|
658
1227
|
getRecordAction(): string | null;
|
|
@@ -664,10 +1233,18 @@ export declare class Table<R = any> {
|
|
|
664
1233
|
getHeaderActions(): any[];
|
|
665
1234
|
/** Bulk actions ("Bulk actions" menu); if never called, the host provides its default ones. */
|
|
666
1235
|
groupedBulkActions(actions: any[]): this;
|
|
1236
|
+
/** Bulk actions: those of `groupedBulkActions()`, then those of the `BulkActionGroup`s of `toolbarActions()`; `null` when none is declared. */
|
|
667
1237
|
getBulkActions(): any[] | null;
|
|
1238
|
+
private _toolbarActions;
|
|
1239
|
+
/** Actions in the toolbar, left of the search field: buttons, and a `BulkActionGroup` for the bulk actions dropdown. */
|
|
1240
|
+
toolbarActions(actions: any[]): this;
|
|
1241
|
+
/** Toolbar actions other than bulk action groups. */
|
|
1242
|
+
getToolbarActions(): any[];
|
|
668
1243
|
/** Row actions: `Action`s or an `ActionGroup` (dropdown). */
|
|
669
1244
|
recordActions(actions: any[]): this;
|
|
670
1245
|
getRecordActions(): any[];
|
|
1246
|
+
/** Actions given to columns with `action()` (not those named after a record action). */
|
|
1247
|
+
getColumnActions(): any[];
|
|
671
1248
|
/** CSS classes added to a row depending on its record. */
|
|
672
1249
|
recordClasses(resolver: (record: R) => string | null): this;
|
|
673
1250
|
getRecordClasses(record: R): string | null;
|
|
@@ -676,19 +1253,110 @@ export declare class Table<R = any> {
|
|
|
676
1253
|
}): this;
|
|
677
1254
|
filtersLayout(layout: FiltersLayout): this;
|
|
678
1255
|
getFiltersLayout(): FiltersLayout;
|
|
679
|
-
|
|
680
|
-
|
|
1256
|
+
private _deferFilters;
|
|
1257
|
+
private _filtersFormColumns;
|
|
1258
|
+
private _filtersFormWidth;
|
|
1259
|
+
private _filtersFormMaxHeight;
|
|
1260
|
+
private _filtersResetPosition;
|
|
1261
|
+
private _filterIndicatorsHidden;
|
|
1262
|
+
private _persist;
|
|
1263
|
+
private _recordActionsPosition;
|
|
1264
|
+
private _recordActionsAlignment;
|
|
1265
|
+
/**
|
|
1266
|
+
* Where row actions go: after the columns (default), before the columns (after the checkbox), or before the checkbox
|
|
1267
|
+
* (`before-cells`). `after-cells` is the same as `after-columns`.
|
|
1268
|
+
*/
|
|
1269
|
+
recordActionsPosition(position: 'before-columns' | 'before-cells' | 'after-columns' | 'after-cells'): this;
|
|
1270
|
+
getRecordActionsPosition(): 'before-columns' | 'before-cells' | 'after-columns' | 'after-cells';
|
|
1271
|
+
/** Alignment of row actions in their cell. */
|
|
1272
|
+
recordActionsAlignment(alignment: 'start' | 'center' | 'end' | null): this;
|
|
1273
|
+
getRecordActionsAlignment(): 'start' | 'center' | 'end' | null;
|
|
1274
|
+
private _isRecordSelectable;
|
|
1275
|
+
private _maxSelectableRecords;
|
|
1276
|
+
private _selectsCurrentPageOnly;
|
|
1277
|
+
/** Records for which this returns `false` have no checkbox, and are ignored by bulk actions even if the browser sends them. */
|
|
1278
|
+
checkIfRecordIsSelectableUsing(callback: ((record: R) => boolean | Promise<boolean>) | null): this;
|
|
1279
|
+
hasRecordSelectabilityCheck(): boolean;
|
|
1280
|
+
isRecordSelectable(record: R): Promise<boolean>;
|
|
1281
|
+
/** Maximum number of records the user may select at once (also enforced on the server). */
|
|
1282
|
+
maxSelectableRecords(count: number | null): this;
|
|
1283
|
+
getMaxSelectableRecords(): number | null;
|
|
1284
|
+
/** "Select all" only selects the records of the current page. */
|
|
1285
|
+
selectCurrentPageOnly(condition?: boolean): this;
|
|
1286
|
+
selectsCurrentPageOnly(): boolean;
|
|
1287
|
+
/** `false`: filters apply as soon as a field changes, without the "Apply" button. */
|
|
1288
|
+
deferFilters(condition?: boolean): this;
|
|
1289
|
+
private _filterActions;
|
|
1290
|
+
/** Customizes the button that opens the filters: `filtersTriggerAction((action) => action.button().label('Filter'))`. */
|
|
1291
|
+
filtersTriggerAction(configure: (action: FiltersAction) => FiltersAction | void): this;
|
|
1292
|
+
/** Customizes the "Apply" button of deferred filters. */
|
|
1293
|
+
filtersApplyAction(configure: (action: FiltersAction) => FiltersAction | void): this;
|
|
1294
|
+
/** Customizes the "Reset" button (`hidden()` removes it). */
|
|
1295
|
+
filtersResetAction(configure: (action: FiltersAction) => FiltersAction | void): this;
|
|
1296
|
+
getFiltersActionView(kind: 'trigger' | 'apply' | 'reset'): FiltersActionView;
|
|
1297
|
+
private _filtersFormSchema;
|
|
1298
|
+
/**
|
|
1299
|
+
* Arranges the filters form yourself: the function receives each filter's form group, keyed by filter name, and returns
|
|
1300
|
+
* the form components (e.g. sections). Filters left out are not shown.
|
|
1301
|
+
*/
|
|
1302
|
+
filtersFormSchema(schema: ((filters: Record<string, any>) => any[]) | null): this;
|
|
1303
|
+
getFiltersFormSchema(): ((filters: Record<string, any>) => any[]) | null;
|
|
1304
|
+
hasDeferredFilters(): boolean;
|
|
1305
|
+
/** Columns of the filters form grid (1 in a dropdown or modal, up to 5 above or below the content by default). */
|
|
1306
|
+
filtersFormColumns(columns: number | Record<string, number> | null): this;
|
|
1307
|
+
getFiltersFormColumns(): number | Record<string, number>;
|
|
1308
|
+
/** Width of the filters dropdown, modal or side panel: `xs` to `7xl`, `full`, `screen`... */
|
|
1309
|
+
filtersFormWidth(width: string | null): this;
|
|
1310
|
+
getFiltersFormWidth(): string | null;
|
|
1311
|
+
/** Maximum height of the filters dropdown, as a CSS length; it scrolls beyond. */
|
|
1312
|
+
filtersFormMaxHeight(height: string | null): this;
|
|
1313
|
+
getFiltersFormMaxHeight(): string | null;
|
|
1314
|
+
/** `footer`: the "Reset" button goes next to "Apply" instead of the filters heading. */
|
|
1315
|
+
filtersResetActionPosition(position: 'header' | 'footer'): this;
|
|
1316
|
+
getFiltersResetActionPosition(): 'header' | 'footer';
|
|
1317
|
+
/** Hides the active filter badges above the table. */
|
|
1318
|
+
hiddenFilterIndicators(condition?: boolean): this;
|
|
1319
|
+
areFilterIndicatorsHidden(): boolean;
|
|
1320
|
+
/** Keeps the applied filters for the user's browser session (restored when the page is opened again). */
|
|
1321
|
+
persistFiltersInSession(condition?: boolean): this;
|
|
1322
|
+
persistSearchInSession(condition?: boolean): this;
|
|
1323
|
+
persistColumnSearchesInSession(condition?: boolean): this;
|
|
1324
|
+
persistSortInSession(condition?: boolean): this;
|
|
1325
|
+
private _persistGrouping;
|
|
1326
|
+
persistGroupingInSession(condition?: boolean): this;
|
|
1327
|
+
persistsGroupingInSession(): boolean;
|
|
1328
|
+
persistsFiltersInSession(): boolean;
|
|
1329
|
+
persistsSearchInSession(): boolean;
|
|
1330
|
+
persistsColumnSearchesInSession(): boolean;
|
|
1331
|
+
persistsSortInSession(): boolean;
|
|
681
1332
|
defaultSort(column: string, direction?: SortDirection): this;
|
|
682
1333
|
recordUrl(resolver: (record: R) => string | null): this;
|
|
683
1334
|
private _reorderColumn;
|
|
684
1335
|
/** Lets users reorder rows by hand; `column` stores the position. */
|
|
685
1336
|
reorderable(column: string | null): this;
|
|
686
1337
|
getReorderColumn(): string | null;
|
|
687
|
-
|
|
1338
|
+
/** Page sizes offered; `'all'` shows every record (up to `MAX_UNPAGINATED_RECORDS`). */
|
|
1339
|
+
paginationPageOptions(options: (number | 'all')[]): this;
|
|
1340
|
+
/** `false`: no pagination, every record is shown (up to `MAX_UNPAGINATED_RECORDS`). An array sets the page options. */
|
|
1341
|
+
paginated(condition?: boolean | (number | 'all')[]): this;
|
|
1342
|
+
isPaginated(): boolean;
|
|
1343
|
+
/** Heading of the empty state, instead of "No <records>". */
|
|
1344
|
+
emptyStateHeading(heading: string | (() => string) | null): this;
|
|
1345
|
+
emptyStateDescription(description: string | (() => string | null) | null): this;
|
|
1346
|
+
emptyStateIcon(icon: string | null): this;
|
|
1347
|
+
/** Actions shown in the empty state, e.g. a create action. They are mounted like table header actions. */
|
|
1348
|
+
emptyStateActions(actions: any[]): this;
|
|
1349
|
+
getEmptyStateActions(): any[];
|
|
1350
|
+
/** Replaces the whole empty state with your HTML (inserted as it is: escape your data with `e()`). */
|
|
1351
|
+
emptyState(html: string | (() => string | Promise<string>) | null): this;
|
|
1352
|
+
getEmptyStateHeading(): string;
|
|
1353
|
+
getEmptyStateDescription(): string | null;
|
|
1354
|
+
getEmptyStateIcon(): string;
|
|
1355
|
+
getCustomEmptyState(): Promise<string | null>;
|
|
688
1356
|
private _defaultPageOption;
|
|
689
1357
|
/** Rows per page when the table opens. */
|
|
690
|
-
defaultPaginationPageOption(option: number | null): this;
|
|
691
|
-
getDefaultPageOption(): number;
|
|
1358
|
+
defaultPaginationPageOption(option: number | 'all' | null): this;
|
|
1359
|
+
getDefaultPageOption(): number | 'all';
|
|
692
1360
|
private _paginationMode;
|
|
693
1361
|
/** `'simple'`: previous / next buttons only, without page numbers or total. */
|
|
694
1362
|
paginationMode(mode: 'default' | 'simple'): this;
|
|
@@ -703,7 +1371,7 @@ export declare class Table<R = any> {
|
|
|
703
1371
|
direction: SortDirection;
|
|
704
1372
|
} | null;
|
|
705
1373
|
getRecordUrl(record: R): string | null;
|
|
706
|
-
getPageOptions(): number[];
|
|
1374
|
+
getPageOptions(): (number | 'all')[];
|
|
707
1375
|
isStackedOnMobile(): boolean;
|
|
708
1376
|
getPluralModelLabel(): string;
|
|
709
1377
|
hasToggleableColumns(): boolean;
|
|
@@ -717,7 +1385,7 @@ export interface TableHost {
|
|
|
717
1385
|
tableSearch: string;
|
|
718
1386
|
tableSort: string | null;
|
|
719
1387
|
tableColumnSearches: Record<string, string>;
|
|
720
|
-
tableRecordsPerPage: number;
|
|
1388
|
+
tableRecordsPerPage: number | 'all';
|
|
721
1389
|
paginators: Record<string, number>;
|
|
722
1390
|
tableFilters?: Record<string, FilterState>;
|
|
723
1391
|
tableColumns?: ColumnState[];
|
|
@@ -749,6 +1417,10 @@ export declare function getFilterIndicators<R>(table: Table<R>, host: TableHost)
|
|
|
749
1417
|
field: string;
|
|
750
1418
|
label: string;
|
|
751
1419
|
}[];
|
|
1420
|
+
/** Whether an applied filter can be removed: none of its indicators is marked `removable(false)`. */
|
|
1421
|
+
export declare function isTableFilterRemovable<R>(table: Table<R>, host: TableHost, filterName: string): Promise<boolean>;
|
|
1422
|
+
/** Keys whose record passes `checkIfRecordIsSelectableUsing()`, loaded in chunks. Without a check, the keys are returned as they are. */
|
|
1423
|
+
export declare function filterSelectableKeys<R>(table: Table<R>, adapter: Pick<DataAdapter<R>, 'find'>, keys: string[], chunkSize?: number): Promise<string[]>;
|
|
752
1424
|
/** Cycles a column's sort: none → asc → desc → none. */
|
|
753
1425
|
export declare function sortTable(host: TableHost, column?: string | null, direction?: string | null): void;
|
|
754
1426
|
/** Loads the page of records matching the host's state. */
|
|
@@ -774,6 +1446,10 @@ export type RenderTableOptions<R> = {
|
|
|
774
1446
|
after?: string;
|
|
775
1447
|
/** Already rendered HTML of the table header actions. */
|
|
776
1448
|
headerActions?: string[];
|
|
1449
|
+
/** Already rendered HTML of the toolbar actions. */
|
|
1450
|
+
toolbarActions?: string[];
|
|
1451
|
+
/** Already rendered HTML of the empty state actions. */
|
|
1452
|
+
emptyStateActions?: string[];
|
|
777
1453
|
/** Already rendered HTML of the row actions (ActionGroup…), replacing the `rowActions` links. */
|
|
778
1454
|
rowActionsHtml?: (record: R) => Promise<string>;
|
|
779
1455
|
bulkActions?: string[];
|