@mmlogic/components 0.1.24 → 0.1.26

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.
Files changed (45) hide show
  1. package/dist/cjs/loader.cjs.js +1 -1
  2. package/dist/cjs/mosterdcomponents.cjs.js +1 -1
  3. package/dist/cjs/mrd-boolean-field_19.cjs.entry.js +3142 -0
  4. package/dist/collection/collection-manifest.json +1 -0
  5. package/dist/collection/components/mrd-layout-section/mrd-layout-section.js +733 -0
  6. package/dist/collection/components/mrd-layout-section/mrd-layout-section.scss +354 -0
  7. package/dist/collection/components/mrd-longtext-field/mrd-longtext-field.js +1 -1
  8. package/dist/collection/components/mrd-number-field/mrd-number-field.js +1 -1
  9. package/dist/collection/components/mrd-table/mrd-table.js +53 -42
  10. package/dist/collection/components/mrd-table/mrd-table.scss +29 -71
  11. package/dist/collection/components/mrd-text-field/mrd-text-field.js +1 -1
  12. package/dist/collection/components/mrd-textarea-field/mrd-textarea-field.js +1 -1
  13. package/dist/collection/components/mrd-time-field/mrd-time-field.js +1 -1
  14. package/dist/collection/dev/app.js +109 -3
  15. package/dist/collection/dev/example-data.js +324 -0
  16. package/dist/collection/utils/cell-renderer.js +26 -0
  17. package/dist/components/mrd-layout-section.d.ts +11 -0
  18. package/dist/components/mrd-layout-section.js +1 -0
  19. package/dist/components/mrd-longtext-field2.js +1 -1
  20. package/dist/components/mrd-number-field2.js +1 -1
  21. package/dist/components/mrd-table.js +1 -1
  22. package/dist/components/mrd-table2.js +1 -0
  23. package/dist/components/mrd-text-field2.js +1 -1
  24. package/dist/components/mrd-textarea-field2.js +1 -1
  25. package/dist/components/mrd-time-field2.js +1 -1
  26. package/dist/esm/loader.js +1 -1
  27. package/dist/esm/mosterdcomponents.js +1 -1
  28. package/dist/esm/mrd-boolean-field_19.entry.js +3122 -0
  29. package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
  30. package/dist/mosterdcomponents/p-e1a5587b.entry.js +1 -0
  31. package/dist/types/components/mrd-layout-section/mrd-layout-section.d.ts +93 -0
  32. package/dist/types/components/mrd-table/mrd-table.d.ts +5 -6
  33. package/dist/types/components.d.ts +128 -8
  34. package/dist/types/types/client-layout.d.ts +19 -0
  35. package/dist/types/utils/cell-renderer.d.ts +9 -1
  36. package/package.json +1 -1
  37. package/dist/cjs/format-DExY8_nu.js +0 -328
  38. package/dist/cjs/mrd-boolean-field_17.cjs.entry.js +0 -1554
  39. package/dist/cjs/mrd-table.cjs.entry.js +0 -888
  40. package/dist/esm/format-CcRjWvcb.js +0 -319
  41. package/dist/esm/mrd-boolean-field_17.entry.js +0 -1536
  42. package/dist/esm/mrd-table.entry.js +0 -886
  43. package/dist/mosterdcomponents/p-17fe94c6.entry.js +0 -1
  44. package/dist/mosterdcomponents/p-3d856b27.entry.js +0 -1
  45. package/dist/mosterdcomponents/p-CcRjWvcb.js +0 -1
