@lavalogic/scoria 0.37.4 → 0.37.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.
|
@@ -125,6 +125,7 @@ export function createColumnFactory() {
|
|
|
125
125
|
id: opts.id,
|
|
126
126
|
...commonProps(opts),
|
|
127
127
|
accessorFn: opts.accessor,
|
|
128
|
+
getDisplayValue: opts.getDisplayValue,
|
|
128
129
|
filterValueType: FilterValueType.String,
|
|
129
130
|
});
|
|
130
131
|
return makeSpec('text', def, {
|
|
@@ -137,6 +138,7 @@ export function createColumnFactory() {
|
|
|
137
138
|
id: opts.id,
|
|
138
139
|
...commonProps(opts),
|
|
139
140
|
accessorFn: opts.accessor,
|
|
141
|
+
getDisplayValue: opts.getDisplayValue,
|
|
140
142
|
min: opts.min ?? Number.MIN_SAFE_INTEGER,
|
|
141
143
|
max: opts.max ?? Number.MAX_SAFE_INTEGER,
|
|
142
144
|
filterValueType: FilterValueType.Number,
|
|
@@ -151,6 +153,7 @@ export function createColumnFactory() {
|
|
|
151
153
|
id: opts.id,
|
|
152
154
|
...commonProps(opts),
|
|
153
155
|
accessorFn: opts.accessor,
|
|
156
|
+
getDisplayValue: opts.getDisplayValue,
|
|
154
157
|
filterValueType: FilterValueType.Bool,
|
|
155
158
|
});
|
|
156
159
|
return makeSpec('checkbox', def, {
|
|
@@ -163,6 +166,7 @@ export function createColumnFactory() {
|
|
|
163
166
|
id: opts.id,
|
|
164
167
|
...commonProps(opts),
|
|
165
168
|
accessorFn: opts.accessor,
|
|
169
|
+
getDisplayValue: opts.getDisplayValue,
|
|
166
170
|
showTime: opts.withTime ?? false,
|
|
167
171
|
filterValueType: FilterValueType.Date,
|
|
168
172
|
});
|
|
@@ -197,8 +201,12 @@ export function createColumnFactory() {
|
|
|
197
201
|
id: opts.id,
|
|
198
202
|
...commonProps(opts),
|
|
199
203
|
accessorFn: opts.accessor,
|
|
200
|
-
query
|
|
201
|
-
|
|
204
|
+
// Forward the row to the consumer's query callback so it
|
|
205
|
+
// may scope results by row-level context (e.g. a `pod`
|
|
206
|
+
// query filtered by `row.warehouse_id`). Index dropped on
|
|
207
|
+
// the public surface but available internally.
|
|
208
|
+
query: (queryString, item) => opts
|
|
209
|
+
.query(queryString, item)
|
|
202
210
|
.then((res) => res),
|
|
203
211
|
getDisplayValue: opts.getDisplayValue ?? ((row) => String(row[opts.id] ?? '')),
|
|
204
212
|
filterValueType: FilterValueType.Select,
|
|
@@ -211,6 +219,9 @@ export function createColumnFactory() {
|
|
|
211
219
|
// ─── Display kinds ──────────────────────────────────────────
|
|
212
220
|
display(opts) {
|
|
213
221
|
const id = mintSyntheticId('display', opts.idHint);
|
|
222
|
+
const normalisedOptions = opts.getOptions
|
|
223
|
+
? normaliseOptionsLoader(opts.getOptions)
|
|
224
|
+
: undefined;
|
|
214
225
|
const def = new DisplayDef({
|
|
215
226
|
id,
|
|
216
227
|
...commonProps(opts),
|
|
@@ -221,6 +232,8 @@ export function createColumnFactory() {
|
|
|
221
232
|
// column kind). Consumers opt in by passing the type they
|
|
222
233
|
// want the filter input rendered as.
|
|
223
234
|
filterValueType: opts.filterValueType,
|
|
235
|
+
getSortingFn: opts.getSortingFn,
|
|
236
|
+
getOptions: normalisedOptions,
|
|
224
237
|
});
|
|
225
238
|
return makeSpec('display', def);
|
|
226
239
|
},
|
|
@@ -285,13 +298,20 @@ export function createColumnFactory() {
|
|
|
285
298
|
return makeSpec('rowSelection', def);
|
|
286
299
|
},
|
|
287
300
|
actions(opts) {
|
|
288
|
-
const wrapped = opts.actions.map((action) =>
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
301
|
+
const wrapped = opts.actions.map((action) => {
|
|
302
|
+
// `label` may be a literal string or a `(row) => string |
|
|
303
|
+
// Promise<string>` function. The internal Def expects a
|
|
304
|
+
// `getLabel(item, index)` so wrap accordingly.
|
|
305
|
+
const labelOption = action.label;
|
|
306
|
+
const getLabel = typeof labelOption === 'function' ? (item) => labelOption(item) : () => labelOption;
|
|
307
|
+
return {
|
|
308
|
+
getLabel,
|
|
309
|
+
callback: (row) => {
|
|
310
|
+
void action.callback(row);
|
|
311
|
+
},
|
|
312
|
+
colourSet: action.colourSet,
|
|
313
|
+
};
|
|
314
|
+
});
|
|
295
315
|
const isEnabledFn = opts.isEnabled;
|
|
296
316
|
const def = new ActionsDef({
|
|
297
317
|
actions: wrapped,
|
|
@@ -316,9 +336,14 @@ export function createColumnFactory() {
|
|
|
316
336
|
accessorFn: opts.childRows,
|
|
317
337
|
headerIcon: opts.headerIcon ?? 'chevron-down',
|
|
318
338
|
innerTableName: scoriaStorageKey(opts.name),
|
|
319
|
-
getInnerColumnDefs: () => {
|
|
339
|
+
getInnerColumnDefs: (row, index) => {
|
|
340
|
+
// `childColumns` receives the outer row + index so the
|
|
341
|
+
// inner column set may branch per row (pick-wave-subtype
|
|
342
|
+
// drill-downs, for example). Outer-row args are optional
|
|
343
|
+
// at the consumer site, so closures that ignore them
|
|
344
|
+
// continue working unchanged.
|
|
320
345
|
const innerFactory = createColumnFactory();
|
|
321
|
-
const innerSpecs = opts.childColumns(innerFactory);
|
|
346
|
+
const innerSpecs = opts.childColumns(innerFactory, row, index);
|
|
322
347
|
const innerDefs = innerSpecs.map((spec) => unwrapColumnSpec(spec).def);
|
|
323
348
|
return { defs: innerDefs };
|
|
324
349
|
},
|
|
@@ -40,6 +40,14 @@ export interface TextColumnOptions<TRow extends object, K extends StringKeyOf<TR
|
|
|
40
40
|
id: K;
|
|
41
41
|
/** Reads the cell value from the row. Defaults to `row[id]`. */
|
|
42
42
|
accessor?: (row: TRow, index: number) => TRow[K] | Promise<TRow[K]>;
|
|
43
|
+
/** Renders a different value in the cell while the underlying field
|
|
44
|
+
* (and therefore the typed filter / sort / edit input) remains
|
|
45
|
+
* `row[id]`. Useful for foreign-key columns where the cell shows a
|
|
46
|
+
* resolved name but the column's identity stays the typed field
|
|
47
|
+
* (e.g. `id: 'userName'` but the cell wants to render
|
|
48
|
+
* "{firstName} {lastName}" instead). Returns `null` to fall back to
|
|
49
|
+
* the accessor / default. */
|
|
50
|
+
getDisplayValue?: (row: TRow, index: number) => string | null | Promise<string | null>;
|
|
43
51
|
/** Placeholder shown in the edit input when the cell is empty. */
|
|
44
52
|
placeholder?: string;
|
|
45
53
|
/** Maximum input length. */
|
|
@@ -61,6 +69,11 @@ export interface TextColumnOptions<TRow extends object, K extends StringKeyOf<TR
|
|
|
61
69
|
export interface NumberColumnOptions<TRow extends object, K extends NumberKeyOf<TRow>> extends BaseColumnOptions {
|
|
62
70
|
id: K;
|
|
63
71
|
accessor?: (row: TRow, index: number) => TRow[K] | Promise<TRow[K]>;
|
|
72
|
+
/** See `TextColumnOptions.getDisplayValue`. Common use: render
|
|
73
|
+
* placeholder text like "Already Held" / "Already Released" in
|
|
74
|
+
* non-editable cells while the underlying numeric field still drives
|
|
75
|
+
* the typed filter UI. */
|
|
76
|
+
getDisplayValue?: (row: TRow, index: number) => string | null | Promise<string | null>;
|
|
64
77
|
/** Lower bound. The edit input enforces; values outside resolve as invalid. */
|
|
65
78
|
min?: number;
|
|
66
79
|
/** Upper bound. */
|
|
@@ -78,6 +91,8 @@ export interface NumberColumnOptions<TRow extends object, K extends NumberKeyOf<
|
|
|
78
91
|
export interface CheckboxColumnOptions<TRow extends object, K extends BooleanKeyOf<TRow>> extends BaseColumnOptions {
|
|
79
92
|
id: K;
|
|
80
93
|
accessor?: (row: TRow, index: number) => TRow[K] | Promise<TRow[K]>;
|
|
94
|
+
/** See `TextColumnOptions.getDisplayValue`. */
|
|
95
|
+
getDisplayValue?: (row: TRow, index: number) => string | null | Promise<string | null>;
|
|
81
96
|
isEditable?: (row: TRow, index: number) => boolean | Promise<boolean>;
|
|
82
97
|
onEdit?: (row: TRow, value: TRow[K], coords: CellCoordinates) => void | Promise<void>;
|
|
83
98
|
reactiveDependencies?: (row: TRow) => ReadonlyArray<unknown>;
|
|
@@ -86,6 +101,8 @@ export interface CheckboxColumnOptions<TRow extends object, K extends BooleanKey
|
|
|
86
101
|
export interface DateColumnOptions<TRow extends object, K extends DateKeyOf<TRow>> extends BaseColumnOptions {
|
|
87
102
|
id: K;
|
|
88
103
|
accessor?: (row: TRow, index: number) => TRow[K] | Promise<TRow[K]>;
|
|
104
|
+
/** See `TextColumnOptions.getDisplayValue`. */
|
|
105
|
+
getDisplayValue?: (row: TRow, index: number) => string | null | Promise<string | null>;
|
|
89
106
|
/** Whether the time component is editable. Defaults to false (date-only). */
|
|
90
107
|
withTime?: boolean;
|
|
91
108
|
isValid?: ValidationFn<TRow>;
|
|
@@ -113,9 +130,12 @@ export interface SelectColumnOptions<TRow extends object, K extends keyof TRow &
|
|
|
113
130
|
/** Options for `col.query({ id, header, query, ... })`. */
|
|
114
131
|
export interface QueryColumnOptions<TRow extends object, K extends keyof TRow & string, TValue = TRow[K]> extends BaseColumnOptions {
|
|
115
132
|
id: K;
|
|
116
|
-
/** Async query loader;
|
|
117
|
-
*
|
|
118
|
-
|
|
133
|
+
/** Async query loader; receives the current user input and the row
|
|
134
|
+
* being edited so the result set may depend on row-level context
|
|
135
|
+
* (e.g. a `pod` query scoped by the row's `warehouse_id`). The `row`
|
|
136
|
+
* argument is optional at the consumer site - `(input) => ...`
|
|
137
|
+
* callbacks continue working unchanged. */
|
|
138
|
+
query: (input: string, row: TRow) => Promise<ReadonlyArray<SelectOption<TValue>>>;
|
|
119
139
|
accessor?: (row: TRow, index: number) => TValue | Promise<TValue>;
|
|
120
140
|
getDisplayValue?: (row: TRow, index: number) => string | null | Promise<string | null>;
|
|
121
141
|
isValid?: ValidationFn<TRow>;
|
|
@@ -148,6 +168,22 @@ export interface DisplayColumnOptions<TRow extends object, TValue = unknown> ext
|
|
|
148
168
|
* id matching the server field name).
|
|
149
169
|
*/
|
|
150
170
|
filterValueType?: FilterValueType;
|
|
171
|
+
/**
|
|
172
|
+
* Per-column sort comparator. Returns a `(a, b) => 1 | -1 | 0` for the
|
|
173
|
+
* given direction. Useful when the displayed `value` derives from a
|
|
174
|
+
* different field than the server would sort on, or when the value
|
|
175
|
+
* needs a non-default ordering (e.g. status enum ranked by workflow
|
|
176
|
+
* stage rather than alphabetically). Defaults to a generic
|
|
177
|
+
* `value`-derived comparator.
|
|
178
|
+
*/
|
|
179
|
+
getSortingFn?: (desc: boolean) => (a: TRow, b: TRow) => 1 | -1 | 0;
|
|
180
|
+
/**
|
|
181
|
+
* Option list for `filterValueType: 'Select'`. Drives the filter row's
|
|
182
|
+
* dropdown contents. Returning a `Promise` lets consumers fetch
|
|
183
|
+
* options lazily on first read. Has no effect for non-Select filter
|
|
184
|
+
* types.
|
|
185
|
+
*/
|
|
186
|
+
getOptions?: () => ReadonlyArray<SelectOption<TValue>> | Promise<ReadonlyArray<SelectOption<TValue>>>;
|
|
151
187
|
}
|
|
152
188
|
/** Options for `col.bubble({ header, value, colour, ... })`. Renders one or
|
|
153
189
|
* more coloured pill bubbles per row. */
|
|
@@ -216,7 +252,14 @@ export interface ActionsColumnOptions<TRow extends object> extends Omit<BaseColu
|
|
|
216
252
|
}
|
|
217
253
|
/** Single row-action entry. */
|
|
218
254
|
export interface RowAction<TRow extends object> {
|
|
219
|
-
|
|
255
|
+
/**
|
|
256
|
+
* Button label. May be a literal string, or a function that derives the
|
|
257
|
+
* label from the row (sync or async). Use the function form when the
|
|
258
|
+
* same action button should render different text per row (e.g. a
|
|
259
|
+
* combined "View / Edit" button whose label flips based on the row's
|
|
260
|
+
* editable state).
|
|
261
|
+
*/
|
|
262
|
+
label: string | ((row: TRow) => string | Promise<string>);
|
|
220
263
|
icon?: string;
|
|
221
264
|
colourSet?: ColourSet;
|
|
222
265
|
/** Invoked when the action is clicked. Receives the row. */
|
|
@@ -278,9 +321,19 @@ export interface ExpandColumnOptions<TRow extends object, TInner extends object,
|
|
|
278
321
|
* shape on `CreateTableOptions` so callers can use the same
|
|
279
322
|
* shorthand at every nesting level. */
|
|
280
323
|
childRowId: (keyof TInner & string) | ((inner: TInner) => TInnerId | Promise<TInnerId>);
|
|
281
|
-
/**
|
|
282
|
-
*
|
|
283
|
-
|
|
324
|
+
/**
|
|
325
|
+
* Inner column declarations. Builder closure receives a typed
|
|
326
|
+
* `ColumnFactory<TInner>` plus the outer row and its index, so the inner
|
|
327
|
+
* column set may branch per-row (e.g. a pick-wave subtype that shows
|
|
328
|
+
* shipment lines for shipment-typed waves and job lines for job-typed
|
|
329
|
+
* waves). The outer row + index arguments are optional at the consumer
|
|
330
|
+
* site - existing `(col) => [...]` closures continue to compile.
|
|
331
|
+
*
|
|
332
|
+
* Called per expansion, so the closure may safely read row-specific
|
|
333
|
+
* state. Returned `ColumnSpec` arrays are NOT cached between expansions
|
|
334
|
+
* - return shape may differ per call.
|
|
335
|
+
*/
|
|
336
|
+
childColumns: (col: ColumnFactory<TInner>, row: TRow, index: number) => ReadonlyArray<ColumnSpec<TInner>>;
|
|
284
337
|
/**
|
|
285
338
|
* Icon rendered on the per-row expand toggle button. Defaults to
|
|
286
339
|
* `'chevron-down'`. Useful when the parent context needs a richer
|
|
@@ -52,13 +52,23 @@ export interface SelectionApi<TRow extends object, TRowId extends Primitive> {
|
|
|
52
52
|
export interface FilteringApi<TRow extends object> {
|
|
53
53
|
/** Current column-filter state. Reactive. */
|
|
54
54
|
readonly state: ColumnFiltersState;
|
|
55
|
-
/**
|
|
56
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Set or clear the filter for a single column.
|
|
57
|
+
*
|
|
58
|
+
* `columnId` accepts any string so consumers may filter on synthetic
|
|
59
|
+
* display-column ids, nested-path filter ids, and `col.filterOnly`
|
|
60
|
+
* server-only ids (all of which are not `keyof TRow`). Typed callers
|
|
61
|
+
* that pass a row key keep their narrowed inference.
|
|
62
|
+
*/
|
|
63
|
+
set(columnId: (keyof TRow & string) | string, value: unknown): void;
|
|
57
64
|
/** Reset every column's filter to its default. */
|
|
58
65
|
reset(): void;
|
|
59
|
-
/**
|
|
60
|
-
*
|
|
61
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Change the filter mode (e.g. `'contains'` vs `'starts-with'`) for a
|
|
68
|
+
* string column or `'between'` for a number / date column. Same
|
|
69
|
+
* widened `columnId` rules as `set`.
|
|
70
|
+
*/
|
|
71
|
+
setMode(columnId: (keyof TRow & string) | string, mode: FilterMode): void;
|
|
62
72
|
/** Whether the quick-filter input row is visible. */
|
|
63
73
|
showQuickFilter: boolean;
|
|
64
74
|
/** Whether the table is showing only selected rows. */
|