@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,7 +1,7 @@
|
|
|
1
|
-
import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-
|
|
1
|
+
import { r as registerInstance, c as createEvent, h, H as Host, g as getElement, w as writeTask } from './index-DiSEJMA8.js';
|
|
2
2
|
import { ClientLayoutItemFieldDataType, ClientLayoutItemType, ClientLayoutItemRelationDisplayType, ClientLayoutItemRelationEditBehavior, resolveArchetype, ARCHETYPE_DOCUMENT } from './index.js';
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
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)}`;
|
|
5
5
|
|
|
6
6
|
const MrdBooleanField = class {
|
|
7
7
|
constructor(hostRef) {
|
|
@@ -27,10 +27,83 @@ const MrdBooleanField = class {
|
|
|
27
27
|
this.checked = !!this.value;
|
|
28
28
|
}
|
|
29
29
|
render() {
|
|
30
|
-
return (h(Host, { key: '
|
|
30
|
+
return (h(Host, { key: 'f7851813646d31c565c262bf3c8d4083177dd993' }, h("div", { key: '4b3c9f46e8b79bdc97ef5815afb85ba5ddde0c9a', class: "mrd-boolean-field" }, h("label", { key: 'f81fa28d5a79de0445c2c192352343f0807609a1', class: "mrd-boolean-field__toggle-label" }, 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 }), h("span", { key: '949e042c8af0f2872cf973a0d5407fce972eb240', class: "mrd-boolean-field__toggle", "aria-hidden": "true" }), this.label && (h("span", { key: 'e8c52b5820887b2a8ec9a20eb7e4116a528d27d4', class: `mrd-boolean-field__text${this.required ? ' mrd-boolean-field__text--required' : ''}` }, this.label))))));
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
|
-
MrdBooleanField.style =
|
|
33
|
+
MrdBooleanField.style = mrdBooleanFieldCss();
|
|
34
|
+
|
|
35
|
+
function formatNumber(value, locale, options) {
|
|
36
|
+
if (value === null || value === undefined || isNaN(value))
|
|
37
|
+
return '';
|
|
38
|
+
return new Intl.NumberFormat(locale, options).format(value);
|
|
39
|
+
}
|
|
40
|
+
function formatCurrency(amount, currency, locale) {
|
|
41
|
+
if (amount === null || amount === undefined || isNaN(amount))
|
|
42
|
+
return '';
|
|
43
|
+
return new Intl.NumberFormat(locale, {
|
|
44
|
+
style: 'currency',
|
|
45
|
+
currency,
|
|
46
|
+
minimumFractionDigits: 2,
|
|
47
|
+
maximumFractionDigits: 2,
|
|
48
|
+
}).format(amount);
|
|
49
|
+
}
|
|
50
|
+
function formatPercentage(value, locale, decimalPrecision = 2) {
|
|
51
|
+
if (value === null || value === undefined || isNaN(value))
|
|
52
|
+
return '';
|
|
53
|
+
return new Intl.NumberFormat(locale, {
|
|
54
|
+
style: 'percent',
|
|
55
|
+
minimumFractionDigits: decimalPrecision,
|
|
56
|
+
maximumFractionDigits: decimalPrecision,
|
|
57
|
+
}).format(value);
|
|
58
|
+
}
|
|
59
|
+
function formatDate(value, locale) {
|
|
60
|
+
if (!value)
|
|
61
|
+
return '';
|
|
62
|
+
const date = typeof value === 'string' ? new Date(value) : value;
|
|
63
|
+
if (isNaN(date.getTime()))
|
|
64
|
+
return '';
|
|
65
|
+
return new Intl.DateTimeFormat(locale, { year: 'numeric', month: '2-digit', day: '2-digit' }).format(date);
|
|
66
|
+
}
|
|
67
|
+
function formatDateTime(value, locale) {
|
|
68
|
+
if (!value)
|
|
69
|
+
return '';
|
|
70
|
+
const date = typeof value === 'string' ? new Date(value) : value;
|
|
71
|
+
if (isNaN(date.getTime()))
|
|
72
|
+
return '';
|
|
73
|
+
return new Intl.DateTimeFormat(locale, {
|
|
74
|
+
year: 'numeric',
|
|
75
|
+
month: '2-digit',
|
|
76
|
+
day: '2-digit',
|
|
77
|
+
hour: '2-digit',
|
|
78
|
+
minute: '2-digit',
|
|
79
|
+
}).format(date);
|
|
80
|
+
}
|
|
81
|
+
function formatTime(value, locale) {
|
|
82
|
+
if (!value)
|
|
83
|
+
return '';
|
|
84
|
+
// value is HH:MM or HH:MM:SS
|
|
85
|
+
const [hours, minutes] = value.split(':').map(Number);
|
|
86
|
+
const date = new Date();
|
|
87
|
+
date.setHours(hours, minutes, 0, 0);
|
|
88
|
+
return new Intl.DateTimeFormat(locale, { hour: '2-digit', minute: '2-digit' }).format(date);
|
|
89
|
+
}
|
|
90
|
+
function parseLocalizedNumber(str, locale) {
|
|
91
|
+
var _a, _b, _c, _d;
|
|
92
|
+
if (!str || !str.trim())
|
|
93
|
+
return null;
|
|
94
|
+
// Detect decimal and thousands separators from the locale
|
|
95
|
+
const parts = new Intl.NumberFormat(locale).formatToParts(1234567.89);
|
|
96
|
+
const groupSep = (_b = (_a = parts.find((p) => p.type === 'group')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : ',';
|
|
97
|
+
const decimalSep = (_d = (_c = parts.find((p) => p.type === 'decimal')) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : '.';
|
|
98
|
+
// Remove group separators, replace decimal separator with '.'
|
|
99
|
+
const normalized = str
|
|
100
|
+
.replace(new RegExp(`\\${groupSep}`, 'g'), '')
|
|
101
|
+
.replace(new RegExp(`\\${decimalSep}`), '.')
|
|
102
|
+
.replace('%', '')
|
|
103
|
+
.trim();
|
|
104
|
+
const parsed = parseFloat(normalized);
|
|
105
|
+
return isNaN(parsed) ? null : parsed;
|
|
106
|
+
}
|
|
34
107
|
|
|
35
108
|
const translations = {
|
|
36
109
|
nl: {
|
|
@@ -47,8 +120,10 @@ const translations = {
|
|
|
47
120
|
drop_file_here: 'Sleep bestand hierheen of',
|
|
48
121
|
browse: 'bladeren',
|
|
49
122
|
file_too_large: 'Bestand is te groot',
|
|
123
|
+
invalid_image: 'Selecteer een afbeeldingsbestand',
|
|
50
124
|
search_results: 'Zoekresultaten',
|
|
51
125
|
no_results: 'Geen resultaten gevonden',
|
|
126
|
+
load_failed_retry: 'Laden mislukt — opnieuw proberen',
|
|
52
127
|
loading: 'Laden...',
|
|
53
128
|
submit: 'Opslaan',
|
|
54
129
|
cancel: 'Annuleren',
|
|
@@ -119,8 +194,10 @@ const translations = {
|
|
|
119
194
|
drop_file_here: 'Drop file here or',
|
|
120
195
|
browse: 'browse',
|
|
121
196
|
file_too_large: 'File is too large',
|
|
197
|
+
invalid_image: 'Please select an image file',
|
|
122
198
|
search_results: 'Search results',
|
|
123
199
|
no_results: 'No results found',
|
|
200
|
+
load_failed_retry: 'Failed to load — retry',
|
|
124
201
|
loading: 'Loading...',
|
|
125
202
|
submit: 'Save',
|
|
126
203
|
cancel: 'Cancel',
|
|
@@ -191,8 +268,10 @@ const translations = {
|
|
|
191
268
|
drop_file_here: 'اسحب الملف هنا أو',
|
|
192
269
|
browse: 'تصفح',
|
|
193
270
|
file_too_large: 'الملف كبير جداً',
|
|
271
|
+
invalid_image: 'يرجى اختيار ملف صورة',
|
|
194
272
|
search_results: 'نتائج البحث',
|
|
195
273
|
no_results: 'لم يتم العثور على نتائج',
|
|
274
|
+
load_failed_retry: 'فشل التحميل — إعادة المحاولة',
|
|
196
275
|
loading: 'جار التحميل...',
|
|
197
276
|
submit: 'حفظ',
|
|
198
277
|
cancel: 'إلغاء',
|
|
@@ -257,8 +336,10 @@ const translations = {
|
|
|
257
336
|
drop_file_here: 'Déposez le fichier ici ou',
|
|
258
337
|
browse: 'parcourir',
|
|
259
338
|
file_too_large: 'Le fichier est trop volumineux',
|
|
339
|
+
invalid_image: 'Veuillez sélectionner un fichier image',
|
|
260
340
|
search_results: 'Résultats de recherche',
|
|
261
341
|
no_results: 'Aucun résultat trouvé',
|
|
342
|
+
load_failed_retry: 'Échec du chargement — réessayer',
|
|
262
343
|
loading: 'Chargement...',
|
|
263
344
|
submit: 'Enregistrer',
|
|
264
345
|
cancel: 'Annuler',
|
|
@@ -323,8 +404,10 @@ const translations = {
|
|
|
323
404
|
drop_file_here: 'Datei hier ablegen oder',
|
|
324
405
|
browse: 'durchsuchen',
|
|
325
406
|
file_too_large: 'Datei ist zu groß',
|
|
407
|
+
invalid_image: 'Bitte eine Bilddatei auswählen',
|
|
326
408
|
search_results: 'Suchergebnisse',
|
|
327
409
|
no_results: 'Keine Ergebnisse gefunden',
|
|
410
|
+
load_failed_retry: 'Laden fehlgeschlagen — erneut versuchen',
|
|
328
411
|
loading: 'Laden...',
|
|
329
412
|
submit: 'Speichern',
|
|
330
413
|
cancel: 'Abbrechen',
|
|
@@ -389,8 +472,10 @@ const translations = {
|
|
|
389
472
|
drop_file_here: 'Suelte el archivo aquí o',
|
|
390
473
|
browse: 'explorar',
|
|
391
474
|
file_too_large: 'El archivo es demasiado grande',
|
|
475
|
+
invalid_image: 'Seleccione un archivo de imagen',
|
|
392
476
|
search_results: 'Resultados de búsqueda',
|
|
393
477
|
no_results: 'No se encontraron resultados',
|
|
478
|
+
load_failed_retry: 'Error al cargar — reintentar',
|
|
394
479
|
loading: 'Cargando...',
|
|
395
480
|
submit: 'Guardar',
|
|
396
481
|
cancel: 'Cancelar',
|
|
@@ -455,8 +540,10 @@ const translations = {
|
|
|
455
540
|
drop_file_here: 'Trascina il file qui o',
|
|
456
541
|
browse: 'sfoglia',
|
|
457
542
|
file_too_large: 'Il file è troppo grande',
|
|
543
|
+
invalid_image: 'Seleziona un file immagine',
|
|
458
544
|
search_results: 'Risultati della ricerca',
|
|
459
545
|
no_results: 'Nessun risultato trovato',
|
|
546
|
+
load_failed_retry: 'Caricamento non riuscito — riprova',
|
|
460
547
|
loading: 'Caricamento...',
|
|
461
548
|
submit: 'Salva',
|
|
462
549
|
cancel: 'Annulla',
|
|
@@ -521,8 +608,10 @@ const translations = {
|
|
|
521
608
|
drop_file_here: 'Перетягніть файл сюди або',
|
|
522
609
|
browse: 'огляд',
|
|
523
610
|
file_too_large: 'Файл занадто великий',
|
|
611
|
+
invalid_image: 'Будь ласка, виберіть файл зображення',
|
|
524
612
|
search_results: 'Результати пошуку',
|
|
525
613
|
no_results: 'Результатів не знайдено',
|
|
614
|
+
load_failed_retry: 'Не вдалося завантажити — повторити',
|
|
526
615
|
loading: 'Завантаження...',
|
|
527
616
|
submit: 'Зберегти',
|
|
528
617
|
cancel: 'Скасувати',
|
|
@@ -631,80 +720,22 @@ function validateNumber(value, dataType) {
|
|
|
631
720
|
return true;
|
|
632
721
|
}
|
|
633
722
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
return
|
|
643
|
-
style: 'currency',
|
|
644
|
-
currency,
|
|
645
|
-
minimumFractionDigits: 2,
|
|
646
|
-
maximumFractionDigits: 2,
|
|
647
|
-
}).format(amount);
|
|
648
|
-
}
|
|
649
|
-
function formatPercentage(value, locale, decimalPrecision = 2) {
|
|
650
|
-
if (value === null || value === undefined || isNaN(value))
|
|
651
|
-
return '';
|
|
652
|
-
return new Intl.NumberFormat(locale, {
|
|
653
|
-
style: 'percent',
|
|
654
|
-
minimumFractionDigits: decimalPrecision,
|
|
655
|
-
maximumFractionDigits: decimalPrecision,
|
|
656
|
-
}).format(value);
|
|
723
|
+
/**
|
|
724
|
+
* Shared building blocks for the leaf field components.
|
|
725
|
+
* `base` is the BEM block name, e.g. 'mrd-text-field'.
|
|
726
|
+
*/
|
|
727
|
+
const FieldLabel = ({ base, label, required }) => label ? h("label", { class: `${base}__label${required ? ` ${base}__label--required` : ''}` }, label) : null;
|
|
728
|
+
const FieldError = ({ base, error }) => error ? h("span", { class: `${base}__error` }, error) : null;
|
|
729
|
+
/** Class string for the form control, with the --error modifier when applicable. */
|
|
730
|
+
function controlClass(base, hasError, element = 'input') {
|
|
731
|
+
return `${base}__${element}${hasError ? ` ${base}__${element}--error` : ''}`;
|
|
657
732
|
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
const date = typeof value === 'string' ? new Date(value) : value;
|
|
662
|
-
if (isNaN(date.getTime()))
|
|
663
|
-
return '';
|
|
664
|
-
return new Intl.DateTimeFormat(locale, { year: 'numeric', month: '2-digit', day: '2-digit' }).format(date);
|
|
665
|
-
}
|
|
666
|
-
function formatDateTime(value, locale) {
|
|
667
|
-
if (!value)
|
|
668
|
-
return '';
|
|
669
|
-
const date = typeof value === 'string' ? new Date(value) : value;
|
|
670
|
-
if (isNaN(date.getTime()))
|
|
671
|
-
return '';
|
|
672
|
-
return new Intl.DateTimeFormat(locale, {
|
|
673
|
-
year: 'numeric',
|
|
674
|
-
month: '2-digit',
|
|
675
|
-
day: '2-digit',
|
|
676
|
-
hour: '2-digit',
|
|
677
|
-
minute: '2-digit',
|
|
678
|
-
}).format(date);
|
|
679
|
-
}
|
|
680
|
-
function formatTime(value, locale) {
|
|
681
|
-
if (!value)
|
|
682
|
-
return '';
|
|
683
|
-
// value is HH:MM or HH:MM:SS
|
|
684
|
-
const [hours, minutes] = value.split(':').map(Number);
|
|
685
|
-
const date = new Date();
|
|
686
|
-
date.setHours(hours, minutes, 0, 0);
|
|
687
|
-
return new Intl.DateTimeFormat(locale, { hour: '2-digit', minute: '2-digit' }).format(date);
|
|
688
|
-
}
|
|
689
|
-
function parseLocalizedNumber(str, locale) {
|
|
690
|
-
var _a, _b, _c, _d;
|
|
691
|
-
if (!str || !str.trim())
|
|
692
|
-
return null;
|
|
693
|
-
// Detect decimal and thousands separators from the locale
|
|
694
|
-
const parts = new Intl.NumberFormat(locale).formatToParts(1234567.89);
|
|
695
|
-
const groupSep = (_b = (_a = parts.find((p) => p.type === 'group')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : ',';
|
|
696
|
-
const decimalSep = (_d = (_c = parts.find((p) => p.type === 'decimal')) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : '.';
|
|
697
|
-
// Remove group separators, replace decimal separator with '.'
|
|
698
|
-
const normalized = str
|
|
699
|
-
.replace(new RegExp(`\\${groupSep}`, 'g'), '')
|
|
700
|
-
.replace(new RegExp(`\\${decimalSep}`), '.')
|
|
701
|
-
.replace('%', '')
|
|
702
|
-
.trim();
|
|
703
|
-
const parsed = parseFloat(normalized);
|
|
704
|
-
return isNaN(parsed) ? null : parsed;
|
|
733
|
+
/** Returns the localised required-error, or '' when the value passes. */
|
|
734
|
+
function requiredError(value, required, locale) {
|
|
735
|
+
return required && !validateRequired(value) ? t('required', locale) : '';
|
|
705
736
|
}
|
|
706
737
|
|
|
707
|
-
const
|
|
738
|
+
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)}`;
|
|
708
739
|
|
|
709
740
|
const COMMON_CURRENCIES = [
|
|
710
741
|
'EUR', 'USD', 'GBP', 'CHF', 'JPY', 'CNY', 'AUD', 'CAD',
|
|
@@ -731,12 +762,7 @@ const MrdCurrencyField = class {
|
|
|
731
762
|
this.handleAmountBlur = (e) => {
|
|
732
763
|
const raw = e.target.value;
|
|
733
764
|
const parsed = parseLocalizedNumber(raw, this.locale);
|
|
734
|
-
|
|
735
|
-
this.error = t('required', this.locale);
|
|
736
|
-
}
|
|
737
|
-
else {
|
|
738
|
-
this.error = '';
|
|
739
|
-
}
|
|
765
|
+
this.error = requiredError(raw, this.required, this.locale);
|
|
740
766
|
const val = { amount: parsed, currency: this.currency };
|
|
741
767
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
742
768
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
@@ -755,12 +781,12 @@ const MrdCurrencyField = class {
|
|
|
755
781
|
}
|
|
756
782
|
render() {
|
|
757
783
|
const hasError = !!this.error;
|
|
758
|
-
return (h(Host, { key: '
|
|
784
|
+
return (h(Host, { key: '24c530db6e0420af39fa0a35b31e966286f2d00c' }, h("div", { key: '795bc336425fbf1b86828f4a8f5df93930169a3c', class: "mrd-currency-field" }, h(FieldLabel, { key: 'b302cd9296c29ed5719b1f768bd5d4eea86f6406', base: "mrd-currency-field", label: this.label, required: this.required }), h("div", { key: '7efca51615f405ffd660e120accae32f55a9b5a0', class: "mrd-currency-field__row" }, 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 }), h("select", { key: '83ad5e92b623c3c60d161b8828e780adb476682c', class: "mrd-currency-field__currency", disabled: this.disabled, onChange: this.handleCurrencyChange }, COMMON_CURRENCIES.map(c => (h("option", { key: c, value: c, selected: c === this.currency }, c))))), h(FieldError, { key: 'b059290bb566b119c4f192e750b3e365446243e6', base: "mrd-currency-field", error: this.error }))));
|
|
759
785
|
}
|
|
760
786
|
};
|
|
761
|
-
MrdCurrencyField.style =
|
|
787
|
+
MrdCurrencyField.style = mrdCurrencyFieldCss();
|
|
762
788
|
|
|
763
|
-
const
|
|
789
|
+
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}`;
|
|
764
790
|
|
|
765
791
|
const MrdDateField = class {
|
|
766
792
|
constructor(hostRef) {
|
|
@@ -776,12 +802,7 @@ const MrdDateField = class {
|
|
|
776
802
|
this.error = '';
|
|
777
803
|
this.handleChange = (e) => {
|
|
778
804
|
const val = e.target.value;
|
|
779
|
-
|
|
780
|
-
this.error = t('required', this.locale);
|
|
781
|
-
}
|
|
782
|
-
else {
|
|
783
|
-
this.error = '';
|
|
784
|
-
}
|
|
805
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
785
806
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
786
807
|
};
|
|
787
808
|
this.handleBlur = (e) => {
|
|
@@ -790,13 +811,12 @@ const MrdDateField = class {
|
|
|
790
811
|
};
|
|
791
812
|
}
|
|
792
813
|
render() {
|
|
793
|
-
|
|
794
|
-
return (h(Host, { key: '2c0dc2311068a5c759fe8efe58a98a71a9cf4b7b' }, h("div", { key: 'ee1cc0e9a2943cc42439825b8f21cd3492eaca05', class: "mrd-date-field" }, this.label && (h("label", { key: '3f836a991e676b6070a8b3800edfce00cc0d3b3d', class: `mrd-date-field__label${this.required ? ' mrd-date-field__label--required' : ''}` }, this.label)), 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 && h("span", { key: '480ec99200989f3dc543d9afc648d83d31992b3c', class: "mrd-date-field__error" }, this.error))));
|
|
814
|
+
return (h(Host, { key: '71be9e4bcc87b40cf3b777d3fe0bff23c1a0fa94' }, h("div", { key: '40ced03df5d4185264ba9d03c832b3870ce8ae19', class: "mrd-date-field" }, h(FieldLabel, { key: 'd85ec7c4617a22c8c5862253e8090c85484f8c41', base: "mrd-date-field", label: this.label, required: this.required }), 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 }), h(FieldError, { key: '9dd64475bf8a77bea5344faa71f20485b34b86f9', base: "mrd-date-field", error: this.error }))));
|
|
795
815
|
}
|
|
796
816
|
};
|
|
797
|
-
MrdDateField.style =
|
|
817
|
+
MrdDateField.style = mrdDateFieldCss();
|
|
798
818
|
|
|
799
|
-
const
|
|
819
|
+
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}`;
|
|
800
820
|
|
|
801
821
|
const MrdDatetimeField = class {
|
|
802
822
|
constructor(hostRef) {
|
|
@@ -814,12 +834,7 @@ const MrdDatetimeField = class {
|
|
|
814
834
|
this.handleChange = (e) => {
|
|
815
835
|
const localVal = e.target.value;
|
|
816
836
|
this.localValue = localVal;
|
|
817
|
-
|
|
818
|
-
this.error = t('required', this.locale);
|
|
819
|
-
}
|
|
820
|
-
else {
|
|
821
|
-
this.error = '';
|
|
822
|
-
}
|
|
837
|
+
this.error = requiredError(localVal, this.required, this.locale);
|
|
823
838
|
this.mrdChange.emit({ name: this.name, value: this.localToUtc(localVal) });
|
|
824
839
|
};
|
|
825
840
|
this.handleBlur = (e) => {
|
|
@@ -853,8 +868,7 @@ const MrdDatetimeField = class {
|
|
|
853
868
|
return d.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
854
869
|
}
|
|
855
870
|
render() {
|
|
856
|
-
|
|
857
|
-
return (h(Host, { key: 'ea8b3b68100ffdb316bc5048f82d85d238bb2e4b' }, h("div", { key: 'c192c6998ee474aaf4df7b3b97ae0bd61f6d624d', class: "mrd-datetime-field" }, this.label && (h("label", { key: '1fbd66c17d76508f0d698a2c258be6779e98d85e', class: `mrd-datetime-field__label${this.required ? ' mrd-datetime-field__label--required' : ''}` }, this.label)), 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 && h("span", { key: '8788ac01739302f6ad61010b238ff38d45e1b68a', class: "mrd-datetime-field__error" }, this.error))));
|
|
871
|
+
return (h(Host, { key: 'ac07ec2ba79cde998d1247e9d71de336c0e72a64' }, h("div", { key: '8144cf68c4b6b9cbc8396903b84bb355f380ceda', class: "mrd-datetime-field" }, h(FieldLabel, { key: '972686469f68c932e33b8d2c3806422553a3cce3', base: "mrd-datetime-field", label: this.label, required: this.required }), 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 }), h(FieldError, { key: 'b7a812f82a6b0d2c938aa1f1c2494df685258555', base: "mrd-datetime-field", error: this.error }))));
|
|
858
872
|
}
|
|
859
873
|
static get watchers() { return {
|
|
860
874
|
"value": [{
|
|
@@ -862,9 +876,9 @@ const MrdDatetimeField = class {
|
|
|
862
876
|
}]
|
|
863
877
|
}; }
|
|
864
878
|
};
|
|
865
|
-
MrdDatetimeField.style =
|
|
879
|
+
MrdDatetimeField.style = mrdDatetimeFieldCss();
|
|
866
880
|
|
|
867
|
-
const
|
|
881
|
+
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}`;
|
|
868
882
|
|
|
869
883
|
const MrdDocumentContainer = class {
|
|
870
884
|
constructor(hostRef) {
|
|
@@ -896,8 +910,8 @@ const MrdDocumentContainer = class {
|
|
|
896
910
|
/** Whether the currently mounted table has been init()'d. Reset on every mode switch. */
|
|
897
911
|
this.tableInited = false;
|
|
898
912
|
this.createFolder = () => {
|
|
899
|
-
var _a
|
|
900
|
-
(
|
|
913
|
+
var _a;
|
|
914
|
+
(_a = this.listEl) === null || _a === void 0 ? void 0 : _a.createFolder();
|
|
901
915
|
};
|
|
902
916
|
}
|
|
903
917
|
/** The embedded table does not self-load: like every mrd-table it waits for the
|
|
@@ -909,7 +923,7 @@ const MrdDocumentContainer = class {
|
|
|
909
923
|
if (this.mode === 'list' && this.tableEl && !this.tableInited) {
|
|
910
924
|
this.tableInited = true;
|
|
911
925
|
const table = this.tableEl;
|
|
912
|
-
Promise.resolve((_a = table.componentOnReady) === null || _a === void 0 ? void 0 : _a.call(table)).then(() =>
|
|
926
|
+
Promise.resolve((_a = table.componentOnReady) === null || _a === void 0 ? void 0 : _a.call(table)).then(() => table.init());
|
|
913
927
|
}
|
|
914
928
|
}
|
|
915
929
|
setMode(mode) {
|
|
@@ -969,13 +983,240 @@ const MrdDocumentContainer = class {
|
|
|
969
983
|
}
|
|
970
984
|
render() {
|
|
971
985
|
const treeMode = this.mode === 'tree';
|
|
972
|
-
return (h(Host, { key: '
|
|
986
|
+
return (h(Host, { key: '018c9eacd169fdf7d352a51472651348af2b45df' }, this.renderToolbar(), h("div", { key: '5ff2ac77d4d12369905696ff075f99785dc1c809', class: "mrd-document-container__body", style: treeMode ? { height: `${this.height}px`, overflowY: 'auto' } : {} }, treeMode ? this.renderTree() : this.renderList())));
|
|
973
987
|
}
|
|
974
988
|
get el() { return getElement(this); }
|
|
975
989
|
};
|
|
976
|
-
MrdDocumentContainer.style =
|
|
990
|
+
MrdDocumentContainer.style = mrdDocumentContainerCss();
|
|
991
|
+
|
|
992
|
+
/**
|
|
993
|
+
* Shared path/query-param conventions for list requests,
|
|
994
|
+
* used by mrd-table and mrd-document-list.
|
|
995
|
+
*/
|
|
996
|
+
/** Applies the view-level static filters to `params` using the API operator conventions. */
|
|
997
|
+
function applyViewFilters(params, filters) {
|
|
998
|
+
var _a, _b, _c;
|
|
999
|
+
for (const f of filters !== null && filters !== void 0 ? filters : []) {
|
|
1000
|
+
if (!f.name)
|
|
1001
|
+
continue;
|
|
1002
|
+
if (f.operator === 'EMPTY') {
|
|
1003
|
+
params.set(f.name, '');
|
|
1004
|
+
continue;
|
|
1005
|
+
}
|
|
1006
|
+
if (f.operator === 'NOT_EMPTY') {
|
|
1007
|
+
params.set(f.name + '_notempty', 'true');
|
|
1008
|
+
continue;
|
|
1009
|
+
}
|
|
1010
|
+
if (f.operator === 'STARTS_WITH') {
|
|
1011
|
+
params.set(f.name + '_startswith', String((_a = f.value) !== null && _a !== void 0 ? _a : ''));
|
|
1012
|
+
continue;
|
|
1013
|
+
}
|
|
1014
|
+
if (f.operator === 'FROM') {
|
|
1015
|
+
params.set(f.name + '_from', String((_b = f.value) !== null && _b !== void 0 ? _b : ''));
|
|
1016
|
+
continue;
|
|
1017
|
+
}
|
|
1018
|
+
if (f.operator === 'TO') {
|
|
1019
|
+
params.set(f.name + '_to', String((_c = f.value) !== null && _c !== void 0 ? _c : ''));
|
|
1020
|
+
continue;
|
|
1021
|
+
}
|
|
1022
|
+
if (f.value != null) {
|
|
1023
|
+
params.set(f.name, String(f.value));
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
/** VIEW: `/{dataClass}`; RELATED_VIEW: `/{fromClass}/{parentId}/{dataClass}`. */
|
|
1028
|
+
function buildListPath(opts) {
|
|
1029
|
+
var _a, _b, _c;
|
|
1030
|
+
if (opts.isRelatedView) {
|
|
1031
|
+
return `/${(_a = opts.fromClass) !== null && _a !== void 0 ? _a : ''}/${opts.parentId}/${(_b = opts.dataClass) !== null && _b !== void 0 ? _b : ''}`;
|
|
1032
|
+
}
|
|
1033
|
+
return `/${(_c = opts.dataClass) !== null && _c !== void 0 ? _c : ''}`;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
/**
|
|
1037
|
+
* Tree model and pure tree logic for mrd-document-list.
|
|
1038
|
+
* Nodes are mutated in place; the component triggers re-renders via bump().
|
|
1039
|
+
*/
|
|
1040
|
+
/** Normalise a folder path: null/""/"/" → root ([]); else split on "/" dropping empties. */
|
|
1041
|
+
function splitFolder(path) {
|
|
1042
|
+
if (path == null)
|
|
1043
|
+
return [];
|
|
1044
|
+
const s = String(path).trim();
|
|
1045
|
+
if (s === '' || s === '/')
|
|
1046
|
+
return [];
|
|
1047
|
+
return s.split('/').map(x => x.trim()).filter(Boolean);
|
|
1048
|
+
}
|
|
1049
|
+
function makeContainerNode(href, label, count) {
|
|
1050
|
+
return {
|
|
1051
|
+
id: 'c:' + href, kind: 'container', label, href,
|
|
1052
|
+
hasDocs: false, docCount: 0, totalCount: count, children: [],
|
|
1053
|
+
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
function makeFolderNode(id, label, containerId) {
|
|
1057
|
+
return {
|
|
1058
|
+
id, kind: 'folder', label, containerId,
|
|
1059
|
+
hasDocs: false, docCount: 0, totalCount: 0, children: [],
|
|
1060
|
+
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1061
|
+
};
|
|
1062
|
+
}
|
|
1063
|
+
/** Recompute totalCount over the subtree; returns the node's aggregate. */
|
|
1064
|
+
function computeTotals(node) {
|
|
1065
|
+
let total = node.docCount;
|
|
1066
|
+
for (const c of node.children)
|
|
1067
|
+
total += computeTotals(c);
|
|
1068
|
+
node.totalCount = total;
|
|
1069
|
+
return total;
|
|
1070
|
+
}
|
|
1071
|
+
/** Folder path segments of a node relative to its container (derived from its id). */
|
|
1072
|
+
function segmentsOf(node, container) {
|
|
1073
|
+
if (node.kind === 'container')
|
|
1074
|
+
return [];
|
|
1075
|
+
const prefix = container.id + '/';
|
|
1076
|
+
const rest = node.id.startsWith(prefix) ? node.id.slice(prefix.length) : '';
|
|
1077
|
+
return rest ? rest.split('/') : [];
|
|
1078
|
+
}
|
|
1079
|
+
/** Folder string a node represents: the raw distinct value when it holds
|
|
1080
|
+
* documents, else derived from its path segments; null for a container root. */
|
|
1081
|
+
function folderStringOf(node, container) {
|
|
1082
|
+
if (node.kind === 'container')
|
|
1083
|
+
return null;
|
|
1084
|
+
if (node.fullPath != null && node.fullPath !== '')
|
|
1085
|
+
return node.fullPath;
|
|
1086
|
+
const segs = segmentsOf(node, container);
|
|
1087
|
+
return segs.length ? '/' + segs.join('/') : null;
|
|
1088
|
+
}
|
|
1089
|
+
/** Strip a single trailing extension for the document title. */
|
|
1090
|
+
function stripExtension(name) {
|
|
1091
|
+
return name.replace(/\.[^./\\]+$/, '');
|
|
1092
|
+
}
|
|
1093
|
+
/** Rebuild a container's folder subtree from the /distinct folder strings.
|
|
1094
|
+
* New nodes are registered in `nodeIndex`; the container is mutated in place. */
|
|
1095
|
+
function applyFolderDistinct(container, values, nodeIndex) {
|
|
1096
|
+
container.children = [];
|
|
1097
|
+
container.hasDocs = false;
|
|
1098
|
+
container.docCount = 0;
|
|
1099
|
+
for (const v of values) {
|
|
1100
|
+
const raw = typeof v.value === 'string' ? v.value : v.value == null ? '' : String(v.value);
|
|
1101
|
+
const segs = splitFolder(raw);
|
|
1102
|
+
if (segs.length === 0) {
|
|
1103
|
+
// Root documents — the container's own direct documents.
|
|
1104
|
+
container.hasDocs = true;
|
|
1105
|
+
container.docCount = v.count;
|
|
1106
|
+
container.fullPath = raw;
|
|
1107
|
+
continue;
|
|
1108
|
+
}
|
|
1109
|
+
let node = container;
|
|
1110
|
+
const acc = [];
|
|
1111
|
+
for (const seg of segs) {
|
|
1112
|
+
acc.push(seg);
|
|
1113
|
+
let child = node.children.find(c => c.label === seg);
|
|
1114
|
+
if (!child) {
|
|
1115
|
+
child = makeFolderNode(container.id + '/' + acc.join('/'), seg, container.id);
|
|
1116
|
+
node.children.push(child);
|
|
1117
|
+
nodeIndex.set(child.id, child);
|
|
1118
|
+
}
|
|
1119
|
+
node = child;
|
|
1120
|
+
}
|
|
1121
|
+
node.hasDocs = true;
|
|
1122
|
+
node.docCount = v.count;
|
|
1123
|
+
node.fullPath = raw;
|
|
1124
|
+
}
|
|
1125
|
+
computeTotals(container);
|
|
1126
|
+
container.foldersLoaded = true;
|
|
1127
|
+
container.loading = false;
|
|
1128
|
+
}
|
|
1129
|
+
/** Optimistic in-place tree update for a document moved between folders. */
|
|
1130
|
+
function applyDocMove(doc, fromNode, toNode, targetFolder) {
|
|
1131
|
+
fromNode.docs = fromNode.docs.filter(d => d !== doc);
|
|
1132
|
+
fromNode.docCount = Math.max(0, fromNode.docCount - 1);
|
|
1133
|
+
// A now-empty folder should stop showing an expand chevron (it disappears on
|
|
1134
|
+
// the next reload anyway, since it is derived from document folder strings).
|
|
1135
|
+
if (fromNode.docsLoaded)
|
|
1136
|
+
fromNode.hasDocs = fromNode.docs.length > 0;
|
|
1137
|
+
toNode.hasDocs = true;
|
|
1138
|
+
toNode.pending = false; // a pending folder is now materialised
|
|
1139
|
+
toNode.docCount += 1;
|
|
1140
|
+
if (toNode.kind === 'folder')
|
|
1141
|
+
toNode.fullPath = targetFolder !== null && targetFolder !== void 0 ? targetFolder : '';
|
|
1142
|
+
if (toNode.docsLoaded)
|
|
1143
|
+
toNode.docs = [...toNode.docs, doc];
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
function chevron(open, leaf) {
|
|
1147
|
+
return (h("span", { class: `mrd-document-list__chev${leaf ? ' mrd-document-list__chev--leaf' : ''}${open ? ' mrd-document-list__chev--open' : ''}` }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("path", { d: "M9 6l6 6-6 6" }))));
|
|
1148
|
+
}
|
|
1149
|
+
function dossierIcon() {
|
|
1150
|
+
return (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" }, 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" })));
|
|
1151
|
+
}
|
|
1152
|
+
function folderIcon() {
|
|
1153
|
+
return (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" }, 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" })));
|
|
1154
|
+
}
|
|
1155
|
+
function docIcon() {
|
|
1156
|
+
return (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" }, h("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }), h("path", { d: "M14 2v6h6" })));
|
|
1157
|
+
}
|
|
1158
|
+
function indent(depth) {
|
|
1159
|
+
return h("span", { class: "mrd-document-list__indent", style: { width: `${depth * 18}px` } });
|
|
1160
|
+
}
|
|
1161
|
+
function renderLoadingRow(ctx, depth) {
|
|
1162
|
+
return (h("div", { class: "mrd-document-list__loading", key: "loading" }, indent(depth), h("span", { class: "mrd-document-list__spinner" }), t('loading', ctx.locale)));
|
|
1163
|
+
}
|
|
1164
|
+
function renderUploadingRow(ctx, depth) {
|
|
1165
|
+
return (h("div", { class: "mrd-document-list__loading", key: "uploading" }, indent(depth), h("span", { class: "mrd-document-list__spinner" }), t('upload_file', ctx.locale)));
|
|
1166
|
+
}
|
|
1167
|
+
function renderDocRow(ctx, doc, node, container, depth) {
|
|
1168
|
+
var _a, _b, _c, _d, _e;
|
|
1169
|
+
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 : '';
|
|
1170
|
+
const dateRaw = ctx.dateField ? doc === null || doc === void 0 ? void 0 : doc[ctx.dateField] : undefined;
|
|
1171
|
+
const date = dateRaw ? formatDate(dateRaw, ctx.locale) : '';
|
|
1172
|
+
return (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(), h("span", { class: "mrd-document-list__label" }, label), date && h("span", { class: "mrd-document-list__date" }, date)));
|
|
1173
|
+
}
|
|
1174
|
+
function renderFolderEditRow(ctx, node, depth) {
|
|
1175
|
+
return (h("div", { class: "mrd-document-list__node", key: node.id }, h("div", { class: "mrd-document-list__row mrd-document-list__row--edit" }, indent(depth), chevron(false, true), folderIcon(), 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 && (h("div", { class: "mrd-document-list__error", style: { paddingLeft: `${depth * 18 + 52}px` } }, node.error))));
|
|
1176
|
+
}
|
|
1177
|
+
function renderNodeChildren(ctx, container, node, depth) {
|
|
1178
|
+
const out = [];
|
|
1179
|
+
// Direct documents of this node (root docs live on the container node).
|
|
1180
|
+
if (node.hasDocs) {
|
|
1181
|
+
if (node.docsLoaded) {
|
|
1182
|
+
for (const doc of node.docs)
|
|
1183
|
+
out.push(renderDocRow(ctx, doc, node, container, depth));
|
|
1184
|
+
}
|
|
1185
|
+
else if (node.loading) {
|
|
1186
|
+
out.push(renderLoadingRow(ctx, depth));
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
// Child folders.
|
|
1190
|
+
for (const child of node.children) {
|
|
1191
|
+
out.push(renderFolderNode(ctx, container, child, depth));
|
|
1192
|
+
}
|
|
1193
|
+
// An uploading file dropped onto this node.
|
|
1194
|
+
if (node.id === ctx.uploadingNodeId)
|
|
1195
|
+
out.push(renderUploadingRow(ctx, depth));
|
|
1196
|
+
return out;
|
|
1197
|
+
}
|
|
1198
|
+
function renderFolderNode(ctx, container, node, depth) {
|
|
1199
|
+
if (node.editing)
|
|
1200
|
+
return renderFolderEditRow(ctx, node, depth);
|
|
1201
|
+
const leaf = node.children.length === 0 && !node.hasDocs;
|
|
1202
|
+
const selected = node.id === ctx.selectedId;
|
|
1203
|
+
const cls = 'mrd-document-list__row'
|
|
1204
|
+
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1205
|
+
+ (node.pending ? ' mrd-document-list__row--pending' : '')
|
|
1206
|
+
+ (node.id === ctx.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1207
|
+
return (h("div", { class: "mrd-document-list__node", key: node.id }, 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(), h("span", { class: "mrd-document-list__label" }, node.label), h("span", { class: "mrd-document-list__count" }, node.totalCount)), node.open && h("div", { class: "mrd-document-list__kids" }, renderNodeChildren(ctx, container, node, depth + 1))));
|
|
1208
|
+
}
|
|
1209
|
+
function renderContainerNode(ctx, node, depth) {
|
|
1210
|
+
const selected = node.id === ctx.selectedId;
|
|
1211
|
+
const cls = 'mrd-document-list__row mrd-document-list__row--dossier'
|
|
1212
|
+
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1213
|
+
+ (node.id === ctx.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1214
|
+
return (h("div", { class: "mrd-document-list__node", key: node.id }, 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(), h("span", { class: "mrd-document-list__label" }, node.label), h("span", { class: "mrd-document-list__count" }, node.totalCount)), node.open && (h("div", { class: "mrd-document-list__kids" }, node.loading && !node.foldersLoaded
|
|
1215
|
+
? renderLoadingRow(ctx, depth + 1)
|
|
1216
|
+
: renderNodeChildren(ctx, node, node, depth + 1)))));
|
|
1217
|
+
}
|
|
977
1218
|
|
|
978
|
-
const
|
|
1219
|
+
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)}`;
|
|
979
1220
|
|
|
980
1221
|
const MrdDocumentList = class {
|
|
981
1222
|
constructor(hostRef) {
|
|
@@ -1042,7 +1283,7 @@ const MrdDocumentList = class {
|
|
|
1042
1283
|
return;
|
|
1043
1284
|
const { target, container } = resolved;
|
|
1044
1285
|
const tempId = `${container.id}/__new__${this.newFolderSeq++}`;
|
|
1045
|
-
const node =
|
|
1286
|
+
const node = makeFolderNode(tempId, '', container.id);
|
|
1046
1287
|
node.pending = true;
|
|
1047
1288
|
node.editing = true;
|
|
1048
1289
|
target.children = [...target.children, node];
|
|
@@ -1181,7 +1422,7 @@ const MrdDocumentList = class {
|
|
|
1181
1422
|
}
|
|
1182
1423
|
/** Seed the single implied container from context and load its folders. */
|
|
1183
1424
|
seedSingleContainer() {
|
|
1184
|
-
const node =
|
|
1425
|
+
const node = makeContainerNode(this.containerHref, this.containerField, 0);
|
|
1185
1426
|
this.nodeIndex.set(node.id, node);
|
|
1186
1427
|
this.containers = [node];
|
|
1187
1428
|
this.rootLoading = false;
|
|
@@ -1228,61 +1469,37 @@ const MrdDocumentList = class {
|
|
|
1228
1469
|
* type (e.g. "contents"), filtered down to the concrete `filterClass` via the
|
|
1229
1470
|
* `type` query param — see baseParams(). */
|
|
1230
1471
|
buildDataPath() {
|
|
1231
|
-
var _a, _b
|
|
1472
|
+
var _a, _b;
|
|
1232
1473
|
const it = this.item;
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1474
|
+
return buildListPath({
|
|
1475
|
+
isRelatedView: (it === null || it === void 0 ? void 0 : it.type) === ClientLayoutItemType.RELATED_VIEW,
|
|
1476
|
+
fromClass: it === null || it === void 0 ? void 0 : it.fromClass,
|
|
1477
|
+
parentId: this.parentId,
|
|
1478
|
+
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 : '',
|
|
1479
|
+
});
|
|
1238
1480
|
}
|
|
1239
1481
|
/** Path for creating a new document (file-drop). Unlike buildDataPath(), this
|
|
1240
1482
|
* must target the concrete type: `dataClass`/`relatedClass` can be an abstract
|
|
1241
1483
|
* base type (e.g. "contents") that cannot be POSTed to directly, so prefer
|
|
1242
1484
|
* `filterClass` (e.g. "documents") when present. */
|
|
1243
1485
|
buildCreatePath() {
|
|
1244
|
-
var _a, _b, _c
|
|
1486
|
+
var _a, _b, _c;
|
|
1245
1487
|
const it = this.item;
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1488
|
+
return buildListPath({
|
|
1489
|
+
isRelatedView: (it === null || it === void 0 ? void 0 : it.type) === ClientLayoutItemType.RELATED_VIEW,
|
|
1490
|
+
fromClass: it === null || it === void 0 ? void 0 : it.fromClass,
|
|
1491
|
+
parentId: this.parentId,
|
|
1492
|
+
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 : '',
|
|
1493
|
+
});
|
|
1251
1494
|
}
|
|
1252
1495
|
/** View-level static filters + filterClass, shared by every request. */
|
|
1253
1496
|
baseParams() {
|
|
1254
|
-
var _a, _b, _c
|
|
1497
|
+
var _a, _b, _c;
|
|
1255
1498
|
const p = new URLSearchParams();
|
|
1256
1499
|
const filterClass = (_a = this.item) === null || _a === void 0 ? void 0 : _a.filterClass;
|
|
1257
1500
|
if (filterClass)
|
|
1258
1501
|
p.set('type', filterClass);
|
|
1259
|
-
|
|
1260
|
-
if (!f.name)
|
|
1261
|
-
continue;
|
|
1262
|
-
if (f.operator === 'EMPTY') {
|
|
1263
|
-
p.set(f.name, '');
|
|
1264
|
-
continue;
|
|
1265
|
-
}
|
|
1266
|
-
if (f.operator === 'NOT_EMPTY') {
|
|
1267
|
-
p.set(f.name + '_notempty', 'true');
|
|
1268
|
-
continue;
|
|
1269
|
-
}
|
|
1270
|
-
if (f.operator === 'STARTS_WITH') {
|
|
1271
|
-
p.set(f.name + '_startswith', String((_e = f.value) !== null && _e !== void 0 ? _e : ''));
|
|
1272
|
-
continue;
|
|
1273
|
-
}
|
|
1274
|
-
if (f.operator === 'FROM') {
|
|
1275
|
-
p.set(f.name + '_from', String((_f = f.value) !== null && _f !== void 0 ? _f : ''));
|
|
1276
|
-
continue;
|
|
1277
|
-
}
|
|
1278
|
-
if (f.operator === 'TO') {
|
|
1279
|
-
p.set(f.name + '_to', String((_g = f.value) !== null && _g !== void 0 ? _g : ''));
|
|
1280
|
-
continue;
|
|
1281
|
-
}
|
|
1282
|
-
if (f.value != null) {
|
|
1283
|
-
p.set(f.name, String(f.value));
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1502
|
+
applyViewFilters(p, (_c = (_b = this.item) === null || _b === void 0 ? void 0 : _b.view) === null || _c === void 0 ? void 0 : _c.filter);
|
|
1286
1503
|
return p;
|
|
1287
1504
|
}
|
|
1288
1505
|
emitContainerDistinct() {
|
|
@@ -1349,7 +1566,7 @@ const MrdDocumentList = class {
|
|
|
1349
1566
|
if (!v.value || typeof v.value !== 'object')
|
|
1350
1567
|
continue;
|
|
1351
1568
|
const href = v.value.href;
|
|
1352
|
-
const node =
|
|
1569
|
+
const node = makeContainerNode(href, v.value.name, v.count);
|
|
1353
1570
|
nodes.push(node);
|
|
1354
1571
|
this.nodeIndex.set(node.id, node);
|
|
1355
1572
|
}
|
|
@@ -1367,38 +1584,7 @@ const MrdDocumentList = class {
|
|
|
1367
1584
|
const container = this.nodeIndex.get(containerId);
|
|
1368
1585
|
if (!container)
|
|
1369
1586
|
return;
|
|
1370
|
-
container
|
|
1371
|
-
container.hasDocs = false;
|
|
1372
|
-
container.docCount = 0;
|
|
1373
|
-
for (const v of values) {
|
|
1374
|
-
const raw = typeof v.value === 'string' ? v.value : v.value == null ? '' : String(v.value);
|
|
1375
|
-
const segs = this.splitFolder(raw);
|
|
1376
|
-
if (segs.length === 0) {
|
|
1377
|
-
// Root documents — the container's own direct documents.
|
|
1378
|
-
container.hasDocs = true;
|
|
1379
|
-
container.docCount = v.count;
|
|
1380
|
-
container.fullPath = raw;
|
|
1381
|
-
continue;
|
|
1382
|
-
}
|
|
1383
|
-
let node = container;
|
|
1384
|
-
const acc = [];
|
|
1385
|
-
for (const seg of segs) {
|
|
1386
|
-
acc.push(seg);
|
|
1387
|
-
let child = node.children.find(c => c.label === seg);
|
|
1388
|
-
if (!child) {
|
|
1389
|
-
child = this.makeFolderNode(container.id + '/' + acc.join('/'), seg, container.id);
|
|
1390
|
-
node.children.push(child);
|
|
1391
|
-
this.nodeIndex.set(child.id, child);
|
|
1392
|
-
}
|
|
1393
|
-
node = child;
|
|
1394
|
-
}
|
|
1395
|
-
node.hasDocs = true;
|
|
1396
|
-
node.docCount = v.count;
|
|
1397
|
-
node.fullPath = raw;
|
|
1398
|
-
}
|
|
1399
|
-
this.computeTotals(container);
|
|
1400
|
-
container.foldersLoaded = true;
|
|
1401
|
-
container.loading = false;
|
|
1587
|
+
applyFolderDistinct(container, values, this.nodeIndex);
|
|
1402
1588
|
// If the container has root documents, load them now (they show inline on expand).
|
|
1403
1589
|
if (container.hasDocs && !container.docsLoaded) {
|
|
1404
1590
|
this.emitDocuments(container, container);
|
|
@@ -1406,36 +1592,6 @@ const MrdDocumentList = class {
|
|
|
1406
1592
|
this.bump();
|
|
1407
1593
|
}
|
|
1408
1594
|
// ── Tree helpers ─────────────────────────────────────────────────────────
|
|
1409
|
-
/** Normalise a folder path: null/""/"/" → root ([]); else split on "/" dropping empties. */
|
|
1410
|
-
splitFolder(path) {
|
|
1411
|
-
if (path == null)
|
|
1412
|
-
return [];
|
|
1413
|
-
const s = String(path).trim();
|
|
1414
|
-
if (s === '' || s === '/')
|
|
1415
|
-
return [];
|
|
1416
|
-
return s.split('/').map(x => x.trim()).filter(Boolean);
|
|
1417
|
-
}
|
|
1418
|
-
makeContainerNode(href, label, count) {
|
|
1419
|
-
return {
|
|
1420
|
-
id: 'c:' + href, kind: 'container', label, href,
|
|
1421
|
-
hasDocs: false, docCount: 0, totalCount: count, children: [],
|
|
1422
|
-
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1423
|
-
};
|
|
1424
|
-
}
|
|
1425
|
-
makeFolderNode(id, label, containerId) {
|
|
1426
|
-
return {
|
|
1427
|
-
id, kind: 'folder', label, containerId,
|
|
1428
|
-
hasDocs: false, docCount: 0, totalCount: 0, children: [],
|
|
1429
|
-
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1430
|
-
};
|
|
1431
|
-
}
|
|
1432
|
-
computeTotals(node) {
|
|
1433
|
-
let total = node.docCount;
|
|
1434
|
-
for (const c of node.children)
|
|
1435
|
-
total += this.computeTotals(c);
|
|
1436
|
-
node.totalCount = total;
|
|
1437
|
-
return total;
|
|
1438
|
-
}
|
|
1439
1595
|
/** Force a re-render after mutating nodes in place. */
|
|
1440
1596
|
bump() {
|
|
1441
1597
|
this.containers = [...this.containers];
|
|
@@ -1485,14 +1641,6 @@ const MrdDocumentList = class {
|
|
|
1485
1641
|
async createFolder() {
|
|
1486
1642
|
this.startCreateFolder();
|
|
1487
1643
|
}
|
|
1488
|
-
/** Folder path segments of a node relative to its container (derived from its id). */
|
|
1489
|
-
segmentsOf(node, container) {
|
|
1490
|
-
if (node.kind === 'container')
|
|
1491
|
-
return [];
|
|
1492
|
-
const prefix = container.id + '/';
|
|
1493
|
-
const rest = node.id.startsWith(prefix) ? node.id.slice(prefix.length) : '';
|
|
1494
|
-
return rest ? rest.split('/') : [];
|
|
1495
|
-
}
|
|
1496
1644
|
commitFolder() {
|
|
1497
1645
|
const node = this.pendingNode;
|
|
1498
1646
|
const parent = this.pendingParent;
|
|
@@ -1517,7 +1665,7 @@ const MrdDocumentList = class {
|
|
|
1517
1665
|
}
|
|
1518
1666
|
// Finalise: swap the temp id for the real path-derived id so a later distinct
|
|
1519
1667
|
// value with the same folder string merges onto this node.
|
|
1520
|
-
const segs = [...
|
|
1668
|
+
const segs = [...segmentsOf(parent, container), name];
|
|
1521
1669
|
this.nodeIndex.delete(node.id);
|
|
1522
1670
|
node.id = container.id + '/' + segs.join('/');
|
|
1523
1671
|
node.fullPath = '/' + segs.join('/');
|
|
@@ -1566,10 +1714,6 @@ const MrdDocumentList = class {
|
|
|
1566
1714
|
this.bump();
|
|
1567
1715
|
this.mrdUpload.emit({ file });
|
|
1568
1716
|
}
|
|
1569
|
-
/** Strip a single trailing extension for the document title. */
|
|
1570
|
-
stripExtension(name) {
|
|
1571
|
-
return name.replace(/\.[^./\\]+$/, '');
|
|
1572
|
-
}
|
|
1573
1717
|
/** Host callback with the uploaded file reference. Builds the create payload
|
|
1574
1718
|
* from the archetype slots and requests the new document. */
|
|
1575
1719
|
async setFileReference(uri) {
|
|
@@ -1577,16 +1721,20 @@ const MrdDocumentList = class {
|
|
|
1577
1721
|
if (!up)
|
|
1578
1722
|
return;
|
|
1579
1723
|
const { file, node, container } = up;
|
|
1580
|
-
const folder =
|
|
1724
|
+
const folder = folderStringOf(node, container);
|
|
1581
1725
|
const values = {
|
|
1582
1726
|
[this.fileField]: uri,
|
|
1583
|
-
[this.titleField]:
|
|
1727
|
+
[this.titleField]: stripExtension(file.name),
|
|
1584
1728
|
[this.folderField]: folder,
|
|
1585
|
-
[this.containerField]: container.href,
|
|
1586
1729
|
};
|
|
1730
|
+
// The create path already embeds the container (/{fromClass}/{parentId}/...)
|
|
1731
|
+
// when this is the seeded single-container context; omit the redundant field.
|
|
1732
|
+
if (!this.isSeededSingleContainer()) {
|
|
1733
|
+
values[this.containerField] = container.href;
|
|
1734
|
+
}
|
|
1587
1735
|
this.mrdCreateObject.emit({ path: this.buildCreatePath(), values });
|
|
1588
1736
|
// Optimistically show the new document (no href until a reload).
|
|
1589
|
-
const optimistic = { [this.titleField]:
|
|
1737
|
+
const optimistic = { [this.titleField]: stripExtension(file.name), _optimistic: true };
|
|
1590
1738
|
const wasUnloadedEmpty = !node.docsLoaded && node.docCount === 0;
|
|
1591
1739
|
node.hasDocs = true;
|
|
1592
1740
|
node.pending = false;
|
|
@@ -1615,16 +1763,6 @@ const MrdDocumentList = class {
|
|
|
1615
1763
|
this.lastOptimisticDoc = null;
|
|
1616
1764
|
this.bump();
|
|
1617
1765
|
}
|
|
1618
|
-
/** Folder string a node represents: the raw distinct value when it holds
|
|
1619
|
-
* documents, else derived from its path segments; null for a container root. */
|
|
1620
|
-
folderStringOf(node, container) {
|
|
1621
|
-
if (node.kind === 'container')
|
|
1622
|
-
return null;
|
|
1623
|
-
if (node.fullPath != null && node.fullPath !== '')
|
|
1624
|
-
return node.fullPath;
|
|
1625
|
-
const segs = this.segmentsOf(node, container);
|
|
1626
|
-
return segs.length ? '/' + segs.join('/') : null;
|
|
1627
|
-
}
|
|
1628
1766
|
moveDocument(toNode, toContainer) {
|
|
1629
1767
|
var _a, _b;
|
|
1630
1768
|
const doc = this.dragDoc;
|
|
@@ -1636,26 +1774,14 @@ const MrdDocumentList = class {
|
|
|
1636
1774
|
: (fromNode.containerId ? this.nodeIndex.get(fromNode.containerId) : undefined);
|
|
1637
1775
|
if (!fromContainer)
|
|
1638
1776
|
return;
|
|
1639
|
-
const targetFolder =
|
|
1640
|
-
const sourceFolder =
|
|
1777
|
+
const targetFolder = folderStringOf(toNode, toContainer);
|
|
1778
|
+
const sourceFolder = folderStringOf(fromNode, fromContainer);
|
|
1641
1779
|
const sameContainer = toContainer === fromContainer;
|
|
1642
1780
|
// No-op: dropped back onto its own folder.
|
|
1643
1781
|
if (toNode === fromNode || (sameContainer && targetFolder === sourceFolder))
|
|
1644
1782
|
return;
|
|
1645
|
-
//
|
|
1646
|
-
|
|
1647
|
-
fromNode.docCount = Math.max(0, fromNode.docCount - 1);
|
|
1648
|
-
// A now-empty folder should stop showing an expand chevron (it disappears on
|
|
1649
|
-
// the next reload anyway, since it is derived from document folder strings).
|
|
1650
|
-
if (fromNode.docsLoaded)
|
|
1651
|
-
fromNode.hasDocs = fromNode.docs.length > 0;
|
|
1652
|
-
toNode.hasDocs = true;
|
|
1653
|
-
toNode.pending = false; // a pending folder is now materialised
|
|
1654
|
-
toNode.docCount += 1;
|
|
1655
|
-
if (toNode.kind === 'folder')
|
|
1656
|
-
toNode.fullPath = targetFolder !== null && targetFolder !== void 0 ? targetFolder : '';
|
|
1657
|
-
if (toNode.docsLoaded)
|
|
1658
|
-
toNode.docs = [...toNode.docs, doc];
|
|
1783
|
+
// Optimistic tree update (fire-and-forget; no refetch).
|
|
1784
|
+
applyDocMove(doc, fromNode, toNode, targetFolder);
|
|
1659
1785
|
this.recomputeContainerTotals(fromContainer, -1);
|
|
1660
1786
|
if (!sameContainer)
|
|
1661
1787
|
this.recomputeContainerTotals(toContainer, 1);
|
|
@@ -1673,7 +1799,7 @@ const MrdDocumentList = class {
|
|
|
1673
1799
|
* loaded; otherwise just nudge the aggregate badge by the delta. */
|
|
1674
1800
|
recomputeContainerTotals(container, delta) {
|
|
1675
1801
|
if (container.foldersLoaded) {
|
|
1676
|
-
|
|
1802
|
+
computeTotals(container);
|
|
1677
1803
|
}
|
|
1678
1804
|
else {
|
|
1679
1805
|
container.totalCount = Math.max(0, container.totalCount + delta);
|
|
@@ -1686,111 +1812,64 @@ const MrdDocumentList = class {
|
|
|
1686
1812
|
this.mrdNavigate.emit({ href, label });
|
|
1687
1813
|
}
|
|
1688
1814
|
// ── Render ───────────────────────────────────────────────────────────────
|
|
1689
|
-
|
|
1690
|
-
return
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
return (h("div", { class: "mrd-document-list__loading", key: "loading" }, this.indent(depth), h("span", { class: "mrd-document-list__spinner" }), t('loading', this.locale)));
|
|
1713
|
-
}
|
|
1714
|
-
renderChildren(container, node, depth) {
|
|
1715
|
-
const out = [];
|
|
1716
|
-
// Direct documents of this node (root docs live on the container node).
|
|
1717
|
-
if (node.hasDocs) {
|
|
1718
|
-
if (node.docsLoaded) {
|
|
1719
|
-
for (const doc of node.docs)
|
|
1720
|
-
out.push(this.renderDocRow(doc, node, container, depth));
|
|
1721
|
-
}
|
|
1722
|
-
else if (node.loading) {
|
|
1723
|
-
out.push(this.renderLoadingRow(depth));
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
// Child folders.
|
|
1727
|
-
for (const child of node.children) {
|
|
1728
|
-
out.push(this.renderFolderNode(container, child, depth));
|
|
1729
|
-
}
|
|
1730
|
-
// An uploading file dropped onto this node.
|
|
1731
|
-
if (node.id === this.uploadingNodeId)
|
|
1732
|
-
out.push(this.renderUploadingRow(depth));
|
|
1733
|
-
return out;
|
|
1734
|
-
}
|
|
1735
|
-
renderUploadingRow(depth) {
|
|
1736
|
-
return (h("div", { class: "mrd-document-list__loading", key: "uploading" }, this.indent(depth), h("span", { class: "mrd-document-list__spinner" }), t('upload_file', this.locale)));
|
|
1737
|
-
}
|
|
1738
|
-
renderFolderEditRow(node, depth) {
|
|
1739
|
-
return (h("div", { class: "mrd-document-list__node", key: node.id }, h("div", { class: "mrd-document-list__row mrd-document-list__row--edit" }, this.indent(depth), this.renderChevron(false, true), this.renderFolderIcon(), 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 && (h("div", { class: "mrd-document-list__error", style: { paddingLeft: `${depth * 18 + 52}px` } }, node.error))));
|
|
1740
|
-
}
|
|
1741
|
-
renderFolderNode(container, node, depth) {
|
|
1742
|
-
if (node.editing)
|
|
1743
|
-
return this.renderFolderEditRow(node, depth);
|
|
1744
|
-
const leaf = node.children.length === 0 && !node.hasDocs;
|
|
1745
|
-
const selected = node.id === this.selectedId;
|
|
1746
|
-
const cls = 'mrd-document-list__row'
|
|
1747
|
-
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1748
|
-
+ (node.pending ? ' mrd-document-list__row--pending' : '')
|
|
1749
|
-
+ (node.id === this.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1750
|
-
return (h("div", { class: "mrd-document-list__node", key: node.id }, 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(), h("span", { class: "mrd-document-list__label" }, node.label), h("span", { class: "mrd-document-list__count" }, node.totalCount)), node.open && h("div", { class: "mrd-document-list__kids" }, this.renderChildren(container, node, depth + 1))));
|
|
1751
|
-
}
|
|
1752
|
-
renderContainerNode(node, depth) {
|
|
1753
|
-
const selected = node.id === this.selectedId;
|
|
1754
|
-
const cls = 'mrd-document-list__row mrd-document-list__row--dossier'
|
|
1755
|
-
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1756
|
-
+ (node.id === this.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1757
|
-
return (h("div", { class: "mrd-document-list__node", key: node.id }, 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(), h("span", { class: "mrd-document-list__label" }, node.label), h("span", { class: "mrd-document-list__count" }, node.totalCount)), node.open && (h("div", { class: "mrd-document-list__kids" }, node.loading && !node.foldersLoaded
|
|
1758
|
-
? this.renderLoadingRow(depth + 1)
|
|
1759
|
-
: this.renderChildren(node, node, depth + 1)))));
|
|
1815
|
+
treeCtx() {
|
|
1816
|
+
return {
|
|
1817
|
+
locale: this.locale,
|
|
1818
|
+
titleField: this.titleField,
|
|
1819
|
+
dateField: this.dateField,
|
|
1820
|
+
selectedId: this.selectedId,
|
|
1821
|
+
dropTargetId: this.dropTargetId,
|
|
1822
|
+
uploadingNodeId: this.uploadingNodeId,
|
|
1823
|
+
on: {
|
|
1824
|
+
toggleContainer: node => this.toggleContainer(node),
|
|
1825
|
+
toggleFolder: (container, node) => this.toggleFolder(container, node),
|
|
1826
|
+
openDoc: doc => this.openDoc(doc),
|
|
1827
|
+
docDragStart: this.onDocDragStart,
|
|
1828
|
+
docDragEnd: this.onDocDragEnd,
|
|
1829
|
+
nodeDragOver: this.onNodeDragOver,
|
|
1830
|
+
nodeDragLeave: this.onNodeDragLeave,
|
|
1831
|
+
nodeDrop: this.onNodeDrop,
|
|
1832
|
+
pendingInput: this.onPendingInput,
|
|
1833
|
+
pendingKeyDown: this.onPendingKeyDown,
|
|
1834
|
+
cancelFolder: () => this.cancelFolder(),
|
|
1835
|
+
setPendingInputEl: el => (this.pendingInputEl = el),
|
|
1836
|
+
},
|
|
1837
|
+
};
|
|
1760
1838
|
}
|
|
1761
1839
|
render() {
|
|
1840
|
+
const ctx = this.treeCtx();
|
|
1762
1841
|
let body;
|
|
1763
1842
|
if (this.rootLoading) {
|
|
1764
|
-
body =
|
|
1843
|
+
body = renderLoadingRow(ctx, 0);
|
|
1765
1844
|
}
|
|
1766
1845
|
else if (this.containers.length === 0) {
|
|
1767
|
-
body = h("div", { key: '
|
|
1846
|
+
body = h("div", { key: 'ce40dab51ab61447838e5059159ae4778209a6f3', class: "mrd-document-list__empty" }, t('no_results', this.locale));
|
|
1768
1847
|
}
|
|
1769
1848
|
else if (this.singleContainer) {
|
|
1770
1849
|
// Dossier context: render the single container's folder tree at the root.
|
|
1771
1850
|
const only = this.containers[0];
|
|
1772
1851
|
if (only.loading && !only.foldersLoaded) {
|
|
1773
|
-
body =
|
|
1852
|
+
body = renderLoadingRow(ctx, 0);
|
|
1774
1853
|
}
|
|
1775
1854
|
else {
|
|
1776
|
-
const kids =
|
|
1855
|
+
const kids = renderNodeChildren(ctx, only, only, 0);
|
|
1777
1856
|
body = kids.length
|
|
1778
1857
|
? kids
|
|
1779
1858
|
: h("div", { class: "mrd-document-list__empty" }, t('doc_empty_drop', this.locale));
|
|
1780
1859
|
}
|
|
1781
1860
|
}
|
|
1782
1861
|
else {
|
|
1783
|
-
body = this.containers.map(c =>
|
|
1862
|
+
body = this.containers.map(c => renderContainerNode(ctx, c, 0));
|
|
1784
1863
|
}
|
|
1785
|
-
return (h(Host, { key: '
|
|
1864
|
+
return (h(Host, { key: '9e1f7805ae18bce506c530a481db902900ad95f3' }, 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)));
|
|
1786
1865
|
}
|
|
1787
1866
|
get el() { return getElement(this); }
|
|
1788
1867
|
};
|
|
1789
1868
|
/** Root sentinel id for the container-level distinct request. */
|
|
1790
1869
|
MrdDocumentList.ROOT = '__root__';
|
|
1791
|
-
MrdDocumentList.style =
|
|
1870
|
+
MrdDocumentList.style = mrdDocumentListCss();
|
|
1792
1871
|
|
|
1793
|
-
const
|
|
1872
|
+
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)}`;
|
|
1794
1873
|
|
|
1795
1874
|
const MrdDocumentView = class {
|
|
1796
1875
|
constructor(hostRef) {
|
|
@@ -1840,12 +1919,12 @@ const MrdDocumentView = class {
|
|
|
1840
1919
|
const date = dateRaw != null && dateRaw !== '' ? formatDate(dateRaw, this.locale) : null;
|
|
1841
1920
|
const summaryRaw = this.slotValue('summary');
|
|
1842
1921
|
const summary = summaryRaw != null && summaryRaw !== '' ? String(summaryRaw) : null;
|
|
1843
|
-
return (h(Host, { key: '
|
|
1922
|
+
return (h(Host, { key: '0c64c72eaf5e1eefc2ca9aebb2543081eb1eae32' }, h("div", { key: '70cce81b089fee81a4c163a6ba5fbcc8cb46131c', class: "mrd-document-view" }, this.renderContainer(), title && h("h1", { key: '50f85b32a6740d6cf57fdf1bb0bcc597b5e97b31', class: "mrd-document-view__title" }, title), date && h("p", { key: 'b3c8fb3b4382104858d49ef9a1597034665122bb', class: "mrd-document-view__date" }, date), this.renderFile(), summary && (h("div", { key: '2046c1eca7601549115de0c95ff778abaf5faf46', class: "mrd-document-view__summary" }, h("div", { key: '875863d3e438eee3d4df10473a93f09370fde08c', class: "mrd-document-view__summary-body", innerHTML: summary }))))));
|
|
1844
1923
|
}
|
|
1845
1924
|
};
|
|
1846
|
-
MrdDocumentView.style =
|
|
1925
|
+
MrdDocumentView.style = mrdDocumentViewCss();
|
|
1847
1926
|
|
|
1848
|
-
const
|
|
1927
|
+
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)}`;
|
|
1849
1928
|
|
|
1850
1929
|
const MrdEmailField = class {
|
|
1851
1930
|
constructor(hostRef) {
|
|
@@ -1866,26 +1945,18 @@ const MrdEmailField = class {
|
|
|
1866
1945
|
};
|
|
1867
1946
|
this.handleBlur = (e) => {
|
|
1868
1947
|
const val = e.target.value;
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
}
|
|
1872
|
-
else if (val && !validateEmail(val)) {
|
|
1873
|
-
this.error = t('invalid_email', this.locale);
|
|
1874
|
-
}
|
|
1875
|
-
else {
|
|
1876
|
-
this.error = '';
|
|
1877
|
-
}
|
|
1948
|
+
this.error = requiredError(val, this.required, this.locale)
|
|
1949
|
+
|| (val && !validateEmail(val) ? t('invalid_email', this.locale) : '');
|
|
1878
1950
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
1879
1951
|
};
|
|
1880
1952
|
}
|
|
1881
1953
|
render() {
|
|
1882
|
-
|
|
1883
|
-
return (h(Host, { key: '0d442ab2a711c26c83fcdbf0fd8cd006d8dd8649' }, h("div", { key: 'ceb2a80679514c4c5b888fe096c90ed6cc973f64', class: "mrd-email-field" }, this.label && (h("label", { key: '663f95eff1002ee56cfc3104514bf31b47e26750', class: `mrd-email-field__label${this.required ? ' mrd-email-field__label--required' : ''}` }, this.label)), 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 && h("span", { key: '626ee856ceaa7051fb9dd1de8b7cbd708e83f617', class: "mrd-email-field__error" }, this.error))));
|
|
1954
|
+
return (h(Host, { key: '93f7c4975c24e6001e772f2858344edec04cda10' }, h("div", { key: '4f49a2a1f68a4161762861c5d54fd3690c88ac5d', class: "mrd-email-field" }, h(FieldLabel, { key: '23b20799f3e7c04889b7bc3a271e61b0bb5d7537', base: "mrd-email-field", label: this.label, required: this.required }), 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 }), h(FieldError, { key: '34945fff9c69cf2f0aeb56492c95052250514d5c', base: "mrd-email-field", error: this.error }))));
|
|
1884
1955
|
}
|
|
1885
1956
|
};
|
|
1886
|
-
MrdEmailField.style =
|
|
1957
|
+
MrdEmailField.style = mrdEmailFieldCss();
|
|
1887
1958
|
|
|
1888
|
-
const
|
|
1959
|
+
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)}`;
|
|
1889
1960
|
|
|
1890
1961
|
const MrdField = class {
|
|
1891
1962
|
constructor(hostRef) {
|
|
@@ -2070,9 +2141,47 @@ const MrdField = class {
|
|
|
2070
2141
|
}]
|
|
2071
2142
|
}; }
|
|
2072
2143
|
};
|
|
2073
|
-
MrdField.style =
|
|
2144
|
+
MrdField.style = mrdFieldCss();
|
|
2074
2145
|
|
|
2075
|
-
|
|
2146
|
+
/**
|
|
2147
|
+
* Shared upload behaviour for mrd-file-field and mrd-image-field:
|
|
2148
|
+
* file validation, drop-zone class building and drag-drop wiring.
|
|
2149
|
+
*/
|
|
2150
|
+
/** Validates a selected/dropped file; returns a localised error message or '' when accepted. */
|
|
2151
|
+
function validateUploadFile(file, maxSize, locale, requireImage = false) {
|
|
2152
|
+
if (maxSize > 0 && file.size > maxSize)
|
|
2153
|
+
return t('file_too_large', locale);
|
|
2154
|
+
if (requireImage && !file.type.startsWith('image/'))
|
|
2155
|
+
return t('invalid_image', locale);
|
|
2156
|
+
return '';
|
|
2157
|
+
}
|
|
2158
|
+
/** BEM class string for the drop zone, e.g. base 'mrd-file-field' → 'mrd-file-field__zone …'. */
|
|
2159
|
+
function uploadZoneClass(base, opts) {
|
|
2160
|
+
return [
|
|
2161
|
+
`${base}__zone`,
|
|
2162
|
+
opts.dragging ? `${base}__zone--dragging` : '',
|
|
2163
|
+
opts.error ? `${base}__zone--error` : '',
|
|
2164
|
+
opts.disabled ? `${base}__zone--disabled` : '',
|
|
2165
|
+
].filter(Boolean).join(' ');
|
|
2166
|
+
}
|
|
2167
|
+
/** Drag-drop handlers for the drop zone; the component owns the dragging state and file handling. */
|
|
2168
|
+
function makeDragHandlers(setDragging, onFile) {
|
|
2169
|
+
return {
|
|
2170
|
+
onDragOver: (e) => {
|
|
2171
|
+
e.preventDefault();
|
|
2172
|
+
setDragging(true);
|
|
2173
|
+
},
|
|
2174
|
+
onDragLeave: () => setDragging(false),
|
|
2175
|
+
onDrop: (e) => {
|
|
2176
|
+
var _a, _b, _c;
|
|
2177
|
+
e.preventDefault();
|
|
2178
|
+
setDragging(false);
|
|
2179
|
+
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);
|
|
2180
|
+
},
|
|
2181
|
+
};
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2184
|
+
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)}}`;
|
|
2076
2185
|
|
|
2077
2186
|
const MrdFileField = class {
|
|
2078
2187
|
constructor(hostRef) {
|
|
@@ -2097,20 +2206,7 @@ const MrdFileField = class {
|
|
|
2097
2206
|
const files = e.target.files;
|
|
2098
2207
|
this.handleFile((_a = files === null || files === void 0 ? void 0 : files[0]) !== null && _a !== void 0 ? _a : null);
|
|
2099
2208
|
};
|
|
2100
|
-
this.
|
|
2101
|
-
e.preventDefault();
|
|
2102
|
-
this.isDragging = true;
|
|
2103
|
-
};
|
|
2104
|
-
this.handleDragLeave = () => {
|
|
2105
|
-
this.isDragging = false;
|
|
2106
|
-
};
|
|
2107
|
-
this.handleDrop = (e) => {
|
|
2108
|
-
var _a, _b, _c;
|
|
2109
|
-
e.preventDefault();
|
|
2110
|
-
this.isDragging = false;
|
|
2111
|
-
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;
|
|
2112
|
-
this.handleFile(file);
|
|
2113
|
-
};
|
|
2209
|
+
this.drag = makeDragHandlers(dragging => (this.isDragging = dragging), file => this.handleFile(file));
|
|
2114
2210
|
this.handleZoneClick = () => {
|
|
2115
2211
|
var _a;
|
|
2116
2212
|
if (!this.disabled && !this.uploading) {
|
|
@@ -2144,8 +2240,9 @@ const MrdFileField = class {
|
|
|
2144
2240
|
this.mrdChange.emit({ name: this.name, value: null });
|
|
2145
2241
|
return;
|
|
2146
2242
|
}
|
|
2147
|
-
|
|
2148
|
-
|
|
2243
|
+
const uploadError = validateUploadFile(file, this.maxSize, this.locale);
|
|
2244
|
+
if (uploadError) {
|
|
2245
|
+
this.error = uploadError;
|
|
2149
2246
|
return;
|
|
2150
2247
|
}
|
|
2151
2248
|
this.error = '';
|
|
@@ -2157,13 +2254,12 @@ const MrdFileField = class {
|
|
|
2157
2254
|
render() {
|
|
2158
2255
|
const hasFile = this.uploading || (typeof this.value === 'string' && this.value) || this.fileName;
|
|
2159
2256
|
const hasError = !!this.error;
|
|
2160
|
-
const zoneClass =
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
return (h(Host, { key: '095bb39f3cb1680cf5e7e51bdfd06d8eb087f237' }, h("div", { key: '7e5b5fe6e63b6530221083c8bcb82bcac59a5fe7', class: "mrd-file-field" }, this.label && (h("label", { key: 'c34723f4199371d6fe8ea87463d878b89c038590', class: `mrd-file-field__label${this.required ? ' mrd-file-field__label--required' : ''}` }, this.label)), h("div", { key: '4727667345d3cd4a5c65a431744a09f366943c13', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, 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 ? (h("div", { class: "mrd-file-field__selected" }, this.uploading ? (h("span", { class: "mrd-file-field__spinner", "aria-label": t('loading', this.locale) })) : (h("svg", { class: "mrd-file-field__icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }), h("polyline", { points: "14 2 14 8 20 8" }))), h("span", { class: "mrd-file-field__filename" }, this.fileName), !this.uploading && (h("button", { class: "mrd-file-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, "\u2715")))) : (h("div", { class: "mrd-file-field__prompt" }, h("svg", { class: "mrd-file-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("polyline", { points: "16 16 12 12 8 16" }), h("line", { x1: "12", y1: "12", x2: "12", y2: "21" }), h("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-file-field__browse" }, t('browse', this.locale)))))), hasError && h("span", { key: '00ce94ead3c32ed63e903cfd9d8480084a308d84', class: "mrd-file-field__error" }, this.error))));
|
|
2257
|
+
const zoneClass = uploadZoneClass('mrd-file-field', {
|
|
2258
|
+
dragging: this.isDragging,
|
|
2259
|
+
error: hasError,
|
|
2260
|
+
disabled: this.disabled || this.uploading,
|
|
2261
|
+
});
|
|
2262
|
+
return (h(Host, { key: '2c4cee79cd0f95ed3750dfc86007a2b36aa3da15' }, h("div", { key: '5b47d0f83e8e38b22bb04409544ec2af580274f1', class: "mrd-file-field" }, h(FieldLabel, { key: '47a92d5680670bf750854fa6e7883da54a40baec', base: "mrd-file-field", label: this.label, required: this.required }), h("div", { key: '684f6ab39c32635fb5ca966ccab4a061d8682f89', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, 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 ? (h("div", { class: "mrd-file-field__selected" }, this.uploading ? (h("span", { class: "mrd-file-field__spinner", "aria-label": t('loading', this.locale) })) : (h("svg", { class: "mrd-file-field__icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }), h("polyline", { points: "14 2 14 8 20 8" }))), h("span", { class: "mrd-file-field__filename" }, this.fileName), !this.uploading && (h("button", { class: "mrd-file-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, "\u2715")))) : (h("div", { class: "mrd-file-field__prompt" }, h("svg", { class: "mrd-file-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("polyline", { points: "16 16 12 12 8 16" }), h("line", { x1: "12", y1: "12", x2: "12", y2: "21" }), h("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-file-field__browse" }, t('browse', this.locale)))))), h(FieldError, { key: '5f18e91aa94319a5571c368e745c108fb0d371a7', base: "mrd-file-field", error: this.error }))));
|
|
2167
2263
|
}
|
|
2168
2264
|
static get watchers() { return {
|
|
2169
2265
|
"value": [{
|
|
@@ -2171,9 +2267,9 @@ const MrdFileField = class {
|
|
|
2171
2267
|
}]
|
|
2172
2268
|
}; }
|
|
2173
2269
|
};
|
|
2174
|
-
MrdFileField.style =
|
|
2270
|
+
MrdFileField.style = mrdFileFieldCss();
|
|
2175
2271
|
|
|
2176
|
-
const
|
|
2272
|
+
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)}`;
|
|
2177
2273
|
|
|
2178
2274
|
const MrdForm = class {
|
|
2179
2275
|
constructor(hostRef) {
|
|
@@ -2540,9 +2636,9 @@ const MrdForm = class {
|
|
|
2540
2636
|
}]
|
|
2541
2637
|
}; }
|
|
2542
2638
|
};
|
|
2543
|
-
MrdForm.style =
|
|
2639
|
+
MrdForm.style = mrdFormCss();
|
|
2544
2640
|
|
|
2545
|
-
const
|
|
2641
|
+
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)}`;
|
|
2546
2642
|
|
|
2547
2643
|
const MrdHyperlinkField = class {
|
|
2548
2644
|
constructor(hostRef) {
|
|
@@ -2568,15 +2664,8 @@ const MrdHyperlinkField = class {
|
|
|
2568
2664
|
this.mrdChange.emit({ name: this.name, value: this.buildValue() });
|
|
2569
2665
|
};
|
|
2570
2666
|
this.handleBlur = () => {
|
|
2571
|
-
|
|
2572
|
-
this.
|
|
2573
|
-
}
|
|
2574
|
-
else if (this.internalHref && !validateUrl(this.internalHref)) {
|
|
2575
|
-
this.error = t('invalid_url', this.locale);
|
|
2576
|
-
}
|
|
2577
|
-
else {
|
|
2578
|
-
this.error = '';
|
|
2579
|
-
}
|
|
2667
|
+
this.error = requiredError(this.internalHref, this.required, this.locale)
|
|
2668
|
+
|| (this.internalHref && !validateUrl(this.internalHref) ? t('invalid_url', this.locale) : '');
|
|
2580
2669
|
this.mrdBlur.emit({ name: this.name, value: this.buildValue() });
|
|
2581
2670
|
};
|
|
2582
2671
|
}
|
|
@@ -2609,7 +2698,7 @@ const MrdHyperlinkField = class {
|
|
|
2609
2698
|
? h("a", { class: "mrd-hyperlink-field__link", href: this.internalHref, target: "_blank", rel: "noopener noreferrer" }, this.internalName || this.internalHref)
|
|
2610
2699
|
: h("span", { class: "mrd-hyperlink-field__empty" }, "\u2014"))));
|
|
2611
2700
|
}
|
|
2612
|
-
return (h(Host, null, h("div", { class: "mrd-hyperlink-field" },
|
|
2701
|
+
return (h(Host, null, h("div", { class: "mrd-hyperlink-field" }, h(FieldLabel, { base: "mrd-hyperlink-field", label: this.label, required: this.required }), 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 }), 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 }), h(FieldError, { base: "mrd-hyperlink-field", error: this.error }))));
|
|
2613
2702
|
}
|
|
2614
2703
|
static get watchers() { return {
|
|
2615
2704
|
"value": [{
|
|
@@ -2617,9 +2706,9 @@ const MrdHyperlinkField = class {
|
|
|
2617
2706
|
}]
|
|
2618
2707
|
}; }
|
|
2619
2708
|
};
|
|
2620
|
-
MrdHyperlinkField.style =
|
|
2709
|
+
MrdHyperlinkField.style = mrdHyperlinkFieldCss();
|
|
2621
2710
|
|
|
2622
|
-
const
|
|
2711
|
+
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)}`;
|
|
2623
2712
|
|
|
2624
2713
|
const MrdImageField = class {
|
|
2625
2714
|
constructor(hostRef) {
|
|
@@ -2645,20 +2734,7 @@ const MrdImageField = class {
|
|
|
2645
2734
|
const files = e.target.files;
|
|
2646
2735
|
this.handleFile((_a = files === null || files === void 0 ? void 0 : files[0]) !== null && _a !== void 0 ? _a : null);
|
|
2647
2736
|
};
|
|
2648
|
-
this.
|
|
2649
|
-
e.preventDefault();
|
|
2650
|
-
this.isDragging = true;
|
|
2651
|
-
};
|
|
2652
|
-
this.handleDragLeave = () => {
|
|
2653
|
-
this.isDragging = false;
|
|
2654
|
-
};
|
|
2655
|
-
this.handleDrop = (e) => {
|
|
2656
|
-
var _a, _b, _c;
|
|
2657
|
-
e.preventDefault();
|
|
2658
|
-
this.isDragging = false;
|
|
2659
|
-
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;
|
|
2660
|
-
this.handleFile(file);
|
|
2661
|
-
};
|
|
2737
|
+
this.drag = makeDragHandlers(dragging => (this.isDragging = dragging), file => this.handleFile(file));
|
|
2662
2738
|
this.handleZoneClick = () => {
|
|
2663
2739
|
var _a;
|
|
2664
2740
|
if (!this.disabled && !this.uploading) {
|
|
@@ -2695,12 +2771,9 @@ const MrdImageField = class {
|
|
|
2695
2771
|
this.mrdChange.emit({ name: this.name, value: null });
|
|
2696
2772
|
return;
|
|
2697
2773
|
}
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
}
|
|
2702
|
-
if (!file.type.startsWith('image/')) {
|
|
2703
|
-
this.error = 'Please select an image file';
|
|
2774
|
+
const uploadError = validateUploadFile(file, this.maxSize, this.locale, true);
|
|
2775
|
+
if (uploadError) {
|
|
2776
|
+
this.error = uploadError;
|
|
2704
2777
|
return;
|
|
2705
2778
|
}
|
|
2706
2779
|
this.error = '';
|
|
@@ -2718,13 +2791,12 @@ const MrdImageField = class {
|
|
|
2718
2791
|
}
|
|
2719
2792
|
render() {
|
|
2720
2793
|
const hasError = !!this.error;
|
|
2721
|
-
const zoneClass =
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
return (h(Host, { key: '97db2df72839f36b7a46e153a5dd1c208c52b522' }, h("div", { key: 'c8f2d3d858f90d322d26082aaf5adb57acfc78f4', class: "mrd-image-field" }, this.label && (h("label", { key: '6625e5031ff0b7c06f76c1ea0387f1bd5c1858a4', class: `mrd-image-field__label${this.required ? ' mrd-image-field__label--required' : ''}` }, this.label)), h("div", { key: '364216e6a96e845e21c42e821fdff02bd2612ff8', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, 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 ? (h("div", { class: "mrd-image-field__preview-container" }, h("div", { class: "mrd-image-field__preview-thumb" }, h("img", { class: "mrd-image-field__preview", src: this.previewUrl, alt: this.fileName }), this.uploading && h("div", { class: "mrd-image-field__preview-overlay" }, h("span", { class: "mrd-image-field__spinner" }))), h("div", { class: "mrd-image-field__preview-info" }, h("span", { class: "mrd-image-field__preview-name" }, this.fileName), this.uploading && (h("span", { class: "mrd-image-field__upload-status" }, t('loading', this.locale)))), !this.uploading && (h("button", { class: "mrd-image-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, t('remove', this.locale))))) : (h("div", { class: "mrd-image-field__prompt" }, h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), h("polyline", { points: "21 15 16 10 5 21" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-image-field__browse" }, t('browse', this.locale)))))), hasError && h("span", { key: 'bd505ef4f4b67c4e9138d8825c6e600f583f4cab', class: "mrd-image-field__error" }, this.error))));
|
|
2794
|
+
const zoneClass = uploadZoneClass('mrd-image-field', {
|
|
2795
|
+
dragging: this.isDragging,
|
|
2796
|
+
error: hasError,
|
|
2797
|
+
disabled: this.disabled || this.uploading,
|
|
2798
|
+
});
|
|
2799
|
+
return (h(Host, { key: 'ab78d93ab6c810363a8993bea4545f7406680e58' }, h("div", { key: '727ae5d9c1cce22d90d26229a9ea5d677abb4b07', class: "mrd-image-field" }, h(FieldLabel, { key: 'aab0e9fcc0204e8ea617453b5ca458f683194125', base: "mrd-image-field", label: this.label, required: this.required }), h("div", { key: '1241faff26c47a303fd0431201f490c6b8725987', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.drag.onDragOver, onDragLeave: this.drag.onDragLeave, onDrop: this.drag.onDrop }, 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 ? (h("div", { class: "mrd-image-field__preview-container" }, h("div", { class: "mrd-image-field__preview-thumb" }, h("img", { class: "mrd-image-field__preview", src: this.previewUrl, alt: this.fileName }), this.uploading && h("div", { class: "mrd-image-field__preview-overlay" }, h("span", { class: "mrd-image-field__spinner" }))), h("div", { class: "mrd-image-field__preview-info" }, h("span", { class: "mrd-image-field__preview-name" }, this.fileName), this.uploading && (h("span", { class: "mrd-image-field__upload-status" }, t('loading', this.locale)))), !this.uploading && (h("button", { class: "mrd-image-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, t('remove', this.locale))))) : (h("div", { class: "mrd-image-field__prompt" }, h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), h("polyline", { points: "21 15 16 10 5 21" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-image-field__browse" }, t('browse', this.locale)))))), h(FieldError, { key: '01552a994c1e5a9f25129586a95562c32a377046', base: "mrd-image-field", error: this.error }))));
|
|
2728
2800
|
}
|
|
2729
2801
|
static get watchers() { return {
|
|
2730
2802
|
"value": [{
|
|
@@ -2732,7 +2804,36 @@ const MrdImageField = class {
|
|
|
2732
2804
|
}]
|
|
2733
2805
|
}; }
|
|
2734
2806
|
};
|
|
2735
|
-
MrdImageField.style =
|
|
2807
|
+
MrdImageField.style = mrdImageFieldCss();
|
|
2808
|
+
|
|
2809
|
+
/** Key an embedded view is addressed by (setViewPage etc.). */
|
|
2810
|
+
function viewKeyFor(item) {
|
|
2811
|
+
var _a, _b, _c, _d;
|
|
2812
|
+
if (item.type === ClientLayoutItemType.RELATED_VIEW)
|
|
2813
|
+
return (_b = (_a = item.relatedClass) !== null && _a !== void 0 ? _a : item.name) !== null && _b !== void 0 ? _b : '';
|
|
2814
|
+
return (_d = (_c = item.dataClass) !== null && _c !== void 0 ? _c : item.name) !== null && _d !== void 0 ? _d : '';
|
|
2815
|
+
}
|
|
2816
|
+
/** Depth-first flatten of the SECTION/GROUP tree. */
|
|
2817
|
+
function flattenItems(items) {
|
|
2818
|
+
const result = [];
|
|
2819
|
+
for (const item of items) {
|
|
2820
|
+
result.push(item);
|
|
2821
|
+
if (item.items)
|
|
2822
|
+
result.push(...flattenItems(item.items));
|
|
2823
|
+
}
|
|
2824
|
+
return result;
|
|
2825
|
+
}
|
|
2826
|
+
/** Build the canonical parent href `/{base}/{tenant}/{fromClass}/{parentId}` from
|
|
2827
|
+
* the object's self href. Empty unless it is a RELATED_VIEW with a fromClass. */
|
|
2828
|
+
function buildContainerHref(item, selfHref, parentId) {
|
|
2829
|
+
if (item.type !== ClientLayoutItemType.RELATED_VIEW || !item.fromClass || !parentId)
|
|
2830
|
+
return '';
|
|
2831
|
+
const segs = selfHref.split('/').filter(Boolean);
|
|
2832
|
+
if (segs.length < 2)
|
|
2833
|
+
return '';
|
|
2834
|
+
const [base, tenant] = segs;
|
|
2835
|
+
return `/${base}/${tenant}/${item.fromClass}/${parentId}`;
|
|
2836
|
+
}
|
|
2736
2837
|
|
|
2737
2838
|
class CellRenderer {
|
|
2738
2839
|
static render(column, row, locale) {
|
|
@@ -2838,7 +2939,114 @@ class CellRenderer {
|
|
|
2838
2939
|
}
|
|
2839
2940
|
}
|
|
2840
2941
|
|
|
2841
|
-
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}`;
|
|
2942
|
+
/** FILE and IMAGE cells share the same download button. */
|
|
2943
|
+
function downloadLink(ctx, href, fileName, label) {
|
|
2944
|
+
return (h("button", { class: "mrd-layout-section__download-link", onClick: () => href && ctx.on.download({ href, fileName }) }, h("svg", { class: "mrd-layout-section__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 7V3.5L18.5 9H13zm-3 8l-3-3 1.41-1.41L10 14.17l4.59-4.58L16 11l-6 6z" })), label));
|
|
2945
|
+
}
|
|
2946
|
+
function renderSingleFieldValue(ctx, item, value) {
|
|
2947
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
2948
|
+
const dt = item.dataType;
|
|
2949
|
+
switch (dt) {
|
|
2950
|
+
case ClientLayoutItemFieldDataType.HYPERLINK: {
|
|
2951
|
+
const v = value;
|
|
2952
|
+
const href = (_a = v === null || v === void 0 ? void 0 : v.href) !== null && _a !== void 0 ? _a : String(value);
|
|
2953
|
+
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;
|
|
2954
|
+
return (h("a", { class: "mrd-layout-section__link", href: href, target: "_blank", rel: "noopener noreferrer" }, label));
|
|
2955
|
+
}
|
|
2956
|
+
case ClientLayoutItemFieldDataType.TEXTBLOCK:
|
|
2957
|
+
return h("div", { class: "mrd-layout-section__prose", innerHTML: String(value) });
|
|
2958
|
+
case ClientLayoutItemFieldDataType.LONGTEXT:
|
|
2959
|
+
return h("pre", { class: "mrd-layout-section__pre" }, String(value));
|
|
2960
|
+
case ClientLayoutItemFieldDataType.JSON:
|
|
2961
|
+
return h("pre", { class: "mrd-layout-section__pre", innerHTML: CellRenderer.formatJson(value) });
|
|
2962
|
+
case ClientLayoutItemFieldDataType.FILE: {
|
|
2963
|
+
const v = value;
|
|
2964
|
+
const fileName = (_e = v === null || v === void 0 ? void 0 : v.fileName) !== null && _e !== void 0 ? _e : String(value);
|
|
2965
|
+
const href = (_f = v === null || v === void 0 ? void 0 : v.href) !== null && _f !== void 0 ? _f : '';
|
|
2966
|
+
return downloadLink(ctx, href, fileName, t('download', ctx.locale));
|
|
2967
|
+
}
|
|
2968
|
+
case ClientLayoutItemFieldDataType.IMAGE: {
|
|
2969
|
+
const v = value;
|
|
2970
|
+
const href = (_g = v === null || v === void 0 ? void 0 : v.href) !== null && _g !== void 0 ? _g : '';
|
|
2971
|
+
const fileName = (_h = v === null || v === void 0 ? void 0 : v.fileName) !== null && _h !== void 0 ? _h : '';
|
|
2972
|
+
const previewUrl = ctx.imagePreviews[item.name];
|
|
2973
|
+
if (previewUrl) {
|
|
2974
|
+
return (h("button", { class: "mrd-layout-section__image-thumb-btn", onClick: () => ctx.on.openImage(previewUrl), title: fileName || undefined }, h("img", { class: "mrd-layout-section__image-thumb", src: previewUrl, alt: fileName })));
|
|
2975
|
+
}
|
|
2976
|
+
return downloadLink(ctx, href, fileName, fileName || href);
|
|
2977
|
+
}
|
|
2978
|
+
case ClientLayoutItemFieldDataType.BOOLEAN:
|
|
2979
|
+
return (h("span", { class: `mrd-layout-section__boolean mrd-layout-section__boolean--${value ? 'true' : 'false'}` }, value ? t('yes', ctx.locale) : t('no', ctx.locale)));
|
|
2980
|
+
case ClientLayoutItemFieldDataType.LIST: {
|
|
2981
|
+
const listItem = ((_j = item.listItems) !== null && _j !== void 0 ? _j : []).find(li => li.key === String(value));
|
|
2982
|
+
const label = (_k = listItem === null || listItem === void 0 ? void 0 : listItem.label) !== null && _k !== void 0 ? _k : String(value);
|
|
2983
|
+
const color = listItem === null || listItem === void 0 ? void 0 : listItem.color;
|
|
2984
|
+
const bg = listItem === null || listItem === void 0 ? void 0 : listItem.backgroundColor;
|
|
2985
|
+
if (color && bg) {
|
|
2986
|
+
return (h("span", { class: "mrd-layout-section__badge", style: { color, backgroundColor: bg } }, label));
|
|
2987
|
+
}
|
|
2988
|
+
if (color) {
|
|
2989
|
+
return (h("span", { class: "mrd-layout-section__badge-dot-row" }, h("span", { class: "mrd-layout-section__badge-dot", style: { backgroundColor: color } }), label));
|
|
2990
|
+
}
|
|
2991
|
+
return label;
|
|
2992
|
+
}
|
|
2993
|
+
case ClientLayoutItemFieldDataType.SECRET:
|
|
2994
|
+
return value ? h("span", { class: "mrd-layout-section__secret-masked" }, '••••••••') : null;
|
|
2995
|
+
default: {
|
|
2996
|
+
const text = CellRenderer.renderValue(dt, value, (_l = item.listItems) !== null && _l !== void 0 ? _l : [], ctx.locale);
|
|
2997
|
+
return text || null;
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
function renderFieldValue(ctx, item, rawValue) {
|
|
3002
|
+
if (rawValue == null || rawValue === '')
|
|
3003
|
+
return null;
|
|
3004
|
+
if (item.multiple && Array.isArray(rawValue)) {
|
|
3005
|
+
const rendered = rawValue.map(v => renderSingleFieldValue(ctx, item, v));
|
|
3006
|
+
if (rendered.every(r => typeof r === 'string' || r == null)) {
|
|
3007
|
+
return rendered.filter(Boolean).join(', ') || null;
|
|
3008
|
+
}
|
|
3009
|
+
return (h("span", null, rendered.map((r, i) => (h("span", { key: String(i) }, r, i < rendered.length - 1 ? ', ' : '')))));
|
|
3010
|
+
}
|
|
3011
|
+
return renderSingleFieldValue(ctx, item, rawValue);
|
|
3012
|
+
}
|
|
3013
|
+
function renderHistoryBadge(ctx, item, raw) {
|
|
3014
|
+
var _a, _b, _c;
|
|
3015
|
+
const hist = (_a = item.historyEnabled) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.historyEnabled;
|
|
3016
|
+
if (!hist || !item.name)
|
|
3017
|
+
return null;
|
|
3018
|
+
const history = (_c = raw === null || raw === void 0 ? void 0 : raw.history) !== null && _c !== void 0 ? _c : [];
|
|
3019
|
+
if (!history.length)
|
|
3020
|
+
return null;
|
|
3021
|
+
const sorted = [...history].sort((a, b) => b.until.localeCompare(a.until));
|
|
3022
|
+
const isOpen = ctx.openHistoryField === item.name;
|
|
3023
|
+
return (h("span", { class: "mrd-layout-section__history-wrap" }, 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) => {
|
|
3024
|
+
e.stopPropagation();
|
|
3025
|
+
ctx.on.toggleHistory(isOpen ? null : item.name);
|
|
3026
|
+
} }, h("svg", { class: "mrd-layout-section__history-icon", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, 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 && (h("div", { class: "mrd-layout-section__history-popover", role: "listbox" }, sorted.map((entry, i) => (h("div", { key: String(i), class: "mrd-layout-section__history-entry" }, entry.value, " (", t('history_until', ctx.locale), " ", formatDate(entry.until, ctx.locale), ")")))))));
|
|
3027
|
+
}
|
|
3028
|
+
function renderField(ctx, item) {
|
|
3029
|
+
var _a, _b;
|
|
3030
|
+
if (!item.name)
|
|
3031
|
+
return null;
|
|
3032
|
+
const raw = ctx.data[item.name];
|
|
3033
|
+
const hist = (_a = item.historyEnabled) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.historyEnabled;
|
|
3034
|
+
const rawValue = hist && raw !== null && typeof raw === 'object' && 'current' in raw
|
|
3035
|
+
? raw.current
|
|
3036
|
+
: raw;
|
|
3037
|
+
const renderedValue = renderFieldValue(ctx, item, rawValue);
|
|
3038
|
+
if (item.header) {
|
|
3039
|
+
return (h("h1", { class: "mrd-layout-section__field-header", key: item.name }, typeof renderedValue === 'string' ? renderedValue : rawValue != null ? String(rawValue) : item.label));
|
|
3040
|
+
}
|
|
3041
|
+
if (renderedValue == null)
|
|
3042
|
+
return null;
|
|
3043
|
+
const isBlock = item.dataType === ClientLayoutItemFieldDataType.TEXTBLOCK
|
|
3044
|
+
|| item.dataType === ClientLayoutItemFieldDataType.LONGTEXT
|
|
3045
|
+
|| item.dataType === ClientLayoutItemFieldDataType.JSON;
|
|
3046
|
+
return (h("div", { class: `mrd-layout-section__field${isBlock ? ' mrd-layout-section__field--block' : ''}`, key: item.name }, h("span", { class: "mrd-layout-section__field-label" }, item.label), h("span", { class: "mrd-layout-section__field-value" }, renderedValue, renderHistoryBadge(ctx, item, raw))));
|
|
3047
|
+
}
|
|
3048
|
+
|
|
3049
|
+
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}`;
|
|
2842
3050
|
|
|
2843
3051
|
const MrdLayoutSection = class {
|
|
2844
3052
|
constructor(hostRef) {
|
|
@@ -2920,14 +3128,8 @@ const MrdLayoutSection = class {
|
|
|
2920
3128
|
}
|
|
2921
3129
|
}
|
|
2922
3130
|
}
|
|
2923
|
-
viewKeyFor(item) {
|
|
2924
|
-
var _a, _b, _c, _d;
|
|
2925
|
-
if (item.type === ClientLayoutItemType.RELATED_VIEW)
|
|
2926
|
-
return (_b = (_a = item.relatedClass) !== null && _a !== void 0 ? _a : item.name) !== null && _b !== void 0 ? _b : '';
|
|
2927
|
-
return (_d = (_c = item.dataClass) !== null && _c !== void 0 ? _c : item.name) !== null && _d !== void 0 ? _d : '';
|
|
2928
|
-
}
|
|
2929
3131
|
emitLoadImages() {
|
|
2930
|
-
for (const item of
|
|
3132
|
+
for (const item of flattenItems(this.items)) {
|
|
2931
3133
|
if (item.type === ClientLayoutItemType.FIELD && item.dataType === ClientLayoutItemFieldDataType.IMAGE) {
|
|
2932
3134
|
const fieldName = item.name;
|
|
2933
3135
|
const raw = this.data[fieldName];
|
|
@@ -2937,15 +3139,6 @@ const MrdLayoutSection = class {
|
|
|
2937
3139
|
}
|
|
2938
3140
|
}
|
|
2939
3141
|
}
|
|
2940
|
-
flattenItems(items) {
|
|
2941
|
-
const result = [];
|
|
2942
|
-
for (const item of items) {
|
|
2943
|
-
result.push(item);
|
|
2944
|
-
if (item.items)
|
|
2945
|
-
result.push(...this.flattenItems(item.items));
|
|
2946
|
-
}
|
|
2947
|
-
return result;
|
|
2948
|
-
}
|
|
2949
3142
|
/** Inject search results. Pass dataClass to target a specific SEARCH item; omit when there is only one. */
|
|
2950
3143
|
async setSearchResults(results, dataClass) {
|
|
2951
3144
|
const key = dataClass !== null && dataClass !== void 0 ? dataClass : this.resolveSearchKey();
|
|
@@ -3011,113 +3204,26 @@ const MrdLayoutSection = class {
|
|
|
3011
3204
|
}
|
|
3012
3205
|
resolveSearchKey() {
|
|
3013
3206
|
var _a;
|
|
3014
|
-
const items =
|
|
3207
|
+
const items = flattenItems(this.items).filter(i => i.type === ClientLayoutItemType.SEARCH);
|
|
3015
3208
|
if (items.length === 1)
|
|
3016
3209
|
return (_a = items[0].dataClass) !== null && _a !== void 0 ? _a : null;
|
|
3017
3210
|
return null;
|
|
3018
3211
|
}
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
case ClientLayoutItemFieldDataType.LONGTEXT:
|
|
3032
|
-
return h("pre", { class: "mrd-layout-section__pre" }, String(value));
|
|
3033
|
-
case ClientLayoutItemFieldDataType.JSON:
|
|
3034
|
-
return h("pre", { class: "mrd-layout-section__pre", innerHTML: CellRenderer.formatJson(value) });
|
|
3035
|
-
case ClientLayoutItemFieldDataType.FILE: {
|
|
3036
|
-
const v = value;
|
|
3037
|
-
const fileName = (_e = v === null || v === void 0 ? void 0 : v.fileName) !== null && _e !== void 0 ? _e : String(value);
|
|
3038
|
-
const href = (_f = v === null || v === void 0 ? void 0 : v.href) !== null && _f !== void 0 ? _f : '';
|
|
3039
|
-
return (h("button", { class: "mrd-layout-section__download-link", onClick: () => href && this.mrdDownload.emit({ href, fileName }) }, h("svg", { class: "mrd-layout-section__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 7V3.5L18.5 9H13zm-3 8l-3-3 1.41-1.41L10 14.17l4.59-4.58L16 11l-6 6z" })), t('download', this.locale)));
|
|
3040
|
-
}
|
|
3041
|
-
case ClientLayoutItemFieldDataType.IMAGE: {
|
|
3042
|
-
const v = value;
|
|
3043
|
-
const href = (_g = v === null || v === void 0 ? void 0 : v.href) !== null && _g !== void 0 ? _g : '';
|
|
3044
|
-
const fileName = (_h = v === null || v === void 0 ? void 0 : v.fileName) !== null && _h !== void 0 ? _h : '';
|
|
3045
|
-
const previewUrl = this.imagePreviews[item.name];
|
|
3046
|
-
if (previewUrl) {
|
|
3047
|
-
return (h("button", { class: "mrd-layout-section__image-thumb-btn", onClick: () => { this.imagePreviewUrl = previewUrl; }, title: fileName || undefined }, h("img", { class: "mrd-layout-section__image-thumb", src: previewUrl, alt: fileName })));
|
|
3048
|
-
}
|
|
3049
|
-
return (h("button", { class: "mrd-layout-section__download-link", onClick: () => href && this.mrdDownload.emit({ href, fileName }) }, h("svg", { class: "mrd-layout-section__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 7V3.5L18.5 9H13zm-3 8l-3-3 1.41-1.41L10 14.17l4.59-4.58L16 11l-6 6z" })), fileName || href));
|
|
3050
|
-
}
|
|
3051
|
-
case ClientLayoutItemFieldDataType.BOOLEAN:
|
|
3052
|
-
return (h("span", { class: `mrd-layout-section__boolean mrd-layout-section__boolean--${value ? 'true' : 'false'}` }, value ? t('yes', this.locale) : t('no', this.locale)));
|
|
3053
|
-
case ClientLayoutItemFieldDataType.LIST: {
|
|
3054
|
-
const listItem = ((_j = item.listItems) !== null && _j !== void 0 ? _j : []).find(li => li.key === String(value));
|
|
3055
|
-
const label = (_k = listItem === null || listItem === void 0 ? void 0 : listItem.label) !== null && _k !== void 0 ? _k : String(value);
|
|
3056
|
-
const color = listItem === null || listItem === void 0 ? void 0 : listItem.color;
|
|
3057
|
-
const bg = listItem === null || listItem === void 0 ? void 0 : listItem.backgroundColor;
|
|
3058
|
-
if (color && bg) {
|
|
3059
|
-
return (h("span", { class: "mrd-layout-section__badge", style: { color, backgroundColor: bg } }, label));
|
|
3060
|
-
}
|
|
3061
|
-
if (color) {
|
|
3062
|
-
return (h("span", { class: "mrd-layout-section__badge-dot-row" }, h("span", { class: "mrd-layout-section__badge-dot", style: { backgroundColor: color } }), label));
|
|
3063
|
-
}
|
|
3064
|
-
return label;
|
|
3065
|
-
}
|
|
3066
|
-
case ClientLayoutItemFieldDataType.SECRET:
|
|
3067
|
-
return value ? h("span", { class: "mrd-layout-section__secret-masked" }, '••••••••') : null;
|
|
3068
|
-
default: {
|
|
3069
|
-
const text = CellRenderer.renderValue(dt, value, (_l = item.listItems) !== null && _l !== void 0 ? _l : [], this.locale);
|
|
3070
|
-
return text || null;
|
|
3071
|
-
}
|
|
3072
|
-
}
|
|
3073
|
-
}
|
|
3074
|
-
renderFieldValue(item, rawValue) {
|
|
3075
|
-
if (rawValue == null || rawValue === '')
|
|
3076
|
-
return null;
|
|
3077
|
-
if (item.multiple && Array.isArray(rawValue)) {
|
|
3078
|
-
const rendered = rawValue.map(v => this.renderSingleFieldValue(item, v));
|
|
3079
|
-
if (rendered.every(r => typeof r === 'string' || r == null)) {
|
|
3080
|
-
return rendered.filter(Boolean).join(', ') || null;
|
|
3081
|
-
}
|
|
3082
|
-
return (h("span", null, rendered.map((r, i) => (h("span", { key: String(i) }, r, i < rendered.length - 1 ? ', ' : '')))));
|
|
3083
|
-
}
|
|
3084
|
-
return this.renderSingleFieldValue(item, rawValue);
|
|
3085
|
-
}
|
|
3086
|
-
renderHistoryBadge(item, raw) {
|
|
3087
|
-
var _a, _b, _c;
|
|
3088
|
-
const hist = (_a = item.historyEnabled) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.historyEnabled;
|
|
3089
|
-
if (!hist || !item.name)
|
|
3090
|
-
return null;
|
|
3091
|
-
const history = (_c = raw === null || raw === void 0 ? void 0 : raw.history) !== null && _c !== void 0 ? _c : [];
|
|
3092
|
-
if (!history.length)
|
|
3093
|
-
return null;
|
|
3094
|
-
const sorted = [...history].sort((a, b) => b.until.localeCompare(a.until));
|
|
3095
|
-
const isOpen = this.openHistoryField === item.name;
|
|
3096
|
-
const { locale } = this;
|
|
3097
|
-
return (h("span", { class: "mrd-layout-section__history-wrap" }, 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) => {
|
|
3098
|
-
e.stopPropagation();
|
|
3099
|
-
this.openHistoryField = isOpen ? null : item.name;
|
|
3100
|
-
} }, h("svg", { class: "mrd-layout-section__history-icon", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, 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 && (h("div", { class: "mrd-layout-section__history-popover", role: "listbox" }, sorted.map((entry, i) => (h("div", { key: String(i), class: "mrd-layout-section__history-entry" }, entry.value, " (", t('history_until', locale), " ", formatDate(entry.until, locale), ")")))))));
|
|
3212
|
+
fieldCtx() {
|
|
3213
|
+
return {
|
|
3214
|
+
locale: this.locale,
|
|
3215
|
+
data: this.data,
|
|
3216
|
+
imagePreviews: this.imagePreviews,
|
|
3217
|
+
openHistoryField: this.openHistoryField,
|
|
3218
|
+
on: {
|
|
3219
|
+
download: detail => this.mrdDownload.emit(detail),
|
|
3220
|
+
openImage: url => { this.imagePreviewUrl = url; },
|
|
3221
|
+
toggleHistory: fieldName => { this.openHistoryField = fieldName; },
|
|
3222
|
+
},
|
|
3223
|
+
};
|
|
3101
3224
|
}
|
|
3102
3225
|
renderField(item) {
|
|
3103
|
-
|
|
3104
|
-
if (!item.name)
|
|
3105
|
-
return null;
|
|
3106
|
-
const raw = this.data[item.name];
|
|
3107
|
-
const hist = (_a = item.historyEnabled) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.historyEnabled;
|
|
3108
|
-
const rawValue = hist && raw !== null && typeof raw === 'object' && 'current' in raw
|
|
3109
|
-
? raw.current
|
|
3110
|
-
: raw;
|
|
3111
|
-
const renderedValue = this.renderFieldValue(item, rawValue);
|
|
3112
|
-
if (item.header) {
|
|
3113
|
-
return (h("h1", { class: "mrd-layout-section__field-header", key: item.name }, typeof renderedValue === 'string' ? renderedValue : rawValue != null ? String(rawValue) : item.label));
|
|
3114
|
-
}
|
|
3115
|
-
if (renderedValue == null)
|
|
3116
|
-
return null;
|
|
3117
|
-
const isBlock = item.dataType === ClientLayoutItemFieldDataType.TEXTBLOCK
|
|
3118
|
-
|| item.dataType === ClientLayoutItemFieldDataType.LONGTEXT
|
|
3119
|
-
|| item.dataType === ClientLayoutItemFieldDataType.JSON;
|
|
3120
|
-
return (h("div", { class: `mrd-layout-section__field${isBlock ? ' mrd-layout-section__field--block' : ''}`, key: item.name }, h("span", { class: "mrd-layout-section__field-label" }, item.label), h("span", { class: "mrd-layout-section__field-value" }, renderedValue, this.renderHistoryBadge(item, raw))));
|
|
3226
|
+
return renderField(this.fieldCtx(), item);
|
|
3121
3227
|
}
|
|
3122
3228
|
renderRelation(item) {
|
|
3123
3229
|
var _a, _b, _c;
|
|
@@ -3150,7 +3256,7 @@ const MrdLayoutSection = class {
|
|
|
3150
3256
|
}
|
|
3151
3257
|
renderRelatedView(item) {
|
|
3152
3258
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
3153
|
-
const key =
|
|
3259
|
+
const key = viewKeyFor(item);
|
|
3154
3260
|
if (!key)
|
|
3155
3261
|
return null;
|
|
3156
3262
|
if (!item.view)
|
|
@@ -3165,22 +3271,11 @@ const MrdLayoutSection = class {
|
|
|
3165
3271
|
// Canonical parent href for single-container seeding: use the RELATED_VIEW's
|
|
3166
3272
|
// fromClass (base class) rather than the route class, so polymorphic subtypes
|
|
3167
3273
|
// resolve to the same container the documents actually reference.
|
|
3168
|
-
const containerHref =
|
|
3274
|
+
const containerHref = buildContainerHref(item, selfHref, parentId);
|
|
3169
3275
|
return (h("div", { class: "mrd-layout-section__related-view", key: `view-${key}` }, showTitle && item.label && h("h3", { class: "mrd-layout-section__related-view-title" }, item.label), docArchetype
|
|
3170
3276
|
? this.renderDocumentContainer(item, key, parentId, docArchetype, containerHref)
|
|
3171
3277
|
: this.renderTable(item, key, parentId)));
|
|
3172
3278
|
}
|
|
3173
|
-
/** Build the canonical parent href `/{base}/{tenant}/{fromClass}/{parentId}` from
|
|
3174
|
-
* the object's self href. Empty unless it is a RELATED_VIEW with a fromClass. */
|
|
3175
|
-
buildContainerHref(item, selfHref, parentId) {
|
|
3176
|
-
if (item.type !== ClientLayoutItemType.RELATED_VIEW || !item.fromClass || !parentId)
|
|
3177
|
-
return '';
|
|
3178
|
-
const segs = selfHref.split('/').filter(Boolean);
|
|
3179
|
-
if (segs.length < 2)
|
|
3180
|
-
return '';
|
|
3181
|
-
const [base, tenant] = segs;
|
|
3182
|
-
return `/${base}/${tenant}/${item.fromClass}/${parentId}`;
|
|
3183
|
-
}
|
|
3184
3279
|
/** Document collection view: owns the view-switch + collection actions and
|
|
3185
3280
|
* swaps between the folder tree and the flat table. Events are re-emitted to
|
|
3186
3281
|
* the host with the view key, exactly as the raw list/table events were. */
|
|
@@ -3281,7 +3376,7 @@ const MrdLayoutSection = class {
|
|
|
3281
3376
|
}
|
|
3282
3377
|
render() {
|
|
3283
3378
|
const docArchetype = resolveArchetype(this.archetypes, ARCHETYPE_DOCUMENT);
|
|
3284
|
-
return (h(Host, { key: '
|
|
3379
|
+
return (h(Host, { key: '5d778188356a25ea13d45745dc5ed573ab2b2ef0' }, h("div", { key: '0b673a4bcf8b36cd21662bb8a3506cc3f30edb04', class: "mrd-layout-section" }, docArchetype
|
|
3285
3380
|
? this.renderDocumentObject(docArchetype)
|
|
3286
3381
|
: this.items.map(item => this.renderItem(item))), this.renderImageModal()));
|
|
3287
3382
|
}
|
|
@@ -3292,9 +3387,9 @@ const MrdLayoutSection = class {
|
|
|
3292
3387
|
}]
|
|
3293
3388
|
}; }
|
|
3294
3389
|
};
|
|
3295
|
-
MrdLayoutSection.style =
|
|
3390
|
+
MrdLayoutSection.style = mrdLayoutSectionCss();
|
|
3296
3391
|
|
|
3297
|
-
const
|
|
3392
|
+
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}`;
|
|
3298
3393
|
|
|
3299
3394
|
const MrdListField = class {
|
|
3300
3395
|
constructor(hostRef) {
|
|
@@ -3317,22 +3412,12 @@ const MrdListField = class {
|
|
|
3317
3412
|
if (this.multiple) {
|
|
3318
3413
|
const vals = Array.from(select.selectedOptions).map(o => o.value);
|
|
3319
3414
|
this.selected = vals;
|
|
3320
|
-
|
|
3321
|
-
this.error = t('required', this.locale);
|
|
3322
|
-
}
|
|
3323
|
-
else {
|
|
3324
|
-
this.error = '';
|
|
3325
|
-
}
|
|
3415
|
+
this.error = requiredError(vals, this.required, this.locale);
|
|
3326
3416
|
this.mrdChange.emit({ name: this.name, value: vals });
|
|
3327
3417
|
}
|
|
3328
3418
|
else {
|
|
3329
3419
|
const val = select.value;
|
|
3330
|
-
|
|
3331
|
-
this.error = t('required', this.locale);
|
|
3332
|
-
}
|
|
3333
|
-
else {
|
|
3334
|
-
this.error = '';
|
|
3335
|
-
}
|
|
3420
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
3336
3421
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
3337
3422
|
}
|
|
3338
3423
|
};
|
|
@@ -3347,12 +3432,7 @@ const MrdListField = class {
|
|
|
3347
3432
|
else {
|
|
3348
3433
|
this.selected = [...this.selected, key];
|
|
3349
3434
|
}
|
|
3350
|
-
|
|
3351
|
-
this.error = t('required', this.locale);
|
|
3352
|
-
}
|
|
3353
|
-
else {
|
|
3354
|
-
this.error = '';
|
|
3355
|
-
}
|
|
3435
|
+
this.error = requiredError(this.selected, this.required, this.locale);
|
|
3356
3436
|
this.mrdChange.emit({ name: this.name, value: this.selected });
|
|
3357
3437
|
};
|
|
3358
3438
|
}
|
|
@@ -3376,22 +3456,22 @@ const MrdListField = class {
|
|
|
3376
3456
|
const hasError = !!this.error;
|
|
3377
3457
|
const currentValue = Array.isArray(this.value) ? ((_a = this.value[0]) !== null && _a !== void 0 ? _a : '') : ((_b = this.value) !== null && _b !== void 0 ? _b : '');
|
|
3378
3458
|
if (this.multiple) {
|
|
3379
|
-
return (h(Host, null, h("div", { class: "mrd-list-field" },
|
|
3459
|
+
return (h(Host, null, h("div", { class: "mrd-list-field" }, h(FieldLabel, { base: "mrd-list-field", label: this.label, required: this.required }), h("div", { class: controlClass('mrd-list-field', hasError, 'checkbox-list') }, this.listItems.map(lv => {
|
|
3380
3460
|
var _a, _b;
|
|
3381
3461
|
return (h("label", { key: lv.key, class: "mrd-list-field__checkbox-item" }, h("input", { type: "checkbox", checked: this.selected.includes(lv.key), disabled: this.disabled, onChange: () => this.toggleCheckbox(lv.key) }), (lv.color || lv.backgroundColor) && (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 : '' } })), h("span", null, lv.label)));
|
|
3382
|
-
})),
|
|
3462
|
+
})), h(FieldError, { base: "mrd-list-field", error: this.error }))));
|
|
3383
3463
|
}
|
|
3384
|
-
return (h(Host, null, h("div", { class: "mrd-list-field" },
|
|
3464
|
+
return (h(Host, null, h("div", { class: "mrd-list-field" }, h(FieldLabel, { base: "mrd-list-field", label: this.label, required: this.required }), h("select", { class: controlClass('mrd-list-field', hasError, 'select'), name: this.name, required: this.required, disabled: this.disabled, onChange: this.handleSelectChange, onBlur: this.handleBlur }, h("option", { value: "" }, t('select_placeholder', this.locale)), this.listItems.map(lv => {
|
|
3385
3465
|
var _a, _b;
|
|
3386
3466
|
const bg = (_b = (_a = lv.backgroundColor) !== null && _a !== void 0 ? _a : lv.color) !== null && _b !== void 0 ? _b : null;
|
|
3387
3467
|
const style = bg ? { backgroundColor: bg, color: this.getContrastColor(bg) } : {};
|
|
3388
3468
|
return (h("option", { key: lv.key, value: lv.key, selected: lv.key === currentValue, style: style }, lv.label));
|
|
3389
|
-
})),
|
|
3469
|
+
})), h(FieldError, { base: "mrd-list-field", error: this.error }))));
|
|
3390
3470
|
}
|
|
3391
3471
|
};
|
|
3392
|
-
MrdListField.style =
|
|
3472
|
+
MrdListField.style = mrdListFieldCss();
|
|
3393
3473
|
|
|
3394
|
-
const
|
|
3474
|
+
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}`;
|
|
3395
3475
|
|
|
3396
3476
|
const MrdLongtextField = class {
|
|
3397
3477
|
constructor(hostRef) {
|
|
@@ -3412,23 +3492,17 @@ const MrdLongtextField = class {
|
|
|
3412
3492
|
};
|
|
3413
3493
|
this.handleBlur = (e) => {
|
|
3414
3494
|
const val = e.target.value;
|
|
3415
|
-
|
|
3416
|
-
this.error = t('required', this.locale);
|
|
3417
|
-
}
|
|
3418
|
-
else {
|
|
3419
|
-
this.error = '';
|
|
3420
|
-
}
|
|
3495
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
3421
3496
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
3422
3497
|
};
|
|
3423
3498
|
}
|
|
3424
3499
|
render() {
|
|
3425
|
-
|
|
3426
|
-
return (h(Host, { key: 'f00f81944748f8f09e22d44befe5e288456b7cc8' }, h("div", { key: '7b0ae9cf5b6b684cddb648fe4db6005494322535', class: "mrd-longtext-field" }, this.label && (h("label", { key: '3fc6a8710d0e98fe685c45d214a88ae1b0947973', class: `mrd-longtext-field__label${this.required ? ' mrd-longtext-field__label--required' : ''}` }, this.label)), this.disabled ? (h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (h("textarea", { class: `mrd-longtext-field__input${hasError ? ' mrd-longtext-field__input--error' : ''}`, name: this.name, placeholder: this.placeholder, required: this.required, rows: 10, onInput: this.handleInput, onBlur: this.handleBlur }, this.value)), hasError && h("span", { key: 'e96f1dbc6c00a1602f4ce3c97d514a229aeb7cb7', class: "mrd-longtext-field__error" }, this.error))));
|
|
3500
|
+
return (h(Host, { key: '1d23db1324fa0fc97a07fdae65f2d84e43419a72' }, h("div", { key: '0ad2b262088aa3745f088a44af26649593805840', class: "mrd-longtext-field" }, h(FieldLabel, { key: '5a78739d6ced4e2df77589b64c66401819c4b5c7', base: "mrd-longtext-field", label: this.label, required: this.required }), this.disabled ? (h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (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)), h(FieldError, { key: '5b870a75b518e2808518b83c9abebf8589a86108', base: "mrd-longtext-field", error: this.error }))));
|
|
3427
3501
|
}
|
|
3428
3502
|
};
|
|
3429
|
-
MrdLongtextField.style =
|
|
3503
|
+
MrdLongtextField.style = mrdLongtextFieldCss();
|
|
3430
3504
|
|
|
3431
|
-
const
|
|
3505
|
+
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)}`;
|
|
3432
3506
|
|
|
3433
3507
|
const MrdNumberField = class {
|
|
3434
3508
|
constructor(hostRef) {
|
|
@@ -3499,12 +3573,12 @@ const MrdNumberField = class {
|
|
|
3499
3573
|
const hasError = !!this.error;
|
|
3500
3574
|
const suffix = this.dataType === ClientLayoutItemFieldDataType.PERCENTAGE ? '%' :
|
|
3501
3575
|
this.dataType === ClientLayoutItemFieldDataType.DECIMAL ? '' : '';
|
|
3502
|
-
return (h(Host, { key: '
|
|
3576
|
+
return (h(Host, { key: 'fd7220e0a7f574ab0c61094a9ba7fd764e1adafd' }, h("div", { key: 'ef6118a339c9766f187cd2b1fa3fcc85ef8cb69f', class: "mrd-number-field" }, h(FieldLabel, { key: '015207ae65df07f7ee7bbc24ccab45524176dbf7', base: "mrd-number-field", label: this.label, required: this.required }), h("div", { key: '954b99cbcf4002b0336810e354f1a46d39cb8076', class: "mrd-number-field__input-wrapper" }, 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 })), h(FieldError, { key: '87e12bd737aed0a845470cef66d7a6d61d11de0b', base: "mrd-number-field", error: this.error }))));
|
|
3503
3577
|
}
|
|
3504
3578
|
};
|
|
3505
|
-
MrdNumberField.style =
|
|
3579
|
+
MrdNumberField.style = mrdNumberFieldCss();
|
|
3506
3580
|
|
|
3507
|
-
const
|
|
3581
|
+
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}`;
|
|
3508
3582
|
|
|
3509
3583
|
const MrdRelationField = class {
|
|
3510
3584
|
constructor(hostRef) {
|
|
@@ -3605,12 +3679,7 @@ const MrdRelationField = class {
|
|
|
3605
3679
|
this.showResults = false;
|
|
3606
3680
|
this.mrdChange.emit({ name: this.name, value: result.id });
|
|
3607
3681
|
}
|
|
3608
|
-
|
|
3609
|
-
this.error = t('required', this.locale);
|
|
3610
|
-
}
|
|
3611
|
-
else {
|
|
3612
|
-
this.error = '';
|
|
3613
|
-
}
|
|
3682
|
+
this.error = requiredError(this.selectedItems, this.required, this.locale);
|
|
3614
3683
|
};
|
|
3615
3684
|
this.handleRemoveSelected = (id) => {
|
|
3616
3685
|
this.selectedItems = this.selectedItems.filter(i => i.id !== id);
|
|
@@ -3619,12 +3688,7 @@ const MrdRelationField = class {
|
|
|
3619
3688
|
};
|
|
3620
3689
|
this.handleDropdownChange = (e) => {
|
|
3621
3690
|
const val = e.target.value;
|
|
3622
|
-
|
|
3623
|
-
this.error = t('required', this.locale);
|
|
3624
|
-
}
|
|
3625
|
-
else {
|
|
3626
|
-
this.error = '';
|
|
3627
|
-
}
|
|
3691
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
3628
3692
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
3629
3693
|
};
|
|
3630
3694
|
this.handleBlur = () => {
|
|
@@ -3735,19 +3799,19 @@ const MrdRelationField = class {
|
|
|
3735
3799
|
const hasError = !!this.error;
|
|
3736
3800
|
if (this.editBehavior === ClientLayoutItemRelationEditBehavior.DROPDOWN) {
|
|
3737
3801
|
const currentValue = this.getValueHref();
|
|
3738
|
-
return (h(Host, null, h("div", { class: "mrd-relation-field" },
|
|
3802
|
+
return (h(Host, null, h("div", { class: "mrd-relation-field" }, h(FieldLabel, { base: "mrd-relation-field", label: this.label, required: this.required }), h("select", { class: controlClass('mrd-relation-field', hasError, 'select'), name: this.name, required: this.required, disabled: this.disabled, onChange: this.handleDropdownChange }, h("option", { value: "" }, t('select_placeholder', this.locale)), this.allRecords.map(record => (h("option", { key: record.id, value: record.id, selected: record.id === currentValue }, record.label)))), h(FieldError, { base: "mrd-relation-field", error: this.error }))));
|
|
3739
3803
|
}
|
|
3740
3804
|
if (this.displayType === ClientLayoutItemRelationDisplayType.DROPDOWN) {
|
|
3741
3805
|
const currentValue = Array.isArray(this.value) ? ((_a = this.value[0]) !== null && _a !== void 0 ? _a : '') : ((_b = this.value) !== null && _b !== void 0 ? _b : '');
|
|
3742
|
-
return (h(Host, null, h("div", { class: "mrd-relation-field" },
|
|
3806
|
+
return (h(Host, null, h("div", { class: "mrd-relation-field" }, h(FieldLabel, { base: "mrd-relation-field", label: this.label, required: this.required }), h("select", { class: controlClass('mrd-relation-field', hasError, 'select'), name: this.name, required: this.required, disabled: this.disabled, onChange: this.handleDropdownChange }, h("option", { value: "" }, t('select_placeholder', this.locale)), this.dropdownValues.map(dv => (h("option", { key: dv.key, value: dv.key, selected: dv.key === currentValue }, dv.label)))), h(FieldError, { base: "mrd-relation-field", error: this.error }))));
|
|
3743
3807
|
}
|
|
3744
3808
|
// SEARCH mode
|
|
3745
|
-
const labelEl =
|
|
3809
|
+
const labelEl = h(FieldLabel, { base: "mrd-relation-field", label: this.label, required: this.required });
|
|
3746
3810
|
// Single selection: show selected value as a badge, hide the search input
|
|
3747
3811
|
if (!this.multiple && this.selectedItems.length > 0) {
|
|
3748
|
-
return (h(Host, null, h("div", { class: "mrd-relation-field" }, labelEl, h("div", { class: `mrd-relation-field__selected-value${hasError ? ' mrd-relation-field__selected-value--error' : ''}` }, h("span", { class: "mrd-relation-field__selected-name" }, this.selectedItems[0].label), h("button", { type: "button", class: "mrd-relation-field__selected-clear", onClick: this.clearSelection, "aria-label": t('remove', this.locale) }, "\u2715")),
|
|
3812
|
+
return (h(Host, null, h("div", { class: "mrd-relation-field" }, labelEl, h("div", { class: `mrd-relation-field__selected-value${hasError ? ' mrd-relation-field__selected-value--error' : ''}` }, h("span", { class: "mrd-relation-field__selected-name" }, this.selectedItems[0].label), h("button", { type: "button", class: "mrd-relation-field__selected-clear", onClick: this.clearSelection, "aria-label": t('remove', this.locale) }, "\u2715")), h(FieldError, { base: "mrd-relation-field", error: this.error }))));
|
|
3749
3813
|
}
|
|
3750
|
-
return (h(Host, null, h("div", { class: "mrd-relation-field" }, labelEl, this.multiple && this.selectedItems.length > 0 && (h("div", { class: "mrd-relation-field__tags" }, this.selectedItems.map(item => (h("span", { key: item.id, class: "mrd-relation-field__tag" }, item.label, h("button", { type: "button", class: "mrd-relation-field__tag-remove", onClick: () => this.handleRemoveSelected(item.id), "aria-label": t('remove', this.locale) }, "\u2715")))))), h("div", { class: "mrd-relation-field__search-wrapper" }, 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 && (h("span", { class: "mrd-relation-field__spinner", "aria-label": t('loading', this.locale) }))), this.showResults && (h("div", { class: "mrd-relation-field__results" }, this.searchResults.length === 0 && !this.isLoading ? (h("div", { class: "mrd-relation-field__no-results" }, t('no_results', this.locale))) : (this.searchResults.map((result, i) => (h("div", { key: result.id, class: `mrd-relation-field__result-item${i === this.highlightedIndex ? ' mrd-relation-field__result-item--highlighted' : ''}`, onMouseDown: () => this.handleResultSelect(result) }, h("span", { class: "mrd-relation-field__result-label" }, result.label), result.description && (h("span", { class: "mrd-relation-field__result-desc" }, result.description)))))))),
|
|
3814
|
+
return (h(Host, null, h("div", { class: "mrd-relation-field" }, labelEl, this.multiple && this.selectedItems.length > 0 && (h("div", { class: "mrd-relation-field__tags" }, this.selectedItems.map(item => (h("span", { key: item.id, class: "mrd-relation-field__tag" }, item.label, h("button", { type: "button", class: "mrd-relation-field__tag-remove", onClick: () => this.handleRemoveSelected(item.id), "aria-label": t('remove', this.locale) }, "\u2715")))))), h("div", { class: "mrd-relation-field__search-wrapper" }, 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 && (h("span", { class: "mrd-relation-field__spinner", "aria-label": t('loading', this.locale) }))), this.showResults && (h("div", { class: "mrd-relation-field__results" }, this.searchResults.length === 0 && !this.isLoading ? (h("div", { class: "mrd-relation-field__no-results" }, t('no_results', this.locale))) : (this.searchResults.map((result, i) => (h("div", { key: result.id, class: `mrd-relation-field__result-item${i === this.highlightedIndex ? ' mrd-relation-field__result-item--highlighted' : ''}`, onMouseDown: () => this.handleResultSelect(result) }, h("span", { class: "mrd-relation-field__result-label" }, result.label), result.description && (h("span", { class: "mrd-relation-field__result-desc" }, result.description)))))))), h(FieldError, { base: "mrd-relation-field", error: this.error }))));
|
|
3751
3815
|
}
|
|
3752
3816
|
get el() { return getElement(this); }
|
|
3753
3817
|
static get watchers() { return {
|
|
@@ -3759,9 +3823,9 @@ const MrdRelationField = class {
|
|
|
3759
3823
|
}]
|
|
3760
3824
|
}; }
|
|
3761
3825
|
};
|
|
3762
|
-
MrdRelationField.style =
|
|
3826
|
+
MrdRelationField.style = mrdRelationFieldCss();
|
|
3763
3827
|
|
|
3764
|
-
const
|
|
3828
|
+
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}`;
|
|
3765
3829
|
|
|
3766
3830
|
const MrdSecretField = class {
|
|
3767
3831
|
constructor(hostRef) {
|
|
@@ -3782,42 +3846,460 @@ const MrdSecretField = class {
|
|
|
3782
3846
|
};
|
|
3783
3847
|
this.handleBlur = (e) => {
|
|
3784
3848
|
const val = e.target.value;
|
|
3785
|
-
|
|
3786
|
-
this.error = t('required', this.locale);
|
|
3787
|
-
}
|
|
3788
|
-
else {
|
|
3789
|
-
this.error = '';
|
|
3790
|
-
}
|
|
3849
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
3791
3850
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
3792
3851
|
};
|
|
3793
3852
|
}
|
|
3794
3853
|
render() {
|
|
3795
|
-
|
|
3796
|
-
return (h(Host, { key: 'c850ec5bc5967ca0aefca7d7cb65ecae121a9dc1' }, h("div", { key: '3249ffbc441422af054a20806dd8dfce954a8ffc', class: "mrd-secret-field" }, this.label && (h("label", { key: '0b4a86da9cafad32f153af1bc5487a4e9b941e2f', class: `mrd-secret-field__label${this.required ? ' mrd-secret-field__label--required' : ''}` }, this.label)), this.disabled
|
|
3854
|
+
return (h(Host, { key: 'acb865b235652feba713aedda7a7fccbdc01ad20' }, h("div", { key: 'e7471ade9c683cac9469ec89778c967badb046f9', class: "mrd-secret-field" }, h(FieldLabel, { key: '2f9b864779ead352fda53af8597ddcd31377249d', base: "mrd-secret-field", label: this.label, required: this.required }), this.disabled
|
|
3797
3855
|
? (h("span", { class: "mrd-secret-field__masked", "aria-label": this.label }, this.value ? '••••••••' : ''))
|
|
3798
|
-
: (h("input", { class:
|
|
3856
|
+
: (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 })), h(FieldError, { key: '438418e2cf0f53a6c247d5f332aae8e8978b94ea', base: "mrd-secret-field", error: this.error }))));
|
|
3799
3857
|
}
|
|
3800
3858
|
};
|
|
3801
|
-
MrdSecretField.style =
|
|
3859
|
+
MrdSecretField.style = mrdSecretFieldCss();
|
|
3802
3860
|
|
|
3803
|
-
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}`;
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
* aangevraagd. Pagina's die de gebruiker snel voorbij scrollt worden zo geskipt. */
|
|
3808
|
-
const REQUEST_DEBOUNCE_MS = 150;
|
|
3809
|
-
/** Breedte van de filterpopup in px — voor overflow-correctie. */
|
|
3810
|
-
const POPUP_WIDTH = 280;
|
|
3861
|
+
/**
|
|
3862
|
+
* Pure sort/filter/aggregation query logic for mrd-table.
|
|
3863
|
+
* No component state — everything is passed in.
|
|
3864
|
+
*/
|
|
3811
3865
|
const TEXT_TYPES = new Set(['TEXT', 'TEXTBLOCK', 'EMAIL', 'HYPERLINK']);
|
|
3812
3866
|
const NUMERIC_TYPES = new Set(['INTEGER', 'DECIMAL', 'PERCENTAGE', 'CURRENCY']);
|
|
3813
3867
|
const DATE_TYPES = new Set(['DATE', 'DATETIME', 'TIME']);
|
|
3814
3868
|
const NO_FILTER_TYPES = new Set(['FILE', 'IMAGE']);
|
|
3815
3869
|
/** Column types that cannot be sorted or filtered (not stored in PostgreSQL). */
|
|
3816
3870
|
const NON_INTERACTIVE_TYPES = new Set(['LONGTEXT', 'JSON', 'FILE', 'IMAGE']);
|
|
3871
|
+
function parseDefaultSort(defaultSort) {
|
|
3872
|
+
var _a;
|
|
3873
|
+
if (!defaultSort)
|
|
3874
|
+
return { field: '', dir: 'asc' };
|
|
3875
|
+
const parts = defaultSort.split(',');
|
|
3876
|
+
return { field: parts[0].trim(), dir: ((_a = parts[1]) === null || _a === void 0 ? void 0 : _a.trim()) === 'desc' ? 'desc' : 'asc' };
|
|
3877
|
+
}
|
|
3878
|
+
/** Raw sort query-param value, e.g. "name" or "name,desc". */
|
|
3879
|
+
function buildSortParam(field, dir) {
|
|
3880
|
+
if (!field)
|
|
3881
|
+
return '';
|
|
3882
|
+
return dir === 'desc' ? `${field},desc` : field;
|
|
3883
|
+
}
|
|
3884
|
+
/** Query params for a page request: page + sort + filterClass + view filters + active column filters. */
|
|
3885
|
+
function buildTableQueryParams(opts) {
|
|
3886
|
+
var _a, _b;
|
|
3887
|
+
const p = new URLSearchParams();
|
|
3888
|
+
if (opts.page > 0)
|
|
3889
|
+
p.set('page', String(opts.page));
|
|
3890
|
+
if (opts.sort)
|
|
3891
|
+
p.set('sort', opts.sort);
|
|
3892
|
+
if (opts.filterClass)
|
|
3893
|
+
p.set('type', opts.filterClass);
|
|
3894
|
+
applyViewFilters(p, opts.viewFilters);
|
|
3895
|
+
for (const f of opts.activeFilters) {
|
|
3896
|
+
if (f.operator === 'isEmpty') {
|
|
3897
|
+
p.set(f.field, '');
|
|
3898
|
+
continue;
|
|
3899
|
+
}
|
|
3900
|
+
if (f.operator === 'isNotEmpty') {
|
|
3901
|
+
p.set(f.field + '_notempty', 'true');
|
|
3902
|
+
continue;
|
|
3903
|
+
}
|
|
3904
|
+
if (f.operator === 'startsWith') {
|
|
3905
|
+
p.set(f.field + '_startswith', String((_a = f.value) !== null && _a !== void 0 ? _a : ''));
|
|
3906
|
+
continue;
|
|
3907
|
+
}
|
|
3908
|
+
if ((_b = f.values) === null || _b === void 0 ? void 0 : _b.length) {
|
|
3909
|
+
p.set(f.field, f.values.join(','));
|
|
3910
|
+
continue;
|
|
3911
|
+
}
|
|
3912
|
+
if (f.value != null)
|
|
3913
|
+
p.set(f.field, String(f.value));
|
|
3914
|
+
if (f.from != null)
|
|
3915
|
+
p.set(f.field + '_from', String(f.from));
|
|
3916
|
+
if (f.to != null)
|
|
3917
|
+
p.set(f.field + '_to', String(f.to));
|
|
3918
|
+
}
|
|
3919
|
+
return p.toString();
|
|
3920
|
+
}
|
|
3921
|
+
/** Groups aggregate columns by function; null when the view has no aggregates. */
|
|
3922
|
+
function buildAggregationParams(columns) {
|
|
3923
|
+
var _a;
|
|
3924
|
+
const groups = { sum: [], avg: [], count: [] };
|
|
3925
|
+
for (const col of columns) {
|
|
3926
|
+
if (col.type !== 'FIELD' || !col.aggregate)
|
|
3927
|
+
continue;
|
|
3928
|
+
const fn = col.aggregate.toLowerCase();
|
|
3929
|
+
if (fn in groups)
|
|
3930
|
+
groups[fn].push((_a = col.name) !== null && _a !== void 0 ? _a : '');
|
|
3931
|
+
}
|
|
3932
|
+
const params = {};
|
|
3933
|
+
if (groups.sum.length)
|
|
3934
|
+
params.sum = groups.sum;
|
|
3935
|
+
if (groups.avg.length)
|
|
3936
|
+
params.avg = groups.avg;
|
|
3937
|
+
if (groups.count.length)
|
|
3938
|
+
params.count = groups.count;
|
|
3939
|
+
return Object.keys(params).length > 0 ? params : null;
|
|
3940
|
+
}
|
|
3941
|
+
/** Aggregation query string: the page-0 query params without page/sort, plus sum/avg/count. */
|
|
3942
|
+
function buildAggregationQs(basePageQs, columns) {
|
|
3943
|
+
var _a, _b, _c;
|
|
3944
|
+
const p = new URLSearchParams(basePageQs);
|
|
3945
|
+
p.delete('page');
|
|
3946
|
+
p.delete('sort');
|
|
3947
|
+
const groups = buildAggregationParams(columns);
|
|
3948
|
+
if ((_a = groups === null || groups === void 0 ? void 0 : groups.sum) === null || _a === void 0 ? void 0 : _a.length)
|
|
3949
|
+
p.set('sum', groups.sum.join(','));
|
|
3950
|
+
if ((_b = groups === null || groups === void 0 ? void 0 : groups.avg) === null || _b === void 0 ? void 0 : _b.length)
|
|
3951
|
+
p.set('avg', groups.avg.join(','));
|
|
3952
|
+
if ((_c = groups === null || groups === void 0 ? void 0 : groups.count) === null || _c === void 0 ? void 0 : _c.length)
|
|
3953
|
+
p.set('count', groups.count.join(','));
|
|
3954
|
+
return p.toString();
|
|
3955
|
+
}
|
|
3956
|
+
/** True when the pending filter actually constrains anything. */
|
|
3957
|
+
function filterHasValue(f) {
|
|
3958
|
+
if (f.operator === 'isEmpty' || f.operator === 'isNotEmpty')
|
|
3959
|
+
return true;
|
|
3960
|
+
if (f.values !== undefined && f.values.length > 0)
|
|
3961
|
+
return true;
|
|
3962
|
+
if (f.value != null && f.value !== '')
|
|
3963
|
+
return true;
|
|
3964
|
+
if (typeof f.value === 'boolean')
|
|
3965
|
+
return true;
|
|
3966
|
+
if (f.from != null && f.from !== '')
|
|
3967
|
+
return true;
|
|
3968
|
+
if (f.to != null && f.to !== '')
|
|
3969
|
+
return true;
|
|
3970
|
+
return false;
|
|
3971
|
+
}
|
|
3972
|
+
// ── DATETIME filters: the user edits local "YYYY-MM-DD" dates, the API stores UTC ISO ──
|
|
3973
|
+
/** UTC ISO string at the start (midnight) of the given local day. */
|
|
3974
|
+
function dateLocalToUTCStart(dateStr) {
|
|
3975
|
+
if (!dateStr)
|
|
3976
|
+
return dateStr;
|
|
3977
|
+
const [year, month, day] = dateStr.split('-').map(Number);
|
|
3978
|
+
return new Date(year, month - 1, day).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
3979
|
+
}
|
|
3980
|
+
/** Start of the day AFTER the given local date (exclusive range end). */
|
|
3981
|
+
function dateLocalToUTCEndExclusive(dateStr) {
|
|
3982
|
+
if (!dateStr)
|
|
3983
|
+
return dateStr;
|
|
3984
|
+
const [year, month, day] = dateStr.split('-').map(Number);
|
|
3985
|
+
return new Date(year, month - 1, day + 1).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
3986
|
+
}
|
|
3987
|
+
/** Stored UTC ISO string back to the local "YYYY-MM-DD" date. */
|
|
3988
|
+
function utcISOToLocalDate(utcStr) {
|
|
3989
|
+
if (!utcStr)
|
|
3990
|
+
return utcStr;
|
|
3991
|
+
const d = new Date(utcStr);
|
|
3992
|
+
if (isNaN(d.getTime()))
|
|
3993
|
+
return utcStr;
|
|
3994
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
3995
|
+
}
|
|
3996
|
+
/** The stored "to" is the exclusive end (next midnight); subtract a day to recover the entered date. */
|
|
3997
|
+
function utcISOToLocalDateExclusiveEnd(utcStr) {
|
|
3998
|
+
if (!utcStr)
|
|
3999
|
+
return utcStr;
|
|
4000
|
+
const d = new Date(utcStr);
|
|
4001
|
+
if (isNaN(d.getTime()))
|
|
4002
|
+
return utcStr;
|
|
4003
|
+
d.setDate(d.getDate() - 1);
|
|
4004
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
4005
|
+
}
|
|
4006
|
+
/** Applies the local→UTC conversion when a DATETIME filter is submitted.
|
|
4007
|
+
* Exact date → range covering the full local day. */
|
|
4008
|
+
function normalizeDatetimeFilter(f) {
|
|
4009
|
+
const normalized = Object.assign({}, f);
|
|
4010
|
+
if (f.dataType === 'DATETIME' && f.operator !== 'isEmpty' && f.operator !== 'isNotEmpty') {
|
|
4011
|
+
if (typeof normalized.value === 'string' && normalized.value) {
|
|
4012
|
+
normalized.from = dateLocalToUTCStart(normalized.value);
|
|
4013
|
+
normalized.to = dateLocalToUTCEndExclusive(normalized.value);
|
|
4014
|
+
normalized.value = undefined;
|
|
4015
|
+
}
|
|
4016
|
+
else {
|
|
4017
|
+
if (typeof normalized.from === 'string' && normalized.from)
|
|
4018
|
+
normalized.from = dateLocalToUTCStart(normalized.from);
|
|
4019
|
+
if (typeof normalized.to === 'string' && normalized.to)
|
|
4020
|
+
normalized.to = dateLocalToUTCEndExclusive(normalized.to);
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
return normalized;
|
|
4024
|
+
}
|
|
4025
|
+
/** Converts a stored DATETIME filter back to local dates for the popup.
|
|
4026
|
+
* A range covering a single local day is restored to exact-date mode. */
|
|
4027
|
+
function datetimeFilterToDisplay(existing) {
|
|
4028
|
+
const display = Object.assign({}, existing);
|
|
4029
|
+
if (typeof display.from === 'string' && display.from)
|
|
4030
|
+
display.from = utcISOToLocalDate(display.from);
|
|
4031
|
+
if (typeof display.to === 'string' && display.to)
|
|
4032
|
+
display.to = utcISOToLocalDateExclusiveEnd(display.to);
|
|
4033
|
+
if (display.from && display.to && display.from === display.to) {
|
|
4034
|
+
return Object.assign(Object.assign({}, display), { value: display.from, from: undefined, to: undefined });
|
|
4035
|
+
}
|
|
4036
|
+
return display;
|
|
4037
|
+
}
|
|
4038
|
+
|
|
4039
|
+
/**
|
|
4040
|
+
* Stateless render parts of mrd-table. All state and handlers stay in the
|
|
4041
|
+
* component; these components receive plain values and callbacks.
|
|
4042
|
+
*/
|
|
4043
|
+
const FilterIcon = () => (h("span", { class: "mrd-table__filter-icon", "aria-hidden": "true" }, h("svg", { viewBox: "0 0 24 24", width: "14", height: "14", fill: "currentColor" }, h("path", { d: "M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" }))));
|
|
4044
|
+
const TEXTBLOCK_MAX = 200;
|
|
4045
|
+
const TableCell = ({ col, row, locale, onDownload, onOpenTextblock, onOpenJson }) => {
|
|
4046
|
+
var _a, _b, _c;
|
|
4047
|
+
const dataType = (_a = col.dataType) !== null && _a !== void 0 ? _a : '';
|
|
4048
|
+
const isNumeric = col.type === 'FIELD' && NUMERIC_TYPES.has(dataType);
|
|
4049
|
+
const isFile = col.type === 'FIELD' && (dataType === 'FILE' || dataType === 'IMAGE');
|
|
4050
|
+
if (isFile) {
|
|
4051
|
+
const name = (_b = col.name) !== null && _b !== void 0 ? _b : '';
|
|
4052
|
+
const fileVal = row === null || row === void 0 ? void 0 : row[name];
|
|
4053
|
+
const href = fileVal === null || fileVal === void 0 ? void 0 : fileVal.href;
|
|
4054
|
+
const fileName = fileVal === null || fileVal === void 0 ? void 0 : fileVal.fileName;
|
|
4055
|
+
return (h("td", { class: "mrd-table__cell" }, href && fileName ? (h("button", { class: "mrd-table__file-btn", title: fileName, onClick: (e) => {
|
|
4056
|
+
e.stopPropagation();
|
|
4057
|
+
onDownload({ href, fileName });
|
|
4058
|
+
} }, h("svg", { class: "mrd-table__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 7V3.5L18.5 9H13zm-3 8l-3-3 1.41-1.41L10 14.17l4.59-4.58L16 11l-6 6z" })), t('download', locale))) : ''));
|
|
4059
|
+
}
|
|
4060
|
+
if (dataType === 'JSON') {
|
|
4061
|
+
const name = (_c = col.name) !== null && _c !== void 0 ? _c : '';
|
|
4062
|
+
const rawValue = name ? row === null || row === void 0 ? void 0 : row[name] : undefined;
|
|
4063
|
+
if (rawValue == null || rawValue === '')
|
|
4064
|
+
return h("td", { class: "mrd-table__cell" });
|
|
4065
|
+
const compactHtml = CellRenderer.formatJson(rawValue, true);
|
|
4066
|
+
const prettyHtml = CellRenderer.formatJson(rawValue, false);
|
|
4067
|
+
return (h("td", { class: "mrd-table__cell" }, h("span", { class: "mrd-table__json-preview", innerHTML: compactHtml }), h("button", { class: "mrd-table__textblock-btn", onClick: (e) => { e.stopPropagation(); onOpenJson(prettyHtml); }, "aria-label": t('textblock_show_more', locale) }, "\u22EF")));
|
|
4068
|
+
}
|
|
4069
|
+
if (dataType === 'TEXTBLOCK') {
|
|
4070
|
+
const full = CellRenderer.render(col, row, locale);
|
|
4071
|
+
if (full.length <= TEXTBLOCK_MAX) {
|
|
4072
|
+
return h("td", { class: "mrd-table__cell" }, full);
|
|
4073
|
+
}
|
|
4074
|
+
const preview = full.slice(0, TEXTBLOCK_MAX) + '…';
|
|
4075
|
+
return (h("td", { class: "mrd-table__cell" }, preview, h("button", { class: "mrd-table__textblock-btn", onClick: (e) => { e.stopPropagation(); onOpenTextblock(full); }, "aria-label": t('textblock_show_more', locale) }, "\u22EF")));
|
|
4076
|
+
}
|
|
4077
|
+
const value = CellRenderer.render(col, row, locale);
|
|
4078
|
+
return (h("td", { class: `mrd-table__cell${isNumeric ? ' mrd-table__cell--numeric' : ''}` }, value));
|
|
4079
|
+
};
|
|
4080
|
+
/** Formats the aggregation total for one column, '' when not applicable. */
|
|
4081
|
+
function formatAggregationValue(col, aggregations, locale) {
|
|
4082
|
+
var _a;
|
|
4083
|
+
if (col.type !== 'FIELD' || !col.aggregate || !aggregations)
|
|
4084
|
+
return '';
|
|
4085
|
+
const fn = col.aggregate.toLowerCase();
|
|
4086
|
+
const aggData = aggregations[fn];
|
|
4087
|
+
const val = typeof aggData === 'object' && aggData !== null
|
|
4088
|
+
? aggData[(_a = col.name) !== null && _a !== void 0 ? _a : '']
|
|
4089
|
+
: undefined;
|
|
4090
|
+
if (val == null)
|
|
4091
|
+
return '';
|
|
4092
|
+
const dt = col.dataType;
|
|
4093
|
+
if (dt === 'INTEGER')
|
|
4094
|
+
return formatNumber(val, locale, { maximumFractionDigits: 0 });
|
|
4095
|
+
if (dt === 'PERCENTAGE')
|
|
4096
|
+
return formatPercentage(val, locale);
|
|
4097
|
+
if (dt === 'CURRENCY' && col.currencyCode)
|
|
4098
|
+
return formatCurrency(val, col.currencyCode, locale);
|
|
4099
|
+
return formatNumber(val, locale);
|
|
4100
|
+
}
|
|
4101
|
+
const TotalsRow = ({ columns, aggregations, locale }) => {
|
|
4102
|
+
if (!aggregations)
|
|
4103
|
+
return null;
|
|
4104
|
+
if (!columns.some(c => c.type === 'FIELD' && c.aggregate))
|
|
4105
|
+
return null;
|
|
4106
|
+
return (h("tfoot", null, h("tr", { class: "mrd-table__totals-row" }, columns.map(col => {
|
|
4107
|
+
var _a;
|
|
4108
|
+
const val = formatAggregationValue(col, aggregations, locale);
|
|
4109
|
+
const isNumeric = col.type === 'FIELD' && NUMERIC_TYPES.has((_a = col.dataType) !== null && _a !== void 0 ? _a : '');
|
|
4110
|
+
return (h("td", { class: `mrd-table__totals-cell${isNumeric ? ' mrd-table__totals-cell--numeric' : ''}` }, val));
|
|
4111
|
+
}))));
|
|
4112
|
+
};
|
|
4113
|
+
const TextblockModal = ({ text, locale, onClose }) => {
|
|
4114
|
+
if (text === null)
|
|
4115
|
+
return null;
|
|
4116
|
+
return (h("div", { class: "mrd-table__modal-backdrop", onClick: onClose, role: "dialog", "aria-modal": "true" }, h("div", { class: "mrd-table__modal", onClick: (e) => e.stopPropagation() }, h("button", { class: "mrd-table__modal-close", onClick: onClose, "aria-label": t('close', locale) }, "\u2715"), h("p", { class: "mrd-table__modal-text" }, text))));
|
|
4117
|
+
};
|
|
4118
|
+
const JsonModal = ({ html, locale, onClose }) => {
|
|
4119
|
+
if (html === null)
|
|
4120
|
+
return null;
|
|
4121
|
+
return (h("div", { class: "mrd-table__modal-backdrop", onClick: onClose, role: "dialog", "aria-modal": "true" }, h("div", { class: "mrd-table__modal", onClick: (e) => e.stopPropagation() }, h("button", { class: "mrd-table__modal-close", onClick: onClose, "aria-label": t('close', locale) }, "\u2715"), h("pre", { class: "mrd-table__modal-json", innerHTML: html }))));
|
|
4122
|
+
};
|
|
4123
|
+
const Toolbar = ({ locale, filterMode, filterCount, actions, views, activeViewIdx, viewPopoverOpen, createPickerOpen, createTypes, cb }) => {
|
|
4124
|
+
var _a;
|
|
4125
|
+
const hasActions = actions.length > 0;
|
|
4126
|
+
const hasViewSwitcher = views.length > 1;
|
|
4127
|
+
return (h("div", { class: "mrd-table__toolbar" }, h("div", { class: "mrd-table__toolbar-left" }, h("button", { class: `mrd-table__action mrd-table__action--secondary mrd-table__filter-toggle${filterMode ? ' mrd-table__filter-toggle--active' : ''}`, onClick: cb.onFilterToggle }, h("svg", { class: "mrd-table__action-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" })), filterCount > 0 && h("span", { class: "mrd-table__filter-badge" }, filterCount), h("span", { class: "mrd-table__action-tooltip" }, filterMode ? t('table_filter_hide', locale) : t('table_filter', locale), filterCount > 0 ? ` (${filterCount} ${t('table_filter_active', locale)})` : '')), filterCount > 0 && (h("button", { class: "mrd-table__action mrd-table__action--secondary", onClick: cb.onClearAllFilters }, h("svg", { class: "mrd-table__action-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" })), h("span", { class: "mrd-table__action-tooltip" }, t('table_filter_clear_all', locale))))), hasViewSwitcher && (h("div", { class: "mrd-table__toolbar-center" }, h("div", { class: "mrd-table__view-switcher" }, h("button", { class: "mrd-table__view-arrow", "aria-label": "Previous view", onClick: () => cb.onViewSwitch((activeViewIdx - 1 + views.length) % views.length) }, "\u25C0"), h("div", { class: "mrd-table__view-title-wrap" }, h("button", { class: "mrd-table__view-title", onClick: (e) => cb.onToggleViewPopover(e) }, (_a = views[activeViewIdx]) === null || _a === void 0 ? void 0 : _a.label), viewPopoverOpen && (h("div", { class: "mrd-table__view-popover", onClick: (e) => e.stopPropagation() }, views.map((v, i) => (h("button", { key: String(i), class: `mrd-table__view-popover-item${i === activeViewIdx ? ' mrd-table__view-popover-item--active' : ''}`, onClick: () => {
|
|
4128
|
+
if (i !== activeViewIdx)
|
|
4129
|
+
cb.onViewSwitch(i);
|
|
4130
|
+
cb.onCloseViewPopover();
|
|
4131
|
+
} }, v.label)))))), h("button", { class: "mrd-table__view-arrow", "aria-label": "Next view", onClick: () => cb.onViewSwitch((activeViewIdx + 1) % views.length) }, "\u25B6")))), hasActions && (h("div", { class: "mrd-table__toolbar-right" }, actions.map(a => {
|
|
4132
|
+
var _a, _b;
|
|
4133
|
+
const pickerTypes = a.action === 'create' ? createTypes : null;
|
|
4134
|
+
if (pickerTypes === null || pickerTypes === void 0 ? void 0 : pickerTypes.length) {
|
|
4135
|
+
return (h("div", { class: "mrd-table__create-picker-wrap", key: `action-${a.action}` }, h("button", { class: `mrd-table__action mrd-table__action--${(_a = a.variant) !== null && _a !== void 0 ? _a : 'secondary'}`, onClick: cb.onToggleCreatePicker }, a.icon
|
|
4136
|
+
? h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, h("use", { href: a.icon }))
|
|
4137
|
+
: a.label, h("span", { class: "mrd-table__action-tooltip" }, a.label)), createPickerOpen && (h("div", { class: "mrd-table__create-picker" }, pickerTypes.map(ct => (h("button", { key: ct.type, class: "mrd-table__create-picker-item", onClick: () => cb.onCreate(ct.type) }, ct.label)))))));
|
|
4138
|
+
}
|
|
4139
|
+
return (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
|
|
4140
|
+
? h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, h("use", { href: a.icon }))
|
|
4141
|
+
: a.label, h("span", { class: "mrd-table__action-tooltip" }, a.label)));
|
|
4142
|
+
})))));
|
|
4143
|
+
};
|
|
4144
|
+
|
|
4145
|
+
const FilterEditor = ({ col, dataType, openFilterCol, pendingFilter, locale, cb }) => {
|
|
4146
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4147
|
+
const pf = pendingFilter;
|
|
4148
|
+
if (NO_FILTER_TYPES.has(dataType)) {
|
|
4149
|
+
return h("p", { class: "mrd-table__filter-no-support" }, t('filter_no_support', locale));
|
|
4150
|
+
}
|
|
4151
|
+
if (dataType === 'BOOLEAN') {
|
|
4152
|
+
const boolOp = pf.operator;
|
|
4153
|
+
const noValueOp = boolOp === 'isEmpty' || boolOp === 'isNotEmpty';
|
|
4154
|
+
return (h("div", { class: "mrd-table__filter-radio-group" }, [
|
|
4155
|
+
{ labelKey: 'filter_all', value: null },
|
|
4156
|
+
{ labelKey: 'yes', value: true },
|
|
4157
|
+
{ labelKey: 'no', value: false },
|
|
4158
|
+
].map(opt => (h("label", { class: "mrd-table__filter-radio-label" }, 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)))), h("label", { class: "mrd-table__filter-radio-label" }, 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)), h("label", { class: "mrd-table__filter-radio-label" }, 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))));
|
|
4159
|
+
}
|
|
4160
|
+
if (dataType === 'LIST') {
|
|
4161
|
+
const items = (_a = col.listItems) !== null && _a !== void 0 ? _a : [];
|
|
4162
|
+
const selected = (_b = pf.values) !== null && _b !== void 0 ? _b : [];
|
|
4163
|
+
return (h("div", { class: "mrd-table__filter-list" }, h("div", { class: "mrd-table__filter-list-controls" }, h("button", { class: "mrd-table__filter-list-btn", onClick: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { values: items.map(i => i.key) })) }, t('filter_select_all', locale)), 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 => (h("label", { class: "mrd-table__filter-checkbox-label" }, h("input", { type: "checkbox", checked: selected.includes(item.key), onChange: (e) => cb.onToggleValue(item.key, e.target.checked) }), item.label)))));
|
|
4164
|
+
}
|
|
4165
|
+
if (TEXT_TYPES.has(dataType) || dataType === 'RELATION') {
|
|
4166
|
+
const op = (_c = pf.operator) !== null && _c !== void 0 ? _c : 'startsWith';
|
|
4167
|
+
const noInput = op === 'isEmpty' || op === 'isNotEmpty';
|
|
4168
|
+
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => cb.onSetPending('operator', e.target.value) }, [
|
|
4169
|
+
{ val: 'startsWith', labelKey: 'filter_starts_with' },
|
|
4170
|
+
{ val: 'equals', labelKey: 'filter_equals' },
|
|
4171
|
+
{ val: 'isEmpty', labelKey: 'filter_is_empty' },
|
|
4172
|
+
{ val: 'isNotEmpty', labelKey: 'filter_is_not_empty' },
|
|
4173
|
+
].map(o => h("option", { value: o.val, selected: op === o.val }, t(o.labelKey, locale)))), !noInput && (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) }))));
|
|
4174
|
+
}
|
|
4175
|
+
if (NUMERIC_TYPES.has(dataType)) {
|
|
4176
|
+
const numOp = pf.operator;
|
|
4177
|
+
const noInput = numOp === 'isEmpty' || numOp === 'isNotEmpty';
|
|
4178
|
+
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4179
|
+
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4180
|
+
const val = e.target.value;
|
|
4181
|
+
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4182
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined }));
|
|
4183
|
+
}
|
|
4184
|
+
else {
|
|
4185
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: undefined }));
|
|
4186
|
+
}
|
|
4187
|
+
} }, h("option", { value: "", selected: !noInput }, t('filter_has_value', locale)), h("option", { value: "isEmpty", selected: numOp === 'isEmpty' }, t('filter_is_empty', locale)), h("option", { value: "isNotEmpty", selected: numOp === 'isNotEmpty' }, t('filter_is_not_empty', locale))), !noInput && (h("div", { class: "mrd-table__filter-editor" }, h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `nm-${openFilterCol}`, checked: !rangeMode, onChange: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { from: undefined, to: undefined })) }), t('filter_exact', locale)), h("label", { class: "mrd-table__filter-radio-label" }, 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 ? (h("input", { type: "number", class: "mrd-table__filter-input", value: pf.value != null ? String(pf.value) : '', onInput: (e) => cb.onSetPending('value', e.target.value) })) : (h("div", { class: "mrd-table__filter-range" }, 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) }), h("span", { class: "mrd-table__filter-range-sep" }, "\u2013"), 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) })))))));
|
|
4188
|
+
}
|
|
4189
|
+
if (dataType === 'DATETIME') {
|
|
4190
|
+
const dtOp = pf.operator;
|
|
4191
|
+
const noInput = dtOp === 'isEmpty' || dtOp === 'isNotEmpty';
|
|
4192
|
+
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4193
|
+
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4194
|
+
const val = e.target.value;
|
|
4195
|
+
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4196
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined }));
|
|
4197
|
+
}
|
|
4198
|
+
else {
|
|
4199
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: undefined }));
|
|
4200
|
+
}
|
|
4201
|
+
} }, h("option", { value: "", selected: !noInput }, t('filter_has_value', locale)), h("option", { value: "isEmpty", selected: dtOp === 'isEmpty' }, t('filter_is_empty', locale)), h("option", { value: "isNotEmpty", selected: dtOp === 'isNotEmpty' }, t('filter_is_not_empty', locale))), !noInput && (h("div", { class: "mrd-table__filter-editor" }, h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `dt-${openFilterCol}`, checked: !rangeMode, onChange: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { from: undefined, to: undefined })) }), t('filter_exact', locale)), h("label", { class: "mrd-table__filter-radio-label" }, 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 ? (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) })) : (h("div", { class: "mrd-table__filter-range mrd-table__filter-range--stacked" }, h("label", { class: "mrd-table__filter-range-label" }, t('filter_from', locale)), h("input", { type: "date", class: "mrd-table__filter-input", value: pf.from != null ? String(pf.from) : '', onInput: (e) => cb.onSetPending('from', e.target.value) }), h("label", { class: "mrd-table__filter-range-label" }, t('filter_to', locale)), h("input", { type: "date", class: "mrd-table__filter-input", value: pf.to != null ? String(pf.to) : '', onInput: (e) => cb.onSetPending('to', e.target.value) })))))));
|
|
4202
|
+
}
|
|
4203
|
+
if (DATE_TYPES.has(dataType)) {
|
|
4204
|
+
const inputType = dataType === 'DATE' ? 'date' : 'time';
|
|
4205
|
+
const dtdOp = pf.operator;
|
|
4206
|
+
const noInput = dtdOp === 'isEmpty' || dtdOp === 'isNotEmpty';
|
|
4207
|
+
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4208
|
+
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4209
|
+
const val = e.target.value;
|
|
4210
|
+
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4211
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined }));
|
|
4212
|
+
}
|
|
4213
|
+
else {
|
|
4214
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: undefined }));
|
|
4215
|
+
}
|
|
4216
|
+
} }, h("option", { value: "", selected: !noInput }, t('filter_has_value', locale)), h("option", { value: "isEmpty", selected: dtdOp === 'isEmpty' }, t('filter_is_empty', locale)), h("option", { value: "isNotEmpty", selected: dtdOp === 'isNotEmpty' }, t('filter_is_not_empty', locale))), !noInput && (h("div", { class: "mrd-table__filter-editor" }, h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `dt-${openFilterCol}`, checked: !rangeMode, onChange: () => cb.onReplacePending(Object.assign(Object.assign({}, pf), { from: undefined, to: undefined })) }), t('filter_exact', locale)), h("label", { class: "mrd-table__filter-radio-label" }, 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 ? (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) })) : (h("div", { class: "mrd-table__filter-range" }, 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) }), 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) })))))));
|
|
4217
|
+
}
|
|
4218
|
+
return null;
|
|
4219
|
+
};
|
|
4220
|
+
const FilterPopup = (props) => {
|
|
4221
|
+
var _a;
|
|
4222
|
+
const { col, openFilterCol, popupPos, sortField, sortDir, locale, cb } = props;
|
|
4223
|
+
const label = (_a = col.label) !== null && _a !== void 0 ? _a : openFilterCol;
|
|
4224
|
+
const sortActive = sortField === openFilterCol;
|
|
4225
|
+
return (h("div", { class: "mrd-table__filter-popup", style: { top: `${popupPos.top}px`, left: `${popupPos.left}px` }, onClick: (e) => e.stopPropagation() }, h("div", { class: "mrd-table__filter-popup-header" }, h("span", { class: "mrd-table__filter-popup-title" }, label), h("button", { class: "mrd-table__filter-close", onClick: cb.onClose }, "\u2715")), h("div", { class: "mrd-table__filter-section" }, h("div", { class: "mrd-table__filter-section-label" }, t('filter_sorting', locale)), h("div", { class: "mrd-table__filter-sort-buttons" }, 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)), 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)))), h("div", { class: "mrd-table__filter-divider" }), h("div", { class: "mrd-table__filter-section" }, h("div", { class: "mrd-table__filter-section-label" }, t('filter_section', locale)), h(FilterEditor, Object.assign({}, props))), h("div", { class: "mrd-table__filter-popup-footer" }, h("button", { class: "mrd-table__filter-btn mrd-table__filter-btn--clear", onClick: cb.onClear }, t('filter_clear', locale)), h("button", { class: "mrd-table__filter-btn mrd-table__filter-btn--apply", onClick: cb.onApply }, t('filter_apply', locale)))));
|
|
4226
|
+
};
|
|
4227
|
+
|
|
4228
|
+
/**
|
|
4229
|
+
* Pure window/paging maths for the mrd-table virtual scroll.
|
|
4230
|
+
* The window state itself stays @State in the component; these
|
|
4231
|
+
* functions only compute values from it.
|
|
4232
|
+
*/
|
|
4233
|
+
const BUFFER = 10;
|
|
4234
|
+
/** Wait this long (ms) after the last scroll event before requesting pages,
|
|
4235
|
+
* so pages the user quickly scrolls past are skipped. */
|
|
4236
|
+
const REQUEST_DEBOUNCE_MS = 150;
|
|
4237
|
+
/** Default time (ms) to wait for setPage() before treating a request as stale and retrying. */
|
|
4238
|
+
const REQUEST_TIMEOUT_MS = 15000;
|
|
4239
|
+
/** Max retries for a stale page request before giving up and showing a retry row. */
|
|
4240
|
+
const MAX_RETRY_ATTEMPTS = 3;
|
|
4241
|
+
function visibleCount(tableHeight, rowHeight) {
|
|
4242
|
+
return Math.ceil(tableHeight / rowHeight);
|
|
4243
|
+
}
|
|
4244
|
+
/** Render window (with buffer) for the given scroll offset. */
|
|
4245
|
+
function computeWindow(scrollTop, rowHeight, tableHeight, total) {
|
|
4246
|
+
const visStart = Math.floor(scrollTop / rowHeight);
|
|
4247
|
+
const visEnd = Math.min(visStart + visibleCount(tableHeight, rowHeight), total - 1);
|
|
4248
|
+
return {
|
|
4249
|
+
renderStart: Math.max(0, visStart - BUFFER),
|
|
4250
|
+
renderEnd: Math.min(total - 1, visEnd + BUFFER),
|
|
4251
|
+
};
|
|
4252
|
+
}
|
|
4253
|
+
/** First/last page (0-based) covering the given row window. */
|
|
4254
|
+
function pageRange(start, end, pageSize) {
|
|
4255
|
+
return { firstPage: Math.floor(start / pageSize), lastPage: Math.floor(end / pageSize) };
|
|
4256
|
+
}
|
|
4257
|
+
function getRowFromPages(pages, index, pageSize) {
|
|
4258
|
+
var _a;
|
|
4259
|
+
const page = pages.get(Math.floor(index / pageSize));
|
|
4260
|
+
return (_a = page === null || page === void 0 ? void 0 : page[index % pageSize]) !== null && _a !== void 0 ? _a : null;
|
|
4261
|
+
}
|
|
4262
|
+
/** Authoritative row count: a page shorter than pageSize is the last page,
|
|
4263
|
+
* so the true total cannot exceed its end index. */
|
|
4264
|
+
function computeEffectiveTotal(loadedPages, pageSize, baseTotal) {
|
|
4265
|
+
let effectiveTotal = baseTotal;
|
|
4266
|
+
for (const [pageNum, pageRows] of loadedPages) {
|
|
4267
|
+
if (pageRows.length < pageSize) {
|
|
4268
|
+
effectiveTotal = Math.min(effectiveTotal, pageNum * pageSize + pageRows.length);
|
|
4269
|
+
}
|
|
4270
|
+
}
|
|
4271
|
+
return effectiveTotal;
|
|
4272
|
+
}
|
|
4273
|
+
/** True when some loaded page was short — the exact total is then known. */
|
|
4274
|
+
function isTotalKnownFromPages(loadedPages, pageSize) {
|
|
4275
|
+
for (const rows of loadedPages.values()) {
|
|
4276
|
+
if (rows.length < pageSize)
|
|
4277
|
+
return true;
|
|
4278
|
+
}
|
|
4279
|
+
return false;
|
|
4280
|
+
}
|
|
4281
|
+
/** Pages whose request timestamp is older than timeoutMs — candidates for retry or failure.
|
|
4282
|
+
* Caller is expected to already exclude pages present in loadedPages. */
|
|
4283
|
+
function getStalePages(requestedAt, now, timeoutMs) {
|
|
4284
|
+
const stale = [];
|
|
4285
|
+
for (const [page, ts] of requestedAt) {
|
|
4286
|
+
if (now - ts >= timeoutMs)
|
|
4287
|
+
stale.push(page);
|
|
4288
|
+
}
|
|
4289
|
+
return stale;
|
|
4290
|
+
}
|
|
4291
|
+
|
|
4292
|
+
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}`;
|
|
4293
|
+
|
|
4294
|
+
/** How often (ms) to scan outstanding page requests for staleness. */
|
|
4295
|
+
const STALE_CHECK_INTERVAL_MS = 2000;
|
|
4296
|
+
/** Breedte van de filterpopup in px — voor overflow-correctie. */
|
|
4297
|
+
const POPUP_WIDTH = 280;
|
|
3817
4298
|
const MrdTable = class {
|
|
3818
4299
|
constructor(hostRef) {
|
|
3819
4300
|
registerInstance(this, hostRef);
|
|
3820
4301
|
this.mrdLoadPage = createEvent(this, "mrdLoadPage");
|
|
4302
|
+
this.mrdPageError = createEvent(this, "mrdPageError");
|
|
3821
4303
|
this.mrdRowClick = createEvent(this, "mrdRowClick");
|
|
3822
4304
|
this.mrdAction = createEvent(this, "mrdAction");
|
|
3823
4305
|
this.mrdDownload = createEvent(this, "mrdDownload");
|
|
@@ -3825,10 +4307,17 @@ const MrdTable = class {
|
|
|
3825
4307
|
// ── Non-state internals ────────────────────────────────────────────────────
|
|
3826
4308
|
this.pendingPages = new Set();
|
|
3827
4309
|
this.debounceTimer = null;
|
|
4310
|
+
/** Timestamp of the last mrdLoadPage emission per outstanding page — drives stale-request detection. */
|
|
4311
|
+
this.requestedAt = new Map();
|
|
4312
|
+
/** Retry count per page since it first became stale. */
|
|
4313
|
+
this.retryAttempts = new Map();
|
|
4314
|
+
this.staleCheckTimer = null;
|
|
3828
4315
|
this.outsideClickHandler = null;
|
|
3829
4316
|
this.keydownHandler = null;
|
|
3830
4317
|
this.createPickerClickHandler = null;
|
|
3831
4318
|
this.viewPopoverClickHandler = null;
|
|
4319
|
+
/** Guards against scheduling more than one column-width measurement per freeze. */
|
|
4320
|
+
this.colWidthMeasureScheduled = false;
|
|
3832
4321
|
// ── Props ──────────────────────────────────────────────────────────────────
|
|
3833
4322
|
/** The VIEW or RELATED_VIEW layout item. Contains view config, dataClass, fromClass, actions etc. */
|
|
3834
4323
|
this.item = null;
|
|
@@ -3845,11 +4334,16 @@ const MrdTable = class {
|
|
|
3845
4334
|
this.rowHeight = 36;
|
|
3846
4335
|
/** Height of the scroll container in px. */
|
|
3847
4336
|
this.tableHeight = 500;
|
|
4337
|
+
/** Time (ms) to wait for setPage() before retrying a page request; after
|
|
4338
|
+
* MAX_RETRY_ATTEMPTS retries the page is marked failed (see failedPages). */
|
|
4339
|
+
this.requestTimeoutMs = REQUEST_TIMEOUT_MS;
|
|
3848
4340
|
// ── Internal state ─────────────────────────────────────────────────────────
|
|
3849
4341
|
/** Index into allViews[] for the currently displayed view. 0 = primary, 1+ = alternatives. */
|
|
3850
4342
|
this.activeViewIdx = 0;
|
|
3851
4343
|
this.loadedPages = new Map();
|
|
3852
4344
|
this.requestedPages = new Set();
|
|
4345
|
+
/** Pages that timed out MAX_RETRY_ATTEMPTS times — rendered as a retry row instead of shimmer. */
|
|
4346
|
+
this.failedPages = new Set();
|
|
3853
4347
|
this.renderStart = 0;
|
|
3854
4348
|
this.renderEnd = 0;
|
|
3855
4349
|
this.colWidths = [];
|
|
@@ -3885,13 +4379,10 @@ const MrdTable = class {
|
|
|
3885
4379
|
this.minKnownTotal = 0;
|
|
3886
4380
|
this.handleScroll = (e) => {
|
|
3887
4381
|
const scroller = e.currentTarget;
|
|
3888
|
-
const
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
this.scrollTop = scrollTop;
|
|
3893
|
-
this.renderStart = Math.max(0, visStart - BUFFER);
|
|
3894
|
-
this.renderEnd = Math.min(total - 1, visEnd + BUFFER);
|
|
4382
|
+
const { renderStart, renderEnd } = computeWindow(scroller.scrollTop, this.rowHeight, this.tableHeight, this.baseTotal);
|
|
4383
|
+
this.scrollTop = scroller.scrollTop;
|
|
4384
|
+
this.renderStart = renderStart;
|
|
4385
|
+
this.renderEnd = renderEnd;
|
|
3895
4386
|
this.requestPagesForWindow(this.renderStart, this.renderEnd);
|
|
3896
4387
|
};
|
|
3897
4388
|
}
|
|
@@ -3911,18 +4402,14 @@ const MrdTable = class {
|
|
|
3911
4402
|
var _a, _b, _c;
|
|
3912
4403
|
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 : '');
|
|
3913
4404
|
}
|
|
4405
|
+
componentDidLoad() {
|
|
4406
|
+
this.staleCheckTimer = setInterval(() => this.checkStalePages(), STALE_CHECK_INTERVAL_MS);
|
|
4407
|
+
}
|
|
3914
4408
|
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
3915
4409
|
applyDefaultSort(defaultSort) {
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
this.sortField = parts[0].trim();
|
|
3920
|
-
this.sortDir = ((_a = parts[1]) === null || _a === void 0 ? void 0 : _a.trim()) === 'desc' ? 'desc' : 'asc';
|
|
3921
|
-
}
|
|
3922
|
-
else {
|
|
3923
|
-
this.sortField = '';
|
|
3924
|
-
this.sortDir = 'asc';
|
|
3925
|
-
}
|
|
4410
|
+
const { field, dir } = parseDefaultSort(defaultSort);
|
|
4411
|
+
this.sortField = field;
|
|
4412
|
+
this.sortDir = dir;
|
|
3926
4413
|
}
|
|
3927
4414
|
// ── Public API ─────────────────────────────────────────────────────────────
|
|
3928
4415
|
/**
|
|
@@ -3938,7 +4425,11 @@ const MrdTable = class {
|
|
|
3938
4425
|
this.pendingPages.clear();
|
|
3939
4426
|
this.loadedPages = new Map();
|
|
3940
4427
|
this.requestedPages = new Set();
|
|
4428
|
+
this.failedPages = new Set();
|
|
4429
|
+
this.requestedAt.clear();
|
|
4430
|
+
this.retryAttempts.clear();
|
|
3941
4431
|
this.colWidths = [];
|
|
4432
|
+
this.colWidthMeasureScheduled = false;
|
|
3942
4433
|
this.scrollTop = 0;
|
|
3943
4434
|
this.renderStart = 0;
|
|
3944
4435
|
// Always fill the visible viewport on init — totalElements may be stale from a
|
|
@@ -3952,7 +4443,7 @@ const MrdTable = class {
|
|
|
3952
4443
|
this.aggregationsPending = true;
|
|
3953
4444
|
this.minKnownTotal = 0;
|
|
3954
4445
|
// Always request page 0 — totalElements may be unknown (0) on first load.
|
|
3955
|
-
this.
|
|
4446
|
+
this.emitLoadPage(0);
|
|
3956
4447
|
this.requestedPages = new Set([0]);
|
|
3957
4448
|
}
|
|
3958
4449
|
/**
|
|
@@ -3983,6 +4474,13 @@ const MrdTable = class {
|
|
|
3983
4474
|
const next = new Map(this.loadedPages);
|
|
3984
4475
|
next.set(pageNumber, rows);
|
|
3985
4476
|
this.loadedPages = next;
|
|
4477
|
+
this.requestedAt.delete(pageNumber);
|
|
4478
|
+
this.retryAttempts.delete(pageNumber);
|
|
4479
|
+
if (this.failedPages.has(pageNumber)) {
|
|
4480
|
+
const nextFailed = new Set(this.failedPages);
|
|
4481
|
+
nextFailed.delete(pageNumber);
|
|
4482
|
+
this.failedPages = nextFailed;
|
|
4483
|
+
}
|
|
3986
4484
|
if (pageNumber === 0 && this.aggregationsPending) {
|
|
3987
4485
|
this.aggregationsPending = false;
|
|
3988
4486
|
const hasAggColumns = this.columns.some(c => c.type === 'FIELD' && c.aggregate);
|
|
@@ -4001,6 +4499,10 @@ const MrdTable = class {
|
|
|
4001
4499
|
}
|
|
4002
4500
|
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
4003
4501
|
disconnectedCallback() {
|
|
4502
|
+
if (this.staleCheckTimer !== null) {
|
|
4503
|
+
clearInterval(this.staleCheckTimer);
|
|
4504
|
+
this.staleCheckTimer = null;
|
|
4505
|
+
}
|
|
4004
4506
|
if (this.outsideClickHandler) {
|
|
4005
4507
|
document.removeEventListener('click', this.outsideClickHandler);
|
|
4006
4508
|
this.outsideClickHandler = null;
|
|
@@ -4019,21 +4521,34 @@ const MrdTable = class {
|
|
|
4019
4521
|
}
|
|
4020
4522
|
}
|
|
4021
4523
|
componentDidRender() {
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4524
|
+
// Freeze header widths once the first data page has rendered. The measurement
|
|
4525
|
+
// reads offsetWidth and writes the colWidths @State, which would trigger a
|
|
4526
|
+
// re-render *during* the render cycle if done synchronously here. Defer it to a
|
|
4527
|
+
// writeTask so the state mutation happens outside the render pass (avoids the
|
|
4528
|
+
// Stencil "state/prop changed during rendering" warning and potential loops).
|
|
4529
|
+
if (this.colWidths.length === 0 &&
|
|
4530
|
+
!this.colWidthMeasureScheduled &&
|
|
4531
|
+
this.loadedPages.size > 0 &&
|
|
4532
|
+
this.totalElements > 0) {
|
|
4533
|
+
this.colWidthMeasureScheduled = true;
|
|
4534
|
+
writeTask(() => {
|
|
4535
|
+
this.colWidthMeasureScheduled = false;
|
|
4536
|
+
// Re-check: state may have changed (e.g. a reset) between scheduling and running.
|
|
4537
|
+
if (this.colWidths.length !== 0)
|
|
4538
|
+
return;
|
|
4539
|
+
const ths = this.el.querySelectorAll('.mrd-table__header');
|
|
4540
|
+
if (ths.length > 0) {
|
|
4541
|
+
this.colWidths = Array.from(ths).map(th => th.offsetWidth);
|
|
4542
|
+
}
|
|
4543
|
+
});
|
|
4027
4544
|
}
|
|
4028
4545
|
}
|
|
4029
4546
|
// ── Paging / scroll helpers ────────────────────────────────────────────────
|
|
4030
4547
|
visibleCount() {
|
|
4031
|
-
return
|
|
4548
|
+
return visibleCount(this.tableHeight, this.rowHeight);
|
|
4032
4549
|
}
|
|
4033
4550
|
sortParam() {
|
|
4034
|
-
|
|
4035
|
-
return '';
|
|
4036
|
-
return this.sortDir === 'desc' ? `${this.sortField},desc` : this.sortField;
|
|
4551
|
+
return buildSortParam(this.sortField, this.sortDir);
|
|
4037
4552
|
}
|
|
4038
4553
|
/** Stable ordered list: primary view first, then alternatives (from the item prop). */
|
|
4039
4554
|
get allViews() {
|
|
@@ -4059,14 +4574,16 @@ const MrdTable = class {
|
|
|
4059
4574
|
* VIEW: /excel/{dataClass}
|
|
4060
4575
|
* RELATED_VIEW: /excel/{fromClass}/{parentId}/{dataClass} */
|
|
4061
4576
|
buildExcelPath() {
|
|
4062
|
-
var _a
|
|
4577
|
+
var _a;
|
|
4063
4578
|
const v = this.allViews[this.activeViewIdx];
|
|
4064
4579
|
if (!v)
|
|
4065
4580
|
return '';
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4581
|
+
return '/excel' + buildListPath({
|
|
4582
|
+
isRelatedView: ((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'RELATED_VIEW',
|
|
4583
|
+
fromClass: v.fromClass,
|
|
4584
|
+
parentId: this.parentId,
|
|
4585
|
+
dataClass: v.dataClass,
|
|
4586
|
+
});
|
|
4070
4587
|
}
|
|
4071
4588
|
buildActionDetail(action, basicType) {
|
|
4072
4589
|
var _a, _b, _c;
|
|
@@ -4086,80 +4603,28 @@ const MrdTable = class {
|
|
|
4086
4603
|
* VIEW: /{dataClass}
|
|
4087
4604
|
* RELATED_VIEW: /{fromClass}/{parentId}/{dataClass} */
|
|
4088
4605
|
buildDataPath() {
|
|
4089
|
-
var _a
|
|
4606
|
+
var _a;
|
|
4090
4607
|
const v = this.allViews[this.activeViewIdx];
|
|
4091
4608
|
if (!v)
|
|
4092
4609
|
return '';
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4610
|
+
return buildListPath({
|
|
4611
|
+
isRelatedView: ((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'RELATED_VIEW',
|
|
4612
|
+
fromClass: v.fromClass,
|
|
4613
|
+
parentId: this.parentId,
|
|
4614
|
+
dataClass: v.dataClass,
|
|
4615
|
+
});
|
|
4097
4616
|
}
|
|
4098
4617
|
/** Build query params for a page request from current sort, view filters, filterClass and active column filters. */
|
|
4099
4618
|
buildQueryParams(page) {
|
|
4100
|
-
var _a
|
|
4619
|
+
var _a;
|
|
4101
4620
|
const v = this.allViews[this.activeViewIdx];
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
if (filterClass)
|
|
4110
|
-
p.set('type', filterClass);
|
|
4111
|
-
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 : [])) {
|
|
4112
|
-
if (!f.name)
|
|
4113
|
-
continue;
|
|
4114
|
-
if (f.operator === 'EMPTY') {
|
|
4115
|
-
p.set(f.name, '');
|
|
4116
|
-
continue;
|
|
4117
|
-
}
|
|
4118
|
-
if (f.operator === 'NOT_EMPTY') {
|
|
4119
|
-
p.set(f.name + '_notempty', 'true');
|
|
4120
|
-
continue;
|
|
4121
|
-
}
|
|
4122
|
-
if (f.operator === 'STARTS_WITH') {
|
|
4123
|
-
p.set(f.name + '_startswith', String((_c = f.value) !== null && _c !== void 0 ? _c : ''));
|
|
4124
|
-
continue;
|
|
4125
|
-
}
|
|
4126
|
-
if (f.operator === 'FROM') {
|
|
4127
|
-
p.set(f.name + '_from', String((_d = f.value) !== null && _d !== void 0 ? _d : ''));
|
|
4128
|
-
continue;
|
|
4129
|
-
}
|
|
4130
|
-
if (f.operator === 'TO') {
|
|
4131
|
-
p.set(f.name + '_to', String((_e = f.value) !== null && _e !== void 0 ? _e : ''));
|
|
4132
|
-
continue;
|
|
4133
|
-
}
|
|
4134
|
-
if (f.value != null) {
|
|
4135
|
-
p.set(f.name, String(f.value));
|
|
4136
|
-
}
|
|
4137
|
-
}
|
|
4138
|
-
for (const f of this.activeFilters.values()) {
|
|
4139
|
-
if (f.operator === 'isEmpty') {
|
|
4140
|
-
p.set(f.field, '');
|
|
4141
|
-
continue;
|
|
4142
|
-
}
|
|
4143
|
-
if (f.operator === 'isNotEmpty') {
|
|
4144
|
-
p.set(f.field + '_notempty', 'true');
|
|
4145
|
-
continue;
|
|
4146
|
-
}
|
|
4147
|
-
if (f.operator === 'startsWith') {
|
|
4148
|
-
p.set(f.field + '_startswith', String((_f = f.value) !== null && _f !== void 0 ? _f : ''));
|
|
4149
|
-
continue;
|
|
4150
|
-
}
|
|
4151
|
-
if ((_g = f.values) === null || _g === void 0 ? void 0 : _g.length) {
|
|
4152
|
-
p.set(f.field, f.values.join(','));
|
|
4153
|
-
continue;
|
|
4154
|
-
}
|
|
4155
|
-
if (f.value != null)
|
|
4156
|
-
p.set(f.field, String(f.value));
|
|
4157
|
-
if (f.from != null)
|
|
4158
|
-
p.set(f.field + '_from', String(f.from));
|
|
4159
|
-
if (f.to != null)
|
|
4160
|
-
p.set(f.field + '_to', String(f.to));
|
|
4161
|
-
}
|
|
4162
|
-
return p.toString();
|
|
4621
|
+
return buildTableQueryParams({
|
|
4622
|
+
page,
|
|
4623
|
+
sort: this.sortParam(),
|
|
4624
|
+
filterClass: v === null || v === void 0 ? void 0 : v.filterClass,
|
|
4625
|
+
viewFilters: (_a = v === null || v === void 0 ? void 0 : v.view) === null || _a === void 0 ? void 0 : _a.filter,
|
|
4626
|
+
activeFilters: this.activeFilters.values(),
|
|
4627
|
+
});
|
|
4163
4628
|
}
|
|
4164
4629
|
get columns() {
|
|
4165
4630
|
var _a, _b, _c;
|
|
@@ -4214,11 +4679,7 @@ const MrdTable = class {
|
|
|
4214
4679
|
isTotalKnown() {
|
|
4215
4680
|
if (this.aggregationsTotal != null)
|
|
4216
4681
|
return true;
|
|
4217
|
-
|
|
4218
|
-
if (rows.length < this.pageSize)
|
|
4219
|
-
return true;
|
|
4220
|
-
}
|
|
4221
|
-
return false;
|
|
4682
|
+
return isTotalKnownFromPages(this.loadedPages, this.pageSize);
|
|
4222
4683
|
}
|
|
4223
4684
|
/** Effective total: aggregations-response > totalElements prop > minKnownTotal from setPage(). */
|
|
4224
4685
|
get baseTotal() {
|
|
@@ -4229,61 +4690,9 @@ const MrdTable = class {
|
|
|
4229
4690
|
return this.minKnownTotal;
|
|
4230
4691
|
}
|
|
4231
4692
|
// ── Aggregation helpers ────────────────────────────────────────────────────
|
|
4232
|
-
buildAggregationParams() {
|
|
4233
|
-
var _a;
|
|
4234
|
-
const groups = { sum: [], avg: [], count: [] };
|
|
4235
|
-
for (const col of this.columns) {
|
|
4236
|
-
if (col.type !== 'FIELD' || !col.aggregate)
|
|
4237
|
-
continue;
|
|
4238
|
-
const fn = col.aggregate.toLowerCase();
|
|
4239
|
-
if (fn in groups)
|
|
4240
|
-
groups[fn].push((_a = col.name) !== null && _a !== void 0 ? _a : '');
|
|
4241
|
-
}
|
|
4242
|
-
const params = {};
|
|
4243
|
-
if (groups.sum.length)
|
|
4244
|
-
params.sum = groups.sum;
|
|
4245
|
-
if (groups.avg.length)
|
|
4246
|
-
params.avg = groups.avg;
|
|
4247
|
-
if (groups.count.length)
|
|
4248
|
-
params.count = groups.count;
|
|
4249
|
-
return Object.keys(params).length > 0 ? params : null;
|
|
4250
|
-
}
|
|
4251
|
-
buildAggregationQs() {
|
|
4252
|
-
var _a, _b, _c;
|
|
4253
|
-
const p = new URLSearchParams(this.buildQueryParams(0));
|
|
4254
|
-
p.delete('page');
|
|
4255
|
-
p.delete('sort');
|
|
4256
|
-
const groups = this.buildAggregationParams();
|
|
4257
|
-
if ((_a = groups === null || groups === void 0 ? void 0 : groups.sum) === null || _a === void 0 ? void 0 : _a.length)
|
|
4258
|
-
p.set('sum', groups.sum.join(','));
|
|
4259
|
-
if ((_b = groups === null || groups === void 0 ? void 0 : groups.avg) === null || _b === void 0 ? void 0 : _b.length)
|
|
4260
|
-
p.set('avg', groups.avg.join(','));
|
|
4261
|
-
if ((_c = groups === null || groups === void 0 ? void 0 : groups.count) === null || _c === void 0 ? void 0 : _c.length)
|
|
4262
|
-
p.set('count', groups.count.join(','));
|
|
4263
|
-
return p.toString();
|
|
4264
|
-
}
|
|
4265
4693
|
emitLoadAggregations() {
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
renderAggregationValue(col) {
|
|
4269
|
-
var _a;
|
|
4270
|
-
if (col.type !== 'FIELD' || !col.aggregate || !this.aggregations)
|
|
4271
|
-
return '';
|
|
4272
|
-
const fn = col.aggregate.toLowerCase();
|
|
4273
|
-
const aggData = this.aggregations[fn];
|
|
4274
|
-
const val = typeof aggData === 'object' && aggData !== null
|
|
4275
|
-
? aggData[(_a = col.name) !== null && _a !== void 0 ? _a : '']
|
|
4276
|
-
: undefined;
|
|
4277
|
-
if (val == null)
|
|
4278
|
-
return '';
|
|
4279
|
-
const dt = col.dataType;
|
|
4280
|
-
if (dt === 'INTEGER')
|
|
4281
|
-
return formatNumber(val, this.locale, { maximumFractionDigits: 0 });
|
|
4282
|
-
if (dt === 'PERCENTAGE')
|
|
4283
|
-
return formatPercentage(val, this.locale);
|
|
4284
|
-
if (dt === 'CURRENCY' && col.currencyCode)
|
|
4285
|
-
return formatCurrency(val, col.currencyCode, this.locale);
|
|
4286
|
-
return formatNumber(val, this.locale);
|
|
4694
|
+
const qs = this.buildQueryParams(0);
|
|
4695
|
+
this.mrdLoadAggregations.emit({ path: this.buildDataPath(), qs, aggQs: buildAggregationQs(qs, this.columns) });
|
|
4287
4696
|
}
|
|
4288
4697
|
// ── Reset pagination ───────────────────────────────────────────────────────
|
|
4289
4698
|
/** Reset pagination state and scroll to top (used after sort or filter change). */
|
|
@@ -4295,7 +4704,11 @@ const MrdTable = class {
|
|
|
4295
4704
|
this.pendingPages.clear();
|
|
4296
4705
|
this.loadedPages = new Map();
|
|
4297
4706
|
this.requestedPages = new Set();
|
|
4707
|
+
this.failedPages = new Set();
|
|
4708
|
+
this.requestedAt.clear();
|
|
4709
|
+
this.retryAttempts.clear();
|
|
4298
4710
|
this.colWidths = [];
|
|
4711
|
+
this.colWidthMeasureScheduled = false;
|
|
4299
4712
|
this.scrollTop = 0;
|
|
4300
4713
|
this.renderStart = 0;
|
|
4301
4714
|
this.minKnownTotal = 0;
|
|
@@ -4324,15 +4737,19 @@ const MrdTable = class {
|
|
|
4324
4737
|
this.resetPages();
|
|
4325
4738
|
this.emitPagesForWindow(this.renderStart, this.renderEnd);
|
|
4326
4739
|
}
|
|
4740
|
+
/** Emits mrdLoadPage for a page and records the request timestamp for stale-request detection. */
|
|
4741
|
+
emitLoadPage(page) {
|
|
4742
|
+
this.mrdLoadPage.emit({ page, sort: this.sortParam(), path: this.buildDataPath(), qs: this.buildQueryParams(page) });
|
|
4743
|
+
this.requestedAt.set(page, Date.now());
|
|
4744
|
+
}
|
|
4327
4745
|
emitPagesForWindow(start, end) {
|
|
4328
|
-
const firstPage =
|
|
4329
|
-
const lastPage = Math.floor(end / this.pageSize);
|
|
4746
|
+
const { firstPage, lastPage } = pageRange(start, end, this.pageSize);
|
|
4330
4747
|
const next = new Set(this.requestedPages);
|
|
4331
4748
|
let changed = false;
|
|
4332
4749
|
for (let p = firstPage; p <= lastPage; p++) {
|
|
4333
4750
|
if (!this.loadedPages.has(p) && !next.has(p)) {
|
|
4334
4751
|
next.add(p);
|
|
4335
|
-
this.
|
|
4752
|
+
this.emitLoadPage(p);
|
|
4336
4753
|
changed = true;
|
|
4337
4754
|
}
|
|
4338
4755
|
}
|
|
@@ -4340,13 +4757,10 @@ const MrdTable = class {
|
|
|
4340
4757
|
this.requestedPages = next;
|
|
4341
4758
|
}
|
|
4342
4759
|
getRow(i) {
|
|
4343
|
-
|
|
4344
|
-
const page = this.loadedPages.get(Math.floor(i / this.pageSize));
|
|
4345
|
-
return (_a = page === null || page === void 0 ? void 0 : page[i % this.pageSize]) !== null && _a !== void 0 ? _a : null;
|
|
4760
|
+
return getRowFromPages(this.loadedPages, i, this.pageSize);
|
|
4346
4761
|
}
|
|
4347
4762
|
requestPagesForWindow(start, end) {
|
|
4348
|
-
const firstPage =
|
|
4349
|
-
const lastPage = Math.floor(end / this.pageSize);
|
|
4763
|
+
const { firstPage, lastPage } = pageRange(start, end, this.pageSize);
|
|
4350
4764
|
let anyNew = false;
|
|
4351
4765
|
for (let p = firstPage; p <= lastPage; p++) {
|
|
4352
4766
|
if (!this.loadedPages.has(p) && !this.requestedPages.has(p) && !this.pendingPages.has(p)) {
|
|
@@ -4374,13 +4788,53 @@ const MrdTable = class {
|
|
|
4374
4788
|
if (pageEnd < this.renderStart || pageStart > this.renderEnd)
|
|
4375
4789
|
continue;
|
|
4376
4790
|
next.add(page);
|
|
4377
|
-
this.
|
|
4791
|
+
this.emitLoadPage(page);
|
|
4378
4792
|
changed = true;
|
|
4379
4793
|
}
|
|
4380
4794
|
this.pendingPages.clear();
|
|
4381
4795
|
if (changed)
|
|
4382
4796
|
this.requestedPages = next;
|
|
4383
4797
|
}
|
|
4798
|
+
/** Scans outstanding requests for staleness: retries up to MAX_RETRY_ATTEMPTS times,
|
|
4799
|
+
* then gives up and marks the page as failed (rendered as a retry row). */
|
|
4800
|
+
checkStalePages() {
|
|
4801
|
+
var _a;
|
|
4802
|
+
if (this.requestedAt.size === 0)
|
|
4803
|
+
return;
|
|
4804
|
+
const stale = getStalePages(this.requestedAt, Date.now(), this.requestTimeoutMs)
|
|
4805
|
+
.filter(p => !this.loadedPages.has(p));
|
|
4806
|
+
if (stale.length === 0)
|
|
4807
|
+
return;
|
|
4808
|
+
let nextFailed = null;
|
|
4809
|
+
for (const page of stale) {
|
|
4810
|
+
const attempts = (_a = this.retryAttempts.get(page)) !== null && _a !== void 0 ? _a : 0;
|
|
4811
|
+
if (attempts < MAX_RETRY_ATTEMPTS) {
|
|
4812
|
+
this.retryAttempts.set(page, attempts + 1);
|
|
4813
|
+
this.emitLoadPage(page);
|
|
4814
|
+
}
|
|
4815
|
+
else {
|
|
4816
|
+
this.requestedAt.delete(page);
|
|
4817
|
+
this.retryAttempts.delete(page);
|
|
4818
|
+
if (!nextFailed)
|
|
4819
|
+
nextFailed = new Set(this.failedPages);
|
|
4820
|
+
nextFailed.add(page);
|
|
4821
|
+
this.mrdPageError.emit({ page });
|
|
4822
|
+
}
|
|
4823
|
+
}
|
|
4824
|
+
if (nextFailed)
|
|
4825
|
+
this.failedPages = nextFailed;
|
|
4826
|
+
}
|
|
4827
|
+
/** Manually retry a page the user gave up on (clicked the retry row). */
|
|
4828
|
+
retryPage(page) {
|
|
4829
|
+
const next = new Set(this.failedPages);
|
|
4830
|
+
next.delete(page);
|
|
4831
|
+
this.failedPages = next;
|
|
4832
|
+
this.retryAttempts.delete(page);
|
|
4833
|
+
this.emitLoadPage(page);
|
|
4834
|
+
const requested = new Set(this.requestedPages);
|
|
4835
|
+
requested.add(page);
|
|
4836
|
+
this.requestedPages = requested;
|
|
4837
|
+
}
|
|
4384
4838
|
// ── Filter helpers ─────────────────────────────────────────────────────────
|
|
4385
4839
|
handleFilterToggle() {
|
|
4386
4840
|
this.filterMode = !this.filterMode;
|
|
@@ -4408,17 +4862,7 @@ const MrdTable = class {
|
|
|
4408
4862
|
// If from and to cover the same local day it was an exact-date filter — restore
|
|
4409
4863
|
// to exact mode so the user sees the single-date input again.
|
|
4410
4864
|
if (dataType === 'DATETIME' && existing && existing.operator !== 'isEmpty' && existing.operator !== 'isNotEmpty') {
|
|
4411
|
-
|
|
4412
|
-
if (typeof display.from === 'string' && display.from)
|
|
4413
|
-
display.from = this.utcISOToLocalDate(display.from);
|
|
4414
|
-
if (typeof display.to === 'string' && display.to)
|
|
4415
|
-
display.to = this.utcISOToLocalDateExclusiveEnd(display.to);
|
|
4416
|
-
if (display.from && display.to && display.from === display.to) {
|
|
4417
|
-
this.pendingFilter = Object.assign(Object.assign({}, display), { value: display.from, from: undefined, to: undefined });
|
|
4418
|
-
}
|
|
4419
|
-
else {
|
|
4420
|
-
this.pendingFilter = display;
|
|
4421
|
-
}
|
|
4865
|
+
this.pendingFilter = datetimeFilterToDisplay(existing);
|
|
4422
4866
|
}
|
|
4423
4867
|
else {
|
|
4424
4868
|
this.pendingFilter = existing ? Object.assign({}, existing) : { field: name, dataType, operator: defaultOperator };
|
|
@@ -4484,81 +4928,15 @@ const MrdTable = class {
|
|
|
4484
4928
|
const current = (_b = (_a = this.pendingFilter) === null || _a === void 0 ? void 0 : _a.values) !== null && _b !== void 0 ? _b : [];
|
|
4485
4929
|
this.pendingFilter = Object.assign(Object.assign({}, this.pendingFilter), { values: checked ? [...current, key] : current.filter(k => k !== key) });
|
|
4486
4930
|
}
|
|
4487
|
-
filterHasValue(f) {
|
|
4488
|
-
if (f.operator === 'isEmpty' || f.operator === 'isNotEmpty')
|
|
4489
|
-
return true;
|
|
4490
|
-
if (f.values !== undefined && f.values.length > 0)
|
|
4491
|
-
return true;
|
|
4492
|
-
if (f.value != null && f.value !== '')
|
|
4493
|
-
return true;
|
|
4494
|
-
if (typeof f.value === 'boolean')
|
|
4495
|
-
return true;
|
|
4496
|
-
if (f.from != null && f.from !== '')
|
|
4497
|
-
return true;
|
|
4498
|
-
if (f.to != null && f.to !== '')
|
|
4499
|
-
return true;
|
|
4500
|
-
return false;
|
|
4501
|
-
}
|
|
4502
|
-
// Convert a local "YYYY-MM-DD" date string to the UTC ISO string at the
|
|
4503
|
-
// start of that local day (midnight). new Date(y, m, d) uses local time.
|
|
4504
|
-
dateLocalToUTCStart(dateStr) {
|
|
4505
|
-
if (!dateStr)
|
|
4506
|
-
return dateStr;
|
|
4507
|
-
const [year, month, day] = dateStr.split('-').map(Number);
|
|
4508
|
-
return new Date(year, month - 1, day).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
4509
|
-
}
|
|
4510
|
-
// Start of the day AFTER the given local date (exclusive range end).
|
|
4511
|
-
dateLocalToUTCEndExclusive(dateStr) {
|
|
4512
|
-
if (!dateStr)
|
|
4513
|
-
return dateStr;
|
|
4514
|
-
const [year, month, day] = dateStr.split('-').map(Number);
|
|
4515
|
-
return new Date(year, month - 1, day + 1).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
4516
|
-
}
|
|
4517
|
-
// Convert a stored UTC ISO string back to the local "YYYY-MM-DD" date.
|
|
4518
|
-
utcISOToLocalDate(utcStr) {
|
|
4519
|
-
if (!utcStr)
|
|
4520
|
-
return utcStr;
|
|
4521
|
-
const d = new Date(utcStr);
|
|
4522
|
-
if (isNaN(d.getTime()))
|
|
4523
|
-
return utcStr;
|
|
4524
|
-
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
4525
|
-
}
|
|
4526
|
-
// The stored "to" value is the exclusive end (midnight of the next day).
|
|
4527
|
-
// Subtract one day to recover the local date the user entered.
|
|
4528
|
-
utcISOToLocalDateExclusiveEnd(utcStr) {
|
|
4529
|
-
if (!utcStr)
|
|
4530
|
-
return utcStr;
|
|
4531
|
-
const d = new Date(utcStr);
|
|
4532
|
-
if (isNaN(d.getTime()))
|
|
4533
|
-
return utcStr;
|
|
4534
|
-
d.setDate(d.getDate() - 1);
|
|
4535
|
-
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
4536
|
-
}
|
|
4537
4931
|
applyFilter() {
|
|
4538
4932
|
const f = this.pendingFilter;
|
|
4539
4933
|
if (!(f === null || f === void 0 ? void 0 : f.field)) {
|
|
4540
4934
|
this.closeFilterPopup();
|
|
4541
4935
|
return;
|
|
4542
4936
|
}
|
|
4543
|
-
|
|
4544
|
-
// Exact date → range covering the full local day (from = midnight, to = next midnight).
|
|
4545
|
-
// "to" is always the exclusive end (midnight of the next local day).
|
|
4546
|
-
let normalized = Object.assign({}, f);
|
|
4547
|
-
if (f.dataType === 'DATETIME' && f.operator !== 'isEmpty' && f.operator !== 'isNotEmpty') {
|
|
4548
|
-
if (typeof normalized.value === 'string' && normalized.value) {
|
|
4549
|
-
normalized.from = this.dateLocalToUTCStart(normalized.value);
|
|
4550
|
-
normalized.to = this.dateLocalToUTCEndExclusive(normalized.value);
|
|
4551
|
-
normalized.value = undefined;
|
|
4552
|
-
}
|
|
4553
|
-
else {
|
|
4554
|
-
if (typeof normalized.from === 'string' && normalized.from)
|
|
4555
|
-
normalized.from = this.dateLocalToUTCStart(normalized.from);
|
|
4556
|
-
if (typeof normalized.to === 'string' && normalized.to)
|
|
4557
|
-
normalized.to = this.dateLocalToUTCEndExclusive(normalized.to);
|
|
4558
|
-
}
|
|
4559
|
-
}
|
|
4937
|
+
const normalized = normalizeDatetimeFilter(f);
|
|
4560
4938
|
const next = new Map(this.activeFilters);
|
|
4561
|
-
if (
|
|
4939
|
+
if (filterHasValue(normalized)) {
|
|
4562
4940
|
next.set(normalized.field, normalized);
|
|
4563
4941
|
}
|
|
4564
4942
|
else {
|
|
@@ -4613,140 +4991,53 @@ const MrdTable = class {
|
|
|
4613
4991
|
toggleViewPopover(e) {
|
|
4614
4992
|
e.stopPropagation();
|
|
4615
4993
|
if (this.viewPopoverOpen) {
|
|
4616
|
-
this.
|
|
4617
|
-
if (this.viewPopoverClickHandler) {
|
|
4618
|
-
document.removeEventListener('click', this.viewPopoverClickHandler);
|
|
4619
|
-
this.viewPopoverClickHandler = null;
|
|
4620
|
-
}
|
|
4994
|
+
this.closeViewPopover();
|
|
4621
4995
|
return;
|
|
4622
4996
|
}
|
|
4623
4997
|
this.viewPopoverOpen = true;
|
|
4624
|
-
this.viewPopoverClickHandler = () =>
|
|
4625
|
-
|
|
4998
|
+
this.viewPopoverClickHandler = () => this.closeViewPopover();
|
|
4999
|
+
document.addEventListener('click', this.viewPopoverClickHandler);
|
|
5000
|
+
}
|
|
5001
|
+
closeViewPopover() {
|
|
5002
|
+
this.viewPopoverOpen = false;
|
|
5003
|
+
if (this.viewPopoverClickHandler) {
|
|
4626
5004
|
document.removeEventListener('click', this.viewPopoverClickHandler);
|
|
4627
5005
|
this.viewPopoverClickHandler = null;
|
|
4628
|
-
}
|
|
4629
|
-
document.addEventListener('click', this.viewPopoverClickHandler);
|
|
5006
|
+
}
|
|
4630
5007
|
}
|
|
4631
5008
|
// ── Render: toolbar ────────────────────────────────────────────────────────
|
|
4632
5009
|
renderToolbar() {
|
|
4633
5010
|
var _a;
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
} }, v.label)))))), h("button", { class: "mrd-table__view-arrow", "aria-label": "Next view", onClick: () => this.handleViewSwitch((this.activeViewIdx + 1) % allViews.length) }, "\u25B6")))), hasActions && (h("div", { class: "mrd-table__toolbar-right" }, actions.map(a => {
|
|
4648
|
-
var _a, _b, _c;
|
|
4649
|
-
const createTypes = a.action === 'create' ? (_a = this.item) === null || _a === void 0 ? void 0 : _a.createTypes : null;
|
|
4650
|
-
if (createTypes === null || createTypes === void 0 ? void 0 : createTypes.length) {
|
|
4651
|
-
return (h("div", { class: "mrd-table__create-picker-wrap", key: `action-${a.action}` }, h("button", { class: `mrd-table__action mrd-table__action--${(_b = a.variant) !== null && _b !== void 0 ? _b : 'secondary'}`, onClick: () => this.toggleCreatePicker() }, a.icon
|
|
4652
|
-
? h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, h("use", { href: a.icon }))
|
|
4653
|
-
: a.label, h("span", { class: "mrd-table__action-tooltip" }, a.label)), this.createPickerOpen && (h("div", { class: "mrd-table__create-picker" }, createTypes.map(ct => (h("button", { key: ct.type, class: "mrd-table__create-picker-item", onClick: () => {
|
|
4654
|
-
this.mrdAction.emit(this.buildActionDetail('create', ct.type));
|
|
4655
|
-
this.closeCreatePicker();
|
|
4656
|
-
} }, ct.label)))))));
|
|
4657
|
-
}
|
|
4658
|
-
return (h("button", { key: `action-${a.action}`, class: `mrd-table__action mrd-table__action--${(_c = a.variant) !== null && _c !== void 0 ? _c : 'secondary'}`, disabled: a.disabled, onClick: () => this.mrdAction.emit(this.buildActionDetail(a.action)) }, a.icon
|
|
4659
|
-
? h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, h("use", { href: a.icon }))
|
|
4660
|
-
: a.label, h("span", { class: "mrd-table__action-tooltip" }, a.label)));
|
|
4661
|
-
})))));
|
|
5011
|
+
return (h(Toolbar, { locale: this.locale, filterMode: this.filterMode, filterCount: this.activeFilters.size, actions: this.tableActions, views: this.allViews, activeViewIdx: this.activeViewIdx, viewPopoverOpen: this.viewPopoverOpen, createPickerOpen: this.createPickerOpen, createTypes: (_a = this.item) === null || _a === void 0 ? void 0 : _a.createTypes, cb: {
|
|
5012
|
+
onFilterToggle: () => this.handleFilterToggle(),
|
|
5013
|
+
onClearAllFilters: () => this.clearAllFilters(),
|
|
5014
|
+
onViewSwitch: idx => this.handleViewSwitch(idx),
|
|
5015
|
+
onToggleViewPopover: e => this.toggleViewPopover(e),
|
|
5016
|
+
onCloseViewPopover: () => this.closeViewPopover(),
|
|
5017
|
+
onToggleCreatePicker: () => this.toggleCreatePicker(),
|
|
5018
|
+
onCreate: basicType => {
|
|
5019
|
+
this.mrdAction.emit(this.buildActionDetail('create', basicType));
|
|
5020
|
+
this.closeCreatePicker();
|
|
5021
|
+
},
|
|
5022
|
+
onAction: action => this.mrdAction.emit(this.buildActionDetail(action)),
|
|
5023
|
+
} }));
|
|
4662
5024
|
}
|
|
4663
5025
|
// ── Render: filter popup ───────────────────────────────────────────────────
|
|
4664
|
-
renderFilterEditor(col) {
|
|
4665
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
4666
|
-
const pf = (_a = this.pendingFilter) !== null && _a !== void 0 ? _a : {};
|
|
4667
|
-
const dataType = this.colDataType(col);
|
|
4668
|
-
if (NO_FILTER_TYPES.has(dataType)) {
|
|
4669
|
-
return h("p", { class: "mrd-table__filter-no-support" }, t('filter_no_support', this.locale));
|
|
4670
|
-
}
|
|
4671
|
-
if (dataType === 'BOOLEAN') {
|
|
4672
|
-
const boolOp = pf.operator;
|
|
4673
|
-
const noValueOp = boolOp === 'isEmpty' || boolOp === 'isNotEmpty';
|
|
4674
|
-
return (h("div", { class: "mrd-table__filter-radio-group" }, [
|
|
4675
|
-
{ labelKey: 'filter_all', value: null },
|
|
4676
|
-
{ labelKey: 'yes', value: true },
|
|
4677
|
-
{ labelKey: 'no', value: false },
|
|
4678
|
-
].map(opt => (h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `bf-${this.openFilterCol}`, checked: !noValueOp && pf.value === opt.value, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined, value: opt.value }); } }), t(opt.labelKey, this.locale)))), h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `bf-${this.openFilterCol}`, checked: boolOp === 'isEmpty', onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: 'isEmpty', value: undefined }); } }), t('filter_is_empty', this.locale)), h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `bf-${this.openFilterCol}`, checked: boolOp === 'isNotEmpty', onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: 'isNotEmpty', value: undefined }); } }), t('filter_is_not_empty', this.locale))));
|
|
4679
|
-
}
|
|
4680
|
-
if (dataType === 'LIST') {
|
|
4681
|
-
const items = (_b = col.listItems) !== null && _b !== void 0 ? _b : [];
|
|
4682
|
-
const selected = (_c = pf.values) !== null && _c !== void 0 ? _c : [];
|
|
4683
|
-
return (h("div", { class: "mrd-table__filter-list" }, h("div", { class: "mrd-table__filter-list-controls" }, h("button", { class: "mrd-table__filter-list-btn", onClick: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { values: items.map(i => i.key) }); } }, t('filter_select_all', this.locale)), h("button", { class: "mrd-table__filter-list-btn", onClick: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { values: [] }); } }, t('filter_select_none', this.locale))), items.map(item => (h("label", { class: "mrd-table__filter-checkbox-label" }, h("input", { type: "checkbox", checked: selected.includes(item.key), onChange: (e) => this.togglePendingValue(item.key, e.target.checked) }), item.label)))));
|
|
4684
|
-
}
|
|
4685
|
-
if (TEXT_TYPES.has(dataType) || dataType === 'RELATION') {
|
|
4686
|
-
const op = (_d = pf.operator) !== null && _d !== void 0 ? _d : 'startsWith';
|
|
4687
|
-
const noInput = op === 'isEmpty' || op === 'isNotEmpty';
|
|
4688
|
-
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => this.setPending('operator', e.target.value) }, [
|
|
4689
|
-
{ val: 'startsWith', labelKey: 'filter_starts_with' },
|
|
4690
|
-
{ val: 'equals', labelKey: 'filter_equals' },
|
|
4691
|
-
{ val: 'isEmpty', labelKey: 'filter_is_empty' },
|
|
4692
|
-
{ val: 'isNotEmpty', labelKey: 'filter_is_not_empty' },
|
|
4693
|
-
].map(o => h("option", { value: o.val, selected: op === o.val }, t(o.labelKey, this.locale)))), !noInput && (h("input", { type: "text", class: "mrd-table__filter-input", value: String((_e = pf.value) !== null && _e !== void 0 ? _e : ''), placeholder: t('filter_search_value', this.locale), onInput: (e) => this.setPending('value', e.target.value) }))));
|
|
4694
|
-
}
|
|
4695
|
-
if (NUMERIC_TYPES.has(dataType)) {
|
|
4696
|
-
const numOp = pf.operator;
|
|
4697
|
-
const noInput = numOp === 'isEmpty' || numOp === 'isNotEmpty';
|
|
4698
|
-
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4699
|
-
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4700
|
-
const val = e.target.value;
|
|
4701
|
-
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4702
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined });
|
|
4703
|
-
}
|
|
4704
|
-
else {
|
|
4705
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined });
|
|
4706
|
-
}
|
|
4707
|
-
} }, h("option", { value: "", selected: !noInput }, t('filter_has_value', this.locale)), h("option", { value: "isEmpty", selected: numOp === 'isEmpty' }, t('filter_is_empty', this.locale)), h("option", { value: "isNotEmpty", selected: numOp === 'isNotEmpty' }, t('filter_is_not_empty', this.locale))), !noInput && (h("div", { class: "mrd-table__filter-editor" }, h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `nm-${this.openFilterCol}`, checked: !rangeMode, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { from: undefined, to: undefined }); } }), t('filter_exact', this.locale)), h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `nm-${this.openFilterCol}`, checked: rangeMode, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { value: undefined, from: null, to: null }); } }), t('filter_range', this.locale))), !rangeMode ? (h("input", { type: "number", class: "mrd-table__filter-input", value: pf.value != null ? String(pf.value) : '', onInput: (e) => this.setPending('value', e.target.value) })) : (h("div", { class: "mrd-table__filter-range" }, h("input", { type: "number", class: "mrd-table__filter-input", placeholder: t('filter_from', this.locale), value: pf.from != null ? String(pf.from) : '', onInput: (e) => this.setPending('from', e.target.value) }), h("span", { class: "mrd-table__filter-range-sep" }, "\u2013"), h("input", { type: "number", class: "mrd-table__filter-input", placeholder: t('filter_to', this.locale), value: pf.to != null ? String(pf.to) : '', onInput: (e) => this.setPending('to', e.target.value) })))))));
|
|
4708
|
-
}
|
|
4709
|
-
if (dataType === 'DATETIME') {
|
|
4710
|
-
const dtOp = pf.operator;
|
|
4711
|
-
const noInput = dtOp === 'isEmpty' || dtOp === 'isNotEmpty';
|
|
4712
|
-
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4713
|
-
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4714
|
-
const val = e.target.value;
|
|
4715
|
-
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4716
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined });
|
|
4717
|
-
}
|
|
4718
|
-
else {
|
|
4719
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined });
|
|
4720
|
-
}
|
|
4721
|
-
} }, h("option", { value: "", selected: !noInput }, t('filter_has_value', this.locale)), h("option", { value: "isEmpty", selected: dtOp === 'isEmpty' }, t('filter_is_empty', this.locale)), h("option", { value: "isNotEmpty", selected: dtOp === 'isNotEmpty' }, t('filter_is_not_empty', this.locale))), !noInput && (h("div", { class: "mrd-table__filter-editor" }, h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `dt-${this.openFilterCol}`, checked: !rangeMode, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { from: undefined, to: undefined }); } }), t('filter_exact', this.locale)), h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `dt-${this.openFilterCol}`, checked: rangeMode, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { value: undefined, from: null, to: null }); } }), t('filter_range', this.locale))), !rangeMode ? (h("input", { type: "date", class: "mrd-table__filter-input", value: String((_f = pf.value) !== null && _f !== void 0 ? _f : ''), onInput: (e) => this.setPending('value', e.target.value) })) : (h("div", { class: "mrd-table__filter-range mrd-table__filter-range--stacked" }, h("label", { class: "mrd-table__filter-range-label" }, t('filter_from', this.locale)), h("input", { type: "date", class: "mrd-table__filter-input", value: pf.from != null ? String(pf.from) : '', onInput: (e) => this.setPending('from', e.target.value) }), h("label", { class: "mrd-table__filter-range-label" }, t('filter_to', this.locale)), h("input", { type: "date", class: "mrd-table__filter-input", value: pf.to != null ? String(pf.to) : '', onInput: (e) => this.setPending('to', e.target.value) })))))));
|
|
4722
|
-
}
|
|
4723
|
-
if (DATE_TYPES.has(dataType)) {
|
|
4724
|
-
const inputType = dataType === 'DATE' ? 'date' : 'time';
|
|
4725
|
-
const dtdOp = pf.operator;
|
|
4726
|
-
const noInput = dtdOp === 'isEmpty' || dtdOp === 'isNotEmpty';
|
|
4727
|
-
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4728
|
-
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4729
|
-
const val = e.target.value;
|
|
4730
|
-
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4731
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined });
|
|
4732
|
-
}
|
|
4733
|
-
else {
|
|
4734
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined });
|
|
4735
|
-
}
|
|
4736
|
-
} }, h("option", { value: "", selected: !noInput }, t('filter_has_value', this.locale)), h("option", { value: "isEmpty", selected: dtdOp === 'isEmpty' }, t('filter_is_empty', this.locale)), h("option", { value: "isNotEmpty", selected: dtdOp === 'isNotEmpty' }, t('filter_is_not_empty', this.locale))), !noInput && (h("div", { class: "mrd-table__filter-editor" }, h("div", { class: "mrd-table__filter-radio-group mrd-table__filter-radio-group--inline" }, h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `dt-${this.openFilterCol}`, checked: !rangeMode, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { from: undefined, to: undefined }); } }), t('filter_exact', this.locale)), h("label", { class: "mrd-table__filter-radio-label" }, h("input", { type: "radio", name: `dt-${this.openFilterCol}`, checked: rangeMode, onChange: () => { this.pendingFilter = Object.assign(Object.assign({}, pf), { value: undefined, from: null, to: null }); } }), t('filter_range', this.locale))), !rangeMode ? (h("input", { type: inputType, class: "mrd-table__filter-input", value: String((_g = pf.value) !== null && _g !== void 0 ? _g : ''), onInput: (e) => this.setPending('value', e.target.value) })) : (h("div", { class: "mrd-table__filter-range" }, h("input", { type: inputType, class: "mrd-table__filter-input", placeholder: t('filter_from', this.locale), value: pf.from != null ? String(pf.from) : '', onInput: (e) => this.setPending('from', e.target.value) }), h("input", { type: inputType, class: "mrd-table__filter-input", placeholder: t('filter_to', this.locale), value: pf.to != null ? String(pf.to) : '', onInput: (e) => this.setPending('to', e.target.value) })))))));
|
|
4737
|
-
}
|
|
4738
|
-
return null;
|
|
4739
|
-
}
|
|
4740
5026
|
renderFilterPopup() {
|
|
4741
|
-
var _a;
|
|
4742
5027
|
if (!this.openFilterCol || !this.pendingFilter)
|
|
4743
5028
|
return null;
|
|
4744
5029
|
const col = this.columns.find(c => this.colName(c) === this.openFilterCol);
|
|
4745
5030
|
if (!col)
|
|
4746
5031
|
return null;
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
5032
|
+
return (h(FilterPopup, { col: col, dataType: this.colDataType(col), openFilterCol: this.openFilterCol, pendingFilter: this.pendingFilter, popupPos: this.popupPos, sortField: this.sortField, sortDir: this.sortDir, locale: this.locale, cb: {
|
|
5033
|
+
onSetPending: (key, val) => this.setPending(key, val),
|
|
5034
|
+
onReplacePending: pf => (this.pendingFilter = pf),
|
|
5035
|
+
onToggleValue: (key, checked) => this.togglePendingValue(key, checked),
|
|
5036
|
+
onApplySort: dir => this.applySort(col, dir),
|
|
5037
|
+
onApply: () => this.applyFilter(),
|
|
5038
|
+
onClear: () => this.clearFilter(),
|
|
5039
|
+
onClose: () => this.closeFilterPopup(),
|
|
5040
|
+
} }));
|
|
4750
5041
|
}
|
|
4751
5042
|
// ── Render: footer ────────────────────────────────────────────────────────
|
|
4752
5043
|
renderFooter(rowCount, effectiveTotal, isTotalKnown = true) {
|
|
@@ -4771,54 +5062,11 @@ const MrdTable = class {
|
|
|
4771
5062
|
}
|
|
4772
5063
|
// ── Render: cell ──────────────────────────────────────────────────────────
|
|
4773
5064
|
renderCell(col, row) {
|
|
4774
|
-
|
|
4775
|
-
const numericTypes = new Set(['INTEGER', 'DECIMAL', 'PERCENTAGE', 'CURRENCY']);
|
|
4776
|
-
const dataType = (_a = col.dataType) !== null && _a !== void 0 ? _a : '';
|
|
4777
|
-
const isNumeric = col.type === 'FIELD' && numericTypes.has(dataType);
|
|
4778
|
-
const isFile = col.type === 'FIELD' && (dataType === 'FILE' || dataType === 'IMAGE');
|
|
4779
|
-
if (isFile) {
|
|
4780
|
-
const name = (_b = col.name) !== null && _b !== void 0 ? _b : '';
|
|
4781
|
-
const fileVal = row === null || row === void 0 ? void 0 : row[name];
|
|
4782
|
-
const href = fileVal === null || fileVal === void 0 ? void 0 : fileVal.href;
|
|
4783
|
-
const fileName = fileVal === null || fileVal === void 0 ? void 0 : fileVal.fileName;
|
|
4784
|
-
return (h("td", { class: "mrd-table__cell" }, href && fileName ? (h("button", { class: "mrd-table__file-btn", title: fileName, onClick: (e) => {
|
|
4785
|
-
e.stopPropagation();
|
|
4786
|
-
this.mrdDownload.emit({ href, fileName });
|
|
4787
|
-
} }, h("svg", { class: "mrd-table__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 7V3.5L18.5 9H13zm-3 8l-3-3 1.41-1.41L10 14.17l4.59-4.58L16 11l-6 6z" })), t('download', this.locale))) : ''));
|
|
4788
|
-
}
|
|
4789
|
-
if (dataType === 'JSON') {
|
|
4790
|
-
const name = (_c = col.name) !== null && _c !== void 0 ? _c : '';
|
|
4791
|
-
const rawValue = name ? row === null || row === void 0 ? void 0 : row[name] : undefined;
|
|
4792
|
-
if (rawValue == null || rawValue === '')
|
|
4793
|
-
return h("td", { class: "mrd-table__cell" });
|
|
4794
|
-
const compactHtml = CellRenderer.formatJson(rawValue, true);
|
|
4795
|
-
const prettyHtml = CellRenderer.formatJson(rawValue, false);
|
|
4796
|
-
return (h("td", { class: "mrd-table__cell" }, h("span", { class: "mrd-table__json-preview", innerHTML: compactHtml }), h("button", { class: "mrd-table__textblock-btn", onClick: (e) => { e.stopPropagation(); this.openJsonModal(prettyHtml); }, "aria-label": t('textblock_show_more', this.locale) }, "\u22EF")));
|
|
4797
|
-
}
|
|
4798
|
-
const TEXTBLOCK_MAX = 200;
|
|
4799
|
-
if (dataType === 'TEXTBLOCK') {
|
|
4800
|
-
const full = CellRenderer.render(col, row, this.locale);
|
|
4801
|
-
if (full.length <= TEXTBLOCK_MAX) {
|
|
4802
|
-
return h("td", { class: "mrd-table__cell" }, full);
|
|
4803
|
-
}
|
|
4804
|
-
const preview = full.slice(0, TEXTBLOCK_MAX) + '…';
|
|
4805
|
-
return (h("td", { class: "mrd-table__cell" }, preview, h("button", { class: "mrd-table__textblock-btn", onClick: (e) => { e.stopPropagation(); this.openTextblockModal(full); }, "aria-label": t('textblock_show_more', this.locale) }, "\u22EF")));
|
|
4806
|
-
}
|
|
4807
|
-
const value = CellRenderer.render(col, row, this.locale);
|
|
4808
|
-
return (h("td", { class: `mrd-table__cell${isNumeric ? ' mrd-table__cell--numeric' : ''}` }, value));
|
|
5065
|
+
return (h(TableCell, { col: col, row: row, locale: this.locale, onDownload: detail => this.mrdDownload.emit(detail), onOpenTextblock: full => this.openTextblockModal(full), onOpenJson: html => this.openJsonModal(html) }));
|
|
4809
5066
|
}
|
|
4810
5067
|
// ── Render: totals row ────────────────────────────────────────────────────
|
|
4811
5068
|
renderTotalsRow() {
|
|
4812
|
-
|
|
4813
|
-
return null;
|
|
4814
|
-
if (!this.columns.some(c => c.type === 'FIELD' && c.aggregate))
|
|
4815
|
-
return null;
|
|
4816
|
-
return (h("tfoot", null, h("tr", { class: "mrd-table__totals-row" }, this.columns.map(col => {
|
|
4817
|
-
var _a;
|
|
4818
|
-
const val = this.renderAggregationValue(col);
|
|
4819
|
-
const isNumeric = col.type === 'FIELD' && NUMERIC_TYPES.has((_a = col.dataType) !== null && _a !== void 0 ? _a : '');
|
|
4820
|
-
return (h("td", { class: `mrd-table__totals-cell${isNumeric ? ' mrd-table__totals-cell--numeric' : ''}` }, val));
|
|
4821
|
-
}))));
|
|
5069
|
+
return h(TotalsRow, { columns: this.columns, aggregations: this.aggregations, locale: this.locale });
|
|
4822
5070
|
}
|
|
4823
5071
|
// ── Render ─────────────────────────────────────────────────────────────────
|
|
4824
5072
|
render() {
|
|
@@ -4838,7 +5086,7 @@ const MrdTable = class {
|
|
|
4838
5086
|
isFiltered ? 'mrd-table__header--filtered' : '',
|
|
4839
5087
|
this.filterMode ? 'mrd-table__header--sortable' : '',
|
|
4840
5088
|
].filter(Boolean).join(' ');
|
|
4841
|
-
return (h("th", { class: cls, onClick: this.filterMode ? (e) => this.handleFilterOpen(col, e) : undefined }, h("span", { class: "mrd-table__header-label" }, (_a = col.label) !== null && _a !== void 0 ? _a : ''), isFiltered &&
|
|
5089
|
+
return (h("th", { class: cls, onClick: this.filterMode ? (e) => this.handleFilterOpen(col, e) : undefined }, h("span", { class: "mrd-table__header-label" }, (_a = col.label) !== null && _a !== void 0 ? _a : ''), isFiltered && h(FilterIcon, null)));
|
|
4842
5090
|
}))), h("tbody", null, (_b = this.rows) === null || _b === void 0 ? void 0 : _b.map((row, i) => (h("tr", { class: "mrd-table__row mrd-table__row--clickable", style: { background: i % 2 === 0 ? '' : 'var(--mrd-color-neutral-100)' }, onClick: () => this.mrdRowClick.emit(row) }, this.columns.map(col => this.renderCell(col, row)))))), this.renderTotalsRow()), (!this.rows || this.rows.length === 0) && (h("p", { class: "mrd-table__empty" }, t('no_results', this.locale)))), this.renderFooter((_c = this.rows) === null || _c === void 0 ? void 0 : _c.length), this.renderFilterPopup(), this.renderTextblockModal(), this.renderJsonModal()));
|
|
4843
5091
|
}
|
|
4844
5092
|
// ── Paginated / virtual-scroll mode ────────────────────────────────────
|
|
@@ -4846,12 +5094,7 @@ const MrdTable = class {
|
|
|
4846
5094
|
// if any loaded page is shorter than pageSize it is the last page,
|
|
4847
5095
|
// so the true total cannot exceed (pageNum * pageSize + pageRows.length).
|
|
4848
5096
|
// aggregationsTotal (from setAggregations) takes priority over the totalElements prop.
|
|
4849
|
-
|
|
4850
|
-
for (const [pageNum, pageRows] of this.loadedPages) {
|
|
4851
|
-
if (pageRows.length < this.pageSize) {
|
|
4852
|
-
effectiveTotal = Math.min(effectiveTotal, pageNum * this.pageSize + pageRows.length);
|
|
4853
|
-
}
|
|
4854
|
-
}
|
|
5097
|
+
const effectiveTotal = computeEffectiveTotal(this.loadedPages, this.pageSize, this.baseTotal);
|
|
4855
5098
|
// Clamp renderEnd to what we actually know exists (-1 when empty)
|
|
4856
5099
|
const clampedEnd = Math.min(this.renderEnd, effectiveTotal - 1);
|
|
4857
5100
|
const colCount = this.columns.length;
|
|
@@ -4864,7 +5107,13 @@ const MrdTable = class {
|
|
|
4864
5107
|
for (let i = this.renderStart; i <= clampedEnd; i++) {
|
|
4865
5108
|
const row = this.getRow(i);
|
|
4866
5109
|
if (row === null) {
|
|
4867
|
-
|
|
5110
|
+
const page = Math.floor(i / this.pageSize);
|
|
5111
|
+
if (this.failedPages.has(page)) {
|
|
5112
|
+
renderedRows.push(h("tr", { class: "mrd-table__row mrd-table__row--failed" }, h("td", { class: "mrd-table__cell--failed", colSpan: colCount }, h("button", { type: "button", class: "mrd-table__retry-button", onClick: () => this.retryPage(page) }, t('load_failed_retry', this.locale)))));
|
|
5113
|
+
}
|
|
5114
|
+
else {
|
|
5115
|
+
renderedRows.push(h("tr", { class: "mrd-table__row mrd-table__row--loading" }, h("td", { class: "mrd-table__cell--placeholder", colSpan: colCount }, h("span", { class: "mrd-table__placeholder-bar" }))));
|
|
5116
|
+
}
|
|
4868
5117
|
}
|
|
4869
5118
|
else {
|
|
4870
5119
|
renderedRows.push(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))));
|
|
@@ -4882,21 +5131,14 @@ const MrdTable = class {
|
|
|
4882
5131
|
isActive ? `mrd-table__header--sorted-${this.sortDir}` : '',
|
|
4883
5132
|
isFiltered ? 'mrd-table__header--filtered' : '',
|
|
4884
5133
|
].filter(Boolean).join(' ');
|
|
4885
|
-
return (h("th", { class: cls, style: this.colWidths[idx] ? { width: `${this.colWidths[idx]}px` } : undefined, onClick: isInteractive ? ((e) => this.filterMode ? this.handleFilterOpen(col, e) : this.handleSortClick(col)) : undefined }, h("span", { class: "mrd-table__header-label" }, (_a = col.label) !== null && _a !== void 0 ? _a : ''), isInteractive && isActive && (h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, this.sortDir === 'asc' ? '▲' : '▼')), isInteractive && !isActive && !this.filterMode && (h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, "\u21C5")), isInteractive && isFiltered &&
|
|
4886
|
-
}))), h("tbody", null, topSpacerHeight > 0 && (h("tr", { class: "mrd-table__spacer", style: { height: `${topSpacerHeight}px` } }, h("td", { colSpan: colCount }))), renderedRows, bottomSpacerHeight > 0 && (h("tr", { class: "mrd-table__spacer", style: { height: `${bottomSpacerHeight}px` } }, h("td", { colSpan: colCount })))), this.renderTotalsRow())), effectiveTotal === 0 && this.loadedPages.has(0) && (h("p", { class: "mrd-table__empty" }, t('no_results', this.locale))), effectiveTotal > 0 && this.renderFooter(undefined, effectiveTotal, this.isTotalKnown()), this.renderFilterPopup(), this.renderTextblockModal()));
|
|
4887
|
-
}
|
|
4888
|
-
renderFilterIcon() {
|
|
4889
|
-
return (h("span", { class: "mrd-table__filter-icon", "aria-hidden": "true" }, h("svg", { viewBox: "0 0 24 24", width: "14", height: "14", fill: "currentColor" }, h("path", { d: "M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" }))));
|
|
5134
|
+
return (h("th", { class: cls, style: this.colWidths[idx] ? { width: `${this.colWidths[idx]}px` } : undefined, onClick: isInteractive ? ((e) => this.filterMode ? this.handleFilterOpen(col, e) : this.handleSortClick(col)) : undefined }, h("span", { class: "mrd-table__header-label" }, (_a = col.label) !== null && _a !== void 0 ? _a : ''), isInteractive && isActive && (h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, this.sortDir === 'asc' ? '▲' : '▼')), isInteractive && !isActive && !this.filterMode && (h("span", { class: "mrd-table__sort-icon", "aria-hidden": "true" }, "\u21C5")), isInteractive && isFiltered && h(FilterIcon, null)));
|
|
5135
|
+
}))), h("tbody", null, topSpacerHeight > 0 && (h("tr", { class: "mrd-table__spacer", style: { height: `${topSpacerHeight}px` } }, h("td", { colSpan: colCount }))), renderedRows, bottomSpacerHeight > 0 && (h("tr", { class: "mrd-table__spacer", style: { height: `${bottomSpacerHeight}px` } }, h("td", { colSpan: colCount })))), this.renderTotalsRow())), effectiveTotal === 0 && this.loadedPages.has(0) && (h("p", { class: "mrd-table__empty" }, t('no_results', this.locale))), effectiveTotal > 0 && this.renderFooter(undefined, effectiveTotal, this.isTotalKnown()), this.renderFilterPopup(), this.renderTextblockModal(), this.renderJsonModal()));
|
|
4890
5136
|
}
|
|
4891
5137
|
renderTextblockModal() {
|
|
4892
|
-
|
|
4893
|
-
return null;
|
|
4894
|
-
return (h("div", { class: "mrd-table__modal-backdrop", onClick: () => this.closeTextblockModal(), role: "dialog", "aria-modal": "true" }, h("div", { class: "mrd-table__modal", onClick: (e) => e.stopPropagation() }, h("button", { class: "mrd-table__modal-close", onClick: () => this.closeTextblockModal(), "aria-label": t('close', this.locale) }, "\u2715"), h("p", { class: "mrd-table__modal-text" }, this.textblockModal))));
|
|
5138
|
+
return h(TextblockModal, { text: this.textblockModal, locale: this.locale, onClose: () => this.closeTextblockModal() });
|
|
4895
5139
|
}
|
|
4896
5140
|
renderJsonModal() {
|
|
4897
|
-
|
|
4898
|
-
return null;
|
|
4899
|
-
return (h("div", { class: "mrd-table__modal-backdrop", onClick: () => this.closeJsonModal(), role: "dialog", "aria-modal": "true" }, h("div", { class: "mrd-table__modal", onClick: (e) => e.stopPropagation() }, h("button", { class: "mrd-table__modal-close", onClick: () => this.closeJsonModal(), "aria-label": t('close', this.locale) }, "\u2715"), h("pre", { class: "mrd-table__modal-json", innerHTML: this.jsonModal }))));
|
|
5141
|
+
return h(JsonModal, { html: this.jsonModal, locale: this.locale, onClose: () => this.closeJsonModal() });
|
|
4900
5142
|
}
|
|
4901
5143
|
get el() { return getElement(this); }
|
|
4902
5144
|
static get watchers() { return {
|
|
@@ -4908,9 +5150,9 @@ const MrdTable = class {
|
|
|
4908
5150
|
}]
|
|
4909
5151
|
}; }
|
|
4910
5152
|
};
|
|
4911
|
-
MrdTable.style =
|
|
5153
|
+
MrdTable.style = mrdTableCss();
|
|
4912
5154
|
|
|
4913
|
-
const
|
|
5155
|
+
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)}`;
|
|
4914
5156
|
|
|
4915
5157
|
const MrdTextField = class {
|
|
4916
5158
|
constructor(hostRef) {
|
|
@@ -4931,23 +5173,17 @@ const MrdTextField = class {
|
|
|
4931
5173
|
};
|
|
4932
5174
|
this.handleBlur = (e) => {
|
|
4933
5175
|
const val = e.target.value;
|
|
4934
|
-
|
|
4935
|
-
this.error = t('required', this.locale);
|
|
4936
|
-
}
|
|
4937
|
-
else {
|
|
4938
|
-
this.error = '';
|
|
4939
|
-
}
|
|
5176
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
4940
5177
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
4941
5178
|
};
|
|
4942
5179
|
}
|
|
4943
5180
|
render() {
|
|
4944
|
-
|
|
4945
|
-
return (h(Host, { key: 'e9252b251faf98ab190e643b97c13fa32d12ef22' }, h("div", { key: '37f4259a111c293f2fe12f321f08c00c25e77feb', class: "mrd-text-field" }, this.label && (h("label", { key: 'c59e0346fb71a765ea38629b03c06341567ed210', class: `mrd-text-field__label${this.required ? ' mrd-text-field__label--required' : ''}` }, this.label)), 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 && h("span", { key: '037653857a372854a16b28ebf8994b23e3e0d696', class: "mrd-text-field__error" }, this.error))));
|
|
5181
|
+
return (h(Host, { key: '71de1ae949941820574fc2d45cac6cca8264d8f9' }, h("div", { key: 'a63d3dd0811e012ae3d5a9f02c1a2ad1fcc0af86', class: "mrd-text-field" }, h(FieldLabel, { key: '1a6db878b634364f47522209344540a9cdc20635', base: "mrd-text-field", label: this.label, required: this.required }), 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 }), h(FieldError, { key: '1530066fefbda722df0c37871978995a139fcef0', base: "mrd-text-field", error: this.error }))));
|
|
4946
5182
|
}
|
|
4947
5183
|
};
|
|
4948
|
-
MrdTextField.style =
|
|
5184
|
+
MrdTextField.style = mrdTextFieldCss();
|
|
4949
5185
|
|
|
4950
|
-
const
|
|
5186
|
+
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}`;
|
|
4951
5187
|
|
|
4952
5188
|
const MrdTextareaField = class {
|
|
4953
5189
|
constructor(hostRef) {
|
|
@@ -5000,12 +5236,7 @@ const MrdTextareaField = class {
|
|
|
5000
5236
|
var _a, _b;
|
|
5001
5237
|
if (!range) {
|
|
5002
5238
|
const html = (_b = (_a = this.editorEl.querySelector('.ql-editor')) === null || _a === void 0 ? void 0 : _a.innerHTML) !== null && _b !== void 0 ? _b : '';
|
|
5003
|
-
|
|
5004
|
-
this.error = t('required', this.locale);
|
|
5005
|
-
}
|
|
5006
|
-
else {
|
|
5007
|
-
this.error = '';
|
|
5008
|
-
}
|
|
5239
|
+
this.error = requiredError(html, this.required, this.locale);
|
|
5009
5240
|
this.mrdBlur.emit({ name: this.name, value: html });
|
|
5010
5241
|
}
|
|
5011
5242
|
});
|
|
@@ -5016,13 +5247,13 @@ const MrdTextareaField = class {
|
|
|
5016
5247
|
}
|
|
5017
5248
|
}
|
|
5018
5249
|
render() {
|
|
5019
|
-
return (h(Host, { key: '
|
|
5250
|
+
return (h(Host, { key: '464c1edde8447043d9352f1b5f9757bba97e9b17' }, h("div", { key: '8d06728214f54feeb1063700e5aaf7c439eb5473', class: "mrd-textarea-field" }, h(FieldLabel, { key: 'dbf93ecf41bd704706b49f8c455262798fbbe10b', base: "mrd-textarea-field", label: this.label, required: this.required }), h("div", { key: '9c39ccfa38ee01b880973966e910ee32aa60b144', class: controlClass('mrd-textarea-field', !!this.error, 'container') }, h("div", { key: '0217cd4350c1933018b2b8f489516b6d43a52538', class: "mrd-textarea-field__editor" })), h(FieldError, { key: '62d2a5db053ea6e4ec6868440f3ab31e1c05e633', base: "mrd-textarea-field", error: this.error }))));
|
|
5020
5251
|
}
|
|
5021
5252
|
get el() { return getElement(this); }
|
|
5022
5253
|
};
|
|
5023
|
-
MrdTextareaField.style =
|
|
5254
|
+
MrdTextareaField.style = mrdTextareaFieldCss();
|
|
5024
5255
|
|
|
5025
|
-
const
|
|
5256
|
+
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}`;
|
|
5026
5257
|
|
|
5027
5258
|
const MrdTimeField = class {
|
|
5028
5259
|
constructor(hostRef) {
|
|
@@ -5038,12 +5269,7 @@ const MrdTimeField = class {
|
|
|
5038
5269
|
this.error = '';
|
|
5039
5270
|
this.handleChange = (e) => {
|
|
5040
5271
|
const val = e.target.value;
|
|
5041
|
-
|
|
5042
|
-
this.error = t('required', this.locale);
|
|
5043
|
-
}
|
|
5044
|
-
else {
|
|
5045
|
-
this.error = '';
|
|
5046
|
-
}
|
|
5272
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
5047
5273
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
5048
5274
|
};
|
|
5049
5275
|
this.handleBlur = (e) => {
|
|
@@ -5052,10 +5278,9 @@ const MrdTimeField = class {
|
|
|
5052
5278
|
};
|
|
5053
5279
|
}
|
|
5054
5280
|
render() {
|
|
5055
|
-
|
|
5056
|
-
return (h(Host, { key: '579219a478e31325b5a676465807c1d936724a2b' }, h("div", { key: '51b25f6e083a29989505c0ad79edbcd3b0060736', class: "mrd-time-field" }, this.label && (h("label", { key: '67d98bebb8803deea2d2a4a63f36706789ccd8c7', class: `mrd-time-field__label${this.required ? ' mrd-time-field__label--required' : ''}` }, this.label)), 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 && h("span", { key: '0dbd168d14966dc56a77c97cd8fd8f9b208a4bf5', class: "mrd-time-field__error" }, this.error))));
|
|
5281
|
+
return (h(Host, { key: 'fc30bdeb7c8d37bebc67a768f48013602879fb3d' }, h("div", { key: '52f899a889376773c1948f0c116670684db25cf4', class: "mrd-time-field" }, h(FieldLabel, { key: '3aba58f122fa4bb9f0ba4ad0b56fc3b29f03d4a3', base: "mrd-time-field", label: this.label, required: this.required }), 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 }), h(FieldError, { key: '07ad4ccbc5188e129d8bd3085e856839ec6a81c9', base: "mrd-time-field", error: this.error }))));
|
|
5057
5282
|
}
|
|
5058
5283
|
};
|
|
5059
|
-
MrdTimeField.style =
|
|
5284
|
+
MrdTimeField.style = mrdTimeFieldCss();
|
|
5060
5285
|
|
|
5061
5286
|
export { MrdBooleanField as mrd_boolean_field, MrdCurrencyField as mrd_currency_field, MrdDateField as mrd_date_field, MrdDatetimeField as mrd_datetime_field, MrdDocumentContainer as mrd_document_container, MrdDocumentList as mrd_document_list, MrdDocumentView as mrd_document_view, MrdEmailField as mrd_email_field, MrdField as mrd_field, MrdFileField as mrd_file_field, MrdForm as mrd_form, MrdHyperlinkField as mrd_hyperlink_field, MrdImageField as mrd_image_field, MrdLayoutSection as mrd_layout_section, MrdListField as mrd_list_field, MrdLongtextField as mrd_longtext_field, MrdNumberField as mrd_number_field, MrdRelationField as mrd_relation_field, MrdSecretField as mrd_secret_field, MrdTable as mrd_table, MrdTextField as mrd_text_field, MrdTextareaField as mrd_textarea_field, MrdTimeField as mrd_time_field };
|