@@ -0,0 +1,354 @@
1
+ .mrd-layout-section {
2
+ font-family: var(--mrd-font-family);
3
+ font-size: var(--mrd-font-size-base);
4
+ color: var(--mrd-color-neutral-800);
5
+ }
6
+
7
+ .mrd-layout-section__field {
8
+ display: grid;
9
+ grid-template-columns: 200px 1fr;
10
+ align-items: baseline;
11
+ gap: 0 var(--mrd-space-2);
12
+ padding: var(--mrd-space-1) 0;
13
+ }
14
+
15
+ .mrd-layout-section__field-label {
16
+ font-size: var(--mrd-font-size-xs);
17
+ font-weight: var(--mrd-font-weight-normal);
18
+ color: var(--mrd-color-neutral-500);
19
+ padding-top: 1px;
20
+ }
21
+
22
+ .mrd-layout-section__field-value {
23
+ font-size: var(--mrd-font-size-sm);
24
+ font-weight: var(--mrd-font-weight-medium);
25
+ color: var(--mrd-color-neutral-800);
26
+ word-break: break-word;
27
+ }
28
+
29
+ .mrd-layout-section__field-header {
30
+ font-size: var(--mrd-font-size-2xl);
31
+ font-weight: var(--mrd-font-weight-bold);
32
+ color: var(--mrd-color-neutral-900);
33
+ margin: 0 0 var(--mrd-space-4) 0;
34
+ padding: 0;
35
+ }
36
+
37
+ .mrd-layout-section__header {
38
+ font-size: var(--mrd-font-size-xl);
39
+ font-weight: var(--mrd-font-weight-semibold);
40
+ color: var(--mrd-color-neutral-800);
41
+ margin: var(--mrd-space-4) 0 var(--mrd-space-2) 0;
42
+ padding: 0;
43
+ }
44
+
45
+ .mrd-layout-section__text {
46
+ font-size: var(--mrd-font-size-base);
47
+ color: var(--mrd-color-neutral-700);
48
+ line-height: var(--mrd-line-height-relaxed);
49
+ margin: var(--mrd-space-2) 0;
50
+ }
51
+
52
+ .mrd-layout-section__navigate {
53
+ display: inline-flex;
54
+ align-items: center;
55
+ gap: var(--mrd-space-2);
56
+ padding: var(--mrd-space-2) var(--mrd-space-3);
57
+ background: none;
58
+ border: 1px solid var(--mrd-color-neutral-300);
59
+ border-radius: var(--mrd-border-radius);
60
+ font-family: var(--mrd-font-family);
61
+ font-size: var(--mrd-font-size-sm);
62
+ color: var(--mrd-color-primary);
63
+ cursor: pointer;
64
+ margin: var(--mrd-space-2) 0;
65
+ }
66
+
67
+ .mrd-layout-section__navigate:hover {
68
+ background-color: var(--mrd-color-primary-light);
69
+ border-color: var(--mrd-color-primary);
70
+ }
71
+
72
+ .mrd-layout-section__link {
73
+ color: var(--mrd-color-primary);
74
+ text-decoration: none;
75
+ }
76
+
77
+ .mrd-layout-section__link:hover {
78
+ text-decoration: underline;
79
+ }
80
+
81
+ .mrd-layout-section__relation-link {
82
+ background: none;
83
+ border: none;
84
+ padding: 0;
85
+ font-family: var(--mrd-font-family);
86
+ font-size: var(--mrd-font-size-sm);
87
+ font-weight: var(--mrd-font-weight-semibold);
88
+ color: var(--mrd-color-primary);
89
+ cursor: pointer;
90
+ text-align: left;
91
+ }
92
+
93
+ .mrd-layout-section__relation-link:hover {
94
+ text-decoration: underline;
95
+ }
96
+
97
+ .mrd-layout-section__download-link {
98
+ display: inline-flex;
99
+ align-items: center;
100
+ gap: var(--mrd-space-1);
101
+ background: none;
102
+ border: none;
103
+ padding: 0;
104
+ font-family: var(--mrd-font-family);
105
+ font-size: var(--mrd-font-size-sm);
106
+ color: var(--mrd-color-primary);
107
+ cursor: pointer;
108
+ text-align: left;
109
+ }
110
+
111
+ .mrd-layout-section__download-link:hover {
112
+ text-decoration: underline;
113
+ color: var(--mrd-color-primary-dark);
114
+ }
115
+
116
+ .mrd-layout-section__file-icon {
117
+ flex-shrink: 0;
118
+ width: 1rem;
119
+ height: 1rem;
120
+ }
121
+
122
+ .mrd-layout-section__boolean--true {
123
+ color: var(--mrd-color-success);
124
+ font-weight: var(--mrd-font-weight-semibold);
125
+ }
126
+
127
+ .mrd-layout-section__boolean--false {
128
+ color: var(--mrd-color-neutral-400);
129
+ }
130
+
131
+ .mrd-layout-section__field--block {
132
+ grid-template-columns: 1fr;
133
+ }
134
+
135
+ .mrd-layout-section__badge {
136
+ display: inline-block;
137
+ font-size: var(--mrd-font-size-xs);
138
+ font-weight: var(--mrd-font-weight-medium);
139
+ padding: 2px var(--mrd-space-3);
140
+ border-radius: 10px;
141
+ }
142
+
143
+ .mrd-layout-section__badge-dot-row {
144
+ display: inline-flex;
145
+ align-items: center;
146
+ gap: var(--mrd-space-2);
147
+ }
148
+
149
+ .mrd-layout-section__badge-dot {
150
+ display: inline-block;
151
+ width: 10px;
152
+ height: 10px;
153
+ border-radius: 50%;
154
+ flex-shrink: 0;
155
+ }
156
+
157
+ .mrd-layout-section__pre {
158
+ font-family: var(--mrd-font-family-mono);
159
+ font-size: var(--mrd-font-size-xs);
160
+ background-color: var(--mrd-color-neutral-50);
161
+ border: 1px solid var(--mrd-color-neutral-200);
162
+ border-radius: var(--mrd-border-radius);
163
+ padding: var(--mrd-space-3);
164
+ margin: 0;
165
+ max-height: calc(10 * 1.5 * var(--mrd-font-size-xs));
166
+ overflow-x: auto;
167
+ overflow-y: auto;
168
+ white-space: pre-wrap;
169
+ word-break: break-word;
170
+ }
171
+
172
+ .mrd-layout-section__group {
173
+ margin: var(--mrd-space-4) 0;
174
+ }
175
+
176
+ .mrd-layout-section__group-title {
177
+ font-size: var(--mrd-font-size-sm);
178
+ font-weight: var(--mrd-font-weight-semibold);
179
+ color: var(--mrd-color-neutral-500);
180
+ margin: 0 0 var(--mrd-space-2) 0;
181
+ padding-bottom: 0;
182
+ text-transform: uppercase;
183
+ letter-spacing: 0.05em;
184
+ }
185
+
186
+ .mrd-layout-section__related-view {
187
+ margin: var(--mrd-space-4) 0;
188
+ }
189
+
190
+ .mrd-layout-section__related-view-title {
191
+ font-size: var(--mrd-font-size-lg);
192
+ font-weight: var(--mrd-font-weight-semibold);
193
+ color: var(--mrd-color-neutral-800);
194
+ margin: 0 0 var(--mrd-space-3) 0;
195
+ }
196
+
197
+ .mrd-layout-section__search {
198
+ position: relative;
199
+ margin: var(--mrd-space-2) 0;
200
+ }
201
+
202
+ .mrd-layout-section__search-input {
203
+ display: block;
204
+ width: 100%;
205
+ height: var(--mrd-input-height);
206
+ padding: var(--mrd-input-padding-y) var(--mrd-input-padding-x);
207
+ font-family: var(--mrd-font-family);
208
+ font-size: var(--mrd-font-size-base);
209
+ color: var(--mrd-input-color);
210
+ background-color: var(--mrd-input-bg);
211
+ border: var(--mrd-border-width) solid var(--mrd-border-color);
212
+ border-radius: var(--mrd-border-radius);
213
+ outline: none;
214
+ appearance: none;
215
+ box-sizing: border-box;
216
+ }
217
+
218
+ .mrd-layout-section__search-input:focus {
219
+ border-color: var(--mrd-border-color-focus);
220
+ box-shadow: var(--mrd-shadow-focus);
221
+ }
222
+
223
+ .mrd-layout-section__search-input::placeholder {
224
+ color: var(--mrd-input-placeholder-color);
225
+ }
226
+
227
+ .mrd-layout-section__search-results {
228
+ position: absolute;
229
+ top: 100%;
230
+ left: 0;
231
+ right: 0;
232
+ background-color: var(--mrd-color-white);
233
+ border: 1px solid var(--mrd-color-neutral-300);
234
+ border-top: none;
235
+ border-radius: 0 0 var(--mrd-border-radius) var(--mrd-border-radius);
236
+ box-shadow: var(--mrd-shadow-sm);
237
+ z-index: 100;
238
+ max-height: 300px;
239
+ overflow-y: auto;
240
+ list-style: none;
241
+ margin: 0;
242
+ padding: var(--mrd-space-1) 0;
243
+ }
244
+
245
+ .mrd-layout-section__search-result {
246
+ margin: 0;
247
+ padding: 0;
248
+ }
249
+
250
+ .mrd-layout-section__search-result-btn {
251
+ display: flex;
252
+ flex-direction: column;
253
+ width: 100%;
254
+ padding: var(--mrd-space-2) var(--mrd-space-3);
255
+ background: none;
256
+ border: none;
257
+ text-align: left;
258
+ cursor: pointer;
259
+ font-family: var(--mrd-font-family);
260
+ }
261
+
262
+ .mrd-layout-section__search-result-btn:hover {
263
+ background-color: var(--mrd-color-primary-light);
264
+ }
265
+
266
+ .mrd-layout-section__search-result-label {
267
+ font-size: var(--mrd-font-size-sm);
268
+ font-weight: var(--mrd-font-weight-medium);
269
+ color: var(--mrd-color-neutral-800);
270
+ }
271
+
272
+ .mrd-layout-section__search-result-desc {
273
+ font-size: var(--mrd-font-size-xs);
274
+ color: var(--mrd-color-neutral-500);
275
+ margin-top: var(--mrd-space-1);
276
+ }
277
+
278
+ .mrd-layout-section__image-thumb-btn {
279
+ background: none;
280
+ border: none;
281
+ padding: 0;
282
+ cursor: pointer;
283
+ display: inline-block;
284
+ border-radius: var(--mrd-border-radius);
285
+ overflow: hidden;
286
+ line-height: 0;
287
+ }
288
+
289
+ .mrd-layout-section__image-thumb-btn:hover .mrd-layout-section__image-thumb {
290
+ opacity: 0.85;
291
+ }
292
+
293
+ .mrd-layout-section__image-thumb {
294
+ display: block;
295
+ max-width: 160px;
296
+ max-height: 100px;
297
+ border-radius: var(--mrd-border-radius);
298
+ object-fit: cover;
299
+ transition: opacity 0.15s;
300
+ }
301
+
302
+ .mrd-layout-section__modal-backdrop {
303
+ position: fixed;
304
+ inset: 0;
305
+ background: rgba(0, 0, 0, 0.6);
306
+ z-index: 300;
307
+ display: flex;
308
+ align-items: center;
309
+ justify-content: center;
310
+ }
311
+
312
+ .mrd-layout-section__modal {
313
+ position: relative;
314
+ background: #fff;
315
+ border-radius: var(--mrd-border-radius);
316
+ padding: var(--mrd-space-3);
317
+ max-width: min(90vw, 900px);
318
+ max-height: 90vh;
319
+ display: flex;
320
+ align-items: center;
321
+ justify-content: center;
322
+ box-shadow: var(--mrd-shadow-lg);
323
+ }
324
+
325
+ .mrd-layout-section__modal-close {
326
+ position: absolute;
327
+ top: var(--mrd-space-2);
328
+ right: var(--mrd-space-2);
329
+ background: rgba(0, 0, 0, 0.5);
330
+ border: none;
331
+ border-radius: 50%;
332
+ width: 28px;
333
+ height: 28px;
334
+ display: flex;
335
+ align-items: center;
336
+ justify-content: center;
337
+ color: #fff;
338
+ cursor: pointer;
339
+ font-size: var(--mrd-font-size-sm);
340
+ line-height: 1;
341
+ z-index: 1;
342
+ }
343
+
344
+ .mrd-layout-section__modal-close:hover {
345
+ background: rgba(0, 0, 0, 0.8);
346
+ }
347
+
348
+ .mrd-layout-section__modal-image {
349
+ display: block;
350
+ max-width: 100%;
351
+ max-height: calc(90vh - 2rem);
352
+ border-radius: var(--mrd-border-radius);
353
+ object-fit: contain;
354
+ }
@@ -28,7 +28,7 @@ export class MrdLongtextField {
28
28
  }
