@mmlogic/components 0.3.11 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{index-BPj2cBXs.js → index-CAzwGt9u.js} +38 -0
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/mosterdcomponents.cjs.js +1 -1
- package/dist/cjs/mrd-boolean-field_23.cjs.entry.js +1203 -1084
- package/dist/collection/collection-manifest.json +23 -23
- package/dist/collection/components/{mrd-document-container/mrd-document-container.scss → documents/mrd-document-container/mrd-document-container.css} +3 -3
- package/dist/collection/components/{mrd-document-container → documents/mrd-document-container}/mrd-document-container.js +7 -7
- package/dist/collection/components/documents/mrd-document-list/folder-tree.js +109 -0
- package/dist/collection/components/{mrd-document-list/mrd-document-list.scss → documents/mrd-document-list/mrd-document-list.css} +6 -4
- package/dist/collection/components/{mrd-document-list → documents/mrd-document-list}/mrd-document-list.js +83 -240
- package/dist/collection/components/documents/mrd-document-list/tree-view.js +75 -0
- package/dist/collection/components/{mrd-document-view/mrd-document-view.scss → documents/mrd-document-view/mrd-document-view.css} +1 -1
- package/dist/collection/components/{mrd-document-view → documents/mrd-document-view}/mrd-document-view.js +4 -4
- package/dist/collection/components/fields/field-helpers.js +17 -0
- package/dist/collection/components/fields/file-upload-common.js +38 -0
- package/dist/collection/components/{mrd-boolean-field/mrd-boolean-field.scss → fields/mrd-boolean-field/mrd-boolean-field.css} +3 -3
- package/dist/collection/components/{mrd-boolean-field → fields/mrd-boolean-field}/mrd-boolean-field.js +1 -1
- package/dist/collection/components/{mrd-currency-field/mrd-currency-field.scss → fields/mrd-currency-field/mrd-currency-field.css} +11 -9
- package/dist/collection/components/{mrd-currency-field → fields/mrd-currency-field}/mrd-currency-field.js +7 -13
- package/dist/collection/components/{mrd-date-field/mrd-date-field.scss → fields/mrd-date-field/mrd-date-field.css} +8 -10
- package/dist/collection/components/{mrd-date-field → fields/mrd-date-field}/mrd-date-field.js +3 -10
- package/dist/collection/components/{mrd-datetime-field/mrd-datetime-field.scss → fields/mrd-datetime-field/mrd-datetime-field.css} +8 -10
- package/dist/collection/components/{mrd-datetime-field → fields/mrd-datetime-field}/mrd-datetime-field.js +3 -10
- package/dist/collection/components/{mrd-email-field/mrd-email-field.scss → fields/mrd-email-field/mrd-email-field.css} +2 -11
- package/dist/collection/components/{mrd-email-field → fields/mrd-email-field}/mrd-email-field.js +6 -13
- package/dist/collection/components/{mrd-file-field/mrd-file-field.scss → fields/mrd-file-field/mrd-file-field.css} +19 -24
- package/dist/collection/components/{mrd-file-field → fields/mrd-file-field}/mrd-file-field.js +13 -24
- package/dist/collection/components/{mrd-hyperlink-field/mrd-hyperlink-field.scss → fields/mrd-hyperlink-field/mrd-hyperlink-field.css} +7 -16
- package/dist/collection/components/{mrd-hyperlink-field → fields/mrd-hyperlink-field}/mrd-hyperlink-field.js +9 -15
- package/dist/collection/components/{mrd-image-field/mrd-image-field.scss → fields/mrd-image-field/mrd-image-field.css} +15 -24
- package/dist/collection/components/{mrd-image-field → fields/mrd-image-field}/mrd-image-field.js +13 -28
- package/dist/collection/components/{mrd-list-field/mrd-list-field.scss → fields/mrd-list-field/mrd-list-field.css} +18 -21
- package/dist/collection/components/{mrd-list-field → fields/mrd-list-field}/mrd-list-field.js +10 -25
- package/dist/collection/components/{mrd-longtext-field/mrd-longtext-field.scss → fields/mrd-longtext-field/mrd-longtext-field.css} +21 -18
- package/dist/collection/components/{mrd-longtext-field → fields/mrd-longtext-field}/mrd-longtext-field.js +3 -10
- package/dist/collection/components/{mrd-number-field/mrd-number-field.scss → fields/mrd-number-field/mrd-number-field.css} +9 -10
- package/dist/collection/components/{mrd-number-field → fields/mrd-number-field}/mrd-number-field.js +7 -6
- package/dist/collection/components/{mrd-relation-field/mrd-relation-field.scss → fields/mrd-relation-field/mrd-relation-field.css} +61 -59
- package/dist/collection/components/{mrd-relation-field → fields/mrd-relation-field}/mrd-relation-field.js +16 -26
- package/dist/collection/components/{mrd-secret-field/mrd-secret-field.scss → fields/mrd-secret-field/mrd-secret-field.css} +7 -10
- package/dist/collection/components/{mrd-secret-field → fields/mrd-secret-field}/mrd-secret-field.js +4 -11
- package/dist/collection/components/{mrd-text-field/mrd-text-field.scss → fields/mrd-text-field/mrd-text-field.css} +2 -11
- package/dist/collection/components/{mrd-text-field → fields/mrd-text-field}/mrd-text-field.js +3 -10
- package/dist/collection/components/{mrd-textarea-field/mrd-textarea-field.scss → fields/mrd-textarea-field/mrd-textarea-field.css} +7 -10
- package/dist/collection/components/{mrd-textarea-field → fields/mrd-textarea-field}/mrd-textarea-field.js +3 -9
- package/dist/collection/components/{mrd-time-field/mrd-time-field.scss → fields/mrd-time-field/mrd-time-field.css} +8 -10
- package/dist/collection/components/{mrd-time-field → fields/mrd-time-field}/mrd-time-field.js +3 -10
- package/dist/collection/components/{mrd-field/mrd-field.scss → form/mrd-field/mrd-field.css} +1 -1
- package/dist/collection/components/{mrd-field → form/mrd-field}/mrd-field.js +3 -3
- package/dist/collection/components/{mrd-form/mrd-form.scss → form/mrd-form/mrd-form.css} +1 -1
- package/dist/collection/components/{mrd-form → form/mrd-form}/mrd-form.js +5 -5
- package/dist/collection/components/layout/mrd-layout-section/field-value.js +111 -0
- package/dist/collection/components/layout/mrd-layout-section/layout-helpers.js +29 -0
- package/dist/collection/components/{mrd-layout-section/mrd-layout-section.scss → layout/mrd-layout-section/mrd-layout-section.css} +4 -4
- package/dist/collection/components/{mrd-layout-section → layout/mrd-layout-section}/mrd-layout-section.js +52 -142
- package/dist/collection/components/{mrd-table/mrd-table.scss → table/mrd-table/mrd-table.css} +11 -13
- package/dist/collection/components/{mrd-table → table/mrd-table}/mrd-table.js +111 -439
- package/dist/collection/components/table/mrd-table/table-filter-popup.js +85 -0
- package/dist/collection/components/table/mrd-table/table-parts.js +110 -0
- package/dist/collection/components/table/mrd-table/table-query.js +178 -0
- package/dist/collection/components/table/mrd-table/virtual-scroll.js +49 -0
- package/dist/collection/dev/app.js +19 -18
- package/dist/collection/dev/example-data.js +58 -43
- package/dist/collection/utils/i18n.js +8 -0
- package/dist/collection/utils/query-params.js +43 -0
- package/dist/components/field-helpers.js +1 -0
- package/dist/components/file-upload-common.js +1 -0
- package/dist/components/i18n.js +1 -1
- package/dist/components/mrd-boolean-field2.js +1 -1
- package/dist/components/mrd-currency-field2.js +1 -1
- package/dist/components/mrd-date-field2.js +1 -1
- package/dist/components/mrd-datetime-field2.js +1 -1
- package/dist/components/mrd-document-container2.js +1 -1
- package/dist/components/mrd-document-list2.js +1 -1
- package/dist/components/mrd-document-view2.js +1 -1
- package/dist/components/mrd-email-field2.js +1 -1
- package/dist/components/mrd-file-field2.js +1 -1
- package/dist/components/mrd-form.js +1 -1
- package/dist/components/mrd-hyperlink-field2.js +1 -1
- package/dist/components/mrd-image-field2.js +1 -1
- package/dist/components/mrd-layout-section.js +1 -1
- package/dist/components/mrd-list-field2.js +1 -1
- package/dist/components/mrd-longtext-field2.js +1 -1
- package/dist/components/mrd-number-field2.js +1 -1
- package/dist/components/mrd-relation-field2.js +1 -1
- package/dist/components/mrd-secret-field2.js +1 -1
- package/dist/components/mrd-table2.js +1 -1
- package/dist/components/mrd-text-field2.js +1 -1
- package/dist/components/mrd-textarea-field2.js +1 -1
- package/dist/components/mrd-time-field2.js +1 -1
- package/dist/components/query-params.js +1 -0
- package/dist/esm/{index-_tsCCkAi.js → index-DiSEJMA8.js} +38 -1
- package/dist/esm/loader.js +2 -2
- package/dist/esm/mosterdcomponents.js +2 -2
- package/dist/esm/mrd-boolean-field_23.entry.js +1203 -1084
- package/dist/mosterdcomponents/mosterdcomponents.css +1 -1
- package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
- package/dist/mosterdcomponents/p-9b3c0917.entry.js +1 -0
- package/dist/mosterdcomponents/p-DiSEJMA8.js +2 -0
- package/dist/types/components/{mrd-document-container → documents/mrd-document-container}/mrd-document-container.d.ts +2 -2
- package/dist/types/components/documents/mrd-document-list/folder-tree.d.ts +66 -0
- package/dist/types/components/{mrd-document-list → documents/mrd-document-list}/mrd-document-list.d.ts +4 -37
- package/dist/types/components/documents/mrd-document-list/tree-view.d.ts +32 -0
- package/dist/types/components/{mrd-document-view → documents/mrd-document-view}/mrd-document-view.d.ts +2 -2
- package/dist/types/components/fields/field-helpers.d.ts +18 -0
- package/dist/types/components/fields/file-upload-common.d.ts +18 -0
- package/dist/types/components/{mrd-boolean-field → fields/mrd-boolean-field}/mrd-boolean-field.d.ts +1 -1
- package/dist/types/components/{mrd-currency-field → fields/mrd-currency-field}/mrd-currency-field.d.ts +2 -2
- package/dist/types/components/{mrd-date-field → fields/mrd-date-field}/mrd-date-field.d.ts +1 -1
- package/dist/types/components/{mrd-datetime-field → fields/mrd-datetime-field}/mrd-datetime-field.d.ts +1 -1
- package/dist/types/components/{mrd-email-field → fields/mrd-email-field}/mrd-email-field.d.ts +1 -1
- package/dist/types/components/{mrd-file-field → fields/mrd-file-field}/mrd-file-field.d.ts +2 -4
- package/dist/types/components/{mrd-hyperlink-field → fields/mrd-hyperlink-field}/mrd-hyperlink-field.d.ts +2 -2
- package/dist/types/components/{mrd-image-field → fields/mrd-image-field}/mrd-image-field.d.ts +2 -4
- package/dist/types/components/{mrd-list-field → fields/mrd-list-field}/mrd-list-field.d.ts +2 -2
- package/dist/types/components/{mrd-longtext-field → fields/mrd-longtext-field}/mrd-longtext-field.d.ts +1 -1
- package/dist/types/components/{mrd-number-field → fields/mrd-number-field}/mrd-number-field.d.ts +2 -2
- package/dist/types/components/{mrd-relation-field → fields/mrd-relation-field}/mrd-relation-field.d.ts +2 -2
- package/dist/types/components/{mrd-secret-field → fields/mrd-secret-field}/mrd-secret-field.d.ts +1 -1
- package/dist/types/components/{mrd-text-field → fields/mrd-text-field}/mrd-text-field.d.ts +1 -1
- package/dist/types/components/{mrd-textarea-field → fields/mrd-textarea-field}/mrd-textarea-field.d.ts +1 -1
- package/dist/types/components/{mrd-time-field → fields/mrd-time-field}/mrd-time-field.d.ts +1 -1
- package/dist/types/components/{mrd-field → form/mrd-field}/mrd-field.d.ts +2 -2
- package/dist/types/components/{mrd-form → form/mrd-form}/mrd-form.d.ts +2 -2
- package/dist/types/components/layout/mrd-layout-section/field-value.d.ts +22 -0
- package/dist/types/components/layout/mrd-layout-section/layout-helpers.d.ts +8 -0
- package/dist/types/components/{mrd-layout-section → layout/mrd-layout-section}/mrd-layout-section.d.ts +4 -11
- package/dist/types/components/{mrd-table → table/mrd-table}/mrd-table.d.ts +6 -13
- package/dist/types/components/table/mrd-table/table-filter-popup.d.ts +35 -0
- package/dist/types/components/table/mrd-table/table-parts.d.ts +61 -0
- package/dist/types/components/table/mrd-table/table-query.d.ts +50 -0
- package/dist/types/components/table/mrd-table/virtual-scroll.d.ts +26 -0
- package/dist/types/components.d.ts +3 -5
- package/dist/types/utils/query-params.d.ts +14 -0
- package/package.json +7 -2
- package/dist/components/validation.js +0 -1
- package/dist/mosterdcomponents/p-_tsCCkAi.js +0 -2
- package/dist/mosterdcomponents/p-a9618055.entry.js +0 -1
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
import { h, Host } from "@stencil/core";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const REQUEST_DEBOUNCE_MS = 150;
|
|
1
|
+
import { h, Host, writeTask } from "@stencil/core";
|
|
2
|
+
import { t } from "../../../utils/i18n";
|
|
3
|
+
import { buildListPath } from "../../../utils/query-params";
|
|
4
|
+
import { TEXT_TYPES, NON_INTERACTIVE_TYPES, parseDefaultSort, buildSortParam, buildTableQueryParams, buildAggregationQs, filterHasValue, normalizeDatetimeFilter, datetimeFilterToDisplay, } from "./table-query";
|
|
5
|
+
import { FilterIcon, TableCell, TotalsRow, TextblockModal, JsonModal, Toolbar } from "./table-parts";
|
|
6
|
+
import { FilterPopup } from "./table-filter-popup";
|
|
7
|
+
import { REQUEST_DEBOUNCE_MS, visibleCount, computeWindow, pageRange, getRowFromPages, computeEffectiveTotal, isTotalKnownFromPages, } from "./virtual-scroll";
|
|
9
8
|
/** Breedte van de filterpopup in px — voor overflow-correctie. */
|
|
10
9
|
const POPUP_WIDTH = 280;
|
|
11
|
-
const TEXT_TYPES = new Set(['TEXT', 'TEXTBLOCK', 'EMAIL', 'HYPERLINK']);
|
|
12
|
-
const NUMERIC_TYPES = new Set(['INTEGER', 'DECIMAL', 'PERCENTAGE', 'CURRENCY']);
|
|
13
|
-
const DATE_TYPES = new Set(['DATE', 'DATETIME', 'TIME']);
|
|
14
|
-
const NO_FILTER_TYPES = new Set(['FILE', 'IMAGE']);
|
|
15
|
-
/** Column types that cannot be sorted or filtered (not stored in PostgreSQL). */
|
|
16
|
-
const NON_INTERACTIVE_TYPES = new Set(['LONGTEXT', 'JSON', 'FILE', 'IMAGE']);
|
|
17
10
|
export class MrdTable {
|
|
18
11
|
constructor() {
|
|
19
12
|
// ── Non-state internals ────────────────────────────────────────────────────
|
|
@@ -23,6 +16,8 @@ export class MrdTable {
|
|
|
23
16
|
this.keydownHandler = null;
|
|
24
17
|
this.createPickerClickHandler = null;
|
|
25
18
|
this.viewPopoverClickHandler = null;
|
|
19
|
+
/** Guards against scheduling more than one column-width measurement per freeze. */
|
|
20
|
+
this.colWidthMeasureScheduled = false;
|
|
26
21
|
// ── Props ──────────────────────────────────────────────────────────────────
|
|
27
22
|
/** The VIEW or RELATED_VIEW layout item. Contains view config, dataClass, fromClass, actions etc. */
|
|
28
23
|
this.item = null;
|
|
@@ -79,13 +74,10 @@ export class MrdTable {
|
|
|
79
74
|
this.minKnownTotal = 0;
|
|
80
75
|
this.handleScroll = (e) => {
|
|
81
76
|
const scroller = e.currentTarget;
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
this.scrollTop = scrollTop;
|
|
87
|
-
this.renderStart = Math.max(0, visStart - BUFFER);
|
|
88
|
-
this.renderEnd = Math.min(total - 1, visEnd + BUFFER);
|
|
77
|
+
const { renderStart, renderEnd } = computeWindow(scroller.scrollTop, this.rowHeight, this.tableHeight, this.baseTotal);
|
|
78
|
+
this.scrollTop = scroller.scrollTop;
|
|
79
|
+
this.renderStart = renderStart;
|
|
80
|
+
this.renderEnd = renderEnd;
|
|
89
81
|
this.requestPagesForWindow(this.renderStart, this.renderEnd);
|
|
90
82
|
};
|
|
91
83
|
}
|
|
@@ -107,16 +99,9 @@ export class MrdTable {
|
|
|
107
99
|
}
|
|
108
100
|
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
109
101
|
applyDefaultSort(defaultSort) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
this.sortField = parts[0].trim();
|
|
114
|
-
this.sortDir = ((_a = parts[1]) === null || _a === void 0 ? void 0 : _a.trim()) === 'desc' ? 'desc' : 'asc';
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
this.sortField = '';
|
|
118
|
-
this.sortDir = 'asc';
|
|
119
|
-
}
|
|
102
|
+
const { field, dir } = parseDefaultSort(defaultSort);
|
|
103
|
+
this.sortField = field;
|
|
104
|
+
this.sortDir = dir;
|
|
120
105
|
}
|
|
121
106
|
// ── Public API ─────────────────────────────────────────────────────────────
|
|
122
107
|
/**
|
|
@@ -133,6 +118,7 @@ export class MrdTable {
|
|
|
133
118
|
this.loadedPages = new Map();
|
|
134
119
|
this.requestedPages = new Set();
|
|
135
120
|
this.colWidths = [];
|
|
121
|
+
this.colWidthMeasureScheduled = false;
|
|
136
122
|
this.scrollTop = 0;
|
|
137
123
|
this.renderStart = 0;
|
|
138
124
|
// Always fill the visible viewport on init — totalElements may be stale from a
|
|
@@ -213,21 +199,34 @@ export class MrdTable {
|
|
|
213
199
|
}
|
|
214
200
|
}
|
|
215
201
|
componentDidRender() {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
202
|
+
// Freeze header widths once the first data page has rendered. The measurement
|
|
203
|
+
// reads offsetWidth and writes the colWidths @State, which would trigger a
|
|
204
|
+
// re-render *during* the render cycle if done synchronously here. Defer it to a
|
|
205
|
+
// writeTask so the state mutation happens outside the render pass (avoids the
|
|
206
|
+
// Stencil "state/prop changed during rendering" warning and potential loops).
|
|
207
|
+
if (this.colWidths.length === 0 &&
|
|
208
|
+
!this.colWidthMeasureScheduled &&
|
|
209
|
+
this.loadedPages.size > 0 &&
|
|
210
|
+
this.totalElements > 0) {
|
|
211
|
+
this.colWidthMeasureScheduled = true;
|
|
212
|
+
writeTask(() => {
|
|
213
|
+
this.colWidthMeasureScheduled = false;
|
|
214
|
+
// Re-check: state may have changed (e.g. a reset) between scheduling and running.
|
|
215
|
+
if (this.colWidths.length !== 0)
|
|
216
|
+
return;
|
|
217
|
+
const ths = this.el.querySelectorAll('.mrd-table__header');
|
|
218
|
+
if (ths.length > 0) {
|
|
219
|
+
this.colWidths = Array.from(ths).map(th => th.offsetWidth);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
221
222
|
}
|
|
222
223
|
}
|
|
223
224
|
// ── Paging / scroll helpers ────────────────────────────────────────────────
|
|
224
225
|
visibleCount() {
|
|
225
|
-
return
|
|
226
|
+
return visibleCount(this.tableHeight, this.rowHeight);
|
|
226
227
|
}
|
|
227
228
|
sortParam() {
|
|
228
|
-
|
|
229
|
-
return '';
|
|
230
|
-
return this.sortDir === 'desc' ? `${this.sortField},desc` : this.sortField;
|
|
229
|
+
return buildSortParam(this.sortField, this.sortDir);
|
|
231
230
|
}
|
|
232
231
|
/** Stable ordered list: primary view first, then alternatives (from the item prop). */
|
|
233
232
|
get allViews() {
|
|
@@ -253,14 +252,16 @@ export class MrdTable {
|
|
|
253
252
|
* VIEW: /excel/{dataClass}
|
|
254
253
|
* RELATED_VIEW: /excel/{fromClass}/{parentId}/{dataClass} */
|
|
255
254
|
buildExcelPath() {
|
|
256
|
-
var _a
|
|
255
|
+
var _a;
|
|
257
256
|
const v = this.allViews[this.activeViewIdx];
|
|
258
257
|
if (!v)
|
|
259
258
|
return '';
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
259
|
+
return '/excel' + buildListPath({
|
|
260
|
+
isRelatedView: ((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'RELATED_VIEW',
|
|
261
|
+
fromClass: v.fromClass,
|
|
262
|
+
parentId: this.parentId,
|
|
263
|
+
dataClass: v.dataClass,
|
|
264
|
+
});
|
|
264
265
|
}
|
|
265
266
|
buildActionDetail(action, basicType) {
|
|
266
267
|
var _a, _b, _c;
|
|
@@ -280,80 +281,28 @@ export class MrdTable {
|
|
|
280
281
|
* VIEW: /{dataClass}
|
|
281
282
|
* RELATED_VIEW: /{fromClass}/{parentId}/{dataClass} */
|
|
282
283
|
buildDataPath() {
|
|
283
|
-
var _a
|
|
284
|
+
var _a;
|
|
284
285
|
const v = this.allViews[this.activeViewIdx];
|
|
285
286
|
if (!v)
|
|
286
287
|
return '';
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
288
|
+
return buildListPath({
|
|
289
|
+
isRelatedView: ((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'RELATED_VIEW',
|
|
290
|
+
fromClass: v.fromClass,
|
|
291
|
+
parentId: this.parentId,
|
|
292
|
+
dataClass: v.dataClass,
|
|
293
|
+
});
|
|
291
294
|
}
|
|
292
295
|
/** Build query params for a page request from current sort, view filters, filterClass and active column filters. */
|
|
293
296
|
buildQueryParams(page) {
|
|
294
|
-
var _a
|
|
297
|
+
var _a;
|
|
295
298
|
const v = this.allViews[this.activeViewIdx];
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
if (filterClass)
|
|
304
|
-
p.set('type', filterClass);
|
|
305
|
-
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 : [])) {
|
|
306
|
-
if (!f.name)
|
|
307
|
-
continue;
|
|
308
|
-
if (f.operator === 'EMPTY') {
|
|
309
|
-
p.set(f.name, '');
|
|
310
|
-
continue;
|
|
311
|
-
}
|
|
312
|
-
if (f.operator === 'NOT_EMPTY') {
|
|
313
|
-
p.set(f.name + '_notempty', 'true');
|
|
314
|
-
continue;
|
|
315
|
-
}
|
|
316
|
-
if (f.operator === 'STARTS_WITH') {
|
|
317
|
-
p.set(f.name + '_startswith', String((_c = f.value) !== null && _c !== void 0 ? _c : ''));
|
|
318
|
-
continue;
|
|
319
|
-
}
|
|
320
|
-
if (f.operator === 'FROM') {
|
|
321
|
-
p.set(f.name + '_from', String((_d = f.value) !== null && _d !== void 0 ? _d : ''));
|
|
322
|
-
continue;
|
|
323
|
-
}
|
|
324
|
-
if (f.operator === 'TO') {
|
|
325
|
-
p.set(f.name + '_to', String((_e = f.value) !== null && _e !== void 0 ? _e : ''));
|
|
326
|
-
continue;
|
|
327
|
-
}
|
|
328
|
-
if (f.value != null) {
|
|
329
|
-
p.set(f.name, String(f.value));
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
for (const f of this.activeFilters.values()) {
|
|
333
|
-
if (f.operator === 'isEmpty') {
|
|
334
|
-
p.set(f.field, '');
|
|
335
|
-
continue;
|
|
336
|
-
}
|
|
337
|
-
if (f.operator === 'isNotEmpty') {
|
|
338
|
-
p.set(f.field + '_notempty', 'true');
|
|
339
|
-
continue;
|
|
340
|
-
}
|
|
341
|
-
if (f.operator === 'startsWith') {
|
|
342
|
-
p.set(f.field + '_startswith', String((_f = f.value) !== null && _f !== void 0 ? _f : ''));
|
|
343
|
-
continue;
|
|
344
|
-
}
|
|
345
|
-
if ((_g = f.values) === null || _g === void 0 ? void 0 : _g.length) {
|
|
346
|
-
p.set(f.field, f.values.join(','));
|
|
347
|
-
continue;
|
|
348
|
-
}
|
|
349
|
-
if (f.value != null)
|
|
350
|
-
p.set(f.field, String(f.value));
|
|
351
|
-
if (f.from != null)
|
|
352
|
-
p.set(f.field + '_from', String(f.from));
|
|
353
|
-
if (f.to != null)
|
|
354
|
-
p.set(f.field + '_to', String(f.to));
|
|
355
|
-
}
|
|
356
|
-
return p.toString();
|
|
299
|
+
return buildTableQueryParams({
|
|
300
|
+
page,
|
|
301
|
+
sort: this.sortParam(),
|
|
302
|
+
filterClass: v === null || v === void 0 ? void 0 : v.filterClass,
|
|
303
|
+
viewFilters: (_a = v === null || v === void 0 ? void 0 : v.view) === null || _a === void 0 ? void 0 : _a.filter,
|
|
304
|
+
activeFilters: this.activeFilters.values(),
|
|
305
|
+
});
|
|
357
306
|
}
|
|
358
307
|
get columns() {
|
|
359
308
|
var _a, _b, _c;
|
|
@@ -408,11 +357,7 @@ export class MrdTable {
|
|
|
408
357
|
isTotalKnown() {
|
|
409
358
|
if (this.aggregationsTotal != null)
|
|
410
359
|
return true;
|
|
411
|
-
|
|
412
|
-
if (rows.length < this.pageSize)
|
|
413
|
-
return true;
|
|
414
|
-
}
|
|
415
|
-
return false;
|
|
360
|
+
return isTotalKnownFromPages(this.loadedPages, this.pageSize);
|
|
416
361
|
}
|
|
417
362
|
/** Effective total: aggregations-response > totalElements prop > minKnownTotal from setPage(). */
|
|
418
363
|
get baseTotal() {
|
|
@@ -423,61 +368,9 @@ export class MrdTable {
|
|
|
423
368
|
return this.minKnownTotal;
|
|
424
369
|
}
|
|
425
370
|
// ── Aggregation helpers ────────────────────────────────────────────────────
|
|
426
|
-
buildAggregationParams() {
|
|
427
|
-
var _a;
|
|
428
|
-
const groups = { sum: [], avg: [], count: [] };
|
|
429
|
-
for (const col of this.columns) {
|
|
430
|
-
if (col.type !== 'FIELD' || !col.aggregate)
|
|
431
|
-
continue;
|
|
432
|
-
const fn = col.aggregate.toLowerCase();
|
|
433
|
-
if (fn in groups)
|
|
434
|
-
groups[fn].push((_a = col.name) !== null && _a !== void 0 ? _a : '');
|
|
435
|
-
}
|
|
436
|
-
const params = {};
|
|
437
|
-
if (groups.sum.length)
|
|
438
|
-
params.sum = groups.sum;
|
|
439
|
-
if (groups.avg.length)
|
|
440
|
-
params.avg = groups.avg;
|
|
441
|
-
if (groups.count.length)
|
|
442
|
-
params.count = groups.count;
|
|
443
|
-
return Object.keys(params).length > 0 ? params : null;
|
|
444
|
-
}
|
|
445
|
-
buildAggregationQs() {
|
|
446
|
-
var _a, _b, _c;
|
|
447
|
-
const p = new URLSearchParams(this.buildQueryParams(0));
|
|
448
|
-
p.delete('page');
|
|
449
|
-
p.delete('sort');
|
|
450
|
-
const groups = this.buildAggregationParams();
|
|
451
|
-
if ((_a = groups === null || groups === void 0 ? void 0 : groups.sum) === null || _a === void 0 ? void 0 : _a.length)
|
|
452
|
-
p.set('sum', groups.sum.join(','));
|
|
453
|
-
if ((_b = groups === null || groups === void 0 ? void 0 : groups.avg) === null || _b === void 0 ? void 0 : _b.length)
|
|
454
|
-
p.set('avg', groups.avg.join(','));
|
|
455
|
-
if ((_c = groups === null || groups === void 0 ? void 0 : groups.count) === null || _c === void 0 ? void 0 : _c.length)
|
|
456
|
-
p.set('count', groups.count.join(','));
|
|
457
|
-
return p.toString();
|
|
458
|
-
}
|
|
459
371
|
emitLoadAggregations() {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
renderAggregationValue(col) {
|
|
463
|
-
var _a;
|
|
464
|
-
if (col.type !== 'FIELD' || !col.aggregate || !this.aggregations)
|
|
465
|
-
return '';
|
|
466
|
-
const fn = col.aggregate.toLowerCase();
|
|
467
|
-
const aggData = this.aggregations[fn];
|
|
468
|
-
const val = typeof aggData === 'object' && aggData !== null
|
|
469
|
-
? aggData[(_a = col.name) !== null && _a !== void 0 ? _a : '']
|
|
470
|
-
: undefined;
|
|
471
|
-
if (val == null)
|
|
472
|
-
return '';
|
|
473
|
-
const dt = col.dataType;
|
|
474
|
-
if (dt === 'INTEGER')
|
|
475
|
-
return formatNumber(val, this.locale, { maximumFractionDigits: 0 });
|
|
476
|
-
if (dt === 'PERCENTAGE')
|
|
477
|
-
return formatPercentage(val, this.locale);
|
|
478
|
-
if (dt === 'CURRENCY' && col.currencyCode)
|
|
479
|
-
return formatCurrency(val, col.currencyCode, this.locale);
|
|
480
|
-
return formatNumber(val, this.locale);
|
|
372
|
+
const qs = this.buildQueryParams(0);
|
|
373
|
+
this.mrdLoadAggregations.emit({ path: this.buildDataPath(), qs, aggQs: buildAggregationQs(qs, this.columns) });
|
|
481
374
|
}
|
|
482
375
|
// ── Reset pagination ───────────────────────────────────────────────────────
|
|
483
376
|
/** Reset pagination state and scroll to top (used after sort or filter change). */
|
|
@@ -490,6 +383,7 @@ export class MrdTable {
|
|
|
490
383
|
this.loadedPages = new Map();
|
|
491
384
|
this.requestedPages = new Set();
|
|
492
385
|
this.colWidths = [];
|
|
386
|
+
this.colWidthMeasureScheduled = false;
|
|
493
387
|
this.scrollTop = 0;
|
|
494
388
|
this.renderStart = 0;
|
|
495
389
|
this.minKnownTotal = 0;
|
|
@@ -519,8 +413,7 @@ export class MrdTable {
|
|
|
519
413
|
this.emitPagesForWindow(this.renderStart, this.renderEnd);
|
|
520
414
|
}
|
|
521
415
|
emitPagesForWindow(start, end) {
|
|
522
|
-
const firstPage =
|
|
523
|
-
const lastPage = Math.floor(end / this.pageSize);
|
|
416
|
+
const { firstPage, lastPage } = pageRange(start, end, this.pageSize);
|
|
524
417
|
const next = new Set(this.requestedPages);
|
|
525
418
|
let changed = false;
|
|
526
419
|
for (let p = firstPage; p <= lastPage; p++) {
|
|
@@ -534,13 +427,10 @@ export class MrdTable {
|
|
|
534
427
|
this.requestedPages = next;
|
|
535
428
|
}
|
|
536
429
|
getRow(i) {
|
|
537
|
-
|
|
538
|
-
const page = this.loadedPages.get(Math.floor(i / this.pageSize));
|
|
539
|
-
return (_a = page === null || page === void 0 ? void 0 : page[i % this.pageSize]) !== null && _a !== void 0 ? _a : null;
|
|
430
|
+
return getRowFromPages(this.loadedPages, i, this.pageSize);
|
|
540
431
|
}
|
|
541
432
|
requestPagesForWindow(start, end) {
|
|
542
|
-
const firstPage =
|
|
543
|
-
const lastPage = Math.floor(end / this.pageSize);
|
|
433
|
+
const { firstPage, lastPage } = pageRange(start, end, this.pageSize);
|
|
544
434
|
let anyNew = false;
|
|
545
435
|
for (let p = firstPage; p <= lastPage; p++) {
|
|
546
436
|
if (!this.loadedPages.has(p) && !this.requestedPages.has(p) && !this.pendingPages.has(p)) {
|
|
@@ -602,17 +492,7 @@ export class MrdTable {
|
|
|
602
492
|
// If from and to cover the same local day it was an exact-date filter — restore
|
|
603
493
|
// to exact mode so the user sees the single-date input again.
|
|
604
494
|
if (dataType === 'DATETIME' && existing && existing.operator !== 'isEmpty' && existing.operator !== 'isNotEmpty') {
|
|
605
|
-
|
|
606
|
-
if (typeof display.from === 'string' && display.from)
|
|
607
|
-
display.from = this.utcISOToLocalDate(display.from);
|
|
608
|
-
if (typeof display.to === 'string' && display.to)
|
|
609
|
-
display.to = this.utcISOToLocalDateExclusiveEnd(display.to);
|
|
610
|
-
if (display.from && display.to && display.from === display.to) {
|
|
611
|
-
this.pendingFilter = Object.assign(Object.assign({}, display), { value: display.from, from: undefined, to: undefined });
|
|
612
|
-
}
|
|
613
|
-
else {
|
|
614
|
-
this.pendingFilter = display;
|
|
615
|
-
}
|
|
495
|
+
this.pendingFilter = datetimeFilterToDisplay(existing);
|
|
616
496
|
}
|
|
617
497
|
else {
|
|
618
498
|
this.pendingFilter = existing ? Object.assign({}, existing) : { field: name, dataType, operator: defaultOperator };
|
|
@@ -678,81 +558,15 @@ export class MrdTable {
|
|
|
678
558
|
const current = (_b = (_a = this.pendingFilter) === null || _a === void 0 ? void 0 : _a.values) !== null && _b !== void 0 ? _b : [];
|
|
679
559
|
this.pendingFilter = Object.assign(Object.assign({}, this.pendingFilter), { values: checked ? [...current, key] : current.filter(k => k !== key) });
|
|
680
560
|
}
|
|
681
|
-
filterHasValue(f) {
|
|
682
|
-
if (f.operator === 'isEmpty' || f.operator === 'isNotEmpty')
|
|
683
|
-
return true;
|
|
684
|
-
if (f.values !== undefined && f.values.length > 0)
|
|
685
|
-
return true;
|
|
686
|
-
if (f.value != null && f.value !== '')
|
|
687
|
-
return true;
|
|
688
|
-
if (typeof f.value === 'boolean')
|
|
689
|
-
return true;
|
|
690
|
-
if (f.from != null && f.from !== '')
|
|
691
|
-
return true;
|
|
692
|
-
if (f.to != null && f.to !== '')
|
|
693
|
-
return true;
|
|
694
|
-
return false;
|
|
695
|
-
}
|
|
696
|
-
// Convert a local "YYYY-MM-DD" date string to the UTC ISO string at the
|
|
697
|
-
// start of that local day (midnight). new Date(y, m, d) uses local time.
|
|
698
|
-
dateLocalToUTCStart(dateStr) {
|
|
699
|
-
if (!dateStr)
|
|
700
|
-
return dateStr;
|
|
701
|
-
const [year, month, day] = dateStr.split('-').map(Number);
|
|
702
|
-
return new Date(year, month - 1, day).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
703
|
-
}
|
|
704
|
-
// Start of the day AFTER the given local date (exclusive range end).
|
|
705
|
-
dateLocalToUTCEndExclusive(dateStr) {
|
|
706
|
-
if (!dateStr)
|
|
707
|
-
return dateStr;
|
|
708
|
-
const [year, month, day] = dateStr.split('-').map(Number);
|
|
709
|
-
return new Date(year, month - 1, day + 1).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
710
|
-
}
|
|
711
|
-
// Convert a stored UTC ISO string back to the local "YYYY-MM-DD" date.
|
|
712
|
-
utcISOToLocalDate(utcStr) {
|
|
713
|
-
if (!utcStr)
|
|
714
|
-
return utcStr;
|
|
715
|
-
const d = new Date(utcStr);
|
|
716
|
-
if (isNaN(d.getTime()))
|
|
717
|
-
return utcStr;
|
|
718
|
-
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
719
|
-
}
|
|
720
|
-
// The stored "to" value is the exclusive end (midnight of the next day).
|
|
721
|
-
// Subtract one day to recover the local date the user entered.
|
|
722
|
-
utcISOToLocalDateExclusiveEnd(utcStr) {
|
|
723
|
-
if (!utcStr)
|
|
724
|
-
return utcStr;
|
|
725
|
-
const d = new Date(utcStr);
|
|
726
|
-
if (isNaN(d.getTime()))
|
|
727
|
-
return utcStr;
|
|
728
|
-
d.setDate(d.getDate() - 1);
|
|
729
|
-
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
730
|
-
}
|
|
731
561
|
applyFilter() {
|
|
732
562
|
const f = this.pendingFilter;
|
|
733
563
|
if (!(f === null || f === void 0 ? void 0 : f.field)) {
|
|
734
564
|
this.closeFilterPopup();
|
|
735
565
|
return;
|
|
736
566
|
}
|
|
737
|
-
|
|
738
|
-
// Exact date → range covering the full local day (from = midnight, to = next midnight).
|
|
739
|
-
// "to" is always the exclusive end (midnight of the next local day).
|
|
740
|
-
let normalized = Object.assign({}, f);
|
|
741
|
-
if (f.dataType === 'DATETIME' && f.operator !== 'isEmpty' && f.operator !== 'isNotEmpty') {
|
|
742
|
-
if (typeof normalized.value === 'string' && normalized.value) {
|
|
743
|
-
normalized.from = this.dateLocalToUTCStart(normalized.value);
|
|
744
|
-
normalized.to = this.dateLocalToUTCEndExclusive(normalized.value);
|
|
745
|
-
normalized.value = undefined;
|
|
746
|
-
}
|
|
747
|
-
else {
|
|
748
|
-
if (typeof normalized.from === 'string' && normalized.from)
|
|
749
|
-
normalized.from = this.dateLocalToUTCStart(normalized.from);
|
|
750
|
-
if (typeof normalized.to === 'string' && normalized.to)
|
|
751
|
-
normalized.to = this.dateLocalToUTCEndExclusive(normalized.to);
|
|
752
|
-
}
|
|
753
|
-
}
|
|
567
|
+
const normalized = normalizeDatetimeFilter(f);
|
|
754
568
|
const next = new Map(this.activeFilters);
|
|
755
|
-
if (
|
|
569
|
+
if (filterHasValue(normalized)) {
|
|
756
570
|
next.set(normalized.field, normalized);
|
|
757
571
|
}
|
|
758
572
|
else {
|
|
@@ -807,140 +621,53 @@ export class MrdTable {
|
|
|
807
621
|
toggleViewPopover(e) {
|
|
808
622
|
e.stopPropagation();
|
|
809
623
|
if (this.viewPopoverOpen) {
|
|
810
|
-
this.
|
|
811
|
-
if (this.viewPopoverClickHandler) {
|
|
812
|
-
document.removeEventListener('click', this.viewPopoverClickHandler);
|
|
813
|
-
this.viewPopoverClickHandler = null;
|
|
814
|
-
}
|
|
624
|
+
this.closeViewPopover();
|
|
815
625
|
return;
|
|
816
626
|
}
|
|
817
627
|
this.viewPopoverOpen = true;
|
|
818
|
-
this.viewPopoverClickHandler = () =>
|
|
819
|
-
|
|
628
|
+
this.viewPopoverClickHandler = () => this.closeViewPopover();
|
|
629
|
+
document.addEventListener('click', this.viewPopoverClickHandler);
|
|
630
|
+
}
|
|
631
|
+
closeViewPopover() {
|
|
632
|
+
this.viewPopoverOpen = false;
|
|
633
|
+
if (this.viewPopoverClickHandler) {
|
|
820
634
|
document.removeEventListener('click', this.viewPopoverClickHandler);
|
|
821
635
|
this.viewPopoverClickHandler = null;
|
|
822
|
-
}
|
|
823
|
-
document.addEventListener('click', this.viewPopoverClickHandler);
|
|
636
|
+
}
|
|
824
637
|
}
|
|
825
638
|
// ── Render: toolbar ────────────────────────────────────────────────────────
|
|
826
639
|
renderToolbar() {
|
|
827
640
|
var _a;
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
} }, v.label)))))), h("button", { class: "mrd-table__view-arrow", "aria-label": "Next view", onClick: () => this.handleViewSwitch((this.activeViewIdx + 1) % allViews.length) }, "\u25B6")))), hasActions && (h("div", { class: "mrd-table__toolbar-right" }, actions.map(a => {
|
|
842
|
-
var _a, _b, _c;
|
|
843
|
-
const createTypes = a.action === 'create' ? (_a = this.item) === null || _a === void 0 ? void 0 : _a.createTypes : null;
|
|
844
|
-
if (createTypes === null || createTypes === void 0 ? void 0 : createTypes.length) {
|
|
845
|
-
return (h("div", { class: "mrd-table__create-picker-wrap", key: `action-${a.action}` }, h("button", { class: `mrd-table__action mrd-table__action--${(_b = a.variant) !== null && _b !== void 0 ? _b : 'secondary'}`, onClick: () => this.toggleCreatePicker() }, a.icon
|
|
846
|
-
? h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, h("use", { href: a.icon }))
|
|
847
|
-
: a.label, h("span", { class: "mrd-table__action-tooltip" }, a.label)), this.createPickerOpen && (h("div", { class: "mrd-table__create-picker" }, createTypes.map(ct => (h("button", { key: ct.type, class: "mrd-table__create-picker-item", onClick: () => {
|
|
848
|
-
this.mrdAction.emit(this.buildActionDetail('create', ct.type));
|
|
849
|
-
this.closeCreatePicker();
|
|
850
|
-
} }, ct.label)))))));
|
|
851
|
-
}
|
|
852
|
-
return (h("button", { key: `action-${a.action}`, class: `mrd-table__action mrd-table__action--${(_c = a.variant) !== null && _c !== void 0 ? _c : 'secondary'}`, disabled: a.disabled, onClick: () => this.mrdAction.emit(this.buildActionDetail(a.action)) }, a.icon
|
|
853
|
-
? h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, h("use", { href: a.icon }))
|
|
854
|
-
: a.label, h("span", { class: "mrd-table__action-tooltip" }, a.label)));
|
|
855
|
-
})))));
|
|
641
|
+
return (h(Toolbar, { locale: this.locale, filterMode: this.filterMode, filterCount: this.activeFilters.size, actions: this.tableActions, views: this.allViews, activeViewIdx: this.activeViewIdx, viewPopoverOpen: this.viewPopoverOpen, createPickerOpen: this.createPickerOpen, createTypes: (_a = this.item) === null || _a === void 0 ? void 0 : _a.createTypes, cb: {
|
|
642
|
+
onFilterToggle: () => this.handleFilterToggle(),
|
|
643
|
+
onClearAllFilters: () => this.clearAllFilters(),
|
|
644
|
+
onViewSwitch: idx => this.handleViewSwitch(idx),
|
|
645
|
+
onToggleViewPopover: e => this.toggleViewPopover(e),
|
|
646
|
+
onCloseViewPopover: () => this.closeViewPopover(),
|
|
647
|
+
onToggleCreatePicker: () => this.toggleCreatePicker(),
|
|
648
|
+
onCreate: basicType => {
|
|
649
|
+
this.mrdAction.emit(this.buildActionDetail('create', basicType));
|
|
650
|
+
this.closeCreatePicker();
|
|
651
|
+
},
|
|
652
|
+
onAction: action => this.mrdAction.emit(this.buildActionDetail(action)),
|
|
653
|
+
} }));
|
|
856
654
|
}
|
|
857
655
|
// ── Render: filter popup ───────────────────────────────────────────────────
|
|
858
|
-
renderFilterEditor(col) {
|
|
859
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
860
|
-
const pf = (_a = this.pendingFilter) !== null && _a !== void 0 ? _a : {};
|
|
861
|
-
const dataType = this.colDataType(col);
|
|
862
|
-
if (NO_FILTER_TYPES.has(dataType)) {
|
|
863
|
-
return h("p", { class: "mrd-table__filter-no-support" }, t('filter_no_support', this.locale));
|
|
864
|
-
}
|
|
865
|
-
if (dataType === 'BOOLEAN') {
|
|
866
|
-
const boolOp = pf.operator;
|
|
867
|
-
const noValueOp = boolOp === 'isEmpty' || boolOp === 'isNotEmpty';
|
|
868
|
-
return (h("div", { class: "mrd-table__filter-radio-group" }, [
|
|
869
|
-
{ labelKey: 'filter_all', value: null },
|
|
870
|
-
{ labelKey: 'yes', value: true },
|
|
871
|
-
{ labelKey: 'no', value: false },
|
|
872
|
-
].map(opt => (h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `bf-${this.openFilterCol}`, checked: !noValueOp && pf.value === opt.value, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined, value: opt.value }); } }), t(opt.labelKey, this.locale)))), h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `bf-${this.openFilterCol}`, checked: boolOp === 'isEmpty', onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: 'isEmpty', value: undefined }); } }), t('filter_is_empty', this.locale)), h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `bf-${this.openFilterCol}`, checked: boolOp === 'isNotEmpty', onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: 'isNotEmpty', value: undefined }); } }), t('filter_is_not_empty', this.locale))));
|
|
873
|
-
}
|
|
874
|
-
if (dataType === 'LIST') {
|
|
875
|
-
const items = (_b = col.listItems) !== null && _b !== void 0 ? _b : [];
|
|
876
|
-
const selected = (_c = pf.values) !== null && _c !== void 0 ? _c : [];
|
|
877
|
-
return (h("div", { class: "mrd-table__filter-list" }, h("div", { class: "mrd-table__filter-list-controls" }, h("button", { class: "mrd-table__filter-list-btn", onClick: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { values: items.map(i => i.key) }); } }, t('filter_select_all', this.locale)), h("button", { class: "mrd-table__filter-list-btn", onClick: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { values: [] }); } }, t('filter_select_none', this.locale))), items.map(item => (h("label", { class: "mrd-table__filter-checkbox-label" }, h("input", { type: "checkbox", checked: selected.includes(item.key), onChange: (e) => this.togglePendingValue(item.key, e.target.checked) }), item.label)))));
|
|
878
|
-
}
|
|
879
|
-
if (TEXT_TYPES.has(dataType) || dataType === 'RELATION') {
|
|
880
|
-
const op = (_d = pf.operator) !== null && _d !== void 0 ? _d : 'startsWith';
|
|
881
|
-
const noInput = op === 'isEmpty' || op === 'isNotEmpty';
|
|
882
|
-
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => this.setPending('operator', e.target.value) }, [
|
|
883
|
-
{ val: 'startsWith', labelKey: 'filter_starts_with' },
|
|
884
|
-
{ val: 'equals', labelKey: 'filter_equals' },
|
|
885
|
-
{ val: 'isEmpty', labelKey: 'filter_is_empty' },
|
|
886
|
-
{ val: 'isNotEmpty', labelKey: 'filter_is_not_empty' },
|
|
887
|
-
].map(o => h("option", { value: o.val, selected: op === o.val }, t(o.labelKey, this.locale)))), !noInput && (h("input", { type: "text", class: "mrd-table__filter-input", value: String((_e = pf.value) !== null && _e !== void 0 ? _e : ''), placeholder: t('filter_search_value', this.locale), onInput: (e) => this.setPending('value', e.target.value) }))));
|
|
888
|
-
}
|
|
889
|
-
if (NUMERIC_TYPES.has(dataType)) {
|
|
890
|
-
const numOp = pf.operator;
|
|
891
|
-
const noInput = numOp === 'isEmpty' || numOp === 'isNotEmpty';
|
|
892
|
-
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
893
|
-
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
894
|
-
const val = e.target.value;
|
|
895
|
-
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
896
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined });
|
|
897
|
-
}
|
|
898
|
-
else {
|
|
899
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined });
|
|
900
|
-
}
|
|
901
|
-
} }, h("option", { value: "", selected: !noInput }, t('filter_has_value', this.locale)), h("option", { value: "isEmpty", selected: numOp === 'isEmpty' }, t('filter_is_empty', this.locale)), h("option", { value: "isNotEmpty", selected: numOp === 'isNotEmpty' }, t('filter_is_not_empty', this.locale))), !noInput && (h("div", { class: "mrd-table__filter-editor" }, h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `nm-${this.openFilterCol}`, checked: !rangeMode, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { from: undefined, to: undefined }); } }), t('filter_exact', this.locale)), h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `nm-${this.openFilterCol}`, checked: rangeMode, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { value: undefined, from: null, to: null }); } }), t('filter_range', this.locale))), !rangeMode ? (h("input", { type: "number", class: "mrd-table__filter-input", value: pf.value != null ? String(pf.value) : '', onInput: (e) => this.setPending('value', e.target.value) })) : (h("div", { class: "mrd-table__filter-range" }, h("input", { type: "number", class: "mrd-table__filter-input", placeholder: t('filter_from', this.locale), value: pf.from != null ? String(pf.from) : '', onInput: (e) => this.setPending('from', e.target.value) }), h("span", { class: "mrd-table__filter-range-sep" }, "\u2013"), h("input", { type: "number", class: "mrd-table__filter-input", placeholder: t('filter_to', this.locale), value: pf.to != null ? String(pf.to) : '', onInput: (e) => this.setPending('to', e.target.value) })))))));
|
|
902
|
-
}
|
|
903
|
-
if (dataType === 'DATETIME') {
|
|
904
|
-
const dtOp = pf.operator;
|
|
905
|
-
const noInput = dtOp === 'isEmpty' || dtOp === 'isNotEmpty';
|
|
906
|
-
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
907
|
-
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
908
|
-
const val = e.target.value;
|
|
909
|
-
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
910
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined });
|
|
911
|
-
}
|
|
912
|
-
else {
|
|
913
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined });
|
|
914
|
-
}
|
|
915
|
-
} }, h("option", { value: "", selected: !noInput }, t('filter_has_value', this.locale)), h("option", { value: "isEmpty", selected: dtOp === 'isEmpty' }, t('filter_is_empty', this.locale)), h("option", { value: "isNotEmpty", selected: dtOp === 'isNotEmpty' }, t('filter_is_not_empty', this.locale))), !noInput && (h("div", { class: "mrd-table__filter-editor" }, h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `dt-${this.openFilterCol}`, checked: !rangeMode, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { from: undefined, to: undefined }); } }), t('filter_exact', this.locale)), h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `dt-${this.openFilterCol}`, checked: rangeMode, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { value: undefined, from: null, to: null }); } }), t('filter_range', this.locale))), !rangeMode ? (h("input", { type: "date", class: "mrd-table__filter-input", value: String((_f = pf.value) !== null && _f !== void 0 ? _f : ''), onInput: (e) => this.setPending('value', e.target.value) })) : (h("div", { class: "mrd-table__filter-range mrd-table__filter-range--stacked" }, h("label", { class: "mrd-table__filter-range-label" }, t('filter_from', this.locale)), h("input", { type: "date", class: "mrd-table__filter-input", value: pf.from != null ? String(pf.from) : '', onInput: (e) => this.setPending('from', e.target.value) }), h("label", { class: "mrd-table__filter-range-label" }, t('filter_to', this.locale)), h("input", { type: "date", class: "mrd-table__filter-input", value: pf.to != null ? String(pf.to) : '', onInput: (e) => this.setPending('to', e.target.value) })))))));
|
|
916
|
-
}
|
|
917
|
-
if (DATE_TYPES.has(dataType)) {
|
|
918
|
-
const inputType = dataType === 'DATE' ? 'date' : 'time';
|
|
919
|
-
const dtdOp = pf.operator;
|
|
920
|
-
const noInput = dtdOp === 'isEmpty' || dtdOp === 'isNotEmpty';
|
|
921
|
-
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
922
|
-
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
923
|
-
const val = e.target.value;
|
|
924
|
-
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
925
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined });
|
|
926
|
-
}
|
|
927
|
-
else {
|
|
928
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined });
|
|
929
|
-
}
|
|
930
|
-
} }, h("option", { value: "", selected: !noInput }, t('filter_has_value', this.locale)), h("option", { value: "isEmpty", selected: dtdOp === 'isEmpty' }, t('filter_is_empty', this.locale)), h("option", { value: "isNotEmpty", selected: dtdOp === 'isNotEmpty' }, t('filter_is_not_empty', this.locale))), !noInput && (h("div", { class: "mrd-table__filter-editor" }, h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `dt-${this.openFilterCol}`, checked: !rangeMode, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { from: undefined, to: undefined }); } }), t('filter_exact', this.locale)), h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `dt-${this.openFilterCol}`, checked: rangeMode, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { value: undefined, from: null, to: null }); } }), t('filter_range', this.locale))), !rangeMode ? (h("input", { type: inputType, class: "mrd-table__filter-input", value: String((_g = pf.value) !== null && _g !== void 0 ? _g : ''), onInput: (e) => this.setPending('value', e.target.value) })) : (h("div", { class: "mrd-table__filter-range" }, h("input", { type: inputType, class: "mrd-table__filter-input", placeholder: t('filter_from', this.locale), value: pf.from != null ? String(pf.from) : '', onInput: (e) => this.setPending('from', e.target.value) }), h("input", { type: inputType, class: "mrd-table__filter-input", placeholder: t('filter_to', this.locale), value: pf.to != null ? String(pf.to) : '', onInput: (e) => this.setPending('to', e.target.value) })))))));
|
|
931
|
-
}
|
|
932
|
-
return null;
|
|
933
|
-
}
|
|
934
656
|
renderFilterPopup() {
|
|
935
|
-
var _a;
|
|
936
657
|
if (!this.openFilterCol || !this.pendingFilter)
|
|
937
658
|
return null;
|
|
938
659
|
const col = this.columns.find(c => this.colName(c) === this.openFilterCol);
|
|
939
660
|
if (!col)
|
|
940
661
|
return null;
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
662
|
+
return (h(FilterPopup, { col: col, dataType: this.colDataType(col), openFilterCol: this.openFilterCol, pendingFilter: this.pendingFilter, popupPos: this.popupPos, sortField: this.sortField, sortDir: this.sortDir, locale: this.locale, cb: {
|
|
663
|
+
onSetPending: (key, val) => this.setPending(key, val),
|
|
664
|
+
onReplacePending: pf => (this.pendingFilter = pf),
|
|
665
|
+
onToggleValue: (key, checked) => this.togglePendingValue(key, checked),
|
|
666
|
+
onApplySort: dir => this.applySort(col, dir),
|
|
667
|
+
onApply: () => this.applyFilter(),
|
|
668
|
+
onClear: () => this.clearFilter(),
|
|
669
|
+
onClose: () => this.closeFilterPopup(),
|
|
670
|
+
} }));
|
|
944
671
|
}
|
|
945
672
|
// ── Render: footer ────────────────────────────────────────────────────────
|
|
946
673
|
renderFooter(rowCount, effectiveTotal, isTotalKnown = true) {
|
|
@@ -965,54 +692,11 @@ export class MrdTable {
|
|
|
965
692
|
}
|
|
966
693
|
// ── Render: cell ──────────────────────────────────────────────────────────
|
|
967
694
|
renderCell(col, row) {
|
|
968
|
-
|
|
969
|
-
const numericTypes = new Set(['INTEGER', 'DECIMAL', 'PERCENTAGE', 'CURRENCY']);
|
|
970
|
-
const dataType = (_a = col.dataType) !== null && _a !== void 0 ? _a : '';
|
|
971
|
-
const isNumeric = col.type === 'FIELD' && numericTypes.has(dataType);
|
|
972
|
-
const isFile = col.type === 'FIELD' && (dataType === 'FILE' || dataType === 'IMAGE');
|
|
973
|
-
if (isFile) {
|
|
974
|
-
const name = (_b = col.name) !== null && _b !== void 0 ? _b : '';
|
|
975
|
-
const fileVal = row === null || row === void 0 ? void 0 : row[name];
|
|
976
|
-
const href = fileVal === null || fileVal === void 0 ? void 0 : fileVal.href;
|
|
977
|
-
const fileName = fileVal === null || fileVal === void 0 ? void 0 : fileVal.fileName;
|
|
978
|
-
return (h("td", { class: "mrd-table__cell" }, href && fileName ? (h("button", { class: "mrd-table__file-btn", title: fileName, onClick: (e) => {
|
|
979
|
-
e.stopPropagation();
|
|
980
|
-
this.mrdDownload.emit({ href, fileName });
|
|
981
|
-
} }, h("svg", { class: "mrd-table__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 7V3.5L18.5 9H13zm-3 8l-3-3 1.41-1.41L10 14.17l4.59-4.58L16 11l-6 6z" })), t('download', this.locale))) : ''));
|
|
982
|
-
}
|
|
983
|
-
if (dataType === 'JSON') {
|
|
984
|
-
const name = (_c = col.name) !== null && _c !== void 0 ? _c : '';
|
|
985
|
-
const rawValue = name ? row === null || row === void 0 ? void 0 : row[name] : undefined;
|
|
986
|
-
if (rawValue == null || rawValue === '')
|
|
987
|
-
return h("td", { class: "mrd-table__cell" });
|
|
988
|
-
const compactHtml = CellRenderer.formatJson(rawValue, true);
|
|
989
|
-
const prettyHtml = CellRenderer.formatJson(rawValue, false);
|
|
990
|
-
return (h("td", { class: "mrd-table__cell" }, h("span", { class: "mrd-table__json-preview", innerHTML: compactHtml }), h("button", { class: "mrd-table__textblock-btn", onClick: (e) => { e.stopPropagation(); this.openJsonModal(prettyHtml); }, "aria-label": t('textblock_show_more', this.locale) }, "\u22EF")));
|
|
991
|
-
}
|
|
992
|
-
const TEXTBLOCK_MAX = 200;
|
|
993
|
-
if (dataType === 'TEXTBLOCK') {
|
|
994
|
-
const full = CellRenderer.render(col, row, this.locale);
|
|
995
|
-
if (full.length <= TEXTBLOCK_MAX) {
|
|
996
|
-
return h("td", { class: "mrd-table__cell" }, full);
|
|
997
|
-
}
|
|
998
|
-
const preview = full.slice(0, TEXTBLOCK_MAX) + '…';
|
|
999
|
-
return (h("td", { class: "mrd-table__cell" }, preview, h("button", { class: "mrd-table__textblock-btn", onClick: (e) => { e.stopPropagation(); this.openTextblockModal(full); }, "aria-label": t('textblock_show_more', this.locale) }, "\u22EF")));
|
|
1000
|
-
}
|
|
1001
|
-
const value = CellRenderer.render(col, row, this.locale);
|
|
1002
|
-
return (h("td", { class: `mrd-table__cell${isNumeric ? ' mrd-table__cell--numeric' : ''}` }, value));
|
|
695
|
+
return (h(TableCell, { col: col, row: row, locale: this.locale, onDownload: detail => this.mrdDownload.emit(detail), onOpenTextblock: full => this.openTextblockModal(full), onOpenJson: html => this.openJsonModal(html) }));
|
|
1003
696
|
}
|
|
1004
697
|
// ── Render: totals row ────────────────────────────────────────────────────
|
|
1005
698
|
renderTotalsRow() {
|
|
1006
|
-
|
|
1007
|
-
return null;
|
|
1008
|
-
if (!this.columns.some(c => c.type === 'FIELD' && c.aggregate))
|
|
1009
|
-
return null;
|
|
1010
|
-
return (h("tfoot", null, h("tr", { class: "mrd-table__totals-row" }, this.columns.map(col => {
|
|
1011
|
-
var _a;
|
|
1012
|
-
const val = this.renderAggregationValue(col);
|
|
1013
|
-
const isNumeric = col.type === 'FIELD' && NUMERIC_TYPES.has((_a = col.dataType) !== null && _a !== void 0 ? _a : '');
|
|
1014
|
-
return (h("td", { class: `mrd-table__totals-cell${isNumeric ? ' mrd-table__totals-cell--numeric' : ''}` }, val));
|
|
1015
|
-
}))));
|
|
699
|
+
return h(TotalsRow, { columns: this.columns, aggregations: this.aggregations, locale: this.locale });
|
|
1016
700
|
}
|
|
1017
701
|
// ── Render ─────────────────────────────────────────────────────────────────
|
|
1018
702
|
render() {
|
|
@@ -1032,7 +716,7 @@ export class MrdTable {
|
|
|
1032
716
|
isFiltered ? 'mrd-table__header--filtered' : '',
|
|
1033
717
|
this.filterMode ? 'mrd-table__header--sortable' : '',
|
|
1034
718
|
].filter(Boolean).join(' ');
|
|
1035
|
-
return (h("th", { class: cls, onClick: this.filterMode ? (e) => this.handleFilterOpen(col, e) : undefined }, h("span", { class: "mrd-table__header-label" }, (_a = col.label) !== null && _a !== void 0 ? _a : ''), isFiltered &&
|
|
719
|
+
return (h("th", { class: cls, onClick: this.filterMode ? (e) => this.handleFilterOpen(col, e) : undefined }, h("span", { class: "mrd-table__header-label" }, (_a = col.label) !== null && _a !== void 0 ? _a : ''), isFiltered && h(FilterIcon, null)));
|
|
1036
720
|
}))), h("tbody", null, (_b = this.rows) === null || _b === void 0 ? void 0 : _b.map((row, i) => (h("tr", { class: "mrd-table__row mrd-table__row--clickable", style: { background: i % 2 === 0 ? '' : 'var(--mrd-color-neutral-100)' }, onClick: () => this.mrdRowClick.emit(row) }, this.columns.map(col => this.renderCell(col, row)))))), this.renderTotalsRow()), (!this.rows || this.rows.length === 0) && (h("p", { class: "mrd-table__empty" }, t('no_results', this.locale)))), this.renderFooter((_c = this.rows) === null || _c === void 0 ? void 0 : _c.length), this.renderFilterPopup(), this.renderTextblockModal(), this.renderJsonModal()));
|
|
1037
721
|
}
|
|
1038
722
|
// ── Paginated / virtual-scroll mode ────────────────────────────────────
|
|
@@ -1040,12 +724,7 @@ export class MrdTable {
|
|
|
1040
724
|
// if any loaded page is shorter than pageSize it is the last page,
|
|
1041
725
|
// so the true total cannot exceed (pageNum * pageSize + pageRows.length).
|
|
1042
726
|
// aggregationsTotal (from setAggregations) takes priority over the totalElements prop.
|
|
1043
|
-
|
|
1044
|
-
for (const [pageNum, pageRows] of this.loadedPages) {
|
|
1045
|
-
if (pageRows.length < this.pageSize) {
|
|
1046
|
-
effectiveTotal = Math.min(effectiveTotal, pageNum * this.pageSize + pageRows.length);
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
727
|
+
const effectiveTotal = computeEffectiveTotal(this.loadedPages, this.pageSize, this.baseTotal);
|
|
1049
728
|
// Clamp renderEnd to what we actually know exists (-1 when empty)
|
|
1050
729
|
const clampedEnd = Math.min(this.renderEnd, effectiveTotal - 1);
|
|
1051
730
|
const colCount = this.columns.length;
|
|
@@ -1076,21 +755,14 @@ export class MrdTable {
|
|
|
1076
755
|
isActive ? `mrd-table__header--sorted-${this.sortDir}` : '',
|
|
1077
756
|
isFiltered ? 'mrd-table__header--filtered' : '',
|
|
1078
757
|
].filter(Boolean).join(' ');
|
|
1079
|
-
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 &&
|
|
1080
|
-
}))), 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()));
|
|
1081
|
-
}
|
|
1082
|
-
renderFilterIcon() {
|
|
1083
|
-
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" }))));
|
|
758
|
+
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 && h(FilterIcon, null)));
|
|
759
|
+
}))), 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(), this.renderJsonModal()));
|
|
1084
760
|
}
|
|
1085
761
|
renderTextblockModal() {
|
|
1086
|
-
|
|
1087
|
-
return null;
|
|
1088
|
-
return (h("div", { class: "mrd-table__modal-backdrop", onClick: () => this.closeTextblockModal(), role: "dialog", "aria-modal": "true" }, h("div", { class: "mrd-table__modal", onClick: (e) => e.stopPropagation() }, h("button", { class: "mrd-table__modal-close", onClick: () => this.closeTextblockModal(), "aria-label": t('close', this.locale) }, "\u2715"), h("p", { class: "mrd-table__modal-text" }, this.textblockModal))));
|
|
762
|
+
return h(TextblockModal, { text: this.textblockModal, locale: this.locale, onClose: () => this.closeTextblockModal() });
|
|
1089
763
|
}
|
|
1090
764
|
renderJsonModal() {
|
|
1091
|
-
|
|
1092
|
-
return null;
|
|
1093
|
-
return (h("div", { class: "mrd-table__modal-backdrop", onClick: () => this.closeJsonModal(), role: "dialog", "aria-modal": "true" }, h("div", { class: "mrd-table__modal", onClick: (e) => e.stopPropagation() }, h("button", { class: "mrd-table__modal-close", onClick: () => this.closeJsonModal(), "aria-label": t('close', this.locale) }, "\u2715"), h("pre", { class: "mrd-table__modal-json", innerHTML: this.jsonModal }))));
|
|
765
|
+
return h(JsonModal, { html: this.jsonModal, locale: this.locale, onClose: () => this.closeJsonModal() });
|
|
1094
766
|
}
|
|
1095
767
|
static get is() { return "mrd-table"; }
|
|
1096
768
|
static get encapsulation() { return "scoped"; }
|
|
@@ -1115,7 +787,7 @@ export class MrdTable {
|
|
|
1115
787
|
"references": {
|
|
1116
788
|
"ClientLayoutItem": {
|
|
1117
789
|
"location": "import",
|
|
1118
|
-
"path": "
|
|
790
|
+
"path": "../../../types/client-layout",
|
|
1119
791
|
"id": "src/types/client-layout.ts::ClientLayoutItem",
|
|
1120
792
|
"referenceLocation": "ClientLayoutItem"
|
|
1121
793
|
}
|
|
@@ -1455,7 +1127,7 @@ export class MrdTable {
|
|
|
1455
1127
|
},
|
|
1456
1128
|
"AggregationResult": {
|
|
1457
1129
|
"location": "import",
|
|
1458
|
-
"path": "
|
|
1130
|
+
"path": "../../../types/client-layout",
|
|
1459
1131
|
"id": "src/types/client-layout.ts::AggregationResult",
|
|
1460
1132
|
"referenceLocation": "AggregationResult"
|
|
1461
1133
|
}
|