@mmlogic/components 0.2.0 → 0.3.1
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/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/mosterdcomponents.cjs.js +1 -1
- package/dist/cjs/mrd-boolean-field_19.cjs.entry.js +323 -184
- package/dist/collection/components/mrd-layout-section/mrd-layout-section.js +61 -177
- package/dist/collection/components/mrd-table/mrd-table.js +325 -214
- package/dist/collection/dev/api.js +23 -6
- package/dist/collection/dev/app.js +358 -268
- package/dist/components/mrd-layout-section.js +1 -1
- package/dist/components/mrd-table2.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/mosterdcomponents.js +1 -1
- package/dist/esm/mrd-boolean-field_19.entry.js +323 -184
- package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
- package/dist/mosterdcomponents/p-af4c247e.entry.js +1 -0
- package/dist/types/components/mrd-layout-section/mrd-layout-section.d.ts +18 -32
- package/dist/types/components/mrd-table/mrd-table.d.ts +54 -29
- package/dist/types/components.d.ts +42 -88
- package/dist/types/types/client-layout.d.ts +18 -17
- package/package.json +1 -1
- package/dist/mosterdcomponents/p-61ef0232.entry.js +0 -1
|
@@ -22,7 +22,10 @@ export class MrdTable {
|
|
|
22
22
|
this.outsideClickHandler = null;
|
|
23
23
|
this.keydownHandler = null;
|
|
24
24
|
// ── Props ──────────────────────────────────────────────────────────────────
|
|
25
|
-
|
|
25
|
+
/** The VIEW or RELATED_VIEW layout item. Contains view config, dataClass, fromClass, actions etc. */
|
|
26
|
+
this.item = null;
|
|
27
|
+
/** Parent record id — required for RELATED_VIEW to build /{fromClass}/{parentId}/{dataClass}. */
|
|
28
|
+
this.parentId = '';
|
|
26
29
|
/** Direct rows (non-paginated mode, used when totalElements === 0). */
|
|
27
30
|
this.rows = [];
|
|
28
31
|
this.locale = navigator.language;
|
|
@@ -34,16 +37,9 @@ export class MrdTable {
|
|
|
34
37
|
this.rowHeight = 36;
|
|
35
38
|
/** Height of the scroll container in px. */
|
|
36
39
|
this.tableHeight = 500;
|
|
37
|
-
/** Initial sort applied on load, e.g. "timestamp,desc" or "name".
|
|
38
|
-
* Parsed by init() into sortField + sortDir. */
|
|
39
|
-
this.defaultSort = '';
|
|
40
|
-
/** Toolbar action buttons rendered above the table. */
|
|
41
|
-
this.actions = [];
|
|
42
|
-
/** Display label of the current view — shown in the toolbar center as a view picker trigger. */
|
|
43
|
-
this.viewLabel = '';
|
|
44
|
-
/** Alternative views available for this table; renders a dropdown when non-empty. */
|
|
45
|
-
this.alternativeViews = [];
|
|
46
40
|
// ── Internal state ─────────────────────────────────────────────────────────
|
|
41
|
+
/** Index into allViews[] for the currently displayed view. 0 = primary, 1+ = alternatives. */
|
|
42
|
+
this.activeViewIdx = 0;
|
|
47
43
|
this.loadedPages = new Map();
|
|
48
44
|
this.requestedPages = new Set();
|
|
49
45
|
this.renderStart = 0;
|
|
@@ -69,10 +65,16 @@ export class MrdTable {
|
|
|
69
65
|
this.jsonModal = null;
|
|
70
66
|
/** Aggregation totals received from the host via setAggregations(). Null = not yet loaded. */
|
|
71
67
|
this.aggregations = null;
|
|
68
|
+
/** Record count received via setAggregations().total; overrides totalElements for display. */
|
|
69
|
+
this.aggregationsTotal = null;
|
|
70
|
+
/** True when a fresh aggregations request is needed (set on init / filter change). */
|
|
71
|
+
this.aggregationsPending = false;
|
|
72
|
+
/** Lower bound on total derived from setPage() hasNext info; grows as pages load. */
|
|
73
|
+
this.minKnownTotal = 0;
|
|
72
74
|
this.handleScroll = (e) => {
|
|
73
75
|
const scroller = e.currentTarget;
|
|
74
76
|
const scrollTop = scroller.scrollTop;
|
|
75
|
-
const total = this.
|
|
77
|
+
const total = this.baseTotal;
|
|
76
78
|
const visStart = Math.floor(scrollTop / this.rowHeight);
|
|
77
79
|
const visEnd = Math.min(visStart + this.visibleCount(), total - 1);
|
|
78
80
|
this.scrollTop = scrollTop;
|
|
@@ -86,13 +88,16 @@ export class MrdTable {
|
|
|
86
88
|
totalElementsChanged(newVal) {
|
|
87
89
|
this.renderEnd = Math.min(this.renderEnd, Math.max(0, newVal - 1));
|
|
88
90
|
}
|
|
89
|
-
/**
|
|
90
|
-
|
|
91
|
-
|
|
91
|
+
/** Reset to primary view when the item prop is replaced from outside. */
|
|
92
|
+
itemChanged(newVal) {
|
|
93
|
+
var _a, _b;
|
|
94
|
+
this.activeViewIdx = 0;
|
|
95
|
+
this.applyDefaultSort((_b = (_a = newVal === null || newVal === void 0 ? void 0 : newVal.view) === null || _a === void 0 ? void 0 : _a.defaultSort) !== null && _b !== void 0 ? _b : '');
|
|
92
96
|
}
|
|
93
97
|
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
94
98
|
componentWillLoad() {
|
|
95
|
-
|
|
99
|
+
var _a, _b, _c;
|
|
100
|
+
this.applyDefaultSort((_c = (_b = (_a = this.item) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.defaultSort) !== null && _c !== void 0 ? _c : '');
|
|
96
101
|
}
|
|
97
102
|
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
98
103
|
applyDefaultSort(defaultSort) {
|
|
@@ -124,14 +129,19 @@ export class MrdTable {
|
|
|
124
129
|
this.colWidths = [];
|
|
125
130
|
this.scrollTop = 0;
|
|
126
131
|
this.renderStart = 0;
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
this.renderEnd =
|
|
132
|
+
// Always fill the visible viewport on init — totalElements may be stale from a
|
|
133
|
+
// previous view. setPage() clamps renderEnd when the page is shorter than pageSize.
|
|
134
|
+
this.renderEnd = this.visibleCount() - 1;
|
|
130
135
|
const scroller = this.el.querySelector('.mrd-table__scroll');
|
|
131
136
|
if (scroller)
|
|
132
137
|
scroller.scrollTop = 0;
|
|
133
138
|
this.aggregations = null;
|
|
134
|
-
this.
|
|
139
|
+
this.aggregationsTotal = null;
|
|
140
|
+
this.aggregationsPending = true;
|
|
141
|
+
this.minKnownTotal = 0;
|
|
142
|
+
// Always request page 0 — totalElements may be unknown (0) on first load.
|
|
143
|
+
this.mrdLoadPage.emit({ page: 0, sort: this.sortParam(), path: this.buildDataPath(), qs: this.buildQueryParams(0) });
|
|
144
|
+
this.requestedPages = new Set([0]);
|
|
135
145
|
}
|
|
136
146
|
/**
|
|
137
147
|
* Inject the rows for a given page (0-based).
|
|
@@ -140,20 +150,41 @@ export class MrdTable {
|
|
|
140
150
|
* When the page contains fewer rows than pageSize it is the last page.
|
|
141
151
|
* renderEnd is clamped immediately so no loading-placeholder rows appear
|
|
142
152
|
* beyond the actual data — without requiring the host to update totalElements.
|
|
153
|
+
*
|
|
154
|
+
* Pass hasNext (from _links.next in the API response) for accurate last-page
|
|
155
|
+
* detection even when rows.length === pageSize (exact multiple of page size).
|
|
143
156
|
*/
|
|
144
|
-
async setPage(pageNumber, rows) {
|
|
145
|
-
|
|
157
|
+
async setPage(pageNumber, rows, hasNext) {
|
|
158
|
+
const isLastPage = hasNext !== undefined ? !hasNext : rows.length < this.pageSize;
|
|
159
|
+
if (isLastPage) {
|
|
146
160
|
// lastRowIdx is -1 when the page is empty; clamp renderEnd to -1 so the
|
|
147
161
|
// render loop does not execute and no shimmer rows appear.
|
|
148
162
|
const lastRowIdx = pageNumber * this.pageSize + rows.length - 1;
|
|
149
163
|
this.renderEnd = Math.min(this.renderEnd, lastRowIdx);
|
|
164
|
+
// Exact total is known: update minKnownTotal so the scroll container has the right height.
|
|
165
|
+
this.minKnownTotal = pageNumber * this.pageSize + rows.length;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
// There is at least one more page — ensure the scrollbar covers at least that next page.
|
|
169
|
+
this.minKnownTotal = Math.max(this.minKnownTotal, (pageNumber + 1) * this.pageSize + 1);
|
|
150
170
|
}
|
|
151
171
|
const next = new Map(this.loadedPages);
|
|
152
172
|
next.set(pageNumber, rows);
|
|
153
173
|
this.loadedPages = next;
|
|
174
|
+
if (pageNumber === 0 && this.aggregationsPending) {
|
|
175
|
+
this.aggregationsPending = false;
|
|
176
|
+
const hasAggColumns = this.columns.some(c => c.type === 'FIELD' && c.aggregate);
|
|
177
|
+
if (!isLastPage || hasAggColumns) {
|
|
178
|
+
this.emitLoadAggregations();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
154
181
|
}
|
|
155
182
|
/** Inject aggregation totals returned by the /aggregations endpoint. */
|
|
156
183
|
async setAggregations(data) {
|
|
184
|
+
var _a;
|
|
185
|
+
const total = (_a = data.total) !== null && _a !== void 0 ? _a : (typeof data.count === 'number' ? data.count : undefined);
|
|
186
|
+
if (total != null)
|
|
187
|
+
this.aggregationsTotal = total;
|
|
157
188
|
this.aggregations = data;
|
|
158
189
|
}
|
|
159
190
|
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
@@ -184,6 +215,147 @@ export class MrdTable {
|
|
|
184
215
|
return '';
|
|
185
216
|
return this.sortDir === 'desc' ? `${this.sortField},desc` : this.sortField;
|
|
186
217
|
}
|
|
218
|
+
/** Stable ordered list: primary view first, then alternatives (from the item prop). */
|
|
219
|
+
get allViews() {
|
|
220
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
221
|
+
if (!this.item)
|
|
222
|
+
return [];
|
|
223
|
+
const it = this.item;
|
|
224
|
+
return [
|
|
225
|
+
{ label: (_e = (_d = (_c = (_a = it.label) !== null && _a !== void 0 ? _a : (_b = it.view) === null || _b === void 0 ? void 0 : _b.pluralLabel) !== null && _c !== void 0 ? _c : it.dataClass) !== null && _d !== void 0 ? _d : it.relatedClass) !== null && _e !== void 0 ? _e : '', dataClass: (_f = it.dataClass) !== null && _f !== void 0 ? _f : it.relatedClass, fromClass: it.fromClass, filterClass: it.filterClass, view: it.view },
|
|
226
|
+
...((_g = it.alternativeViews) !== null && _g !== void 0 ? _g : []).map(av => {
|
|
227
|
+
var _a, _b, _c, _d;
|
|
228
|
+
return ({
|
|
229
|
+
label: (_d = (_c = (_a = av.label) !== null && _a !== void 0 ? _a : (_b = av.view) === null || _b === void 0 ? void 0 : _b.pluralLabel) !== null && _c !== void 0 ? _c : av.dataClass) !== null && _d !== void 0 ? _d : '',
|
|
230
|
+
dataClass: av.dataClass,
|
|
231
|
+
fromClass: av.fromClass,
|
|
232
|
+
filterClass: av.filterClass,
|
|
233
|
+
view: av.view,
|
|
234
|
+
});
|
|
235
|
+
}),
|
|
236
|
+
];
|
|
237
|
+
}
|
|
238
|
+
/** Relative excel export path for the current view.
|
|
239
|
+
* VIEW: /excel/{dataClass}
|
|
240
|
+
* RELATED_VIEW: /excel/{fromClass}/{parentId}/{dataClass} */
|
|
241
|
+
buildExcelPath() {
|
|
242
|
+
var _a, _b, _c, _d;
|
|
243
|
+
const v = this.allViews[this.activeViewIdx];
|
|
244
|
+
if (!v)
|
|
245
|
+
return '';
|
|
246
|
+
if (((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'RELATED_VIEW') {
|
|
247
|
+
return `/excel/${(_b = v.fromClass) !== null && _b !== void 0 ? _b : ''}/${this.parentId}/${(_c = v.dataClass) !== null && _c !== void 0 ? _c : ''}`;
|
|
248
|
+
}
|
|
249
|
+
return `/excel/${(_d = v.dataClass) !== null && _d !== void 0 ? _d : ''}`;
|
|
250
|
+
}
|
|
251
|
+
buildActionDetail(action) {
|
|
252
|
+
var _a, _b, _c;
|
|
253
|
+
if (action === 'export') {
|
|
254
|
+
return { action, path: this.buildExcelPath(), qs: this.buildQueryParams(0) };
|
|
255
|
+
}
|
|
256
|
+
if (action === 'create') {
|
|
257
|
+
const v = this.allViews[this.activeViewIdx];
|
|
258
|
+
const parentPath = ((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'RELATED_VIEW'
|
|
259
|
+
? `/${(_b = v === null || v === void 0 ? void 0 : v.fromClass) !== null && _b !== void 0 ? _b : ''}/${this.parentId}`
|
|
260
|
+
: null;
|
|
261
|
+
return { action, dataClass: (_c = v === null || v === void 0 ? void 0 : v.dataClass) !== null && _c !== void 0 ? _c : '', parentPath };
|
|
262
|
+
}
|
|
263
|
+
return { action };
|
|
264
|
+
}
|
|
265
|
+
/** Relative data path for the current view, without query string.
|
|
266
|
+
* VIEW: /{dataClass}
|
|
267
|
+
* RELATED_VIEW: /{fromClass}/{parentId}/{dataClass} */
|
|
268
|
+
buildDataPath() {
|
|
269
|
+
var _a, _b, _c, _d;
|
|
270
|
+
const v = this.allViews[this.activeViewIdx];
|
|
271
|
+
if (!v)
|
|
272
|
+
return '';
|
|
273
|
+
if (((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'RELATED_VIEW') {
|
|
274
|
+
return `/${(_b = v.fromClass) !== null && _b !== void 0 ? _b : ''}/${this.parentId}/${(_c = v.dataClass) !== null && _c !== void 0 ? _c : ''}`;
|
|
275
|
+
}
|
|
276
|
+
return `/${(_d = v.dataClass) !== null && _d !== void 0 ? _d : ''}`;
|
|
277
|
+
}
|
|
278
|
+
/** Build query params for a page request from current sort, view filters, filterClass and active column filters. */
|
|
279
|
+
buildQueryParams(page) {
|
|
280
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
281
|
+
const v = this.allViews[this.activeViewIdx];
|
|
282
|
+
const p = new URLSearchParams();
|
|
283
|
+
if (page > 0)
|
|
284
|
+
p.set('page', String(page));
|
|
285
|
+
const sort = this.sortParam();
|
|
286
|
+
if (sort)
|
|
287
|
+
p.set('sort', sort);
|
|
288
|
+
const filterClass = v === null || v === void 0 ? void 0 : v.filterClass;
|
|
289
|
+
if (filterClass)
|
|
290
|
+
p.set('type', filterClass);
|
|
291
|
+
for (const f of ((_b = (_a = v === null || v === void 0 ? void 0 : v.view) === null || _a === void 0 ? void 0 : _a.filter) !== null && _b !== void 0 ? _b : [])) {
|
|
292
|
+
if (!f.name)
|
|
293
|
+
continue;
|
|
294
|
+
if (f.operator === 'EMPTY') {
|
|
295
|
+
p.set(f.name, '');
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
if (f.operator === 'NOT_EMPTY') {
|
|
299
|
+
p.set(f.name + '_notempty', 'true');
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
if (f.operator === 'STARTS_WITH') {
|
|
303
|
+
p.set(f.name + '_startswith', String((_c = f.value) !== null && _c !== void 0 ? _c : ''));
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
if (f.operator === 'FROM') {
|
|
307
|
+
p.set(f.name + '_from', String((_d = f.value) !== null && _d !== void 0 ? _d : ''));
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
if (f.operator === 'TO') {
|
|
311
|
+
p.set(f.name + '_to', String((_e = f.value) !== null && _e !== void 0 ? _e : ''));
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (f.value != null) {
|
|
315
|
+
p.set(f.name, String(f.value));
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
for (const f of this.activeFilters.values()) {
|
|
319
|
+
if (f.operator === 'isEmpty') {
|
|
320
|
+
p.set(f.field, '');
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
if (f.operator === 'isNotEmpty') {
|
|
324
|
+
p.set(f.field + '_notempty', 'true');
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (f.operator === 'startsWith') {
|
|
328
|
+
p.set(f.field + '_startswith', String((_f = f.value) !== null && _f !== void 0 ? _f : ''));
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
if ((_g = f.values) === null || _g === void 0 ? void 0 : _g.length) {
|
|
332
|
+
p.set(f.field, f.values.join(','));
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
if (f.value != null)
|
|
336
|
+
p.set(f.field, String(f.value));
|
|
337
|
+
if (f.from != null)
|
|
338
|
+
p.set(f.field + '_from', String(f.from));
|
|
339
|
+
if (f.to != null)
|
|
340
|
+
p.set(f.field + '_to', String(f.to));
|
|
341
|
+
}
|
|
342
|
+
return p.toString();
|
|
343
|
+
}
|
|
344
|
+
get columns() {
|
|
345
|
+
var _a, _b, _c;
|
|
346
|
+
return ((_c = (_b = (_a = this.allViews[this.activeViewIdx]) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.values) !== null && _c !== void 0 ? _c : []);
|
|
347
|
+
}
|
|
348
|
+
get tableActions() {
|
|
349
|
+
var _a, _b;
|
|
350
|
+
const raw = (_b = (_a = this.item) === null || _a === void 0 ? void 0 : _a.actions) !== null && _b !== void 0 ? _b : [];
|
|
351
|
+
return (raw !== null && raw !== void 0 ? raw : []).reduce((acc, a) => {
|
|
352
|
+
if (a === 'NEW')
|
|
353
|
+
acc.push({ action: 'create', label: t('table_new_record', this.locale), icon: 'assets/sprites.svg#icon-plus', variant: 'primary' });
|
|
354
|
+
if (a === 'EXPORT')
|
|
355
|
+
acc.push({ action: 'export', label: t('table_export_excel', this.locale), icon: 'assets/sprites.svg#icon-file-excel' });
|
|
356
|
+
return acc;
|
|
357
|
+
}, []);
|
|
358
|
+
}
|
|
187
359
|
colName(col) {
|
|
188
360
|
var _a;
|
|
189
361
|
return (_a = col.name) !== null && _a !== void 0 ? _a : '';
|
|
@@ -194,6 +366,25 @@ export class MrdTable {
|
|
|
194
366
|
return 'RELATION';
|
|
195
367
|
return (_a = col.dataType) !== null && _a !== void 0 ? _a : 'TEXT';
|
|
196
368
|
}
|
|
369
|
+
/** True when we have a reliable total: either from the aggregations response or because
|
|
370
|
+
* a short page told us it was the last page (exact count from row length). */
|
|
371
|
+
isTotalKnown() {
|
|
372
|
+
if (this.aggregationsTotal != null)
|
|
373
|
+
return true;
|
|
374
|
+
for (const rows of this.loadedPages.values()) {
|
|
375
|
+
if (rows.length < this.pageSize)
|
|
376
|
+
return true;
|
|
377
|
+
}
|
|
378
|
+
return false;
|
|
379
|
+
}
|
|
380
|
+
/** Effective total: aggregations-response > totalElements prop > minKnownTotal from setPage(). */
|
|
381
|
+
get baseTotal() {
|
|
382
|
+
if (this.aggregationsTotal != null)
|
|
383
|
+
return this.aggregationsTotal;
|
|
384
|
+
if (this.totalElements > 0)
|
|
385
|
+
return this.totalElements;
|
|
386
|
+
return this.minKnownTotal;
|
|
387
|
+
}
|
|
197
388
|
// ── Aggregation helpers ────────────────────────────────────────────────────
|
|
198
389
|
buildAggregationParams() {
|
|
199
390
|
var _a;
|
|
@@ -214,17 +405,32 @@ export class MrdTable {
|
|
|
214
405
|
params.count = groups.count;
|
|
215
406
|
return Object.keys(params).length > 0 ? params : null;
|
|
216
407
|
}
|
|
408
|
+
buildAggregationQs() {
|
|
409
|
+
var _a, _b, _c;
|
|
410
|
+
const p = new URLSearchParams(this.buildQueryParams(0));
|
|
411
|
+
p.delete('page');
|
|
412
|
+
p.delete('sort');
|
|
413
|
+
const groups = this.buildAggregationParams();
|
|
414
|
+
if ((_a = groups === null || groups === void 0 ? void 0 : groups.sum) === null || _a === void 0 ? void 0 : _a.length)
|
|
415
|
+
p.set('sum', groups.sum.join(','));
|
|
416
|
+
if ((_b = groups === null || groups === void 0 ? void 0 : groups.avg) === null || _b === void 0 ? void 0 : _b.length)
|
|
417
|
+
p.set('avg', groups.avg.join(','));
|
|
418
|
+
if ((_c = groups === null || groups === void 0 ? void 0 : groups.count) === null || _c === void 0 ? void 0 : _c.length)
|
|
419
|
+
p.set('count', groups.count.join(','));
|
|
420
|
+
return p.toString();
|
|
421
|
+
}
|
|
217
422
|
emitLoadAggregations() {
|
|
218
|
-
|
|
219
|
-
if (params)
|
|
220
|
-
this.mrdLoadAggregations.emit(params);
|
|
423
|
+
this.mrdLoadAggregations.emit({ path: this.buildDataPath(), qs: this.buildQueryParams(0), aggQs: this.buildAggregationQs() });
|
|
221
424
|
}
|
|
222
425
|
renderAggregationValue(col) {
|
|
223
|
-
var _a
|
|
426
|
+
var _a;
|
|
224
427
|
if (col.type !== 'FIELD' || !col.aggregate || !this.aggregations)
|
|
225
428
|
return '';
|
|
226
429
|
const fn = col.aggregate.toLowerCase();
|
|
227
|
-
const
|
|
430
|
+
const aggData = this.aggregations[fn];
|
|
431
|
+
const val = typeof aggData === 'object' && aggData !== null
|
|
432
|
+
? aggData[(_a = col.name) !== null && _a !== void 0 ? _a : '']
|
|
433
|
+
: undefined;
|
|
228
434
|
if (val == null)
|
|
229
435
|
return '';
|
|
230
436
|
const dt = col.dataType;
|
|
@@ -249,9 +455,10 @@ export class MrdTable {
|
|
|
249
455
|
this.colWidths = [];
|
|
250
456
|
this.scrollTop = 0;
|
|
251
457
|
this.renderStart = 0;
|
|
252
|
-
|
|
253
|
-
//
|
|
254
|
-
|
|
458
|
+
this.minKnownTotal = 0;
|
|
459
|
+
// Mirror init(): use visibleCount so the first page is always requested.
|
|
460
|
+
// setPage() will clamp renderEnd down when the last page is shorter.
|
|
461
|
+
this.renderEnd = this.visibleCount() - 1;
|
|
255
462
|
const scroller = this.el.querySelector('.mrd-table__scroll');
|
|
256
463
|
if (scroller)
|
|
257
464
|
scroller.scrollTop = 0;
|
|
@@ -282,7 +489,7 @@ export class MrdTable {
|
|
|
282
489
|
for (let p = firstPage; p <= lastPage; p++) {
|
|
283
490
|
if (!this.loadedPages.has(p) && !next.has(p)) {
|
|
284
491
|
next.add(p);
|
|
285
|
-
this.mrdLoadPage.emit({ page: p, sort: this.sortParam() });
|
|
492
|
+
this.mrdLoadPage.emit({ page: p, sort: this.sortParam(), path: this.buildDataPath(), qs: this.buildQueryParams(p) });
|
|
286
493
|
changed = true;
|
|
287
494
|
}
|
|
288
495
|
}
|
|
@@ -324,7 +531,7 @@ export class MrdTable {
|
|
|
324
531
|
if (pageEnd < this.renderStart || pageStart > this.renderEnd)
|
|
325
532
|
continue;
|
|
326
533
|
next.add(page);
|
|
327
|
-
this.mrdLoadPage.emit({ page, sort: this.sortParam() });
|
|
534
|
+
this.mrdLoadPage.emit({ page, sort: this.sortParam(), path: this.buildDataPath(), qs: this.buildQueryParams(page) });
|
|
328
535
|
changed = true;
|
|
329
536
|
}
|
|
330
537
|
this.pendingPages.clear();
|
|
@@ -516,9 +723,9 @@ export class MrdTable {
|
|
|
516
723
|
}
|
|
517
724
|
this.activeFilters = next;
|
|
518
725
|
this.closeFilterPopup();
|
|
519
|
-
this.mrdFilter.emit({ filters: Array.from(this.activeFilters.values()) });
|
|
520
726
|
this.aggregations = null;
|
|
521
|
-
this.
|
|
727
|
+
this.aggregationsTotal = null;
|
|
728
|
+
this.aggregationsPending = true;
|
|
522
729
|
if (this.totalElements > 0) {
|
|
523
730
|
this.resetPages();
|
|
524
731
|
this.emitPagesForWindow(this.renderStart, this.renderEnd);
|
|
@@ -531,9 +738,9 @@ export class MrdTable {
|
|
|
531
738
|
next.delete(name);
|
|
532
739
|
this.activeFilters = next;
|
|
533
740
|
this.closeFilterPopup();
|
|
534
|
-
this.mrdFilter.emit({ filters: Array.from(this.activeFilters.values()) });
|
|
535
741
|
this.aggregations = null;
|
|
536
|
-
this.
|
|
742
|
+
this.aggregationsTotal = null;
|
|
743
|
+
this.aggregationsPending = true;
|
|
537
744
|
if (this.totalElements > 0) {
|
|
538
745
|
this.resetPages();
|
|
539
746
|
this.emitPagesForWindow(this.renderStart, this.renderEnd);
|
|
@@ -541,37 +748,39 @@ export class MrdTable {
|
|
|
541
748
|
}
|
|
542
749
|
clearAllFilters() {
|
|
543
750
|
this.activeFilters = new Map();
|
|
544
|
-
this.mrdFilter.emit({ filters: [] });
|
|
545
751
|
this.aggregations = null;
|
|
546
|
-
this.
|
|
752
|
+
this.aggregationsTotal = null;
|
|
753
|
+
this.aggregationsPending = true;
|
|
547
754
|
if (this.totalElements > 0) {
|
|
548
755
|
this.resetPages();
|
|
549
756
|
this.emitPagesForWindow(this.renderStart, this.renderEnd);
|
|
550
757
|
}
|
|
551
758
|
}
|
|
552
759
|
// ── View switcher ──────────────────────────────────────────────────────────
|
|
553
|
-
handleViewSwitch(
|
|
554
|
-
|
|
760
|
+
handleViewSwitch(targetIdx) {
|
|
761
|
+
var _a, _b;
|
|
762
|
+
const target = this.allViews[targetIdx];
|
|
763
|
+
if (!(target === null || target === void 0 ? void 0 : target.view))
|
|
764
|
+
return;
|
|
765
|
+
this.activeViewIdx = targetIdx;
|
|
766
|
+
this.applyDefaultSort((_b = (_a = target.view) === null || _a === void 0 ? void 0 : _a.defaultSort) !== null && _b !== void 0 ? _b : '');
|
|
767
|
+
this.activeFilters = new Map();
|
|
768
|
+
this.init();
|
|
555
769
|
}
|
|
556
770
|
// ── Render: toolbar ────────────────────────────────────────────────────────
|
|
557
771
|
renderToolbar() {
|
|
558
|
-
var _a, _b;
|
|
559
772
|
const filterCount = this.activeFilters.size;
|
|
560
|
-
const
|
|
561
|
-
const
|
|
773
|
+
const actions = this.tableActions;
|
|
774
|
+
const allViews = this.allViews;
|
|
775
|
+
const hasActions = actions.length > 0;
|
|
776
|
+
const hasViewSwitcher = allViews.length > 1;
|
|
562
777
|
return (h("div", { class: "mrd-table__toolbar" }, h("div", { class: "mrd-table__toolbar-left" }, h("button", { class: `mrd-table__action mrd-table__action--secondary mrd-table__filter-toggle${this.filterMode ? ' mrd-table__filter-toggle--active' : ''}`, onClick: () => this.handleFilterToggle() }, h("svg", { class: "mrd-table__action-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" })), filterCount > 0 && h("span", { class: "mrd-table__filter-badge" }, filterCount), h("span", { class: "mrd-table__action-tooltip" }, this.filterMode ? t('table_filter_hide', this.locale) : t('table_filter', this.locale), filterCount > 0 ? ` (${filterCount} ${t('table_filter_active', this.locale)})` : '')), filterCount > 0 && (h("button", { class: "mrd-table__action mrd-table__action--secondary", onClick: () => this.clearAllFilters() }, h("svg", { class: "mrd-table__action-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" })), h("span", { class: "mrd-table__action-tooltip" }, t('table_filter_clear_all', this.locale))))), hasViewSwitcher && (h("div", { class: "mrd-table__toolbar-center" }, h("select", { class: "mrd-table__view-select", onChange: (e) => {
|
|
563
|
-
const
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
this.handleViewSwitch(view);
|
|
568
|
-
}
|
|
569
|
-
} }, h("option", { value: "" }, this.viewLabel), this.alternativeViews.map(v => {
|
|
570
|
-
var _a;
|
|
571
|
-
return (h("option", { value: v.name }, (_a = v.label) !== null && _a !== void 0 ? _a : v.name));
|
|
572
|
-
})))), hasActions && (h("div", { class: "mrd-table__toolbar-right" }, this.actions.map(a => {
|
|
778
|
+
const idx = parseInt(e.target.value, 10);
|
|
779
|
+
if (!isNaN(idx) && idx !== this.activeViewIdx)
|
|
780
|
+
this.handleViewSwitch(idx);
|
|
781
|
+
} }, allViews.map((v, i) => (h("option", { value: String(i), selected: i === this.activeViewIdx }, v.label)))))), hasActions && (h("div", { class: "mrd-table__toolbar-right" }, actions.map(a => {
|
|
573
782
|
var _a;
|
|
574
|
-
return (h("button", { class: `mrd-table__action mrd-table__action--${(_a = a.variant) !== null && _a !== void 0 ? _a : 'secondary'}`, disabled: a.disabled, onClick: () => this.mrdAction.emit(
|
|
783
|
+
return (h("button", { class: `mrd-table__action mrd-table__action--${(_a = a.variant) !== null && _a !== void 0 ? _a : 'secondary'}`, disabled: a.disabled, onClick: () => this.mrdAction.emit(this.buildActionDetail(a.action)) }, a.icon
|
|
575
784
|
? h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, h("use", { href: a.icon }))
|
|
576
785
|
: a.label, h("span", { class: "mrd-table__action-tooltip" }, a.label)));
|
|
577
786
|
})))));
|
|
@@ -665,10 +874,9 @@ export class MrdTable {
|
|
|
665
874
|
return (h("div", { class: "mrd-table__filter-popup", style: { top: `${this.popupPos.top}px`, left: `${this.popupPos.left}px` }, onClick: (e) => e.stopPropagation() }, h("div", { class: "mrd-table__filter-popup-header" }, h("span", { class: "mrd-table__filter-popup-title" }, label), h("button", { class: "mrd-table__filter-close", onClick: () => this.closeFilterPopup() }, "\u2715")), h("div", { class: "mrd-table__filter-section" }, h("div", { class: "mrd-table__filter-section-label" }, t('filter_sorting', this.locale)), h("div", { class: "mrd-table__filter-sort-buttons" }, h("button", { class: `mrd-table__filter-sort-btn${sortActive && this.sortDir === 'asc' ? ' mrd-table__filter-sort-btn--active' : ''}`, onClick: () => this.applySort(col, 'asc') }, "\u25B2 ", t('filter_ascending', this.locale)), h("button", { class: `mrd-table__filter-sort-btn${sortActive && this.sortDir === 'desc' ? ' mrd-table__filter-sort-btn--active' : ''}`, onClick: () => this.applySort(col, 'desc') }, "\u25BC ", t('filter_descending', this.locale)))), h("div", { class: "mrd-table__filter-divider" }), h("div", { class: "mrd-table__filter-section" }, h("div", { class: "mrd-table__filter-section-label" }, t('filter_section', this.locale)), this.renderFilterEditor(col)), h("div", { class: "mrd-table__filter-popup-footer" }, h("button", { class: "mrd-table__filter-btn mrd-table__filter-btn--clear", onClick: () => this.clearFilter() }, t('filter_clear', this.locale)), h("button", { class: "mrd-table__filter-btn mrd-table__filter-btn--apply", onClick: () => this.applyFilter() }, t('filter_apply', this.locale)))));
|
|
666
875
|
}
|
|
667
876
|
// ── Render: footer ────────────────────────────────────────────────────────
|
|
668
|
-
renderFooter(rowCount, effectiveTotal) {
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
if (total === 0) {
|
|
877
|
+
renderFooter(rowCount, effectiveTotal, isTotalKnown = true) {
|
|
878
|
+
// Non-paginated mode: totalElements=0 and no paginated data loaded yet
|
|
879
|
+
if (this.totalElements === 0 && this.loadedPages.size === 0) {
|
|
672
880
|
const count = rowCount !== null && rowCount !== void 0 ? rowCount : 0;
|
|
673
881
|
if (count === 0)
|
|
674
882
|
return null;
|
|
@@ -677,13 +885,14 @@ export class MrdTable {
|
|
|
677
885
|
// Paginated mode: only show once page 0 has loaded (avoids stale total during filter reset)
|
|
678
886
|
if (!this.loadedPages.has(0))
|
|
679
887
|
return null;
|
|
680
|
-
//
|
|
681
|
-
|
|
682
|
-
const displayTotal = effectiveTotal !== null && effectiveTotal !== void 0 ? effectiveTotal : total;
|
|
888
|
+
// effectiveTotal from render(); fall back to baseTotal when not provided.
|
|
889
|
+
const displayTotal = effectiveTotal !== null && effectiveTotal !== void 0 ? effectiveTotal : this.baseTotal;
|
|
683
890
|
// Compute from/to independently so partial rows at top/bottom are included.
|
|
684
891
|
const from = Math.min(Math.floor(this.scrollTop / this.rowHeight) + 1, displayTotal);
|
|
685
892
|
const to = Math.min(Math.ceil((this.scrollTop + this.tableHeight) / this.rowHeight), displayTotal);
|
|
686
|
-
|
|
893
|
+
// Show '…' for the total until we have a reliable count (aggregations or last page loaded).
|
|
894
|
+
const totalLabel = isTotalKnown ? String(displayTotal) : '…';
|
|
895
|
+
return (h("div", { class: "mrd-table__footer" }, from, "\u2013", to, " ", t('table_of', this.locale), " ", totalLabel));
|
|
687
896
|
}
|
|
688
897
|
// ── Render: cell ──────────────────────────────────────────────────────────
|
|
689
898
|
renderCell(col, row) {
|
|
@@ -742,7 +951,9 @@ export class MrdTable {
|
|
|
742
951
|
if (!((_a = this.columns) === null || _a === void 0 ? void 0 : _a.length))
|
|
743
952
|
return null;
|
|
744
953
|
// ── Non-paginated mode ──────────────────────────────────────────────────
|
|
745
|
-
|
|
954
|
+
// Only enter non-paginated mode when totalElements is 0 AND no paginated data
|
|
955
|
+
// has been loaded yet — prevents the wrong branch when the host omits totalElements.
|
|
956
|
+
if (this.totalElements === 0 && this.loadedPages.size === 0) {
|
|
746
957
|
return (h(Host, null, this.renderToolbar(), h("div", { class: "mrd-table" }, h("table", { class: "mrd-table__table" }, h("thead", null, h("tr", null, this.columns.map(col => {
|
|
747
958
|
var _a;
|
|
748
959
|
const name = this.colName(col);
|
|
@@ -759,8 +970,8 @@ export class MrdTable {
|
|
|
759
970
|
// Derive the authoritative row count from loaded pages:
|
|
760
971
|
// if any loaded page is shorter than pageSize it is the last page,
|
|
761
972
|
// so the true total cannot exceed (pageNum * pageSize + pageRows.length).
|
|
762
|
-
//
|
|
763
|
-
let effectiveTotal = this.
|
|
973
|
+
// aggregationsTotal (from setAggregations) takes priority over the totalElements prop.
|
|
974
|
+
let effectiveTotal = this.baseTotal;
|
|
764
975
|
for (const [pageNum, pageRows] of this.loadedPages) {
|
|
765
976
|
if (pageRows.length < this.pageSize) {
|
|
766
977
|
effectiveTotal = Math.min(effectiveTotal, pageNum * this.pageSize + pageRows.length);
|
|
@@ -797,7 +1008,7 @@ export class MrdTable {
|
|
|
797
1008
|
isFiltered ? 'mrd-table__header--filtered' : '',
|
|
798
1009
|
].filter(Boolean).join(' ');
|
|
799
1010
|
return (h("th", { class: cls, style: this.colWidths[idx] ? { width: `${this.colWidths[idx]}px` } : undefined, onClick: isInteractive ? ((e) => this.filterMode ? this.handleFilterOpen(col, e) : this.handleSortClick(col)) : undefined }, h("span", { class: "mrd-table__header-label" }, (_a = col.label) !== null && _a !== void 0 ? _a : ''), isInteractive && isActive && (h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, this.sortDir === 'asc' ? '▲' : '▼')), isInteractive && !isActive && !this.filterMode && (h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, "\u21C5")), isInteractive && isFiltered && this.renderFilterIcon()));
|
|
800
|
-
}))), h("tbody", null, topSpacerHeight > 0 && (h("tr", { class: "mrd-table__spacer", style: { height: `${topSpacerHeight}px` } }, h("td", { colSpan: colCount }))), renderedRows, bottomSpacerHeight > 0 && (h("tr", { class: "mrd-table__spacer", style: { height: `${bottomSpacerHeight}px` } }, h("td", { colSpan: colCount })))), this.renderTotalsRow())), effectiveTotal === 0 && this.loadedPages.has(0) && (h("p", { class: "mrd-table__empty" }, t('no_results', this.locale))), effectiveTotal > 0 && this.renderFooter(undefined, effectiveTotal), this.renderFilterPopup(), this.renderTextblockModal()));
|
|
1011
|
+
}))), h("tbody", null, topSpacerHeight > 0 && (h("tr", { class: "mrd-table__spacer", style: { height: `${topSpacerHeight}px` } }, h("td", { colSpan: colCount }))), renderedRows, bottomSpacerHeight > 0 && (h("tr", { class: "mrd-table__spacer", style: { height: `${bottomSpacerHeight}px` } }, h("td", { colSpan: colCount })))), this.renderTotalsRow())), effectiveTotal === 0 && this.loadedPages.has(0) && (h("p", { class: "mrd-table__empty" }, t('no_results', this.locale))), effectiveTotal > 0 && this.renderFooter(undefined, effectiveTotal, this.isTotalKnown()), this.renderFilterPopup(), this.renderTextblockModal()));
|
|
801
1012
|
}
|
|
802
1013
|
renderFilterIcon() {
|
|
803
1014
|
return (h("span", { class: "mrd-table__filter-icon", "aria-hidden": "true" }, h("svg", { viewBox: "0 0 24 24", width: "14", height: "14", fill: "currentColor" }, h("path", { d: "M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" }))));
|
|
@@ -826,18 +1037,18 @@ export class MrdTable {
|
|
|
826
1037
|
}
|
|
827
1038
|
static get properties() {
|
|
828
1039
|
return {
|
|
829
|
-
"
|
|
1040
|
+
"item": {
|
|
830
1041
|
"type": "unknown",
|
|
831
1042
|
"mutable": false,
|
|
832
1043
|
"complexType": {
|
|
833
|
-
"original": "
|
|
834
|
-
"resolved": "ClientLayoutItem
|
|
1044
|
+
"original": "ClientLayoutItem | null",
|
|
1045
|
+
"resolved": "ClientLayoutItem | null",
|
|
835
1046
|
"references": {
|
|
836
|
-
"
|
|
1047
|
+
"ClientLayoutItem": {
|
|
837
1048
|
"location": "import",
|
|
838
|
-
"path": "../../
|
|
839
|
-
"id": "src/
|
|
840
|
-
"referenceLocation": "
|
|
1049
|
+
"path": "../../types/client-layout",
|
|
1050
|
+
"id": "src/types/client-layout.ts::ClientLayoutItem",
|
|
1051
|
+
"referenceLocation": "ClientLayoutItem"
|
|
841
1052
|
}
|
|
842
1053
|
}
|
|
843
1054
|
},
|
|
@@ -845,11 +1056,31 @@ export class MrdTable {
|
|
|
845
1056
|
"optional": false,
|
|
846
1057
|
"docs": {
|
|
847
1058
|
"tags": [],
|
|
848
|
-
"text": ""
|
|
1059
|
+
"text": "The VIEW or RELATED_VIEW layout item. Contains view config, dataClass, fromClass, actions etc."
|
|
849
1060
|
},
|
|
850
1061
|
"getter": false,
|
|
851
1062
|
"setter": false,
|
|
852
|
-
"defaultValue": "
|
|
1063
|
+
"defaultValue": "null"
|
|
1064
|
+
},
|
|
1065
|
+
"parentId": {
|
|
1066
|
+
"type": "string",
|
|
1067
|
+
"mutable": false,
|
|
1068
|
+
"complexType": {
|
|
1069
|
+
"original": "string",
|
|
1070
|
+
"resolved": "string",
|
|
1071
|
+
"references": {}
|
|
1072
|
+
},
|
|
1073
|
+
"required": false,
|
|
1074
|
+
"optional": false,
|
|
1075
|
+
"docs": {
|
|
1076
|
+
"tags": [],
|
|
1077
|
+
"text": "Parent record id \u2014 required for RELATED_VIEW to build /{fromClass}/{parentId}/{dataClass}."
|
|
1078
|
+
},
|
|
1079
|
+
"getter": false,
|
|
1080
|
+
"setter": false,
|
|
1081
|
+
"reflect": false,
|
|
1082
|
+
"attribute": "parent-id",
|
|
1083
|
+
"defaultValue": "''"
|
|
853
1084
|
},
|
|
854
1085
|
"rows": {
|
|
855
1086
|
"type": "unknown",
|
|
@@ -973,101 +1204,12 @@ export class MrdTable {
|
|
|
973
1204
|
"reflect": false,
|
|
974
1205
|
"attribute": "table-height",
|
|
975
1206
|
"defaultValue": "500"
|
|
976
|
-
},
|
|
977
|
-
"defaultSort": {
|
|
978
|
-
"type": "string",
|
|
979
|
-
"mutable": false,
|
|
980
|
-
"complexType": {
|
|
981
|
-
"original": "string",
|
|
982
|
-
"resolved": "string",
|
|
983
|
-
"references": {}
|
|
984
|
-
},
|
|
985
|
-
"required": false,
|
|
986
|
-
"optional": false,
|
|
987
|
-
"docs": {
|
|
988
|
-
"tags": [],
|
|
989
|
-
"text": "Initial sort applied on load, e.g. \"timestamp,desc\" or \"name\".\nParsed by init() into sortField + sortDir."
|
|
990
|
-
},
|
|
991
|
-
"getter": false,
|
|
992
|
-
"setter": false,
|
|
993
|
-
"reflect": false,
|
|
994
|
-
"attribute": "default-sort",
|
|
995
|
-
"defaultValue": "''"
|
|
996
|
-
},
|
|
997
|
-
"actions": {
|
|
998
|
-
"type": "unknown",
|
|
999
|
-
"mutable": false,
|
|
1000
|
-
"complexType": {
|
|
1001
|
-
"original": "TableAction[]",
|
|
1002
|
-
"resolved": "TableAction[]",
|
|
1003
|
-
"references": {
|
|
1004
|
-
"TableAction": {
|
|
1005
|
-
"location": "import",
|
|
1006
|
-
"path": "../../utils/cell-renderer",
|
|
1007
|
-
"id": "src/utils/cell-renderer.ts::TableAction",
|
|
1008
|
-
"referenceLocation": "TableAction"
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
},
|
|
1012
|
-
"required": false,
|
|
1013
|
-
"optional": false,
|
|
1014
|
-
"docs": {
|
|
1015
|
-
"tags": [],
|
|
1016
|
-
"text": "Toolbar action buttons rendered above the table."
|
|
1017
|
-
},
|
|
1018
|
-
"getter": false,
|
|
1019
|
-
"setter": false,
|
|
1020
|
-
"defaultValue": "[]"
|
|
1021
|
-
},
|
|
1022
|
-
"viewLabel": {
|
|
1023
|
-
"type": "string",
|
|
1024
|
-
"mutable": false,
|
|
1025
|
-
"complexType": {
|
|
1026
|
-
"original": "string",
|
|
1027
|
-
"resolved": "string",
|
|
1028
|
-
"references": {}
|
|
1029
|
-
},
|
|
1030
|
-
"required": false,
|
|
1031
|
-
"optional": false,
|
|
1032
|
-
"docs": {
|
|
1033
|
-
"tags": [],
|
|
1034
|
-
"text": "Display label of the current view \u2014 shown in the toolbar center as a view picker trigger."
|
|
1035
|
-
},
|
|
1036
|
-
"getter": false,
|
|
1037
|
-
"setter": false,
|
|
1038
|
-
"reflect": false,
|
|
1039
|
-
"attribute": "view-label",
|
|
1040
|
-
"defaultValue": "''"
|
|
1041
|
-
},
|
|
1042
|
-
"alternativeViews": {
|
|
1043
|
-
"type": "unknown",
|
|
1044
|
-
"mutable": false,
|
|
1045
|
-
"complexType": {
|
|
1046
|
-
"original": "AlternativeView[]",
|
|
1047
|
-
"resolved": "AlternativeView[]",
|
|
1048
|
-
"references": {
|
|
1049
|
-
"AlternativeView": {
|
|
1050
|
-
"location": "import",
|
|
1051
|
-
"path": "../../utils/cell-renderer",
|
|
1052
|
-
"id": "src/utils/cell-renderer.ts::AlternativeView",
|
|
1053
|
-
"referenceLocation": "AlternativeView"
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
},
|
|
1057
|
-
"required": false,
|
|
1058
|
-
"optional": false,
|
|
1059
|
-
"docs": {
|
|
1060
|
-
"tags": [],
|
|
1061
|
-
"text": "Alternative views available for this table; renders a dropdown when non-empty."
|
|
1062
|
-
},
|
|
1063
|
-
"getter": false,
|
|
1064
|
-
"setter": false,
|
|
1065
|
-
"defaultValue": "[]"
|
|
1066
1207
|
}
|
|
1067
1208
|
};
|
|
1068
1209
|
}
|
|
1069
1210
|
static get states() {
|
|
1070
1211
|
return {
|
|
1212
|
+
"activeViewIdx": {},
|
|
1071
1213
|
"loadedPages": {},
|
|
1072
1214
|
"requestedPages": {},
|
|
1073
1215
|
"renderStart": {},
|
|
@@ -1083,7 +1225,9 @@ export class MrdTable {
|
|
|
1083
1225
|
"scrollTop": {},
|
|
1084
1226
|
"textblockModal": {},
|
|
1085
1227
|
"jsonModal": {},
|
|
1086
|
-
"aggregations": {}
|
|
1228
|
+
"aggregations": {},
|
|
1229
|
+
"aggregationsTotal": {},
|
|
1230
|
+
"minKnownTotal": {}
|
|
1087
1231
|
};
|
|
1088
1232
|
}
|
|
1089
1233
|
static get events() {
|
|
@@ -1098,8 +1242,8 @@ export class MrdTable {
|
|
|
1098
1242
|
"text": "Fired when a page needs to be fetched. Host fetches and calls setPage().\n`sort` is the raw query-param value, e.g. \"name\" or \"name,desc\"."
|
|
1099
1243
|
},
|
|
1100
1244
|
"complexType": {
|
|
1101
|
-
"original": "{ page: number; sort: string }",
|
|
1102
|
-
"resolved": "{ page: number; sort: string; }",
|
|
1245
|
+
"original": "{ page: number; sort: string; path: string; qs: string }",
|
|
1246
|
+
"resolved": "{ page: number; sort: string; path: string; qs: string; }",
|
|
1103
1247
|
"references": {}
|
|
1104
1248
|
}
|
|
1105
1249
|
}, {
|
|
@@ -1130,35 +1274,13 @@ export class MrdTable {
|
|
|
1130
1274
|
"composed": true,
|
|
1131
1275
|
"docs": {
|
|
1132
1276
|
"tags": [],
|
|
1133
|
-
"text": "Fired when a toolbar action button is clicked
|
|
1277
|
+
"text": "Fired when a toolbar action button is clicked.\nFor 'export': includes `path` (relative excel path) and `qs` (current sort+filter params).\nFor 'create': includes `dataClass` (target type) and `parentPath` (e.g. /buyers/123 for RELATED_VIEW)."
|
|
1134
1278
|
},
|
|
1135
1279
|
"complexType": {
|
|
1136
|
-
"original": "{ action: string }",
|
|
1137
|
-
"resolved": "{ action: string; }",
|
|
1280
|
+
"original": "{ action: string; path?: string; qs?: string; dataClass?: string; parentPath?: string | null }",
|
|
1281
|
+
"resolved": "{ action: string; path?: string | undefined; qs?: string | undefined; dataClass?: string | undefined; parentPath?: string | null | undefined; }",
|
|
1138
1282
|
"references": {}
|
|
1139
1283
|
}
|
|
1140
|
-
}, {
|
|
1141
|
-
"method": "mrdFilter",
|
|
1142
|
-
"name": "mrdFilter",
|
|
1143
|
-
"bubbles": true,
|
|
1144
|
-
"cancelable": true,
|
|
1145
|
-
"composed": true,
|
|
1146
|
-
"docs": {
|
|
1147
|
-
"tags": [],
|
|
1148
|
-
"text": "Fired when active filters change. Host translates filters to API query params."
|
|
1149
|
-
},
|
|
1150
|
-
"complexType": {
|
|
1151
|
-
"original": "{ filters: ColumnFilter[] }",
|
|
1152
|
-
"resolved": "{ filters: ColumnFilter[]; }",
|
|
1153
|
-
"references": {
|
|
1154
|
-
"ColumnFilter": {
|
|
1155
|
-
"location": "import",
|
|
1156
|
-
"path": "../../utils/cell-renderer",
|
|
1157
|
-
"id": "src/utils/cell-renderer.ts::ColumnFilter",
|
|
1158
|
-
"referenceLocation": "ColumnFilter"
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
1284
|
}, {
|
|
1163
1285
|
"method": "mrdDownload",
|
|
1164
1286
|
"name": "mrdDownload",
|
|
@@ -1174,21 +1296,6 @@ export class MrdTable {
|
|
|
1174
1296
|
"resolved": "{ href: string; fileName: string; }",
|
|
1175
1297
|
"references": {}
|
|
1176
1298
|
}
|
|
1177
|
-
}, {
|
|
1178
|
-
"method": "mrdSwitchView",
|
|
1179
|
-
"name": "mrdSwitchView",
|
|
1180
|
-
"bubbles": true,
|
|
1181
|
-
"cancelable": true,
|
|
1182
|
-
"composed": true,
|
|
1183
|
-
"docs": {
|
|
1184
|
-
"tags": [],
|
|
1185
|
-
"text": "Fired when the user selects an alternative view from the view switcher dropdown."
|
|
1186
|
-
},
|
|
1187
|
-
"complexType": {
|
|
1188
|
-
"original": "{ name: string; class?: string }",
|
|
1189
|
-
"resolved": "{ name: string; class?: string | undefined; }",
|
|
1190
|
-
"references": {}
|
|
1191
|
-
}
|
|
1192
1299
|
}, {
|
|
1193
1300
|
"method": "mrdLoadAggregations",
|
|
1194
1301
|
"name": "mrdLoadAggregations",
|
|
@@ -1197,11 +1304,11 @@ export class MrdTable {
|
|
|
1197
1304
|
"composed": true,
|
|
1198
1305
|
"docs": {
|
|
1199
1306
|
"tags": [],
|
|
1200
|
-
"text": "Fired when aggregation totals need to be (re-)fetched.\
|
|
1307
|
+
"text": "Fired when aggregation totals need to be (re-)fetched.\n`aggQs` is a ready-to-use query string: active filters (no page/sort) + sum/avg/count params.\nHost calls the /aggregations endpoint and passes the result to setAggregations()."
|
|
1201
1308
|
},
|
|
1202
1309
|
"complexType": {
|
|
1203
|
-
"original": "{
|
|
1204
|
-
"resolved": "{
|
|
1310
|
+
"original": "{ path: string; qs: string; aggQs: string }",
|
|
1311
|
+
"resolved": "{ path: string; qs: string; aggQs: string; }",
|
|
1205
1312
|
"references": {}
|
|
1206
1313
|
}
|
|
1207
1314
|
}];
|
|
@@ -1231,7 +1338,7 @@ export class MrdTable {
|
|
|
1231
1338
|
},
|
|
1232
1339
|
"setPage": {
|
|
1233
1340
|
"complexType": {
|
|
1234
|
-
"signature": "(pageNumber: number, rows: Record<string, any>[]) => Promise<void>",
|
|
1341
|
+
"signature": "(pageNumber: number, rows: Record<string, any>[], hasNext?: boolean) => Promise<void>",
|
|
1235
1342
|
"parameters": [{
|
|
1236
1343
|
"name": "pageNumber",
|
|
1237
1344
|
"type": "number",
|
|
@@ -1240,6 +1347,10 @@ export class MrdTable {
|
|
|
1240
1347
|
"name": "rows",
|
|
1241
1348
|
"type": "Record<string, any>[]",
|
|
1242
1349
|
"docs": ""
|
|
1350
|
+
}, {
|
|
1351
|
+
"name": "hasNext",
|
|
1352
|
+
"type": "boolean | undefined",
|
|
1353
|
+
"docs": ""
|
|
1243
1354
|
}],
|
|
1244
1355
|
"references": {
|
|
1245
1356
|
"Promise": {
|
|
@@ -1254,7 +1365,7 @@ export class MrdTable {
|
|
|
1254
1365
|
"return": "Promise<void>"
|
|
1255
1366
|
},
|
|
1256
1367
|
"docs": {
|
|
1257
|
-
"text": "Inject the rows for a given page (0-based).\nCreates a new Map reference so Stencil detects the state change.\n\nWhen the page contains fewer rows than pageSize it is the last page.\nrenderEnd is clamped immediately so no loading-placeholder rows appear\nbeyond the actual data \u2014 without requiring the host to update totalElements.",
|
|
1368
|
+
"text": "Inject the rows for a given page (0-based).\nCreates a new Map reference so Stencil detects the state change.\n\nWhen the page contains fewer rows than pageSize it is the last page.\nrenderEnd is clamped immediately so no loading-placeholder rows appear\nbeyond the actual data \u2014 without requiring the host to update totalElements.\n\nPass hasNext (from _links.next in the API response) for accurate last-page\ndetection even when rows.length === pageSize (exact multiple of page size).",
|
|
1258
1369
|
"tags": []
|
|
1259
1370
|
}
|
|
1260
1371
|
},
|
|
@@ -1293,8 +1404,8 @@ export class MrdTable {
|
|
|
1293
1404
|
"propName": "totalElements",
|
|
1294
1405
|
"methodName": "totalElementsChanged"
|
|
1295
1406
|
}, {
|
|
1296
|
-
"propName": "
|
|
1297
|
-
"methodName": "
|
|
1407
|
+
"propName": "item",
|
|
1408
|
+
"methodName": "itemChanged"
|
|
1298
1409
|
}];
|
|
1299
1410
|
}
|
|
1300
1411
|
}
|