@mmlogic/components 0.3.11 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{index-BPj2cBXs.js → index-CAzwGt9u.js} +38 -0
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/mosterdcomponents.cjs.js +2 -2
- package/dist/cjs/mrd-boolean-field_23.cjs.entry.js +1313 -1088
- package/dist/collection/collection-manifest.json +23 -23
- package/dist/collection/components/{mrd-document-container/mrd-document-container.scss → documents/mrd-document-container/mrd-document-container.css} +3 -3
- package/dist/collection/components/{mrd-document-container → documents/mrd-document-container}/mrd-document-container.js +7 -7
- package/dist/collection/components/documents/mrd-document-list/folder-tree.js +109 -0
- package/dist/collection/components/{mrd-document-list/mrd-document-list.scss → documents/mrd-document-list/mrd-document-list.css} +6 -4
- package/dist/collection/components/{mrd-document-list → documents/mrd-document-list}/mrd-document-list.js +83 -240
- package/dist/collection/components/documents/mrd-document-list/tree-view.js +75 -0
- package/dist/collection/components/{mrd-document-view/mrd-document-view.scss → documents/mrd-document-view/mrd-document-view.css} +1 -1
- package/dist/collection/components/{mrd-document-view → documents/mrd-document-view}/mrd-document-view.js +4 -4
- package/dist/collection/components/fields/field-helpers.js +17 -0
- package/dist/collection/components/fields/file-upload-common.js +38 -0
- package/dist/collection/components/{mrd-boolean-field/mrd-boolean-field.scss → fields/mrd-boolean-field/mrd-boolean-field.css} +3 -3
- package/dist/collection/components/{mrd-boolean-field → fields/mrd-boolean-field}/mrd-boolean-field.js +1 -1
- package/dist/collection/components/{mrd-currency-field/mrd-currency-field.scss → fields/mrd-currency-field/mrd-currency-field.css} +11 -9
- package/dist/collection/components/{mrd-currency-field → fields/mrd-currency-field}/mrd-currency-field.js +7 -13
- package/dist/collection/components/{mrd-date-field/mrd-date-field.scss → fields/mrd-date-field/mrd-date-field.css} +8 -10
- package/dist/collection/components/{mrd-date-field → fields/mrd-date-field}/mrd-date-field.js +3 -10
- package/dist/collection/components/{mrd-datetime-field/mrd-datetime-field.scss → fields/mrd-datetime-field/mrd-datetime-field.css} +8 -10
- package/dist/collection/components/{mrd-datetime-field → fields/mrd-datetime-field}/mrd-datetime-field.js +3 -10
- package/dist/collection/components/{mrd-email-field/mrd-email-field.scss → fields/mrd-email-field/mrd-email-field.css} +2 -11
- package/dist/collection/components/{mrd-email-field → fields/mrd-email-field}/mrd-email-field.js +6 -13
- package/dist/collection/components/{mrd-file-field/mrd-file-field.scss → fields/mrd-file-field/mrd-file-field.css} +19 -24
- package/dist/collection/components/{mrd-file-field → fields/mrd-file-field}/mrd-file-field.js +13 -24
- package/dist/collection/components/{mrd-hyperlink-field/mrd-hyperlink-field.scss → fields/mrd-hyperlink-field/mrd-hyperlink-field.css} +7 -16
- package/dist/collection/components/{mrd-hyperlink-field → fields/mrd-hyperlink-field}/mrd-hyperlink-field.js +9 -15
- package/dist/collection/components/{mrd-image-field/mrd-image-field.scss → fields/mrd-image-field/mrd-image-field.css} +15 -24
- package/dist/collection/components/{mrd-image-field → fields/mrd-image-field}/mrd-image-field.js +13 -28
- package/dist/collection/components/{mrd-list-field/mrd-list-field.scss → fields/mrd-list-field/mrd-list-field.css} +18 -21
- package/dist/collection/components/{mrd-list-field → fields/mrd-list-field}/mrd-list-field.js +10 -25
- package/dist/collection/components/{mrd-longtext-field/mrd-longtext-field.scss → fields/mrd-longtext-field/mrd-longtext-field.css} +21 -18
- package/dist/collection/components/{mrd-longtext-field → fields/mrd-longtext-field}/mrd-longtext-field.js +3 -10
- package/dist/collection/components/{mrd-number-field/mrd-number-field.scss → fields/mrd-number-field/mrd-number-field.css} +9 -10
- package/dist/collection/components/{mrd-number-field → fields/mrd-number-field}/mrd-number-field.js +7 -6
- package/dist/collection/components/{mrd-relation-field/mrd-relation-field.scss → fields/mrd-relation-field/mrd-relation-field.css} +61 -59
- package/dist/collection/components/{mrd-relation-field → fields/mrd-relation-field}/mrd-relation-field.js +16 -26
- package/dist/collection/components/{mrd-secret-field/mrd-secret-field.scss → fields/mrd-secret-field/mrd-secret-field.css} +7 -10
- package/dist/collection/components/{mrd-secret-field → fields/mrd-secret-field}/mrd-secret-field.js +4 -11
- package/dist/collection/components/{mrd-text-field/mrd-text-field.scss → fields/mrd-text-field/mrd-text-field.css} +2 -11
- package/dist/collection/components/{mrd-text-field → fields/mrd-text-field}/mrd-text-field.js +3 -10
- package/dist/collection/components/{mrd-textarea-field/mrd-textarea-field.scss → fields/mrd-textarea-field/mrd-textarea-field.css} +7 -10
- package/dist/collection/components/{mrd-textarea-field → fields/mrd-textarea-field}/mrd-textarea-field.js +3 -9
- package/dist/collection/components/{mrd-time-field/mrd-time-field.scss → fields/mrd-time-field/mrd-time-field.css} +8 -10
- package/dist/collection/components/{mrd-time-field → fields/mrd-time-field}/mrd-time-field.js +3 -10
- package/dist/collection/components/{mrd-field/mrd-field.scss → form/mrd-field/mrd-field.css} +1 -1
- package/dist/collection/components/{mrd-field → form/mrd-field}/mrd-field.js +3 -3
- package/dist/collection/components/{mrd-form/mrd-form.scss → form/mrd-form/mrd-form.css} +1 -1
- package/dist/collection/components/{mrd-form → form/mrd-form}/mrd-form.js +5 -5
- package/dist/collection/components/layout/mrd-layout-section/field-value.js +111 -0
- package/dist/collection/components/layout/mrd-layout-section/layout-helpers.js +29 -0
- package/dist/collection/components/{mrd-layout-section/mrd-layout-section.scss → layout/mrd-layout-section/mrd-layout-section.css} +4 -4
- package/dist/collection/components/{mrd-layout-section → layout/mrd-layout-section}/mrd-layout-section.js +52 -142
- package/dist/collection/components/{mrd-table/mrd-table.scss → table/mrd-table/mrd-table.css} +30 -12
- package/dist/collection/components/{mrd-table → table/mrd-table}/mrd-table.js +234 -443
- package/dist/collection/components/table/mrd-table/table-filter-popup.js +85 -0
- package/dist/collection/components/table/mrd-table/table-parts.js +110 -0
- package/dist/collection/components/table/mrd-table/table-query.js +178 -0
- package/dist/collection/components/table/mrd-table/virtual-scroll.js +63 -0
- package/dist/collection/dev/app.js +19 -18
- package/dist/collection/dev/example-data.js +58 -43
- package/dist/collection/utils/i18n.js +16 -0
- package/dist/collection/utils/query-params.js +43 -0
- package/dist/components/field-helpers.js +1 -0
- package/dist/components/file-upload-common.js +1 -0
- package/dist/components/i18n.js +1 -1
- package/dist/components/mrd-boolean-field2.js +1 -1
- package/dist/components/mrd-currency-field2.js +1 -1
- package/dist/components/mrd-date-field2.js +1 -1
- package/dist/components/mrd-datetime-field2.js +1 -1
- package/dist/components/mrd-document-container2.js +1 -1
- package/dist/components/mrd-document-list2.js +1 -1
- package/dist/components/mrd-document-view2.js +1 -1
- package/dist/components/mrd-email-field2.js +1 -1
- package/dist/components/mrd-file-field2.js +1 -1
- package/dist/components/mrd-form.js +1 -1
- package/dist/components/mrd-hyperlink-field2.js +1 -1
- package/dist/components/mrd-image-field2.js +1 -1
- package/dist/components/mrd-layout-section.js +1 -1
- package/dist/components/mrd-list-field2.js +1 -1
- package/dist/components/mrd-longtext-field2.js +1 -1
- package/dist/components/mrd-number-field2.js +1 -1
- package/dist/components/mrd-relation-field2.js +1 -1
- package/dist/components/mrd-secret-field2.js +1 -1
- package/dist/components/mrd-table2.js +1 -1
- package/dist/components/mrd-text-field2.js +1 -1
- package/dist/components/mrd-textarea-field2.js +1 -1
- package/dist/components/mrd-time-field2.js +1 -1
- package/dist/components/query-params.js +1 -0
- package/dist/esm/{index-_tsCCkAi.js → index-DiSEJMA8.js} +38 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/mosterdcomponents.js +3 -3
- package/dist/esm/mrd-boolean-field_23.entry.js +1313 -1088
- package/dist/mosterdcomponents/mosterdcomponents.css +1 -1
- package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
- package/dist/mosterdcomponents/p-DiSEJMA8.js +2 -0
- package/dist/mosterdcomponents/p-b1a2e108.entry.js +1 -0
- package/dist/types/components/{mrd-document-container → documents/mrd-document-container}/mrd-document-container.d.ts +2 -2
- package/dist/types/components/documents/mrd-document-list/folder-tree.d.ts +66 -0
- package/dist/types/components/{mrd-document-list → documents/mrd-document-list}/mrd-document-list.d.ts +4 -37
- package/dist/types/components/documents/mrd-document-list/tree-view.d.ts +32 -0
- package/dist/types/components/{mrd-document-view → documents/mrd-document-view}/mrd-document-view.d.ts +2 -2
- package/dist/types/components/fields/field-helpers.d.ts +18 -0
- package/dist/types/components/fields/file-upload-common.d.ts +18 -0
- package/dist/types/components/{mrd-boolean-field → fields/mrd-boolean-field}/mrd-boolean-field.d.ts +1 -1
- package/dist/types/components/{mrd-currency-field → fields/mrd-currency-field}/mrd-currency-field.d.ts +2 -2
- package/dist/types/components/{mrd-date-field → fields/mrd-date-field}/mrd-date-field.d.ts +1 -1
- package/dist/types/components/{mrd-datetime-field → fields/mrd-datetime-field}/mrd-datetime-field.d.ts +1 -1
- package/dist/types/components/{mrd-email-field → fields/mrd-email-field}/mrd-email-field.d.ts +1 -1
- package/dist/types/components/{mrd-file-field → fields/mrd-file-field}/mrd-file-field.d.ts +2 -4
- package/dist/types/components/{mrd-hyperlink-field → fields/mrd-hyperlink-field}/mrd-hyperlink-field.d.ts +2 -2
- package/dist/types/components/{mrd-image-field → fields/mrd-image-field}/mrd-image-field.d.ts +2 -4
- package/dist/types/components/{mrd-list-field → fields/mrd-list-field}/mrd-list-field.d.ts +2 -2
- package/dist/types/components/{mrd-longtext-field → fields/mrd-longtext-field}/mrd-longtext-field.d.ts +1 -1
- package/dist/types/components/{mrd-number-field → fields/mrd-number-field}/mrd-number-field.d.ts +2 -2
- package/dist/types/components/{mrd-relation-field → fields/mrd-relation-field}/mrd-relation-field.d.ts +2 -2
- package/dist/types/components/{mrd-secret-field → fields/mrd-secret-field}/mrd-secret-field.d.ts +1 -1
- package/dist/types/components/{mrd-text-field → fields/mrd-text-field}/mrd-text-field.d.ts +1 -1
- package/dist/types/components/{mrd-textarea-field → fields/mrd-textarea-field}/mrd-textarea-field.d.ts +1 -1
- package/dist/types/components/{mrd-time-field → fields/mrd-time-field}/mrd-time-field.d.ts +1 -1
- package/dist/types/components/{mrd-field → form/mrd-field}/mrd-field.d.ts +2 -2
- package/dist/types/components/{mrd-form → form/mrd-form}/mrd-form.d.ts +2 -2
- package/dist/types/components/layout/mrd-layout-section/field-value.d.ts +22 -0
- package/dist/types/components/layout/mrd-layout-section/layout-helpers.d.ts +8 -0
- package/dist/types/components/{mrd-layout-section → layout/mrd-layout-section}/mrd-layout-section.d.ts +4 -11
- package/dist/types/components/{mrd-table → table/mrd-table}/mrd-table.d.ts +29 -13
- package/dist/types/components/table/mrd-table/table-filter-popup.d.ts +35 -0
- package/dist/types/components/table/mrd-table/table-parts.d.ts +61 -0
- package/dist/types/components/table/mrd-table/table-query.d.ts +50 -0
- package/dist/types/components/table/mrd-table/virtual-scroll.d.ts +33 -0
- package/dist/types/components.d.ts +19 -5
- package/dist/types/utils/query-params.d.ts +14 -0
- package/package.json +7 -2
- package/dist/components/validation.js +0 -1
- package/dist/mosterdcomponents/p-_tsCCkAi.js +0 -2
- package/dist/mosterdcomponents/p-a9618055.entry.js +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-CAzwGt9u.js');
|
|
4
4
|
var index$1 = require('./index.cjs.js');
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const mrdBooleanFieldCss = () => `.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)}`;
|
|
7
7
|
|
|
8
8
|
const MrdBooleanField = class {
|
|
9
9
|
constructor(hostRef) {
|
|
@@ -29,10 +29,83 @@ const MrdBooleanField = class {
|
|
|
29
29
|
this.checked = !!this.value;
|
|
30
30
|
}
|
|
31
31
|
render() {
|
|
32
|
-
return (index.h(index.Host, { key: '
|
|
32
|
+
return (index.h(index.Host, { key: 'f7851813646d31c565c262bf3c8d4083177dd993' }, index.h("div", { key: '4b3c9f46e8b79bdc97ef5815afb85ba5ddde0c9a', class: "mrd-boolean-field" }, index.h("label", { key: 'f81fa28d5a79de0445c2c192352343f0807609a1', class: "mrd-boolean-field__toggle-label" }, index.h("input", { key: '510a4f5533cbe2741b8df34cb64fc739475a26cf', class: "mrd-boolean-field__checkbox", type: "checkbox", name: this.name, checked: this.checked, disabled: this.disabled, onChange: this.handleChange, onBlur: this.handleBlur }), index.h("span", { key: '949e042c8af0f2872cf973a0d5407fce972eb240', class: "mrd-boolean-field__toggle", "aria-hidden": "true" }), this.label && (index.h("span", { key: 'e8c52b5820887b2a8ec9a20eb7e4116a528d27d4', class: `mrd-boolean-field__text${this.required ? ' mrd-boolean-field__text--required' : ''}` }, this.label))))));
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
|
-
MrdBooleanField.style =
|
|
35
|
+
MrdBooleanField.style = mrdBooleanFieldCss();
|
|
36
|
+
|
|
37
|
+
function formatNumber(value, locale, options) {
|
|
38
|
+
if (value === null || value === undefined || isNaN(value))
|
|
39
|
+
return '';
|
|
40
|
+
return new Intl.NumberFormat(locale, options).format(value);
|
|
41
|
+
}
|
|
42
|
+
function formatCurrency(amount, currency, locale) {
|
|
43
|
+
if (amount === null || amount === undefined || isNaN(amount))
|
|
44
|
+
return '';
|
|
45
|
+
return new Intl.NumberFormat(locale, {
|
|
46
|
+
style: 'currency',
|
|
47
|
+
currency,
|
|
48
|
+
minimumFractionDigits: 2,
|
|
49
|
+
maximumFractionDigits: 2,
|
|
50
|
+
}).format(amount);
|
|
51
|
+
}
|
|
52
|
+
function formatPercentage(value, locale, decimalPrecision = 2) {
|
|
53
|
+
if (value === null || value === undefined || isNaN(value))
|
|
54
|
+
return '';
|
|
55
|
+
return new Intl.NumberFormat(locale, {
|
|
56
|
+
style: 'percent',
|
|
57
|
+
minimumFractionDigits: decimalPrecision,
|
|
58
|
+
maximumFractionDigits: decimalPrecision,
|
|
59
|
+
}).format(value);
|
|
60
|
+
}
|
|
61
|
+
function formatDate(value, locale) {
|
|
62
|
+
if (!value)
|
|
63
|
+
return '';
|
|
64
|
+
const date = typeof value === 'string' ? new Date(value) : value;
|
|
65
|
+
if (isNaN(date.getTime()))
|
|
66
|
+
return '';
|
|
67
|
+
return new Intl.DateTimeFormat(locale, { year: 'numeric', month: '2-digit', day: '2-digit' }).format(date);
|
|
68
|
+
}
|
|
69
|
+
function formatDateTime(value, locale) {
|
|
70
|
+
if (!value)
|
|
71
|
+
return '';
|
|
72
|
+
const date = typeof value === 'string' ? new Date(value) : value;
|
|
73
|
+
if (isNaN(date.getTime()))
|
|
74
|
+
return '';
|
|
75
|
+
return new Intl.DateTimeFormat(locale, {
|
|
76
|
+
year: 'numeric',
|
|
77
|
+
month: '2-digit',
|
|
78
|
+
day: '2-digit',
|
|
79
|
+
hour: '2-digit',
|
|
80
|
+
minute: '2-digit',
|
|
81
|
+
}).format(date);
|
|
82
|
+
}
|
|
83
|
+
function formatTime(value, locale) {
|
|
84
|
+
if (!value)
|
|
85
|
+
return '';
|
|
86
|
+
// value is HH:MM or HH:MM:SS
|
|
87
|
+
const [hours, minutes] = value.split(':').map(Number);
|
|
88
|
+
const date = new Date();
|
|
89
|
+
date.setHours(hours, minutes, 0, 0);
|
|
90
|
+
return new Intl.DateTimeFormat(locale, { hour: '2-digit', minute: '2-digit' }).format(date);
|
|
91
|
+
}
|
|
92
|
+
function parseLocalizedNumber(str, locale) {
|
|
93
|
+
var _a, _b, _c, _d;
|
|
94
|
+
if (!str || !str.trim())
|
|
95
|
+
return null;
|
|
96
|
+
// Detect decimal and thousands separators from the locale
|
|
97
|
+
const parts = new Intl.NumberFormat(locale).formatToParts(1234567.89);
|
|
98
|
+
const groupSep = (_b = (_a = parts.find((p) => p.type === 'group')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : ',';
|
|
99
|
+
const decimalSep = (_d = (_c = parts.find((p) => p.type === 'decimal')) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : '.';
|
|
100
|
+
// Remove group separators, replace decimal separator with '.'
|
|
101
|
+
const normalized = str
|
|
102
|
+
.replace(new RegExp(`\\${groupSep}`, 'g'), '')
|
|
103
|
+
.replace(new RegExp(`\\${decimalSep}`), '.')
|
|
104
|
+
.replace('%', '')
|
|
105
|
+
.trim();
|
|
106
|
+
const parsed = parseFloat(normalized);
|
|
107
|
+
return isNaN(parsed) ? null : parsed;
|
|
108
|
+
}
|
|
36
109
|
|
|
37
110
|
const translations = {
|
|
38
111
|
nl: {
|
|
@@ -49,8 +122,10 @@ const translations = {
|
|
|
49
122
|
drop_file_here: 'Sleep bestand hierheen of',
|
|
50
123
|
browse: 'bladeren',
|
|
51
124
|
file_too_large: 'Bestand is te groot',
|
|
125
|
+
invalid_image: 'Selecteer een afbeeldingsbestand',
|
|
52
126
|
search_results: 'Zoekresultaten',
|
|
53
127
|
no_results: 'Geen resultaten gevonden',
|
|
128
|
+
load_failed_retry: 'Laden mislukt — opnieuw proberen',
|
|
54
129
|
loading: 'Laden...',
|
|
55
130
|
submit: 'Opslaan',
|
|
56
131
|
cancel: 'Annuleren',
|
|
@@ -121,8 +196,10 @@ const translations = {
|
|
|
121
196
|
drop_file_here: 'Drop file here or',
|
|
122
197
|
browse: 'browse',
|
|
123
198
|
file_too_large: 'File is too large',
|
|
199
|
+
invalid_image: 'Please select an image file',
|
|
124
200
|
search_results: 'Search results',
|
|
125
201
|
no_results: 'No results found',
|
|
202
|
+
load_failed_retry: 'Failed to load — retry',
|
|
126
203
|
loading: 'Loading...',
|
|
127
204
|
submit: 'Save',
|
|
128
205
|
cancel: 'Cancel',
|
|
@@ -193,8 +270,10 @@ const translations = {
|
|
|
193
270
|
drop_file_here: 'اسحب الملف هنا أو',
|
|
194
271
|
browse: 'تصفح',
|
|
195
272
|
file_too_large: 'الملف كبير جداً',
|
|
273
|
+
invalid_image: 'يرجى اختيار ملف صورة',
|
|
196
274
|
search_results: 'نتائج البحث',
|
|
197
275
|
no_results: 'لم يتم العثور على نتائج',
|
|
276
|
+
load_failed_retry: 'فشل التحميل — إعادة المحاولة',
|
|
198
277
|
loading: 'جار التحميل...',
|
|
199
278
|
submit: 'حفظ',
|
|
200
279
|
cancel: 'إلغاء',
|
|
@@ -259,8 +338,10 @@ const translations = {
|
|
|
259
338
|
drop_file_here: 'Déposez le fichier ici ou',
|
|
260
339
|
browse: 'parcourir',
|
|
261
340
|
file_too_large: 'Le fichier est trop volumineux',
|
|
341
|
+
invalid_image: 'Veuillez sélectionner un fichier image',
|
|
262
342
|
search_results: 'Résultats de recherche',
|
|
263
343
|
no_results: 'Aucun résultat trouvé',
|
|
344
|
+
load_failed_retry: 'Échec du chargement — réessayer',
|
|
264
345
|
loading: 'Chargement...',
|
|
265
346
|
submit: 'Enregistrer',
|
|
266
347
|
cancel: 'Annuler',
|
|
@@ -325,8 +406,10 @@ const translations = {
|
|
|
325
406
|
drop_file_here: 'Datei hier ablegen oder',
|
|
326
407
|
browse: 'durchsuchen',
|
|
327
408
|
file_too_large: 'Datei ist zu groß',
|
|
409
|
+
invalid_image: 'Bitte eine Bilddatei auswählen',
|
|
328
410
|
search_results: 'Suchergebnisse',
|
|
329
411
|
no_results: 'Keine Ergebnisse gefunden',
|
|
412
|
+
load_failed_retry: 'Laden fehlgeschlagen — erneut versuchen',
|
|
330
413
|
loading: 'Laden...',
|
|
331
414
|
submit: 'Speichern',
|
|
332
415
|
cancel: 'Abbrechen',
|
|
@@ -391,8 +474,10 @@ const translations = {
|
|
|
391
474
|
drop_file_here: 'Suelte el archivo aquí o',
|
|
392
475
|
browse: 'explorar',
|
|
393
476
|
file_too_large: 'El archivo es demasiado grande',
|
|
477
|
+
invalid_image: 'Seleccione un archivo de imagen',
|
|
394
478
|
search_results: 'Resultados de búsqueda',
|
|
395
479
|
no_results: 'No se encontraron resultados',
|
|
480
|
+
load_failed_retry: 'Error al cargar — reintentar',
|
|
396
481
|
loading: 'Cargando...',
|
|
397
482
|
submit: 'Guardar',
|
|
398
483
|
cancel: 'Cancelar',
|
|
@@ -457,8 +542,10 @@ const translations = {
|
|
|
457
542
|
drop_file_here: 'Trascina il file qui o',
|
|
458
543
|
browse: 'sfoglia',
|
|
459
544
|
file_too_large: 'Il file è troppo grande',
|
|
545
|
+
invalid_image: 'Seleziona un file immagine',
|
|
460
546
|
search_results: 'Risultati della ricerca',
|
|
461
547
|
no_results: 'Nessun risultato trovato',
|
|
548
|
+
load_failed_retry: 'Caricamento non riuscito — riprova',
|
|
462
549
|
loading: 'Caricamento...',
|
|
463
550
|
submit: 'Salva',
|
|
464
551
|
cancel: 'Annulla',
|
|
@@ -523,8 +610,10 @@ const translations = {
|
|
|
523
610
|
drop_file_here: 'Перетягніть файл сюди або',
|
|
524
611
|
browse: 'огляд',
|
|
525
612
|
file_too_large: 'Файл занадто великий',
|
|
613
|
+
invalid_image: 'Будь ласка, виберіть файл зображення',
|
|
526
614
|
search_results: 'Результати пошуку',
|
|
527
615
|
no_results: 'Результатів не знайдено',
|
|
616
|
+
load_failed_retry: 'Не вдалося завантажити — повторити',
|
|
528
617
|
loading: 'Завантаження...',
|
|
529
618
|
submit: 'Зберегти',
|
|
530
619
|
cancel: 'Скасувати',
|
|
@@ -633,80 +722,22 @@ function validateNumber(value, dataType) {
|
|
|
633
722
|
return true;
|
|
634
723
|
}
|
|
635
724
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
return
|
|
645
|
-
style: 'currency',
|
|
646
|
-
currency,
|
|
647
|
-
minimumFractionDigits: 2,
|
|
648
|
-
maximumFractionDigits: 2,
|
|
649
|
-
}).format(amount);
|
|
650
|
-
}
|
|
651
|
-
function formatPercentage(value, locale, decimalPrecision = 2) {
|
|
652
|
-
if (value === null || value === undefined || isNaN(value))
|
|
653
|
-
return '';
|
|
654
|
-
return new Intl.NumberFormat(locale, {
|
|
655
|
-
style: 'percent',
|
|
656
|
-
minimumFractionDigits: decimalPrecision,
|
|
657
|
-
maximumFractionDigits: decimalPrecision,
|
|
658
|
-
}).format(value);
|
|
725
|
+
/**
|
|
726
|
+
* Shared building blocks for the leaf field components.
|
|
727
|
+
* `base` is the BEM block name, e.g. 'mrd-text-field'.
|
|
728
|
+
*/
|
|
729
|
+
const FieldLabel = ({ base, label, required }) => label ? index.h("label", { class: `${base}__label${required ? ` ${base}__label--required` : ''}` }, label) : null;
|
|
730
|
+
const FieldError = ({ base, error }) => error ? index.h("span", { class: `${base}__error` }, error) : null;
|
|
731
|
+
/** Class string for the form control, with the --error modifier when applicable. */
|
|
732
|
+
function controlClass(base, hasError, element = 'input') {
|
|
733
|
+
return `${base}__${element}${hasError ? ` ${base}__${element}--error` : ''}`;
|
|
659
734
|
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
const date = typeof value === 'string' ? new Date(value) : value;
|
|
664
|
-
if (isNaN(date.getTime()))
|
|
665
|
-
return '';
|
|
666
|
-
return new Intl.DateTimeFormat(locale, { year: 'numeric', month: '2-digit', day: '2-digit' }).format(date);
|
|
667
|
-
}
|
|
668
|
-
function formatDateTime(value, locale) {
|
|
669
|
-
if (!value)
|
|
670
|
-
return '';
|
|
671
|
-
const date = typeof value === 'string' ? new Date(value) : value;
|
|
672
|
-
if (isNaN(date.getTime()))
|
|
673
|
-
return '';
|
|
674
|
-
return new Intl.DateTimeFormat(locale, {
|
|
675
|
-
year: 'numeric',
|
|
676
|
-
month: '2-digit',
|
|
677
|
-
day: '2-digit',
|
|
678
|
-
hour: '2-digit',
|
|
679
|
-
minute: '2-digit',
|
|
680
|
-
}).format(date);
|
|
681
|
-
}
|
|
682
|
-
function formatTime(value, locale) {
|
|
683
|
-
if (!value)
|
|
684
|
-
return '';
|
|
685
|
-
// value is HH:MM or HH:MM:SS
|
|
686
|
-
const [hours, minutes] = value.split(':').map(Number);
|
|
687
|
-
const date = new Date();
|
|
688
|
-
date.setHours(hours, minutes, 0, 0);
|
|
689
|
-
return new Intl.DateTimeFormat(locale, { hour: '2-digit', minute: '2-digit' }).format(date);
|
|
690
|
-
}
|
|
691
|
-
function parseLocalizedNumber(str, locale) {
|
|
692
|
-
var _a, _b, _c, _d;
|
|
693
|
-
if (!str || !str.trim())
|
|
694
|
-
return null;
|
|
695
|
-
// Detect decimal and thousands separators from the locale
|
|
696
|
-
const parts = new Intl.NumberFormat(locale).formatToParts(1234567.89);
|
|
697
|
-
const groupSep = (_b = (_a = parts.find((p) => p.type === 'group')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : ',';
|
|
698
|
-
const decimalSep = (_d = (_c = parts.find((p) => p.type === 'decimal')) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : '.';
|
|
699
|
-
// Remove group separators, replace decimal separator with '.'
|
|
700
|
-
const normalized = str
|
|
701
|
-
.replace(new RegExp(`\\${groupSep}`, 'g'), '')
|
|
702
|
-
.replace(new RegExp(`\\${decimalSep}`), '.')
|
|
703
|
-
.replace('%', '')
|
|
704
|
-
.trim();
|
|
705
|
-
const parsed = parseFloat(normalized);
|
|
706
|
-
return isNaN(parsed) ? null : parsed;
|
|
735
|
+
/** Returns the localised required-error, or '' when the value passes. */
|
|
736
|
+
function requiredError(value, required, locale) {
|
|
737
|
+
return required && !validateRequired(value) ? t('required', locale) : '';
|
|
707
738
|
}
|
|
708
739
|
|
|
709
|
-
const
|
|
740
|
+
const mrdCurrencyFieldCss = () => `.sc-mrd-currency-field-h{display:block}.mrd-currency-field.sc-mrd-currency-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-currency-field__label.sc-mrd-currency-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-currency-field__label--required.sc-mrd-currency-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-currency-field__row.sc-mrd-currency-field{display:flex;gap:var(--mrd-space-2);align-items:stretch}.mrd-currency-field__amount.sc-mrd-currency-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-currency-field__amount.sc-mrd-currency-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-currency-field__amount.sc-mrd-currency-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-currency-field__amount.sc-mrd-currency-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-currency-field__amount--error.sc-mrd-currency-field{border-color:var(--mrd-border-color-error)}.mrd-currency-field__amount--error.sc-mrd-currency-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-currency-field__amount.sc-mrd-currency-field{flex:1;text-align:right}.mrd-currency-field__currency.sc-mrd-currency-field{width:90px;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-space-2);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-input-color);background-color:var(--mrd-color-neutral-50);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);outline:none;cursor:pointer;box-sizing:border-box;appearance:none;text-align:center}.mrd-currency-field__currency.sc-mrd-currency-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-currency-field__currency.sc-mrd-currency-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-currency-field__error.sc-mrd-currency-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}`;
|
|
710
741
|
|
|
711
742
|
const COMMON_CURRENCIES = [
|
|
712
743
|
'EUR', 'USD', 'GBP', 'CHF', 'JPY', 'CNY', 'AUD', 'CAD',
|
|
@@ -733,12 +764,7 @@ const MrdCurrencyField = class {
|
|
|
733
764
|
this.handleAmountBlur = (e) => {
|
|
734
765
|
const raw = e.target.value;
|
|
735
766
|
const parsed = parseLocalizedNumber(raw, this.locale);
|
|
736
|
-
|
|
737
|
-
this.error = t('required', this.locale);
|
|
738
|
-
}
|
|
739
|
-
else {
|
|
740
|
-
this.error = '';
|
|
741
|
-
}
|
|
767
|
+
this.error = requiredError(raw, this.required, this.locale);
|
|
742
768
|
const val = { amount: parsed, currency: this.currency };
|
|
743
769
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
744
770
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
@@ -757,12 +783,12 @@ const MrdCurrencyField = class {
|
|
|
757
783
|
}
|
|
758
784
|
render() {
|
|
759
785
|
const hasError = !!this.error;
|
|
760
|
-
return (index.h(index.Host, { key: '
|
|
786
|
+
return (index.h(index.Host, { key: '24c530db6e0420af39fa0a35b31e966286f2d00c' }, index.h("div", { key: '795bc336425fbf1b86828f4a8f5df93930169a3c', class: "mrd-currency-field" }, index.h(FieldLabel, { key: 'b302cd9296c29ed5719b1f768bd5d4eea86f6406', base: "mrd-currency-field", label: this.label, required: this.required }), index.h("div", { key: '7efca51615f405ffd660e120accae32f55a9b5a0', class: "mrd-currency-field__row" }, index.h("input", { key: '5c6fd3549d5631fba49a8a701e6c3a1d0a672890', class: controlClass('mrd-currency-field', hasError, 'amount'), type: "text", inputMode: "decimal", name: `${this.name}_amount`, value: this.amountDisplay, placeholder: "0.00", required: this.required, disabled: this.disabled, onInput: this.handleAmountInput, onBlur: this.handleAmountBlur }), index.h("select", { key: '83ad5e92b623c3c60d161b8828e780adb476682c', class: "mrd-currency-field__currency", disabled: this.disabled, onChange: this.handleCurrencyChange }, COMMON_CURRENCIES.map(c => (index.h("option", { key: c, value: c, selected: c === this.currency }, c))))), index.h(FieldError, { key: 'b059290bb566b119c4f192e750b3e365446243e6', base: "mrd-currency-field", error: this.error }))));
|
|
761
787
|
}
|
|
762
788
|
};
|
|
763
|
-
MrdCurrencyField.style =
|
|
789
|
+
MrdCurrencyField.style = mrdCurrencyFieldCss();
|
|
764
790
|
|
|
765
|
-
const
|
|
791
|
+
const mrdDateFieldCss = () => `.sc-mrd-date-field-h{display:block}.mrd-date-field.sc-mrd-date-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-date-field__label.sc-mrd-date-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-date-field__label--required.sc-mrd-date-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-date-field__input.sc-mrd-date-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-date-field__input.sc-mrd-date-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-date-field__input.sc-mrd-date-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-date-field__input.sc-mrd-date-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-date-field__input--error.sc-mrd-date-field{border-color:var(--mrd-border-color-error)}.mrd-date-field__input--error.sc-mrd-date-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-date-field__error.sc-mrd-date-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-date-field__input.sc-mrd-date-field{cursor:pointer}`;
|
|
766
792
|
|
|
767
793
|
const MrdDateField = class {
|
|
768
794
|
constructor(hostRef) {
|
|
@@ -778,12 +804,7 @@ const MrdDateField = class {
|
|
|
778
804
|
this.error = '';
|
|
779
805
|
this.handleChange = (e) => {
|
|
780
806
|
const val = e.target.value;
|
|
781
|
-
|
|
782
|
-
this.error = t('required', this.locale);
|
|
783
|
-
}
|
|
784
|
-
else {
|
|
785
|
-
this.error = '';
|
|
786
|
-
}
|
|
807
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
787
808
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
788
809
|
};
|
|
789
810
|
this.handleBlur = (e) => {
|
|
@@ -792,13 +813,12 @@ const MrdDateField = class {
|
|
|
792
813
|
};
|
|
793
814
|
}
|
|
794
815
|
render() {
|
|
795
|
-
|
|
796
|
-
return (index.h(index.Host, { key: '2c0dc2311068a5c759fe8efe58a98a71a9cf4b7b' }, index.h("div", { key: 'ee1cc0e9a2943cc42439825b8f21cd3492eaca05', class: "mrd-date-field" }, this.label && (index.h("label", { key: '3f836a991e676b6070a8b3800edfce00cc0d3b3d', class: `mrd-date-field__label${this.required ? ' mrd-date-field__label--required' : ''}` }, this.label)), index.h("input", { key: '575185661987eea3dc91950f51995b2cc75debea', class: `mrd-date-field__input${hasError ? ' mrd-date-field__input--error' : ''}`, type: "date", name: this.name, value: this.value, required: this.required, disabled: this.disabled, onChange: this.handleChange, onBlur: this.handleBlur }), hasError && index.h("span", { key: '480ec99200989f3dc543d9afc648d83d31992b3c', class: "mrd-date-field__error" }, this.error))));
|
|
816
|
+
return (index.h(index.Host, { key: '71be9e4bcc87b40cf3b777d3fe0bff23c1a0fa94' }, index.h("div", { key: '40ced03df5d4185264ba9d03c832b3870ce8ae19', class: "mrd-date-field" }, index.h(FieldLabel, { key: 'd85ec7c4617a22c8c5862253e8090c85484f8c41', base: "mrd-date-field", label: this.label, required: this.required }), index.h("input", { key: 'c9211fdefdd9527c7ff40ed9de33153303fc1742', class: controlClass('mrd-date-field', !!this.error), type: "date", name: this.name, value: this.value, required: this.required, disabled: this.disabled, onChange: this.handleChange, onBlur: this.handleBlur }), index.h(FieldError, { key: '9dd64475bf8a77bea5344faa71f20485b34b86f9', base: "mrd-date-field", error: this.error }))));
|
|
797
817
|
}
|
|
798
818
|
};
|
|
799
|
-
MrdDateField.style =
|
|
819
|
+
MrdDateField.style = mrdDateFieldCss();
|
|
800
820
|
|
|
801
|
-
const
|
|
821
|
+
const mrdDatetimeFieldCss = () => `.sc-mrd-datetime-field-h{display:block}.mrd-datetime-field.sc-mrd-datetime-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-datetime-field__label.sc-mrd-datetime-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-datetime-field__label--required.sc-mrd-datetime-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-datetime-field__input.sc-mrd-datetime-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-datetime-field__input.sc-mrd-datetime-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-datetime-field__input.sc-mrd-datetime-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-datetime-field__input.sc-mrd-datetime-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-datetime-field__input--error.sc-mrd-datetime-field{border-color:var(--mrd-border-color-error)}.mrd-datetime-field__input--error.sc-mrd-datetime-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-datetime-field__error.sc-mrd-datetime-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-datetime-field__input.sc-mrd-datetime-field{cursor:pointer}`;
|
|
802
822
|
|
|
803
823
|
const MrdDatetimeField = class {
|
|
804
824
|
constructor(hostRef) {
|
|
@@ -816,12 +836,7 @@ const MrdDatetimeField = class {
|
|
|
816
836
|
this.handleChange = (e) => {
|
|
817
837
|
const localVal = e.target.value;
|
|
818
838
|
this.localValue = localVal;
|
|
819
|
-
|
|
820
|
-
this.error = t('required', this.locale);
|
|
821
|
-
}
|
|
822
|
-
else {
|
|
823
|
-
this.error = '';
|
|
824
|
-
}
|
|
839
|
+
this.error = requiredError(localVal, this.required, this.locale);
|
|
825
840
|
this.mrdChange.emit({ name: this.name, value: this.localToUtc(localVal) });
|
|
826
841
|
};
|
|
827
842
|
this.handleBlur = (e) => {
|
|
@@ -855,8 +870,7 @@ const MrdDatetimeField = class {
|
|
|
855
870
|
return d.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
856
871
|
}
|
|
857
872
|
render() {
|
|
858
|
-
|
|
859
|
-
return (index.h(index.Host, { key: 'ea8b3b68100ffdb316bc5048f82d85d238bb2e4b' }, index.h("div", { key: 'c192c6998ee474aaf4df7b3b97ae0bd61f6d624d', class: "mrd-datetime-field" }, this.label && (index.h("label", { key: '1fbd66c17d76508f0d698a2c258be6779e98d85e', class: `mrd-datetime-field__label${this.required ? ' mrd-datetime-field__label--required' : ''}` }, this.label)), index.h("input", { key: 'fc9612c062a1cab5076a06598cabf227adce996c', class: `mrd-datetime-field__input${hasError ? ' mrd-datetime-field__input--error' : ''}`, type: "datetime-local", name: this.name, value: this.localValue, required: this.required, disabled: this.disabled, onChange: this.handleChange, onBlur: this.handleBlur }), hasError && index.h("span", { key: '8788ac01739302f6ad61010b238ff38d45e1b68a', class: "mrd-datetime-field__error" }, this.error))));
|
|
873
|
+
return (index.h(index.Host, { key: 'ac07ec2ba79cde998d1247e9d71de336c0e72a64' }, index.h("div", { key: '8144cf68c4b6b9cbc8396903b84bb355f380ceda', class: "mrd-datetime-field" }, index.h(FieldLabel, { key: '972686469f68c932e33b8d2c3806422553a3cce3', base: "mrd-datetime-field", label: this.label, required: this.required }), index.h("input", { key: '370b6032c38fbee22e662c1b2871f96b53b58956', class: controlClass('mrd-datetime-field', !!this.error), type: "datetime-local", name: this.name, value: this.localValue, required: this.required, disabled: this.disabled, onChange: this.handleChange, onBlur: this.handleBlur }), index.h(FieldError, { key: 'b7a812f82a6b0d2c938aa1f1c2494df685258555', base: "mrd-datetime-field", error: this.error }))));
|
|
860
874
|
}
|
|
861
875
|
static get watchers() { return {
|
|
862
876
|
"value": [{
|
|
@@ -864,9 +878,9 @@ const MrdDatetimeField = class {
|
|
|
864
878
|
}]
|
|
865
879
|
}; }
|
|
866
880
|
};
|
|
867
|
-
MrdDatetimeField.style =
|
|
881
|
+
MrdDatetimeField.style = mrdDatetimeFieldCss();
|
|
868
882
|
|
|
869
|
-
const
|
|
883
|
+
const mrdDocumentContainerCss = () => `.sc-mrd-document-container-h{display:block}.mrd-document-container__toolbar.sc-mrd-document-container{display:flex;align-items:center;justify-content:flex-end;gap:var(--mrd-space-2);padding:var(--mrd-space-2) var(--mrd-space-4);border-bottom:1px solid var(--mrd-color-neutral-100)}.mrd-document-container__action.sc-mrd-document-container{display:inline-flex;align-items:center;gap:var(--mrd-space-2);height:1.625rem;padding:0 var(--mrd-space-3);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-700);background:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-border-radius);cursor:pointer;transition:background var(--mrd-transition-fast), border-color var(--mrd-transition-fast)}.mrd-document-container__action.sc-mrd-document-container svg.sc-mrd-document-container{width:1rem;height:1rem;color:var(--mrd-color-folder)}.mrd-document-container__action.sc-mrd-document-container:hover:not(:disabled){background:var(--mrd-color-neutral-50);border-color:var(--mrd-color-neutral-300)}.mrd-document-container__action.sc-mrd-document-container:disabled{opacity:0.5;cursor:not-allowed}.mrd-document-container__seg.sc-mrd-document-container{display:inline-flex;gap:2px;padding:2px;background:var(--mrd-color-neutral-100);border-radius:var(--mrd-border-radius)}.mrd-document-container__seg-btn.sc-mrd-document-container{width:1.875rem;height:1.625rem;display:grid;place-items:center;border:none;background:none;border-radius:var(--mrd-border-radius-sm);color:var(--mrd-color-neutral-500);cursor:pointer;transition:color var(--mrd-transition-fast), background var(--mrd-transition-fast)}.mrd-document-container__seg-btn.sc-mrd-document-container:hover{color:var(--mrd-color-neutral-800)}.mrd-document-container__seg-btn[aria-pressed=true].sc-mrd-document-container{background:var(--mrd-color-white);color:var(--mrd-color-primary-dark);box-shadow:var(--mrd-shadow-sm)}.mrd-document-container__seg-btn.sc-mrd-document-container svg.sc-mrd-document-container{width:1rem;height:1rem}`;
|
|
870
884
|
|
|
871
885
|
const MrdDocumentContainer = class {
|
|
872
886
|
constructor(hostRef) {
|
|
@@ -898,8 +912,8 @@ const MrdDocumentContainer = class {
|
|
|
898
912
|
/** Whether the currently mounted table has been init()'d. Reset on every mode switch. */
|
|
899
913
|
this.tableInited = false;
|
|
900
914
|
this.createFolder = () => {
|
|
901
|
-
var _a
|
|
902
|
-
(
|
|
915
|
+
var _a;
|
|
916
|
+
(_a = this.listEl) === null || _a === void 0 ? void 0 : _a.createFolder();
|
|
903
917
|
};
|
|
904
918
|
}
|
|
905
919
|
/** The embedded table does not self-load: like every mrd-table it waits for the
|
|
@@ -911,7 +925,7 @@ const MrdDocumentContainer = class {
|
|
|
911
925
|
if (this.mode === 'list' && this.tableEl && !this.tableInited) {
|
|
912
926
|
this.tableInited = true;
|
|
913
927
|
const table = this.tableEl;
|
|
914
|
-
Promise.resolve((_a = table.componentOnReady) === null || _a === void 0 ? void 0 : _a.call(table)).then(() =>
|
|
928
|
+
Promise.resolve((_a = table.componentOnReady) === null || _a === void 0 ? void 0 : _a.call(table)).then(() => table.init());
|
|
915
929
|
}
|
|
916
930
|
}
|
|
917
931
|
setMode(mode) {
|
|
@@ -971,13 +985,240 @@ const MrdDocumentContainer = class {
|
|
|
971
985
|
}
|
|
972
986
|
render() {
|
|
973
987
|
const treeMode = this.mode === 'tree';
|
|
974
|
-
return (index.h(index.Host, { key: '
|
|
988
|
+
return (index.h(index.Host, { key: '018c9eacd169fdf7d352a51472651348af2b45df' }, this.renderToolbar(), index.h("div", { key: '5ff2ac77d4d12369905696ff075f99785dc1c809', class: "mrd-document-container__body", style: treeMode ? { height: `${this.height}px`, overflowY: 'auto' } : {} }, treeMode ? this.renderTree() : this.renderList())));
|
|
975
989
|
}
|
|
976
990
|
get el() { return index.getElement(this); }
|
|
977
991
|
};
|
|
978
|
-
MrdDocumentContainer.style =
|
|
992
|
+
MrdDocumentContainer.style = mrdDocumentContainerCss();
|
|
993
|
+
|
|
994
|
+
/**
|
|
995
|
+
* Shared path/query-param conventions for list requests,
|
|
996
|
+
* used by mrd-table and mrd-document-list.
|
|
997
|
+
*/
|
|
998
|
+
/** Applies the view-level static filters to `params` using the API operator conventions. */
|
|
999
|
+
function applyViewFilters(params, filters) {
|
|
1000
|
+
var _a, _b, _c;
|
|
1001
|
+
for (const f of filters !== null && filters !== void 0 ? filters : []) {
|
|
1002
|
+
if (!f.name)
|
|
1003
|
+
continue;
|
|
1004
|
+
if (f.operator === 'EMPTY') {
|
|
1005
|
+
params.set(f.name, '');
|
|
1006
|
+
continue;
|
|
1007
|
+
}
|
|
1008
|
+
if (f.operator === 'NOT_EMPTY') {
|
|
1009
|
+
params.set(f.name + '_notempty', 'true');
|
|
1010
|
+
continue;
|
|
1011
|
+
}
|
|
1012
|
+
if (f.operator === 'STARTS_WITH') {
|
|
1013
|
+
params.set(f.name + '_startswith', String((_a = f.value) !== null && _a !== void 0 ? _a : ''));
|
|
1014
|
+
continue;
|
|
1015
|
+
}
|
|
1016
|
+
if (f.operator === 'FROM') {
|
|
1017
|
+
params.set(f.name + '_from', String((_b = f.value) !== null && _b !== void 0 ? _b : ''));
|
|
1018
|
+
continue;
|
|
1019
|
+
}
|
|
1020
|
+
if (f.operator === 'TO') {
|
|
1021
|
+
params.set(f.name + '_to', String((_c = f.value) !== null && _c !== void 0 ? _c : ''));
|
|
1022
|
+
continue;
|
|
1023
|
+
}
|
|
1024
|
+
if (f.value != null) {
|
|
1025
|
+
params.set(f.name, String(f.value));
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
/** VIEW: `/{dataClass}`; RELATED_VIEW: `/{fromClass}/{parentId}/{dataClass}`. */
|
|
1030
|
+
function buildListPath(opts) {
|
|
1031
|
+
var _a, _b, _c;
|
|
1032
|
+
if (opts.isRelatedView) {
|
|
1033
|
+
return `/${(_a = opts.fromClass) !== null && _a !== void 0 ? _a : ''}/${opts.parentId}/${(_b = opts.dataClass) !== null && _b !== void 0 ? _b : ''}`;
|
|
1034
|
+
}
|
|
1035
|
+
return `/${(_c = opts.dataClass) !== null && _c !== void 0 ? _c : ''}`;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
/**
|
|
1039
|
+
* Tree model and pure tree logic for mrd-document-list.
|
|
1040
|
+
* Nodes are mutated in place; the component triggers re-renders via bump().
|
|
1041
|
+
*/
|
|
1042
|
+
/** Normalise a folder path: null/""/"/" → root ([]); else split on "/" dropping empties. */
|
|
1043
|
+
function splitFolder(path) {
|
|
1044
|
+
if (path == null)
|
|
1045
|
+
return [];
|
|
1046
|
+
const s = String(path).trim();
|
|
1047
|
+
if (s === '' || s === '/')
|
|
1048
|
+
return [];
|
|
1049
|
+
return s.split('/').map(x => x.trim()).filter(Boolean);
|
|
1050
|
+
}
|
|
1051
|
+
function makeContainerNode(href, label, count) {
|
|
1052
|
+
return {
|
|
1053
|
+
id: 'c:' + href, kind: 'container', label, href,
|
|
1054
|
+
hasDocs: false, docCount: 0, totalCount: count, children: [],
|
|
1055
|
+
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
function makeFolderNode(id, label, containerId) {
|
|
1059
|
+
return {
|
|
1060
|
+
id, kind: 'folder', label, containerId,
|
|
1061
|
+
hasDocs: false, docCount: 0, totalCount: 0, children: [],
|
|
1062
|
+
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
/** Recompute totalCount over the subtree; returns the node's aggregate. */
|
|
1066
|
+
function computeTotals(node) {
|
|
1067
|
+
let total = node.docCount;
|
|
1068
|
+
for (const c of node.children)
|
|
1069
|
+
total += computeTotals(c);
|
|
1070
|
+
node.totalCount = total;
|
|
1071
|
+
return total;
|
|
1072
|
+
}
|
|
1073
|
+
/** Folder path segments of a node relative to its container (derived from its id). */
|
|
1074
|
+
function segmentsOf(node, container) {
|
|
1075
|
+
if (node.kind === 'container')
|
|
1076
|
+
return [];
|
|
1077
|
+
const prefix = container.id + '/';
|
|
1078
|
+
const rest = node.id.startsWith(prefix) ? node.id.slice(prefix.length) : '';
|
|
1079
|
+
return rest ? rest.split('/') : [];
|
|
1080
|
+
}
|
|
1081
|
+
/** Folder string a node represents: the raw distinct value when it holds
|
|
1082
|
+
* documents, else derived from its path segments; null for a container root. */
|
|
1083
|
+
function folderStringOf(node, container) {
|
|
1084
|
+
if (node.kind === 'container')
|
|
1085
|
+
return null;
|
|
1086
|
+
if (node.fullPath != null && node.fullPath !== '')
|
|
1087
|
+
return node.fullPath;
|
|
1088
|
+
const segs = segmentsOf(node, container);
|
|
1089
|
+
return segs.length ? '/' + segs.join('/') : null;
|
|
1090
|
+
}
|
|
1091
|
+
/** Strip a single trailing extension for the document title. */
|
|
1092
|
+
function stripExtension(name) {
|
|
1093
|
+
return name.replace(/\.[^./\\]+$/, '');
|
|
1094
|
+
}
|
|
1095
|
+
/** Rebuild a container's folder subtree from the /distinct folder strings.
|
|
1096
|
+
* New nodes are registered in `nodeIndex`; the container is mutated in place. */
|
|
1097
|
+
function applyFolderDistinct(container, values, nodeIndex) {
|
|
1098
|
+
container.children = [];
|
|
1099
|
+
container.hasDocs = false;
|
|
1100
|
+
container.docCount = 0;
|
|
1101
|
+
for (const v of values) {
|
|
1102
|
+
const raw = typeof v.value === 'string' ? v.value : v.value == null ? '' : String(v.value);
|
|
1103
|
+
const segs = splitFolder(raw);
|
|
1104
|
+
if (segs.length === 0) {
|
|
1105
|
+
// Root documents — the container's own direct documents.
|
|
1106
|
+
container.hasDocs = true;
|
|
1107
|
+
container.docCount = v.count;
|
|
1108
|
+
container.fullPath = raw;
|
|
1109
|
+
continue;
|
|
1110
|
+
}
|
|
1111
|
+
let node = container;
|
|
1112
|
+
const acc = [];
|
|
1113
|
+
for (const seg of segs) {
|
|
1114
|
+
acc.push(seg);
|
|
1115
|
+
let child = node.children.find(c => c.label === seg);
|
|
1116
|
+
if (!child) {
|
|
1117
|
+
child = makeFolderNode(container.id + '/' + acc.join('/'), seg, container.id);
|
|
1118
|
+
node.children.push(child);
|
|
1119
|
+
nodeIndex.set(child.id, child);
|
|
1120
|
+
}
|
|
1121
|
+
node = child;
|
|
1122
|
+
}
|
|
1123
|
+
node.hasDocs = true;
|
|
1124
|
+
node.docCount = v.count;
|
|
1125
|
+
node.fullPath = raw;
|
|
1126
|
+
}
|
|
1127
|
+
computeTotals(container);
|
|
1128
|
+
container.foldersLoaded = true;
|
|
1129
|
+
container.loading = false;
|
|
1130
|
+
}
|
|
1131
|
+
/** Optimistic in-place tree update for a document moved between folders. */
|
|
1132
|
+
function applyDocMove(doc, fromNode, toNode, targetFolder) {
|
|
1133
|
+
fromNode.docs = fromNode.docs.filter(d => d !== doc);
|
|
1134
|
+
fromNode.docCount = Math.max(0, fromNode.docCount - 1);
|
|
1135
|
+
// A now-empty folder should stop showing an expand chevron (it disappears on
|
|
1136
|
+
// the next reload anyway, since it is derived from document folder strings).
|
|
1137
|
+
if (fromNode.docsLoaded)
|
|
1138
|
+
fromNode.hasDocs = fromNode.docs.length > 0;
|
|
1139
|
+
toNode.hasDocs = true;
|
|
1140
|
+
toNode.pending = false; // a pending folder is now materialised
|
|
1141
|
+
toNode.docCount += 1;
|
|
1142
|
+
if (toNode.kind === 'folder')
|
|
1143
|
+
toNode.fullPath = targetFolder !== null && targetFolder !== void 0 ? targetFolder : '';
|
|
1144
|
+
if (toNode.docsLoaded)
|
|
1145
|
+
toNode.docs = [...toNode.docs, doc];
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
function chevron(open, leaf) {
|
|
1149
|
+
return (index.h("span", { class: `mrd-document-list__chev${leaf ? ' mrd-document-list__chev--leaf' : ''}${open ? ' mrd-document-list__chev--open' : ''}` }, index.h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.h("path", { d: "M9 6l6 6-6 6" }))));
|
|
1150
|
+
}
|
|
1151
|
+
function dossierIcon() {
|
|
1152
|
+
return (index.h("svg", { class: "mrd-document-list__icon mrd-document-list__icon--dossier", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.h("path", { d: "M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" })));
|
|
1153
|
+
}
|
|
1154
|
+
function folderIcon() {
|
|
1155
|
+
return (index.h("svg", { class: "mrd-document-list__icon mrd-document-list__icon--folder", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.h("path", { d: "M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" })));
|
|
1156
|
+
}
|
|
1157
|
+
function docIcon() {
|
|
1158
|
+
return (index.h("svg", { class: "mrd-document-list__icon mrd-document-list__icon--doc", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.h("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }), index.h("path", { d: "M14 2v6h6" })));
|
|
1159
|
+
}
|
|
1160
|
+
function indent(depth) {
|
|
1161
|
+
return index.h("span", { class: "mrd-document-list__indent", style: { width: `${depth * 18}px` } });
|
|
1162
|
+
}
|
|
1163
|
+
function renderLoadingRow(ctx, depth) {
|
|
1164
|
+
return (index.h("div", { class: "mrd-document-list__loading", key: "loading" }, indent(depth), index.h("span", { class: "mrd-document-list__spinner" }), t('loading', ctx.locale)));
|
|
1165
|
+
}
|
|
1166
|
+
function renderUploadingRow(ctx, depth) {
|
|
1167
|
+
return (index.h("div", { class: "mrd-document-list__loading", key: "uploading" }, indent(depth), index.h("span", { class: "mrd-document-list__spinner" }), t('upload_file', ctx.locale)));
|
|
1168
|
+
}
|
|
1169
|
+
function renderDocRow(ctx, doc, node, container, depth) {
|
|
1170
|
+
var _a, _b, _c, _d, _e;
|
|
1171
|
+
const label = (_b = (_a = doc === null || doc === void 0 ? void 0 : doc[ctx.titleField]) !== null && _a !== void 0 ? _a : doc === null || doc === void 0 ? void 0 : doc.name) !== null && _b !== void 0 ? _b : '';
|
|
1172
|
+
const dateRaw = ctx.dateField ? doc === null || doc === void 0 ? void 0 : doc[ctx.dateField] : undefined;
|
|
1173
|
+
const date = dateRaw ? formatDate(dateRaw, ctx.locale) : '';
|
|
1174
|
+
return (index.h("div", { class: "mrd-document-list__row mrd-document-list__row--doc", key: (_e = (_d = (_c = doc === null || doc === void 0 ? void 0 : doc._links) === null || _c === void 0 ? void 0 : _c.self) === null || _d === void 0 ? void 0 : _d.href) !== null && _e !== void 0 ? _e : label, draggable: true, onClick: () => ctx.on.openDoc(doc), onDragStart: (e) => ctx.on.docDragStart(e, doc, node), onDragEnd: ctx.on.docDragEnd, onDragOver: (e) => ctx.on.nodeDragOver(e, node), onDragLeave: () => ctx.on.nodeDragLeave(node), onDrop: (e) => ctx.on.nodeDrop(e, node, container) }, indent(depth), chevron(false, true), docIcon(), index.h("span", { class: "mrd-document-list__label" }, label), date && index.h("span", { class: "mrd-document-list__date" }, date)));
|
|
1175
|
+
}
|
|
1176
|
+
function renderFolderEditRow(ctx, node, depth) {
|
|
1177
|
+
return (index.h("div", { class: "mrd-document-list__node", key: node.id }, index.h("div", { class: "mrd-document-list__row mrd-document-list__row--edit" }, indent(depth), chevron(false, true), folderIcon(), index.h("input", { class: "mrd-document-list__name-input", type: "text", placeholder: t('folder_name_placeholder', ctx.locale), ref: el => ctx.on.setPendingInputEl(el), onInput: ctx.on.pendingInput, onKeyDown: ctx.on.pendingKeyDown, onBlur: () => ctx.on.cancelFolder() })), node.error && (index.h("div", { class: "mrd-document-list__error", style: { paddingLeft: `${depth * 18 + 52}px` } }, node.error))));
|
|
1178
|
+
}
|
|
1179
|
+
function renderNodeChildren(ctx, container, node, depth) {
|
|
1180
|
+
const out = [];
|
|
1181
|
+
// Direct documents of this node (root docs live on the container node).
|
|
1182
|
+
if (node.hasDocs) {
|
|
1183
|
+
if (node.docsLoaded) {
|
|
1184
|
+
for (const doc of node.docs)
|
|
1185
|
+
out.push(renderDocRow(ctx, doc, node, container, depth));
|
|
1186
|
+
}
|
|
1187
|
+
else if (node.loading) {
|
|
1188
|
+
out.push(renderLoadingRow(ctx, depth));
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
// Child folders.
|
|
1192
|
+
for (const child of node.children) {
|
|
1193
|
+
out.push(renderFolderNode(ctx, container, child, depth));
|
|
1194
|
+
}
|
|
1195
|
+
// An uploading file dropped onto this node.
|
|
1196
|
+
if (node.id === ctx.uploadingNodeId)
|
|
1197
|
+
out.push(renderUploadingRow(ctx, depth));
|
|
1198
|
+
return out;
|
|
1199
|
+
}
|
|
1200
|
+
function renderFolderNode(ctx, container, node, depth) {
|
|
1201
|
+
if (node.editing)
|
|
1202
|
+
return renderFolderEditRow(ctx, node, depth);
|
|
1203
|
+
const leaf = node.children.length === 0 && !node.hasDocs;
|
|
1204
|
+
const selected = node.id === ctx.selectedId;
|
|
1205
|
+
const cls = 'mrd-document-list__row'
|
|
1206
|
+
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1207
|
+
+ (node.pending ? ' mrd-document-list__row--pending' : '')
|
|
1208
|
+
+ (node.id === ctx.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1209
|
+
return (index.h("div", { class: "mrd-document-list__node", key: node.id }, index.h("div", { class: cls, onClick: () => ctx.on.toggleFolder(container, node), onDragOver: (e) => ctx.on.nodeDragOver(e, node), onDragLeave: () => ctx.on.nodeDragLeave(node), onDrop: (e) => ctx.on.nodeDrop(e, node, container) }, indent(depth), chevron(node.open, leaf), folderIcon(), index.h("span", { class: "mrd-document-list__label" }, node.label), index.h("span", { class: "mrd-document-list__count" }, node.totalCount)), node.open && index.h("div", { class: "mrd-document-list__kids" }, renderNodeChildren(ctx, container, node, depth + 1))));
|
|
1210
|
+
}
|
|
1211
|
+
function renderContainerNode(ctx, node, depth) {
|
|
1212
|
+
const selected = node.id === ctx.selectedId;
|
|
1213
|
+
const cls = 'mrd-document-list__row mrd-document-list__row--dossier'
|
|
1214
|
+
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1215
|
+
+ (node.id === ctx.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1216
|
+
return (index.h("div", { class: "mrd-document-list__node", key: node.id }, index.h("div", { class: cls, onClick: () => ctx.on.toggleContainer(node), onDragOver: (e) => ctx.on.nodeDragOver(e, node), onDragLeave: () => ctx.on.nodeDragLeave(node), onDrop: (e) => ctx.on.nodeDrop(e, node, node) }, indent(depth), chevron(node.open, false), dossierIcon(), index.h("span", { class: "mrd-document-list__label" }, node.label), index.h("span", { class: "mrd-document-list__count" }, node.totalCount)), node.open && (index.h("div", { class: "mrd-document-list__kids" }, node.loading && !node.foldersLoaded
|
|
1217
|
+
? renderLoadingRow(ctx, depth + 1)
|
|
1218
|
+
: renderNodeChildren(ctx, node, node, depth + 1)))));
|
|
1219
|
+
}
|
|
979
1220
|
|
|
980
|
-
const
|
|
1221
|
+
const mrdDocumentListCss = () => `@charset "UTF-8";.sc-mrd-document-list-h{display:block;height:100%}.mrd-document-list.sc-mrd-document-list{padding:var(--mrd-space-2) 0;min-height:100%;box-sizing:border-box}.mrd-document-list--drop-active.sc-mrd-document-list{outline:2px dashed var(--mrd-color-primary);outline-offset:-4px;background:var(--mrd-color-primary-50, rgba(22, 163, 74, 0.06))}.mrd-document-list__row.sc-mrd-document-list{display:flex;align-items:center;gap:var(--mrd-space-2);height:2.125rem;padding:0 var(--mrd-space-4);cursor:pointer;user-select:none;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-800)}.mrd-document-list__row.sc-mrd-document-list:hover{background:var(--mrd-color-neutral-50)}.mrd-document-list__row--selected.sc-mrd-document-list{background:var(--mrd-color-primary-50, rgba(22, 163, 74, 0.1))}.mrd-document-list__row--selected.sc-mrd-document-list:hover{background:var(--mrd-color-primary-50, rgba(22, 163, 74, 0.1))}.mrd-document-list__row--pending.sc-mrd-document-list .mrd-document-list__label.sc-mrd-document-list{font-style:italic;color:var(--mrd-color-neutral-500)}.mrd-document-list__row--doc.sc-mrd-document-list{cursor:grab}.mrd-document-list__row--doc.sc-mrd-document-list:active{cursor:grabbing}.mrd-document-list__row--drop.sc-mrd-document-list{background:var(--mrd-color-primary-50, rgba(22, 163, 74, 0.1));box-shadow:inset 0 0 0 1px var(--mrd-color-primary)}.mrd-document-list__row--drop.sc-mrd-document-list:hover{background:var(--mrd-color-primary-50, rgba(22, 163, 74, 0.1))}.mrd-document-list__row--edit.sc-mrd-document-list{cursor:default}.mrd-document-list__name-input.sc-mrd-document-list{flex:1;min-width:0;height:1.625rem;padding:0 var(--mrd-space-2);font-size:var(--mrd-font-size-sm);font-family:inherit;color:var(--mrd-color-neutral-800);border:1px solid var(--mrd-color-primary);border-radius:var(--mrd-border-radius);outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-document-list__error.sc-mrd-document-list{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-danger, #dc2626);padding-top:0.125rem;padding-bottom:0.25rem}.mrd-document-list__row--dossier.sc-mrd-document-list .mrd-document-list__label.sc-mrd-document-list{font-weight:var(--mrd-font-weight-semibold)}.mrd-document-list__indent.sc-mrd-document-list{flex:none}.mrd-document-list__chev.sc-mrd-document-list{width:1rem;height:1rem;flex:none;display:grid;place-items:center;color:var(--mrd-color-neutral-400);transition:transform var(--mrd-transition-fast)}.mrd-document-list__chev.sc-mrd-document-list svg.sc-mrd-document-list{width:0.6875rem;height:0.6875rem}.mrd-document-list__chev--open.sc-mrd-document-list{transform:rotate(90deg)}.mrd-document-list__chev--leaf.sc-mrd-document-list{visibility:hidden}.mrd-document-list__icon.sc-mrd-document-list{width:1.0625rem;height:1.0625rem;flex:none}.mrd-document-list__icon--dossier.sc-mrd-document-list{color:var(--mrd-color-primary)}.mrd-document-list__icon--folder.sc-mrd-document-list{color:var(--mrd-color-folder)}.mrd-document-list__icon--doc.sc-mrd-document-list{color:var(--mrd-color-neutral-400)}.mrd-document-list__label.sc-mrd-document-list{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mrd-document-list__count.sc-mrd-document-list{flex:none;font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);background:var(--mrd-color-neutral-100);border-radius:var(--mrd-border-radius-full);padding:0.0625rem 0.5rem}.mrd-document-list__date.sc-mrd-document-list{flex:none;font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-400);font-variant-numeric:tabular-nums}.mrd-document-list__loading.sc-mrd-document-list{display:flex;align-items:center;gap:var(--mrd-space-2);height:1.875rem;padding:0 var(--mrd-space-4);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-400)}.mrd-document-list__spinner.sc-mrd-document-list{width:0.75rem;height:0.75rem;border:2px solid var(--mrd-color-neutral-300);border-top-color:var(--mrd-color-primary);border-radius:50%;animation:mrd-document-list-spin 0.7s linear infinite}@keyframes mrd-document-list-spin{to{transform:rotate(360deg)}}.mrd-document-list__empty.sc-mrd-document-list{padding:var(--mrd-space-8) var(--mrd-space-4);text-align:center;color:var(--mrd-color-neutral-400);font-size:var(--mrd-font-size-sm)}`;
|
|
981
1222
|
|
|
982
1223
|
const MrdDocumentList = class {
|
|
983
1224
|
constructor(hostRef) {
|
|
@@ -1044,7 +1285,7 @@ const MrdDocumentList = class {
|
|
|
1044
1285
|
return;
|
|
1045
1286
|
const { target, container } = resolved;
|
|
1046
1287
|
const tempId = `${container.id}/__new__${this.newFolderSeq++}`;
|
|
1047
|
-
const node =
|
|
1288
|
+
const node = makeFolderNode(tempId, '', container.id);
|
|
1048
1289
|
node.pending = true;
|
|
1049
1290
|
node.editing = true;
|
|
1050
1291
|
target.children = [...target.children, node];
|
|
@@ -1183,7 +1424,7 @@ const MrdDocumentList = class {
|
|
|
1183
1424
|
}
|
|
1184
1425
|
/** Seed the single implied container from context and load its folders. */
|
|
1185
1426
|
seedSingleContainer() {
|
|
1186
|
-
const node =
|
|
1427
|
+
const node = makeContainerNode(this.containerHref, this.containerField, 0);
|
|
1187
1428
|
this.nodeIndex.set(node.id, node);
|
|
1188
1429
|
this.containers = [node];
|
|
1189
1430
|
this.rootLoading = false;
|
|
@@ -1230,61 +1471,37 @@ const MrdDocumentList = class {
|
|
|
1230
1471
|
* type (e.g. "contents"), filtered down to the concrete `filterClass` via the
|
|
1231
1472
|
* `type` query param — see baseParams(). */
|
|
1232
1473
|
buildDataPath() {
|
|
1233
|
-
var _a, _b
|
|
1474
|
+
var _a, _b;
|
|
1234
1475
|
const it = this.item;
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1476
|
+
return buildListPath({
|
|
1477
|
+
isRelatedView: (it === null || it === void 0 ? void 0 : it.type) === index$1.ClientLayoutItemType.RELATED_VIEW,
|
|
1478
|
+
fromClass: it === null || it === void 0 ? void 0 : it.fromClass,
|
|
1479
|
+
parentId: this.parentId,
|
|
1480
|
+
dataClass: (_b = (_a = it === null || it === void 0 ? void 0 : it.dataClass) !== null && _a !== void 0 ? _a : it === null || it === void 0 ? void 0 : it.relatedClass) !== null && _b !== void 0 ? _b : '',
|
|
1481
|
+
});
|
|
1240
1482
|
}
|
|
1241
1483
|
/** Path for creating a new document (file-drop). Unlike buildDataPath(), this
|
|
1242
1484
|
* must target the concrete type: `dataClass`/`relatedClass` can be an abstract
|
|
1243
1485
|
* base type (e.g. "contents") that cannot be POSTed to directly, so prefer
|
|
1244
1486
|
* `filterClass` (e.g. "documents") when present. */
|
|
1245
1487
|
buildCreatePath() {
|
|
1246
|
-
var _a, _b, _c
|
|
1488
|
+
var _a, _b, _c;
|
|
1247
1489
|
const it = this.item;
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1490
|
+
return buildListPath({
|
|
1491
|
+
isRelatedView: (it === null || it === void 0 ? void 0 : it.type) === index$1.ClientLayoutItemType.RELATED_VIEW,
|
|
1492
|
+
fromClass: it === null || it === void 0 ? void 0 : it.fromClass,
|
|
1493
|
+
parentId: this.parentId,
|
|
1494
|
+
dataClass: (_c = (_b = (_a = it === null || it === void 0 ? void 0 : it.filterClass) !== null && _a !== void 0 ? _a : it === null || it === void 0 ? void 0 : it.dataClass) !== null && _b !== void 0 ? _b : it === null || it === void 0 ? void 0 : it.relatedClass) !== null && _c !== void 0 ? _c : '',
|
|
1495
|
+
});
|
|
1253
1496
|
}
|
|
1254
1497
|
/** View-level static filters + filterClass, shared by every request. */
|
|
1255
1498
|
baseParams() {
|
|
1256
|
-
var _a, _b, _c
|
|
1499
|
+
var _a, _b, _c;
|
|
1257
1500
|
const p = new URLSearchParams();
|
|
1258
1501
|
const filterClass = (_a = this.item) === null || _a === void 0 ? void 0 : _a.filterClass;
|
|
1259
1502
|
if (filterClass)
|
|
1260
1503
|
p.set('type', filterClass);
|
|
1261
|
-
|
|
1262
|
-
if (!f.name)
|
|
1263
|
-
continue;
|
|
1264
|
-
if (f.operator === 'EMPTY') {
|
|
1265
|
-
p.set(f.name, '');
|
|
1266
|
-
continue;
|
|
1267
|
-
}
|
|
1268
|
-
if (f.operator === 'NOT_EMPTY') {
|
|
1269
|
-
p.set(f.name + '_notempty', 'true');
|
|
1270
|
-
continue;
|
|
1271
|
-
}
|
|
1272
|
-
if (f.operator === 'STARTS_WITH') {
|
|
1273
|
-
p.set(f.name + '_startswith', String((_e = f.value) !== null && _e !== void 0 ? _e : ''));
|
|
1274
|
-
continue;
|
|
1275
|
-
}
|
|
1276
|
-
if (f.operator === 'FROM') {
|
|
1277
|
-
p.set(f.name + '_from', String((_f = f.value) !== null && _f !== void 0 ? _f : ''));
|
|
1278
|
-
continue;
|
|
1279
|
-
}
|
|
1280
|
-
if (f.operator === 'TO') {
|
|
1281
|
-
p.set(f.name + '_to', String((_g = f.value) !== null && _g !== void 0 ? _g : ''));
|
|
1282
|
-
continue;
|
|
1283
|
-
}
|
|
1284
|
-
if (f.value != null) {
|
|
1285
|
-
p.set(f.name, String(f.value));
|
|
1286
|
-
}
|
|
1287
|
-
}
|
|
1504
|
+
applyViewFilters(p, (_c = (_b = this.item) === null || _b === void 0 ? void 0 : _b.view) === null || _c === void 0 ? void 0 : _c.filter);
|
|
1288
1505
|
return p;
|
|
1289
1506
|
}
|
|
1290
1507
|
emitContainerDistinct() {
|
|
@@ -1351,7 +1568,7 @@ const MrdDocumentList = class {
|
|
|
1351
1568
|
if (!v.value || typeof v.value !== 'object')
|
|
1352
1569
|
continue;
|
|
1353
1570
|
const href = v.value.href;
|
|
1354
|
-
const node =
|
|
1571
|
+
const node = makeContainerNode(href, v.value.name, v.count);
|
|
1355
1572
|
nodes.push(node);
|
|
1356
1573
|
this.nodeIndex.set(node.id, node);
|
|
1357
1574
|
}
|
|
@@ -1369,38 +1586,7 @@ const MrdDocumentList = class {
|
|
|
1369
1586
|
const container = this.nodeIndex.get(containerId);
|
|
1370
1587
|
if (!container)
|
|
1371
1588
|
return;
|
|
1372
|
-
container
|
|
1373
|
-
container.hasDocs = false;
|
|
1374
|
-
container.docCount = 0;
|
|
1375
|
-
for (const v of values) {
|
|
1376
|
-
const raw = typeof v.value === 'string' ? v.value : v.value == null ? '' : String(v.value);
|
|
1377
|
-
const segs = this.splitFolder(raw);
|
|
1378
|
-
if (segs.length === 0) {
|
|
1379
|
-
// Root documents — the container's own direct documents.
|
|
1380
|
-
container.hasDocs = true;
|
|
1381
|
-
container.docCount = v.count;
|
|
1382
|
-
container.fullPath = raw;
|
|
1383
|
-
continue;
|
|
1384
|
-
}
|
|
1385
|
-
let node = container;
|
|
1386
|
-
const acc = [];
|
|
1387
|
-
for (const seg of segs) {
|
|
1388
|
-
acc.push(seg);
|
|
1389
|
-
let child = node.children.find(c => c.label === seg);
|
|
1390
|
-
if (!child) {
|
|
1391
|
-
child = this.makeFolderNode(container.id + '/' + acc.join('/'), seg, container.id);
|
|
1392
|
-
node.children.push(child);
|
|
1393
|
-
this.nodeIndex.set(child.id, child);
|
|
1394
|
-
}
|
|
1395
|
-
node = child;
|
|
1396
|
-
}
|
|
1397
|
-
node.hasDocs = true;
|
|
1398
|
-
node.docCount = v.count;
|
|
1399
|
-
node.fullPath = raw;
|
|
1400
|
-
}
|
|
1401
|
-
this.computeTotals(container);
|
|
1402
|
-
container.foldersLoaded = true;
|
|
1403
|
-
container.loading = false;
|
|
1589
|
+
applyFolderDistinct(container, values, this.nodeIndex);
|
|
1404
1590
|
// If the container has root documents, load them now (they show inline on expand).
|
|
1405
1591
|
if (container.hasDocs && !container.docsLoaded) {
|
|
1406
1592
|
this.emitDocuments(container, container);
|
|
@@ -1408,36 +1594,6 @@ const MrdDocumentList = class {
|
|
|
1408
1594
|
this.bump();
|
|
1409
1595
|
}
|
|
1410
1596
|
// ── Tree helpers ─────────────────────────────────────────────────────────
|
|
1411
|
-
/** Normalise a folder path: null/""/"/" → root ([]); else split on "/" dropping empties. */
|
|
1412
|
-
splitFolder(path) {
|
|
1413
|
-
if (path == null)
|
|
1414
|
-
return [];
|
|
1415
|
-
const s = String(path).trim();
|
|
1416
|
-
if (s === '' || s === '/')
|
|
1417
|
-
return [];
|
|
1418
|
-
return s.split('/').map(x => x.trim()).filter(Boolean);
|
|
1419
|
-
}
|
|
1420
|
-
makeContainerNode(href, label, count) {
|
|
1421
|
-
return {
|
|
1422
|
-
id: 'c:' + href, kind: 'container', label, href,
|
|
1423
|
-
hasDocs: false, docCount: 0, totalCount: count, children: [],
|
|
1424
|
-
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1425
|
-
};
|
|
1426
|
-
}
|
|
1427
|
-
makeFolderNode(id, label, containerId) {
|
|
1428
|
-
return {
|
|
1429
|
-
id, kind: 'folder', label, containerId,
|
|
1430
|
-
hasDocs: false, docCount: 0, totalCount: 0, children: [],
|
|
1431
|
-
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1432
|
-
};
|
|
1433
|
-
}
|
|
1434
|
-
computeTotals(node) {
|
|
1435
|
-
let total = node.docCount;
|
|
1436
|
-
for (const c of node.children)
|
|
1437
|
-
total += this.computeTotals(c);
|
|
1438
|
-
node.totalCount = total;
|
|
1439
|
-
return total;
|
|
1440
|
-
}
|
|
1441
1597
|
/** Force a re-render after mutating nodes in place. */
|
|
1442
1598
|
bump() {
|
|
1443
1599
|
this.containers = [...this.containers];
|
|
@@ -1487,14 +1643,6 @@ const MrdDocumentList = class {
|
|
|
1487
1643
|
async createFolder() {
|
|
1488
1644
|
this.startCreateFolder();
|
|
1489
1645
|
}
|
|
1490
|
-
/** Folder path segments of a node relative to its container (derived from its id). */
|
|
1491
|
-
segmentsOf(node, container) {
|
|
1492
|
-
if (node.kind === 'container')
|
|
1493
|
-
return [];
|
|
1494
|
-
const prefix = container.id + '/';
|
|
1495
|
-
const rest = node.id.startsWith(prefix) ? node.id.slice(prefix.length) : '';
|
|
1496
|
-
return rest ? rest.split('/') : [];
|
|
1497
|
-
}
|
|
1498
1646
|
commitFolder() {
|
|
1499
1647
|
const node = this.pendingNode;
|
|
1500
1648
|
const parent = this.pendingParent;
|
|
@@ -1519,7 +1667,7 @@ const MrdDocumentList = class {
|
|
|
1519
1667
|
}
|
|
1520
1668
|
// Finalise: swap the temp id for the real path-derived id so a later distinct
|
|
1521
1669
|
// value with the same folder string merges onto this node.
|
|
1522
|
-
const segs = [...
|
|
1670
|
+
const segs = [...segmentsOf(parent, container), name];
|
|
1523
1671
|
this.nodeIndex.delete(node.id);
|
|
1524
1672
|
node.id = container.id + '/' + segs.join('/');
|
|
1525
1673
|
node.fullPath = '/' + segs.join('/');
|
|
@@ -1568,10 +1716,6 @@ const MrdDocumentList = class {
|
|
|
1568
1716
|
this.bump();
|
|
1569
1717
|
this.mrdUpload.emit({ file });
|
|
1570
1718
|
}
|
|
1571
|
-
/** Strip a single trailing extension for the document title. */
|
|
1572
|
-
stripExtension(name) {
|
|
1573
|
-
return name.replace(/\.[^./\\]+$/, '');
|
|
1574
|
-
}
|
|
1575
1719
|
/** Host callback with the uploaded file reference. Builds the create payload
|
|
1576
1720
|
* from the archetype slots and requests the new document. */
|
|
1577
1721
|
async setFileReference(uri) {
|
|
@@ -1579,16 +1723,20 @@ const MrdDocumentList = class {
|
|
|
1579
1723
|
if (!up)
|
|
1580
1724
|
return;
|
|
1581
1725
|
const { file, node, container } = up;
|
|
1582
|
-
const folder =
|
|
1726
|
+
const folder = folderStringOf(node, container);
|
|
1583
1727
|
const values = {
|
|
1584
1728
|
[this.fileField]: uri,
|
|
1585
|
-
[this.titleField]:
|
|
1729
|
+
[this.titleField]: stripExtension(file.name),
|
|
1586
1730
|
[this.folderField]: folder,
|
|
1587
|
-
[this.containerField]: container.href,
|
|
1588
1731
|
};
|
|
1732
|
+
// The create path already embeds the container (/{fromClass}/{parentId}/...)
|
|
1733
|
+
// when this is the seeded single-container context; omit the redundant field.
|
|
1734
|
+
if (!this.isSeededSingleContainer()) {
|
|
1735
|
+
values[this.containerField] = container.href;
|
|
1736
|
+
}
|
|
1589
1737
|
this.mrdCreateObject.emit({ path: this.buildCreatePath(), values });
|
|
1590
1738
|
// Optimistically show the new document (no href until a reload).
|
|
1591
|
-
const optimistic = { [this.titleField]:
|
|
1739
|
+
const optimistic = { [this.titleField]: stripExtension(file.name), _optimistic: true };
|
|
1592
1740
|
const wasUnloadedEmpty = !node.docsLoaded && node.docCount === 0;
|
|
1593
1741
|
node.hasDocs = true;
|
|
1594
1742
|
node.pending = false;
|
|
@@ -1617,16 +1765,6 @@ const MrdDocumentList = class {
|
|
|
1617
1765
|
this.lastOptimisticDoc = null;
|
|
1618
1766
|
this.bump();
|
|
1619
1767
|
}
|
|
1620
|
-
/** Folder string a node represents: the raw distinct value when it holds
|
|
1621
|
-
* documents, else derived from its path segments; null for a container root. */
|
|
1622
|
-
folderStringOf(node, container) {
|
|
1623
|
-
if (node.kind === 'container')
|
|
1624
|
-
return null;
|
|
1625
|
-
if (node.fullPath != null && node.fullPath !== '')
|
|
1626
|
-
return node.fullPath;
|
|
1627
|
-
const segs = this.segmentsOf(node, container);
|
|
1628
|
-
return segs.length ? '/' + segs.join('/') : null;
|
|
1629
|
-
}
|
|
1630
1768
|
moveDocument(toNode, toContainer) {
|
|
1631
1769
|
var _a, _b;
|
|
1632
1770
|
const doc = this.dragDoc;
|
|
@@ -1638,26 +1776,14 @@ const MrdDocumentList = class {
|
|
|
1638
1776
|
: (fromNode.containerId ? this.nodeIndex.get(fromNode.containerId) : undefined);
|
|
1639
1777
|
if (!fromContainer)
|
|
1640
1778
|
return;
|
|
1641
|
-
const targetFolder =
|
|
1642
|
-
const sourceFolder =
|
|
1779
|
+
const targetFolder = folderStringOf(toNode, toContainer);
|
|
1780
|
+
const sourceFolder = folderStringOf(fromNode, fromContainer);
|
|
1643
1781
|
const sameContainer = toContainer === fromContainer;
|
|
1644
1782
|
// No-op: dropped back onto its own folder.
|
|
1645
1783
|
if (toNode === fromNode || (sameContainer && targetFolder === sourceFolder))
|
|
1646
1784
|
return;
|
|
1647
|
-
//
|
|
1648
|
-
|
|
1649
|
-
fromNode.docCount = Math.max(0, fromNode.docCount - 1);
|
|
1650
|
-
// A now-empty folder should stop showing an expand chevron (it disappears on
|
|
1651
|
-
// the next reload anyway, since it is derived from document folder strings).
|
|
1652
|
-
if (fromNode.docsLoaded)
|
|
1653
|
-
fromNode.hasDocs = fromNode.docs.length > 0;
|
|
1654
|
-
toNode.hasDocs = true;
|
|
1655
|
-
toNode.pending = false; // a pending folder is now materialised
|
|
1656
|
-
toNode.docCount += 1;
|
|
1657
|
-
if (toNode.kind === 'folder')
|
|
1658
|
-
toNode.fullPath = targetFolder !== null && targetFolder !== void 0 ? targetFolder : '';
|
|
1659
|
-
if (toNode.docsLoaded)
|
|
1660
|
-
toNode.docs = [...toNode.docs, doc];
|
|
1785
|
+
// Optimistic tree update (fire-and-forget; no refetch).
|
|
1786
|
+
applyDocMove(doc, fromNode, toNode, targetFolder);
|
|
1661
1787
|
this.recomputeContainerTotals(fromContainer, -1);
|
|
1662
1788
|
if (!sameContainer)
|
|
1663
1789
|
this.recomputeContainerTotals(toContainer, 1);
|
|
@@ -1675,7 +1801,7 @@ const MrdDocumentList = class {
|
|
|
1675
1801
|
* loaded; otherwise just nudge the aggregate badge by the delta. */
|
|
1676
1802
|
recomputeContainerTotals(container, delta) {
|
|
1677
1803
|
if (container.foldersLoaded) {
|
|
1678
|
-
|
|
1804
|
+
computeTotals(container);
|
|
1679
1805
|
}
|
|
1680
1806
|
else {
|
|
1681
1807
|
container.totalCount = Math.max(0, container.totalCount + delta);
|
|
@@ -1688,111 +1814,64 @@ const MrdDocumentList = class {
|
|
|
1688
1814
|
this.mrdNavigate.emit({ href, label });
|
|
1689
1815
|
}
|
|
1690
1816
|
// ── Render ───────────────────────────────────────────────────────────────
|
|
1691
|
-
|
|
1692
|
-
return
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
return (index.h("div", { class: "mrd-document-list__loading", key: "loading" }, this.indent(depth), index.h("span", { class: "mrd-document-list__spinner" }), t('loading', this.locale)));
|
|
1715
|
-
}
|
|
1716
|
-
renderChildren(container, node, depth) {
|
|
1717
|
-
const out = [];
|
|
1718
|
-
// Direct documents of this node (root docs live on the container node).
|
|
1719
|
-
if (node.hasDocs) {
|
|
1720
|
-
if (node.docsLoaded) {
|
|
1721
|
-
for (const doc of node.docs)
|
|
1722
|
-
out.push(this.renderDocRow(doc, node, container, depth));
|
|
1723
|
-
}
|
|
1724
|
-
else if (node.loading) {
|
|
1725
|
-
out.push(this.renderLoadingRow(depth));
|
|
1726
|
-
}
|
|
1727
|
-
}
|
|
1728
|
-
// Child folders.
|
|
1729
|
-
for (const child of node.children) {
|
|
1730
|
-
out.push(this.renderFolderNode(container, child, depth));
|
|
1731
|
-
}
|
|
1732
|
-
// An uploading file dropped onto this node.
|
|
1733
|
-
if (node.id === this.uploadingNodeId)
|
|
1734
|
-
out.push(this.renderUploadingRow(depth));
|
|
1735
|
-
return out;
|
|
1736
|
-
}
|
|
1737
|
-
renderUploadingRow(depth) {
|
|
1738
|
-
return (index.h("div", { class: "mrd-document-list__loading", key: "uploading" }, this.indent(depth), index.h("span", { class: "mrd-document-list__spinner" }), t('upload_file', this.locale)));
|
|
1739
|
-
}
|
|
1740
|
-
renderFolderEditRow(node, depth) {
|
|
1741
|
-
return (index.h("div", { class: "mrd-document-list__node", key: node.id }, index.h("div", { class: "mrd-document-list__row mrd-document-list__row--edit" }, this.indent(depth), this.renderChevron(false, true), this.renderFolderIcon(), index.h("input", { class: "mrd-document-list__name-input", type: "text", placeholder: t('folder_name_placeholder', this.locale), ref: el => (this.pendingInputEl = el), onInput: this.onPendingInput, onKeyDown: this.onPendingKeyDown, onBlur: () => this.cancelFolder() })), node.error && (index.h("div", { class: "mrd-document-list__error", style: { paddingLeft: `${depth * 18 + 52}px` } }, node.error))));
|
|
1742
|
-
}
|
|
1743
|
-
renderFolderNode(container, node, depth) {
|
|
1744
|
-
if (node.editing)
|
|
1745
|
-
return this.renderFolderEditRow(node, depth);
|
|
1746
|
-
const leaf = node.children.length === 0 && !node.hasDocs;
|
|
1747
|
-
const selected = node.id === this.selectedId;
|
|
1748
|
-
const cls = 'mrd-document-list__row'
|
|
1749
|
-
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1750
|
-
+ (node.pending ? ' mrd-document-list__row--pending' : '')
|
|
1751
|
-
+ (node.id === this.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1752
|
-
return (index.h("div", { class: "mrd-document-list__node", key: node.id }, index.h("div", { class: cls, onClick: () => this.toggleFolder(container, node), onDragOver: (e) => this.onNodeDragOver(e, node), onDragLeave: () => this.onNodeDragLeave(node), onDrop: (e) => this.onNodeDrop(e, node, container) }, this.indent(depth), this.renderChevron(node.open, leaf), this.renderFolderIcon(), index.h("span", { class: "mrd-document-list__label" }, node.label), index.h("span", { class: "mrd-document-list__count" }, node.totalCount)), node.open && index.h("div", { class: "mrd-document-list__kids" }, this.renderChildren(container, node, depth + 1))));
|
|
1753
|
-
}
|
|
1754
|
-
renderContainerNode(node, depth) {
|
|
1755
|
-
const selected = node.id === this.selectedId;
|
|
1756
|
-
const cls = 'mrd-document-list__row mrd-document-list__row--dossier'
|
|
1757
|
-
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1758
|
-
+ (node.id === this.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1759
|
-
return (index.h("div", { class: "mrd-document-list__node", key: node.id }, index.h("div", { class: cls, onClick: () => this.toggleContainer(node), onDragOver: (e) => this.onNodeDragOver(e, node), onDragLeave: () => this.onNodeDragLeave(node), onDrop: (e) => this.onNodeDrop(e, node, node) }, this.indent(depth), this.renderChevron(node.open, false), this.renderDossierIcon(), index.h("span", { class: "mrd-document-list__label" }, node.label), index.h("span", { class: "mrd-document-list__count" }, node.totalCount)), node.open && (index.h("div", { class: "mrd-document-list__kids" }, node.loading && !node.foldersLoaded
|
|
1760
|
-
? this.renderLoadingRow(depth + 1)
|
|
1761
|
-
: this.renderChildren(node, node, depth + 1)))));
|
|
1817
|
+
treeCtx() {
|
|
1818
|
+
return {
|
|
1819
|
+
locale: this.locale,
|
|
1820
|
+
titleField: this.titleField,
|
|
1821
|
+
dateField: this.dateField,
|
|
1822
|
+
selectedId: this.selectedId,
|
|
1823
|
+
dropTargetId: this.dropTargetId,
|
|
1824
|
+
uploadingNodeId: this.uploadingNodeId,
|
|
1825
|
+
on: {
|
|
1826
|
+
toggleContainer: node => this.toggleContainer(node),
|
|
1827
|
+
toggleFolder: (container, node) => this.toggleFolder(container, node),
|
|
1828
|
+
openDoc: doc => this.openDoc(doc),
|
|
1829
|
+
docDragStart: this.onDocDragStart,
|
|
1830
|
+
docDragEnd: this.onDocDragEnd,
|
|
1831
|
+
nodeDragOver: this.onNodeDragOver,
|
|
1832
|
+
nodeDragLeave: this.onNodeDragLeave,
|
|
1833
|
+
nodeDrop: this.onNodeDrop,
|
|
1834
|
+
pendingInput: this.onPendingInput,
|
|
1835
|
+
pendingKeyDown: this.onPendingKeyDown,
|
|
1836
|
+
cancelFolder: () => this.cancelFolder(),
|
|
1837
|
+
setPendingInputEl: el => (this.pendingInputEl = el),
|
|
1838
|
+
},
|
|
1839
|
+
};
|
|
1762
1840
|
}
|
|
1763
1841
|
render() {
|
|
1842
|
+
const ctx = this.treeCtx();
|
|
1764
1843
|
let body;
|
|
1765
1844
|
if (this.rootLoading) {
|
|
1766
|
-
body =
|
|
1845
|
+
body = renderLoadingRow(ctx, 0);
|
|
1767
1846
|
}
|
|
1768
1847
|
else if (this.containers.length === 0) {
|
|
1769
|
-
body = index.h("div", { key: '
|
|
1848
|
+
body = index.h("div", { key: 'ce40dab51ab61447838e5059159ae4778209a6f3', class: "mrd-document-list__empty" }, t('no_results', this.locale));
|
|
1770
1849
|
}
|
|
1771
1850
|
else if (this.singleContainer) {
|
|
1772
1851
|
// Dossier context: render the single container's folder tree at the root.
|
|
1773
1852
|
const only = this.containers[0];
|
|
1774
1853
|
if (only.loading && !only.foldersLoaded) {
|
|
1775
|
-
body =
|
|
1854
|
+
body = renderLoadingRow(ctx, 0);
|
|
1776
1855
|
}
|
|
1777
1856
|
else {
|
|
1778
|
-
const kids =
|
|
1857
|
+
const kids = renderNodeChildren(ctx, only, only, 0);
|
|
1779
1858
|
body = kids.length
|
|
1780
1859
|
? kids
|
|
1781
1860
|
: index.h("div", { class: "mrd-document-list__empty" }, t('doc_empty_drop', this.locale));
|
|
1782
1861
|
}
|
|
1783
1862
|
}
|
|
1784
1863
|
else {
|
|
1785
|
-
body = this.containers.map(c =>
|
|
1864
|
+
body = this.containers.map(c => renderContainerNode(ctx, c, 0));
|
|
1786
1865
|
}
|
|
1787
|
-
return (index.h(index.Host, { key: '
|
|
1866
|
+
return (index.h(index.Host, { key: '9e1f7805ae18bce506c530a481db902900ad95f3' }, index.h("div", { key: 'a51334634e94310a71650ad49f17f0a20e2aed4d', class: 'mrd-document-list' + (this.rootDropActive ? ' mrd-document-list--drop-active' : ''), onDragOver: this.onRootDragOver, onDragLeave: this.onRootDragLeave, onDrop: this.onRootDrop }, body)));
|
|
1788
1867
|
}
|
|
1789
1868
|
get el() { return index.getElement(this); }
|
|
1790
1869
|
};
|
|
1791
1870
|
/** Root sentinel id for the container-level distinct request. */
|
|
1792
1871
|
MrdDocumentList.ROOT = '__root__';
|
|
1793
|
-
MrdDocumentList.style =
|
|
1872
|
+
MrdDocumentList.style = mrdDocumentListCss();
|
|
1794
1873
|
|
|
1795
|
-
const
|
|
1874
|
+
const mrdDocumentViewCss = () => `.sc-mrd-document-view-h{display:block}.mrd-document-view.sc-mrd-document-view{max-width:720px}.mrd-document-view__crumb.sc-mrd-document-view{display:inline-flex;align-items:center;gap:var(--mrd-space-2);margin-bottom:var(--mrd-space-4);padding:var(--mrd-space-1) var(--mrd-space-3);background:var(--mrd-color-primary-light);border:1px solid transparent;border-radius:var(--mrd-border-radius);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-primary-dark);cursor:pointer}.mrd-document-view__crumb.sc-mrd-document-view:hover{border-color:var(--mrd-color-primary)}.mrd-document-view__crumb-icon.sc-mrd-document-view{width:0.875rem;height:0.875rem;flex-shrink:0}.mrd-document-view__title.sc-mrd-document-view{font-size:var(--mrd-font-size-2xl);font-weight:var(--mrd-font-weight-bold);color:var(--mrd-color-neutral-900);letter-spacing:-0.02em;margin:0 0 var(--mrd-space-1) 0}.mrd-document-view__date.sc-mrd-document-view{font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-400);font-variant-numeric:tabular-nums;margin:0 0 var(--mrd-space-6) 0}.mrd-document-view__file.sc-mrd-document-view{display:flex;align-items:center;gap:var(--mrd-space-4);padding:var(--mrd-space-4);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);background:var(--mrd-color-neutral-50);margin-bottom:var(--mrd-space-6)}.mrd-document-view__file-preview.sc-mrd-document-view{width:2.875rem;height:3.625rem;flex-shrink:0;display:grid;place-items:center;border-radius:var(--mrd-border-radius-sm);background:var(--mrd-color-white);border:1px solid var(--mrd-border-color);color:var(--mrd-color-danger);box-shadow:var(--mrd-shadow-sm)}.mrd-document-view__file-preview.sc-mrd-document-view svg.sc-mrd-document-view{width:1.5rem;height:1.5rem}.mrd-document-view__file-meta.sc-mrd-document-view{flex:1;min-width:0}.mrd-document-view__file-name.sc-mrd-document-view{font-weight:var(--mrd-font-weight-semibold);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-800);word-break:break-word}.mrd-document-view__download.sc-mrd-document-view{display:inline-flex;align-items:center;gap:var(--mrd-space-2);flex-shrink:0;height:2rem;padding:0 var(--mrd-space-3);background:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-300);border-radius:var(--mrd-border-radius);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-700);cursor:pointer}.mrd-document-view__download.sc-mrd-document-view:hover{background:var(--mrd-color-neutral-100);color:var(--mrd-color-neutral-900)}.mrd-document-view__download.sc-mrd-document-view svg.sc-mrd-document-view{width:0.9375rem;height:0.9375rem}.mrd-document-view__summary-body.sc-mrd-document-view{font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-700);line-height:var(--mrd-line-height-relaxed)}`;
|
|
1796
1875
|
|
|
1797
1876
|
const MrdDocumentView = class {
|
|
1798
1877
|
constructor(hostRef) {
|
|
@@ -1842,12 +1921,12 @@ const MrdDocumentView = class {
|
|
|
1842
1921
|
const date = dateRaw != null && dateRaw !== '' ? formatDate(dateRaw, this.locale) : null;
|
|
1843
1922
|
const summaryRaw = this.slotValue('summary');
|
|
1844
1923
|
const summary = summaryRaw != null && summaryRaw !== '' ? String(summaryRaw) : null;
|
|
1845
|
-
return (index.h(index.Host, { key: '
|
|
1924
|
+
return (index.h(index.Host, { key: '0c64c72eaf5e1eefc2ca9aebb2543081eb1eae32' }, index.h("div", { key: '70cce81b089fee81a4c163a6ba5fbcc8cb46131c', class: "mrd-document-view" }, this.renderContainer(), title && index.h("h1", { key: '50f85b32a6740d6cf57fdf1bb0bcc597b5e97b31', class: "mrd-document-view__title" }, title), date && index.h("p", { key: 'b3c8fb3b4382104858d49ef9a1597034665122bb', class: "mrd-document-view__date" }, date), this.renderFile(), summary && (index.h("div", { key: '2046c1eca7601549115de0c95ff778abaf5faf46', class: "mrd-document-view__summary" }, index.h("div", { key: '875863d3e438eee3d4df10473a93f09370fde08c', class: "mrd-document-view__summary-body", innerHTML: summary }))))));
|
|
1846
1925
|
}
|
|
1847
1926
|
};
|
|
1848
|
-
MrdDocumentView.style =
|
|
1927
|
+
MrdDocumentView.style = mrdDocumentViewCss();
|
|
1849
1928
|
|
|
1850
|
-
const
|
|
1929
|
+
const mrdEmailFieldCss = () => `.sc-mrd-email-field-h{display:block}.mrd-email-field.sc-mrd-email-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-email-field__label.sc-mrd-email-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-email-field__label--required.sc-mrd-email-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-email-field__input.sc-mrd-email-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-email-field__input.sc-mrd-email-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-email-field__input.sc-mrd-email-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-email-field__input.sc-mrd-email-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-email-field__input--error.sc-mrd-email-field{border-color:var(--mrd-border-color-error)}.mrd-email-field__input--error.sc-mrd-email-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-email-field__error.sc-mrd-email-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}`;
|
|
1851
1930
|
|
|
1852
1931
|
const MrdEmailField = class {
|
|
1853
1932
|
constructor(hostRef) {
|
|
@@ -1868,26 +1947,18 @@ const MrdEmailField = class {
|
|
|
1868
1947
|
};
|
|
1869
1948
|
this.handleBlur = (e) => {
|
|
1870
1949
|
const val = e.target.value;
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
}
|
|
1874
|
-
else if (val && !validateEmail(val)) {
|
|
1875
|
-
this.error = t('invalid_email', this.locale);
|
|
1876
|
-
}
|
|
1877
|
-
else {
|
|
1878
|
-
this.error = '';
|
|
1879
|
-
}
|
|
1950
|
+
this.error = requiredError(val, this.required, this.locale)
|
|
1951
|
+
|| (val && !validateEmail(val) ? t('invalid_email', this.locale) : '');
|
|
1880
1952
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
1881
1953
|
};
|
|
1882
1954
|
}
|
|
1883
1955
|
render() {
|
|
1884
|
-
|
|
1885
|
-
return (index.h(index.Host, { key: '0d442ab2a711c26c83fcdbf0fd8cd006d8dd8649' }, index.h("div", { key: 'ceb2a80679514c4c5b888fe096c90ed6cc973f64', class: "mrd-email-field" }, this.label && (index.h("label", { key: '663f95eff1002ee56cfc3104514bf31b47e26750', class: `mrd-email-field__label${this.required ? ' mrd-email-field__label--required' : ''}` }, this.label)), index.h("input", { key: '42dbdec25a47b37cfd68d00d0b8a481f96fe8241', class: `mrd-email-field__input${hasError ? ' mrd-email-field__input--error' : ''}`, type: "email", name: this.name, value: this.value, placeholder: this.placeholder || 'name@example.com', required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur }), hasError && index.h("span", { key: '626ee856ceaa7051fb9dd1de8b7cbd708e83f617', class: "mrd-email-field__error" }, this.error))));
|
|
1956
|
+
return (index.h(index.Host, { key: '93f7c4975c24e6001e772f2858344edec04cda10' }, index.h("div", { key: '4f49a2a1f68a4161762861c5d54fd3690c88ac5d', class: "mrd-email-field" }, index.h(FieldLabel, { key: '23b20799f3e7c04889b7bc3a271e61b0bb5d7537', base: "mrd-email-field", label: this.label, required: this.required }), index.h("input", { key: '0fc452bfb9295a80102eeed4b32bcc9475c9d17b', class: controlClass('mrd-email-field', !!this.error), type: "email", name: this.name, value: this.value, placeholder: this.placeholder || 'name@example.com', required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur }), index.h(FieldError, { key: '34945fff9c69cf2f0aeb56492c95052250514d5c', base: "mrd-email-field", error: this.error }))));
|
|
1886
1957
|
}
|
|
1887
1958
|
};
|
|
1888
|
-
MrdEmailField.style =
|
|
1959
|
+
MrdEmailField.style = mrdEmailFieldCss();
|
|
1889
1960
|
|
|
1890
|
-
const
|
|
1961
|
+
const mrdFieldCss = () => `.sc-mrd-field-h{display:block}.mrd-field__inner.sc-mrd-field{display:block;width:100%}.mrd-field__history-editor.sc-mrd-field{margin-top:var(--mrd-space-2);display:flex;flex-direction:column;gap:var(--mrd-space-1)}.mrd-field__history-editor-label.sc-mrd-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-500)}.mrd-field__history-editor-row.sc-mrd-field{display:flex;align-items:center;gap:var(--mrd-space-2)}.mrd-field__history-editor-sep.sc-mrd-field{flex-shrink:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500)}.mrd-field__history-editor-value.sc-mrd-field{flex:1 1 0;min-width:0;height:var(--mrd-input-height);padding:0 var(--mrd-space-3);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-800);background-color:var(--mrd-color-white);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);outline:none;transition:border-color var(--mrd-transition-fast), box-shadow var(--mrd-transition-fast)}.mrd-field__history-editor-value.sc-mrd-field:focus{border-color:var(--mrd-color-primary);box-shadow:var(--mrd-shadow-focus)}.mrd-field__history-editor-until.sc-mrd-field{flex:0 0 10rem;height:var(--mrd-input-height);padding:0 var(--mrd-space-3);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-800);background-color:var(--mrd-color-white);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);outline:none;transition:border-color var(--mrd-transition-fast), box-shadow var(--mrd-transition-fast)}.mrd-field__history-editor-until.sc-mrd-field:focus{border-color:var(--mrd-color-primary);box-shadow:var(--mrd-shadow-focus)}.mrd-field__history-editor-remove.sc-mrd-field{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;padding:0;background:transparent;border:none;border-radius:var(--mrd-border-radius-sm);color:var(--mrd-color-neutral-400);cursor:pointer;transition:color var(--mrd-transition-fast), background-color var(--mrd-transition-fast)}.mrd-field__history-editor-remove.sc-mrd-field:hover{color:var(--mrd-color-danger);background-color:var(--mrd-color-danger-light)}.mrd-field__history-editor-remove.sc-mrd-field svg.sc-mrd-field{width:1rem;height:1rem}.mrd-field__history-editor-add.sc-mrd-field{align-self:flex-start;padding:var(--mrd-space-1) var(--mrd-space-3);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-primary);background:transparent;border:var(--mrd-border-width) solid var(--mrd-color-primary);border-radius:var(--mrd-border-radius-md);cursor:pointer;transition:background-color var(--mrd-transition-fast), color var(--mrd-transition-fast)}.mrd-field__history-editor-add.sc-mrd-field:hover{background-color:var(--mrd-color-primary-light)}`;
|
|
1891
1962
|
|
|
1892
1963
|
const MrdField = class {
|
|
1893
1964
|
constructor(hostRef) {
|
|
@@ -2072,9 +2143,47 @@ const MrdField = class {
|
|
|
2072
2143
|
}]
|
|
2073
2144
|
}; }
|
|
2074
2145
|
};
|
|
2075
|
-
MrdField.style =
|
|
2146
|
+
MrdField.style = mrdFieldCss();
|
|
2076
2147
|
|
|
2077
|
-
|
|
2148
|
+
/**
|
|
2149
|
+
* Shared upload behaviour for mrd-file-field and mrd-image-field:
|
|
2150
|
+
* file validation, drop-zone class building and drag-drop wiring.
|
|
2151
|
+
*/
|
|
2152
|
+
/** Validates a selected/dropped file; returns a localised error message or '' when accepted. */
|
|
2153
|
+
function validateUploadFile(file, maxSize, locale, requireImage = false) {
|
|
2154
|
+
if (maxSize > 0 && file.size > maxSize)
|
|
2155
|
+
return t('file_too_large', locale);
|
|
2156
|
+
if (requireImage && !file.type.startsWith('image/'))
|
|
2157
|
+
return t('invalid_image', locale);
|
|
2158
|
+
return '';
|
|
2159
|
+
}
|
|
2160
|
+
/** BEM class string for the drop zone, e.g. base 'mrd-file-field' → 'mrd-file-field__zone …'. */
|
|
2161
|
+
function uploadZoneClass(base, opts) {
|
|
2162
|
+
return [
|
|
2163
|
+
`${base}__zone`,
|
|
2164
|
+
opts.dragging ? `${base}__zone--dragging` : '',
|
|
2165
|
+
opts.error ? `${base}__zone--error` : '',
|
|
2166
|
+
opts.disabled ? `${base}__zone--disabled` : '',
|
|
2167
|
+
].filter(Boolean).join(' ');
|
|
2168
|
+
}
|
|
2169
|
+
/** Drag-drop handlers for the drop zone; the component owns the dragging state and file handling. */
|
|
2170
|
+
function makeDragHandlers(setDragging, onFile) {
|
|
2171
|
+
return {
|
|
2172
|
+
onDragOver: (e) => {
|
|
2173
|
+
e.preventDefault();
|
|
2174
|
+
setDragging(true);
|
|
2175
|
+
},
|
|
2176
|
+
onDragLeave: () => setDragging(false),
|
|
2177
|
+
onDrop: (e) => {
|
|
2178
|
+
var _a, _b, _c;
|
|
2179
|
+
e.preventDefault();
|
|
2180
|
+
setDragging(false);
|
|
2181
|
+
onFile((_c = (_b = (_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : null);
|
|
2182
|
+
},
|
|
2183
|
+
};
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
const mrdFileFieldCss = () => `.sc-mrd-file-field-h{display:block}.mrd-file-field.sc-mrd-file-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-file-field__label.sc-mrd-file-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-file-field__label--required.sc-mrd-file-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-file-field__error.sc-mrd-file-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-file-field__zone.sc-mrd-file-field{display:flex;align-items:center;justify-content:center;border:2px dashed var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);background-color:var(--mrd-color-neutral-50);cursor:pointer;transition:border-color var(--mrd-transition), background-color var(--mrd-transition);min-height:100px;position:relative}.mrd-file-field__zone.sc-mrd-file-field:hover,.mrd-file-field__zone--dragging.sc-mrd-file-field{border-color:var(--mrd-color-primary);background-color:var(--mrd-color-primary-light)}.mrd-file-field__zone--error.sc-mrd-file-field{border-color:var(--mrd-border-color-error)}.mrd-file-field__zone--disabled.sc-mrd-file-field{opacity:0.6;cursor:not-allowed}.mrd-file-field__zone--disabled.sc-mrd-file-field:hover{border-color:var(--mrd-border-color);background-color:var(--mrd-color-neutral-50)}.mrd-file-field__zone.sc-mrd-file-field{padding:var(--mrd-space-6)}.mrd-file-field__input.sc-mrd-file-field{position:absolute;inset:0;opacity:0;width:100%;height:100%;pointer-events:none;cursor:pointer}.mrd-file-field__prompt.sc-mrd-file-field{display:flex;flex-direction:column;align-items:center;gap:var(--mrd-space-2);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-500);text-align:center}.mrd-file-field__upload-icon.sc-mrd-file-field{width:32px;height:32px;color:var(--mrd-color-neutral-400)}.mrd-file-field__browse.sc-mrd-file-field{color:var(--mrd-color-primary);font-weight:var(--mrd-font-weight-medium);text-decoration:underline}.mrd-file-field__selected.sc-mrd-file-field{display:flex;align-items:center;gap:var(--mrd-space-2);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-700)}.mrd-file-field__icon.sc-mrd-file-field{width:20px;height:20px;color:var(--mrd-color-primary);flex-shrink:0}.mrd-file-field__filename.sc-mrd-file-field{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:200px}.mrd-file-field__clear.sc-mrd-file-field{background:none;border:none;cursor:pointer;color:var(--mrd-color-neutral-400);font-size:var(--mrd-font-size-sm);padding:var(--mrd-space-1);border-radius:var(--mrd-border-radius-sm);line-height:1}.mrd-file-field__clear.sc-mrd-file-field:hover{color:var(--mrd-color-danger);background-color:var(--mrd-color-danger-light)}.mrd-file-field__spinner.sc-mrd-file-field{display:inline-block;width:18px;height:18px;border:2px solid var(--mrd-color-neutral-300);border-top-color:var(--mrd-color-primary);border-radius:50%;animation:mrd-spin 0.6s linear infinite;flex-shrink:0}@keyframes mrd-spin{to{transform:rotate(360deg)}}`;
|
|
2078
2187
|
|
|
2079
2188
|
const MrdFileField = class {
|
|
2080
2189
|
constructor(hostRef) {
|
|
@@ -2099,20 +2208,7 @@ const MrdFileField = class {
|
|
|
2099
2208
|
const files = e.target.files;
|
|
2100
2209
|
this.handleFile((_a = files === null || files === void 0 ? void 0 : files[0]) !== null && _a !== void 0 ? _a : null);
|
|
2101
2210
|
};
|
|
2102
|
-
this.
|
|
2103
|
-
e.preventDefault();
|
|
2104
|
-
this.isDragging = true;
|
|
2105
|
-
};
|
|
2106
|
-
this.handleDragLeave = () => {
|
|
2107
|
-
this.isDragging = false;
|
|
2108
|
-
};
|
|
2109
|
-
this.handleDrop = (e) => {
|
|
2110
|
-
var _a, _b, _c;
|
|
2111
|
-
e.preventDefault();
|
|
2112
|
-
this.isDragging = false;
|
|
2113
|
-
const file = (_c = (_b = (_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : null;
|
|
2114
|
-
this.handleFile(file);
|
|
2115
|
-
};
|
|
2211
|
+
this.drag = makeDragHandlers(dragging => (this.isDragging = dragging), file => this.handleFile(file));
|
|
2116
2212
|
this.handleZoneClick = () => {
|
|
2117
2213
|
var _a;
|
|
2118
2214
|
if (!this.disabled && !this.uploading) {
|
|
@@ -2146,8 +2242,9 @@ const MrdFileField = class {
|
|
|
2146
2242
|
this.mrdChange.emit({ name: this.name, value: null });
|
|
2147
2243
|
return;
|
|
2148
2244
|
}
|
|
2149
|
-
|
|
2150
|
-
|
|
2245
|
+
const uploadError = validateUploadFile(file, this.maxSize, this.locale);
|
|
2246
|
+
if (uploadError) {
|
|
2247
|
+
this.error = uploadError;
|
|
2151
2248
|
return;
|
|
2152
2249
|
}
|
|
2153
2250
|
this.error = '';
|
|
@@ -2159,13 +2256,12 @@ const MrdFileField = class {
|
|
|
2159
2256
|
render() {
|
|
2160
2257
|
const hasFile = this.uploading || (typeof this.value === 'string' && this.value) || this.fileName;
|
|
2161
2258
|
const hasError = !!this.error;
|
|
2162
|
-
const zoneClass =
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
return (index.h(index.Host, { key: '095bb39f3cb1680cf5e7e51bdfd06d8eb087f237' }, index.h("div", { key: '7e5b5fe6e63b6530221083c8bcb82bcac59a5fe7', class: "mrd-file-field" }, this.label && (index.h("label", { key: 'c34723f4199371d6fe8ea87463d878b89c038590', class: `mrd-file-field__label${this.required ? ' mrd-file-field__label--required' : ''}` }, this.label)), index.h("div", { key: '4727667345d3cd4a5c65a431744a09f366943c13', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, index.h("input", { key: '45ed41c0f094dbe269561c8586e473f908cdf4a4', ref: el => (this.fileInputRef = el), class: "mrd-file-field__input", type: "file", name: this.name, accept: this.accept, disabled: this.disabled || this.uploading, required: this.required && !hasFile, onChange: this.handleInputChange }), hasFile ? (index.h("div", { class: "mrd-file-field__selected" }, this.uploading ? (index.h("span", { class: "mrd-file-field__spinner", "aria-label": t('loading', this.locale) })) : (index.h("svg", { class: "mrd-file-field__icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }), index.h("polyline", { points: "14 2 14 8 20 8" }))), index.h("span", { class: "mrd-file-field__filename" }, this.fileName), !this.uploading && (index.h("button", { class: "mrd-file-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, "\u2715")))) : (index.h("div", { class: "mrd-file-field__prompt" }, index.h("svg", { class: "mrd-file-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("polyline", { points: "16 16 12 12 8 16" }), index.h("line", { x1: "12", y1: "12", x2: "12", y2: "21" }), index.h("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" })), index.h("span", null, t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-file-field__browse" }, t('browse', this.locale)))))), hasError && index.h("span", { key: '00ce94ead3c32ed63e903cfd9d8480084a308d84', class: "mrd-file-field__error" }, this.error))));
|
|
2259
|
+
const zoneClass = uploadZoneClass('mrd-file-field', {
|
|
2260
|
+
dragging: this.isDragging,
|
|
2261
|
+
error: hasError,
|
|
2262
|
+
disabled: this.disabled || this.uploading,
|
|
2263
|
+
});
|
|
2264
|
+
return (index.h(index.Host, { key: '2c4cee79cd0f95ed3750dfc86007a2b36aa3da15' }, index.h("div", { key: '5b47d0f83e8e38b22bb04409544ec2af580274f1', class: "mrd-file-field" }, index.h(FieldLabel, { key: '47a92d5680670bf750854fa6e7883da54a40baec', base: "mrd-file-field", label: this.label, required: this.required }), index.h("div", { key: '684f6ab39c32635fb5ca966ccab4a061d8682f89', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, index.h("input", { key: 'a47231d8c68280623daf0c5a2e4341417e7a88d0', ref: el => (this.fileInputRef = el), class: "mrd-file-field__input", type: "file", name: this.name, accept: this.accept, disabled: this.disabled || this.uploading, required: this.required && !hasFile, onChange: this.handleInputChange }), hasFile ? (index.h("div", { class: "mrd-file-field__selected" }, this.uploading ? (index.h("span", { class: "mrd-file-field__spinner", "aria-label": t('loading', this.locale) })) : (index.h("svg", { class: "mrd-file-field__icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }), index.h("polyline", { points: "14 2 14 8 20 8" }))), index.h("span", { class: "mrd-file-field__filename" }, this.fileName), !this.uploading && (index.h("button", { class: "mrd-file-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, "\u2715")))) : (index.h("div", { class: "mrd-file-field__prompt" }, index.h("svg", { class: "mrd-file-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("polyline", { points: "16 16 12 12 8 16" }), index.h("line", { x1: "12", y1: "12", x2: "12", y2: "21" }), index.h("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" })), index.h("span", null, t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-file-field__browse" }, t('browse', this.locale)))))), index.h(FieldError, { key: '5f18e91aa94319a5571c368e745c108fb0d371a7', base: "mrd-file-field", error: this.error }))));
|
|
2169
2265
|
}
|
|
2170
2266
|
static get watchers() { return {
|
|
2171
2267
|
"value": [{
|
|
@@ -2173,9 +2269,9 @@ const MrdFileField = class {
|
|
|
2173
2269
|
}]
|
|
2174
2270
|
}; }
|
|
2175
2271
|
};
|
|
2176
|
-
MrdFileField.style =
|
|
2272
|
+
MrdFileField.style = mrdFileFieldCss();
|
|
2177
2273
|
|
|
2178
|
-
const
|
|
2274
|
+
const mrdFormCss = () => `.sc-mrd-form-h{display:block}.mrd-form.sc-mrd-form{font-family:var(--mrd-font-family);width:100%}.mrd-form__title.sc-mrd-form{font-size:var(--mrd-font-size-2xl);font-weight:var(--mrd-font-weight-bold);color:var(--mrd-color-neutral-900);margin:0 0 var(--mrd-space-6) 0}.mrd-form__body.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-5)}.mrd-form__field.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-1)}.mrd-form__field-error.sc-mrd-form{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-form__section.sc-mrd-form{border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);padding:var(--mrd-space-4) var(--mrd-space-5);margin:0}.mrd-form__section-legend.sc-mrd-form{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-700);padding:0 var(--mrd-space-2)}.mrd-form__section-body.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-4);margin-top:var(--mrd-space-2)}.mrd-form__group.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-2)}.mrd-form__group-label.sc-mrd-form{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-500);text-transform:uppercase;letter-spacing:0.05em}.mrd-form__group-body.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-4);padding-left:var(--mrd-space-4);border-left:3px solid var(--mrd-color-neutral-200)}.mrd-form__footer.sc-mrd-form{margin-top:var(--mrd-space-8);padding-top:var(--mrd-space-5);border-top:var(--mrd-border-width) solid var(--mrd-border-color);display:flex;justify-content:flex-end;gap:var(--mrd-space-3)}.mrd-form__submit.sc-mrd-form{display:inline-flex;align-items:center;justify-content:center;height:var(--mrd-input-height);padding:0 var(--mrd-space-6);background-color:var(--mrd-color-primary);color:var(--mrd-color-white);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);border:none;border-radius:var(--mrd-border-radius);cursor:pointer;transition:background-color var(--mrd-transition)}.mrd-form__submit.sc-mrd-form:hover{background-color:var(--mrd-color-primary-hover)}.mrd-form__submit.sc-mrd-form:focus{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-form__submit.sc-mrd-form:active{background-color:var(--mrd-color-primary-dark)}.mrd-form__cancel.sc-mrd-form{display:inline-flex;align-items:center;justify-content:center;height:var(--mrd-input-height);padding:0 var(--mrd-space-6);background-color:transparent;color:var(--mrd-color-neutral-600);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);cursor:pointer;transition:background-color var(--mrd-transition), color var(--mrd-transition)}.mrd-form__cancel.sc-mrd-form:hover{background-color:var(--mrd-color-neutral-100);color:var(--mrd-color-neutral-800)}.mrd-form__cancel.sc-mrd-form:focus{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-form__cancel.sc-mrd-form:active{background-color:var(--mrd-color-neutral-200)}`;
|
|
2179
2275
|
|
|
2180
2276
|
const MrdForm = class {
|
|
2181
2277
|
constructor(hostRef) {
|
|
@@ -2542,9 +2638,9 @@ const MrdForm = class {
|
|
|
2542
2638
|
}]
|
|
2543
2639
|
}; }
|
|
2544
2640
|
};
|
|
2545
|
-
MrdForm.style =
|
|
2641
|
+
MrdForm.style = mrdFormCss();
|
|
2546
2642
|
|
|
2547
|
-
const
|
|
2643
|
+
const mrdHyperlinkFieldCss = () => `.sc-mrd-hyperlink-field-h{display:block}.mrd-hyperlink-field.sc-mrd-hyperlink-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-hyperlink-field__label.sc-mrd-hyperlink-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-hyperlink-field__label--required.sc-mrd-hyperlink-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-hyperlink-field__input.sc-mrd-hyperlink-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-hyperlink-field__input.sc-mrd-hyperlink-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-hyperlink-field__input.sc-mrd-hyperlink-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-hyperlink-field__input.sc-mrd-hyperlink-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-hyperlink-field__input--error.sc-mrd-hyperlink-field{border-color:var(--mrd-border-color-error)}.mrd-hyperlink-field__input--error.sc-mrd-hyperlink-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-hyperlink-field__error.sc-mrd-hyperlink-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-hyperlink-field__input--name.sc-mrd-hyperlink-field{margin-top:var(--mrd-space-1)}.mrd-hyperlink-field__link.sc-mrd-hyperlink-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-primary);text-decoration:underline;word-break:break-all}.mrd-hyperlink-field__link.sc-mrd-hyperlink-field:hover{opacity:0.8}.mrd-hyperlink-field__empty.sc-mrd-hyperlink-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-400)}`;
|
|
2548
2644
|
|
|
2549
2645
|
const MrdHyperlinkField = class {
|
|
2550
2646
|
constructor(hostRef) {
|
|
@@ -2570,15 +2666,8 @@ const MrdHyperlinkField = class {
|
|
|
2570
2666
|
this.mrdChange.emit({ name: this.name, value: this.buildValue() });
|
|
2571
2667
|
};
|
|
2572
2668
|
this.handleBlur = () => {
|
|
2573
|
-
|
|
2574
|
-
this.
|
|
2575
|
-
}
|
|
2576
|
-
else if (this.internalHref && !validateUrl(this.internalHref)) {
|
|
2577
|
-
this.error = t('invalid_url', this.locale);
|
|
2578
|
-
}
|
|
2579
|
-
else {
|
|
2580
|
-
this.error = '';
|
|
2581
|
-
}
|
|
2669
|
+
this.error = requiredError(this.internalHref, this.required, this.locale)
|
|
2670
|
+
|| (this.internalHref && !validateUrl(this.internalHref) ? t('invalid_url', this.locale) : '');
|
|
2582
2671
|
this.mrdBlur.emit({ name: this.name, value: this.buildValue() });
|
|
2583
2672
|
};
|
|
2584
2673
|
}
|
|
@@ -2611,7 +2700,7 @@ const MrdHyperlinkField = class {
|
|
|
2611
2700
|
? index.h("a", { class: "mrd-hyperlink-field__link", href: this.internalHref, target: "_blank", rel: "noopener noreferrer" }, this.internalName || this.internalHref)
|
|
2612
2701
|
: index.h("span", { class: "mrd-hyperlink-field__empty" }, "\u2014"))));
|
|
2613
2702
|
}
|
|
2614
|
-
return (index.h(index.Host, null, index.h("div", { class: "mrd-hyperlink-field" },
|
|
2703
|
+
return (index.h(index.Host, null, index.h("div", { class: "mrd-hyperlink-field" }, index.h(FieldLabel, { base: "mrd-hyperlink-field", label: this.label, required: this.required }), index.h("input", { class: controlClass('mrd-hyperlink-field', hasError), type: "url", name: this.name, value: this.internalHref, placeholder: this.placeholder || 'https://', required: this.required, onInput: this.handleHrefInput, onBlur: this.handleBlur }), index.h("input", { class: "mrd-hyperlink-field__input mrd-hyperlink-field__input--name", type: "text", value: this.internalName, placeholder: t('hyperlink_name', this.locale), onInput: this.handleNameInput, onBlur: this.handleBlur }), index.h(FieldError, { base: "mrd-hyperlink-field", error: this.error }))));
|
|
2615
2704
|
}
|
|
2616
2705
|
static get watchers() { return {
|
|
2617
2706
|
"value": [{
|
|
@@ -2619,9 +2708,9 @@ const MrdHyperlinkField = class {
|
|
|
2619
2708
|
}]
|
|
2620
2709
|
}; }
|
|
2621
2710
|
};
|
|
2622
|
-
MrdHyperlinkField.style =
|
|
2711
|
+
MrdHyperlinkField.style = mrdHyperlinkFieldCss();
|
|
2623
2712
|
|
|
2624
|
-
const
|
|
2713
|
+
const mrdImageFieldCss = () => `.sc-mrd-image-field-h{display:block}.mrd-image-field.sc-mrd-image-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-image-field__label.sc-mrd-image-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-image-field__label--required.sc-mrd-image-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-image-field__error.sc-mrd-image-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-image-field__zone.sc-mrd-image-field{display:flex;align-items:center;justify-content:center;border:2px dashed var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);background-color:var(--mrd-color-neutral-50);cursor:pointer;transition:border-color var(--mrd-transition), background-color var(--mrd-transition);min-height:100px;position:relative}.mrd-image-field__zone.sc-mrd-image-field:hover,.mrd-image-field__zone--dragging.sc-mrd-image-field{border-color:var(--mrd-color-primary);background-color:var(--mrd-color-primary-light)}.mrd-image-field__zone--error.sc-mrd-image-field{border-color:var(--mrd-border-color-error)}.mrd-image-field__zone--disabled.sc-mrd-image-field{opacity:0.6;cursor:not-allowed}.mrd-image-field__zone--disabled.sc-mrd-image-field:hover{border-color:var(--mrd-border-color);background-color:var(--mrd-color-neutral-50)}.mrd-image-field__input.sc-mrd-image-field{position:absolute;inset:0;opacity:0;width:100%;height:100%;pointer-events:none}.mrd-image-field__prompt.sc-mrd-image-field{display:flex;flex-direction:column;align-items:center;gap:var(--mrd-space-2);padding:var(--mrd-space-6);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-500);text-align:center}.mrd-image-field__upload-icon.sc-mrd-image-field{width:40px;height:40px;color:var(--mrd-color-neutral-400)}.mrd-image-field__browse.sc-mrd-image-field{color:var(--mrd-color-primary);font-weight:var(--mrd-font-weight-medium);text-decoration:underline}.mrd-image-field__preview-container.sc-mrd-image-field{display:flex;align-items:center;gap:var(--mrd-space-4);padding:var(--mrd-space-4);width:100%}.mrd-image-field__preview-thumb.sc-mrd-image-field{flex-shrink:0;width:80px;height:80px;border-radius:var(--mrd-border-radius);overflow:hidden;border:var(--mrd-border-width) solid var(--mrd-border-color);background-color:var(--mrd-color-neutral-100)}.mrd-image-field__preview.sc-mrd-image-field{width:100%;height:100%;object-fit:cover;display:block}.mrd-image-field__preview-info.sc-mrd-image-field{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--mrd-space-1)}.mrd-image-field__preview-name.sc-mrd-image-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mrd-image-field__preview-overlay.sc-mrd-image-field{position:absolute;inset:0;background:rgba(255, 255, 255, 0.7);display:flex;align-items:center;justify-content:center;border-radius:var(--mrd-border-radius)}.mrd-image-field__spinner.sc-mrd-image-field{display:inline-block;width:24px;height:24px;border:2px solid var(--mrd-color-neutral-300);border-top-color:var(--mrd-color-primary);border-radius:50%;animation:mrd-spin 0.6s linear infinite}@keyframes mrd-spin{to{transform:rotate(360deg)}}.mrd-image-field__upload-status.sc-mrd-image-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500)}.mrd-image-field__clear.sc-mrd-image-field{flex-shrink:0;background-color:var(--mrd-color-white);color:var(--mrd-color-danger);border:var(--mrd-border-width) solid var(--mrd-color-danger);border-radius:var(--mrd-border-radius);padding:var(--mrd-space-1) var(--mrd-space-3);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);cursor:pointer;transition:background-color var(--mrd-transition), color var(--mrd-transition)}.mrd-image-field__clear.sc-mrd-image-field:hover{background-color:var(--mrd-color-danger);color:var(--mrd-color-white)}`;
|
|
2625
2714
|
|
|
2626
2715
|
const MrdImageField = class {
|
|
2627
2716
|
constructor(hostRef) {
|
|
@@ -2647,20 +2736,7 @@ const MrdImageField = class {
|
|
|
2647
2736
|
const files = e.target.files;
|
|
2648
2737
|
this.handleFile((_a = files === null || files === void 0 ? void 0 : files[0]) !== null && _a !== void 0 ? _a : null);
|
|
2649
2738
|
};
|
|
2650
|
-
this.
|
|
2651
|
-
e.preventDefault();
|
|
2652
|
-
this.isDragging = true;
|
|
2653
|
-
};
|
|
2654
|
-
this.handleDragLeave = () => {
|
|
2655
|
-
this.isDragging = false;
|
|
2656
|
-
};
|
|
2657
|
-
this.handleDrop = (e) => {
|
|
2658
|
-
var _a, _b, _c;
|
|
2659
|
-
e.preventDefault();
|
|
2660
|
-
this.isDragging = false;
|
|
2661
|
-
const file = (_c = (_b = (_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : null;
|
|
2662
|
-
this.handleFile(file);
|
|
2663
|
-
};
|
|
2739
|
+
this.drag = makeDragHandlers(dragging => (this.isDragging = dragging), file => this.handleFile(file));
|
|
2664
2740
|
this.handleZoneClick = () => {
|
|
2665
2741
|
var _a;
|
|
2666
2742
|
if (!this.disabled && !this.uploading) {
|
|
@@ -2697,12 +2773,9 @@ const MrdImageField = class {
|
|
|
2697
2773
|
this.mrdChange.emit({ name: this.name, value: null });
|
|
2698
2774
|
return;
|
|
2699
2775
|
}
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
}
|
|
2704
|
-
if (!file.type.startsWith('image/')) {
|
|
2705
|
-
this.error = 'Please select an image file';
|
|
2776
|
+
const uploadError = validateUploadFile(file, this.maxSize, this.locale, true);
|
|
2777
|
+
if (uploadError) {
|
|
2778
|
+
this.error = uploadError;
|
|
2706
2779
|
return;
|
|
2707
2780
|
}
|
|
2708
2781
|
this.error = '';
|
|
@@ -2720,13 +2793,12 @@ const MrdImageField = class {
|
|
|
2720
2793
|
}
|
|
2721
2794
|
render() {
|
|
2722
2795
|
const hasError = !!this.error;
|
|
2723
|
-
const zoneClass =
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
return (index.h(index.Host, { key: '97db2df72839f36b7a46e153a5dd1c208c52b522' }, index.h("div", { key: 'c8f2d3d858f90d322d26082aaf5adb57acfc78f4', class: "mrd-image-field" }, this.label && (index.h("label", { key: '6625e5031ff0b7c06f76c1ea0387f1bd5c1858a4', class: `mrd-image-field__label${this.required ? ' mrd-image-field__label--required' : ''}` }, this.label)), index.h("div", { key: '364216e6a96e845e21c42e821fdff02bd2612ff8', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, index.h("input", { key: '0487706ddd9f48cda1cb0c2a178809d90674486b', ref: el => (this.fileInputRef = el), class: "mrd-image-field__input", type: "file", name: this.name, accept: this.accept, disabled: this.disabled || this.uploading, required: this.required && !this.previewUrl, onChange: this.handleInputChange }), this.previewUrl ? (index.h("div", { class: "mrd-image-field__preview-container" }, index.h("div", { class: "mrd-image-field__preview-thumb" }, index.h("img", { class: "mrd-image-field__preview", src: this.previewUrl, alt: this.fileName }), this.uploading && index.h("div", { class: "mrd-image-field__preview-overlay" }, index.h("span", { class: "mrd-image-field__spinner" }))), index.h("div", { class: "mrd-image-field__preview-info" }, index.h("span", { class: "mrd-image-field__preview-name" }, this.fileName), this.uploading && (index.h("span", { class: "mrd-image-field__upload-status" }, t('loading', this.locale)))), !this.uploading && (index.h("button", { class: "mrd-image-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, t('remove', this.locale))))) : (index.h("div", { class: "mrd-image-field__prompt" }, index.h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), index.h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), index.h("polyline", { points: "21 15 16 10 5 21" })), index.h("span", null, t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-image-field__browse" }, t('browse', this.locale)))))), hasError && index.h("span", { key: 'bd505ef4f4b67c4e9138d8825c6e600f583f4cab', class: "mrd-image-field__error" }, this.error))));
|
|
2796
|
+
const zoneClass = uploadZoneClass('mrd-image-field', {
|
|
2797
|
+
dragging: this.isDragging,
|
|
2798
|
+
error: hasError,
|
|
2799
|
+
disabled: this.disabled || this.uploading,
|
|
2800
|
+
});
|
|
2801
|
+
return (index.h(index.Host, { key: 'ab78d93ab6c810363a8993bea4545f7406680e58' }, index.h("div", { key: '727ae5d9c1cce22d90d26229a9ea5d677abb4b07', class: "mrd-image-field" }, index.h(FieldLabel, { key: 'aab0e9fcc0204e8ea617453b5ca458f683194125', base: "mrd-image-field", label: this.label, required: this.required }), index.h("div", { key: '1241faff26c47a303fd0431201f490c6b8725987', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, index.h("input", { key: '70e3b8f869927ad525465ace96ed3ea24f5b7555', ref: el => (this.fileInputRef = el), class: "mrd-image-field__input", type: "file", name: this.name, accept: this.accept, disabled: this.disabled || this.uploading, required: this.required && !this.previewUrl, onChange: this.handleInputChange }), this.previewUrl ? (index.h("div", { class: "mrd-image-field__preview-container" }, index.h("div", { class: "mrd-image-field__preview-thumb" }, index.h("img", { class: "mrd-image-field__preview", src: this.previewUrl, alt: this.fileName }), this.uploading && index.h("div", { class: "mrd-image-field__preview-overlay" }, index.h("span", { class: "mrd-image-field__spinner" }))), index.h("div", { class: "mrd-image-field__preview-info" }, index.h("span", { class: "mrd-image-field__preview-name" }, this.fileName), this.uploading && (index.h("span", { class: "mrd-image-field__upload-status" }, t('loading', this.locale)))), !this.uploading && (index.h("button", { class: "mrd-image-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, t('remove', this.locale))))) : (index.h("div", { class: "mrd-image-field__prompt" }, index.h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), index.h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), index.h("polyline", { points: "21 15 16 10 5 21" })), index.h("span", null, t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-image-field__browse" }, t('browse', this.locale)))))), index.h(FieldError, { key: '01552a994c1e5a9f25129586a95562c32a377046', base: "mrd-image-field", error: this.error }))));
|
|
2730
2802
|
}
|
|
2731
2803
|
static get watchers() { return {
|
|
2732
2804
|
"value": [{
|
|
@@ -2734,7 +2806,36 @@ const MrdImageField = class {
|
|
|
2734
2806
|
}]
|
|
2735
2807
|
}; }
|
|
2736
2808
|
};
|
|
2737
|
-
MrdImageField.style =
|
|
2809
|
+
MrdImageField.style = mrdImageFieldCss();
|
|
2810
|
+
|
|
2811
|
+
/** Key an embedded view is addressed by (setViewPage etc.). */
|
|
2812
|
+
function viewKeyFor(item) {
|
|
2813
|
+
var _a, _b, _c, _d;
|
|
2814
|
+
if (item.type === index$1.ClientLayoutItemType.RELATED_VIEW)
|
|
2815
|
+
return (_b = (_a = item.relatedClass) !== null && _a !== void 0 ? _a : item.name) !== null && _b !== void 0 ? _b : '';
|
|
2816
|
+
return (_d = (_c = item.dataClass) !== null && _c !== void 0 ? _c : item.name) !== null && _d !== void 0 ? _d : '';
|
|
2817
|
+
}
|
|
2818
|
+
/** Depth-first flatten of the SECTION/GROUP tree. */
|
|
2819
|
+
function flattenItems(items) {
|
|
2820
|
+
const result = [];
|
|
2821
|
+
for (const item of items) {
|
|
2822
|
+
result.push(item);
|
|
2823
|
+
if (item.items)
|
|
2824
|
+
result.push(...flattenItems(item.items));
|
|
2825
|
+
}
|
|
2826
|
+
return result;
|
|
2827
|
+
}
|
|
2828
|
+
/** Build the canonical parent href `/{base}/{tenant}/{fromClass}/{parentId}` from
|
|
2829
|
+
* the object's self href. Empty unless it is a RELATED_VIEW with a fromClass. */
|
|
2830
|
+
function buildContainerHref(item, selfHref, parentId) {
|
|
2831
|
+
if (item.type !== index$1.ClientLayoutItemType.RELATED_VIEW || !item.fromClass || !parentId)
|
|
2832
|
+
return '';
|
|
2833
|
+
const segs = selfHref.split('/').filter(Boolean);
|
|
2834
|
+
if (segs.length < 2)
|
|
2835
|
+
return '';
|
|
2836
|
+
const [base, tenant] = segs;
|
|
2837
|
+
return `/${base}/${tenant}/${item.fromClass}/${parentId}`;
|
|
2838
|
+
}
|
|
2738
2839
|
|
|
2739
2840
|
class CellRenderer {
|
|
2740
2841
|
static render(column, row, locale) {
|
|
@@ -2840,7 +2941,114 @@ class CellRenderer {
|
|
|
2840
2941
|
}
|
|
2841
2942
|
}
|
|
2842
2943
|
|
|
2843
|
-
const mrdLayoutSectionScss = () => `.mrd-layout-section.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-800)}.mrd-layout-section__field.sc-mrd-layout-section{display:grid;grid-template-columns:200px 1fr;align-items:baseline;gap:0 var(--mrd-space-2);padding:var(--mrd-space-1) 0}.mrd-layout-section__field-label.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-normal);color:var(--mrd-color-neutral-500);padding-top:1px}.mrd-layout-section__field-value.sc-mrd-layout-section{font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800);word-break:break-word;display:inline-flex;align-items:center;gap:var(--mrd-space-1)}.mrd-layout-section__history-wrap.sc-mrd-layout-section{position:relative;display:inline-flex;align-items:center}.mrd-layout-section__history-btn.sc-mrd-layout-section{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;padding:0;background:transparent;border:none;border-radius:var(--mrd-border-radius-sm);color:var(--mrd-color-neutral-400);cursor:pointer;flex-shrink:0;transition:color var(--mrd-transition-fast), background-color var(--mrd-transition-fast)}.mrd-layout-section__history-btn.sc-mrd-layout-section:hover{color:var(--mrd-color-neutral-700);background-color:var(--mrd-color-neutral-100)}.mrd-layout-section__history-btn.sc-mrd-layout-section:focus{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-layout-section__history-icon.sc-mrd-layout-section{width:0.875rem;height:0.875rem}.mrd-layout-section__history-popover.sc-mrd-layout-section{position:absolute;top:calc(100% + 0.25rem);left:0;min-width:24rem;max-width:24rem;background-color:var(--mrd-color-white);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);box-shadow:var(--mrd-shadow-md);padding:var(--mrd-space-1) 0;z-index:var(--mrd-z-dropdown)}.mrd-layout-section__history-entry.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-normal);color:var(--mrd-color-neutral-700);padding:var(--mrd-space-2) var(--mrd-space-3);line-height:var(--mrd-line-height-normal)}.mrd-layout-section__history-entry.sc-mrd-layout-section:not(:last-child){border-bottom:var(--mrd-border-width) solid var(--mrd-color-neutral-100)}.mrd-layout-section__field-header.sc-mrd-layout-section{font-size:var(--mrd-font-size-2xl);font-weight:var(--mrd-font-weight-bold);color:var(--mrd-color-neutral-900);margin:0 0 var(--mrd-space-4) 0;padding:0}.mrd-layout-section__header.sc-mrd-layout-section{font-size:var(--mrd-font-size-xl);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-800);margin:var(--mrd-space-4) 0 var(--mrd-space-2) 0;padding:0}.mrd-layout-section__text.sc-mrd-layout-section{font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-700);line-height:var(--mrd-line-height-relaxed);margin:var(--mrd-space-2) 0}.mrd-layout-section__navigate.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-2);padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:1px solid var(--mrd-color-neutral-300);border-radius:var(--mrd-border-radius);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-primary);cursor:pointer;margin:var(--mrd-space-2) 0}.mrd-layout-section__navigate.sc-mrd-layout-section:hover{background-color:var(--mrd-color-primary-light);border-color:var(--mrd-color-primary)}.mrd-layout-section__link.sc-mrd-layout-section{color:var(--mrd-color-primary);text-decoration:none}.mrd-layout-section__link.sc-mrd-layout-section:hover{text-decoration:underline}.mrd-layout-section__relation-link.sc-mrd-layout-section{background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-primary);cursor:pointer;text-align:left}.mrd-layout-section__relation-link.sc-mrd-layout-section:hover{text-decoration:underline}.mrd-layout-section__download-link.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-1);background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-primary);cursor:pointer;text-align:left}.mrd-layout-section__download-link.sc-mrd-layout-section:hover{text-decoration:underline;color:var(--mrd-color-primary-dark)}.mrd-layout-section__file-icon.sc-mrd-layout-section{flex-shrink:0;width:1rem;height:1rem}.mrd-layout-section__boolean--true.sc-mrd-layout-section{color:var(--mrd-color-success);font-weight:var(--mrd-font-weight-semibold)}.mrd-layout-section__boolean--false.sc-mrd-layout-section{color:var(--mrd-color-neutral-400)}.mrd-layout-section__field--block.sc-mrd-layout-section{grid-template-columns:1fr}.mrd-layout-section__badge.sc-mrd-layout-section{display:inline-block;font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium);padding:2px var(--mrd-space-3);border-radius:10px}.mrd-layout-section__badge-dot-row.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-2)}.mrd-layout-section__badge-dot.sc-mrd-layout-section{display:inline-block;width:10px;height:10px;border-radius:50%;flex-shrink:0}.mrd-layout-section__secret-masked.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-label-color);letter-spacing:0.15em;user-select:none;pointer-events:none}.mrd-layout-section__pre.sc-mrd-layout-section{font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);background-color:var(--mrd-color-neutral-50);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-border-radius);padding:var(--mrd-space-3);margin:0;max-height:calc(10 * 1.5 * var(--mrd-font-size-xs));overflow-x:auto;overflow-y:auto;white-space:pre-wrap;word-break:break-word}.mrd-layout-section__group.sc-mrd-layout-section{margin:var(--mrd-space-4) 0}.mrd-layout-section__group-title.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-500);margin:0 0 var(--mrd-space-2) 0;padding-bottom:0;letter-spacing:0.01em}.mrd-layout-section__related-view.sc-mrd-layout-section{margin:var(--mrd-space-4) 0}.mrd-layout-section__related-view-title.sc-mrd-layout-section{font-size:var(--mrd-font-size-lg);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-800);margin:0 0 var(--mrd-space-3) 0}.mrd-layout-section__search.sc-mrd-layout-section{position:relative;margin:var(--mrd-space-2) 0}.mrd-layout-section__search-wrap.sc-mrd-layout-section{position:relative}.mrd-layout-section__search-icon.sc-mrd-layout-section{position:absolute;left:var(--mrd-input-padding-x);top:50%;transform:translateY(-50%);width:1rem;height:1rem;color:var(--mrd-color-neutral-400);pointer-events:none}.mrd-layout-section__search-input.sc-mrd-layout-section{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x) var(--mrd-input-padding-y) calc(var(--mrd-input-padding-x) + 1rem + var(--mrd-space-2));font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);outline:none;appearance:none;box-sizing:border-box}.mrd-layout-section__search-input.sc-mrd-layout-section:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-layout-section__search-input.sc-mrd-layout-section::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-layout-section__search-results.sc-mrd-layout-section{position:absolute;top:100%;left:0;right:0;background-color:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-300);border-top:none;border-radius:0 0 var(--mrd-border-radius) var(--mrd-border-radius);box-shadow:var(--mrd-shadow-sm);z-index:100;max-height:300px;overflow-y:auto;list-style:none;margin:0;padding:var(--mrd-space-1) 0}.mrd-layout-section__search-result.sc-mrd-layout-section{margin:0;padding:0}.mrd-layout-section__search-result-btn.sc-mrd-layout-section{display:flex;flex-direction:column;width:100%;padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:none;text-align:left;cursor:pointer;font-family:var(--mrd-font-family)}.mrd-layout-section__search-result-btn.sc-mrd-layout-section:hover{background-color:var(--mrd-color-primary-light)}.mrd-layout-section__search-result-label.sc-mrd-layout-section{font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800)}.mrd-layout-section__search-result-desc.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);margin-top:var(--mrd-space-1)}.mrd-layout-section__image-thumb-btn.sc-mrd-layout-section{background:none;border:none;padding:0;cursor:pointer;display:inline-block;border-radius:var(--mrd-border-radius);overflow:hidden;line-height:0}.mrd-layout-section__image-thumb-btn.sc-mrd-layout-section:hover .mrd-layout-section__image-thumb.sc-mrd-layout-section{opacity:0.85}.mrd-layout-section__image-thumb.sc-mrd-layout-section{display:block;max-width:160px;max-height:100px;border-radius:var(--mrd-border-radius);object-fit:cover;transition:opacity 0.15s}.mrd-layout-section__modal-backdrop.sc-mrd-layout-section{position:fixed;inset:0;background:rgba(0, 0, 0, 0.6);z-index:300;display:flex;align-items:center;justify-content:center}.mrd-layout-section__modal.sc-mrd-layout-section{position:relative;background:#fff;border-radius:var(--mrd-border-radius);padding:var(--mrd-space-3);max-width:min(90vw, 900px);max-height:90vh;display:flex;align-items:center;justify-content:center;box-shadow:var(--mrd-shadow-lg)}.mrd-layout-section__modal-close.sc-mrd-layout-section{position:absolute;top:var(--mrd-space-2);right:var(--mrd-space-2);background:rgba(0, 0, 0, 0.5);border:none;border-radius:50%;width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:#fff;cursor:pointer;font-size:var(--mrd-font-size-sm);line-height:1;z-index:1}.mrd-layout-section__modal-close.sc-mrd-layout-section:hover{background:rgba(0, 0, 0, 0.8)}.mrd-layout-section__modal-image.sc-mrd-layout-section{display:block;max-width:100%;max-height:calc(90vh - 2rem);border-radius:var(--mrd-border-radius);object-fit:contain}`;
|
|
2944
|
+
/** FILE and IMAGE cells share the same download button. */
|
|
2945
|
+
function downloadLink(ctx, href, fileName, label) {
|
|
2946
|
+
return (index.h("button", { class: "mrd-layout-section__download-link", onClick: () => href && ctx.on.download({ href, fileName }) }, index.h("svg", { class: "mrd-layout-section__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, index.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" })), label));
|
|
2947
|
+
}
|
|
2948
|
+
function renderSingleFieldValue(ctx, item, value) {
|
|
2949
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
2950
|
+
const dt = item.dataType;
|
|
2951
|
+
switch (dt) {
|
|
2952
|
+
case index$1.ClientLayoutItemFieldDataType.HYPERLINK: {
|
|
2953
|
+
const v = value;
|
|
2954
|
+
const href = (_a = v === null || v === void 0 ? void 0 : v.href) !== null && _a !== void 0 ? _a : String(value);
|
|
2955
|
+
const label = (_d = (_c = (_b = v === null || v === void 0 ? void 0 : v.name) !== null && _b !== void 0 ? _b : v === null || v === void 0 ? void 0 : v.text) !== null && _c !== void 0 ? _c : v === null || v === void 0 ? void 0 : v.label) !== null && _d !== void 0 ? _d : href;
|
|
2956
|
+
return (index.h("a", { class: "mrd-layout-section__link", href: href, target: "_blank", rel: "noopener noreferrer" }, label));
|
|
2957
|
+
}
|
|
2958
|
+
case index$1.ClientLayoutItemFieldDataType.TEXTBLOCK:
|
|
2959
|
+
return index.h("div", { class: "mrd-layout-section__prose", innerHTML: String(value) });
|
|
2960
|
+
case index$1.ClientLayoutItemFieldDataType.LONGTEXT:
|
|
2961
|
+
return index.h("pre", { class: "mrd-layout-section__pre" }, String(value));
|
|
2962
|
+
case index$1.ClientLayoutItemFieldDataType.JSON:
|
|
2963
|
+
return index.h("pre", { class: "mrd-layout-section__pre", innerHTML: CellRenderer.formatJson(value) });
|
|
2964
|
+
case index$1.ClientLayoutItemFieldDataType.FILE: {
|
|
2965
|
+
const v = value;
|
|
2966
|
+
const fileName = (_e = v === null || v === void 0 ? void 0 : v.fileName) !== null && _e !== void 0 ? _e : String(value);
|
|
2967
|
+
const href = (_f = v === null || v === void 0 ? void 0 : v.href) !== null && _f !== void 0 ? _f : '';
|
|
2968
|
+
return downloadLink(ctx, href, fileName, t('download', ctx.locale));
|
|
2969
|
+
}
|
|
2970
|
+
case index$1.ClientLayoutItemFieldDataType.IMAGE: {
|
|
2971
|
+
const v = value;
|
|
2972
|
+
const href = (_g = v === null || v === void 0 ? void 0 : v.href) !== null && _g !== void 0 ? _g : '';
|
|
2973
|
+
const fileName = (_h = v === null || v === void 0 ? void 0 : v.fileName) !== null && _h !== void 0 ? _h : '';
|
|
2974
|
+
const previewUrl = ctx.imagePreviews[item.name];
|
|
2975
|
+
if (previewUrl) {
|
|
2976
|
+
return (index.h("button", { class: "mrd-layout-section__image-thumb-btn", onClick: () => ctx.on.openImage(previewUrl), title: fileName || undefined }, index.h("img", { class: "mrd-layout-section__image-thumb", src: previewUrl, alt: fileName })));
|
|
2977
|
+
}
|
|
2978
|
+
return downloadLink(ctx, href, fileName, fileName || href);
|
|
2979
|
+
}
|
|
2980
|
+
case index$1.ClientLayoutItemFieldDataType.BOOLEAN:
|
|
2981
|
+
return (index.h("span", { class: `mrd-layout-section__boolean mrd-layout-section__boolean--${value ? 'true' : 'false'}` }, value ? t('yes', ctx.locale) : t('no', ctx.locale)));
|
|
2982
|
+
case index$1.ClientLayoutItemFieldDataType.LIST: {
|
|
2983
|
+
const listItem = ((_j = item.listItems) !== null && _j !== void 0 ? _j : []).find(li => li.key === String(value));
|
|
2984
|
+
const label = (_k = listItem === null || listItem === void 0 ? void 0 : listItem.label) !== null && _k !== void 0 ? _k : String(value);
|
|
2985
|
+
const color = listItem === null || listItem === void 0 ? void 0 : listItem.color;
|
|
2986
|
+
const bg = listItem === null || listItem === void 0 ? void 0 : listItem.backgroundColor;
|
|
2987
|
+
if (color && bg) {
|
|
2988
|
+
return (index.h("span", { class: "mrd-layout-section__badge", style: { color, backgroundColor: bg } }, label));
|
|
2989
|
+
}
|
|
2990
|
+
if (color) {
|
|
2991
|
+
return (index.h("span", { class: "mrd-layout-section__badge-dot-row" }, index.h("span", { class: "mrd-layout-section__badge-dot", style: { backgroundColor: color } }), label));
|
|
2992
|
+
}
|
|
2993
|
+
return label;
|
|
2994
|
+
}
|
|
2995
|
+
case index$1.ClientLayoutItemFieldDataType.SECRET:
|
|
2996
|
+
return value ? index.h("span", { class: "mrd-layout-section__secret-masked" }, '••••••••') : null;
|
|
2997
|
+
default: {
|
|
2998
|
+
const text = CellRenderer.renderValue(dt, value, (_l = item.listItems) !== null && _l !== void 0 ? _l : [], ctx.locale);
|
|
2999
|
+
return text || null;
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
}
|
|
3003
|
+
function renderFieldValue(ctx, item, rawValue) {
|
|
3004
|
+
if (rawValue == null || rawValue === '')
|
|
3005
|
+
return null;
|
|
3006
|
+
if (item.multiple && Array.isArray(rawValue)) {
|
|
3007
|
+
const rendered = rawValue.map(v => renderSingleFieldValue(ctx, item, v));
|
|
3008
|
+
if (rendered.every(r => typeof r === 'string' || r == null)) {
|
|
3009
|
+
return rendered.filter(Boolean).join(', ') || null;
|
|
3010
|
+
}
|
|
3011
|
+
return (index.h("span", null, rendered.map((r, i) => (index.h("span", { key: String(i) }, r, i < rendered.length - 1 ? ', ' : '')))));
|
|
3012
|
+
}
|
|
3013
|
+
return renderSingleFieldValue(ctx, item, rawValue);
|
|
3014
|
+
}
|
|
3015
|
+
function renderHistoryBadge(ctx, item, raw) {
|
|
3016
|
+
var _a, _b, _c;
|
|
3017
|
+
const hist = (_a = item.historyEnabled) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.historyEnabled;
|
|
3018
|
+
if (!hist || !item.name)
|
|
3019
|
+
return null;
|
|
3020
|
+
const history = (_c = raw === null || raw === void 0 ? void 0 : raw.history) !== null && _c !== void 0 ? _c : [];
|
|
3021
|
+
if (!history.length)
|
|
3022
|
+
return null;
|
|
3023
|
+
const sorted = [...history].sort((a, b) => b.until.localeCompare(a.until));
|
|
3024
|
+
const isOpen = ctx.openHistoryField === item.name;
|
|
3025
|
+
return (index.h("span", { class: "mrd-layout-section__history-wrap" }, index.h("button", { type: "button", class: "mrd-layout-section__history-btn", title: t('history_badge_tooltip', ctx.locale), "aria-label": t('history_badge_tooltip', ctx.locale), onClick: (e) => {
|
|
3026
|
+
e.stopPropagation();
|
|
3027
|
+
ctx.on.toggleHistory(isOpen ? null : item.name);
|
|
3028
|
+
} }, index.h("svg", { class: "mrd-layout-section__history-icon", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, index.h("path", { "fill-rule": "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm.75-13a.75.75 0 00-1.5 0v5c0 .207.085.394.22.53l2.5 2.5a.75.75 0 101.06-1.06L10.75 9.69V5z", "clip-rule": "evenodd" }))), isOpen && (index.h("div", { class: "mrd-layout-section__history-popover", role: "listbox" }, sorted.map((entry, i) => (index.h("div", { key: String(i), class: "mrd-layout-section__history-entry" }, entry.value, " (", t('history_until', ctx.locale), " ", formatDate(entry.until, ctx.locale), ")")))))));
|
|
3029
|
+
}
|
|
3030
|
+
function renderField(ctx, item) {
|
|
3031
|
+
var _a, _b;
|
|
3032
|
+
if (!item.name)
|
|
3033
|
+
return null;
|
|
3034
|
+
const raw = ctx.data[item.name];
|
|
3035
|
+
const hist = (_a = item.historyEnabled) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.historyEnabled;
|
|
3036
|
+
const rawValue = hist && raw !== null && typeof raw === 'object' && 'current' in raw
|
|
3037
|
+
? raw.current
|
|
3038
|
+
: raw;
|
|
3039
|
+
const renderedValue = renderFieldValue(ctx, item, rawValue);
|
|
3040
|
+
if (item.header) {
|
|
3041
|
+
return (index.h("h1", { class: "mrd-layout-section__field-header", key: item.name }, typeof renderedValue === 'string' ? renderedValue : rawValue != null ? String(rawValue) : item.label));
|
|
3042
|
+
}
|
|
3043
|
+
if (renderedValue == null)
|
|
3044
|
+
return null;
|
|
3045
|
+
const isBlock = item.dataType === index$1.ClientLayoutItemFieldDataType.TEXTBLOCK
|
|
3046
|
+
|| item.dataType === index$1.ClientLayoutItemFieldDataType.LONGTEXT
|
|
3047
|
+
|| item.dataType === index$1.ClientLayoutItemFieldDataType.JSON;
|
|
3048
|
+
return (index.h("div", { class: `mrd-layout-section__field${isBlock ? ' mrd-layout-section__field--block' : ''}`, key: item.name }, index.h("span", { class: "mrd-layout-section__field-label" }, item.label), index.h("span", { class: "mrd-layout-section__field-value" }, renderedValue, renderHistoryBadge(ctx, item, raw))));
|
|
3049
|
+
}
|
|
3050
|
+
|
|
3051
|
+
const mrdLayoutSectionCss = () => `.mrd-layout-section.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-800)}.mrd-layout-section__field.sc-mrd-layout-section{display:grid;grid-template-columns:200px 1fr;align-items:baseline;gap:0 var(--mrd-space-2);padding:var(--mrd-space-1) 0}.mrd-layout-section__field-label.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-normal);color:var(--mrd-color-neutral-500);padding-top:1px}.mrd-layout-section__field-value.sc-mrd-layout-section{font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800);word-break:break-word;display:inline-flex;align-items:center;gap:var(--mrd-space-1)}.mrd-layout-section__history-wrap.sc-mrd-layout-section{position:relative;display:inline-flex;align-items:center}.mrd-layout-section__history-btn.sc-mrd-layout-section{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;padding:0;background:transparent;border:none;border-radius:var(--mrd-border-radius-sm);color:var(--mrd-color-neutral-400);cursor:pointer;flex-shrink:0;transition:color var(--mrd-transition-fast), background-color var(--mrd-transition-fast)}.mrd-layout-section__history-btn.sc-mrd-layout-section:hover{color:var(--mrd-color-neutral-700);background-color:var(--mrd-color-neutral-100)}.mrd-layout-section__history-btn.sc-mrd-layout-section:focus{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-layout-section__history-icon.sc-mrd-layout-section{width:0.875rem;height:0.875rem}.mrd-layout-section__history-popover.sc-mrd-layout-section{position:absolute;top:calc(100% + 0.25rem);left:0;min-width:24rem;max-width:24rem;background-color:var(--mrd-color-white);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);box-shadow:var(--mrd-shadow-md);padding:var(--mrd-space-1) 0;z-index:var(--mrd-z-dropdown)}.mrd-layout-section__history-entry.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-normal);color:var(--mrd-color-neutral-700);padding:var(--mrd-space-2) var(--mrd-space-3);line-height:var(--mrd-line-height-normal)}.mrd-layout-section__history-entry.sc-mrd-layout-section:not(:last-child){border-bottom:var(--mrd-border-width) solid var(--mrd-color-neutral-100)}.mrd-layout-section__field-header.sc-mrd-layout-section{font-size:var(--mrd-font-size-2xl);font-weight:var(--mrd-font-weight-bold);color:var(--mrd-color-neutral-900);margin:0 0 var(--mrd-space-4) 0;padding:0}.mrd-layout-section__header.sc-mrd-layout-section{font-size:var(--mrd-font-size-xl);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-800);margin:var(--mrd-space-4) 0 var(--mrd-space-2) 0;padding:0}.mrd-layout-section__text.sc-mrd-layout-section{font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-700);line-height:var(--mrd-line-height-relaxed);margin:var(--mrd-space-2) 0}.mrd-layout-section__navigate.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-2);padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:1px solid var(--mrd-color-neutral-300);border-radius:var(--mrd-border-radius);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-primary);cursor:pointer;margin:var(--mrd-space-2) 0}.mrd-layout-section__navigate.sc-mrd-layout-section:hover{background-color:var(--mrd-color-primary-light);border-color:var(--mrd-color-primary)}.mrd-layout-section__link.sc-mrd-layout-section{color:var(--mrd-color-primary);text-decoration:none}.mrd-layout-section__link.sc-mrd-layout-section:hover{text-decoration:underline}.mrd-layout-section__relation-link.sc-mrd-layout-section{background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-primary);cursor:pointer;text-align:left}.mrd-layout-section__relation-link.sc-mrd-layout-section:hover{text-decoration:underline}.mrd-layout-section__download-link.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-1);background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-primary);cursor:pointer;text-align:left}.mrd-layout-section__download-link.sc-mrd-layout-section:hover{text-decoration:underline;color:var(--mrd-color-primary-dark)}.mrd-layout-section__file-icon.sc-mrd-layout-section{flex-shrink:0;width:1rem;height:1rem}.mrd-layout-section__boolean--true.sc-mrd-layout-section{color:var(--mrd-color-success);font-weight:var(--mrd-font-weight-semibold)}.mrd-layout-section__boolean--false.sc-mrd-layout-section{color:var(--mrd-color-neutral-400)}.mrd-layout-section__field--block.sc-mrd-layout-section{grid-template-columns:1fr}.mrd-layout-section__badge.sc-mrd-layout-section{display:inline-block;font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium);padding:2px var(--mrd-space-3);border-radius:10px}.mrd-layout-section__badge-dot-row.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-2)}.mrd-layout-section__badge-dot.sc-mrd-layout-section{display:inline-block;width:10px;height:10px;border-radius:50%;flex-shrink:0}.mrd-layout-section__secret-masked.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-label-color);letter-spacing:0.15em;user-select:none;pointer-events:none}.mrd-layout-section__pre.sc-mrd-layout-section{font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);background-color:var(--mrd-color-neutral-50);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-border-radius);padding:var(--mrd-space-3);margin:0;max-height:calc(15 * var(--mrd-font-size-xs));overflow-x:auto;overflow-y:auto;white-space:pre-wrap;word-break:break-word}.mrd-layout-section__group.sc-mrd-layout-section{margin:var(--mrd-space-4) 0}.mrd-layout-section__group-title.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-500);margin:0 0 var(--mrd-space-2) 0;padding-bottom:0;letter-spacing:0.01em}.mrd-layout-section__related-view.sc-mrd-layout-section{margin:var(--mrd-space-4) 0}.mrd-layout-section__related-view-title.sc-mrd-layout-section{font-size:var(--mrd-font-size-lg);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-800);margin:0 0 var(--mrd-space-3) 0}.mrd-layout-section__search.sc-mrd-layout-section{position:relative;margin:var(--mrd-space-2) 0}.mrd-layout-section__search-wrap.sc-mrd-layout-section{position:relative}.mrd-layout-section__search-icon.sc-mrd-layout-section{position:absolute;left:var(--mrd-input-padding-x);top:50%;transform:translateY(-50%);width:1rem;height:1rem;color:var(--mrd-color-neutral-400);pointer-events:none}.mrd-layout-section__search-input.sc-mrd-layout-section{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x) var(--mrd-input-padding-y) calc(var(--mrd-input-padding-x) + 1rem + var(--mrd-space-2));font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);outline:none;appearance:none;box-sizing:border-box}.mrd-layout-section__search-input.sc-mrd-layout-section:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-layout-section__search-input.sc-mrd-layout-section::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-layout-section__search-results.sc-mrd-layout-section{position:absolute;top:100%;left:0;right:0;background-color:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-300);border-top:none;border-radius:0 0 var(--mrd-border-radius) var(--mrd-border-radius);box-shadow:var(--mrd-shadow-sm);z-index:100;max-height:300px;overflow-y:auto;list-style:none;margin:0;padding:var(--mrd-space-1) 0}.mrd-layout-section__search-result.sc-mrd-layout-section{margin:0;padding:0}.mrd-layout-section__search-result-btn.sc-mrd-layout-section{display:flex;flex-direction:column;width:100%;padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:none;text-align:left;cursor:pointer;font-family:var(--mrd-font-family)}.mrd-layout-section__search-result-btn.sc-mrd-layout-section:hover{background-color:var(--mrd-color-primary-light)}.mrd-layout-section__search-result-label.sc-mrd-layout-section{font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800)}.mrd-layout-section__search-result-desc.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);margin-top:var(--mrd-space-1)}.mrd-layout-section__image-thumb-btn.sc-mrd-layout-section{background:none;border:none;padding:0;cursor:pointer;display:inline-block;border-radius:var(--mrd-border-radius);overflow:hidden;line-height:0}.mrd-layout-section__image-thumb-btn.sc-mrd-layout-section:hover .mrd-layout-section__image-thumb.sc-mrd-layout-section{opacity:0.85}.mrd-layout-section__image-thumb.sc-mrd-layout-section{display:block;max-width:160px;max-height:100px;border-radius:var(--mrd-border-radius);object-fit:cover;transition:opacity 0.15s}.mrd-layout-section__modal-backdrop.sc-mrd-layout-section{position:fixed;inset:0;background:rgba(0, 0, 0, 0.6);z-index:300;display:flex;align-items:center;justify-content:center}.mrd-layout-section__modal.sc-mrd-layout-section{position:relative;background:var(--mrd-color-white);border-radius:var(--mrd-border-radius);padding:var(--mrd-space-3);max-width:min(90vw, 900px);max-height:90vh;display:flex;align-items:center;justify-content:center;box-shadow:var(--mrd-shadow-lg)}.mrd-layout-section__modal-close.sc-mrd-layout-section{position:absolute;top:var(--mrd-space-2);right:var(--mrd-space-2);background:rgba(0, 0, 0, 0.5);border:none;border-radius:50%;width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:var(--mrd-color-white);cursor:pointer;font-size:var(--mrd-font-size-sm);line-height:1;z-index:1}.mrd-layout-section__modal-close.sc-mrd-layout-section:hover{background:rgba(0, 0, 0, 0.8)}.mrd-layout-section__modal-image.sc-mrd-layout-section{display:block;max-width:100%;max-height:calc(90vh - 2rem);border-radius:var(--mrd-border-radius);object-fit:contain}`;
|
|
2844
3052
|
|
|
2845
3053
|
const MrdLayoutSection = class {
|
|
2846
3054
|
constructor(hostRef) {
|
|
@@ -2922,14 +3130,8 @@ const MrdLayoutSection = class {
|
|
|
2922
3130
|
}
|
|
2923
3131
|
}
|
|
2924
3132
|
}
|
|
2925
|
-
viewKeyFor(item) {
|
|
2926
|
-
var _a, _b, _c, _d;
|
|
2927
|
-
if (item.type === index$1.ClientLayoutItemType.RELATED_VIEW)
|
|
2928
|
-
return (_b = (_a = item.relatedClass) !== null && _a !== void 0 ? _a : item.name) !== null && _b !== void 0 ? _b : '';
|
|
2929
|
-
return (_d = (_c = item.dataClass) !== null && _c !== void 0 ? _c : item.name) !== null && _d !== void 0 ? _d : '';
|
|
2930
|
-
}
|
|
2931
3133
|
emitLoadImages() {
|
|
2932
|
-
for (const item of
|
|
3134
|
+
for (const item of flattenItems(this.items)) {
|
|
2933
3135
|
if (item.type === index$1.ClientLayoutItemType.FIELD && item.dataType === index$1.ClientLayoutItemFieldDataType.IMAGE) {
|
|
2934
3136
|
const fieldName = item.name;
|
|
2935
3137
|
const raw = this.data[fieldName];
|
|
@@ -2939,15 +3141,6 @@ const MrdLayoutSection = class {
|
|
|
2939
3141
|
}
|
|
2940
3142
|
}
|
|
2941
3143
|
}
|
|
2942
|
-
flattenItems(items) {
|
|
2943
|
-
const result = [];
|
|
2944
|
-
for (const item of items) {
|
|
2945
|
-
result.push(item);
|
|
2946
|
-
if (item.items)
|
|
2947
|
-
result.push(...this.flattenItems(item.items));
|
|
2948
|
-
}
|
|
2949
|
-
return result;
|
|
2950
|
-
}
|
|
2951
3144
|
/** Inject search results. Pass dataClass to target a specific SEARCH item; omit when there is only one. */
|
|
2952
3145
|
async setSearchResults(results, dataClass) {
|
|
2953
3146
|
const key = dataClass !== null && dataClass !== void 0 ? dataClass : this.resolveSearchKey();
|
|
@@ -3013,113 +3206,26 @@ const MrdLayoutSection = class {
|
|
|
3013
3206
|
}
|
|
3014
3207
|
resolveSearchKey() {
|
|
3015
3208
|
var _a;
|
|
3016
|
-
const items =
|
|
3209
|
+
const items = flattenItems(this.items).filter(i => i.type === index$1.ClientLayoutItemType.SEARCH);
|
|
3017
3210
|
if (items.length === 1)
|
|
3018
3211
|
return (_a = items[0].dataClass) !== null && _a !== void 0 ? _a : null;
|
|
3019
3212
|
return null;
|
|
3020
3213
|
}
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
case index$1.ClientLayoutItemFieldDataType.LONGTEXT:
|
|
3034
|
-
return index.h("pre", { class: "mrd-layout-section__pre" }, String(value));
|
|
3035
|
-
case index$1.ClientLayoutItemFieldDataType.JSON:
|
|
3036
|
-
return index.h("pre", { class: "mrd-layout-section__pre", innerHTML: CellRenderer.formatJson(value) });
|
|
3037
|
-
case index$1.ClientLayoutItemFieldDataType.FILE: {
|
|
3038
|
-
const v = value;
|
|
3039
|
-
const fileName = (_e = v === null || v === void 0 ? void 0 : v.fileName) !== null && _e !== void 0 ? _e : String(value);
|
|
3040
|
-
const href = (_f = v === null || v === void 0 ? void 0 : v.href) !== null && _f !== void 0 ? _f : '';
|
|
3041
|
-
return (index.h("button", { class: "mrd-layout-section__download-link", onClick: () => href && this.mrdDownload.emit({ href, fileName }) }, index.h("svg", { class: "mrd-layout-section__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, index.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)));
|
|
3042
|
-
}
|
|
3043
|
-
case index$1.ClientLayoutItemFieldDataType.IMAGE: {
|
|
3044
|
-
const v = value;
|
|
3045
|
-
const href = (_g = v === null || v === void 0 ? void 0 : v.href) !== null && _g !== void 0 ? _g : '';
|
|
3046
|
-
const fileName = (_h = v === null || v === void 0 ? void 0 : v.fileName) !== null && _h !== void 0 ? _h : '';
|
|
3047
|
-
const previewUrl = this.imagePreviews[item.name];
|
|
3048
|
-
if (previewUrl) {
|
|
3049
|
-
return (index.h("button", { class: "mrd-layout-section__image-thumb-btn", onClick: () => { this.imagePreviewUrl = previewUrl; }, title: fileName || undefined }, index.h("img", { class: "mrd-layout-section__image-thumb", src: previewUrl, alt: fileName })));
|
|
3050
|
-
}
|
|
3051
|
-
return (index.h("button", { class: "mrd-layout-section__download-link", onClick: () => href && this.mrdDownload.emit({ href, fileName }) }, index.h("svg", { class: "mrd-layout-section__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, index.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" })), fileName || href));
|
|
3052
|
-
}
|
|
3053
|
-
case index$1.ClientLayoutItemFieldDataType.BOOLEAN:
|
|
3054
|
-
return (index.h("span", { class: `mrd-layout-section__boolean mrd-layout-section__boolean--${value ? 'true' : 'false'}` }, value ? t('yes', this.locale) : t('no', this.locale)));
|
|
3055
|
-
case index$1.ClientLayoutItemFieldDataType.LIST: {
|
|
3056
|
-
const listItem = ((_j = item.listItems) !== null && _j !== void 0 ? _j : []).find(li => li.key === String(value));
|
|
3057
|
-
const label = (_k = listItem === null || listItem === void 0 ? void 0 : listItem.label) !== null && _k !== void 0 ? _k : String(value);
|
|
3058
|
-
const color = listItem === null || listItem === void 0 ? void 0 : listItem.color;
|
|
3059
|
-
const bg = listItem === null || listItem === void 0 ? void 0 : listItem.backgroundColor;
|
|
3060
|
-
if (color && bg) {
|
|
3061
|
-
return (index.h("span", { class: "mrd-layout-section__badge", style: { color, backgroundColor: bg } }, label));
|
|
3062
|
-
}
|
|
3063
|
-
if (color) {
|
|
3064
|
-
return (index.h("span", { class: "mrd-layout-section__badge-dot-row" }, index.h("span", { class: "mrd-layout-section__badge-dot", style: { backgroundColor: color } }), label));
|
|
3065
|
-
}
|
|
3066
|
-
return label;
|
|
3067
|
-
}
|
|
3068
|
-
case index$1.ClientLayoutItemFieldDataType.SECRET:
|
|
3069
|
-
return value ? index.h("span", { class: "mrd-layout-section__secret-masked" }, '••••••••') : null;
|
|
3070
|
-
default: {
|
|
3071
|
-
const text = CellRenderer.renderValue(dt, value, (_l = item.listItems) !== null && _l !== void 0 ? _l : [], this.locale);
|
|
3072
|
-
return text || null;
|
|
3073
|
-
}
|
|
3074
|
-
}
|
|
3075
|
-
}
|
|
3076
|
-
renderFieldValue(item, rawValue) {
|
|
3077
|
-
if (rawValue == null || rawValue === '')
|
|
3078
|
-
return null;
|
|
3079
|
-
if (item.multiple && Array.isArray(rawValue)) {
|
|
3080
|
-
const rendered = rawValue.map(v => this.renderSingleFieldValue(item, v));
|
|
3081
|
-
if (rendered.every(r => typeof r === 'string' || r == null)) {
|
|
3082
|
-
return rendered.filter(Boolean).join(', ') || null;
|
|
3083
|
-
}
|
|
3084
|
-
return (index.h("span", null, rendered.map((r, i) => (index.h("span", { key: String(i) }, r, i < rendered.length - 1 ? ', ' : '')))));
|
|
3085
|
-
}
|
|
3086
|
-
return this.renderSingleFieldValue(item, rawValue);
|
|
3087
|
-
}
|
|
3088
|
-
renderHistoryBadge(item, raw) {
|
|
3089
|
-
var _a, _b, _c;
|
|
3090
|
-
const hist = (_a = item.historyEnabled) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.historyEnabled;
|
|
3091
|
-
if (!hist || !item.name)
|
|
3092
|
-
return null;
|
|
3093
|
-
const history = (_c = raw === null || raw === void 0 ? void 0 : raw.history) !== null && _c !== void 0 ? _c : [];
|
|
3094
|
-
if (!history.length)
|
|
3095
|
-
return null;
|
|
3096
|
-
const sorted = [...history].sort((a, b) => b.until.localeCompare(a.until));
|
|
3097
|
-
const isOpen = this.openHistoryField === item.name;
|
|
3098
|
-
const { locale } = this;
|
|
3099
|
-
return (index.h("span", { class: "mrd-layout-section__history-wrap" }, index.h("button", { type: "button", class: "mrd-layout-section__history-btn", title: t('history_badge_tooltip', locale), "aria-label": t('history_badge_tooltip', locale), onClick: (e) => {
|
|
3100
|
-
e.stopPropagation();
|
|
3101
|
-
this.openHistoryField = isOpen ? null : item.name;
|
|
3102
|
-
} }, index.h("svg", { class: "mrd-layout-section__history-icon", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, index.h("path", { "fill-rule": "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm.75-13a.75.75 0 00-1.5 0v5c0 .207.085.394.22.53l2.5 2.5a.75.75 0 101.06-1.06L10.75 9.69V5z", "clip-rule": "evenodd" }))), isOpen && (index.h("div", { class: "mrd-layout-section__history-popover", role: "listbox" }, sorted.map((entry, i) => (index.h("div", { key: String(i), class: "mrd-layout-section__history-entry" }, entry.value, " (", t('history_until', locale), " ", formatDate(entry.until, locale), ")")))))));
|
|
3214
|
+
fieldCtx() {
|
|
3215
|
+
return {
|
|
3216
|
+
locale: this.locale,
|
|
3217
|
+
data: this.data,
|
|
3218
|
+
imagePreviews: this.imagePreviews,
|
|
3219
|
+
openHistoryField: this.openHistoryField,
|
|
3220
|
+
on: {
|
|
3221
|
+
download: detail => this.mrdDownload.emit(detail),
|
|
3222
|
+
openImage: url => { this.imagePreviewUrl = url; },
|
|
3223
|
+
toggleHistory: fieldName => { this.openHistoryField = fieldName; },
|
|
3224
|
+
},
|
|
3225
|
+
};
|
|
3103
3226
|
}
|
|
3104
3227
|
renderField(item) {
|
|
3105
|
-
|
|
3106
|
-
if (!item.name)
|
|
3107
|
-
return null;
|
|
3108
|
-
const raw = this.data[item.name];
|
|
3109
|
-
const hist = (_a = item.historyEnabled) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.historyEnabled;
|
|
3110
|
-
const rawValue = hist && raw !== null && typeof raw === 'object' && 'current' in raw
|
|
3111
|
-
? raw.current
|
|
3112
|
-
: raw;
|
|
3113
|
-
const renderedValue = this.renderFieldValue(item, rawValue);
|
|
3114
|
-
if (item.header) {
|
|
3115
|
-
return (index.h("h1", { class: "mrd-layout-section__field-header", key: item.name }, typeof renderedValue === 'string' ? renderedValue : rawValue != null ? String(rawValue) : item.label));
|
|
3116
|
-
}
|
|
3117
|
-
if (renderedValue == null)
|
|
3118
|
-
return null;
|
|
3119
|
-
const isBlock = item.dataType === index$1.ClientLayoutItemFieldDataType.TEXTBLOCK
|
|
3120
|
-
|| item.dataType === index$1.ClientLayoutItemFieldDataType.LONGTEXT
|
|
3121
|
-
|| item.dataType === index$1.ClientLayoutItemFieldDataType.JSON;
|
|
3122
|
-
return (index.h("div", { class: `mrd-layout-section__field${isBlock ? ' mrd-layout-section__field--block' : ''}`, key: item.name }, index.h("span", { class: "mrd-layout-section__field-label" }, item.label), index.h("span", { class: "mrd-layout-section__field-value" }, renderedValue, this.renderHistoryBadge(item, raw))));
|
|
3228
|
+
return renderField(this.fieldCtx(), item);
|
|
3123
3229
|
}
|
|
3124
3230
|
renderRelation(item) {
|
|
3125
3231
|
var _a, _b, _c;
|
|
@@ -3152,7 +3258,7 @@ const MrdLayoutSection = class {
|
|
|
3152
3258
|
}
|
|
3153
3259
|
renderRelatedView(item) {
|
|
3154
3260
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
3155
|
-
const key =
|
|
3261
|
+
const key = viewKeyFor(item);
|
|
3156
3262
|
if (!key)
|
|
3157
3263
|
return null;
|
|
3158
3264
|
if (!item.view)
|
|
@@ -3167,22 +3273,11 @@ const MrdLayoutSection = class {
|
|
|
3167
3273
|
// Canonical parent href for single-container seeding: use the RELATED_VIEW's
|
|
3168
3274
|
// fromClass (base class) rather than the route class, so polymorphic subtypes
|
|
3169
3275
|
// resolve to the same container the documents actually reference.
|
|
3170
|
-
const containerHref =
|
|
3276
|
+
const containerHref = buildContainerHref(item, selfHref, parentId);
|
|
3171
3277
|
return (index.h("div", { class: "mrd-layout-section__related-view", key: `view-${key}` }, showTitle && item.label && index.h("h3", { class: "mrd-layout-section__related-view-title" }, item.label), docArchetype
|
|
3172
3278
|
? this.renderDocumentContainer(item, key, parentId, docArchetype, containerHref)
|
|
3173
3279
|
: this.renderTable(item, key, parentId)));
|
|
3174
3280
|
}
|
|
3175
|
-
/** Build the canonical parent href `/{base}/{tenant}/{fromClass}/{parentId}` from
|
|
3176
|
-
* the object's self href. Empty unless it is a RELATED_VIEW with a fromClass. */
|
|
3177
|
-
buildContainerHref(item, selfHref, parentId) {
|
|
3178
|
-
if (item.type !== index$1.ClientLayoutItemType.RELATED_VIEW || !item.fromClass || !parentId)
|
|
3179
|
-
return '';
|
|
3180
|
-
const segs = selfHref.split('/').filter(Boolean);
|
|
3181
|
-
if (segs.length < 2)
|
|
3182
|
-
return '';
|
|
3183
|
-
const [base, tenant] = segs;
|
|
3184
|
-
return `/${base}/${tenant}/${item.fromClass}/${parentId}`;
|
|
3185
|
-
}
|
|
3186
3281
|
/** Document collection view: owns the view-switch + collection actions and
|
|
3187
3282
|
* swaps between the folder tree and the flat table. Events are re-emitted to
|
|
3188
3283
|
* the host with the view key, exactly as the raw list/table events were. */
|
|
@@ -3283,7 +3378,7 @@ const MrdLayoutSection = class {
|
|
|
3283
3378
|
}
|
|
3284
3379
|
render() {
|
|
3285
3380
|
const docArchetype = index$1.resolveArchetype(this.archetypes, index$1.ARCHETYPE_DOCUMENT);
|
|
3286
|
-
return (index.h(index.Host, { key: '
|
|
3381
|
+
return (index.h(index.Host, { key: '5d778188356a25ea13d45745dc5ed573ab2b2ef0' }, index.h("div", { key: '0b673a4bcf8b36cd21662bb8a3506cc3f30edb04', class: "mrd-layout-section" }, docArchetype
|
|
3287
3382
|
? this.renderDocumentObject(docArchetype)
|
|
3288
3383
|
: this.items.map(item => this.renderItem(item))), this.renderImageModal()));
|
|
3289
3384
|
}
|
|
@@ -3294,9 +3389,9 @@ const MrdLayoutSection = class {
|
|
|
3294
3389
|
}]
|
|
3295
3390
|
}; }
|
|
3296
3391
|
};
|
|
3297
|
-
MrdLayoutSection.style =
|
|
3392
|
+
MrdLayoutSection.style = mrdLayoutSectionCss();
|
|
3298
3393
|
|
|
3299
|
-
const
|
|
3394
|
+
const mrdListFieldCss = () => `.sc-mrd-list-field-h{display:block}.mrd-list-field.sc-mrd-list-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-list-field__label.sc-mrd-list-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-list-field__label--required.sc-mrd-list-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-list-field__select.sc-mrd-list-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-list-field__select.sc-mrd-list-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-list-field__select.sc-mrd-list-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-list-field__select.sc-mrd-list-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-list-field__select--error.sc-mrd-list-field{border-color:var(--mrd-border-color-error)}.mrd-list-field__select--error.sc-mrd-list-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-list-field__select.sc-mrd-list-field{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right var(--mrd-space-3) center;padding-right:calc(var(--mrd-input-padding-x) + 1.5rem);cursor:pointer}.mrd-list-field__error.sc-mrd-list-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-list-field__checkbox-list.sc-mrd-list-field{display:flex;flex-direction:column;gap:var(--mrd-space-2);padding:var(--mrd-space-3);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);background-color:var(--mrd-input-bg)}.mrd-list-field__checkbox-list--error.sc-mrd-list-field{border-color:var(--mrd-border-color-error)}.mrd-list-field__checkbox-item.sc-mrd-list-field{display:flex;align-items:center;gap:var(--mrd-space-2);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);cursor:pointer}.mrd-list-field__checkbox-item.sc-mrd-list-field input[type=checkbox].sc-mrd-list-field{width:1rem;height:1rem;cursor:pointer;accent-color:var(--mrd-color-primary)}.mrd-list-field__color-dot.sc-mrd-list-field{display:inline-block;width:12px;height:12px;border-radius:50%;flex-shrink:0}`;
|
|
3300
3395
|
|
|
3301
3396
|
const MrdListField = class {
|
|
3302
3397
|
constructor(hostRef) {
|
|
@@ -3319,22 +3414,12 @@ const MrdListField = class {
|
|
|
3319
3414
|
if (this.multiple) {
|
|
3320
3415
|
const vals = Array.from(select.selectedOptions).map(o => o.value);
|
|
3321
3416
|
this.selected = vals;
|
|
3322
|
-
|
|
3323
|
-
this.error = t('required', this.locale);
|
|
3324
|
-
}
|
|
3325
|
-
else {
|
|
3326
|
-
this.error = '';
|
|
3327
|
-
}
|
|
3417
|
+
this.error = requiredError(vals, this.required, this.locale);
|
|
3328
3418
|
this.mrdChange.emit({ name: this.name, value: vals });
|
|
3329
3419
|
}
|
|
3330
3420
|
else {
|
|
3331
3421
|
const val = select.value;
|
|
3332
|
-
|
|
3333
|
-
this.error = t('required', this.locale);
|
|
3334
|
-
}
|
|
3335
|
-
else {
|
|
3336
|
-
this.error = '';
|
|
3337
|
-
}
|
|
3422
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
3338
3423
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
3339
3424
|
}
|
|
3340
3425
|
};
|
|
@@ -3349,12 +3434,7 @@ const MrdListField = class {
|
|
|
3349
3434
|
else {
|
|
3350
3435
|
this.selected = [...this.selected, key];
|
|
3351
3436
|
}
|
|
3352
|
-
|
|
3353
|
-
this.error = t('required', this.locale);
|
|
3354
|
-
}
|
|
3355
|
-
else {
|
|
3356
|
-
this.error = '';
|
|
3357
|
-
}
|
|
3437
|
+
this.error = requiredError(this.selected, this.required, this.locale);
|
|
3358
3438
|
this.mrdChange.emit({ name: this.name, value: this.selected });
|
|
3359
3439
|
};
|
|
3360
3440
|
}
|
|
@@ -3378,22 +3458,22 @@ const MrdListField = class {
|
|
|
3378
3458
|
const hasError = !!this.error;
|
|
3379
3459
|
const currentValue = Array.isArray(this.value) ? ((_a = this.value[0]) !== null && _a !== void 0 ? _a : '') : ((_b = this.value) !== null && _b !== void 0 ? _b : '');
|
|
3380
3460
|
if (this.multiple) {
|
|
3381
|
-
return (index.h(index.Host, null, index.h("div", { class: "mrd-list-field" },
|
|
3461
|
+
return (index.h(index.Host, null, index.h("div", { class: "mrd-list-field" }, index.h(FieldLabel, { base: "mrd-list-field", label: this.label, required: this.required }), index.h("div", { class: controlClass('mrd-list-field', hasError, 'checkbox-list') }, this.listItems.map(lv => {
|
|
3382
3462
|
var _a, _b;
|
|
3383
3463
|
return (index.h("label", { key: lv.key, class: "mrd-list-field__checkbox-item" }, index.h("input", { type: "checkbox", checked: this.selected.includes(lv.key), disabled: this.disabled, onChange: () => this.toggleCheckbox(lv.key) }), (lv.color || lv.backgroundColor) && (index.h("span", { class: "mrd-list-field__color-dot", style: { backgroundColor: (_b = (_a = lv.backgroundColor) !== null && _a !== void 0 ? _a : lv.color) !== null && _b !== void 0 ? _b : '' } })), index.h("span", null, lv.label)));
|
|
3384
|
-
})),
|
|
3464
|
+
})), index.h(FieldError, { base: "mrd-list-field", error: this.error }))));
|
|
3385
3465
|
}
|
|
3386
|
-
return (index.h(index.Host, null, index.h("div", { class: "mrd-list-field" },
|
|
3466
|
+
return (index.h(index.Host, null, index.h("div", { class: "mrd-list-field" }, index.h(FieldLabel, { base: "mrd-list-field", label: this.label, required: this.required }), index.h("select", { class: controlClass('mrd-list-field', hasError, 'select'), name: this.name, required: this.required, disabled: this.disabled, onChange: this.handleSelectChange, onBlur: this.handleBlur }, index.h("option", { value: "" }, t('select_placeholder', this.locale)), this.listItems.map(lv => {
|
|
3387
3467
|
var _a, _b;
|
|
3388
3468
|
const bg = (_b = (_a = lv.backgroundColor) !== null && _a !== void 0 ? _a : lv.color) !== null && _b !== void 0 ? _b : null;
|
|
3389
3469
|
const style = bg ? { backgroundColor: bg, color: this.getContrastColor(bg) } : {};
|
|
3390
3470
|
return (index.h("option", { key: lv.key, value: lv.key, selected: lv.key === currentValue, style: style }, lv.label));
|
|
3391
|
-
})),
|
|
3471
|
+
})), index.h(FieldError, { base: "mrd-list-field", error: this.error }))));
|
|
3392
3472
|
}
|
|
3393
3473
|
};
|
|
3394
|
-
MrdListField.style =
|
|
3474
|
+
MrdListField.style = mrdListFieldCss();
|
|
3395
3475
|
|
|
3396
|
-
const
|
|
3476
|
+
const mrdLongtextFieldCss = () => `.sc-mrd-longtext-field-h{display:block}.mrd-longtext-field.sc-mrd-longtext-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-longtext-field__label.sc-mrd-longtext-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-longtext-field__label--required.sc-mrd-longtext-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-longtext-field__input.sc-mrd-longtext-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-longtext-field__input.sc-mrd-longtext-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-longtext-field__input.sc-mrd-longtext-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-longtext-field__input.sc-mrd-longtext-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-longtext-field__input--error.sc-mrd-longtext-field{border-color:var(--mrd-border-color-error)}.mrd-longtext-field__input--error.sc-mrd-longtext-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-longtext-field__error.sc-mrd-longtext-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-longtext-field__input.sc-mrd-longtext-field{height:auto;min-height:calc(var(--mrd-input-height) * 5);resize:vertical;line-height:1.5}.mrd-longtext-field__content.sc-mrd-longtext-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);white-space:pre-wrap;word-break:break-word;margin:0;padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);background-color:var(--mrd-input-bg-disabled);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);line-height:1.5}`;
|
|
3397
3477
|
|
|
3398
3478
|
const MrdLongtextField = class {
|
|
3399
3479
|
constructor(hostRef) {
|
|
@@ -3414,23 +3494,17 @@ const MrdLongtextField = class {
|
|
|
3414
3494
|
};
|
|
3415
3495
|
this.handleBlur = (e) => {
|
|
3416
3496
|
const val = e.target.value;
|
|
3417
|
-
|
|
3418
|
-
this.error = t('required', this.locale);
|
|
3419
|
-
}
|
|
3420
|
-
else {
|
|
3421
|
-
this.error = '';
|
|
3422
|
-
}
|
|
3497
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
3423
3498
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
3424
3499
|
};
|
|
3425
3500
|
}
|
|
3426
3501
|
render() {
|
|
3427
|
-
|
|
3428
|
-
return (index.h(index.Host, { key: 'f00f81944748f8f09e22d44befe5e288456b7cc8' }, index.h("div", { key: '7b0ae9cf5b6b684cddb648fe4db6005494322535', class: "mrd-longtext-field" }, this.label && (index.h("label", { key: '3fc6a8710d0e98fe685c45d214a88ae1b0947973', class: `mrd-longtext-field__label${this.required ? ' mrd-longtext-field__label--required' : ''}` }, this.label)), this.disabled ? (index.h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (index.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 && index.h("span", { key: 'e96f1dbc6c00a1602f4ce3c97d514a229aeb7cb7', class: "mrd-longtext-field__error" }, this.error))));
|
|
3502
|
+
return (index.h(index.Host, { key: '1d23db1324fa0fc97a07fdae65f2d84e43419a72' }, index.h("div", { key: '0ad2b262088aa3745f088a44af26649593805840', class: "mrd-longtext-field" }, index.h(FieldLabel, { key: '5a78739d6ced4e2df77589b64c66401819c4b5c7', base: "mrd-longtext-field", label: this.label, required: this.required }), this.disabled ? (index.h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (index.h("textarea", { class: controlClass('mrd-longtext-field', !!this.error), name: this.name, placeholder: this.placeholder, required: this.required, rows: 10, onInput: this.handleInput, onBlur: this.handleBlur }, this.value)), index.h(FieldError, { key: '5b870a75b518e2808518b83c9abebf8589a86108', base: "mrd-longtext-field", error: this.error }))));
|
|
3429
3503
|
}
|
|
3430
3504
|
};
|
|
3431
|
-
MrdLongtextField.style =
|
|
3505
|
+
MrdLongtextField.style = mrdLongtextFieldCss();
|
|
3432
3506
|
|
|
3433
|
-
const
|
|
3507
|
+
const mrdNumberFieldCss = () => `.sc-mrd-number-field-h{display:block}.mrd-number-field.sc-mrd-number-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-number-field__label.sc-mrd-number-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-number-field__label--required.sc-mrd-number-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-number-field__input-wrapper.sc-mrd-number-field{position:relative;display:flex;align-items:center}.mrd-number-field__input.sc-mrd-number-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-number-field__input.sc-mrd-number-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-number-field__input.sc-mrd-number-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-number-field__input.sc-mrd-number-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-number-field__input--error.sc-mrd-number-field{border-color:var(--mrd-border-color-error)}.mrd-number-field__input--error.sc-mrd-number-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-number-field__input.sc-mrd-number-field{text-align:right}.mrd-number-field__input.sc-mrd-number-field::placeholder{text-align:left}.mrd-number-field__error.sc-mrd-number-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}`;
|
|
3434
3508
|
|
|
3435
3509
|
const MrdNumberField = class {
|
|
3436
3510
|
constructor(hostRef) {
|
|
@@ -3501,12 +3575,12 @@ const MrdNumberField = class {
|
|
|
3501
3575
|
const hasError = !!this.error;
|
|
3502
3576
|
const suffix = this.dataType === index$1.ClientLayoutItemFieldDataType.PERCENTAGE ? '%' :
|
|
3503
3577
|
this.dataType === index$1.ClientLayoutItemFieldDataType.DECIMAL ? '' : '';
|
|
3504
|
-
return (index.h(index.Host, { key: '
|
|
3578
|
+
return (index.h(index.Host, { key: 'fd7220e0a7f574ab0c61094a9ba7fd764e1adafd' }, index.h("div", { key: 'ef6118a339c9766f187cd2b1fa3fcc85ef8cb69f', class: "mrd-number-field" }, index.h(FieldLabel, { key: '015207ae65df07f7ee7bbc24ccab45524176dbf7', base: "mrd-number-field", label: this.label, required: this.required }), index.h("div", { key: '954b99cbcf4002b0336810e354f1a46d39cb8076', class: "mrd-number-field__input-wrapper" }, index.h("input", { key: 'dddc08e090b200736d186960db1436e44f42703c', class: controlClass('mrd-number-field', hasError), 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 })), index.h(FieldError, { key: '87e12bd737aed0a845470cef66d7a6d61d11de0b', base: "mrd-number-field", error: this.error }))));
|
|
3505
3579
|
}
|
|
3506
3580
|
};
|
|
3507
|
-
MrdNumberField.style =
|
|
3581
|
+
MrdNumberField.style = mrdNumberFieldCss();
|
|
3508
3582
|
|
|
3509
|
-
const
|
|
3583
|
+
const mrdRelationFieldCss = () => `.sc-mrd-relation-field-h{display:block}.mrd-relation-field.sc-mrd-relation-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%;position:relative}.mrd-relation-field__label.sc-mrd-relation-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-relation-field__label--required.sc-mrd-relation-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-relation-field__select.sc-mrd-relation-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-relation-field__select.sc-mrd-relation-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-relation-field__select.sc-mrd-relation-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-relation-field__select.sc-mrd-relation-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-relation-field__select--error.sc-mrd-relation-field{border-color:var(--mrd-border-color-error)}.mrd-relation-field__select--error.sc-mrd-relation-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-relation-field__select.sc-mrd-relation-field{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right var(--mrd-space-3) center;padding-right:calc(var(--mrd-input-padding-x) + 1.5rem);cursor:pointer}.mrd-relation-field__search.sc-mrd-relation-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-relation-field__search.sc-mrd-relation-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-relation-field__search.sc-mrd-relation-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-relation-field__search.sc-mrd-relation-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-relation-field__search--error.sc-mrd-relation-field{border-color:var(--mrd-border-color-error)}.mrd-relation-field__search--error.sc-mrd-relation-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-relation-field__error.sc-mrd-relation-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-relation-field__tags.sc-mrd-relation-field{display:flex;flex-wrap:wrap;gap:var(--mrd-space-1);margin-bottom:var(--mrd-space-1)}.mrd-relation-field__tag.sc-mrd-relation-field{display:inline-flex;align-items:center;gap:var(--mrd-space-1);padding:var(--mrd-space-1) var(--mrd-space-2);background-color:var(--mrd-color-primary-light);color:var(--mrd-color-primary-dark);border-radius:var(--mrd-border-radius-full);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium)}.mrd-relation-field__tag-remove.sc-mrd-relation-field{background:none;border:none;cursor:pointer;color:var(--mrd-color-primary-dark);font-size:var(--mrd-font-size-xs);padding:0;line-height:1;opacity:0.7}.mrd-relation-field__tag-remove.sc-mrd-relation-field:hover{opacity:1}.mrd-relation-field__search-wrapper.sc-mrd-relation-field{position:relative;display:flex;align-items:center}.mrd-relation-field__spinner.sc-mrd-relation-field{position:absolute;right:var(--mrd-space-3);width:16px;height:16px;border:2px solid var(--mrd-color-neutral-200);border-top-color:var(--mrd-color-primary);border-radius:50%;animation:mrd-spin 0.7s linear infinite}@keyframes mrd-spin{to{transform:rotate(360deg)}}.mrd-relation-field__results.sc-mrd-relation-field{position:absolute;top:calc(100% + var(--mrd-space-1));left:0;right:0;background-color:var(--mrd-color-white);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);box-shadow:var(--mrd-shadow-md);z-index:var(--mrd-z-dropdown);max-height:240px;overflow-y:auto}.mrd-relation-field__result-item.sc-mrd-relation-field{display:flex;flex-direction:column;padding:var(--mrd-space-2) var(--mrd-space-3);cursor:pointer;transition:background-color var(--mrd-transition-fast)}.mrd-relation-field__result-item.sc-mrd-relation-field:hover{background-color:var(--mrd-color-neutral-50)}.mrd-relation-field__result-item.sc-mrd-relation-field:not(:last-child){border-bottom:var(--mrd-border-width) solid var(--mrd-color-neutral-100)}.mrd-relation-field__result-label.sc-mrd-relation-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-800);font-weight:var(--mrd-font-weight-medium)}.mrd-relation-field__result-desc.sc-mrd-relation-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);margin-top:var(--mrd-space-1)}.mrd-relation-field__result-item--highlighted.sc-mrd-relation-field{background-color:var(--mrd-color-primary-light)}.mrd-relation-field__selected-value.sc-mrd-relation-field{display:flex;align-items:center;gap:var(--mrd-space-2);height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);background-color:var(--mrd-color-primary-light);border:var(--mrd-border-width) solid var(--mrd-color-primary);border-radius:var(--mrd-border-radius);box-sizing:border-box}.mrd-relation-field__selected-value--error.sc-mrd-relation-field{border-color:var(--mrd-border-color-error);background-color:var(--mrd-color-danger-light)}.mrd-relation-field__selected-name.sc-mrd-relation-field{flex:1;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-primary-dark);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mrd-relation-field__selected-clear.sc-mrd-relation-field{flex-shrink:0;background:none;border:none;cursor:pointer;color:var(--mrd-color-primary-dark);font-size:var(--mrd-font-size-sm);padding:0;line-height:1;opacity:0.6;transition:opacity var(--mrd-transition-fast)}.mrd-relation-field__selected-clear.sc-mrd-relation-field:hover{opacity:1}.mrd-relation-field__no-results.sc-mrd-relation-field{padding:var(--mrd-space-4);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-500);text-align:center}`;
|
|
3510
3584
|
|
|
3511
3585
|
const MrdRelationField = class {
|
|
3512
3586
|
constructor(hostRef) {
|
|
@@ -3607,12 +3681,7 @@ const MrdRelationField = class {
|
|
|
3607
3681
|
this.showResults = false;
|
|
3608
3682
|
this.mrdChange.emit({ name: this.name, value: result.id });
|
|
3609
3683
|
}
|
|
3610
|
-
|
|
3611
|
-
this.error = t('required', this.locale);
|
|
3612
|
-
}
|
|
3613
|
-
else {
|
|
3614
|
-
this.error = '';
|
|
3615
|
-
}
|
|
3684
|
+
this.error = requiredError(this.selectedItems, this.required, this.locale);
|
|
3616
3685
|
};
|
|
3617
3686
|
this.handleRemoveSelected = (id) => {
|
|
3618
3687
|
this.selectedItems = this.selectedItems.filter(i => i.id !== id);
|
|
@@ -3621,12 +3690,7 @@ const MrdRelationField = class {
|
|
|
3621
3690
|
};
|
|
3622
3691
|
this.handleDropdownChange = (e) => {
|
|
3623
3692
|
const val = e.target.value;
|
|
3624
|
-
|
|
3625
|
-
this.error = t('required', this.locale);
|
|
3626
|
-
}
|
|
3627
|
-
else {
|
|
3628
|
-
this.error = '';
|
|
3629
|
-
}
|
|
3693
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
3630
3694
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
3631
3695
|
};
|
|
3632
3696
|
this.handleBlur = () => {
|
|
@@ -3737,19 +3801,19 @@ const MrdRelationField = class {
|
|
|
3737
3801
|
const hasError = !!this.error;
|
|
3738
3802
|
if (this.editBehavior === index$1.ClientLayoutItemRelationEditBehavior.DROPDOWN) {
|
|
3739
3803
|
const currentValue = this.getValueHref();
|
|
3740
|
-
return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" },
|
|
3804
|
+
return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, index.h(FieldLabel, { base: "mrd-relation-field", label: this.label, required: this.required }), index.h("select", { class: controlClass('mrd-relation-field', hasError, 'select'), name: this.name, required: this.required, disabled: this.disabled, onChange: this.handleDropdownChange }, index.h("option", { value: "" }, t('select_placeholder', this.locale)), this.allRecords.map(record => (index.h("option", { key: record.id, value: record.id, selected: record.id === currentValue }, record.label)))), index.h(FieldError, { base: "mrd-relation-field", error: this.error }))));
|
|
3741
3805
|
}
|
|
3742
3806
|
if (this.displayType === index$1.ClientLayoutItemRelationDisplayType.DROPDOWN) {
|
|
3743
3807
|
const currentValue = Array.isArray(this.value) ? ((_a = this.value[0]) !== null && _a !== void 0 ? _a : '') : ((_b = this.value) !== null && _b !== void 0 ? _b : '');
|
|
3744
|
-
return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" },
|
|
3808
|
+
return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, index.h(FieldLabel, { base: "mrd-relation-field", label: this.label, required: this.required }), index.h("select", { class: controlClass('mrd-relation-field', hasError, 'select'), name: this.name, required: this.required, disabled: this.disabled, onChange: this.handleDropdownChange }, index.h("option", { value: "" }, t('select_placeholder', this.locale)), this.dropdownValues.map(dv => (index.h("option", { key: dv.key, value: dv.key, selected: dv.key === currentValue }, dv.label)))), index.h(FieldError, { base: "mrd-relation-field", error: this.error }))));
|
|
3745
3809
|
}
|
|
3746
3810
|
// SEARCH mode
|
|
3747
|
-
const labelEl =
|
|
3811
|
+
const labelEl = index.h(FieldLabel, { base: "mrd-relation-field", label: this.label, required: this.required });
|
|
3748
3812
|
// Single selection: show selected value as a badge, hide the search input
|
|
3749
3813
|
if (!this.multiple && this.selectedItems.length > 0) {
|
|
3750
|
-
return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, labelEl, index.h("div", { class: `mrd-relation-field__selected-value${hasError ? ' mrd-relation-field__selected-value--error' : ''}` }, index.h("span", { class: "mrd-relation-field__selected-name" }, this.selectedItems[0].label), index.h("button", { type: "button", class: "mrd-relation-field__selected-clear", onClick: this.clearSelection, "aria-label": t('remove', this.locale) }, "\u2715")),
|
|
3814
|
+
return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, labelEl, index.h("div", { class: `mrd-relation-field__selected-value${hasError ? ' mrd-relation-field__selected-value--error' : ''}` }, index.h("span", { class: "mrd-relation-field__selected-name" }, this.selectedItems[0].label), index.h("button", { type: "button", class: "mrd-relation-field__selected-clear", onClick: this.clearSelection, "aria-label": t('remove', this.locale) }, "\u2715")), index.h(FieldError, { base: "mrd-relation-field", error: this.error }))));
|
|
3751
3815
|
}
|
|
3752
|
-
return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, labelEl, this.multiple && this.selectedItems.length > 0 && (index.h("div", { class: "mrd-relation-field__tags" }, this.selectedItems.map(item => (index.h("span", { key: item.id, class: "mrd-relation-field__tag" }, item.label, index.h("button", { type: "button", class: "mrd-relation-field__tag-remove", onClick: () => this.handleRemoveSelected(item.id), "aria-label": t('remove', this.locale) }, "\u2715")))))), index.h("div", { class: "mrd-relation-field__search-wrapper" }, index.h("input", { class: `mrd-relation-field__search${hasError ? ' mrd-relation-field__search--error' : ''}`, type: "text", value: this.searchQuery, placeholder: t('search_placeholder', this.locale), disabled: this.disabled, onInput: this.handleSearchInput, onKeyDown: this.handleKeyDown, onBlur: this.handleBlur }), this.isLoading && (index.h("span", { class: "mrd-relation-field__spinner", "aria-label": t('loading', this.locale) }))), this.showResults && (index.h("div", { class: "mrd-relation-field__results" }, this.searchResults.length === 0 && !this.isLoading ? (index.h("div", { class: "mrd-relation-field__no-results" }, t('no_results', this.locale))) : (this.searchResults.map((result, i) => (index.h("div", { key: result.id, class: `mrd-relation-field__result-item${i === this.highlightedIndex ? ' mrd-relation-field__result-item--highlighted' : ''}`, onMouseDown: () => this.handleResultSelect(result) }, index.h("span", { class: "mrd-relation-field__result-label" }, result.label), result.description && (index.h("span", { class: "mrd-relation-field__result-desc" }, result.description)))))))),
|
|
3816
|
+
return (index.h(index.Host, null, index.h("div", { class: "mrd-relation-field" }, labelEl, this.multiple && this.selectedItems.length > 0 && (index.h("div", { class: "mrd-relation-field__tags" }, this.selectedItems.map(item => (index.h("span", { key: item.id, class: "mrd-relation-field__tag" }, item.label, index.h("button", { type: "button", class: "mrd-relation-field__tag-remove", onClick: () => this.handleRemoveSelected(item.id), "aria-label": t('remove', this.locale) }, "\u2715")))))), index.h("div", { class: "mrd-relation-field__search-wrapper" }, index.h("input", { class: `mrd-relation-field__search${hasError ? ' mrd-relation-field__search--error' : ''}`, type: "text", value: this.searchQuery, placeholder: t('search_placeholder', this.locale), disabled: this.disabled, onInput: this.handleSearchInput, onKeyDown: this.handleKeyDown, onBlur: this.handleBlur }), this.isLoading && (index.h("span", { class: "mrd-relation-field__spinner", "aria-label": t('loading', this.locale) }))), this.showResults && (index.h("div", { class: "mrd-relation-field__results" }, this.searchResults.length === 0 && !this.isLoading ? (index.h("div", { class: "mrd-relation-field__no-results" }, t('no_results', this.locale))) : (this.searchResults.map((result, i) => (index.h("div", { key: result.id, class: `mrd-relation-field__result-item${i === this.highlightedIndex ? ' mrd-relation-field__result-item--highlighted' : ''}`, onMouseDown: () => this.handleResultSelect(result) }, index.h("span", { class: "mrd-relation-field__result-label" }, result.label), result.description && (index.h("span", { class: "mrd-relation-field__result-desc" }, result.description)))))))), index.h(FieldError, { base: "mrd-relation-field", error: this.error }))));
|
|
3753
3817
|
}
|
|
3754
3818
|
get el() { return index.getElement(this); }
|
|
3755
3819
|
static get watchers() { return {
|
|
@@ -3761,9 +3825,9 @@ const MrdRelationField = class {
|
|
|
3761
3825
|
}]
|
|
3762
3826
|
}; }
|
|
3763
3827
|
};
|
|
3764
|
-
MrdRelationField.style =
|
|
3828
|
+
MrdRelationField.style = mrdRelationFieldCss();
|
|
3765
3829
|
|
|
3766
|
-
const
|
|
3830
|
+
const mrdSecretFieldCss = () => `.sc-mrd-secret-field-h{display:block}.mrd-secret-field.sc-mrd-secret-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-secret-field__label.sc-mrd-secret-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-secret-field__label--required.sc-mrd-secret-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-secret-field__input.sc-mrd-secret-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-secret-field__input.sc-mrd-secret-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-secret-field__input.sc-mrd-secret-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-secret-field__input.sc-mrd-secret-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-secret-field__input--error.sc-mrd-secret-field{border-color:var(--mrd-border-color-error)}.mrd-secret-field__input--error.sc-mrd-secret-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-secret-field__error.sc-mrd-secret-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-secret-field__masked.sc-mrd-secret-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-label-color);letter-spacing:0.15em;user-select:none;pointer-events:none}`;
|
|
3767
3831
|
|
|
3768
3832
|
const MrdSecretField = class {
|
|
3769
3833
|
constructor(hostRef) {
|
|
@@ -3784,42 +3848,460 @@ const MrdSecretField = class {
|
|
|
3784
3848
|
};
|
|
3785
3849
|
this.handleBlur = (e) => {
|
|
3786
3850
|
const val = e.target.value;
|
|
3787
|
-
|
|
3788
|
-
this.error = t('required', this.locale);
|
|
3789
|
-
}
|
|
3790
|
-
else {
|
|
3791
|
-
this.error = '';
|
|
3792
|
-
}
|
|
3851
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
3793
3852
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
3794
3853
|
};
|
|
3795
3854
|
}
|
|
3796
3855
|
render() {
|
|
3797
|
-
|
|
3798
|
-
return (index.h(index.Host, { key: 'c850ec5bc5967ca0aefca7d7cb65ecae121a9dc1' }, index.h("div", { key: '3249ffbc441422af054a20806dd8dfce954a8ffc', class: "mrd-secret-field" }, this.label && (index.h("label", { key: '0b4a86da9cafad32f153af1bc5487a4e9b941e2f', class: `mrd-secret-field__label${this.required ? ' mrd-secret-field__label--required' : ''}` }, this.label)), this.disabled
|
|
3856
|
+
return (index.h(index.Host, { key: 'acb865b235652feba713aedda7a7fccbdc01ad20' }, index.h("div", { key: 'e7471ade9c683cac9469ec89778c967badb046f9', class: "mrd-secret-field" }, index.h(FieldLabel, { key: '2f9b864779ead352fda53af8597ddcd31377249d', base: "mrd-secret-field", label: this.label, required: this.required }), this.disabled
|
|
3799
3857
|
? (index.h("span", { class: "mrd-secret-field__masked", "aria-label": this.label }, this.value ? '••••••••' : ''))
|
|
3800
|
-
: (index.h("input", { class:
|
|
3858
|
+
: (index.h("input", { class: controlClass('mrd-secret-field', !!this.error), type: "password", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, autocomplete: "new-password", onInput: this.handleInput, onBlur: this.handleBlur })), index.h(FieldError, { key: '438418e2cf0f53a6c247d5f332aae8e8978b94ea', base: "mrd-secret-field", error: this.error }))));
|
|
3801
3859
|
}
|
|
3802
3860
|
};
|
|
3803
|
-
MrdSecretField.style =
|
|
3861
|
+
MrdSecretField.style = mrdSecretFieldCss();
|
|
3804
3862
|
|
|
3805
|
-
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__toolbar-center.sc-mrd-table{flex:1;display:flex;justify-content:center;align-items:center;gap:var(--mrd-space-1)}.mrd-table__view-switcher.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1)}.mrd-table__view-arrow.sc-mrd-table{background:none;border:none;cursor:pointer;padding:0 var(--mrd-space-1);color:var(--mrd-color-neutral-500);font-size:var(--mrd-font-size-xs);line-height:1}.mrd-table__view-arrow.sc-mrd-table:hover{color:var(--mrd-color-neutral-800)}.mrd-table__view-title-wrap.sc-mrd-table{position:relative}.mrd-table__view-title.sc-mrd-table{font-size:var(--mrd-font-size-sm);font-weight:600;color:var(--mrd-color-neutral-800);font-family:var(--mrd-font-family);background:none;border:none;outline:none;cursor:pointer;padding:0 var(--mrd-space-1);max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mrd-table__view-title.sc-mrd-table:hover{color:var(--mrd-color-primary)}.mrd-table__view-popover.sc-mrd-table{position:absolute;top:calc(100% + var(--mrd-space-1));left:50%;transform:translateX(-50%);background:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-radius-md);box-shadow:var(--mrd-shadow-md);z-index:100;min-width:160px;padding:var(--mrd-space-1) 0}.mrd-table__view-popover-item.sc-mrd-table{display:block;width:100%;text-align:left;background:none;border:none;cursor:pointer;padding:var(--mrd-space-2) var(--mrd-space-3);font-size:var(--mrd-font-size-sm);font-family:var(--mrd-font-family);color:var(--mrd-color-neutral-700);white-space:nowrap}.mrd-table__view-popover-item.sc-mrd-table:hover{background:var(--mrd-color-neutral-50)}.mrd-table__view-popover-item--active.sc-mrd-table{font-weight:600;color:var(--mrd-color-primary)}.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__create-picker-wrap.sc-mrd-table{position:relative}.mrd-table__create-picker.sc-mrd-table{position:absolute;right:0;top:calc(100% + 4px);background:var(--mrd-color-white, #fff);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, 0.12));z-index:10;min-width:10rem;padding:var(--mrd-space-1) 0}.mrd-table__create-picker-item.sc-mrd-table{display:block;width:100%;text-align:left;padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:none;cursor:pointer;font-size:var(--mrd-font-size-sm);font-family:var(--mrd-font-family);color:var(--mrd-color-neutral-800)}.mrd-table__create-picker-item.sc-mrd-table:hover{background:var(--mrd-color-neutral-50);color:var(--mrd-color-neutral-900)}.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__totals-row.sc-mrd-table{border-top:2px solid var(--mrd-border-color)}.mrd-table__totals-cell.sc-mrd-table{position:sticky;bottom:0;z-index:2;padding:var(--mrd-space-2) var(--mrd-space-4);background:var(--mrd-color-white);font-weight:var(--mrd-font-weight-medium);font-variant-numeric:tabular-nums;white-space:nowrap;border-top:2px solid var(--mrd-border-color)}.mrd-table__totals-cell--numeric.sc-mrd-table{text-align:right}.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}.mrd-table__json-preview.sc-mrd-table{font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:inline-block;max-width:calc(100% - 1.5rem);vertical-align:middle}.mrd-table__modal-json.sc-mrd-table{margin:0;padding-right:var(--mrd-space-6);font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);white-space:pre-wrap;word-break:break-word;line-height:1.6;background:none;border:none}`;
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
* aangevraagd. Pagina's die de gebruiker snel voorbij scrollt worden zo geskipt. */
|
|
3810
|
-
const REQUEST_DEBOUNCE_MS = 150;
|
|
3811
|
-
/** Breedte van de filterpopup in px — voor overflow-correctie. */
|
|
3812
|
-
const POPUP_WIDTH = 280;
|
|
3863
|
+
/**
|
|
3864
|
+
* Pure sort/filter/aggregation query logic for mrd-table.
|
|
3865
|
+
* No component state — everything is passed in.
|
|
3866
|
+
*/
|
|
3813
3867
|
const TEXT_TYPES = new Set(['TEXT', 'TEXTBLOCK', 'EMAIL', 'HYPERLINK']);
|
|
3814
3868
|
const NUMERIC_TYPES = new Set(['INTEGER', 'DECIMAL', 'PERCENTAGE', 'CURRENCY']);
|
|
3815
3869
|
const DATE_TYPES = new Set(['DATE', 'DATETIME', 'TIME']);
|
|
3816
3870
|
const NO_FILTER_TYPES = new Set(['FILE', 'IMAGE']);
|
|
3817
3871
|
/** Column types that cannot be sorted or filtered (not stored in PostgreSQL). */
|
|
3818
3872
|
const NON_INTERACTIVE_TYPES = new Set(['LONGTEXT', 'JSON', 'FILE', 'IMAGE']);
|
|
3873
|
+
function parseDefaultSort(defaultSort) {
|
|
3874
|
+
var _a;
|
|
3875
|
+
if (!defaultSort)
|
|
3876
|
+
return { field: '', dir: 'asc' };
|
|
3877
|
+
const parts = defaultSort.split(',');
|
|
3878
|
+
return { field: parts[0].trim(), dir: ((_a = parts[1]) === null || _a === void 0 ? void 0 : _a.trim()) === 'desc' ? 'desc' : 'asc' };
|
|
3879
|
+
}
|
|
3880
|
+
/** Raw sort query-param value, e.g. "name" or "name,desc". */
|
|
3881
|
+
function buildSortParam(field, dir) {
|
|
3882
|
+
if (!field)
|
|
3883
|
+
return '';
|
|
3884
|
+
return dir === 'desc' ? `${field},desc` : field;
|
|
3885
|
+
}
|
|
3886
|
+
/** Query params for a page request: page + sort + filterClass + view filters + active column filters. */
|
|
3887
|
+
function buildTableQueryParams(opts) {
|
|
3888
|
+
var _a, _b;
|
|
3889
|
+
const p = new URLSearchParams();
|
|
3890
|
+
if (opts.page > 0)
|
|
3891
|
+
p.set('page', String(opts.page));
|
|
3892
|
+
if (opts.sort)
|
|
3893
|
+
p.set('sort', opts.sort);
|
|
3894
|
+
if (opts.filterClass)
|
|
3895
|
+
p.set('type', opts.filterClass);
|
|
3896
|
+
applyViewFilters(p, opts.viewFilters);
|
|
3897
|
+
for (const f of opts.activeFilters) {
|
|
3898
|
+
if (f.operator === 'isEmpty') {
|
|
3899
|
+
p.set(f.field, '');
|
|
3900
|
+
continue;
|
|
3901
|
+
}
|
|
3902
|
+
if (f.operator === 'isNotEmpty') {
|
|
3903
|
+
p.set(f.field + '_notempty', 'true');
|
|
3904
|
+
continue;
|
|
3905
|
+
}
|
|
3906
|
+
if (f.operator === 'startsWith') {
|
|
3907
|
+
p.set(f.field + '_startswith', String((_a = f.value) !== null && _a !== void 0 ? _a : ''));
|
|
3908
|
+
continue;
|
|
3909
|
+
}
|
|
3910
|
+
if ((_b = f.values) === null || _b === void 0 ? void 0 : _b.length) {
|
|
3911
|
+
p.set(f.field, f.values.join(','));
|
|
3912
|
+
continue;
|
|
3913
|
+
}
|
|
3914
|
+
if (f.value != null)
|
|
3915
|
+
p.set(f.field, String(f.value));
|
|
3916
|
+
if (f.from != null)
|
|
3917
|
+
p.set(f.field + '_from', String(f.from));
|
|
3918
|
+
if (f.to != null)
|
|
3919
|
+
p.set(f.field + '_to', String(f.to));
|
|
3920
|
+
}
|
|
3921
|
+
return p.toString();
|
|
3922
|
+
}
|
|
3923
|
+
/** Groups aggregate columns by function; null when the view has no aggregates. */
|
|
3924
|
+
function buildAggregationParams(columns) {
|
|
3925
|
+
var _a;
|
|
3926
|
+
const groups = { sum: [], avg: [], count: [] };
|
|
3927
|
+
for (const col of columns) {
|
|
3928
|
+
if (col.type !== 'FIELD' || !col.aggregate)
|
|
3929
|
+
continue;
|
|
3930
|
+
const fn = col.aggregate.toLowerCase();
|
|
3931
|
+
if (fn in groups)
|
|
3932
|
+
groups[fn].push((_a = col.name) !== null && _a !== void 0 ? _a : '');
|
|
3933
|
+
}
|
|
3934
|
+
const params = {};
|
|
3935
|
+
if (groups.sum.length)
|
|
3936
|
+
params.sum = groups.sum;
|
|
3937
|
+
if (groups.avg.length)
|
|
3938
|
+
params.avg = groups.avg;
|
|
3939
|
+
if (groups.count.length)
|
|
3940
|
+
params.count = groups.count;
|
|
3941
|
+
return Object.keys(params).length > 0 ? params : null;
|
|
3942
|
+
}
|
|
3943
|
+
/** Aggregation query string: the page-0 query params without page/sort, plus sum/avg/count. */
|
|
3944
|
+
function buildAggregationQs(basePageQs, columns) {
|
|
3945
|
+
var _a, _b, _c;
|
|
3946
|
+
const p = new URLSearchParams(basePageQs);
|
|
3947
|
+
p.delete('page');
|
|
3948
|
+
p.delete('sort');
|
|
3949
|
+
const groups = buildAggregationParams(columns);
|
|
3950
|
+
if ((_a = groups === null || groups === void 0 ? void 0 : groups.sum) === null || _a === void 0 ? void 0 : _a.length)
|
|
3951
|
+
p.set('sum', groups.sum.join(','));
|
|
3952
|
+
if ((_b = groups === null || groups === void 0 ? void 0 : groups.avg) === null || _b === void 0 ? void 0 : _b.length)
|
|
3953
|
+
p.set('avg', groups.avg.join(','));
|
|
3954
|
+
if ((_c = groups === null || groups === void 0 ? void 0 : groups.count) === null || _c === void 0 ? void 0 : _c.length)
|
|
3955
|
+
p.set('count', groups.count.join(','));
|
|
3956
|
+
return p.toString();
|
|
3957
|
+
}
|
|
3958
|
+
/** True when the pending filter actually constrains anything. */
|
|
3959
|
+
function filterHasValue(f) {
|
|
3960
|
+
if (f.operator === 'isEmpty' || f.operator === 'isNotEmpty')
|
|
3961
|
+
return true;
|
|
3962
|
+
if (f.values !== undefined && f.values.length > 0)
|
|
3963
|
+
return true;
|
|
3964
|
+
if (f.value != null && f.value !== '')
|
|
3965
|
+
return true;
|
|
3966
|
+
if (typeof f.value === 'boolean')
|
|
3967
|
+
return true;
|
|
3968
|
+
if (f.from != null && f.from !== '')
|
|
3969
|
+
return true;
|
|
3970
|
+
if (f.to != null && f.to !== '')
|
|
3971
|
+
return true;
|
|
3972
|
+
return false;
|
|
3973
|
+
}
|
|
3974
|
+
// ── DATETIME filters: the user edits local "YYYY-MM-DD" dates, the API stores UTC ISO ──
|
|
3975
|
+
/** UTC ISO string at the start (midnight) of the given local day. */
|
|
3976
|
+
function dateLocalToUTCStart(dateStr) {
|
|
3977
|
+
if (!dateStr)
|
|
3978
|
+
return dateStr;
|
|
3979
|
+
const [year, month, day] = dateStr.split('-').map(Number);
|
|
3980
|
+
return new Date(year, month - 1, day).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
3981
|
+
}
|
|
3982
|
+
/** Start of the day AFTER the given local date (exclusive range end). */
|
|
3983
|
+
function dateLocalToUTCEndExclusive(dateStr) {
|
|
3984
|
+
if (!dateStr)
|
|
3985
|
+
return dateStr;
|
|
3986
|
+
const [year, month, day] = dateStr.split('-').map(Number);
|
|
3987
|
+
return new Date(year, month - 1, day + 1).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
3988
|
+
}
|
|
3989
|
+
/** Stored UTC ISO string back to the local "YYYY-MM-DD" date. */
|
|
3990
|
+
function utcISOToLocalDate(utcStr) {
|
|
3991
|
+
if (!utcStr)
|
|
3992
|
+
return utcStr;
|
|
3993
|
+
const d = new Date(utcStr);
|
|
3994
|
+
if (isNaN(d.getTime()))
|
|
3995
|
+
return utcStr;
|
|
3996
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
3997
|
+
}
|
|
3998
|
+
/** The stored "to" is the exclusive end (next midnight); subtract a day to recover the entered date. */
|
|
3999
|
+
function utcISOToLocalDateExclusiveEnd(utcStr) {
|
|
4000
|
+
if (!utcStr)
|
|
4001
|
+
return utcStr;
|
|
4002
|
+
const d = new Date(utcStr);
|
|
4003
|
+
if (isNaN(d.getTime()))
|
|
4004
|
+
return utcStr;
|
|
4005
|
+
d.setDate(d.getDate() - 1);
|
|
4006
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
4007
|
+
}
|
|
4008
|
+
/** Applies the local→UTC conversion when a DATETIME filter is submitted.
|
|
4009
|
+
* Exact date → range covering the full local day. */
|
|
4010
|
+
function normalizeDatetimeFilter(f) {
|
|
4011
|
+
const normalized = Object.assign({}, f);
|
|
4012
|
+
if (f.dataType === 'DATETIME' && f.operator !== 'isEmpty' && f.operator !== 'isNotEmpty') {
|
|
4013
|
+
if (typeof normalized.value === 'string' && normalized.value) {
|
|
4014
|
+
normalized.from = dateLocalToUTCStart(normalized.value);
|
|
4015
|
+
normalized.to = dateLocalToUTCEndExclusive(normalized.value);
|
|
4016
|
+
normalized.value = undefined;
|
|
4017
|
+
}
|
|
4018
|
+
else {
|
|
4019
|
+
if (typeof normalized.from === 'string' && normalized.from)
|
|
4020
|
+
normalized.from = dateLocalToUTCStart(normalized.from);
|
|
4021
|
+
if (typeof normalized.to === 'string' && normalized.to)
|
|
4022
|
+
normalized.to = dateLocalToUTCEndExclusive(normalized.to);
|
|
4023
|
+
}
|
|
4024
|
+
}
|
|
4025
|
+
return normalized;
|
|
4026
|
+
}
|
|
4027
|
+
/** Converts a stored DATETIME filter back to local dates for the popup.
|
|
4028
|
+
* A range covering a single local day is restored to exact-date mode. */
|
|
4029
|
+
function datetimeFilterToDisplay(existing) {
|
|
4030
|
+
const display = Object.assign({}, existing);
|
|
4031
|
+
if (typeof display.from === 'string' && display.from)
|
|
4032
|
+
display.from = utcISOToLocalDate(display.from);
|
|
4033
|
+
if (typeof display.to === 'string' && display.to)
|
|
4034
|
+
display.to = utcISOToLocalDateExclusiveEnd(display.to);
|
|
4035
|
+
if (display.from && display.to && display.from === display.to) {
|
|
4036
|
+
return Object.assign(Object.assign({}, display), { value: display.from, from: undefined, to: undefined });
|
|
4037
|
+
}
|
|
4038
|
+
return display;
|
|
4039
|
+
}
|
|
4040
|
+
|
|
4041
|
+
/**
|
|
4042
|
+
* Stateless render parts of mrd-table. All state and handlers stay in the
|
|
4043
|
+
* component; these components receive plain values and callbacks.
|
|
4044
|
+
*/
|
|
4045
|
+
const FilterIcon = () => (index.h("span", { class: "mrd-table__filter-icon", "aria-hidden": "true" }, index.h("svg", { viewBox: "0 0 24 24", width: "14", height: "14", fill: "currentColor" }, index.h("path", { d: "M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" }))));
|
|
4046
|
+
const TEXTBLOCK_MAX = 200;
|
|
4047
|
+
const TableCell = ({ col, row, locale, onDownload, onOpenTextblock, onOpenJson }) => {
|
|
4048
|
+
var _a, _b, _c;
|
|
4049
|
+
const dataType = (_a = col.dataType) !== null && _a !== void 0 ? _a : '';
|
|
4050
|
+
const isNumeric = col.type === 'FIELD' && NUMERIC_TYPES.has(dataType);
|
|
4051
|
+
const isFile = col.type === 'FIELD' && (dataType === 'FILE' || dataType === 'IMAGE');
|
|
4052
|
+
if (isFile) {
|
|
4053
|
+
const name = (_b = col.name) !== null && _b !== void 0 ? _b : '';
|
|
4054
|
+
const fileVal = row === null || row === void 0 ? void 0 : row[name];
|
|
4055
|
+
const href = fileVal === null || fileVal === void 0 ? void 0 : fileVal.href;
|
|
4056
|
+
const fileName = fileVal === null || fileVal === void 0 ? void 0 : fileVal.fileName;
|
|
4057
|
+
return (index.h("td", { class: "mrd-table__cell" }, href && fileName ? (index.h("button", { class: "mrd-table__file-btn", title: fileName, onClick: (e) => {
|
|
4058
|
+
e.stopPropagation();
|
|
4059
|
+
onDownload({ href, fileName });
|
|
4060
|
+
} }, index.h("svg", { class: "mrd-table__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, index.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', locale))) : ''));
|
|
4061
|
+
}
|
|
4062
|
+
if (dataType === 'JSON') {
|
|
4063
|
+
const name = (_c = col.name) !== null && _c !== void 0 ? _c : '';
|
|
4064
|
+
const rawValue = name ? row === null || row === void 0 ? void 0 : row[name] : undefined;
|
|
4065
|
+
if (rawValue == null || rawValue === '')
|
|
4066
|
+
return index.h("td", { class: "mrd-table__cell" });
|
|
4067
|
+
const compactHtml = CellRenderer.formatJson(rawValue, true);
|
|
4068
|
+
const prettyHtml = CellRenderer.formatJson(rawValue, false);
|
|
4069
|
+
return (index.h("td", { class: "mrd-table__cell" }, index.h("span", { class: "mrd-table__json-preview", innerHTML: compactHtml }), index.h("button", { class: "mrd-table__textblock-btn", onClick: (e) => { e.stopPropagation(); onOpenJson(prettyHtml); }, "aria-label": t('textblock_show_more', locale) }, "\u22EF")));
|
|
4070
|
+
}
|
|
4071
|
+
if (dataType === 'TEXTBLOCK') {
|
|
4072
|
+
const full = CellRenderer.render(col, row, locale);
|
|
4073
|
+
if (full.length <= TEXTBLOCK_MAX) {
|
|
4074
|
+
return index.h("td", { class: "mrd-table__cell" }, full);
|
|
4075
|
+
}
|
|
4076
|
+
const preview = full.slice(0, TEXTBLOCK_MAX) + '…';
|
|
4077
|
+
return (index.h("td", { class: "mrd-table__cell" }, preview, index.h("button", { class: "mrd-table__textblock-btn", onClick: (e) => { e.stopPropagation(); onOpenTextblock(full); }, "aria-label": t('textblock_show_more', locale) }, "\u22EF")));
|
|
4078
|
+
}
|
|
4079
|
+
const value = CellRenderer.render(col, row, locale);
|
|
4080
|
+
return (index.h("td", { class: `mrd-table__cell${isNumeric ? ' mrd-table__cell--numeric' : ''}` }, value));
|
|
4081
|
+
};
|
|
4082
|
+
/** Formats the aggregation total for one column, '' when not applicable. */
|
|
4083
|
+
function formatAggregationValue(col, aggregations, locale) {
|
|
4084
|
+
var _a;
|
|
4085
|
+
if (col.type !== 'FIELD' || !col.aggregate || !aggregations)
|
|
4086
|
+
return '';
|
|
4087
|
+
const fn = col.aggregate.toLowerCase();
|
|
4088
|
+
const aggData = aggregations[fn];
|
|
4089
|
+
const val = typeof aggData === 'object' && aggData !== null
|
|
4090
|
+
? aggData[(_a = col.name) !== null && _a !== void 0 ? _a : '']
|
|
4091
|
+
: undefined;
|
|
4092
|
+
if (val == null)
|
|
4093
|
+
return '';
|
|
4094
|
+
const dt = col.dataType;
|
|
4095
|
+
if (dt === 'INTEGER')
|
|
4096
|
+
return formatNumber(val, locale, { maximumFractionDigits: 0 });
|
|
4097
|
+
if (dt === 'PERCENTAGE')
|
|
4098
|
+
return formatPercentage(val, locale);
|
|
4099
|
+
if (dt === 'CURRENCY' && col.currencyCode)
|
|
4100
|
+
return formatCurrency(val, col.currencyCode, locale);
|
|
4101
|
+
return formatNumber(val, locale);
|
|
4102
|
+
}
|
|
4103
|
+
const TotalsRow = ({ columns, aggregations, locale }) => {
|
|
4104
|
+
if (!aggregations)
|
|
4105
|
+
return null;
|
|
4106
|
+
if (!columns.some(c => c.type === 'FIELD' && c.aggregate))
|
|
4107
|
+
return null;
|
|
4108
|
+
return (index.h("tfoot", null, index.h("tr", { class: "mrd-table__totals-row" }, columns.map(col => {
|
|
4109
|
+
var _a;
|
|
4110
|
+
const val = formatAggregationValue(col, aggregations, locale);
|
|
4111
|
+
const isNumeric = col.type === 'FIELD' && NUMERIC_TYPES.has((_a = col.dataType) !== null && _a !== void 0 ? _a : '');
|
|
4112
|
+
return (index.h("td", { class: `mrd-table__totals-cell${isNumeric ? ' mrd-table__totals-cell--numeric' : ''}` }, val));
|
|
4113
|
+
}))));
|
|
4114
|
+
};
|
|
4115
|
+
const TextblockModal = ({ text, locale, onClose }) => {
|
|
4116
|
+
if (text === null)
|
|
4117
|
+
return null;
|
|
4118
|
+
return (index.h("div", { class: "mrd-table__modal-backdrop", onClick: onClose, role: "dialog", "aria-modal": "true" }, index.h("div", { class: "mrd-table__modal", onClick: (e) => e.stopPropagation() }, index.h("button", { class: "mrd-table__modal-close", onClick: onClose, "aria-label": t('close', locale) }, "\u2715"), index.h("p", { class: "mrd-table__modal-text" }, text))));
|
|
4119
|
+
};
|
|
4120
|
+
const JsonModal = ({ html, locale, onClose }) => {
|
|
4121
|
+
if (html === null)
|
|
4122
|
+
return null;
|
|
4123
|
+
return (index.h("div", { class: "mrd-table__modal-backdrop", onClick: onClose, role: "dialog", "aria-modal": "true" }, index.h("div", { class: "mrd-table__modal", onClick: (e) => e.stopPropagation() }, index.h("button", { class: "mrd-table__modal-close", onClick: onClose, "aria-label": t('close', locale) }, "\u2715"), index.h("pre", { class: "mrd-table__modal-json", innerHTML: html }))));
|
|
4124
|
+
};
|
|
4125
|
+
const Toolbar = ({ locale, filterMode, filterCount, actions, views, activeViewIdx, viewPopoverOpen, createPickerOpen, createTypes, cb }) => {
|
|
4126
|
+
var _a;
|
|
4127
|
+
const hasActions = actions.length > 0;
|
|
4128
|
+
const hasViewSwitcher = views.length > 1;
|
|
4129
|
+
return (index.h("div", { class: "mrd-table__toolbar" }, index.h("div", { class: "mrd-table__toolbar-left" }, index.h("button", { class: `mrd-table__action mrd-table__action--secondary mrd-table__filter-toggle${filterMode ? ' mrd-table__filter-toggle--active' : ''}`, onClick: cb.onFilterToggle }, index.h("svg", { class: "mrd-table__action-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, index.h("path", { fill: "currentColor", d: "M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" })), filterCount > 0 && index.h("span", { class: "mrd-table__filter-badge" }, filterCount), index.h("span", { class: "mrd-table__action-tooltip" }, filterMode ? t('table_filter_hide', locale) : t('table_filter', locale), filterCount > 0 ? ` (${filterCount} ${t('table_filter_active', locale)})` : '')), filterCount > 0 && (index.h("button", { class: "mrd-table__action mrd-table__action--secondary", onClick: cb.onClearAllFilters }, index.h("svg", { class: "mrd-table__action-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, index.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" })), index.h("span", { class: "mrd-table__action-tooltip" }, t('table_filter_clear_all', locale))))), hasViewSwitcher && (index.h("div", { class: "mrd-table__toolbar-center" }, index.h("div", { class: "mrd-table__view-switcher" }, index.h("button", { class: "mrd-table__view-arrow", "aria-label": "Previous view", onClick: () => cb.onViewSwitch((activeViewIdx - 1 + views.length) % views.length) }, "\u25C0"), index.h("div", { class: "mrd-table__view-title-wrap" }, index.h("button", { class: "mrd-table__view-title", onClick: (e) => cb.onToggleViewPopover(e) }, (_a = views[activeViewIdx]) === null || _a === void 0 ? void 0 : _a.label), viewPopoverOpen && (index.h("div", { class: "mrd-table__view-popover", onClick: (e) => e.stopPropagation() }, views.map((v, i) => (index.h("button", { key: String(i), class: `mrd-table__view-popover-item${i === activeViewIdx ? ' mrd-table__view-popover-item--active' : ''}`, onClick: () => {
|
|
4130
|
+
if (i !== activeViewIdx)
|
|
4131
|
+
cb.onViewSwitch(i);
|
|
4132
|
+
cb.onCloseViewPopover();
|
|
4133
|
+
} }, v.label)))))), index.h("button", { class: "mrd-table__view-arrow", "aria-label": "Next view", onClick: () => cb.onViewSwitch((activeViewIdx + 1) % views.length) }, "\u25B6")))), hasActions && (index.h("div", { class: "mrd-table__toolbar-right" }, actions.map(a => {
|
|
4134
|
+
var _a, _b;
|
|
4135
|
+
const pickerTypes = a.action === 'create' ? createTypes : null;
|
|
4136
|
+
if (pickerTypes === null || pickerTypes === void 0 ? void 0 : pickerTypes.length) {
|
|
4137
|
+
return (index.h("div", { class: "mrd-table__create-picker-wrap", key: `action-${a.action}` }, index.h("button", { class: `mrd-table__action mrd-table__action--${(_a = a.variant) !== null && _a !== void 0 ? _a : 'secondary'}`, onClick: cb.onToggleCreatePicker }, a.icon
|
|
4138
|
+
? index.h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, index.h("use", { href: a.icon }))
|
|
4139
|
+
: a.label, index.h("span", { class: "mrd-table__action-tooltip" }, a.label)), createPickerOpen && (index.h("div", { class: "mrd-table__create-picker" }, pickerTypes.map(ct => (index.h("button", { key: ct.type, class: "mrd-table__create-picker-item", onClick: () => cb.onCreate(ct.type) }, ct.label)))))));
|
|
4140
|
+
}
|
|
4141
|
+
return (index.h("button", { key: `action-${a.action}`, class: `mrd-table__action mrd-table__action--${(_b = a.variant) !== null && _b !== void 0 ? _b : 'secondary'}`, disabled: a.disabled, onClick: () => cb.onAction(a.action) }, a.icon
|
|
4142
|
+
? index.h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, index.h("use", { href: a.icon }))
|
|
4143
|
+
: a.label, index.h("span", { class: "mrd-table__action-tooltip" }, a.label)));
|
|
4144
|
+
})))));
|
|
4145
|
+
};
|
|
4146
|
+
|
|
4147
|
+
const FilterEditor = ({ col, dataType, openFilterCol, pendingFilter, locale, cb }) => {
|
|
4148
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4149
|
+
const pf = pendingFilter;
|
|
4150
|
+
if (NO_FILTER_TYPES.has(dataType)) {
|
|
4151
|
+
return index.h("p", { class: "mrd-table__filter-no-support" }, t('filter_no_support', locale));
|
|
4152
|
+
}
|
|
4153
|
+
if (dataType === 'BOOLEAN') {
|
|
4154
|
+
const boolOp = pf.operator;
|
|
4155
|
+
const noValueOp = boolOp === 'isEmpty' || boolOp === 'isNotEmpty';
|
|
4156
|
+
return (index.h("div", { class: "mrd-table__filter-radio-group" }, [
|
|
4157
|
+
{ labelKey: 'filter_all', value: null },
|
|
4158
|
+
{ labelKey: 'yes', value: true },
|
|
4159
|
+
{ labelKey: 'no', value: false },
|
|
4160
|
+
].map(opt => (index.h("label", { class: "mrd-table__filter-radio-label" }, index.h("input", { type: "radio", name: `bf-${openFilterCol}`, checked: !noValueOp && pf.value === opt.value, onChange: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: undefined, value: opt.value })) }), t(opt.labelKey, locale)))), index.h("label", { class: "mrd-table__filter-radio-label" }, index.h("input", { type: "radio", name: `bf-${openFilterCol}`, checked: boolOp === 'isEmpty', onChange: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: 'isEmpty', value: undefined })) }), t('filter_is_empty', locale)), index.h("label", { class: "mrd-table__filter-radio-label" }, index.h("input", { type: "radio", name: `bf-${openFilterCol}`, checked: boolOp === 'isNotEmpty', onChange: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: 'isNotEmpty', value: undefined })) }), t('filter_is_not_empty', locale))));
|
|
4161
|
+
}
|
|
4162
|
+
if (dataType === 'LIST') {
|
|
4163
|
+
const items = (_a = col.listItems) !== null && _a !== void 0 ? _a : [];
|
|
4164
|
+
const selected = (_b = pf.values) !== null && _b !== void 0 ? _b : [];
|
|
4165
|
+
return (index.h("div", { class: "mrd-table__filter-list" }, index.h("div", { class: "mrd-table__filter-list-controls" }, index.h("button", { class: "mrd-table__filter-list-btn", onClick: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { values: items.map(i => i.key) })) }, t('filter_select_all', locale)), index.h("button", { class: "mrd-table__filter-list-btn", onClick: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { values: [] })) }, t('filter_select_none', locale))), items.map(item => (index.h("label", { class: "mrd-table__filter-checkbox-label" }, index.h("input", { type: "checkbox", checked: selected.includes(item.key), onChange: (e) => cb.onToggleValue(item.key, e.target.checked) }), item.label)))));
|
|
4166
|
+
}
|
|
4167
|
+
if (TEXT_TYPES.has(dataType) || dataType === 'RELATION') {
|
|
4168
|
+
const op = (_c = pf.operator) !== null && _c !== void 0 ? _c : 'startsWith';
|
|
4169
|
+
const noInput = op === 'isEmpty' || op === 'isNotEmpty';
|
|
4170
|
+
return (index.h("div", { class: "mrd-table__filter-editor" }, index.h("select", { class: "mrd-table__filter-select", onChange: (e) => cb.onSetPending('operator', e.target.value) }, [
|
|
4171
|
+
{ val: 'startsWith', labelKey: 'filter_starts_with' },
|
|
4172
|
+
{ val: 'equals', labelKey: 'filter_equals' },
|
|
4173
|
+
{ val: 'isEmpty', labelKey: 'filter_is_empty' },
|
|
4174
|
+
{ val: 'isNotEmpty', labelKey: 'filter_is_not_empty' },
|
|
4175
|
+
].map(o => index.h("option", { value: o.val, selected: op === o.val }, t(o.labelKey, locale)))), !noInput && (index.h("input", { type: "text", class: "mrd-table__filter-input", value: String((_d = pf.value) !== null && _d !== void 0 ? _d : ''), placeholder: t('filter_search_value', locale), onInput: (e) => cb.onSetPending('value', e.target.value) }))));
|
|
4176
|
+
}
|
|
4177
|
+
if (NUMERIC_TYPES.has(dataType)) {
|
|
4178
|
+
const numOp = pf.operator;
|
|
4179
|
+
const noInput = numOp === 'isEmpty' || numOp === 'isNotEmpty';
|
|
4180
|
+
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4181
|
+
return (index.h("div", { class: "mrd-table__filter-editor" }, index.h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4182
|
+
const val = e.target.value;
|
|
4183
|
+
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4184
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined }));
|
|
4185
|
+
}
|
|
4186
|
+
else {
|
|
4187
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: undefined }));
|
|
4188
|
+
}
|
|
4189
|
+
} }, index.h("option", { value: "", selected: !noInput }, t('filter_has_value', locale)), index.h("option", { value: "isEmpty", selected: numOp === 'isEmpty' }, t('filter_is_empty', locale)), index.h("option", { value: "isNotEmpty", selected: numOp === 'isNotEmpty' }, t('filter_is_not_empty', locale))), !noInput && (index.h("div", { class: "mrd-table__filter-editor" }, index.h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, index.h("label", { class: "mrd-table__filter-radio-label" }, index.h("input", { type: "radio", name: `nm-${openFilterCol}`, checked: !rangeMode, onChange: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { from: undefined, to: undefined })) }), t('filter_exact', locale)), index.h("label", { class: "mrd-table__filter-radio-label" }, index.h("input", { type: "radio", name: `nm-${openFilterCol}`, checked: rangeMode, onChange: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { value: undefined, from: null, to: null })) }), t('filter_range', locale))), !rangeMode ? (index.h("input", { type: "number", class: "mrd-table__filter-input", value: pf.value != null ? String(pf.value) : '', onInput: (e) => cb.onSetPending('value', e.target.value) })) : (index.h("div", { class: "mrd-table__filter-range" }, index.h("input", { type: "number", class: "mrd-table__filter-input", placeholder: t('filter_from', locale), value: pf.from != null ? String(pf.from) : '', onInput: (e) => cb.onSetPending('from', e.target.value) }), index.h("span", { class: "mrd-table__filter-range-sep" }, "\u2013"), index.h("input", { type: "number", class: "mrd-table__filter-input", placeholder: t('filter_to', locale), value: pf.to != null ? String(pf.to) : '', onInput: (e) => cb.onSetPending('to', e.target.value) })))))));
|
|
4190
|
+
}
|
|
4191
|
+
if (dataType === 'DATETIME') {
|
|
4192
|
+
const dtOp = pf.operator;
|
|
4193
|
+
const noInput = dtOp === 'isEmpty' || dtOp === 'isNotEmpty';
|
|
4194
|
+
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4195
|
+
return (index.h("div", { class: "mrd-table__filter-editor" }, index.h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4196
|
+
const val = e.target.value;
|
|
4197
|
+
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4198
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined }));
|
|
4199
|
+
}
|
|
4200
|
+
else {
|
|
4201
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: undefined }));
|
|
4202
|
+
}
|
|
4203
|
+
} }, index.h("option", { value: "", selected: !noInput }, t('filter_has_value', locale)), index.h("option", { value: "isEmpty", selected: dtOp === 'isEmpty' }, t('filter_is_empty', locale)), index.h("option", { value: "isNotEmpty", selected: dtOp === 'isNotEmpty' }, t('filter_is_not_empty', locale))), !noInput && (index.h("div", { class: "mrd-table__filter-editor" }, index.h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, index.h("label", { class: "mrd-table__filter-radio-label" }, index.h("input", { type: "radio", name: `dt-${openFilterCol}`, checked: !rangeMode, onChange: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { from: undefined, to: undefined })) }), t('filter_exact', locale)), index.h("label", { class: "mrd-table__filter-radio-label" }, index.h("input", { type: "radio", name: `dt-${openFilterCol}`, checked: rangeMode, onChange: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { value: undefined, from: null, to: null })) }), t('filter_range', locale))), !rangeMode ? (index.h("input", { type: "date", class: "mrd-table__filter-input", value: String((_e = pf.value) !== null && _e !== void 0 ? _e : ''), onInput: (e) => cb.onSetPending('value', e.target.value) })) : (index.h("div", { class: "mrd-table__filter-range mrd-table__filter-range--stacked" }, index.h("label", { class: "mrd-table__filter-range-label" }, t('filter_from', locale)), index.h("input", { type: "date", class: "mrd-table__filter-input", value: pf.from != null ? String(pf.from) : '', onInput: (e) => cb.onSetPending('from', e.target.value) }), index.h("label", { class: "mrd-table__filter-range-label" }, t('filter_to', locale)), index.h("input", { type: "date", class: "mrd-table__filter-input", value: pf.to != null ? String(pf.to) : '', onInput: (e) => cb.onSetPending('to', e.target.value) })))))));
|
|
4204
|
+
}
|
|
4205
|
+
if (DATE_TYPES.has(dataType)) {
|
|
4206
|
+
const inputType = dataType === 'DATE' ? 'date' : 'time';
|
|
4207
|
+
const dtdOp = pf.operator;
|
|
4208
|
+
const noInput = dtdOp === 'isEmpty' || dtdOp === 'isNotEmpty';
|
|
4209
|
+
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4210
|
+
return (index.h("div", { class: "mrd-table__filter-editor" }, index.h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4211
|
+
const val = e.target.value;
|
|
4212
|
+
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4213
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined }));
|
|
4214
|
+
}
|
|
4215
|
+
else {
|
|
4216
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: undefined }));
|
|
4217
|
+
}
|
|
4218
|
+
} }, index.h("option", { value: "", selected: !noInput }, t('filter_has_value', locale)), index.h("option", { value: "isEmpty", selected: dtdOp === 'isEmpty' }, t('filter_is_empty', locale)), index.h("option", { value: "isNotEmpty", selected: dtdOp === 'isNotEmpty' }, t('filter_is_not_empty', locale))), !noInput && (index.h("div", { class: "mrd-table__filter-editor" }, index.h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, index.h("label", { class: "mrd-table__filter-radio-label" }, index.h("input", { type: "radio", name: `dt-${openFilterCol}`, checked: !rangeMode, onChange: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { from: undefined, to: undefined })) }), t('filter_exact', locale)), index.h("label", { class: "mrd-table__filter-radio-label" }, index.h("input", { type: "radio", name: `dt-${openFilterCol}`, checked: rangeMode, onChange: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { value: undefined, from: null, to: null })) }), t('filter_range', locale))), !rangeMode ? (index.h("input", { type: inputType, class: "mrd-table__filter-input", value: String((_f = pf.value) !== null && _f !== void 0 ? _f : ''), onInput: (e) => cb.onSetPending('value', e.target.value) })) : (index.h("div", { class: "mrd-table__filter-range" }, index.h("input", { type: inputType, class: "mrd-table__filter-input", placeholder: t('filter_from', locale), value: pf.from != null ? String(pf.from) : '', onInput: (e) => cb.onSetPending('from', e.target.value) }), index.h("input", { type: inputType, class: "mrd-table__filter-input", placeholder: t('filter_to', locale), value: pf.to != null ? String(pf.to) : '', onInput: (e) => cb.onSetPending('to', e.target.value) })))))));
|
|
4219
|
+
}
|
|
4220
|
+
return null;
|
|
4221
|
+
};
|
|
4222
|
+
const FilterPopup = (props) => {
|
|
4223
|
+
var _a;
|
|
4224
|
+
const { col, openFilterCol, popupPos, sortField, sortDir, locale, cb } = props;
|
|
4225
|
+
const label = (_a = col.label) !== null && _a !== void 0 ? _a : openFilterCol;
|
|
4226
|
+
const sortActive = sortField === openFilterCol;
|
|
4227
|
+
return (index.h("div", { class: "mrd-table__filter-popup", style: { top: `${popupPos.top}px`, left: `${popupPos.left}px` }, onClick: (e) => e.stopPropagation() }, index.h("div", { class: "mrd-table__filter-popup-header" }, index.h("span", { class: "mrd-table__filter-popup-title" }, label), index.h("button", { class: "mrd-table__filter-close", onClick: cb.onClose }, "\u2715")), index.h("div", { class: "mrd-table__filter-section" }, index.h("div", { class: "mrd-table__filter-section-label" }, t('filter_sorting', locale)), index.h("div", { class: "mrd-table__filter-sort-buttons" }, index.h("button", { class: `mrd-table__filter-sort-btn${sortActive && sortDir === 'asc' ? ' mrd-table__filter-sort-btn--active' : ''}`, onClick: () => cb.onApplySort('asc') }, "\u25B2 ", t('filter_ascending', locale)), index.h("button", { class: `mrd-table__filter-sort-btn${sortActive && sortDir === 'desc' ? ' mrd-table__filter-sort-btn--active' : ''}`, onClick: () => cb.onApplySort('desc') }, "\u25BC ", t('filter_descending', locale)))), index.h("div", { class: "mrd-table__filter-divider" }), index.h("div", { class: "mrd-table__filter-section" }, index.h("div", { class: "mrd-table__filter-section-label" }, t('filter_section', locale)), index.h(FilterEditor, Object.assign({}, props))), index.h("div", { class: "mrd-table__filter-popup-footer" }, index.h("button", { class: "mrd-table__filter-btn mrd-table__filter-btn--clear", onClick: cb.onClear }, t('filter_clear', locale)), index.h("button", { class: "mrd-table__filter-btn mrd-table__filter-btn--apply", onClick: cb.onApply }, t('filter_apply', locale)))));
|
|
4228
|
+
};
|
|
4229
|
+
|
|
4230
|
+
/**
|
|
4231
|
+
* Pure window/paging maths for the mrd-table virtual scroll.
|
|
4232
|
+
* The window state itself stays @State in the component; these
|
|
4233
|
+
* functions only compute values from it.
|
|
4234
|
+
*/
|
|
4235
|
+
const BUFFER = 10;
|
|
4236
|
+
/** Wait this long (ms) after the last scroll event before requesting pages,
|
|
4237
|
+
* so pages the user quickly scrolls past are skipped. */
|
|
4238
|
+
const REQUEST_DEBOUNCE_MS = 150;
|
|
4239
|
+
/** Default time (ms) to wait for setPage() before treating a request as stale and retrying. */
|
|
4240
|
+
const REQUEST_TIMEOUT_MS = 15000;
|
|
4241
|
+
/** Max retries for a stale page request before giving up and showing a retry row. */
|
|
4242
|
+
const MAX_RETRY_ATTEMPTS = 3;
|
|
4243
|
+
function visibleCount(tableHeight, rowHeight) {
|
|
4244
|
+
return Math.ceil(tableHeight / rowHeight);
|
|
4245
|
+
}
|
|
4246
|
+
/** Render window (with buffer) for the given scroll offset. */
|
|
4247
|
+
function computeWindow(scrollTop, rowHeight, tableHeight, total) {
|
|
4248
|
+
const visStart = Math.floor(scrollTop / rowHeight);
|
|
4249
|
+
const visEnd = Math.min(visStart + visibleCount(tableHeight, rowHeight), total - 1);
|
|
4250
|
+
return {
|
|
4251
|
+
renderStart: Math.max(0, visStart - BUFFER),
|
|
4252
|
+
renderEnd: Math.min(total - 1, visEnd + BUFFER),
|
|
4253
|
+
};
|
|
4254
|
+
}
|
|
4255
|
+
/** First/last page (0-based) covering the given row window. */
|
|
4256
|
+
function pageRange(start, end, pageSize) {
|
|
4257
|
+
return { firstPage: Math.floor(start / pageSize), lastPage: Math.floor(end / pageSize) };
|
|
4258
|
+
}
|
|
4259
|
+
function getRowFromPages(pages, index, pageSize) {
|
|
4260
|
+
var _a;
|
|
4261
|
+
const page = pages.get(Math.floor(index / pageSize));
|
|
4262
|
+
return (_a = page === null || page === void 0 ? void 0 : page[index % pageSize]) !== null && _a !== void 0 ? _a : null;
|
|
4263
|
+
}
|
|
4264
|
+
/** Authoritative row count: a page shorter than pageSize is the last page,
|
|
4265
|
+
* so the true total cannot exceed its end index. */
|
|
4266
|
+
function computeEffectiveTotal(loadedPages, pageSize, baseTotal) {
|
|
4267
|
+
let effectiveTotal = baseTotal;
|
|
4268
|
+
for (const [pageNum, pageRows] of loadedPages) {
|
|
4269
|
+
if (pageRows.length < pageSize) {
|
|
4270
|
+
effectiveTotal = Math.min(effectiveTotal, pageNum * pageSize + pageRows.length);
|
|
4271
|
+
}
|
|
4272
|
+
}
|
|
4273
|
+
return effectiveTotal;
|
|
4274
|
+
}
|
|
4275
|
+
/** True when some loaded page was short — the exact total is then known. */
|
|
4276
|
+
function isTotalKnownFromPages(loadedPages, pageSize) {
|
|
4277
|
+
for (const rows of loadedPages.values()) {
|
|
4278
|
+
if (rows.length < pageSize)
|
|
4279
|
+
return true;
|
|
4280
|
+
}
|
|
4281
|
+
return false;
|
|
4282
|
+
}
|
|
4283
|
+
/** Pages whose request timestamp is older than timeoutMs — candidates for retry or failure.
|
|
4284
|
+
* Caller is expected to already exclude pages present in loadedPages. */
|
|
4285
|
+
function getStalePages(requestedAt, now, timeoutMs) {
|
|
4286
|
+
const stale = [];
|
|
4287
|
+
for (const [page, ts] of requestedAt) {
|
|
4288
|
+
if (now - ts >= timeoutMs)
|
|
4289
|
+
stale.push(page);
|
|
4290
|
+
}
|
|
4291
|
+
return stale;
|
|
4292
|
+
}
|
|
4293
|
+
|
|
4294
|
+
const mrdTableCss = () => `@charset "UTF-8";.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__row--failed.sc-mrd-table{background:transparent}.mrd-table__cell--failed.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-4);border-bottom:1px solid var(--mrd-border-color)}.mrd-table__retry-button.sc-mrd-table{border:none;background:none;padding:0;color:var(--mrd-color-danger);font-size:inherit;cursor:pointer;text-decoration:underline}.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__toolbar-center.sc-mrd-table{flex:1;display:flex;justify-content:center;align-items:center;gap:var(--mrd-space-1)}.mrd-table__view-switcher.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1)}.mrd-table__view-arrow.sc-mrd-table{background:none;border:none;cursor:pointer;padding:0 var(--mrd-space-1);color:var(--mrd-color-neutral-500);font-size:var(--mrd-font-size-xs);line-height:1}.mrd-table__view-arrow.sc-mrd-table:hover{color:var(--mrd-color-neutral-800)}.mrd-table__view-title-wrap.sc-mrd-table{position:relative}.mrd-table__view-title.sc-mrd-table{font-size:var(--mrd-font-size-sm);font-weight:600;color:var(--mrd-color-neutral-800);font-family:var(--mrd-font-family);background:none;border:none;outline:none;cursor:pointer;padding:0 var(--mrd-space-1);max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mrd-table__view-title.sc-mrd-table:hover{color:var(--mrd-color-primary)}.mrd-table__view-popover.sc-mrd-table{position:absolute;top:calc(100% + var(--mrd-space-1));left:50%;transform:translateX(-50%);background:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-radius-md);box-shadow:var(--mrd-shadow-md);z-index:100;min-width:160px;padding:var(--mrd-space-1) 0}.mrd-table__view-popover-item.sc-mrd-table{display:block;width:100%;text-align:left;background:none;border:none;cursor:pointer;padding:var(--mrd-space-2) var(--mrd-space-3);font-size:var(--mrd-font-size-sm);font-family:var(--mrd-font-family);color:var(--mrd-color-neutral-700);white-space:nowrap}.mrd-table__view-popover-item.sc-mrd-table:hover{background:var(--mrd-color-neutral-50)}.mrd-table__view-popover-item--active.sc-mrd-table{font-weight:600;color:var(--mrd-color-primary)}.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__create-picker-wrap.sc-mrd-table{position:relative}.mrd-table__create-picker.sc-mrd-table{position:absolute;right:0;top:calc(100% + 4px);background:var(--mrd-color-white, #fff);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, 0.12));z-index:10;min-width:10rem;padding:var(--mrd-space-1) 0}.mrd-table__create-picker-item.sc-mrd-table{display:block;width:100%;text-align:left;padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:none;cursor:pointer;font-size:var(--mrd-font-size-sm);font-family:var(--mrd-font-family);color:var(--mrd-color-neutral-800)}.mrd-table__create-picker-item.sc-mrd-table:hover{background:var(--mrd-color-neutral-50);color:var(--mrd-color-neutral-900)}.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, 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, 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__totals-row.sc-mrd-table{border-top:2px solid var(--mrd-border-color)}.mrd-table__totals-cell.sc-mrd-table{position:sticky;bottom:0;z-index:2;padding:var(--mrd-space-2) var(--mrd-space-4);background:var(--mrd-color-white);font-weight:var(--mrd-font-weight-medium);font-variant-numeric:tabular-nums;white-space:nowrap;border-top:2px solid var(--mrd-border-color)}.mrd-table__totals-cell--numeric.sc-mrd-table{text-align:right}.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}.mrd-table__json-preview.sc-mrd-table{font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:inline-block;max-width:calc(100% - 1.5rem);vertical-align:middle}.mrd-table__modal-json.sc-mrd-table{margin:0;padding-right:var(--mrd-space-6);font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);white-space:pre-wrap;word-break:break-word;line-height:1.6;background:none;border:none}`;
|
|
4295
|
+
|
|
4296
|
+
/** How often (ms) to scan outstanding page requests for staleness. */
|
|
4297
|
+
const STALE_CHECK_INTERVAL_MS = 2000;
|
|
4298
|
+
/** Breedte van de filterpopup in px — voor overflow-correctie. */
|
|
4299
|
+
const POPUP_WIDTH = 280;
|
|
3819
4300
|
const MrdTable = class {
|
|
3820
4301
|
constructor(hostRef) {
|
|
3821
4302
|
index.registerInstance(this, hostRef);
|
|
3822
4303
|
this.mrdLoadPage = index.createEvent(this, "mrdLoadPage");
|
|
4304
|
+
this.mrdPageError = index.createEvent(this, "mrdPageError");
|
|
3823
4305
|
this.mrdRowClick = index.createEvent(this, "mrdRowClick");
|
|
3824
4306
|
this.mrdAction = index.createEvent(this, "mrdAction");
|
|
3825
4307
|
this.mrdDownload = index.createEvent(this, "mrdDownload");
|
|
@@ -3827,10 +4309,17 @@ const MrdTable = class {
|
|
|
3827
4309
|
// ── Non-state internals ────────────────────────────────────────────────────
|
|
3828
4310
|
this.pendingPages = new Set();
|
|
3829
4311
|
this.debounceTimer = null;
|
|
4312
|
+
/** Timestamp of the last mrdLoadPage emission per outstanding page — drives stale-request detection. */
|
|
4313
|
+
this.requestedAt = new Map();
|
|
4314
|
+
/** Retry count per page since it first became stale. */
|
|
4315
|
+
this.retryAttempts = new Map();
|
|
4316
|
+
this.staleCheckTimer = null;
|
|
3830
4317
|
this.outsideClickHandler = null;
|
|
3831
4318
|
this.keydownHandler = null;
|
|
3832
4319
|
this.createPickerClickHandler = null;
|
|
3833
4320
|
this.viewPopoverClickHandler = null;
|
|
4321
|
+
/** Guards against scheduling more than one column-width measurement per freeze. */
|
|
4322
|
+
this.colWidthMeasureScheduled = false;
|
|
3834
4323
|
// ── Props ──────────────────────────────────────────────────────────────────
|
|
3835
4324
|
/** The VIEW or RELATED_VIEW layout item. Contains view config, dataClass, fromClass, actions etc. */
|
|
3836
4325
|
this.item = null;
|
|
@@ -3847,11 +4336,16 @@ const MrdTable = class {
|
|
|
3847
4336
|
this.rowHeight = 36;
|
|
3848
4337
|
/** Height of the scroll container in px. */
|
|
3849
4338
|
this.tableHeight = 500;
|
|
4339
|
+
/** Time (ms) to wait for setPage() before retrying a page request; after
|
|
4340
|
+
* MAX_RETRY_ATTEMPTS retries the page is marked failed (see failedPages). */
|
|
4341
|
+
this.requestTimeoutMs = REQUEST_TIMEOUT_MS;
|
|
3850
4342
|
// ── Internal state ─────────────────────────────────────────────────────────
|
|
3851
4343
|
/** Index into allViews[] for the currently displayed view. 0 = primary, 1+ = alternatives. */
|
|
3852
4344
|
this.activeViewIdx = 0;
|
|
3853
4345
|
this.loadedPages = new Map();
|
|
3854
4346
|
this.requestedPages = new Set();
|
|
4347
|
+
/** Pages that timed out MAX_RETRY_ATTEMPTS times — rendered as a retry row instead of shimmer. */
|
|
4348
|
+
this.failedPages = new Set();
|
|
3855
4349
|
this.renderStart = 0;
|
|
3856
4350
|
this.renderEnd = 0;
|
|
3857
4351
|
this.colWidths = [];
|
|
@@ -3887,13 +4381,10 @@ const MrdTable = class {
|
|
|
3887
4381
|
this.minKnownTotal = 0;
|
|
3888
4382
|
this.handleScroll = (e) => {
|
|
3889
4383
|
const scroller = e.currentTarget;
|
|
3890
|
-
const
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
this.scrollTop = scrollTop;
|
|
3895
|
-
this.renderStart = Math.max(0, visStart - BUFFER);
|
|
3896
|
-
this.renderEnd = Math.min(total - 1, visEnd + BUFFER);
|
|
4384
|
+
const { renderStart, renderEnd } = computeWindow(scroller.scrollTop, this.rowHeight, this.tableHeight, this.baseTotal);
|
|
4385
|
+
this.scrollTop = scroller.scrollTop;
|
|
4386
|
+
this.renderStart = renderStart;
|
|
4387
|
+
this.renderEnd = renderEnd;
|
|
3897
4388
|
this.requestPagesForWindow(this.renderStart, this.renderEnd);
|
|
3898
4389
|
};
|
|
3899
4390
|
}
|
|
@@ -3913,18 +4404,14 @@ const MrdTable = class {
|
|
|
3913
4404
|
var _a, _b, _c;
|
|
3914
4405
|
this.applyDefaultSort((_c = (_b = (_a = this.item) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.defaultSort) !== null && _c !== void 0 ? _c : '');
|
|
3915
4406
|
}
|
|
4407
|
+
componentDidLoad() {
|
|
4408
|
+
this.staleCheckTimer = setInterval(() => this.checkStalePages(), STALE_CHECK_INTERVAL_MS);
|
|
4409
|
+
}
|
|
3916
4410
|
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
3917
4411
|
applyDefaultSort(defaultSort) {
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
this.sortField = parts[0].trim();
|
|
3922
|
-
this.sortDir = ((_a = parts[1]) === null || _a === void 0 ? void 0 : _a.trim()) === 'desc' ? 'desc' : 'asc';
|
|
3923
|
-
}
|
|
3924
|
-
else {
|
|
3925
|
-
this.sortField = '';
|
|
3926
|
-
this.sortDir = 'asc';
|
|
3927
|
-
}
|
|
4412
|
+
const { field, dir } = parseDefaultSort(defaultSort);
|
|
4413
|
+
this.sortField = field;
|
|
4414
|
+
this.sortDir = dir;
|
|
3928
4415
|
}
|
|
3929
4416
|
// ── Public API ─────────────────────────────────────────────────────────────
|
|
3930
4417
|
/**
|
|
@@ -3940,7 +4427,11 @@ const MrdTable = class {
|
|
|
3940
4427
|
this.pendingPages.clear();
|
|
3941
4428
|
this.loadedPages = new Map();
|
|
3942
4429
|
this.requestedPages = new Set();
|
|
4430
|
+
this.failedPages = new Set();
|
|
4431
|
+
this.requestedAt.clear();
|
|
4432
|
+
this.retryAttempts.clear();
|
|
3943
4433
|
this.colWidths = [];
|
|
4434
|
+
this.colWidthMeasureScheduled = false;
|
|
3944
4435
|
this.scrollTop = 0;
|
|
3945
4436
|
this.renderStart = 0;
|
|
3946
4437
|
// Always fill the visible viewport on init — totalElements may be stale from a
|
|
@@ -3954,7 +4445,7 @@ const MrdTable = class {
|
|
|
3954
4445
|
this.aggregationsPending = true;
|
|
3955
4446
|
this.minKnownTotal = 0;
|
|
3956
4447
|
// Always request page 0 — totalElements may be unknown (0) on first load.
|
|
3957
|
-
this.
|
|
4448
|
+
this.emitLoadPage(0);
|
|
3958
4449
|
this.requestedPages = new Set([0]);
|
|
3959
4450
|
}
|
|
3960
4451
|
/**
|
|
@@ -3985,6 +4476,13 @@ const MrdTable = class {
|
|
|
3985
4476
|
const next = new Map(this.loadedPages);
|
|
3986
4477
|
next.set(pageNumber, rows);
|
|
3987
4478
|
this.loadedPages = next;
|
|
4479
|
+
this.requestedAt.delete(pageNumber);
|
|
4480
|
+
this.retryAttempts.delete(pageNumber);
|
|
4481
|
+
if (this.failedPages.has(pageNumber)) {
|
|
4482
|
+
const nextFailed = new Set(this.failedPages);
|
|
4483
|
+
nextFailed.delete(pageNumber);
|
|
4484
|
+
this.failedPages = nextFailed;
|
|
4485
|
+
}
|
|
3988
4486
|
if (pageNumber === 0 && this.aggregationsPending) {
|
|
3989
4487
|
this.aggregationsPending = false;
|
|
3990
4488
|
const hasAggColumns = this.columns.some(c => c.type === 'FIELD' && c.aggregate);
|
|
@@ -4003,6 +4501,10 @@ const MrdTable = class {
|
|
|
4003
4501
|
}
|
|
4004
4502
|
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
4005
4503
|
disconnectedCallback() {
|
|
4504
|
+
if (this.staleCheckTimer !== null) {
|
|
4505
|
+
clearInterval(this.staleCheckTimer);
|
|
4506
|
+
this.staleCheckTimer = null;
|
|
4507
|
+
}
|
|
4006
4508
|
if (this.outsideClickHandler) {
|
|
4007
4509
|
document.removeEventListener('click', this.outsideClickHandler);
|
|
4008
4510
|
this.outsideClickHandler = null;
|
|
@@ -4021,21 +4523,34 @@ const MrdTable = class {
|
|
|
4021
4523
|
}
|
|
4022
4524
|
}
|
|
4023
4525
|
componentDidRender() {
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4526
|
+
// Freeze header widths once the first data page has rendered. The measurement
|
|
4527
|
+
// reads offsetWidth and writes the colWidths @State, which would trigger a
|
|
4528
|
+
// re-render *during* the render cycle if done synchronously here. Defer it to a
|
|
4529
|
+
// writeTask so the state mutation happens outside the render pass (avoids the
|
|
4530
|
+
// Stencil "state/prop changed during rendering" warning and potential loops).
|
|
4531
|
+
if (this.colWidths.length === 0 &&
|
|
4532
|
+
!this.colWidthMeasureScheduled &&
|
|
4533
|
+
this.loadedPages.size > 0 &&
|
|
4534
|
+
this.totalElements > 0) {
|
|
4535
|
+
this.colWidthMeasureScheduled = true;
|
|
4536
|
+
index.writeTask(() => {
|
|
4537
|
+
this.colWidthMeasureScheduled = false;
|
|
4538
|
+
// Re-check: state may have changed (e.g. a reset) between scheduling and running.
|
|
4539
|
+
if (this.colWidths.length !== 0)
|
|
4540
|
+
return;
|
|
4541
|
+
const ths = this.el.querySelectorAll('.mrd-table__header');
|
|
4542
|
+
if (ths.length > 0) {
|
|
4543
|
+
this.colWidths = Array.from(ths).map(th => th.offsetWidth);
|
|
4544
|
+
}
|
|
4545
|
+
});
|
|
4029
4546
|
}
|
|
4030
4547
|
}
|
|
4031
4548
|
// ── Paging / scroll helpers ────────────────────────────────────────────────
|
|
4032
4549
|
visibleCount() {
|
|
4033
|
-
return
|
|
4550
|
+
return visibleCount(this.tableHeight, this.rowHeight);
|
|
4034
4551
|
}
|
|
4035
4552
|
sortParam() {
|
|
4036
|
-
|
|
4037
|
-
return '';
|
|
4038
|
-
return this.sortDir === 'desc' ? `${this.sortField},desc` : this.sortField;
|
|
4553
|
+
return buildSortParam(this.sortField, this.sortDir);
|
|
4039
4554
|
}
|
|
4040
4555
|
/** Stable ordered list: primary view first, then alternatives (from the item prop). */
|
|
4041
4556
|
get allViews() {
|
|
@@ -4061,14 +4576,16 @@ const MrdTable = class {
|
|
|
4061
4576
|
* VIEW: /excel/{dataClass}
|
|
4062
4577
|
* RELATED_VIEW: /excel/{fromClass}/{parentId}/{dataClass} */
|
|
4063
4578
|
buildExcelPath() {
|
|
4064
|
-
var _a
|
|
4579
|
+
var _a;
|
|
4065
4580
|
const v = this.allViews[this.activeViewIdx];
|
|
4066
4581
|
if (!v)
|
|
4067
4582
|
return '';
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4583
|
+
return '/excel' + buildListPath({
|
|
4584
|
+
isRelatedView: ((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'RELATED_VIEW',
|
|
4585
|
+
fromClass: v.fromClass,
|
|
4586
|
+
parentId: this.parentId,
|
|
4587
|
+
dataClass: v.dataClass,
|
|
4588
|
+
});
|
|
4072
4589
|
}
|
|
4073
4590
|
buildActionDetail(action, basicType) {
|
|
4074
4591
|
var _a, _b, _c;
|
|
@@ -4088,80 +4605,28 @@ const MrdTable = class {
|
|
|
4088
4605
|
* VIEW: /{dataClass}
|
|
4089
4606
|
* RELATED_VIEW: /{fromClass}/{parentId}/{dataClass} */
|
|
4090
4607
|
buildDataPath() {
|
|
4091
|
-
var _a
|
|
4608
|
+
var _a;
|
|
4092
4609
|
const v = this.allViews[this.activeViewIdx];
|
|
4093
4610
|
if (!v)
|
|
4094
4611
|
return '';
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4612
|
+
return buildListPath({
|
|
4613
|
+
isRelatedView: ((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'RELATED_VIEW',
|
|
4614
|
+
fromClass: v.fromClass,
|
|
4615
|
+
parentId: this.parentId,
|
|
4616
|
+
dataClass: v.dataClass,
|
|
4617
|
+
});
|
|
4099
4618
|
}
|
|
4100
4619
|
/** Build query params for a page request from current sort, view filters, filterClass and active column filters. */
|
|
4101
4620
|
buildQueryParams(page) {
|
|
4102
|
-
var _a
|
|
4621
|
+
var _a;
|
|
4103
4622
|
const v = this.allViews[this.activeViewIdx];
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
if (filterClass)
|
|
4112
|
-
p.set('type', filterClass);
|
|
4113
|
-
for (const f of ((_b = (_a = v === null || v === void 0 ? void 0 : v.view) === null || _a === void 0 ? void 0 : _a.filter) !== null && _b !== void 0 ? _b : [])) {
|
|
4114
|
-
if (!f.name)
|
|
4115
|
-
continue;
|
|
4116
|
-
if (f.operator === 'EMPTY') {
|
|
4117
|
-
p.set(f.name, '');
|
|
4118
|
-
continue;
|
|
4119
|
-
}
|
|
4120
|
-
if (f.operator === 'NOT_EMPTY') {
|
|
4121
|
-
p.set(f.name + '_notempty', 'true');
|
|
4122
|
-
continue;
|
|
4123
|
-
}
|
|
4124
|
-
if (f.operator === 'STARTS_WITH') {
|
|
4125
|
-
p.set(f.name + '_startswith', String((_c = f.value) !== null && _c !== void 0 ? _c : ''));
|
|
4126
|
-
continue;
|
|
4127
|
-
}
|
|
4128
|
-
if (f.operator === 'FROM') {
|
|
4129
|
-
p.set(f.name + '_from', String((_d = f.value) !== null && _d !== void 0 ? _d : ''));
|
|
4130
|
-
continue;
|
|
4131
|
-
}
|
|
4132
|
-
if (f.operator === 'TO') {
|
|
4133
|
-
p.set(f.name + '_to', String((_e = f.value) !== null && _e !== void 0 ? _e : ''));
|
|
4134
|
-
continue;
|
|
4135
|
-
}
|
|
4136
|
-
if (f.value != null) {
|
|
4137
|
-
p.set(f.name, String(f.value));
|
|
4138
|
-
}
|
|
4139
|
-
}
|
|
4140
|
-
for (const f of this.activeFilters.values()) {
|
|
4141
|
-
if (f.operator === 'isEmpty') {
|
|
4142
|
-
p.set(f.field, '');
|
|
4143
|
-
continue;
|
|
4144
|
-
}
|
|
4145
|
-
if (f.operator === 'isNotEmpty') {
|
|
4146
|
-
p.set(f.field + '_notempty', 'true');
|
|
4147
|
-
continue;
|
|
4148
|
-
}
|
|
4149
|
-
if (f.operator === 'startsWith') {
|
|
4150
|
-
p.set(f.field + '_startswith', String((_f = f.value) !== null && _f !== void 0 ? _f : ''));
|
|
4151
|
-
continue;
|
|
4152
|
-
}
|
|
4153
|
-
if ((_g = f.values) === null || _g === void 0 ? void 0 : _g.length) {
|
|
4154
|
-
p.set(f.field, f.values.join(','));
|
|
4155
|
-
continue;
|
|
4156
|
-
}
|
|
4157
|
-
if (f.value != null)
|
|
4158
|
-
p.set(f.field, String(f.value));
|
|
4159
|
-
if (f.from != null)
|
|
4160
|
-
p.set(f.field + '_from', String(f.from));
|
|
4161
|
-
if (f.to != null)
|
|
4162
|
-
p.set(f.field + '_to', String(f.to));
|
|
4163
|
-
}
|
|
4164
|
-
return p.toString();
|
|
4623
|
+
return buildTableQueryParams({
|
|
4624
|
+
page,
|
|
4625
|
+
sort: this.sortParam(),
|
|
4626
|
+
filterClass: v === null || v === void 0 ? void 0 : v.filterClass,
|
|
4627
|
+
viewFilters: (_a = v === null || v === void 0 ? void 0 : v.view) === null || _a === void 0 ? void 0 : _a.filter,
|
|
4628
|
+
activeFilters: this.activeFilters.values(),
|
|
4629
|
+
});
|
|
4165
4630
|
}
|
|
4166
4631
|
get columns() {
|
|
4167
4632
|
var _a, _b, _c;
|
|
@@ -4216,11 +4681,7 @@ const MrdTable = class {
|
|
|
4216
4681
|
isTotalKnown() {
|
|
4217
4682
|
if (this.aggregationsTotal != null)
|
|
4218
4683
|
return true;
|
|
4219
|
-
|
|
4220
|
-
if (rows.length < this.pageSize)
|
|
4221
|
-
return true;
|
|
4222
|
-
}
|
|
4223
|
-
return false;
|
|
4684
|
+
return isTotalKnownFromPages(this.loadedPages, this.pageSize);
|
|
4224
4685
|
}
|
|
4225
4686
|
/** Effective total: aggregations-response > totalElements prop > minKnownTotal from setPage(). */
|
|
4226
4687
|
get baseTotal() {
|
|
@@ -4231,61 +4692,9 @@ const MrdTable = class {
|
|
|
4231
4692
|
return this.minKnownTotal;
|
|
4232
4693
|
}
|
|
4233
4694
|
// ── Aggregation helpers ────────────────────────────────────────────────────
|
|
4234
|
-
buildAggregationParams() {
|
|
4235
|
-
var _a;
|
|
4236
|
-
const groups = { sum: [], avg: [], count: [] };
|
|
4237
|
-
for (const col of this.columns) {
|
|
4238
|
-
if (col.type !== 'FIELD' || !col.aggregate)
|
|
4239
|
-
continue;
|
|
4240
|
-
const fn = col.aggregate.toLowerCase();
|
|
4241
|
-
if (fn in groups)
|
|
4242
|
-
groups[fn].push((_a = col.name) !== null && _a !== void 0 ? _a : '');
|
|
4243
|
-
}
|
|
4244
|
-
const params = {};
|
|
4245
|
-
if (groups.sum.length)
|
|
4246
|
-
params.sum = groups.sum;
|
|
4247
|
-
if (groups.avg.length)
|
|
4248
|
-
params.avg = groups.avg;
|
|
4249
|
-
if (groups.count.length)
|
|
4250
|
-
params.count = groups.count;
|
|
4251
|
-
return Object.keys(params).length > 0 ? params : null;
|
|
4252
|
-
}
|
|
4253
|
-
buildAggregationQs() {
|
|
4254
|
-
var _a, _b, _c;
|
|
4255
|
-
const p = new URLSearchParams(this.buildQueryParams(0));
|
|
4256
|
-
p.delete('page');
|
|
4257
|
-
p.delete('sort');
|
|
4258
|
-
const groups = this.buildAggregationParams();
|
|
4259
|
-
if ((_a = groups === null || groups === void 0 ? void 0 : groups.sum) === null || _a === void 0 ? void 0 : _a.length)
|
|
4260
|
-
p.set('sum', groups.sum.join(','));
|
|
4261
|
-
if ((_b = groups === null || groups === void 0 ? void 0 : groups.avg) === null || _b === void 0 ? void 0 : _b.length)
|
|
4262
|
-
p.set('avg', groups.avg.join(','));
|
|
4263
|
-
if ((_c = groups === null || groups === void 0 ? void 0 : groups.count) === null || _c === void 0 ? void 0 : _c.length)
|
|
4264
|
-
p.set('count', groups.count.join(','));
|
|
4265
|
-
return p.toString();
|
|
4266
|
-
}
|
|
4267
4695
|
emitLoadAggregations() {
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
renderAggregationValue(col) {
|
|
4271
|
-
var _a;
|
|
4272
|
-
if (col.type !== 'FIELD' || !col.aggregate || !this.aggregations)
|
|
4273
|
-
return '';
|
|
4274
|
-
const fn = col.aggregate.toLowerCase();
|
|
4275
|
-
const aggData = this.aggregations[fn];
|
|
4276
|
-
const val = typeof aggData === 'object' && aggData !== null
|
|
4277
|
-
? aggData[(_a = col.name) !== null && _a !== void 0 ? _a : '']
|
|
4278
|
-
: undefined;
|
|
4279
|
-
if (val == null)
|
|
4280
|
-
return '';
|
|
4281
|
-
const dt = col.dataType;
|
|
4282
|
-
if (dt === 'INTEGER')
|
|
4283
|
-
return formatNumber(val, this.locale, { maximumFractionDigits: 0 });
|
|
4284
|
-
if (dt === 'PERCENTAGE')
|
|
4285
|
-
return formatPercentage(val, this.locale);
|
|
4286
|
-
if (dt === 'CURRENCY' && col.currencyCode)
|
|
4287
|
-
return formatCurrency(val, col.currencyCode, this.locale);
|
|
4288
|
-
return formatNumber(val, this.locale);
|
|
4696
|
+
const qs = this.buildQueryParams(0);
|
|
4697
|
+
this.mrdLoadAggregations.emit({ path: this.buildDataPath(), qs, aggQs: buildAggregationQs(qs, this.columns) });
|
|
4289
4698
|
}
|
|
4290
4699
|
// ── Reset pagination ───────────────────────────────────────────────────────
|
|
4291
4700
|
/** Reset pagination state and scroll to top (used after sort or filter change). */
|
|
@@ -4297,7 +4706,11 @@ const MrdTable = class {
|
|
|
4297
4706
|
this.pendingPages.clear();
|
|
4298
4707
|
this.loadedPages = new Map();
|
|
4299
4708
|
this.requestedPages = new Set();
|
|
4709
|
+
this.failedPages = new Set();
|
|
4710
|
+
this.requestedAt.clear();
|
|
4711
|
+
this.retryAttempts.clear();
|
|
4300
4712
|
this.colWidths = [];
|
|
4713
|
+
this.colWidthMeasureScheduled = false;
|
|
4301
4714
|
this.scrollTop = 0;
|
|
4302
4715
|
this.renderStart = 0;
|
|
4303
4716
|
this.minKnownTotal = 0;
|
|
@@ -4326,15 +4739,19 @@ const MrdTable = class {
|
|
|
4326
4739
|
this.resetPages();
|
|
4327
4740
|
this.emitPagesForWindow(this.renderStart, this.renderEnd);
|
|
4328
4741
|
}
|
|
4742
|
+
/** Emits mrdLoadPage for a page and records the request timestamp for stale-request detection. */
|
|
4743
|
+
emitLoadPage(page) {
|
|
4744
|
+
this.mrdLoadPage.emit({ page, sort: this.sortParam(), path: this.buildDataPath(), qs: this.buildQueryParams(page) });
|
|
4745
|
+
this.requestedAt.set(page, Date.now());
|
|
4746
|
+
}
|
|
4329
4747
|
emitPagesForWindow(start, end) {
|
|
4330
|
-
const firstPage =
|
|
4331
|
-
const lastPage = Math.floor(end / this.pageSize);
|
|
4748
|
+
const { firstPage, lastPage } = pageRange(start, end, this.pageSize);
|
|
4332
4749
|
const next = new Set(this.requestedPages);
|
|
4333
4750
|
let changed = false;
|
|
4334
4751
|
for (let p = firstPage; p <= lastPage; p++) {
|
|
4335
4752
|
if (!this.loadedPages.has(p) && !next.has(p)) {
|
|
4336
4753
|
next.add(p);
|
|
4337
|
-
this.
|
|
4754
|
+
this.emitLoadPage(p);
|
|
4338
4755
|
changed = true;
|
|
4339
4756
|
}
|
|
4340
4757
|
}
|
|
@@ -4342,13 +4759,10 @@ const MrdTable = class {
|
|
|
4342
4759
|
this.requestedPages = next;
|
|
4343
4760
|
}
|
|
4344
4761
|
getRow(i) {
|
|
4345
|
-
|
|
4346
|
-
const page = this.loadedPages.get(Math.floor(i / this.pageSize));
|
|
4347
|
-
return (_a = page === null || page === void 0 ? void 0 : page[i % this.pageSize]) !== null && _a !== void 0 ? _a : null;
|
|
4762
|
+
return getRowFromPages(this.loadedPages, i, this.pageSize);
|
|
4348
4763
|
}
|
|
4349
4764
|
requestPagesForWindow(start, end) {
|
|
4350
|
-
const firstPage =
|
|
4351
|
-
const lastPage = Math.floor(end / this.pageSize);
|
|
4765
|
+
const { firstPage, lastPage } = pageRange(start, end, this.pageSize);
|
|
4352
4766
|
let anyNew = false;
|
|
4353
4767
|
for (let p = firstPage; p <= lastPage; p++) {
|
|
4354
4768
|
if (!this.loadedPages.has(p) && !this.requestedPages.has(p) && !this.pendingPages.has(p)) {
|
|
@@ -4376,13 +4790,53 @@ const MrdTable = class {
|
|
|
4376
4790
|
if (pageEnd < this.renderStart || pageStart > this.renderEnd)
|
|
4377
4791
|
continue;
|
|
4378
4792
|
next.add(page);
|
|
4379
|
-
this.
|
|
4793
|
+
this.emitLoadPage(page);
|
|
4380
4794
|
changed = true;
|
|
4381
4795
|
}
|
|
4382
4796
|
this.pendingPages.clear();
|
|
4383
4797
|
if (changed)
|
|
4384
4798
|
this.requestedPages = next;
|
|
4385
4799
|
}
|
|
4800
|
+
/** Scans outstanding requests for staleness: retries up to MAX_RETRY_ATTEMPTS times,
|
|
4801
|
+
* then gives up and marks the page as failed (rendered as a retry row). */
|
|
4802
|
+
checkStalePages() {
|
|
4803
|
+
var _a;
|
|
4804
|
+
if (this.requestedAt.size === 0)
|
|
4805
|
+
return;
|
|
4806
|
+
const stale = getStalePages(this.requestedAt, Date.now(), this.requestTimeoutMs)
|
|
4807
|
+
.filter(p => !this.loadedPages.has(p));
|
|
4808
|
+
if (stale.length === 0)
|
|
4809
|
+
return;
|
|
4810
|
+
let nextFailed = null;
|
|
4811
|
+
for (const page of stale) {
|
|
4812
|
+
const attempts = (_a = this.retryAttempts.get(page)) !== null && _a !== void 0 ? _a : 0;
|
|
4813
|
+
if (attempts < MAX_RETRY_ATTEMPTS) {
|
|
4814
|
+
this.retryAttempts.set(page, attempts + 1);
|
|
4815
|
+
this.emitLoadPage(page);
|
|
4816
|
+
}
|
|
4817
|
+
else {
|
|
4818
|
+
this.requestedAt.delete(page);
|
|
4819
|
+
this.retryAttempts.delete(page);
|
|
4820
|
+
if (!nextFailed)
|
|
4821
|
+
nextFailed = new Set(this.failedPages);
|
|
4822
|
+
nextFailed.add(page);
|
|
4823
|
+
this.mrdPageError.emit({ page });
|
|
4824
|
+
}
|
|
4825
|
+
}
|
|
4826
|
+
if (nextFailed)
|
|
4827
|
+
this.failedPages = nextFailed;
|
|
4828
|
+
}
|
|
4829
|
+
/** Manually retry a page the user gave up on (clicked the retry row). */
|
|
4830
|
+
retryPage(page) {
|
|
4831
|
+
const next = new Set(this.failedPages);
|
|
4832
|
+
next.delete(page);
|
|
4833
|
+
this.failedPages = next;
|
|
4834
|
+
this.retryAttempts.delete(page);
|
|
4835
|
+
this.emitLoadPage(page);
|
|
4836
|
+
const requested = new Set(this.requestedPages);
|
|
4837
|
+
requested.add(page);
|
|
4838
|
+
this.requestedPages = requested;
|
|
4839
|
+
}
|
|
4386
4840
|
// ── Filter helpers ─────────────────────────────────────────────────────────
|
|
4387
4841
|
handleFilterToggle() {
|
|
4388
4842
|
this.filterMode = !this.filterMode;
|
|
@@ -4410,17 +4864,7 @@ const MrdTable = class {
|
|
|
4410
4864
|
// If from and to cover the same local day it was an exact-date filter — restore
|
|
4411
4865
|
// to exact mode so the user sees the single-date input again.
|
|
4412
4866
|
if (dataType === 'DATETIME' && existing && existing.operator !== 'isEmpty' && existing.operator !== 'isNotEmpty') {
|
|
4413
|
-
|
|
4414
|
-
if (typeof display.from === 'string' && display.from)
|
|
4415
|
-
display.from = this.utcISOToLocalDate(display.from);
|
|
4416
|
-
if (typeof display.to === 'string' && display.to)
|
|
4417
|
-
display.to = this.utcISOToLocalDateExclusiveEnd(display.to);
|
|
4418
|
-
if (display.from && display.to && display.from === display.to) {
|
|
4419
|
-
this.pendingFilter = Object.assign(Object.assign({}, display), { value: display.from, from: undefined, to: undefined });
|
|
4420
|
-
}
|
|
4421
|
-
else {
|
|
4422
|
-
this.pendingFilter = display;
|
|
4423
|
-
}
|
|
4867
|
+
this.pendingFilter = datetimeFilterToDisplay(existing);
|
|
4424
4868
|
}
|
|
4425
4869
|
else {
|
|
4426
4870
|
this.pendingFilter = existing ? Object.assign({}, existing) : { field: name, dataType, operator: defaultOperator };
|
|
@@ -4486,81 +4930,15 @@ const MrdTable = class {
|
|
|
4486
4930
|
const current = (_b = (_a = this.pendingFilter) === null || _a === void 0 ? void 0 : _a.values) !== null && _b !== void 0 ? _b : [];
|
|
4487
4931
|
this.pendingFilter = Object.assign(Object.assign({}, this.pendingFilter), { values: checked ? [...current, key] : current.filter(k => k !== key) });
|
|
4488
4932
|
}
|
|
4489
|
-
filterHasValue(f) {
|
|
4490
|
-
if (f.operator === 'isEmpty' || f.operator === 'isNotEmpty')
|
|
4491
|
-
return true;
|
|
4492
|
-
if (f.values !== undefined && f.values.length > 0)
|
|
4493
|
-
return true;
|
|
4494
|
-
if (f.value != null && f.value !== '')
|
|
4495
|
-
return true;
|
|
4496
|
-
if (typeof f.value === 'boolean')
|
|
4497
|
-
return true;
|
|
4498
|
-
if (f.from != null && f.from !== '')
|
|
4499
|
-
return true;
|
|
4500
|
-
if (f.to != null && f.to !== '')
|
|
4501
|
-
return true;
|
|
4502
|
-
return false;
|
|
4503
|
-
}
|
|
4504
|
-
// Convert a local "YYYY-MM-DD" date string to the UTC ISO string at the
|
|
4505
|
-
// start of that local day (midnight). new Date(y, m, d) uses local time.
|
|
4506
|
-
dateLocalToUTCStart(dateStr) {
|
|
4507
|
-
if (!dateStr)
|
|
4508
|
-
return dateStr;
|
|
4509
|
-
const [year, month, day] = dateStr.split('-').map(Number);
|
|
4510
|
-
return new Date(year, month - 1, day).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
4511
|
-
}
|
|
4512
|
-
// Start of the day AFTER the given local date (exclusive range end).
|
|
4513
|
-
dateLocalToUTCEndExclusive(dateStr) {
|
|
4514
|
-
if (!dateStr)
|
|
4515
|
-
return dateStr;
|
|
4516
|
-
const [year, month, day] = dateStr.split('-').map(Number);
|
|
4517
|
-
return new Date(year, month - 1, day + 1).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
4518
|
-
}
|
|
4519
|
-
// Convert a stored UTC ISO string back to the local "YYYY-MM-DD" date.
|
|
4520
|
-
utcISOToLocalDate(utcStr) {
|
|
4521
|
-
if (!utcStr)
|
|
4522
|
-
return utcStr;
|
|
4523
|
-
const d = new Date(utcStr);
|
|
4524
|
-
if (isNaN(d.getTime()))
|
|
4525
|
-
return utcStr;
|
|
4526
|
-
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
4527
|
-
}
|
|
4528
|
-
// The stored "to" value is the exclusive end (midnight of the next day).
|
|
4529
|
-
// Subtract one day to recover the local date the user entered.
|
|
4530
|
-
utcISOToLocalDateExclusiveEnd(utcStr) {
|
|
4531
|
-
if (!utcStr)
|
|
4532
|
-
return utcStr;
|
|
4533
|
-
const d = new Date(utcStr);
|
|
4534
|
-
if (isNaN(d.getTime()))
|
|
4535
|
-
return utcStr;
|
|
4536
|
-
d.setDate(d.getDate() - 1);
|
|
4537
|
-
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
4538
|
-
}
|
|
4539
4933
|
applyFilter() {
|
|
4540
4934
|
const f = this.pendingFilter;
|
|
4541
4935
|
if (!(f === null || f === void 0 ? void 0 : f.field)) {
|
|
4542
4936
|
this.closeFilterPopup();
|
|
4543
4937
|
return;
|
|
4544
4938
|
}
|
|
4545
|
-
|
|
4546
|
-
// Exact date → range covering the full local day (from = midnight, to = next midnight).
|
|
4547
|
-
// "to" is always the exclusive end (midnight of the next local day).
|
|
4548
|
-
let normalized = Object.assign({}, f);
|
|
4549
|
-
if (f.dataType === 'DATETIME' && f.operator !== 'isEmpty' && f.operator !== 'isNotEmpty') {
|
|
4550
|
-
if (typeof normalized.value === 'string' && normalized.value) {
|
|
4551
|
-
normalized.from = this.dateLocalToUTCStart(normalized.value);
|
|
4552
|
-
normalized.to = this.dateLocalToUTCEndExclusive(normalized.value);
|
|
4553
|
-
normalized.value = undefined;
|
|
4554
|
-
}
|
|
4555
|
-
else {
|
|
4556
|
-
if (typeof normalized.from === 'string' && normalized.from)
|
|
4557
|
-
normalized.from = this.dateLocalToUTCStart(normalized.from);
|
|
4558
|
-
if (typeof normalized.to === 'string' && normalized.to)
|
|
4559
|
-
normalized.to = this.dateLocalToUTCEndExclusive(normalized.to);
|
|
4560
|
-
}
|
|
4561
|
-
}
|
|
4939
|
+
const normalized = normalizeDatetimeFilter(f);
|
|
4562
4940
|
const next = new Map(this.activeFilters);
|
|
4563
|
-
if (
|
|
4941
|
+
if (filterHasValue(normalized)) {
|
|
4564
4942
|
next.set(normalized.field, normalized);
|
|
4565
4943
|
}
|
|
4566
4944
|
else {
|
|
@@ -4615,140 +4993,53 @@ const MrdTable = class {
|
|
|
4615
4993
|
toggleViewPopover(e) {
|
|
4616
4994
|
e.stopPropagation();
|
|
4617
4995
|
if (this.viewPopoverOpen) {
|
|
4618
|
-
this.
|
|
4619
|
-
if (this.viewPopoverClickHandler) {
|
|
4620
|
-
document.removeEventListener('click', this.viewPopoverClickHandler);
|
|
4621
|
-
this.viewPopoverClickHandler = null;
|
|
4622
|
-
}
|
|
4996
|
+
this.closeViewPopover();
|
|
4623
4997
|
return;
|
|
4624
4998
|
}
|
|
4625
4999
|
this.viewPopoverOpen = true;
|
|
4626
|
-
this.viewPopoverClickHandler = () =>
|
|
4627
|
-
|
|
5000
|
+
this.viewPopoverClickHandler = () => this.closeViewPopover();
|
|
5001
|
+
document.addEventListener('click', this.viewPopoverClickHandler);
|
|
5002
|
+
}
|
|
5003
|
+
closeViewPopover() {
|
|
5004
|
+
this.viewPopoverOpen = false;
|
|
5005
|
+
if (this.viewPopoverClickHandler) {
|
|
4628
5006
|
document.removeEventListener('click', this.viewPopoverClickHandler);
|
|
4629
5007
|
this.viewPopoverClickHandler = null;
|
|
4630
|
-
}
|
|
4631
|
-
document.addEventListener('click', this.viewPopoverClickHandler);
|
|
5008
|
+
}
|
|
4632
5009
|
}
|
|
4633
5010
|
// ── Render: toolbar ────────────────────────────────────────────────────────
|
|
4634
5011
|
renderToolbar() {
|
|
4635
5012
|
var _a;
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
} }, v.label)))))), index.h("button", { class: "mrd-table__view-arrow", "aria-label": "Next view", onClick: () => this.handleViewSwitch((this.activeViewIdx + 1) % allViews.length) }, "\u25B6")))), hasActions && (index.h("div", { class: "mrd-table__toolbar-right" }, actions.map(a => {
|
|
4650
|
-
var _a, _b, _c;
|
|
4651
|
-
const createTypes = a.action === 'create' ? (_a = this.item) === null || _a === void 0 ? void 0 : _a.createTypes : null;
|
|
4652
|
-
if (createTypes === null || createTypes === void 0 ? void 0 : createTypes.length) {
|
|
4653
|
-
return (index.h("div", { class: "mrd-table__create-picker-wrap", key: `action-${a.action}` }, index.h("button", { class: `mrd-table__action mrd-table__action--${(_b = a.variant) !== null && _b !== void 0 ? _b : 'secondary'}`, onClick: () => this.toggleCreatePicker() }, a.icon
|
|
4654
|
-
? index.h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, index.h("use", { href: a.icon }))
|
|
4655
|
-
: a.label, index.h("span", { class: "mrd-table__action-tooltip" }, a.label)), this.createPickerOpen && (index.h("div", { class: "mrd-table__create-picker" }, createTypes.map(ct => (index.h("button", { key: ct.type, class: "mrd-table__create-picker-item", onClick: () => {
|
|
4656
|
-
this.mrdAction.emit(this.buildActionDetail('create', ct.type));
|
|
4657
|
-
this.closeCreatePicker();
|
|
4658
|
-
} }, ct.label)))))));
|
|
4659
|
-
}
|
|
4660
|
-
return (index.h("button", { key: `action-${a.action}`, class: `mrd-table__action mrd-table__action--${(_c = a.variant) !== null && _c !== void 0 ? _c : 'secondary'}`, disabled: a.disabled, onClick: () => this.mrdAction.emit(this.buildActionDetail(a.action)) }, a.icon
|
|
4661
|
-
? index.h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, index.h("use", { href: a.icon }))
|
|
4662
|
-
: a.label, index.h("span", { class: "mrd-table__action-tooltip" }, a.label)));
|
|
4663
|
-
})))));
|
|
5013
|
+
return (index.h(Toolbar, { locale: this.locale, filterMode: this.filterMode, filterCount: this.activeFilters.size, actions: this.tableActions, views: this.allViews, activeViewIdx: this.activeViewIdx, viewPopoverOpen: this.viewPopoverOpen, createPickerOpen: this.createPickerOpen, createTypes: (_a = this.item) === null || _a === void 0 ? void 0 : _a.createTypes, cb: {
|
|
5014
|
+
onFilterToggle: () => this.handleFilterToggle(),
|
|
5015
|
+
onClearAllFilters: () => this.clearAllFilters(),
|
|
5016
|
+
onViewSwitch: idx => this.handleViewSwitch(idx),
|
|
5017
|
+
onToggleViewPopover: e => this.toggleViewPopover(e),
|
|
5018
|
+
onCloseViewPopover: () => this.closeViewPopover(),
|
|
5019
|
+
onToggleCreatePicker: () => this.toggleCreatePicker(),
|
|
5020
|
+
onCreate: basicType => {
|
|
5021
|
+
this.mrdAction.emit(this.buildActionDetail('create', basicType));
|
|
5022
|
+
this.closeCreatePicker();
|
|
5023
|
+
},
|
|
5024
|
+
onAction: action => this.mrdAction.emit(this.buildActionDetail(action)),
|
|
5025
|
+
} }));
|
|
4664
5026
|
}
|
|
4665
5027
|
// ── Render: filter popup ───────────────────────────────────────────────────
|
|
4666
|
-
renderFilterEditor(col) {
|
|
4667
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
4668
|
-
const pf = (_a = this.pendingFilter) !== null && _a !== void 0 ? _a : {};
|
|
4669
|
-
const dataType = this.colDataType(col);
|
|
4670
|
-
if (NO_FILTER_TYPES.has(dataType)) {
|
|
4671
|
-
return index.h("p", { class: "mrd-table__filter-no-support" }, t('filter_no_support', this.locale));
|
|
4672
|
-
}
|
|
4673
|
-
if (dataType === 'BOOLEAN') {
|
|
4674
|
-
const boolOp = pf.operator;
|
|
4675
|
-
const noValueOp = boolOp === 'isEmpty' || boolOp === 'isNotEmpty';
|
|
4676
|
-
return (index.h("div", { class: "mrd-table__filter-radio-group" }, [
|
|
4677
|
-
{ labelKey: 'filter_all', value: null },
|
|
4678
|
-
{ labelKey: 'yes', value: true },
|
|
4679
|
-
{ labelKey: 'no', value: false },
|
|
4680
|
-
].map(opt => (index.h("label", { class: "mrd-table__filter-radio-label" }, index.h("input", { type: "radio", name: `bf-${this.openFilterCol}`, checked: !noValueOp && pf.value === opt.value, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined, value: opt.value }); } }), t(opt.labelKey, this.locale)))), index.h("label", { class: "mrd-table__filter-radio-label" }, index.h("input", { type: "radio", name: `bf-${this.openFilterCol}`, checked: boolOp === 'isEmpty', onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: 'isEmpty', value: undefined }); } }), t('filter_is_empty', this.locale)), index.h("label", { class: "mrd-table__filter-radio-label" }, index.h("input", { type: "radio", name: `bf-${this.openFilterCol}`, checked: boolOp === 'isNotEmpty', onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: 'isNotEmpty', value: undefined }); } }), t('filter_is_not_empty', this.locale))));
|
|
4681
|
-
}
|
|
4682
|
-
if (dataType === 'LIST') {
|
|
4683
|
-
const items = (_b = col.listItems) !== null && _b !== void 0 ? _b : [];
|
|
4684
|
-
const selected = (_c = pf.values) !== null && _c !== void 0 ? _c : [];
|
|
4685
|
-
return (index.h("div", { class: "mrd-table__filter-list" }, index.h("div", { class: "mrd-table__filter-list-controls" }, index.h("button", { class: "mrd-table__filter-list-btn", onClick: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { values: items.map(i => i.key) }); } }, t('filter_select_all', this.locale)), index.h("button", { class: "mrd-table__filter-list-btn", onClick: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { values: [] }); } }, t('filter_select_none', this.locale))), items.map(item => (index.h("label", { class: "mrd-table__filter-checkbox-label" }, index.h("input", { type: "checkbox", checked: selected.includes(item.key), onChange: (e) => this.togglePendingValue(item.key, e.target.checked) }), item.label)))));
|
|
4686
|
-
}
|
|
4687
|
-
if (TEXT_TYPES.has(dataType) || dataType === 'RELATION') {
|
|
4688
|
-
const op = (_d = pf.operator) !== null && _d !== void 0 ? _d : 'startsWith';
|
|
4689
|
-
const noInput = op === 'isEmpty' || op === 'isNotEmpty';
|
|
4690
|
-
return (index.h("div", { class: "mrd-table__filter-editor" }, index.h("select", { class: "mrd-table__filter-select", onChange: (e) => this.setPending('operator', e.target.value) }, [
|
|
4691
|
-
{ val: 'startsWith', labelKey: 'filter_starts_with' },
|
|
4692
|
-
{ val: 'equals', labelKey: 'filter_equals' },
|
|
4693
|
-
{ val: 'isEmpty', labelKey: 'filter_is_empty' },
|
|
4694
|
-
{ val: 'isNotEmpty', labelKey: 'filter_is_not_empty' },
|
|
4695
|
-
].map(o => index.h("option", { value: o.val, selected: op === o.val }, t(o.labelKey, this.locale)))), !noInput && (index.h("input", { type: "text", class: "mrd-table__filter-input", value: String((_e = pf.value) !== null && _e !== void 0 ? _e : ''), placeholder: t('filter_search_value', this.locale), onInput: (e) => this.setPending('value', e.target.value) }))));
|
|
4696
|
-
}
|
|
4697
|
-
if (NUMERIC_TYPES.has(dataType)) {
|
|
4698
|
-
const numOp = pf.operator;
|
|
4699
|
-
const noInput = numOp === 'isEmpty' || numOp === 'isNotEmpty';
|
|
4700
|
-
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4701
|
-
return (index.h("div", { class: "mrd-table__filter-editor" }, index.h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4702
|
-
const val = e.target.value;
|
|
4703
|
-
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4704
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined });
|
|
4705
|
-
}
|
|
4706
|
-
else {
|
|
4707
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined });
|
|
4708
|
-
}
|
|
4709
|
-
} }, index.h("option", { value: "", selected: !noInput }, t('filter_has_value', this.locale)), index.h("option", { value: "isEmpty", selected: numOp === 'isEmpty' }, t('filter_is_empty', this.locale)), index.h("option", { value: "isNotEmpty", selected: numOp === 'isNotEmpty' }, t('filter_is_not_empty', this.locale))), !noInput && (index.h("div", { class: "mrd-table__filter-editor" }, index.h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, index.h("label", { class: "mrd-table__filter-radio-label" }, index.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)), index.h("label", { class: "mrd-table__filter-radio-label" }, index.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 ? (index.h("input", { type: "number", class: "mrd-table__filter-input", value: pf.value != null ? String(pf.value) : '', onInput: (e) => this.setPending('value', e.target.value) })) : (index.h("div", { class: "mrd-table__filter-range" }, index.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) }), index.h("span", { class: "mrd-table__filter-range-sep" }, "\u2013"), index.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) })))))));
|
|
4710
|
-
}
|
|
4711
|
-
if (dataType === 'DATETIME') {
|
|
4712
|
-
const dtOp = pf.operator;
|
|
4713
|
-
const noInput = dtOp === 'isEmpty' || dtOp === 'isNotEmpty';
|
|
4714
|
-
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4715
|
-
return (index.h("div", { class: "mrd-table__filter-editor" }, index.h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4716
|
-
const val = e.target.value;
|
|
4717
|
-
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4718
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined });
|
|
4719
|
-
}
|
|
4720
|
-
else {
|
|
4721
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined });
|
|
4722
|
-
}
|
|
4723
|
-
} }, index.h("option", { value: "", selected: !noInput }, t('filter_has_value', this.locale)), index.h("option", { value: "isEmpty", selected: dtOp === 'isEmpty' }, t('filter_is_empty', this.locale)), index.h("option", { value: "isNotEmpty", selected: dtOp === 'isNotEmpty' }, t('filter_is_not_empty', this.locale))), !noInput && (index.h("div", { class: "mrd-table__filter-editor" }, index.h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, index.h("label", { class: "mrd-table__filter-radio-label" }, index.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)), index.h("label", { class: "mrd-table__filter-radio-label" }, index.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 ? (index.h("input", { type: "date", class: "mrd-table__filter-input", value: String((_f = pf.value) !== null && _f !== void 0 ? _f : ''), onInput: (e) => this.setPending('value', e.target.value) })) : (index.h("div", { class: "mrd-table__filter-range mrd-table__filter-range--stacked" }, index.h("label", { class: "mrd-table__filter-range-label" }, t('filter_from', this.locale)), index.h("input", { type: "date", class: "mrd-table__filter-input", value: pf.from != null ? String(pf.from) : '', onInput: (e) => this.setPending('from', e.target.value) }), index.h("label", { class: "mrd-table__filter-range-label" }, t('filter_to', this.locale)), index.h("input", { type: "date", class: "mrd-table__filter-input", value: pf.to != null ? String(pf.to) : '', onInput: (e) => this.setPending('to', e.target.value) })))))));
|
|
4724
|
-
}
|
|
4725
|
-
if (DATE_TYPES.has(dataType)) {
|
|
4726
|
-
const inputType = dataType === 'DATE' ? 'date' : 'time';
|
|
4727
|
-
const dtdOp = pf.operator;
|
|
4728
|
-
const noInput = dtdOp === 'isEmpty' || dtdOp === 'isNotEmpty';
|
|
4729
|
-
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4730
|
-
return (index.h("div", { class: "mrd-table__filter-editor" }, index.h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4731
|
-
const val = e.target.value;
|
|
4732
|
-
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4733
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined });
|
|
4734
|
-
}
|
|
4735
|
-
else {
|
|
4736
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined });
|
|
4737
|
-
}
|
|
4738
|
-
} }, index.h("option", { value: "", selected: !noInput }, t('filter_has_value', this.locale)), index.h("option", { value: "isEmpty", selected: dtdOp === 'isEmpty' }, t('filter_is_empty', this.locale)), index.h("option", { value: "isNotEmpty", selected: dtdOp === 'isNotEmpty' }, t('filter_is_not_empty', this.locale))), !noInput && (index.h("div", { class: "mrd-table__filter-editor" }, index.h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, index.h("label", { class: "mrd-table__filter-radio-label" }, index.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)), index.h("label", { class: "mrd-table__filter-radio-label" }, index.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 ? (index.h("input", { type: inputType, class: "mrd-table__filter-input", value: String((_g = pf.value) !== null && _g !== void 0 ? _g : ''), onInput: (e) => this.setPending('value', e.target.value) })) : (index.h("div", { class: "mrd-table__filter-range" }, index.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) }), index.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) })))))));
|
|
4739
|
-
}
|
|
4740
|
-
return null;
|
|
4741
|
-
}
|
|
4742
5028
|
renderFilterPopup() {
|
|
4743
|
-
var _a;
|
|
4744
5029
|
if (!this.openFilterCol || !this.pendingFilter)
|
|
4745
5030
|
return null;
|
|
4746
5031
|
const col = this.columns.find(c => this.colName(c) === this.openFilterCol);
|
|
4747
5032
|
if (!col)
|
|
4748
5033
|
return null;
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
5034
|
+
return (index.h(FilterPopup, { col: col, dataType: this.colDataType(col), openFilterCol: this.openFilterCol, pendingFilter: this.pendingFilter, popupPos: this.popupPos, sortField: this.sortField, sortDir: this.sortDir, locale: this.locale, cb: {
|
|
5035
|
+
onSetPending: (key, val) => this.setPending(key, val),
|
|
5036
|
+
onReplacePending: pf => (this.pendingFilter = pf),
|
|
5037
|
+
onToggleValue: (key, checked) => this.togglePendingValue(key, checked),
|
|
5038
|
+
onApplySort: dir => this.applySort(col, dir),
|
|
5039
|
+
onApply: () => this.applyFilter(),
|
|
5040
|
+
onClear: () => this.clearFilter(),
|
|
5041
|
+
onClose: () => this.closeFilterPopup(),
|
|
5042
|
+
} }));
|
|
4752
5043
|
}
|
|
4753
5044
|
// ── Render: footer ────────────────────────────────────────────────────────
|
|
4754
5045
|
renderFooter(rowCount, effectiveTotal, isTotalKnown = true) {
|
|
@@ -4773,54 +5064,11 @@ const MrdTable = class {
|
|
|
4773
5064
|
}
|
|
4774
5065
|
// ── Render: cell ──────────────────────────────────────────────────────────
|
|
4775
5066
|
renderCell(col, row) {
|
|
4776
|
-
|
|
4777
|
-
const numericTypes = new Set(['INTEGER', 'DECIMAL', 'PERCENTAGE', 'CURRENCY']);
|
|
4778
|
-
const dataType = (_a = col.dataType) !== null && _a !== void 0 ? _a : '';
|
|
4779
|
-
const isNumeric = col.type === 'FIELD' && numericTypes.has(dataType);
|
|
4780
|
-
const isFile = col.type === 'FIELD' && (dataType === 'FILE' || dataType === 'IMAGE');
|
|
4781
|
-
if (isFile) {
|
|
4782
|
-
const name = (_b = col.name) !== null && _b !== void 0 ? _b : '';
|
|
4783
|
-
const fileVal = row === null || row === void 0 ? void 0 : row[name];
|
|
4784
|
-
const href = fileVal === null || fileVal === void 0 ? void 0 : fileVal.href;
|
|
4785
|
-
const fileName = fileVal === null || fileVal === void 0 ? void 0 : fileVal.fileName;
|
|
4786
|
-
return (index.h("td", { class: "mrd-table__cell" }, href && fileName ? (index.h("button", { class: "mrd-table__file-btn", title: fileName, onClick: (e) => {
|
|
4787
|
-
e.stopPropagation();
|
|
4788
|
-
this.mrdDownload.emit({ href, fileName });
|
|
4789
|
-
} }, index.h("svg", { class: "mrd-table__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, index.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))) : ''));
|
|
4790
|
-
}
|
|
4791
|
-
if (dataType === 'JSON') {
|
|
4792
|
-
const name = (_c = col.name) !== null && _c !== void 0 ? _c : '';
|
|
4793
|
-
const rawValue = name ? row === null || row === void 0 ? void 0 : row[name] : undefined;
|
|
4794
|
-
if (rawValue == null || rawValue === '')
|
|
4795
|
-
return index.h("td", { class: "mrd-table__cell" });
|
|
4796
|
-
const compactHtml = CellRenderer.formatJson(rawValue, true);
|
|
4797
|
-
const prettyHtml = CellRenderer.formatJson(rawValue, false);
|
|
4798
|
-
return (index.h("td", { class: "mrd-table__cell" }, index.h("span", { class: "mrd-table__json-preview", innerHTML: compactHtml }), index.h("button", { class: "mrd-table__textblock-btn", onClick: (e) => { e.stopPropagation(); this.openJsonModal(prettyHtml); }, "aria-label": t('textblock_show_more', this.locale) }, "\u22EF")));
|
|
4799
|
-
}
|
|
4800
|
-
const TEXTBLOCK_MAX = 200;
|
|
4801
|
-
if (dataType === 'TEXTBLOCK') {
|
|
4802
|
-
const full = CellRenderer.render(col, row, this.locale);
|
|
4803
|
-
if (full.length <= TEXTBLOCK_MAX) {
|
|
4804
|
-
return index.h("td", { class: "mrd-table__cell" }, full);
|
|
4805
|
-
}
|
|
4806
|
-
const preview = full.slice(0, TEXTBLOCK_MAX) + '…';
|
|
4807
|
-
return (index.h("td", { class: "mrd-table__cell" }, preview, index.h("button", { class: "mrd-table__textblock-btn", onClick: (e) => { e.stopPropagation(); this.openTextblockModal(full); }, "aria-label": t('textblock_show_more', this.locale) }, "\u22EF")));
|
|
4808
|
-
}
|
|
4809
|
-
const value = CellRenderer.render(col, row, this.locale);
|
|
4810
|
-
return (index.h("td", { class: `mrd-table__cell${isNumeric ? ' mrd-table__cell--numeric' : ''}` }, value));
|
|
5067
|
+
return (index.h(TableCell, { col: col, row: row, locale: this.locale, onDownload: detail => this.mrdDownload.emit(detail), onOpenTextblock: full => this.openTextblockModal(full), onOpenJson: html => this.openJsonModal(html) }));
|
|
4811
5068
|
}
|
|
4812
5069
|
// ── Render: totals row ────────────────────────────────────────────────────
|
|
4813
5070
|
renderTotalsRow() {
|
|
4814
|
-
|
|
4815
|
-
return null;
|
|
4816
|
-
if (!this.columns.some(c => c.type === 'FIELD' && c.aggregate))
|
|
4817
|
-
return null;
|
|
4818
|
-
return (index.h("tfoot", null, index.h("tr", { class: "mrd-table__totals-row" }, this.columns.map(col => {
|
|
4819
|
-
var _a;
|
|
4820
|
-
const val = this.renderAggregationValue(col);
|
|
4821
|
-
const isNumeric = col.type === 'FIELD' && NUMERIC_TYPES.has((_a = col.dataType) !== null && _a !== void 0 ? _a : '');
|
|
4822
|
-
return (index.h("td", { class: `mrd-table__totals-cell${isNumeric ? ' mrd-table__totals-cell--numeric' : ''}` }, val));
|
|
4823
|
-
}))));
|
|
5071
|
+
return index.h(TotalsRow, { columns: this.columns, aggregations: this.aggregations, locale: this.locale });
|
|
4824
5072
|
}
|
|
4825
5073
|
// ── Render ─────────────────────────────────────────────────────────────────
|
|
4826
5074
|
render() {
|
|
@@ -4840,7 +5088,7 @@ const MrdTable = class {
|
|
|
4840
5088
|
isFiltered ? 'mrd-table__header--filtered' : '',
|
|
4841
5089
|
this.filterMode ? 'mrd-table__header--sortable' : '',
|
|
4842
5090
|
].filter(Boolean).join(' ');
|
|
4843
|
-
return (index.h("th", { class: cls, onClick: this.filterMode ? (e) => this.handleFilterOpen(col, e) : undefined }, index.h("span", { class: "mrd-table__header-label" }, (_a = col.label) !== null && _a !== void 0 ? _a : ''), isFiltered &&
|
|
5091
|
+
return (index.h("th", { class: cls, onClick: this.filterMode ? (e) => this.handleFilterOpen(col, e) : undefined }, index.h("span", { class: "mrd-table__header-label" }, (_a = col.label) !== null && _a !== void 0 ? _a : ''), isFiltered && index.h(FilterIcon, null)));
|
|
4844
5092
|
}))), index.h("tbody", null, (_b = this.rows) === null || _b === void 0 ? void 0 : _b.map((row, i) => (index.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) && (index.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()));
|
|
4845
5093
|
}
|
|
4846
5094
|
// ── Paginated / virtual-scroll mode ────────────────────────────────────
|
|
@@ -4848,12 +5096,7 @@ const MrdTable = class {
|
|
|
4848
5096
|
// if any loaded page is shorter than pageSize it is the last page,
|
|
4849
5097
|
// so the true total cannot exceed (pageNum * pageSize + pageRows.length).
|
|
4850
5098
|
// aggregationsTotal (from setAggregations) takes priority over the totalElements prop.
|
|
4851
|
-
|
|
4852
|
-
for (const [pageNum, pageRows] of this.loadedPages) {
|
|
4853
|
-
if (pageRows.length < this.pageSize) {
|
|
4854
|
-
effectiveTotal = Math.min(effectiveTotal, pageNum * this.pageSize + pageRows.length);
|
|
4855
|
-
}
|
|
4856
|
-
}
|
|
5099
|
+
const effectiveTotal = computeEffectiveTotal(this.loadedPages, this.pageSize, this.baseTotal);
|
|
4857
5100
|
// Clamp renderEnd to what we actually know exists (-1 when empty)
|
|
4858
5101
|
const clampedEnd = Math.min(this.renderEnd, effectiveTotal - 1);
|
|
4859
5102
|
const colCount = this.columns.length;
|
|
@@ -4866,7 +5109,13 @@ const MrdTable = class {
|
|
|
4866
5109
|
for (let i = this.renderStart; i <= clampedEnd; i++) {
|
|
4867
5110
|
const row = this.getRow(i);
|
|
4868
5111
|
if (row === null) {
|
|
4869
|
-
|
|
5112
|
+
const page = Math.floor(i / this.pageSize);
|
|
5113
|
+
if (this.failedPages.has(page)) {
|
|
5114
|
+
renderedRows.push(index.h("tr", { class: "mrd-table__row mrd-table__row--failed" }, index.h("td", { class: "mrd-table__cell--failed", colSpan: colCount }, index.h("button", { type: "button", class: "mrd-table__retry-button", onClick: () => this.retryPage(page) }, t('load_failed_retry', this.locale)))));
|
|
5115
|
+
}
|
|
5116
|
+
else {
|
|
5117
|
+
renderedRows.push(index.h("tr", { class: "mrd-table__row mrd-table__row--loading" }, index.h("td", { class: "mrd-table__cell--placeholder", colSpan: colCount }, index.h("span", { class: "mrd-table__placeholder-bar" }))));
|
|
5118
|
+
}
|
|
4870
5119
|
}
|
|
4871
5120
|
else {
|
|
4872
5121
|
renderedRows.push(index.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))));
|
|
@@ -4884,21 +5133,14 @@ const MrdTable = class {
|
|
|
4884
5133
|
isActive ? `mrd-table__header--sorted-${this.sortDir}` : '',
|
|
4885
5134
|
isFiltered ? 'mrd-table__header--filtered' : '',
|
|
4886
5135
|
].filter(Boolean).join(' ');
|
|
4887
|
-
return (index.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 }, index.h("span", { class: "mrd-table__header-label" }, (_a = col.label) !== null && _a !== void 0 ? _a : ''), isInteractive && isActive && (index.h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, this.sortDir === 'asc' ? '▲' : '▼')), isInteractive && !isActive && !this.filterMode && (index.h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, "\u21C5")), isInteractive && isFiltered &&
|
|
4888
|
-
}))), index.h("tbody", null, topSpacerHeight > 0 && (index.h("tr", { class: "mrd-table__spacer", style: { height: `${topSpacerHeight}px` } }, index.h("td", { colSpan: colCount }))), renderedRows, bottomSpacerHeight > 0 && (index.h("tr", { class: "mrd-table__spacer", style: { height: `${bottomSpacerHeight}px` } }, index.h("td", { colSpan: colCount })))), this.renderTotalsRow())), effectiveTotal === 0 && this.loadedPages.has(0) && (index.h("p", { class: "mrd-table__empty" }, t('no_results', this.locale))), effectiveTotal > 0 && this.renderFooter(undefined, effectiveTotal, this.isTotalKnown()), this.renderFilterPopup(), this.renderTextblockModal()));
|
|
4889
|
-
}
|
|
4890
|
-
renderFilterIcon() {
|
|
4891
|
-
return (index.h("span", { class: "mrd-table__filter-icon", "aria-hidden": "true" }, index.h("svg", { viewBox: "0 0 24 24", width: "14", height: "14", fill: "currentColor" }, index.h("path", { d: "M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" }))));
|
|
5136
|
+
return (index.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 }, index.h("span", { class: "mrd-table__header-label" }, (_a = col.label) !== null && _a !== void 0 ? _a : ''), isInteractive && isActive && (index.h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, this.sortDir === 'asc' ? '▲' : '▼')), isInteractive && !isActive && !this.filterMode && (index.h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, "\u21C5")), isInteractive && isFiltered && index.h(FilterIcon, null)));
|
|
5137
|
+
}))), index.h("tbody", null, topSpacerHeight > 0 && (index.h("tr", { class: "mrd-table__spacer", style: { height: `${topSpacerHeight}px` } }, index.h("td", { colSpan: colCount }))), renderedRows, bottomSpacerHeight > 0 && (index.h("tr", { class: "mrd-table__spacer", style: { height: `${bottomSpacerHeight}px` } }, index.h("td", { colSpan: colCount })))), this.renderTotalsRow())), effectiveTotal === 0 && this.loadedPages.has(0) && (index.h("p", { class: "mrd-table__empty" }, t('no_results', this.locale))), effectiveTotal > 0 && this.renderFooter(undefined, effectiveTotal, this.isTotalKnown()), this.renderFilterPopup(), this.renderTextblockModal(), this.renderJsonModal()));
|
|
4892
5138
|
}
|
|
4893
5139
|
renderTextblockModal() {
|
|
4894
|
-
|
|
4895
|
-
return null;
|
|
4896
|
-
return (index.h("div", { class: "mrd-table__modal-backdrop", onClick: () => this.closeTextblockModal(), role: "dialog", "aria-modal": "true" }, index.h("div", { class: "mrd-table__modal", onClick: (e) => e.stopPropagation() }, index.h("button", { class: "mrd-table__modal-close", onClick: () => this.closeTextblockModal(), "aria-label": t('close', this.locale) }, "\u2715"), index.h("p", { class: "mrd-table__modal-text" }, this.textblockModal))));
|
|
5140
|
+
return index.h(TextblockModal, { text: this.textblockModal, locale: this.locale, onClose: () => this.closeTextblockModal() });
|
|
4897
5141
|
}
|
|
4898
5142
|
renderJsonModal() {
|
|
4899
|
-
|
|
4900
|
-
return null;
|
|
4901
|
-
return (index.h("div", { class: "mrd-table__modal-backdrop", onClick: () => this.closeJsonModal(), role: "dialog", "aria-modal": "true" }, index.h("div", { class: "mrd-table__modal", onClick: (e) => e.stopPropagation() }, index.h("button", { class: "mrd-table__modal-close", onClick: () => this.closeJsonModal(), "aria-label": t('close', this.locale) }, "\u2715"), index.h("pre", { class: "mrd-table__modal-json", innerHTML: this.jsonModal }))));
|
|
5143
|
+
return index.h(JsonModal, { html: this.jsonModal, locale: this.locale, onClose: () => this.closeJsonModal() });
|
|
4902
5144
|
}
|
|
4903
5145
|
get el() { return index.getElement(this); }
|
|
4904
5146
|
static get watchers() { return {
|
|
@@ -4910,9 +5152,9 @@ const MrdTable = class {
|
|
|
4910
5152
|
}]
|
|
4911
5153
|
}; }
|
|
4912
5154
|
};
|
|
4913
|
-
MrdTable.style =
|
|
5155
|
+
MrdTable.style = mrdTableCss();
|
|
4914
5156
|
|
|
4915
|
-
const
|
|
5157
|
+
const mrdTextFieldCss = () => `.sc-mrd-text-field-h{display:block}.mrd-text-field.sc-mrd-text-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-text-field__label.sc-mrd-text-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-text-field__label--required.sc-mrd-text-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-text-field__input.sc-mrd-text-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-text-field__input.sc-mrd-text-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-text-field__input.sc-mrd-text-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-text-field__input.sc-mrd-text-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-text-field__input--error.sc-mrd-text-field{border-color:var(--mrd-border-color-error)}.mrd-text-field__input--error.sc-mrd-text-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-text-field__error.sc-mrd-text-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}`;
|
|
4916
5158
|
|
|
4917
5159
|
const MrdTextField = class {
|
|
4918
5160
|
constructor(hostRef) {
|
|
@@ -4933,23 +5175,17 @@ const MrdTextField = class {
|
|
|
4933
5175
|
};
|
|
4934
5176
|
this.handleBlur = (e) => {
|
|
4935
5177
|
const val = e.target.value;
|
|
4936
|
-
|
|
4937
|
-
this.error = t('required', this.locale);
|
|
4938
|
-
}
|
|
4939
|
-
else {
|
|
4940
|
-
this.error = '';
|
|
4941
|
-
}
|
|
5178
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
4942
5179
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
4943
5180
|
};
|
|
4944
5181
|
}
|
|
4945
5182
|
render() {
|
|
4946
|
-
|
|
4947
|
-
return (index.h(index.Host, { key: 'e9252b251faf98ab190e643b97c13fa32d12ef22' }, index.h("div", { key: '37f4259a111c293f2fe12f321f08c00c25e77feb', class: "mrd-text-field" }, this.label && (index.h("label", { key: 'c59e0346fb71a765ea38629b03c06341567ed210', class: `mrd-text-field__label${this.required ? ' mrd-text-field__label--required' : ''}` }, this.label)), index.h("input", { key: 'dc09953a672472348719f29904d900966d945843', class: `mrd-text-field__input${hasError ? ' mrd-text-field__input--error' : ''}`, type: "text", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur }), hasError && index.h("span", { key: '037653857a372854a16b28ebf8994b23e3e0d696', class: "mrd-text-field__error" }, this.error))));
|
|
5183
|
+
return (index.h(index.Host, { key: '71de1ae949941820574fc2d45cac6cca8264d8f9' }, index.h("div", { key: 'a63d3dd0811e012ae3d5a9f02c1a2ad1fcc0af86', class: "mrd-text-field" }, index.h(FieldLabel, { key: '1a6db878b634364f47522209344540a9cdc20635', base: "mrd-text-field", label: this.label, required: this.required }), index.h("input", { key: 'b3cd0338f13c5c2c8b744df62d3d02f3bc380aa1', class: controlClass('mrd-text-field', !!this.error), type: "text", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur }), index.h(FieldError, { key: '1530066fefbda722df0c37871978995a139fcef0', base: "mrd-text-field", error: this.error }))));
|
|
4948
5184
|
}
|
|
4949
5185
|
};
|
|
4950
|
-
MrdTextField.style =
|
|
5186
|
+
MrdTextField.style = mrdTextFieldCss();
|
|
4951
5187
|
|
|
4952
|
-
const
|
|
5188
|
+
const mrdTextareaFieldCss = () => `.sc-mrd-textarea-field-h{display:block}.mrd-textarea-field.sc-mrd-textarea-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-textarea-field__label.sc-mrd-textarea-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-textarea-field__label--required.sc-mrd-textarea-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-textarea-field__error.sc-mrd-textarea-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-textarea-field__container.sc-mrd-textarea-field{border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);overflow:hidden;background-color:var(--mrd-input-bg);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition)}.mrd-textarea-field__container.sc-mrd-textarea-field:focus-within{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-textarea-field__container--error.sc-mrd-textarea-field{border-color:var(--mrd-border-color-error)}.mrd-textarea-field__container--error.sc-mrd-textarea-field:focus-within{box-shadow:var(--mrd-shadow-focus-error)}.mrd-textarea-field__editor.sc-mrd-textarea-field{min-height:150px;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base)}.mrd-textarea-field__editor.sc-mrd-textarea-field .ql-toolbar.sc-mrd-textarea-field{border:none;border-bottom:var(--mrd-border-width) solid var(--mrd-border-color);font-family:var(--mrd-font-family)}.mrd-textarea-field__editor.sc-mrd-textarea-field .ql-container.sc-mrd-textarea-field{border:none;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base)}.mrd-textarea-field__editor.sc-mrd-textarea-field .ql-editor.sc-mrd-textarea-field{min-height:120px;padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x)}.mrd-textarea-field__editor.sc-mrd-textarea-field .ql-editor.ql-blank.sc-mrd-textarea-field::before{color:var(--mrd-input-placeholder-color);font-style:normal}`;
|
|
4953
5189
|
|
|
4954
5190
|
const MrdTextareaField = class {
|
|
4955
5191
|
constructor(hostRef) {
|
|
@@ -5002,12 +5238,7 @@ const MrdTextareaField = class {
|
|
|
5002
5238
|
var _a, _b;
|
|
5003
5239
|
if (!range) {
|
|
5004
5240
|
const html = (_b = (_a = this.editorEl.querySelector('.ql-editor')) === null || _a === void 0 ? void 0 : _a.innerHTML) !== null && _b !== void 0 ? _b : '';
|
|
5005
|
-
|
|
5006
|
-
this.error = t('required', this.locale);
|
|
5007
|
-
}
|
|
5008
|
-
else {
|
|
5009
|
-
this.error = '';
|
|
5010
|
-
}
|
|
5241
|
+
this.error = requiredError(html, this.required, this.locale);
|
|
5011
5242
|
this.mrdBlur.emit({ name: this.name, value: html });
|
|
5012
5243
|
}
|
|
5013
5244
|
});
|
|
@@ -5018,13 +5249,13 @@ const MrdTextareaField = class {
|
|
|
5018
5249
|
}
|
|
5019
5250
|
}
|
|
5020
5251
|
render() {
|
|
5021
|
-
return (index.h(index.Host, { key: '
|
|
5252
|
+
return (index.h(index.Host, { key: '464c1edde8447043d9352f1b5f9757bba97e9b17' }, index.h("div", { key: '8d06728214f54feeb1063700e5aaf7c439eb5473', class: "mrd-textarea-field" }, index.h(FieldLabel, { key: 'dbf93ecf41bd704706b49f8c455262798fbbe10b', base: "mrd-textarea-field", label: this.label, required: this.required }), index.h("div", { key: '9c39ccfa38ee01b880973966e910ee32aa60b144', class: controlClass('mrd-textarea-field', !!this.error, 'container') }, index.h("div", { key: '0217cd4350c1933018b2b8f489516b6d43a52538', class: "mrd-textarea-field__editor" })), index.h(FieldError, { key: '62d2a5db053ea6e4ec6868440f3ab31e1c05e633', base: "mrd-textarea-field", error: this.error }))));
|
|
5022
5253
|
}
|
|
5023
5254
|
get el() { return index.getElement(this); }
|
|
5024
5255
|
};
|
|
5025
|
-
MrdTextareaField.style =
|
|
5256
|
+
MrdTextareaField.style = mrdTextareaFieldCss();
|
|
5026
5257
|
|
|
5027
|
-
const
|
|
5258
|
+
const mrdTimeFieldCss = () => `.sc-mrd-time-field-h{display:block}.mrd-time-field.sc-mrd-time-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-time-field__label.sc-mrd-time-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-time-field__label--required.sc-mrd-time-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-time-field__input.sc-mrd-time-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-time-field__input.sc-mrd-time-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-time-field__input.sc-mrd-time-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-time-field__input.sc-mrd-time-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-time-field__input--error.sc-mrd-time-field{border-color:var(--mrd-border-color-error)}.mrd-time-field__input--error.sc-mrd-time-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-time-field__error.sc-mrd-time-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-time-field__input.sc-mrd-time-field{cursor:pointer}`;
|
|
5028
5259
|
|
|
5029
5260
|
const MrdTimeField = class {
|
|
5030
5261
|
constructor(hostRef) {
|
|
@@ -5040,12 +5271,7 @@ const MrdTimeField = class {
|
|
|
5040
5271
|
this.error = '';
|
|
5041
5272
|
this.handleChange = (e) => {
|
|
5042
5273
|
const val = e.target.value;
|
|
5043
|
-
|
|
5044
|
-
this.error = t('required', this.locale);
|
|
5045
|
-
}
|
|
5046
|
-
else {
|
|
5047
|
-
this.error = '';
|
|
5048
|
-
}
|
|
5274
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
5049
5275
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
5050
5276
|
};
|
|
5051
5277
|
this.handleBlur = (e) => {
|
|
@@ -5054,11 +5280,10 @@ const MrdTimeField = class {
|
|
|
5054
5280
|
};
|
|
5055
5281
|
}
|
|
5056
5282
|
render() {
|
|
5057
|
-
|
|
5058
|
-
return (index.h(index.Host, { key: '579219a478e31325b5a676465807c1d936724a2b' }, index.h("div", { key: '51b25f6e083a29989505c0ad79edbcd3b0060736', class: "mrd-time-field" }, this.label && (index.h("label", { key: '67d98bebb8803deea2d2a4a63f36706789ccd8c7', class: `mrd-time-field__label${this.required ? ' mrd-time-field__label--required' : ''}` }, this.label)), index.h("input", { key: '734741e0db1bdd5886fef37bba3b2f8d7200a0ab', class: `mrd-time-field__input${hasError ? ' mrd-time-field__input--error' : ''}`, type: "time", name: this.name, value: this.value, required: this.required, disabled: this.disabled, onChange: this.handleChange, onBlur: this.handleBlur }), hasError && index.h("span", { key: '0dbd168d14966dc56a77c97cd8fd8f9b208a4bf5', class: "mrd-time-field__error" }, this.error))));
|
|
5283
|
+
return (index.h(index.Host, { key: 'fc30bdeb7c8d37bebc67a768f48013602879fb3d' }, index.h("div", { key: '52f899a889376773c1948f0c116670684db25cf4', class: "mrd-time-field" }, index.h(FieldLabel, { key: '3aba58f122fa4bb9f0ba4ad0b56fc3b29f03d4a3', base: "mrd-time-field", label: this.label, required: this.required }), index.h("input", { key: 'e39718394a195eafaf47aa2e62d560341bb0daed', class: controlClass('mrd-time-field', !!this.error), type: "time", name: this.name, value: this.value, required: this.required, disabled: this.disabled, onChange: this.handleChange, onBlur: this.handleBlur }), index.h(FieldError, { key: '07ad4ccbc5188e129d8bd3085e856839ec6a81c9', base: "mrd-time-field", error: this.error }))));
|
|
5059
5284
|
}
|
|
5060
5285
|
};
|
|
5061
|
-
MrdTimeField.style =
|
|
5286
|
+
MrdTimeField.style = mrdTimeFieldCss();
|
|
5062
5287
|
|
|
5063
5288
|
exports.mrd_boolean_field = MrdBooleanField;
|
|
5064
5289
|
exports.mrd_currency_field = MrdCurrencyField;
|