@mmlogic/components 0.1.14 → 0.1.16
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/{format-BT6-_W7X.js → format-IFzg0q-6.js} +13 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/mosterdcomponents.cjs.js +1 -1
- package/dist/cjs/mrd-boolean-field_16.cjs.entry.js +53 -20
- package/dist/cjs/mrd-table.cjs.entry.js +134 -15
- package/dist/collection/components/mrd-field/mrd-field.js +2 -2
- package/dist/collection/components/mrd-form/mrd-form.js +53 -20
- package/dist/collection/components/mrd-relation-field/mrd-relation-field.js +3 -3
- package/dist/collection/components/mrd-table/mrd-table.js +134 -14
- package/dist/collection/components/mrd-table/mrd-table.scss +88 -27
- package/dist/collection/dev/app.js +8 -6
- package/dist/collection/utils/format.js +1 -1
- package/dist/collection/utils/i18n.js +12 -0
- package/dist/components/format.js +1 -1
- package/dist/components/i18n.js +1 -1
- package/dist/components/mrd-form.js +1 -1
- package/dist/components/mrd-relation-field2.js +1 -1
- package/dist/components/mrd-table.js +1 -1
- package/dist/esm/{format-beKIX2qZ.js → format-Cc9kQ1j-.js} +13 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/mosterdcomponents.js +1 -1
- package/dist/esm/mrd-boolean-field_16.entry.js +53 -20
- package/dist/esm/mrd-table.entry.js +134 -15
- package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
- package/dist/mosterdcomponents/p-1e0d88fd.entry.js +1 -0
- package/dist/mosterdcomponents/p-829b9b6f.entry.js +1 -0
- package/dist/mosterdcomponents/p-Cc9kQ1j-.js +1 -0
- package/dist/types/components/mrd-field/mrd-field.d.ts +1 -0
- package/dist/types/components/mrd-form/mrd-form.d.ts +9 -4
- package/dist/types/components/mrd-relation-field/mrd-relation-field.d.ts +1 -0
- package/dist/types/components/mrd-table/mrd-table.d.ts +11 -0
- package/dist/types/components.d.ts +6 -6
- package/package.json +1 -1
- package/dist/mosterdcomponents/p-33e56d76.entry.js +0 -1
- package/dist/mosterdcomponents/p-80d6eff2.entry.js +0 -1
- package/dist/mosterdcomponents/p-beKIX2qZ.js +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-_tsCCkAi.js';
|
|
2
|
-
import { p as parseLocalizedNumber, t, d as formatNumber } from './format-
|
|
2
|
+
import { p as parseLocalizedNumber, t, d as formatNumber } from './format-Cc9kQ1j-.js';
|
|
3
3
|
import { ClientLayoutItemFieldDataType, ClientLayoutItemType, ClientLayoutItemRelationDisplayType, ClientLayoutItemRelationEditBehavior } from './index.js';
|
|
4
4
|
|
|
5
5
|
const mrdBooleanFieldScss = () => `.sc-mrd-boolean-field-h{display:block}.mrd-boolean-field.sc-mrd-boolean-field{display:flex;align-items:center;width:100%}.mrd-boolean-field__toggle-label.sc-mrd-boolean-field{display:flex;align-items:center;gap:var(--mrd-space-3);cursor:pointer;user-select:none}.mrd-boolean-field__checkbox.sc-mrd-boolean-field{position:absolute;opacity:0;width:0;height:0;pointer-events:none}.mrd-boolean-field__checkbox.sc-mrd-boolean-field:checked+.mrd-boolean-field__toggle.sc-mrd-boolean-field{background-color:var(--mrd-color-primary)}.mrd-boolean-field__checkbox.sc-mrd-boolean-field:checked+.mrd-boolean-field__toggle.sc-mrd-boolean-field::after{transform:translateX(20px)}.mrd-boolean-field__checkbox.sc-mrd-boolean-field:focus+.mrd-boolean-field__toggle.sc-mrd-boolean-field{box-shadow:var(--mrd-shadow-focus)}.mrd-boolean-field__checkbox.sc-mrd-boolean-field:disabled+.mrd-boolean-field__toggle.sc-mrd-boolean-field{opacity:0.5;cursor:not-allowed}.mrd-boolean-field__toggle.sc-mrd-boolean-field{position:relative;display:inline-block;width:44px;height:24px;background-color:var(--mrd-color-neutral-300);border-radius:var(--mrd-border-radius-full);transition:background-color var(--mrd-transition);flex-shrink:0}.mrd-boolean-field__toggle.sc-mrd-boolean-field::after{content:'';position:absolute;top:2px;left:2px;width:20px;height:20px;background-color:var(--mrd-color-white);border-radius:50%;transition:transform var(--mrd-transition);box-shadow:var(--mrd-shadow-sm)}.mrd-boolean-field__text.sc-mrd-boolean-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-800)}.mrd-boolean-field__text--required.sc-mrd-boolean-field::after{content:' *';color:var(--mrd-color-danger)}`;
|
|
@@ -469,6 +469,7 @@ const MrdForm = class {
|
|
|
469
469
|
this.formValues = {};
|
|
470
470
|
this.errors = {};
|
|
471
471
|
this.submitted = false;
|
|
472
|
+
this.initialValues = {};
|
|
472
473
|
this.handleFieldChange = (e) => {
|
|
473
474
|
const { name, value } = e.detail;
|
|
474
475
|
const prevHref = this.getHref(this.formValues[name]);
|
|
@@ -519,8 +520,9 @@ const MrdForm = class {
|
|
|
519
520
|
};
|
|
520
521
|
}
|
|
521
522
|
componentWillLoad() {
|
|
522
|
-
var _a;
|
|
523
|
-
this.
|
|
523
|
+
var _a, _b;
|
|
524
|
+
this.initialValues = Object.assign({}, ((_a = this.values) !== null && _a !== void 0 ? _a : {}));
|
|
525
|
+
this.formValues = Object.assign({}, ((_b = this.values) !== null && _b !== void 0 ? _b : {}));
|
|
524
526
|
}
|
|
525
527
|
componentDidLoad() {
|
|
526
528
|
// Apply reference pre-fill and emit mrdFetchAll for dependent DROPDOWN fields.
|
|
@@ -533,6 +535,7 @@ const MrdForm = class {
|
|
|
533
535
|
/** Sync formValues when the values prop is set from outside after mount
|
|
534
536
|
* (e.g. when pre-filling an existing record in edit mode). */
|
|
535
537
|
valuesChanged(newValues) {
|
|
538
|
+
this.initialValues = Object.assign({}, (newValues !== null && newValues !== void 0 ? newValues : {}));
|
|
536
539
|
this.formValues = Object.assign({}, (newValues !== null && newValues !== void 0 ? newValues : {}));
|
|
537
540
|
this.applyReferenceValue();
|
|
538
541
|
this.errors = {};
|
|
@@ -660,10 +663,42 @@ const MrdForm = class {
|
|
|
660
663
|
this.errors = newErrors;
|
|
661
664
|
return Object.keys(newErrors).length === 0;
|
|
662
665
|
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
666
|
+
normalizeFieldValue(value) {
|
|
667
|
+
return (value === '' || value == null) ? null : value;
|
|
668
|
+
}
|
|
669
|
+
normalizeRelationValue(value) {
|
|
670
|
+
if (value == null || value === '')
|
|
671
|
+
return null;
|
|
672
|
+
if (typeof value === 'string')
|
|
673
|
+
return value || null;
|
|
674
|
+
if (Array.isArray(value)) {
|
|
675
|
+
return value.map(v => typeof v === 'object' && v !== null && 'id' in v ? v.id : String(v));
|
|
676
|
+
}
|
|
677
|
+
if (typeof value === 'object' && 'id' in value) {
|
|
678
|
+
return value.id || null;
|
|
679
|
+
}
|
|
680
|
+
return null;
|
|
681
|
+
}
|
|
682
|
+
deepEqual(a, b) {
|
|
683
|
+
if (a === b)
|
|
684
|
+
return true;
|
|
685
|
+
if (a == null && b == null)
|
|
686
|
+
return true;
|
|
687
|
+
if (a == null || b == null)
|
|
688
|
+
return false;
|
|
689
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
690
|
+
if (a.length !== b.length)
|
|
691
|
+
return false;
|
|
692
|
+
const sa = [...a].sort();
|
|
693
|
+
const sb = [...b].sort();
|
|
694
|
+
return JSON.stringify(sa) === JSON.stringify(sb);
|
|
695
|
+
}
|
|
696
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
697
|
+
}
|
|
698
|
+
/** Build a submit payload containing only fields that changed relative to
|
|
699
|
+
* initialValues. For a new record (POST) initialValues is empty, so every
|
|
700
|
+
* non-null field is included. For edit (PATCH) only modified fields are sent,
|
|
701
|
+
* including fields explicitly cleared to null.
|
|
667
702
|
*/
|
|
668
703
|
buildSubmitPayload() {
|
|
669
704
|
var _a, _b;
|
|
@@ -673,23 +708,21 @@ const MrdForm = class {
|
|
|
673
708
|
if (item.type === ClientLayoutItemType.FIELD && item.field) {
|
|
674
709
|
const name = item.field.name;
|
|
675
710
|
const value = this.formValues[name];
|
|
676
|
-
// Skip file/image fields that are still uploading (value is a File object)
|
|
677
711
|
if (value instanceof File)
|
|
678
712
|
continue;
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
713
|
+
const current = this.normalizeFieldValue(value);
|
|
714
|
+
const initial = this.normalizeFieldValue(this.initialValues[name]);
|
|
715
|
+
if (this.deepEqual(current, initial))
|
|
716
|
+
continue;
|
|
717
|
+
payload[name] = current;
|
|
682
718
|
}
|
|
683
719
|
else if (item.type === ClientLayoutItemType.RELATION && item.relation) {
|
|
684
720
|
const name = item.relation.name;
|
|
685
|
-
const
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
else if (value !== '' && value !== undefined) {
|
|
691
|
-
payload[name] = value !== null && value !== void 0 ? value : null;
|
|
692
|
-
}
|
|
721
|
+
const current = this.normalizeRelationValue(this.formValues[name]);
|
|
722
|
+
const initial = this.normalizeRelationValue(this.initialValues[name]);
|
|
723
|
+
if (this.deepEqual(current, initial))
|
|
724
|
+
continue;
|
|
725
|
+
payload[name] = current;
|
|
693
726
|
}
|
|
694
727
|
}
|
|
695
728
|
return payload;
|
|
@@ -1126,7 +1159,7 @@ const MrdRelationField = class {
|
|
|
1126
1159
|
this.isLoading = true;
|
|
1127
1160
|
this.showResults = true;
|
|
1128
1161
|
this.searchDebounce = setTimeout(() => {
|
|
1129
|
-
this.mrdSearch.emit({ query, relatedClass: this.mostSignificantClass });
|
|
1162
|
+
this.mrdSearch.emit({ name: this.name, query, relatedClass: this.mostSignificantClass });
|
|
1130
1163
|
}, 300);
|
|
1131
1164
|
}
|
|
1132
1165
|
else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-_tsCCkAi.js';
|
|
2
|
-
import { f as formatTime, a as formatDateTime, b as formatDate, c as formatCurrency, d as formatNumber, e as formatPercentage, t } from './format-
|
|
2
|
+
import { f as formatTime, a as formatDateTime, b as formatDate, c as formatCurrency, d as formatNumber, e as formatPercentage, t } from './format-Cc9kQ1j-.js';
|
|
3
3
|
import { ClientLayoutItemType } from './index.js';
|
|
4
4
|
|
|
5
5
|
class CellRenderer {
|
|
@@ -66,7 +66,7 @@ class CellRenderer {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
const mrdTableScss = () => `.sc-mrd-table-h{display:block;width:100%}.mrd-table__scroll.sc-mrd-table{overflow-y:auto;overflow-x:auto;border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);overflow-anchor:none}.mrd-table.sc-mrd-table{overflow-x:auto}.mrd-table__table.sc-mrd-table{width:auto;min-width:100%;border-collapse:collapse;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-900)}.mrd-table__scroll.sc-mrd-table .mrd-table__table.sc-mrd-table{min-width:max-content}.mrd-table__header.sc-mrd-table{position:sticky;top:0;z-index:1;background:var(--mrd-color-white);text-align:left;padding:var(--mrd-space-2) var(--mrd-space-4);border-bottom:2px solid var(--mrd-border-color);color:var(--mrd-color-neutral-600);font-weight:var(--mrd-font-weight-medium);white-space:nowrap;font-size:var(--mrd-font-size-xs);text-transform:uppercase;letter-spacing:0.04em}.mrd-table__header--sortable.sc-mrd-table{cursor:pointer;user-select:none}.mrd-table__header--sortable.sc-mrd-table:hover{background:var(--mrd-color-neutral-50);color:var(--mrd-color-neutral-800)}.mrd-table__header--sorted-asc.sc-mrd-table,.mrd-table__header--sorted-desc.sc-mrd-table{color:var(--mrd-color-primary);border-bottom-color:var(--mrd-color-primary)}.mrd-table__header-label.sc-mrd-table{margin-right:var(--mrd-space-1)}.mrd-table__sort-icon.sc-mrd-table{font-size:0.65rem;opacity:0.4;vertical-align:middle}.mrd-table__header--sorted-asc.sc-mrd-table .mrd-table__sort-icon.sc-mrd-table,.mrd-table__header--sorted-desc.sc-mrd-table .mrd-table__sort-icon.sc-mrd-table{opacity:1;color:var(--mrd-color-primary)}.mrd-table__row.sc-mrd-table{border-bottom:1px solid var(--mrd-border-color)}.mrd-table__row.sc-mrd-table:hover{background:var(--mrd-color-neutral-200) !important}.mrd-table__row--clickable.sc-mrd-table{cursor:pointer}.mrd-table__spacer.sc-mrd-table{border:none}.mrd-table__spacer.sc-mrd-table td.sc-mrd-table{padding:0;border:none}.mrd-table__cell.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-4);vertical-align:top;white-space:nowrap}.mrd-table__cell--numeric.sc-mrd-table{text-align:right;font-variant-numeric:tabular-nums}.mrd-table__row--loading.sc-mrd-table{background:transparent}.mrd-table__cell--placeholder.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-4);border-bottom:1px solid var(--mrd-border-color)}.mrd-table__placeholder-bar.sc-mrd-table{display:block;height:0.75rem;width:55%;border-radius:var(--mrd-border-radius-sm);background:linear-gradient( 90deg, var(--mrd-color-neutral-200) 25%, var(--mrd-color-neutral-100) 50%, var(--mrd-color-neutral-200) 75% );background-size:200% 100%;animation:mrd-shimmer 1.4s ease infinite}@keyframes mrd-shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}.mrd-table__toolbar.sc-mrd-table{display:flex;align-items:center;justify-content:space-between;padding-bottom:var(--mrd-space-2)}.mrd-table__toolbar-left.sc-mrd-table,.mrd-table__toolbar-right.sc-mrd-table{display:flex;gap:var(--mrd-space-2);align-items:center}.mrd-table__action.sc-mrd-table{position:relative;display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid transparent;border-radius:var(--mrd-border-radius);cursor:pointer;color:var(--mrd-color-neutral-400);transition:background-color 0.15s, border-color 0.15s, color 0.15s}.mrd-table__action.sc-mrd-table:hover{background-color:var(--mrd-color-neutral-100);border-color:var(--mrd-color-neutral-300);color:var(--mrd-color-neutral-700)}.mrd-table__action.sc-mrd-table:disabled{opacity:0.4;cursor:not-allowed}.mrd-table__action--primary.sc-mrd-table{color:var(--mrd-color-neutral-500)}.mrd-table__action--primary.sc-mrd-table:hover{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__action--danger.sc-mrd-table{color:var(--mrd-color-error)}.mrd-table__action--danger.sc-mrd-table:hover{background-color:var(--mrd-color-error-light, #fef2f2);border-color:var(--mrd-color-error)}.mrd-table__action-icon.sc-mrd-table{width:1.25rem;height:1.25rem;pointer-events:none;fill:currentColor}.mrd-table__action-tooltip.sc-mrd-table{display:none;position:absolute;bottom:calc(100% + 6px);right:0;padding:var(--mrd-space-1) var(--mrd-space-2);font-size:var(--mrd-font-size-xs);white-space:nowrap;background:var(--mrd-color-tooltip, #fffce1);color:var(--mrd-color-neutral-900);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-sm, var(--mrd-border-radius));pointer-events:none;z-index:10}.mrd-table__action.sc-mrd-table:hover .mrd-table__action-tooltip.sc-mrd-table{display:block}.mrd-table__filter-toggle--active.sc-mrd-table{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__filter-toggle--active.sc-mrd-table:hover{background:var(--mrd-color-primary-dark, var(--mrd-color-primary));border-color:var(--mrd-color-primary-dark, var(--mrd-color-primary));color:var(--mrd-color-white)}.mrd-table__filter-badge.sc-mrd-table{position:absolute;top:-6px;right:-6px;min-width:1.25rem;height:1.25rem;padding:0 3px;background:var(--mrd-color-error, #e53e3e);color:var(--mrd-color-white);border-radius:9999px;font-size:0.65rem;font-weight:var(--mrd-font-weight-medium);line-height:1.25rem;text-align:center;pointer-events:none}.mrd-table__header--filtered.sc-mrd-table{color:var(--mrd-color-primary);border-bottom-color:var(--mrd-color-primary)}.mrd-table__header-filter-btn.sc-mrd-table{display:inline-flex;align-items:center;justify-content:center;margin-left:var(--mrd-space-1);padding:0 3px;background:transparent;border:none;border-radius:3px;cursor:pointer;color:var(--mrd-color-neutral-500);font-size:0.8rem;line-height:1;vertical-align:middle}.mrd-table__header-filter-btn.sc-mrd-table:hover{background:var(--mrd-color-neutral-200);color:var(--mrd-color-neutral-800)}.mrd-table__header-filter-btn--active.sc-mrd-table{color:var(--mrd-color-primary)}.mrd-table__filter-popup.sc-mrd-table{position:fixed;width:280px;background:var(--mrd-color-white);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);box-shadow:var(--mrd-shadow-md, 0 4px 12px rgba(0,0,0,.12));z-index:var(--mrd-z-dropdown, 200);font-size:var(--mrd-font-size-sm)}.mrd-table__filter-popup-header.sc-mrd-table{display:flex;align-items:center;justify-content:space-between;padding:var(--mrd-space-2) var(--mrd-space-3);border-bottom:1px solid var(--mrd-border-color)}.mrd-table__filter-popup-title.sc-mrd-table{font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800);font-size:var(--mrd-font-size-sm)}.mrd-table__filter-close.sc-mrd-table{background:transparent;border:none;cursor:pointer;color:var(--mrd-color-neutral-500);font-size:0.9rem;padding:2px 4px;border-radius:3px;line-height:1}.mrd-table__filter-close.sc-mrd-table:hover{background:var(--mrd-color-neutral-100);color:var(--mrd-color-neutral-800)}.mrd-table__filter-section.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-3)}.mrd-table__filter-section-label.sc-mrd-table{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium);text-transform:uppercase;letter-spacing:0.04em;color:var(--mrd-color-neutral-500);margin-bottom:var(--mrd-space-2)}.mrd-table__filter-sort-buttons.sc-mrd-table{display:flex;gap:var(--mrd-space-2)}.mrd-table__filter-sort-btn.sc-mrd-table{flex:1;padding:var(--mrd-space-1) var(--mrd-space-2);background:transparent;border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);cursor:pointer;font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-700)}.mrd-table__filter-sort-btn.sc-mrd-table:hover{background:var(--mrd-color-neutral-100)}.mrd-table__filter-sort-btn--active.sc-mrd-table{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__filter-divider.sc-mrd-table{height:1px;background:var(--mrd-border-color);margin:0}.mrd-table__filter-editor.sc-mrd-table{display:flex;flex-direction:column;gap:var(--mrd-space-2)}.mrd-table__filter-select.sc-mrd-table,.mrd-table__filter-input.sc-mrd-table{width:100%;padding:var(--mrd-space-1) var(--mrd-space-2);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-900);background:var(--mrd-color-white);box-sizing:border-box}.mrd-table__filter-select.sc-mrd-table:focus,.mrd-table__filter-input.sc-mrd-table:focus{outline:none;border-color:var(--mrd-color-primary);box-shadow:0 0 0 2px rgba(0,0,0,.06)}.mrd-table__filter-range.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1)}.mrd-table__filter-range.sc-mrd-table .mrd-table__filter-input.sc-mrd-table{flex:1;min-width:0}.mrd-table__filter-range-sep.sc-mrd-table{color:var(--mrd-color-neutral-400);flex-shrink:0}.mrd-table__filter-radio-group.sc-mrd-table{display:flex;flex-direction:column;gap:var(--mrd-space-1)}.mrd-table__filter-radio-group--inline.sc-mrd-table{flex-direction:row;gap:var(--mrd-space-3)}.mrd-table__filter-radio-label.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1);cursor:pointer;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-800)}.mrd-table__filter-list.sc-mrd-table{display:flex;flex-direction:column;gap:var(--mrd-space-1);max-height:180px;overflow-y:auto}.mrd-table__filter-list-controls.sc-mrd-table{display:flex;gap:var(--mrd-space-2);margin-bottom:var(--mrd-space-1)}.mrd-table__filter-list-btn.sc-mrd-table{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-primary);background:transparent;border:none;cursor:pointer;padding:0;text-decoration:underline}.mrd-table__filter-checkbox-label.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1);cursor:pointer;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-800)}.mrd-table__filter-no-support.sc-mrd-table{font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-500);margin:0;font-style:italic}.mrd-table__filter-popup-footer.sc-mrd-table{display:flex;justify-content:flex-end;gap:var(--mrd-space-2);padding:var(--mrd-space-2) var(--mrd-space-3);border-top:1px solid var(--mrd-border-color)}.mrd-table__filter-btn.sc-mrd-table{padding:var(--mrd-space-1) var(--mrd-space-3);border-radius:var(--mrd-border-radius);border:1px solid var(--mrd-border-color);font-size:var(--mrd-font-size-sm);cursor:pointer}.mrd-table__filter-btn--clear.sc-mrd-table{background:transparent;color:var(--mrd-color-neutral-600)}.mrd-table__filter-btn--clear.sc-mrd-table:hover{background:var(--mrd-color-neutral-100)}.mrd-table__filter-btn--apply.sc-mrd-table{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__filter-btn--apply.sc-mrd-table:hover{background:var(--mrd-color-primary-dark, var(--mrd-color-primary));border-color:var(--mrd-color-primary-dark, var(--mrd-color-primary))}.mrd-table__footer.sc-mrd-table{padding:var(--mrd-space-1) var(--mrd-space-2);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);text-align:right}.mrd-table__empty.sc-mrd-table{padding:var(--mrd-space-4) var(--mrd-space-3);color:var(--mrd-color-neutral-500);font-size:var(--mrd-font-size-sm);text-align:center;margin:0}.mrd-table__file-btn.sc-mrd-table{display:inline-flex;align-items:center;gap:var(--mrd-space-1);background:none;border:none;padding:0;cursor:pointer;color:var(--mrd-color-primary);font-size:var(--mrd-font-size-sm);font-family:inherit;max-width:100%;overflow:hidden}.mrd-table__file-btn.sc-mrd-table:hover{text-decoration:underline;color:var(--mrd-color-primary-dark)}.mrd-table__file-icon.sc-mrd-table{flex-shrink:0;width:1rem;height:1rem}`;
|
|
69
|
+
const mrdTableScss = () => `.sc-mrd-table-h{display:block;width:100%}.mrd-table__scroll.sc-mrd-table{overflow-y:auto;overflow-x:auto;border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);overflow-anchor:none}.mrd-table.sc-mrd-table{overflow-x:auto}.mrd-table__table.sc-mrd-table{width:auto;min-width:100%;border-collapse:collapse;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-900)}.mrd-table__scroll.sc-mrd-table .mrd-table__table.sc-mrd-table{min-width:max-content}.mrd-table__header.sc-mrd-table{position:sticky;top:0;z-index:1;background:var(--mrd-color-white);text-align:left;padding:var(--mrd-space-2) var(--mrd-space-4);border-bottom:2px solid var(--mrd-border-color);color:var(--mrd-color-neutral-600);font-weight:var(--mrd-font-weight-medium);white-space:nowrap;font-size:var(--mrd-font-size-xs);text-transform:uppercase;letter-spacing:0.04em}.mrd-table__header--sortable.sc-mrd-table{cursor:pointer;user-select:none}.mrd-table__header--sortable.sc-mrd-table:hover{background:var(--mrd-color-neutral-50);color:var(--mrd-color-neutral-800)}.mrd-table__header--sorted-asc.sc-mrd-table,.mrd-table__header--sorted-desc.sc-mrd-table{color:var(--mrd-color-primary);border-bottom-color:var(--mrd-color-primary)}.mrd-table__header-label.sc-mrd-table{margin-right:var(--mrd-space-1)}.mrd-table__sort-icon.sc-mrd-table{font-size:0.85rem;opacity:0.4;vertical-align:middle}.mrd-table__header--sorted-asc.sc-mrd-table .mrd-table__sort-icon.sc-mrd-table,.mrd-table__header--sorted-desc.sc-mrd-table .mrd-table__sort-icon.sc-mrd-table{opacity:1;color:var(--mrd-color-primary)}.mrd-table__filter-icon.sc-mrd-table{display:inline-flex;align-items:center;vertical-align:middle;margin-left:var(--mrd-space-1);color:var(--mrd-color-primary)}.mrd-table__row.sc-mrd-table{border-bottom:1px solid var(--mrd-border-color)}.mrd-table__row.sc-mrd-table:hover{background:var(--mrd-color-neutral-200) !important}.mrd-table__row--clickable.sc-mrd-table{cursor:pointer}.mrd-table__spacer.sc-mrd-table{border:none}.mrd-table__spacer.sc-mrd-table td.sc-mrd-table{padding:0;border:none}.mrd-table__cell.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-4);vertical-align:top;white-space:nowrap}.mrd-table__cell--numeric.sc-mrd-table{text-align:right;font-variant-numeric:tabular-nums}.mrd-table__row--loading.sc-mrd-table{background:transparent}.mrd-table__cell--placeholder.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-4);border-bottom:1px solid var(--mrd-border-color)}.mrd-table__placeholder-bar.sc-mrd-table{display:block;height:0.75rem;width:55%;border-radius:var(--mrd-border-radius-sm);background:linear-gradient( 90deg, var(--mrd-color-neutral-200) 25%, var(--mrd-color-neutral-100) 50%, var(--mrd-color-neutral-200) 75% );background-size:200% 100%;animation:mrd-shimmer 1.4s ease infinite}@keyframes mrd-shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}.mrd-table__toolbar.sc-mrd-table{display:flex;align-items:center;justify-content:space-between;padding-bottom:var(--mrd-space-2)}.mrd-table__toolbar-left.sc-mrd-table,.mrd-table__toolbar-right.sc-mrd-table{display:flex;gap:var(--mrd-space-2);align-items:center}.mrd-table__action.sc-mrd-table{position:relative;display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid transparent;border-radius:var(--mrd-border-radius);cursor:pointer;color:var(--mrd-color-neutral-400);transition:background-color 0.15s, border-color 0.15s, color 0.15s}.mrd-table__action.sc-mrd-table:hover{background-color:var(--mrd-color-neutral-100);border-color:var(--mrd-color-neutral-300);color:var(--mrd-color-neutral-700)}.mrd-table__action.sc-mrd-table:disabled{opacity:0.4;cursor:not-allowed}.mrd-table__action--primary.sc-mrd-table{color:var(--mrd-color-neutral-500)}.mrd-table__action--primary.sc-mrd-table:hover{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__action--danger.sc-mrd-table{color:var(--mrd-color-error)}.mrd-table__action--danger.sc-mrd-table:hover{background-color:var(--mrd-color-error-light, #fef2f2);border-color:var(--mrd-color-error)}.mrd-table__action-icon.sc-mrd-table{width:1.25rem;height:1.25rem;pointer-events:none;fill:currentColor}.mrd-table__action-tooltip.sc-mrd-table{display:none;position:absolute;bottom:calc(100% + 6px);right:0;padding:var(--mrd-space-1) var(--mrd-space-2);font-size:var(--mrd-font-size-xs);white-space:nowrap;background:var(--mrd-color-tooltip, #fffce1);color:var(--mrd-color-neutral-900);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-sm, var(--mrd-border-radius));pointer-events:none;z-index:10}.mrd-table__action.sc-mrd-table:hover .mrd-table__action-tooltip.sc-mrd-table{display:block}.mrd-table__filter-toggle--active.sc-mrd-table{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__filter-toggle--active.sc-mrd-table:hover{background:var(--mrd-color-primary-dark, var(--mrd-color-primary));border-color:var(--mrd-color-primary-dark, var(--mrd-color-primary));color:var(--mrd-color-white)}.mrd-table__filter-badge.sc-mrd-table{position:absolute;top:-6px;right:-6px;min-width:1.25rem;height:1.25rem;padding:0 3px;background:var(--mrd-color-error, #e53e3e);color:var(--mrd-color-white);border-radius:9999px;font-size:0.65rem;font-weight:var(--mrd-font-weight-medium);line-height:1.25rem;text-align:center;pointer-events:none}.mrd-table__header--filtered.sc-mrd-table{color:var(--mrd-color-primary);border-bottom-color:var(--mrd-color-primary)}.mrd-table__filter-popup.sc-mrd-table{position:fixed;width:280px;background:var(--mrd-color-white);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);box-shadow:var(--mrd-shadow-md, 0 4px 12px rgba(0,0,0,.12));z-index:var(--mrd-z-dropdown, 200);font-size:var(--mrd-font-size-sm)}.mrd-table__filter-popup-header.sc-mrd-table{display:flex;align-items:center;justify-content:space-between;padding:var(--mrd-space-2) var(--mrd-space-3);border-bottom:1px solid var(--mrd-border-color)}.mrd-table__filter-popup-title.sc-mrd-table{font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800);font-size:var(--mrd-font-size-sm)}.mrd-table__filter-close.sc-mrd-table{background:transparent;border:none;cursor:pointer;color:var(--mrd-color-neutral-500);font-size:0.9rem;padding:2px 4px;border-radius:3px;line-height:1}.mrd-table__filter-close.sc-mrd-table:hover{background:var(--mrd-color-neutral-100);color:var(--mrd-color-neutral-800)}.mrd-table__filter-section.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-3)}.mrd-table__filter-section-label.sc-mrd-table{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium);text-transform:uppercase;letter-spacing:0.04em;color:var(--mrd-color-neutral-500);margin-bottom:var(--mrd-space-2)}.mrd-table__filter-sort-buttons.sc-mrd-table{display:flex;gap:var(--mrd-space-2)}.mrd-table__filter-sort-btn.sc-mrd-table{flex:1;padding:var(--mrd-space-1) var(--mrd-space-2);background:transparent;border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);cursor:pointer;font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-700)}.mrd-table__filter-sort-btn.sc-mrd-table:hover{background:var(--mrd-color-neutral-100)}.mrd-table__filter-sort-btn--active.sc-mrd-table{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__filter-divider.sc-mrd-table{height:1px;background:var(--mrd-border-color);margin:0}.mrd-table__filter-editor.sc-mrd-table{display:flex;flex-direction:column;gap:var(--mrd-space-2)}.mrd-table__filter-select.sc-mrd-table,.mrd-table__filter-input.sc-mrd-table{width:100%;padding:var(--mrd-space-1) var(--mrd-space-2);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-900);background:var(--mrd-color-white);box-sizing:border-box}.mrd-table__filter-select.sc-mrd-table:focus,.mrd-table__filter-input.sc-mrd-table:focus{outline:none;border-color:var(--mrd-color-primary);box-shadow:0 0 0 2px rgba(0,0,0,.06)}.mrd-table__filter-range.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1)}.mrd-table__filter-range.sc-mrd-table .mrd-table__filter-input.sc-mrd-table{flex:1;min-width:0}.mrd-table__filter-range-sep.sc-mrd-table{color:var(--mrd-color-neutral-400);flex-shrink:0}.mrd-table__filter-range--stacked.sc-mrd-table{flex-direction:column;align-items:stretch;gap:var(--mrd-space-2)}.mrd-table__filter-range-label.sc-mrd-table{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);margin-bottom:2px}.mrd-table__filter-radio-group.sc-mrd-table{display:flex;flex-direction:column;gap:var(--mrd-space-1)}.mrd-table__filter-radio-group--inline.sc-mrd-table{flex-direction:row;gap:var(--mrd-space-3)}.mrd-table__filter-radio-label.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1);cursor:pointer;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-800)}.mrd-table__filter-list.sc-mrd-table{display:flex;flex-direction:column;gap:var(--mrd-space-1);max-height:180px;overflow-y:auto}.mrd-table__filter-list-controls.sc-mrd-table{display:flex;gap:var(--mrd-space-2);margin-bottom:var(--mrd-space-1)}.mrd-table__filter-list-btn.sc-mrd-table{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-primary);background:transparent;border:none;cursor:pointer;padding:0;text-decoration:underline}.mrd-table__filter-checkbox-label.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1);cursor:pointer;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-800)}.mrd-table__filter-no-support.sc-mrd-table{font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-500);margin:0;font-style:italic}.mrd-table__filter-popup-footer.sc-mrd-table{display:flex;justify-content:flex-end;gap:var(--mrd-space-2);padding:var(--mrd-space-2) var(--mrd-space-3);border-top:1px solid var(--mrd-border-color)}.mrd-table__filter-btn.sc-mrd-table{padding:var(--mrd-space-1) var(--mrd-space-3);border-radius:var(--mrd-border-radius);border:1px solid var(--mrd-border-color);font-size:var(--mrd-font-size-sm);cursor:pointer}.mrd-table__filter-btn--clear.sc-mrd-table{background:transparent;color:var(--mrd-color-neutral-600)}.mrd-table__filter-btn--clear.sc-mrd-table:hover{background:var(--mrd-color-neutral-100)}.mrd-table__filter-btn--apply.sc-mrd-table{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__filter-btn--apply.sc-mrd-table:hover{background:var(--mrd-color-primary-dark, var(--mrd-color-primary));border-color:var(--mrd-color-primary-dark, var(--mrd-color-primary))}.mrd-table__footer.sc-mrd-table{padding:var(--mrd-space-1) var(--mrd-space-2);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);text-align:right}.mrd-table__empty.sc-mrd-table{padding:var(--mrd-space-4) var(--mrd-space-3);color:var(--mrd-color-neutral-500);font-size:var(--mrd-font-size-sm);text-align:center;margin:0}.mrd-table__file-btn.sc-mrd-table{display:inline-flex;align-items:center;gap:var(--mrd-space-1);background:none;border:none;padding:0;cursor:pointer;color:var(--mrd-color-primary);font-size:var(--mrd-font-size-sm);font-family:inherit;max-width:100%;overflow:hidden}.mrd-table__file-btn.sc-mrd-table:hover{text-decoration:underline;color:var(--mrd-color-primary-dark)}.mrd-table__file-icon.sc-mrd-table{flex-shrink:0;width:1rem;height:1rem}.mrd-table__textblock-btn.sc-mrd-table{display:inline;background:none;border:none;padding:0 0 0 var(--mrd-space-1);cursor:pointer;color:var(--mrd-color-primary);font-size:var(--mrd-font-size-sm);font-family:inherit;line-height:inherit;vertical-align:middle}.mrd-table__textblock-btn.sc-mrd-table:hover{color:var(--mrd-color-primary-dark)}.mrd-table__modal-backdrop.sc-mrd-table{position:fixed;inset:0;background:rgba(0, 0, 0, 0.4);z-index:var(--mrd-z-modal, 300);display:flex;align-items:center;justify-content:center}.mrd-table__modal.sc-mrd-table{background:#fff;border-radius:var(--mrd-radius-md, 0.5rem);padding:var(--mrd-space-6);max-width:min(600px, 90vw);max-height:70vh;overflow-y:auto;position:relative;box-shadow:var(--mrd-shadow-lg)}.mrd-table__modal-close.sc-mrd-table{position:absolute;top:var(--mrd-space-3);right:var(--mrd-space-3);background:none;border:none;cursor:pointer;font-size:1.25rem;line-height:1;color:var(--mrd-color-text-muted, #6b7280);padding:0}.mrd-table__modal-close.sc-mrd-table:hover{color:var(--mrd-color-text, #111827)}.mrd-table__modal-text.sc-mrd-table{margin:0;padding-right:var(--mrd-space-6);white-space:pre-wrap;word-break:break-word;font-size:var(--mrd-font-size-sm);line-height:1.6}`;
|
|
70
70
|
|
|
71
71
|
const BUFFER = 10;
|
|
72
72
|
/** Wacht deze tijd (ms) na het laatste scroll-event voordat pagina's worden
|
|
@@ -90,6 +90,7 @@ const MrdTable = class {
|
|
|
90
90
|
this.pendingPages = new Set();
|
|
91
91
|
this.debounceTimer = null;
|
|
92
92
|
this.outsideClickHandler = null;
|
|
93
|
+
this.keydownHandler = null;
|
|
93
94
|
// ── Props ──────────────────────────────────────────────────────────────────
|
|
94
95
|
this.columns = [];
|
|
95
96
|
/** Direct rows (non-paginated mode, used when totalElements === 0). */
|
|
@@ -128,6 +129,8 @@ const MrdTable = class {
|
|
|
128
129
|
this.popupPos = { top: 0, left: 0 };
|
|
129
130
|
/** Current scroll offset of the scroll container — drives pagination footer. */
|
|
130
131
|
this.scrollTop = 0;
|
|
132
|
+
/** Full text shown in the TEXTBLOCK expand modal (null = closed). */
|
|
133
|
+
this.textblockModal = null;
|
|
131
134
|
this.handleScroll = (e) => {
|
|
132
135
|
const scroller = e.currentTarget;
|
|
133
136
|
const scrollTop = scroller.scrollTop;
|
|
@@ -204,6 +207,10 @@ const MrdTable = class {
|
|
|
204
207
|
document.removeEventListener('click', this.outsideClickHandler);
|
|
205
208
|
this.outsideClickHandler = null;
|
|
206
209
|
}
|
|
210
|
+
if (this.keydownHandler) {
|
|
211
|
+
document.removeEventListener('keydown', this.keydownHandler);
|
|
212
|
+
this.keydownHandler = null;
|
|
213
|
+
}
|
|
207
214
|
}
|
|
208
215
|
componentDidRender() {
|
|
209
216
|
if (this.colWidths.length === 0 && this.loadedPages.size > 0 && this.totalElements > 0) {
|
|
@@ -348,7 +355,26 @@ const MrdTable = class {
|
|
|
348
355
|
const defaultOperator = (TEXT_TYPES.has(dataType) || dataType === 'RELATION')
|
|
349
356
|
? 'startsWith'
|
|
350
357
|
: undefined;
|
|
351
|
-
|
|
358
|
+
// For DATETIME, stored values are UTC ISO strings; convert back to local
|
|
359
|
+
// "YYYY-MM-DD" dates so the date inputs show what the user originally entered.
|
|
360
|
+
// If from and to cover the same local day it was an exact-date filter — restore
|
|
361
|
+
// to exact mode so the user sees the single-date input again.
|
|
362
|
+
if (dataType === 'DATETIME' && existing) {
|
|
363
|
+
const display = Object.assign({}, existing);
|
|
364
|
+
if (typeof display.from === 'string' && display.from)
|
|
365
|
+
display.from = this.utcISOToLocalDate(display.from);
|
|
366
|
+
if (typeof display.to === 'string' && display.to)
|
|
367
|
+
display.to = this.utcISOToLocalDateExclusiveEnd(display.to);
|
|
368
|
+
if (display.from && display.to && display.from === display.to) {
|
|
369
|
+
this.pendingFilter = Object.assign(Object.assign({}, display), { value: display.from, from: undefined, to: undefined });
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
this.pendingFilter = display;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
this.pendingFilter = existing ? Object.assign({}, existing) : { field: name, dataType, operator: defaultOperator };
|
|
377
|
+
}
|
|
352
378
|
this.openFilterCol = name;
|
|
353
379
|
// Close on outside click — re-register to replace any stale handler
|
|
354
380
|
if (this.outsideClickHandler)
|
|
@@ -368,6 +394,23 @@ const MrdTable = class {
|
|
|
368
394
|
this.outsideClickHandler = null;
|
|
369
395
|
}
|
|
370
396
|
}
|
|
397
|
+
openTextblockModal(text) {
|
|
398
|
+
this.textblockModal = text;
|
|
399
|
+
if (this.keydownHandler)
|
|
400
|
+
document.removeEventListener('keydown', this.keydownHandler);
|
|
401
|
+
this.keydownHandler = (ev) => {
|
|
402
|
+
if (ev.key === 'Escape')
|
|
403
|
+
this.closeTextblockModal();
|
|
404
|
+
};
|
|
405
|
+
document.addEventListener('keydown', this.keydownHandler);
|
|
406
|
+
}
|
|
407
|
+
closeTextblockModal() {
|
|
408
|
+
this.textblockModal = null;
|
|
409
|
+
if (this.keydownHandler) {
|
|
410
|
+
document.removeEventListener('keydown', this.keydownHandler);
|
|
411
|
+
this.keydownHandler = null;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
371
414
|
setPending(key, val) {
|
|
372
415
|
this.pendingFilter = Object.assign(Object.assign({}, this.pendingFilter), { [key]: val });
|
|
373
416
|
}
|
|
@@ -391,18 +434,70 @@ const MrdTable = class {
|
|
|
391
434
|
return true;
|
|
392
435
|
return false;
|
|
393
436
|
}
|
|
437
|
+
// Convert a local "YYYY-MM-DD" date string to the UTC ISO string at the
|
|
438
|
+
// start of that local day (midnight). new Date(y, m, d) uses local time.
|
|
439
|
+
dateLocalToUTCStart(dateStr) {
|
|
440
|
+
if (!dateStr)
|
|
441
|
+
return dateStr;
|
|
442
|
+
const [year, month, day] = dateStr.split('-').map(Number);
|
|
443
|
+
return new Date(year, month - 1, day).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
444
|
+
}
|
|
445
|
+
// Start of the day AFTER the given local date (exclusive range end).
|
|
446
|
+
dateLocalToUTCEndExclusive(dateStr) {
|
|
447
|
+
if (!dateStr)
|
|
448
|
+
return dateStr;
|
|
449
|
+
const [year, month, day] = dateStr.split('-').map(Number);
|
|
450
|
+
return new Date(year, month - 1, day + 1).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
451
|
+
}
|
|
452
|
+
// Convert a stored UTC ISO string back to the local "YYYY-MM-DD" date.
|
|
453
|
+
utcISOToLocalDate(utcStr) {
|
|
454
|
+
if (!utcStr)
|
|
455
|
+
return utcStr;
|
|
456
|
+
const d = new Date(utcStr);
|
|
457
|
+
if (isNaN(d.getTime()))
|
|
458
|
+
return utcStr;
|
|
459
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
460
|
+
}
|
|
461
|
+
// The stored "to" value is the exclusive end (midnight of the next day).
|
|
462
|
+
// Subtract one day to recover the local date the user entered.
|
|
463
|
+
utcISOToLocalDateExclusiveEnd(utcStr) {
|
|
464
|
+
if (!utcStr)
|
|
465
|
+
return utcStr;
|
|
466
|
+
const d = new Date(utcStr);
|
|
467
|
+
if (isNaN(d.getTime()))
|
|
468
|
+
return utcStr;
|
|
469
|
+
d.setDate(d.getDate() - 1);
|
|
470
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
471
|
+
}
|
|
394
472
|
applyFilter() {
|
|
395
473
|
const f = this.pendingFilter;
|
|
396
474
|
if (!(f === null || f === void 0 ? void 0 : f.field)) {
|
|
397
475
|
this.closeFilterPopup();
|
|
398
476
|
return;
|
|
399
477
|
}
|
|
478
|
+
// For DATETIME fields the user enters local dates; convert to UTC ISO strings.
|
|
479
|
+
// Exact date → range covering the full local day (from = midnight, to = next midnight).
|
|
480
|
+
// "to" is always the exclusive end (midnight of the next local day).
|
|
481
|
+
let normalized = Object.assign({}, f);
|
|
482
|
+
if (f.dataType === 'DATETIME') {
|
|
483
|
+
if (typeof normalized.value === 'string' && normalized.value) {
|
|
484
|
+
normalized.from = this.dateLocalToUTCStart(normalized.value);
|
|
485
|
+
normalized.to = this.dateLocalToUTCEndExclusive(normalized.value);
|
|
486
|
+
normalized.value = undefined;
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
if (typeof normalized.from === 'string' && normalized.from)
|
|
490
|
+
normalized.from = this.dateLocalToUTCStart(normalized.from);
|
|
491
|
+
if (typeof normalized.to === 'string' && normalized.to)
|
|
492
|
+
normalized.to = this.dateLocalToUTCEndExclusive(normalized.to);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
400
495
|
const next = new Map(this.activeFilters);
|
|
401
|
-
if (this.filterHasValue(
|
|
402
|
-
next.set(
|
|
496
|
+
if (this.filterHasValue(normalized)) {
|
|
497
|
+
next.set(normalized.field, normalized);
|
|
403
498
|
}
|
|
404
499
|
else {
|
|
405
|
-
next.delete(
|
|
500
|
+
next.delete(normalized.field);
|
|
406
501
|
}
|
|
407
502
|
this.activeFilters = next;
|
|
408
503
|
this.closeFilterPopup();
|
|
@@ -447,7 +542,7 @@ const MrdTable = class {
|
|
|
447
542
|
}
|
|
448
543
|
// ── Render: filter popup ───────────────────────────────────────────────────
|
|
449
544
|
renderFilterEditor(col) {
|
|
450
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
545
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
451
546
|
const pf = (_a = this.pendingFilter) !== null && _a !== void 0 ? _a : {};
|
|
452
547
|
const dataType = this.colDataType(col);
|
|
453
548
|
if (NO_FILTER_TYPES.has(dataType)) {
|
|
@@ -479,12 +574,14 @@ const MrdTable = class {
|
|
|
479
574
|
const rangeMode = pf.from !== undefined || pf.to !== undefined;
|
|
480
575
|
return (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) })))));
|
|
481
576
|
}
|
|
577
|
+
if (dataType === 'DATETIME') {
|
|
578
|
+
const rangeMode = pf.from !== undefined || pf.to !== undefined;
|
|
579
|
+
return (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((_g = pf.value) !== null && _g !== void 0 ? _g : ''), 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) })))));
|
|
580
|
+
}
|
|
482
581
|
if (DATE_TYPES.has(dataType)) {
|
|
483
|
-
const inputType = dataType === 'DATE' ? 'date'
|
|
484
|
-
: dataType === 'DATETIME' ? 'datetime-local'
|
|
485
|
-
: 'time';
|
|
582
|
+
const inputType = dataType === 'DATE' ? 'date' : 'time';
|
|
486
583
|
const rangeMode = pf.from !== undefined || pf.to !== undefined;
|
|
487
|
-
return (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((
|
|
584
|
+
return (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((_h = pf.value) !== null && _h !== void 0 ? _h : ''), 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) })))));
|
|
488
585
|
}
|
|
489
586
|
return null;
|
|
490
587
|
}
|
|
@@ -537,6 +634,15 @@ const MrdTable = class {
|
|
|
537
634
|
this.mrdDownload.emit({ href, fileName });
|
|
538
635
|
} }, 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))) : ''));
|
|
539
636
|
}
|
|
637
|
+
const TEXTBLOCK_MAX = 200;
|
|
638
|
+
if (dataType === 'TEXTBLOCK') {
|
|
639
|
+
const full = CellRenderer.render(col, row, this.locale);
|
|
640
|
+
if (full.length <= TEXTBLOCK_MAX) {
|
|
641
|
+
return h("td", { class: "mrd-table__cell" }, full);
|
|
642
|
+
}
|
|
643
|
+
const preview = full.slice(0, TEXTBLOCK_MAX) + '…';
|
|
644
|
+
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")));
|
|
645
|
+
}
|
|
540
646
|
const value = CellRenderer.render(col, row, this.locale);
|
|
541
647
|
return (h("td", { class: `mrd-table__cell${isNumeric ? ' mrd-table__cell--numeric' : ''}` }, value));
|
|
542
648
|
}
|
|
@@ -551,8 +657,13 @@ const MrdTable = class {
|
|
|
551
657
|
var _a, _b, _c, _d;
|
|
552
658
|
const name = this.colName(col);
|
|
553
659
|
const isFiltered = this.activeFilters.has(name);
|
|
554
|
-
|
|
555
|
-
|
|
660
|
+
const cls = [
|
|
661
|
+
'mrd-table__header',
|
|
662
|
+
isFiltered ? 'mrd-table__header--filtered' : '',
|
|
663
|
+
this.filterMode ? 'mrd-table__header--sortable' : '',
|
|
664
|
+
].filter(Boolean).join(' ');
|
|
665
|
+
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()));
|
|
666
|
+
}))), 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.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()));
|
|
556
667
|
}
|
|
557
668
|
// ── Paginated / virtual-scroll mode ────────────────────────────────────
|
|
558
669
|
// Derive the authoritative row count from loaded pages:
|
|
@@ -594,8 +705,16 @@ const MrdTable = class {
|
|
|
594
705
|
isActive ? `mrd-table__header--sorted-${this.sortDir}` : '',
|
|
595
706
|
isFiltered ? 'mrd-table__header--filtered' : '',
|
|
596
707
|
].filter(Boolean).join(' ');
|
|
597
|
-
return (h("th", { class: cls, style: this.colWidths[idx] ? { width: `${this.colWidths[idx]}px` } : undefined, onClick: () => 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 : ''), h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" },
|
|
598
|
-
}))), 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 })))))), 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()));
|
|
708
|
+
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()));
|
|
709
|
+
}))), 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 })))))), 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()));
|
|
710
|
+
}
|
|
711
|
+
renderFilterIcon() {
|
|
712
|
+
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" }))));
|
|
713
|
+
}
|
|
714
|
+
renderTextblockModal() {
|
|
715
|
+
if (this.textblockModal === null)
|
|
716
|
+
return null;
|
|
717
|
+
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))));
|
|
599
718
|
}
|
|
600
719
|
get el() { return getElement(this); }
|
|
601
720
|
static get watchers() { return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{p as e,b as l}from"./p-_tsCCkAi.js";export{s as setNonce}from"./p-_tsCCkAi.js";import{g as a}from"./p-DQuL1Twl.js";(()=>{const l=import.meta.url,a={};return""!==l&&(a.resourcesUrl=new URL(".",l).href),e(a)})().then((async e=>(await a(),l([["p-
|
|
1
|
+
import{p as e,b as l}from"./p-_tsCCkAi.js";export{s as setNonce}from"./p-_tsCCkAi.js";import{g as a}from"./p-DQuL1Twl.js";(()=>{const l=import.meta.url,a={};return""!==l&&(a.resourcesUrl=new URL(".",l).href),e(a)})().then((async e=>(await a(),l([["p-829b9b6f",[[2,"mrd-table",{columns:[16],rows:[16],locale:[1],totalElements:[2,"total-elements"],pageSize:[2,"page-size"],rowHeight:[2,"row-height"],tableHeight:[2,"table-height"],defaultSort:[1,"default-sort"],actions:[16],loadedPages:[32],requestedPages:[32],renderStart:[32],renderEnd:[32],colWidths:[32],sortField:[32],sortDir:[32],filterMode:[32],activeFilters:[32],openFilterCol:[32],pendingFilter:[32],popupPos:[32],scrollTop:[32],textblockModal:[32],init:[64],setPage:[64]},null,{totalElements:[{totalElementsChanged:0}]}]]],["p-1e0d88fd",[[2,"mrd-form",{layout:[16],locale:[1],values:[16],referenceHref:[1,"reference-href"],referenceClass:[1,"reference-class"],showCancel:[4,"show-cancel"],formValues:[32],errors:[32],submitted:[32],setFieldValue:[64]},null,{values:[{valuesChanged:0}]}],[2,"mrd-field",{item:[16],locale:[1],value:[16]}],[2,"mrd-boolean-field",{name:[1],label:[1],value:[4],required:[4],disabled:[4],locale:[1],checked:[32]}],[2,"mrd-currency-field",{name:[1],label:[1],value:[16],required:[4],disabled:[4],locale:[1],amountDisplay:[32],currency:[32],error:[32]}],[2,"mrd-date-field",{name:[1],label:[1],value:[1],required:[4],disabled:[4],locale:[1],error:[32]}],[2,"mrd-datetime-field",{name:[1],label:[1],value:[1],required:[4],disabled:[4],locale:[1],error:[32]}],[2,"mrd-email-field",{name:[1],label:[1],value:[1],placeholder:[1],required:[4],disabled:[4],locale:[1],error:[32]}],[2,"mrd-file-field",{name:[1],label:[1],value:[16],required:[4],disabled:[4],locale:[1],accept:[1],maxSize:[2,"max-size"],fileName:[32],isDragging:[32],uploading:[32],error:[32]},null,{value:[{valueChanged:0}]}],[2,"mrd-hyperlink-field",{name:[1],label:[1],value:[1],placeholder:[1],required:[4],disabled:[4],locale:[1],error:[32]}],[2,"mrd-image-field",{name:[1],label:[1],value:[16],required:[4],disabled:[4],locale:[1],accept:[1],maxSize:[2,"max-size"],previewUrl:[32],fileName:[32],isDragging:[32],uploading:[32],error:[32]},null,{value:[{valueChanged:0}]}],[2,"mrd-list-field",{name:[1],label:[1],value:[1],required:[4],disabled:[4],multiple:[4],locale:[1],listItems:[16],error:[32],selected:[32]}],[2,"mrd-number-field",{name:[1],label:[1],value:[2],placeholder:[1],required:[4],disabled:[4],locale:[1],dataType:[1,"data-type"],decimalPrecision:[2,"decimal-precision"],displayValue:[32],error:[32]}],[2,"mrd-relation-field",{name:[1],label:[1],required:[4],disabled:[4],locale:[1],relatedClass:[1,"related-class"],mostSignificantClass:[1,"most-significant-class"],displayType:[1,"display-type"],editBehavior:[1,"edit-behavior"],commonRelation:[1,"common-relation"],multiple:[4],dropdownValues:[16],value:[1],searchQuery:[32],searchResults:[32],allRecords:[32],isLoading:[32],selectedItems:[32],showResults:[32],error:[32],highlightedIndex:[32],setAllRecords:[64],setSearchResults:[64],setLoading:[64]}],[2,"mrd-text-field",{name:[1],label:[1],value:[1],placeholder:[1],required:[4],disabled:[4],locale:[1],error:[32]}],[2,"mrd-textarea-field",{name:[1],label:[1],value:[1],placeholder:[1],required:[4],disabled:[4],locale:[1],error:[32],editorReady:[32]}],[2,"mrd-time-field",{name:[1],label:[1],value:[1],required:[4],disabled:[4],locale:[1],error:[32]}]]]],e))));
|