@mmlogic/components 0.3.10 → 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 +2 -2
- package/dist/cjs/mosterdcomponents.cjs.js +2 -2
- package/dist/cjs/mrd-boolean-field_23.cjs.entry.js +1280 -1073
- 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 +54 -8
- 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} +17 -4
- package/dist/collection/components/{mrd-document-list → documents/mrd-document-list}/mrd-document-list.js +166 -237
- 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 +58 -133
- 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 +10 -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 +3 -3
- package/dist/esm/mosterdcomponents.js +3 -3
- package/dist/esm/mrd-boolean-field_23.entry.js +1280 -1073
- 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 +7 -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 +28 -38
- 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 -8
- 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 +36 -5
- package/dist/types/types/client-layout.d.ts +5 -0
- 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/cell-renderer-B-AJDBcj.js.map +0 -1
- package/dist/mosterdcomponents/client-layout-ChqRA3AF.js.map +0 -1
- package/dist/mosterdcomponents/format-BAfsQfy1.js.map +0 -1
- package/dist/mosterdcomponents/i18n-s1XrKcD2.js.map +0 -1
- package/dist/mosterdcomponents/index-DkY-NQj0.js.map +0 -1
- package/dist/mosterdcomponents/index-DwF_Sp__.js.map +0 -1
- package/dist/mosterdcomponents/index.esm.js.map +0 -1
- package/dist/mosterdcomponents/mosterdcomponents.esm.js.map +0 -1
- package/dist/mosterdcomponents/p-69452249.entry.js +0 -1
- package/dist/mosterdcomponents/p-_tsCCkAi.js +0 -2
- package/dist/mosterdcomponents/quill-C9pgw_k-.js.map +0 -1
- package/dist/mosterdcomponents/validation-Br9k2Ztw.js.map +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
|
}
|