29
29
  render() {
30
30
  const hasError = !!this.error;
31
- return (h(Host, { key: '0b1764adfb7ddce8c5e645a5d96c69c715652365' }, h("div", { key: '3c0c6bf77bfcd3f1bc97103baf9e5f6588f541f2', class: "mrd-longtext-field" }, this.label && (h("label", { key: 'f096b24c785a8c4b473fe0491a8cfdd7da4770bc', class: `mrd-longtext-field__label${this.required ? ' mrd-longtext-field__label--required' : ''}` }, this.label)), this.disabled ? (h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (h("textarea", { class: `mrd-longtext-field__input${hasError ? ' mrd-longtext-field__input--error' : ''}`, name: this.name, placeholder: this.placeholder, required: this.required, rows: 10, onInput: this.handleInput, onBlur: this.handleBlur }, this.value)), hasError && h("span", { key: '74b6bcecf81ca86172015abd5e3512ad288ae88e', class: "mrd-longtext-field__error" }, this.error))));
31
+ return (h(Host, { key: '3142f97e26fdef5547c8dd9d236ed8bc40d5c65f' }, h("div", { key: 'b78567596d8c6459c8e9b28ea6b02d3fe65fd16c', class: "mrd-longtext-field" }, this.label && (h("label", { key: 'e85d8657fcc49fc7e15c06b8a98b34c03738ef5b', class: `mrd-longtext-field__label${this.required ? ' mrd-longtext-field__label--required' : ''}` }, this.label)), this.disabled ? (h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (h("textarea", { class: `mrd-longtext-field__input${hasError ? ' mrd-longtext-field__input--error' : ''}`, name: this.name, placeholder: this.placeholder, required: this.required, rows: 10, onInput: this.handleInput, onBlur: this.handleBlur }, this.value)), hasError && h("span", { key: '63cdcaf136e345197c42516f150752ec1d8665fa', class: "mrd-longtext-field__error" }, this.error))));
32
32
  }
33
33
  static get is() { return "mrd-longtext-field"; }
34
34
  static get encapsulation() { return "scoped"; }
@@ -69,7 +69,7 @@ export class MrdNumberField {
69
69
  const hasError = !!this.error;
70
70
  const suffix = this.dataType === ClientLayoutItemFieldDataType.PERCENTAGE ? '%' :
71
71
  this.dataType === ClientLayoutItemFieldDataType.DECIMAL ? '' : '';
72
- return (h(Host, { key: '676e773fd4cc22936e64626b16e58c76f74ad8a7' }, h("div", { key: 'c646eab29793326f439d9838ecdab68249c487f1', class: "mrd-number-field" }, this.label && (h("label", { key: 'fb4fdac8f71b513fed52262ed8f5b5a5258f8f0b', class: `mrd-number-field__label${this.required ? ' mrd-number-field__label--required' : ''}` }, this.label)), h("div", { key: '5f7540318761da01f9793430ca709ba014204a11', class: "mrd-number-field__input-wrapper" }, h("input", { key: 'a102a89f9b7d91b29cf65afd5772552002d4c4cc', class: `mrd-number-field__input${hasError ? ' mrd-number-field__input--error' : ''}`, type: "text", inputMode: "decimal", name: this.name, value: this.displayValue, placeholder: this.placeholder || (suffix ? `0${suffix}` : '0'), required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur, onFocus: this.handleFocus })), hasError && h("span", { key: 'eb00631f61d2c9ee6a94343a0c79847a21e8316c', class: "mrd-number-field__error" }, this.error))));
72
+ return (h(Host, { key: 'ba3488fb12f72bb04164e3e94c028fb8a085f1f2' }, h("div", { key: '582e30a2a256c16cc3b0cab6e64460a0a5ec1fa2', class: "mrd-number-field" }, this.label && (h("label", { key: '87fe77ce80e888406ecedaa450e8c3d2a61c790a', class: `mrd-number-field__label${this.required ? ' mrd-number-field__label--required' : ''}` }, this.label)), h("div", { key: 'e3d8cf06f585add372e385d6e6ef7d60ece8071b', class: "mrd-number-field__input-wrapper" }, h("input", { key: '04710b67ee0dcb9db327e25b2467b1b3499bc9a8', class: `mrd-number-field__input${hasError ? ' mrd-number-field__input--error' : ''}`, type: "text", inputMode: "decimal", name: this.name, value: this.displayValue, placeholder: this.placeholder || (suffix ? `0${suffix}` : '0'), required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur, onFocus: this.handleFocus })), hasError && h("span", { key: '9713244d784c82213ea835a5a6d47d468ccb0bb9', class: "mrd-number-field__error" }, this.error))));
73
73
  }
74
74
  static get is() { return "mrd-number-field"; }
75
75
  static get encapsulation() { return "scoped"; }
@@ -12,13 +12,14 @@ const TEXT_TYPES = new Set(['TEXT', 'TEXTBLOCK', 'EMAIL', 'HYPERLINK']);
12
12
  const NUMERIC_TYPES = new Set(['INTEGER', 'DECIMAL', 'PERCENTAGE', 'CURRENCY']);
13
13
  const DATE_TYPES = new Set(['DATE', 'DATETIME', 'TIME']);
14
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']);
15
17
  export class MrdTable {
16
18
  constructor() {
17
19
  // ── Non-state internals ────────────────────────────────────────────────────
18
20
  this.pendingPages = new Set();
19
21
  this.debounceTimer = null;
20
22
  this.outsideClickHandler = null;
21
- this.viewSwitcherClickHandler = null;
22
23
  this.keydownHandler = null;
23
24
  // ── Props ──────────────────────────────────────────────────────────────────
24
25
  this.columns = [];
@@ -64,10 +65,10 @@ export class MrdTable {
64
65
  this.scrollTop = 0;
65
66
  /** Full text shown in the TEXTBLOCK expand modal (null = closed). */
66
67
  this.textblockModal = null;
68
+ /** Syntax-highlighted JSON HTML shown in the JSON expand modal (null = closed). */
69
+ this.jsonModal = null;
67
70
  /** Aggregation totals received from the host via setAggregations(). Null = not yet loaded. */
68
71
  this.aggregations = null;
69
- /** Whether the view switcher dropdown is open. */
70
- this.viewSwitcherOpen = false;
71
72
  this.handleScroll = (e) => {
72
73
  const scroller = e.currentTarget;
73
74
  const scrollTop = scroller.scrollTop;
@@ -150,10 +151,6 @@ export class MrdTable {
150
151
  document.removeEventListener('click', this.outsideClickHandler);
151
152
  this.outsideClickHandler = null;
152
153
  }
153
- if (this.viewSwitcherClickHandler) {
154
- document.removeEventListener('click', this.viewSwitcherClickHandler);
155
- this.viewSwitcherClickHandler = null;
156
- }
157
154
  if (this.keydownHandler) {
158
155
  document.removeEventListener('keydown', this.keydownHandler);
159
156
  this.keydownHandler = null;
@@ -401,6 +398,23 @@ export class MrdTable {
401
398
  this.keydownHandler = null;
402
399
  }
403
400
  }
401
+ openJsonModal(html) {
402
+ this.jsonModal = html;
403
+ if (this.keydownHandler)
404
+ document.removeEventListener('keydown', this.keydownHandler);
405
+ this.keydownHandler = (ev) => {
406
+ if (ev.key === 'Escape')
407
+ this.closeJsonModal();
408
+ };
409
+ document.addEventListener('keydown', this.keydownHandler);
410
+ }
411
+ closeJsonModal() {
412
+ this.jsonModal = null;
413
+ if (this.keydownHandler) {
414
+ document.removeEventListener('keydown', this.keydownHandler);
415
+ this.keydownHandler = null;
416
+ }
417
+ }
404
418
  setPending(key, val) {
405
419
  this.pendingFilter = Object.assign(Object.assign({}, this.pendingFilter), { [key]: val });
406
420
  }
@@ -525,44 +539,26 @@ export class MrdTable {
525
539
  }
526
540
  }
527
541
  // ── View switcher ──────────────────────────────────────────────────────────
528
- openViewSwitcher() {
529
- this.viewSwitcherOpen = true;
530
- if (this.viewSwitcherClickHandler)
531
- document.removeEventListener('click', this.viewSwitcherClickHandler);
532
- this.viewSwitcherClickHandler = (ev) => {
533
- const wrapper = this.el.querySelector('.mrd-table__view-switcher');
534
- if (wrapper && !wrapper.contains(ev.target))
535
- this.closeViewSwitcher();
536
- };
537
- document.addEventListener('click', this.viewSwitcherClickHandler);
538
- }
539
- closeViewSwitcher() {
540
- this.viewSwitcherOpen = false;
541
- if (this.viewSwitcherClickHandler) {
542
- document.removeEventListener('click', this.viewSwitcherClickHandler);
543
- this.viewSwitcherClickHandler = null;
544
- }
545
- }
546
542
  handleViewSwitch(view) {
547
- this.closeViewSwitcher();
548
543
  this.mrdSwitchView.emit({ name: view.name, class: view.class });
549
544
  }
550
- renderViewSwitcher() {
551
- return (h("div", { class: "mrd-table__view-switcher" }, h("button", { class: `mrd-table__view-switcher-btn${this.viewSwitcherOpen ? ' mrd-table__view-switcher-btn--open' : ''}`, "aria-label": this.viewLabel, onClick: (e) => {
552
- e.stopPropagation();
553
- this.viewSwitcherOpen ? this.closeViewSwitcher() : this.openViewSwitcher();
554
- } }, h("svg", { class: "mrd-table__view-switcher-chevron", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M7 10l5 5 5-5z" }))), this.viewSwitcherOpen && (h("div", { class: "mrd-table__view-switcher-dropdown", onClick: (e) => e.stopPropagation() }, this.alternativeViews.map(view => {
555
- var _a;
556
- return (h("button", { class: "mrd-table__view-switcher-item", onClick: () => this.handleViewSwitch(view) }, (_a = view.label) !== null && _a !== void 0 ? _a : view.name));
557
- })))));
558
- }
559
545
  // ── Render: toolbar ────────────────────────────────────────────────────────
560
546
  renderToolbar() {
561
547
  var _a, _b;
562
548
  const filterCount = this.activeFilters.size;
563
549
  const hasActions = ((_a = this.actions) === null || _a === void 0 ? void 0 : _a.length) > 0;
564
550
  const hasViewSwitcher = !!this.viewLabel && ((_b = this.alternativeViews) === null || _b === void 0 ? void 0 : _b.length) > 0;
565
- return (h("div", { class: "mrd-table__toolbar" }, h("div", { class: "mrd-table__toolbar-left" }, h("button", { class: `mrd-table__action mrd-table__action--secondary mrd-table__filter-toggle${this.filterMode ? ' mrd-table__filter-toggle--active' : ''}`, onClick: () => this.handleFilterToggle() }, h("svg", { class: "mrd-table__action-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" })), filterCount > 0 && h("span", { class: "mrd-table__filter-badge" }, filterCount), h("span", { class: "mrd-table__action-tooltip" }, this.filterMode ? t('table_filter_hide', this.locale) : t('table_filter', this.locale), filterCount > 0 ? ` (${filterCount} ${t('table_filter_active', this.locale)})` : '')), filterCount > 0 && (h("button", { class: "mrd-table__action mrd-table__action--secondary", onClick: () => this.clearAllFilters() }, h("svg", { class: "mrd-table__action-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" })), h("span", { class: "mrd-table__action-tooltip" }, t('table_filter_clear_all', this.locale))))), hasViewSwitcher && (h("div", { class: "mrd-table__toolbar-center" }, h("span", { class: "mrd-table__view-title" }, this.viewLabel), this.renderViewSwitcher())), hasActions && (h("div", { class: "mrd-table__toolbar-right" }, this.actions.map(a => {
551
+ return (h("div", { class: "mrd-table__toolbar" }, h("div", { class: "mrd-table__toolbar-left" }, h("button", { class: `mrd-table__action mrd-table__action--secondary mrd-table__filter-toggle${this.filterMode ? ' mrd-table__filter-toggle--active' : ''}`, onClick: () => this.handleFilterToggle() }, h("svg", { class: "mrd-table__action-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" })), filterCount > 0 && h("span", { class: "mrd-table__filter-badge" }, filterCount), h("span", { class: "mrd-table__action-tooltip" }, this.filterMode ? t('table_filter_hide', this.locale) : t('table_filter', this.locale), filterCount > 0 ? ` (${filterCount} ${t('table_filter_active', this.locale)})` : '')), filterCount > 0 && (h("button", { class: "mrd-table__action mrd-table__action--secondary", onClick: () => this.clearAllFilters() }, h("svg", { class: "mrd-table__action-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" })), h("span", { class: "mrd-table__action-tooltip" }, t('table_filter_clear_all', this.locale))))), hasViewSwitcher && (h("div", { class: "mrd-table__toolbar-center" }, h("select", { class: "mrd-table__view-select", onChange: (e) => {
552
+ const sel = e.target;
553
+ const view = this.alternativeViews.find(v => v.name === sel.value);
554
+ if (view) {
555
+ sel.selectedIndex = 0;
556
+ this.handleViewSwitch(view);
557
+ }
558
+ } }, h("option", { value: "" }, this.viewLabel), this.alternativeViews.map(v => {
559
+ var _a;
560
+ return (h("option", { value: v.name }, (_a = v.label) !== null && _a !== void 0 ? _a : v.name));
561
+ })))), hasActions && (h("div", { class: "mrd-table__toolbar-right" }, this.actions.map(a => {
566
562
  var _a;
567
563
  return (h("button", { class: `mrd-table__action mrd-table__action--${(_a = a.variant) !== null && _a !== void 0 ? _a : 'secondary'}`, disabled: a.disabled, onClick: () => this.mrdAction.emit({ action: a.action }) }, a.icon
568
564
  ? h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, h("use", { href: a.icon }))
@@ -680,7 +676,7 @@ export class MrdTable {
680
676
  }
681
677
  // ── Render: cell ──────────────────────────────────────────────────────────
682
678
  renderCell(col, row) {
683
- var _a, _b, _c, _d;
679
+ var _a, _b, _c, _d, _e, _f;
684
680
  const numericTypes = new Set(['INTEGER', 'DECIMAL', 'PERCENTAGE', 'CURRENCY']);
685
681
  const dataType = (_b = (_a = col.field) === null || _a === void 0 ? void 0 : _a.dataType) !== null && _b !== void 0 ? _b : '';
686
682
  const isNumeric = col.type === 'FIELD' && numericTypes.has(dataType);
@@ -695,6 +691,15 @@ export class MrdTable {
695
691
  this.mrdDownload.emit({ href, fileName });
696
692
  } }, 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))) : ''));
697
693
  }
694
+ if (dataType === 'JSON') {
695
+ const name = (_f = (_e = col.field) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : '';
696
+ const rawValue = name ? row === null || row === void 0 ? void 0 : row[name] : undefined;
697
+ if (rawValue == null || rawValue === '')
698
+ return h("td", { class: "mrd-table__cell" });
699
+ const compactHtml = CellRenderer.formatJson(rawValue, true);
700
+ const prettyHtml = CellRenderer.formatJson(rawValue, false);
701
+ 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")));
702
+ }
698
703
  const TEXTBLOCK_MAX = 200;
699
704
  if (dataType === 'TEXTBLOCK') {
700
705
  const full = CellRenderer.render(col, row, this.locale);
@@ -737,7 +742,7 @@ export class MrdTable {
737
742
  this.filterMode ? 'mrd-table__header--sortable' : '',
738
743
  ].filter(Boolean).join(' ');
739
744
  return (h("th", { class: cls, onClick: this.filterMode ? (e) => this.handleFilterOpen(col, e) : undefined }, h("span", { class: "mrd-table__header-label" }, (_d = (_b = (_a = col.field) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : (_c = col.relation) === null || _c === void 0 ? void 0 : _c.label) !== null && _d !== void 0 ? _d : ''), isFiltered && this.renderFilterIcon()));
740
- }))), 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()));
745
+ }))), 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()));
741
746
  }
742
747
  // ── Paginated / virtual-scroll mode ────────────────────────────────────
743
748
  // Derive the authoritative row count from loaded pages:
@@ -773,13 +778,14 @@ export class MrdTable {
773
778
  const name = this.colName(col);
774
779
  const isActive = this.sortField === name;
775
780
  const isFiltered = this.activeFilters.has(name);
781
+ const isInteractive = !NON_INTERACTIVE_TYPES.has(this.colDataType(col));
776
782
  const cls = [
777
783
  'mrd-table__header',
778
- 'mrd-table__header--sortable',
784
+ isInteractive ? 'mrd-table__header--sortable' : '',
779
785
  isActive ? `mrd-table__header--sorted-${this.sortDir}` : '',
780
786
  isFiltered ? 'mrd-table__header--filtered' : '',
781
787
  ].filter(Boolean).join(' ');
782
- return (h("th", { class: cls, style: this.colWidths[idx] ? { width: `${this.colWidths[idx]}px` } : undefined, onClick: (e) => this.filterMode ? this.handleFilterOpen(col, e) : this.handleSortClick(col) }, h("span", { class: "mrd-table__header-label" }, (_d = (_b = (_a = col.field) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : (_c = col.relation) === null || _c === void 0 ? void 0 : _c.label) !== null && _d !== void 0 ? _d : ''), isActive && (h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, this.sortDir === 'asc' ? '▲' : '▼')), !isActive && !this.filterMode && (h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, "\u21C5")), isFiltered && this.renderFilterIcon()));
788
+ 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" }, (_d = (_b = (_a = col.field) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : (_c = col.relation) === null || _c === void 0 ? void 0 : _c.label) !== null && _d !== void 0 ? _d : ''), isInteractive && isActive && (h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, this.sortDir === 'asc' ? '▲' : '▼')), isInteractive && !isActive && !this.filterMode && (h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, "\u21C5")), isInteractive && isFiltered && this.renderFilterIcon()));
783
789
  }))), h("tbody", null, topSpacerHeight > 0 && (h("tr", { class: "mrd-table__spacer", style: { height: `${topSpacerHeight}px` } }, h("td", { colSpan: colCount }))), renderedRows, bottomSpacerHeight > 0 && (h("tr", { class: "mrd-table__spacer", style: { height: `${bottomSpacerHeight}px` } }, h("td", { colSpan: colCount })))), this.renderTotalsRow())), effectiveTotal === 0 && this.loadedPages.has(0) && (h("p", { class: "mrd-table__empty" }, t('no_results', this.locale))), effectiveTotal > 0 && this.renderFooter(undefined, effectiveTotal), this.renderFilterPopup(), this.renderTextblockModal()));
784
790
  }
785
791
  renderFilterIcon() {
@@ -790,6 +796,11 @@ export class MrdTable {
790
796
  return null;
791
797
  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))));
792
798
  }
799
+ renderJsonModal() {
800
+ if (this.jsonModal === null)
801
+ return null;
802
+ 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 }))));
803
+ }
793
804
  static get is() { return "mrd-table"; }
794
805
  static get encapsulation() { return "scoped"; }
795
806
  static get originalStyleUrls() {
@@ -1060,8 +1071,8 @@ export class MrdTable {
1060
1071
  "popupPos": {},
1061
1072
  "scrollTop": {},
1062
1073
  "textblockModal": {},
1063
- "aggregations": {},
1064
- "viewSwitcherOpen": {}
1074
+ "jsonModal": {},
1075
+ "aggregations": {}
1065
1076
  };
1066
1077
  }
1067
1078
  static get events() {