@mmlogic/components 0.3.10 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{index-BPj2cBXs.js → index-CAzwGt9u.js} +38 -0
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/mosterdcomponents.cjs.js +2 -2
- package/dist/cjs/mrd-boolean-field_23.cjs.entry.js +1280 -1073
- package/dist/collection/collection-manifest.json +23 -23
- package/dist/collection/components/{mrd-document-container/mrd-document-container.scss → documents/mrd-document-container/mrd-document-container.css} +3 -3
- package/dist/collection/components/{mrd-document-container → documents/mrd-document-container}/mrd-document-container.js +54 -8
- package/dist/collection/components/documents/mrd-document-list/folder-tree.js +109 -0
- package/dist/collection/components/{mrd-document-list/mrd-document-list.scss → documents/mrd-document-list/mrd-document-list.css} +17 -4
- package/dist/collection/components/{mrd-document-list → documents/mrd-document-list}/mrd-document-list.js +166 -237
- package/dist/collection/components/documents/mrd-document-list/tree-view.js +75 -0
- package/dist/collection/components/{mrd-document-view/mrd-document-view.scss → documents/mrd-document-view/mrd-document-view.css} +1 -1
- package/dist/collection/components/{mrd-document-view → documents/mrd-document-view}/mrd-document-view.js +4 -4
- package/dist/collection/components/fields/field-helpers.js +17 -0
- package/dist/collection/components/fields/file-upload-common.js +38 -0
- package/dist/collection/components/{mrd-boolean-field/mrd-boolean-field.scss → fields/mrd-boolean-field/mrd-boolean-field.css} +3 -3
- package/dist/collection/components/{mrd-boolean-field → fields/mrd-boolean-field}/mrd-boolean-field.js +1 -1
- package/dist/collection/components/{mrd-currency-field/mrd-currency-field.scss → fields/mrd-currency-field/mrd-currency-field.css} +11 -9
- package/dist/collection/components/{mrd-currency-field → fields/mrd-currency-field}/mrd-currency-field.js +7 -13
- package/dist/collection/components/{mrd-date-field/mrd-date-field.scss → fields/mrd-date-field/mrd-date-field.css} +8 -10
- package/dist/collection/components/{mrd-date-field → fields/mrd-date-field}/mrd-date-field.js +3 -10
- package/dist/collection/components/{mrd-datetime-field/mrd-datetime-field.scss → fields/mrd-datetime-field/mrd-datetime-field.css} +8 -10
- package/dist/collection/components/{mrd-datetime-field → fields/mrd-datetime-field}/mrd-datetime-field.js +3 -10
- package/dist/collection/components/{mrd-email-field/mrd-email-field.scss → fields/mrd-email-field/mrd-email-field.css} +2 -11
- package/dist/collection/components/{mrd-email-field → fields/mrd-email-field}/mrd-email-field.js +6 -13
- package/dist/collection/components/{mrd-file-field/mrd-file-field.scss → fields/mrd-file-field/mrd-file-field.css} +19 -24
- package/dist/collection/components/{mrd-file-field → fields/mrd-file-field}/mrd-file-field.js +13 -24
- package/dist/collection/components/{mrd-hyperlink-field/mrd-hyperlink-field.scss → fields/mrd-hyperlink-field/mrd-hyperlink-field.css} +7 -16
- package/dist/collection/components/{mrd-hyperlink-field → fields/mrd-hyperlink-field}/mrd-hyperlink-field.js +9 -15
- package/dist/collection/components/{mrd-image-field/mrd-image-field.scss → fields/mrd-image-field/mrd-image-field.css} +15 -24
- package/dist/collection/components/{mrd-image-field → fields/mrd-image-field}/mrd-image-field.js +13 -28
- package/dist/collection/components/{mrd-list-field/mrd-list-field.scss → fields/mrd-list-field/mrd-list-field.css} +18 -21
- package/dist/collection/components/{mrd-list-field → fields/mrd-list-field}/mrd-list-field.js +10 -25
- package/dist/collection/components/{mrd-longtext-field/mrd-longtext-field.scss → fields/mrd-longtext-field/mrd-longtext-field.css} +21 -18
- package/dist/collection/components/{mrd-longtext-field → fields/mrd-longtext-field}/mrd-longtext-field.js +3 -10
- package/dist/collection/components/{mrd-number-field/mrd-number-field.scss → fields/mrd-number-field/mrd-number-field.css} +9 -10
- package/dist/collection/components/{mrd-number-field → fields/mrd-number-field}/mrd-number-field.js +7 -6
- package/dist/collection/components/{mrd-relation-field/mrd-relation-field.scss → fields/mrd-relation-field/mrd-relation-field.css} +61 -59
- package/dist/collection/components/{mrd-relation-field → fields/mrd-relation-field}/mrd-relation-field.js +16 -26
- package/dist/collection/components/{mrd-secret-field/mrd-secret-field.scss → fields/mrd-secret-field/mrd-secret-field.css} +7 -10
- package/dist/collection/components/{mrd-secret-field → fields/mrd-secret-field}/mrd-secret-field.js +4 -11
- package/dist/collection/components/{mrd-text-field/mrd-text-field.scss → fields/mrd-text-field/mrd-text-field.css} +2 -11
- package/dist/collection/components/{mrd-text-field → fields/mrd-text-field}/mrd-text-field.js +3 -10
- package/dist/collection/components/{mrd-textarea-field/mrd-textarea-field.scss → fields/mrd-textarea-field/mrd-textarea-field.css} +7 -10
- package/dist/collection/components/{mrd-textarea-field → fields/mrd-textarea-field}/mrd-textarea-field.js +3 -9
- package/dist/collection/components/{mrd-time-field/mrd-time-field.scss → fields/mrd-time-field/mrd-time-field.css} +8 -10
- package/dist/collection/components/{mrd-time-field → fields/mrd-time-field}/mrd-time-field.js +3 -10
- package/dist/collection/components/{mrd-field/mrd-field.scss → form/mrd-field/mrd-field.css} +1 -1
- package/dist/collection/components/{mrd-field → form/mrd-field}/mrd-field.js +3 -3
- package/dist/collection/components/{mrd-form/mrd-form.scss → form/mrd-form/mrd-form.css} +1 -1
- package/dist/collection/components/{mrd-form → form/mrd-form}/mrd-form.js +5 -5
- package/dist/collection/components/layout/mrd-layout-section/field-value.js +111 -0
- package/dist/collection/components/layout/mrd-layout-section/layout-helpers.js +29 -0
- package/dist/collection/components/{mrd-layout-section/mrd-layout-section.scss → layout/mrd-layout-section/mrd-layout-section.css} +4 -4
- package/dist/collection/components/{mrd-layout-section → layout/mrd-layout-section}/mrd-layout-section.js +58 -133
- package/dist/collection/components/{mrd-table/mrd-table.scss → table/mrd-table/mrd-table.css} +11 -13
- package/dist/collection/components/{mrd-table → table/mrd-table}/mrd-table.js +111 -439
- package/dist/collection/components/table/mrd-table/table-filter-popup.js +85 -0
- package/dist/collection/components/table/mrd-table/table-parts.js +110 -0
- package/dist/collection/components/table/mrd-table/table-query.js +178 -0
- package/dist/collection/components/table/mrd-table/virtual-scroll.js +49 -0
- package/dist/collection/dev/app.js +19 -18
- package/dist/collection/dev/example-data.js +58 -43
- package/dist/collection/utils/i18n.js +10 -0
- package/dist/collection/utils/query-params.js +43 -0
- package/dist/components/field-helpers.js +1 -0
- package/dist/components/file-upload-common.js +1 -0
- package/dist/components/i18n.js +1 -1
- package/dist/components/mrd-boolean-field2.js +1 -1
- package/dist/components/mrd-currency-field2.js +1 -1
- package/dist/components/mrd-date-field2.js +1 -1
- package/dist/components/mrd-datetime-field2.js +1 -1
- package/dist/components/mrd-document-container2.js +1 -1
- package/dist/components/mrd-document-list2.js +1 -1
- package/dist/components/mrd-document-view2.js +1 -1
- package/dist/components/mrd-email-field2.js +1 -1
- package/dist/components/mrd-file-field2.js +1 -1
- package/dist/components/mrd-form.js +1 -1
- package/dist/components/mrd-hyperlink-field2.js +1 -1
- package/dist/components/mrd-image-field2.js +1 -1
- package/dist/components/mrd-layout-section.js +1 -1
- package/dist/components/mrd-list-field2.js +1 -1
- package/dist/components/mrd-longtext-field2.js +1 -1
- package/dist/components/mrd-number-field2.js +1 -1
- package/dist/components/mrd-relation-field2.js +1 -1
- package/dist/components/mrd-secret-field2.js +1 -1
- package/dist/components/mrd-table2.js +1 -1
- package/dist/components/mrd-text-field2.js +1 -1
- package/dist/components/mrd-textarea-field2.js +1 -1
- package/dist/components/mrd-time-field2.js +1 -1
- package/dist/components/query-params.js +1 -0
- package/dist/esm/{index-_tsCCkAi.js → index-DiSEJMA8.js} +38 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/mosterdcomponents.js +3 -3
- package/dist/esm/mrd-boolean-field_23.entry.js +1280 -1073
- package/dist/mosterdcomponents/mosterdcomponents.css +1 -1
- package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
- package/dist/mosterdcomponents/p-9b3c0917.entry.js +1 -0
- package/dist/mosterdcomponents/p-DiSEJMA8.js +2 -0
- package/dist/types/components/{mrd-document-container → documents/mrd-document-container}/mrd-document-container.d.ts +7 -2
- package/dist/types/components/documents/mrd-document-list/folder-tree.d.ts +66 -0
- package/dist/types/components/{mrd-document-list → documents/mrd-document-list}/mrd-document-list.d.ts +28 -38
- package/dist/types/components/documents/mrd-document-list/tree-view.d.ts +32 -0
- package/dist/types/components/{mrd-document-view → documents/mrd-document-view}/mrd-document-view.d.ts +2 -2
- package/dist/types/components/fields/field-helpers.d.ts +18 -0
- package/dist/types/components/fields/file-upload-common.d.ts +18 -0
- package/dist/types/components/{mrd-boolean-field → fields/mrd-boolean-field}/mrd-boolean-field.d.ts +1 -1
- package/dist/types/components/{mrd-currency-field → fields/mrd-currency-field}/mrd-currency-field.d.ts +2 -2
- package/dist/types/components/{mrd-date-field → fields/mrd-date-field}/mrd-date-field.d.ts +1 -1
- package/dist/types/components/{mrd-datetime-field → fields/mrd-datetime-field}/mrd-datetime-field.d.ts +1 -1
- package/dist/types/components/{mrd-email-field → fields/mrd-email-field}/mrd-email-field.d.ts +1 -1
- package/dist/types/components/{mrd-file-field → fields/mrd-file-field}/mrd-file-field.d.ts +2 -4
- package/dist/types/components/{mrd-hyperlink-field → fields/mrd-hyperlink-field}/mrd-hyperlink-field.d.ts +2 -2
- package/dist/types/components/{mrd-image-field → fields/mrd-image-field}/mrd-image-field.d.ts +2 -4
- package/dist/types/components/{mrd-list-field → fields/mrd-list-field}/mrd-list-field.d.ts +2 -2
- package/dist/types/components/{mrd-longtext-field → fields/mrd-longtext-field}/mrd-longtext-field.d.ts +1 -1
- package/dist/types/components/{mrd-number-field → fields/mrd-number-field}/mrd-number-field.d.ts +2 -2
- package/dist/types/components/{mrd-relation-field → fields/mrd-relation-field}/mrd-relation-field.d.ts +2 -2
- package/dist/types/components/{mrd-secret-field → fields/mrd-secret-field}/mrd-secret-field.d.ts +1 -1
- package/dist/types/components/{mrd-text-field → fields/mrd-text-field}/mrd-text-field.d.ts +1 -1
- package/dist/types/components/{mrd-textarea-field → fields/mrd-textarea-field}/mrd-textarea-field.d.ts +1 -1
- package/dist/types/components/{mrd-time-field → fields/mrd-time-field}/mrd-time-field.d.ts +1 -1
- package/dist/types/components/{mrd-field → form/mrd-field}/mrd-field.d.ts +2 -2
- package/dist/types/components/{mrd-form → form/mrd-form}/mrd-form.d.ts +2 -2
- package/dist/types/components/layout/mrd-layout-section/field-value.d.ts +22 -0
- package/dist/types/components/layout/mrd-layout-section/layout-helpers.d.ts +8 -0
- package/dist/types/components/{mrd-layout-section → layout/mrd-layout-section}/mrd-layout-section.d.ts +4 -8
- package/dist/types/components/{mrd-table → table/mrd-table}/mrd-table.d.ts +6 -13
- package/dist/types/components/table/mrd-table/table-filter-popup.d.ts +35 -0
- package/dist/types/components/table/mrd-table/table-parts.d.ts +61 -0
- package/dist/types/components/table/mrd-table/table-query.d.ts +50 -0
- package/dist/types/components/table/mrd-table/virtual-scroll.d.ts +26 -0
- package/dist/types/components.d.ts +36 -5
- package/dist/types/types/client-layout.d.ts +5 -0
- package/dist/types/utils/query-params.d.ts +14 -0
- package/package.json +7 -2
- package/dist/components/validation.js +0 -1
- package/dist/mosterdcomponents/cell-renderer-B-AJDBcj.js.map +0 -1
- package/dist/mosterdcomponents/client-layout-ChqRA3AF.js.map +0 -1
- package/dist/mosterdcomponents/format-BAfsQfy1.js.map +0 -1
- package/dist/mosterdcomponents/i18n-s1XrKcD2.js.map +0 -1
- package/dist/mosterdcomponents/index-DkY-NQj0.js.map +0 -1
- package/dist/mosterdcomponents/index-DwF_Sp__.js.map +0 -1
- package/dist/mosterdcomponents/index.esm.js.map +0 -1
- package/dist/mosterdcomponents/mosterdcomponents.esm.js.map +0 -1
- package/dist/mosterdcomponents/p-69452249.entry.js +0 -1
- package/dist/mosterdcomponents/p-_tsCCkAi.js +0 -2
- package/dist/mosterdcomponents/quill-C9pgw_k-.js.map +0 -1
- package/dist/mosterdcomponents/validation-Br9k2Ztw.js.map +0 -1
|
@@ -1,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,6 +120,7 @@ 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',
|
|
52
126
|
loading: 'Laden...',
|
|
@@ -103,6 +177,7 @@ const translations = {
|
|
|
103
177
|
folder_name_placeholder: 'Foldernaam',
|
|
104
178
|
folder_no_slash: "Een foldernaam mag geen '/' bevatten",
|
|
105
179
|
folder_duplicate: 'Er bestaat al een folder met deze naam',
|
|
180
|
+
doc_empty_drop: 'Nog geen documenten — sleep bestanden hierheen',
|
|
106
181
|
},
|
|
107
182
|
en: {
|
|
108
183
|
required: 'This field is required',
|
|
@@ -118,6 +193,7 @@ const translations = {
|
|
|
118
193
|
drop_file_here: 'Drop file here or',
|
|
119
194
|
browse: 'browse',
|
|
120
195
|
file_too_large: 'File is too large',
|
|
196
|
+
invalid_image: 'Please select an image file',
|
|
121
197
|
search_results: 'Search results',
|
|
122
198
|
no_results: 'No results found',
|
|
123
199
|
loading: 'Loading...',
|
|
@@ -174,6 +250,7 @@ const translations = {
|
|
|
174
250
|
folder_name_placeholder: 'Folder name',
|
|
175
251
|
folder_no_slash: "A folder name cannot contain '/'",
|
|
176
252
|
folder_duplicate: 'A folder with this name already exists',
|
|
253
|
+
doc_empty_drop: 'No documents yet — drop files here',
|
|
177
254
|
},
|
|
178
255
|
ar: {
|
|
179
256
|
required: 'هذا الحقل مطلوب',
|
|
@@ -189,6 +266,7 @@ const translations = {
|
|
|
189
266
|
drop_file_here: 'اسحب الملف هنا أو',
|
|
190
267
|
browse: 'تصفح',
|
|
191
268
|
file_too_large: 'الملف كبير جداً',
|
|
269
|
+
invalid_image: 'يرجى اختيار ملف صورة',
|
|
192
270
|
search_results: 'نتائج البحث',
|
|
193
271
|
no_results: 'لم يتم العثور على نتائج',
|
|
194
272
|
loading: 'جار التحميل...',
|
|
@@ -255,6 +333,7 @@ const translations = {
|
|
|
255
333
|
drop_file_here: 'Déposez le fichier ici ou',
|
|
256
334
|
browse: 'parcourir',
|
|
257
335
|
file_too_large: 'Le fichier est trop volumineux',
|
|
336
|
+
invalid_image: 'Veuillez sélectionner un fichier image',
|
|
258
337
|
search_results: 'Résultats de recherche',
|
|
259
338
|
no_results: 'Aucun résultat trouvé',
|
|
260
339
|
loading: 'Chargement...',
|
|
@@ -321,6 +400,7 @@ const translations = {
|
|
|
321
400
|
drop_file_here: 'Datei hier ablegen oder',
|
|
322
401
|
browse: 'durchsuchen',
|
|
323
402
|
file_too_large: 'Datei ist zu groß',
|
|
403
|
+
invalid_image: 'Bitte eine Bilddatei auswählen',
|
|
324
404
|
search_results: 'Suchergebnisse',
|
|
325
405
|
no_results: 'Keine Ergebnisse gefunden',
|
|
326
406
|
loading: 'Laden...',
|
|
@@ -387,6 +467,7 @@ const translations = {
|
|
|
387
467
|
drop_file_here: 'Suelte el archivo aquí o',
|
|
388
468
|
browse: 'explorar',
|
|
389
469
|
file_too_large: 'El archivo es demasiado grande',
|
|
470
|
+
invalid_image: 'Seleccione un archivo de imagen',
|
|
390
471
|
search_results: 'Resultados de búsqueda',
|
|
391
472
|
no_results: 'No se encontraron resultados',
|
|
392
473
|
loading: 'Cargando...',
|
|
@@ -453,6 +534,7 @@ const translations = {
|
|
|
453
534
|
drop_file_here: 'Trascina il file qui o',
|
|
454
535
|
browse: 'sfoglia',
|
|
455
536
|
file_too_large: 'Il file è troppo grande',
|
|
537
|
+
invalid_image: 'Seleziona un file immagine',
|
|
456
538
|
search_results: 'Risultati della ricerca',
|
|
457
539
|
no_results: 'Nessun risultato trovato',
|
|
458
540
|
loading: 'Caricamento...',
|
|
@@ -519,6 +601,7 @@ const translations = {
|
|
|
519
601
|
drop_file_here: 'Перетягніть файл сюди або',
|
|
520
602
|
browse: 'огляд',
|
|
521
603
|
file_too_large: 'Файл занадто великий',
|
|
604
|
+
invalid_image: 'Будь ласка, виберіть файл зображення',
|
|
522
605
|
search_results: 'Результати пошуку',
|
|
523
606
|
no_results: 'Результатів не знайдено',
|
|
524
607
|
loading: 'Завантаження...',
|
|
@@ -629,80 +712,22 @@ function validateNumber(value, dataType) {
|
|
|
629
712
|
return true;
|
|
630
713
|
}
|
|
631
714
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
715
|
+
/**
|
|
716
|
+
* Shared building blocks for the leaf field components.
|
|
717
|
+
* `base` is the BEM block name, e.g. 'mrd-text-field'.
|
|
718
|
+
*/
|
|
719
|
+
const FieldLabel = ({ base, label, required }) => label ? h("label", { class: `${base}__label${required ? ` ${base}__label--required` : ''}` }, label) : null;
|
|
720
|
+
const FieldError = ({ base, error }) => error ? h("span", { class: `${base}__error` }, error) : null;
|
|
721
|
+
/** Class string for the form control, with the --error modifier when applicable. */
|
|
722
|
+
function controlClass(base, hasError, element = 'input') {
|
|
723
|
+
return `${base}__${element}${hasError ? ` ${base}__${element}--error` : ''}`;
|
|
636
724
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
return new Intl.NumberFormat(locale, {
|
|
641
|
-
style: 'currency',
|
|
642
|
-
currency,
|
|
643
|
-
minimumFractionDigits: 2,
|
|
644
|
-
maximumFractionDigits: 2,
|
|
645
|
-
}).format(amount);
|
|
646
|
-
}
|
|
647
|
-
function formatPercentage(value, locale, decimalPrecision = 2) {
|
|
648
|
-
if (value === null || value === undefined || isNaN(value))
|
|
649
|
-
return '';
|
|
650
|
-
return new Intl.NumberFormat(locale, {
|
|
651
|
-
style: 'percent',
|
|
652
|
-
minimumFractionDigits: decimalPrecision,
|
|
653
|
-
maximumFractionDigits: decimalPrecision,
|
|
654
|
-
}).format(value);
|
|
655
|
-
}
|
|
656
|
-
function formatDate(value, locale) {
|
|
657
|
-
if (!value)
|
|
658
|
-
return '';
|
|
659
|
-
const date = typeof value === 'string' ? new Date(value) : value;
|
|
660
|
-
if (isNaN(date.getTime()))
|
|
661
|
-
return '';
|
|
662
|
-
return new Intl.DateTimeFormat(locale, { year: 'numeric', month: '2-digit', day: '2-digit' }).format(date);
|
|
663
|
-
}
|
|
664
|
-
function formatDateTime(value, locale) {
|
|
665
|
-
if (!value)
|
|
666
|
-
return '';
|
|
667
|
-
const date = typeof value === 'string' ? new Date(value) : value;
|
|
668
|
-
if (isNaN(date.getTime()))
|
|
669
|
-
return '';
|
|
670
|
-
return new Intl.DateTimeFormat(locale, {
|
|
671
|
-
year: 'numeric',
|
|
672
|
-
month: '2-digit',
|
|
673
|
-
day: '2-digit',
|
|
674
|
-
hour: '2-digit',
|
|
675
|
-
minute: '2-digit',
|
|
676
|
-
}).format(date);
|
|
677
|
-
}
|
|
678
|
-
function formatTime(value, locale) {
|
|
679
|
-
if (!value)
|
|
680
|
-
return '';
|
|
681
|
-
// value is HH:MM or HH:MM:SS
|
|
682
|
-
const [hours, minutes] = value.split(':').map(Number);
|
|
683
|
-
const date = new Date();
|
|
684
|
-
date.setHours(hours, minutes, 0, 0);
|
|
685
|
-
return new Intl.DateTimeFormat(locale, { hour: '2-digit', minute: '2-digit' }).format(date);
|
|
686
|
-
}
|
|
687
|
-
function parseLocalizedNumber(str, locale) {
|
|
688
|
-
var _a, _b, _c, _d;
|
|
689
|
-
if (!str || !str.trim())
|
|
690
|
-
return null;
|
|
691
|
-
// Detect decimal and thousands separators from the locale
|
|
692
|
-
const parts = new Intl.NumberFormat(locale).formatToParts(1234567.89);
|
|
693
|
-
const groupSep = (_b = (_a = parts.find((p) => p.type === 'group')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : ',';
|
|
694
|
-
const decimalSep = (_d = (_c = parts.find((p) => p.type === 'decimal')) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : '.';
|
|
695
|
-
// Remove group separators, replace decimal separator with '.'
|
|
696
|
-
const normalized = str
|
|
697
|
-
.replace(new RegExp(`\\${groupSep}`, 'g'), '')
|
|
698
|
-
.replace(new RegExp(`\\${decimalSep}`), '.')
|
|
699
|
-
.replace('%', '')
|
|
700
|
-
.trim();
|
|
701
|
-
const parsed = parseFloat(normalized);
|
|
702
|
-
return isNaN(parsed) ? null : parsed;
|
|
725
|
+
/** Returns the localised required-error, or '' when the value passes. */
|
|
726
|
+
function requiredError(value, required, locale) {
|
|
727
|
+
return required && !validateRequired(value) ? t('required', locale) : '';
|
|
703
728
|
}
|
|
704
729
|
|
|
705
|
-
const
|
|
730
|
+
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)}`;
|
|
706
731
|
|
|
707
732
|
const COMMON_CURRENCIES = [
|
|
708
733
|
'EUR', 'USD', 'GBP', 'CHF', 'JPY', 'CNY', 'AUD', 'CAD',
|
|
@@ -729,12 +754,7 @@ const MrdCurrencyField = class {
|
|
|
729
754
|
this.handleAmountBlur = (e) => {
|
|
730
755
|
const raw = e.target.value;
|
|
731
756
|
const parsed = parseLocalizedNumber(raw, this.locale);
|
|
732
|
-
|
|
733
|
-
this.error = t('required', this.locale);
|
|
734
|
-
}
|
|
735
|
-
else {
|
|
736
|
-
this.error = '';
|
|
737
|
-
}
|
|
757
|
+
this.error = requiredError(raw, this.required, this.locale);
|
|
738
758
|
const val = { amount: parsed, currency: this.currency };
|
|
739
759
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
740
760
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
@@ -753,12 +773,12 @@ const MrdCurrencyField = class {
|
|
|
753
773
|
}
|
|
754
774
|
render() {
|
|
755
775
|
const hasError = !!this.error;
|
|
756
|
-
return (h(Host, { key: '
|
|
776
|
+
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 }))));
|
|
757
777
|
}
|
|
758
778
|
};
|
|
759
|
-
MrdCurrencyField.style =
|
|
779
|
+
MrdCurrencyField.style = mrdCurrencyFieldCss();
|
|
760
780
|
|
|
761
|
-
const
|
|
781
|
+
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}`;
|
|
762
782
|
|
|
763
783
|
const MrdDateField = class {
|
|
764
784
|
constructor(hostRef) {
|
|
@@ -774,12 +794,7 @@ const MrdDateField = class {
|
|
|
774
794
|
this.error = '';
|
|
775
795
|
this.handleChange = (e) => {
|
|
776
796
|
const val = e.target.value;
|
|
777
|
-
|
|
778
|
-
this.error = t('required', this.locale);
|
|
779
|
-
}
|
|
780
|
-
else {
|
|
781
|
-
this.error = '';
|
|
782
|
-
}
|
|
797
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
783
798
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
784
799
|
};
|
|
785
800
|
this.handleBlur = (e) => {
|
|
@@ -788,13 +803,12 @@ const MrdDateField = class {
|
|
|
788
803
|
};
|
|
789
804
|
}
|
|
790
805
|
render() {
|
|
791
|
-
|
|
792
|
-
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))));
|
|
806
|
+
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 }))));
|
|
793
807
|
}
|
|
794
808
|
};
|
|
795
|
-
MrdDateField.style =
|
|
809
|
+
MrdDateField.style = mrdDateFieldCss();
|
|
796
810
|
|
|
797
|
-
const
|
|
811
|
+
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}`;
|
|
798
812
|
|
|
799
813
|
const MrdDatetimeField = class {
|
|
800
814
|
constructor(hostRef) {
|
|
@@ -812,12 +826,7 @@ const MrdDatetimeField = class {
|
|
|
812
826
|
this.handleChange = (e) => {
|
|
813
827
|
const localVal = e.target.value;
|
|
814
828
|
this.localValue = localVal;
|
|
815
|
-
|
|
816
|
-
this.error = t('required', this.locale);
|
|
817
|
-
}
|
|
818
|
-
else {
|
|
819
|
-
this.error = '';
|
|
820
|
-
}
|
|
829
|
+
this.error = requiredError(localVal, this.required, this.locale);
|
|
821
830
|
this.mrdChange.emit({ name: this.name, value: this.localToUtc(localVal) });
|
|
822
831
|
};
|
|
823
832
|
this.handleBlur = (e) => {
|
|
@@ -851,8 +860,7 @@ const MrdDatetimeField = class {
|
|
|
851
860
|
return d.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
852
861
|
}
|
|
853
862
|
render() {
|
|
854
|
-
|
|
855
|
-
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))));
|
|
863
|
+
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 }))));
|
|
856
864
|
}
|
|
857
865
|
static get watchers() { return {
|
|
858
866
|
"value": [{
|
|
@@ -860,9 +868,9 @@ const MrdDatetimeField = class {
|
|
|
860
868
|
}]
|
|
861
869
|
}; }
|
|
862
870
|
};
|
|
863
|
-
MrdDatetimeField.style =
|
|
871
|
+
MrdDatetimeField.style = mrdDatetimeFieldCss();
|
|
864
872
|
|
|
865
|
-
const
|
|
873
|
+
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}`;
|
|
866
874
|
|
|
867
875
|
const MrdDocumentContainer = class {
|
|
868
876
|
constructor(hostRef) {
|
|
@@ -879,8 +887,13 @@ const MrdDocumentContainer = class {
|
|
|
879
887
|
this.item = null;
|
|
880
888
|
/** Parent record id — required for RELATED_VIEW path building. */
|
|
881
889
|
this.parentId = '';
|
|
890
|
+
/** Canonical parent href, forwarded to the folder tree for single-container seeding. */
|
|
891
|
+
this.containerHref = '';
|
|
882
892
|
/** Lookup key used for the embedded `data-doclist` / `data-view` attributes. */
|
|
883
893
|
this.viewKey = '';
|
|
894
|
+
/** Fixed height (px) of the scrolling folder-tree body — the toolbar stays put
|
|
895
|
+
* on top, Finder-style. The table manages its own height. */
|
|
896
|
+
this.height = 460;
|
|
884
897
|
this.locale = navigator.language;
|
|
885
898
|
/** Active body: folder tree or flat table. */
|
|
886
899
|
this.mode = 'tree';
|
|
@@ -889,8 +902,8 @@ const MrdDocumentContainer = class {
|
|
|
889
902
|
/** Whether the currently mounted table has been init()'d. Reset on every mode switch. */
|
|
890
903
|
this.tableInited = false;
|
|
891
904
|
this.createFolder = () => {
|
|
892
|
-
var _a
|
|
893
|
-
(
|
|
905
|
+
var _a;
|
|
906
|
+
(_a = this.listEl) === null || _a === void 0 ? void 0 : _a.createFolder();
|
|
894
907
|
};
|
|
895
908
|
}
|
|
896
909
|
/** The embedded table does not self-load: like every mrd-table it waits for the
|
|
@@ -902,7 +915,7 @@ const MrdDocumentContainer = class {
|
|
|
902
915
|
if (this.mode === 'list' && this.tableEl && !this.tableInited) {
|
|
903
916
|
this.tableInited = true;
|
|
904
917
|
const table = this.tableEl;
|
|
905
|
-
Promise.resolve((_a = table.componentOnReady) === null || _a === void 0 ? void 0 : _a.call(table)).then(() =>
|
|
918
|
+
Promise.resolve((_a = table.componentOnReady) === null || _a === void 0 ? void 0 : _a.call(table)).then(() => table.init());
|
|
906
919
|
}
|
|
907
920
|
}
|
|
908
921
|
setMode(mode) {
|
|
@@ -920,7 +933,7 @@ const MrdDocumentContainer = class {
|
|
|
920
933
|
}
|
|
921
934
|
// ── Bodies ───────────────────────────────────────────────────────────────
|
|
922
935
|
renderTree() {
|
|
923
|
-
return (h("mrd-document-list", { "data-doclist": this.viewKey, ref: el => (this.listEl = el), item: this.item, archetype: this.archetype, parentId: this.parentId, locale: this.locale, onMrdLoadDistinct: (e) => {
|
|
936
|
+
return (h("mrd-document-list", { "data-doclist": this.viewKey, ref: el => (this.listEl = el), item: this.item, archetype: this.archetype, parentId: this.parentId, containerHref: this.containerHref, locale: this.locale, onMrdLoadDistinct: (e) => {
|
|
924
937
|
e.stopPropagation();
|
|
925
938
|
this.mrdLoadDistinct.emit(e.detail);
|
|
926
939
|
}, onMrdLoadPage: (e) => {
|
|
@@ -961,13 +974,241 @@ const MrdDocumentContainer = class {
|
|
|
961
974
|
} }));
|
|
962
975
|
}
|
|
963
976
|
render() {
|
|
964
|
-
|
|
977
|
+
const treeMode = this.mode === 'tree';
|
|
978
|
+
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())));
|
|
965
979
|
}
|
|
966
980
|
get el() { return getElement(this); }
|
|
967
981
|
};
|
|
968
|
-
MrdDocumentContainer.style =
|
|
982
|
+
MrdDocumentContainer.style = mrdDocumentContainerCss();
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* Shared path/query-param conventions for list requests,
|
|
986
|
+
* used by mrd-table and mrd-document-list.
|
|
987
|
+
*/
|
|
988
|
+
/** Applies the view-level static filters to `params` using the API operator conventions. */
|
|
989
|
+
function applyViewFilters(params, filters) {
|
|
990
|
+
var _a, _b, _c;
|
|
991
|
+
for (const f of filters !== null && filters !== void 0 ? filters : []) {
|
|
992
|
+
if (!f.name)
|
|
993
|
+
continue;
|
|
994
|
+
if (f.operator === 'EMPTY') {
|
|
995
|
+
params.set(f.name, '');
|
|
996
|
+
continue;
|
|
997
|
+
}
|
|
998
|
+
if (f.operator === 'NOT_EMPTY') {
|
|
999
|
+
params.set(f.name + '_notempty', 'true');
|
|
1000
|
+
continue;
|
|
1001
|
+
}
|
|
1002
|
+
if (f.operator === 'STARTS_WITH') {
|
|
1003
|
+
params.set(f.name + '_startswith', String((_a = f.value) !== null && _a !== void 0 ? _a : ''));
|
|
1004
|
+
continue;
|
|
1005
|
+
}
|
|
1006
|
+
if (f.operator === 'FROM') {
|
|
1007
|
+
params.set(f.name + '_from', String((_b = f.value) !== null && _b !== void 0 ? _b : ''));
|
|
1008
|
+
continue;
|
|
1009
|
+
}
|
|
1010
|
+
if (f.operator === 'TO') {
|
|
1011
|
+
params.set(f.name + '_to', String((_c = f.value) !== null && _c !== void 0 ? _c : ''));
|
|
1012
|
+
continue;
|
|
1013
|
+
}
|
|
1014
|
+
if (f.value != null) {
|
|
1015
|
+
params.set(f.name, String(f.value));
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
/** VIEW: `/{dataClass}`; RELATED_VIEW: `/{fromClass}/{parentId}/{dataClass}`. */
|
|
1020
|
+
function buildListPath(opts) {
|
|
1021
|
+
var _a, _b, _c;
|
|
1022
|
+
if (opts.isRelatedView) {
|
|
1023
|
+
return `/${(_a = opts.fromClass) !== null && _a !== void 0 ? _a : ''}/${opts.parentId}/${(_b = opts.dataClass) !== null && _b !== void 0 ? _b : ''}`;
|
|
1024
|
+
}
|
|
1025
|
+
return `/${(_c = opts.dataClass) !== null && _c !== void 0 ? _c : ''}`;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
/**
|
|
1029
|
+
* Tree model and pure tree logic for mrd-document-list.
|
|
1030
|
+
* Nodes are mutated in place; the component triggers re-renders via bump().
|
|
1031
|
+
*/
|
|
1032
|
+
/** Normalise a folder path: null/""/"/" → root ([]); else split on "/" dropping empties. */
|
|
1033
|
+
function splitFolder(path) {
|
|
1034
|
+
if (path == null)
|
|
1035
|
+
return [];
|
|
1036
|
+
const s = String(path).trim();
|
|
1037
|
+
if (s === '' || s === '/')
|
|
1038
|
+
return [];
|
|
1039
|
+
return s.split('/').map(x => x.trim()).filter(Boolean);
|
|
1040
|
+
}
|
|
1041
|
+
function makeContainerNode(href, label, count) {
|
|
1042
|
+
return {
|
|
1043
|
+
id: 'c:' + href, kind: 'container', label, href,
|
|
1044
|
+
hasDocs: false, docCount: 0, totalCount: count, children: [],
|
|
1045
|
+
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
function makeFolderNode(id, label, containerId) {
|
|
1049
|
+
return {
|
|
1050
|
+
id, kind: 'folder', label, containerId,
|
|
1051
|
+
hasDocs: false, docCount: 0, totalCount: 0, children: [],
|
|
1052
|
+
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1053
|
+
};
|
|
1054
|
+
}
|
|
1055
|
+
/** Recompute totalCount over the subtree; returns the node's aggregate. */
|
|
1056
|
+
function computeTotals(node) {
|
|
1057
|
+
let total = node.docCount;
|
|
1058
|
+
for (const c of node.children)
|
|
1059
|
+
total += computeTotals(c);
|
|
1060
|
+
node.totalCount = total;
|
|
1061
|
+
return total;
|
|
1062
|
+
}
|
|
1063
|
+
/** Folder path segments of a node relative to its container (derived from its id). */
|
|
1064
|
+
function segmentsOf(node, container) {
|
|
1065
|
+
if (node.kind === 'container')
|
|
1066
|
+
return [];
|
|
1067
|
+
const prefix = container.id + '/';
|
|
1068
|
+
const rest = node.id.startsWith(prefix) ? node.id.slice(prefix.length) : '';
|
|
1069
|
+
return rest ? rest.split('/') : [];
|
|
1070
|
+
}
|
|
1071
|
+
/** Folder string a node represents: the raw distinct value when it holds
|
|
1072
|
+
* documents, else derived from its path segments; null for a container root. */
|
|
1073
|
+
function folderStringOf(node, container) {
|
|
1074
|
+
if (node.kind === 'container')
|
|
1075
|
+
return null;
|
|
1076
|
+
if (node.fullPath != null && node.fullPath !== '')
|
|
1077
|
+
return node.fullPath;
|
|
1078
|
+
const segs = segmentsOf(node, container);
|
|
1079
|
+
return segs.length ? '/' + segs.join('/') : null;
|
|
1080
|
+
}
|
|
1081
|
+
/** Strip a single trailing extension for the document title. */
|
|
1082
|
+
function stripExtension(name) {
|
|
1083
|
+
return name.replace(/\.[^./\\]+$/, '');
|
|
1084
|
+
}
|
|
1085
|
+
/** Rebuild a container's folder subtree from the /distinct folder strings.
|
|
1086
|
+
* New nodes are registered in `nodeIndex`; the container is mutated in place. */
|
|
1087
|
+
function applyFolderDistinct(container, values, nodeIndex) {
|
|
1088
|
+
container.children = [];
|
|
1089
|
+
container.hasDocs = false;
|
|
1090
|
+
container.docCount = 0;
|
|
1091
|
+
for (const v of values) {
|
|
1092
|
+
const raw = typeof v.value === 'string' ? v.value : v.value == null ? '' : String(v.value);
|
|
1093
|
+
const segs = splitFolder(raw);
|
|
1094
|
+
if (segs.length === 0) {
|
|
1095
|
+
// Root documents — the container's own direct documents.
|
|
1096
|
+
container.hasDocs = true;
|
|
1097
|
+
container.docCount = v.count;
|
|
1098
|
+
container.fullPath = raw;
|
|
1099
|
+
continue;
|
|
1100
|
+
}
|
|
1101
|
+
let node = container;
|
|
1102
|
+
const acc = [];
|
|
1103
|
+
for (const seg of segs) {
|
|
1104
|
+
acc.push(seg);
|
|
1105
|
+
let child = node.children.find(c => c.label === seg);
|
|
1106
|
+
if (!child) {
|
|
1107
|
+
child = makeFolderNode(container.id + '/' + acc.join('/'), seg, container.id);
|
|
1108
|
+
node.children.push(child);
|
|
1109
|
+
nodeIndex.set(child.id, child);
|
|
1110
|
+
}
|
|
1111
|
+
node = child;
|
|
1112
|
+
}
|
|
1113
|
+
node.hasDocs = true;
|
|
1114
|
+
node.docCount = v.count;
|
|
1115
|
+
node.fullPath = raw;
|
|
1116
|
+
}
|
|
1117
|
+
computeTotals(container);
|
|
1118
|
+
container.foldersLoaded = true;
|
|
1119
|
+
container.loading = false;
|
|
1120
|
+
}
|
|
1121
|
+
/** Optimistic in-place tree update for a document moved between folders. */
|
|
1122
|
+
function applyDocMove(doc, fromNode, toNode, targetFolder) {
|
|
1123
|
+
fromNode.docs = fromNode.docs.filter(d => d !== doc);
|
|
1124
|
+
fromNode.docCount = Math.max(0, fromNode.docCount - 1);
|
|
1125
|
+
// A now-empty folder should stop showing an expand chevron (it disappears on
|
|
1126
|
+
// the next reload anyway, since it is derived from document folder strings).
|
|
1127
|
+
if (fromNode.docsLoaded)
|
|
1128
|
+
fromNode.hasDocs = fromNode.docs.length > 0;
|
|
1129
|
+
toNode.hasDocs = true;
|
|
1130
|
+
toNode.pending = false; // a pending folder is now materialised
|
|
1131
|
+
toNode.docCount += 1;
|
|
1132
|
+
if (toNode.kind === 'folder')
|
|
1133
|
+
toNode.fullPath = targetFolder !== null && targetFolder !== void 0 ? targetFolder : '';
|
|
1134
|
+
if (toNode.docsLoaded)
|
|
1135
|
+
toNode.docs = [...toNode.docs, doc];
|
|
1136
|
+
}
|
|
969
1137
|
|
|
970
|
-
|
|
1138
|
+
function chevron(open, leaf) {
|
|
1139
|
+
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" }))));
|
|
1140
|
+
}
|
|
1141
|
+
function dossierIcon() {
|
|
1142
|
+
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" })));
|
|
1143
|
+
}
|
|
1144
|
+
function folderIcon() {
|
|
1145
|
+
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" })));
|
|
1146
|
+
}
|
|
1147
|
+
function docIcon() {
|
|
1148
|
+
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" })));
|
|
1149
|
+
}
|
|
1150
|
+
function indent(depth) {
|
|
1151
|
+
return h("span", { class: "mrd-document-list__indent", style: { width: `${depth * 18}px` } });
|
|
1152
|
+
}
|
|
1153
|
+
function renderLoadingRow(ctx, depth) {
|
|
1154
|
+
return (h("div", { class: "mrd-document-list__loading", key: "loading" }, indent(depth), h("span", { class: "mrd-document-list__spinner" }), t('loading', ctx.locale)));
|
|
1155
|
+
}
|
|
1156
|
+
function renderUploadingRow(ctx, depth) {
|
|
1157
|
+
return (h("div", { class: "mrd-document-list__loading", key: "uploading" }, indent(depth), h("span", { class: "mrd-document-list__spinner" }), t('upload_file', ctx.locale)));
|
|
1158
|
+
}
|
|
1159
|
+
function renderDocRow(ctx, doc, node, container, depth) {
|
|
1160
|
+
var _a, _b, _c, _d, _e;
|
|
1161
|
+
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 : '';
|
|
1162
|
+
const dateRaw = ctx.dateField ? doc === null || doc === void 0 ? void 0 : doc[ctx.dateField] : undefined;
|
|
1163
|
+
const date = dateRaw ? formatDate(dateRaw, ctx.locale) : '';
|
|
1164
|
+
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)));
|
|
1165
|
+
}
|
|
1166
|
+
function renderFolderEditRow(ctx, node, depth) {
|
|
1167
|
+
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))));
|
|
1168
|
+
}
|
|
1169
|
+
function renderNodeChildren(ctx, container, node, depth) {
|
|
1170
|
+
const out = [];
|
|
1171
|
+
// Direct documents of this node (root docs live on the container node).
|
|
1172
|
+
if (node.hasDocs) {
|
|
1173
|
+
if (node.docsLoaded) {
|
|
1174
|
+
for (const doc of node.docs)
|
|
1175
|
+
out.push(renderDocRow(ctx, doc, node, container, depth));
|
|
1176
|
+
}
|
|
1177
|
+
else if (node.loading) {
|
|
1178
|
+
out.push(renderLoadingRow(ctx, depth));
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
// Child folders.
|
|
1182
|
+
for (const child of node.children) {
|
|
1183
|
+
out.push(renderFolderNode(ctx, container, child, depth));
|
|
1184
|
+
}
|
|
1185
|
+
// An uploading file dropped onto this node.
|
|
1186
|
+
if (node.id === ctx.uploadingNodeId)
|
|
1187
|
+
out.push(renderUploadingRow(ctx, depth));
|
|
1188
|
+
return out;
|
|
1189
|
+
}
|
|
1190
|
+
function renderFolderNode(ctx, container, node, depth) {
|
|
1191
|
+
if (node.editing)
|
|
1192
|
+
return renderFolderEditRow(ctx, node, depth);
|
|
1193
|
+
const leaf = node.children.length === 0 && !node.hasDocs;
|
|
1194
|
+
const selected = node.id === ctx.selectedId;
|
|
1195
|
+
const cls = 'mrd-document-list__row'
|
|
1196
|
+
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1197
|
+
+ (node.pending ? ' mrd-document-list__row--pending' : '')
|
|
1198
|
+
+ (node.id === ctx.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1199
|
+
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))));
|
|
1200
|
+
}
|
|
1201
|
+
function renderContainerNode(ctx, node, depth) {
|
|
1202
|
+
const selected = node.id === ctx.selectedId;
|
|
1203
|
+
const cls = 'mrd-document-list__row mrd-document-list__row--dossier'
|
|
1204
|
+
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1205
|
+
+ (node.id === ctx.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1206
|
+
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
|
|
1207
|
+
? renderLoadingRow(ctx, depth + 1)
|
|
1208
|
+
: renderNodeChildren(ctx, node, node, depth + 1)))));
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
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)}`;
|
|
971
1212
|
|
|
972
1213
|
const MrdDocumentList = class {
|
|
973
1214
|
constructor(hostRef) {
|
|
@@ -983,6 +1224,11 @@ const MrdDocumentList = class {
|
|
|
983
1224
|
this.item = null;
|
|
984
1225
|
/** Parent record id — required for RELATED_VIEW path building. */
|
|
985
1226
|
this.parentId = '';
|
|
1227
|
+
/** Canonical parent href (`/{base}/{tenant}/{fromClass}/{parentId}`) supplied by
|
|
1228
|
+
* the host. When the RELATED_VIEW's `inverseRelation` equals the archetype
|
|
1229
|
+
* `container` slot, this seeds a single container so an empty dossier still
|
|
1230
|
+
* accepts file drops and folder creation. */
|
|
1231
|
+
this.containerHref = '';
|
|
986
1232
|
this.locale = navigator.language;
|
|
987
1233
|
this.containers = [];
|
|
988
1234
|
this.rootLoading = true;
|
|
@@ -994,6 +1240,8 @@ const MrdDocumentList = class {
|
|
|
994
1240
|
this.dropTargetId = null;
|
|
995
1241
|
/** Node id showing an "uploading…" indicator while a dropped file is processed. */
|
|
996
1242
|
this.uploadingNodeId = null;
|
|
1243
|
+
/** Whether a drag is hovering the root drop-zone (single-container area highlight). */
|
|
1244
|
+
this.rootDropActive = false;
|
|
997
1245
|
this.nodeIndex = new Map();
|
|
998
1246
|
// ── New-folder editing state ───────────────────────────────────────────────
|
|
999
1247
|
/** The pending node whose inline name input is open (null = not creating). */
|
|
@@ -1027,7 +1275,7 @@ const MrdDocumentList = class {
|
|
|
1027
1275
|
return;
|
|
1028
1276
|
const { target, container } = resolved;
|
|
1029
1277
|
const tempId = `${container.id}/__new__${this.newFolderSeq++}`;
|
|
1030
|
-
const node =
|
|
1278
|
+
const node = makeFolderNode(tempId, '', container.id);
|
|
1031
1279
|
node.pending = true;
|
|
1032
1280
|
node.editing = true;
|
|
1033
1281
|
target.children = [...target.children, node];
|
|
@@ -1118,8 +1366,18 @@ const MrdDocumentList = class {
|
|
|
1118
1366
|
e.preventDefault();
|
|
1119
1367
|
if (e.dataTransfer)
|
|
1120
1368
|
e.dataTransfer.dropEffect = file ? 'copy' : 'move';
|
|
1369
|
+
if (!this.rootDropActive)
|
|
1370
|
+
this.rootDropActive = true;
|
|
1371
|
+
};
|
|
1372
|
+
this.onRootDragLeave = (e) => {
|
|
1373
|
+
const related = e.relatedTarget;
|
|
1374
|
+
if (related && this.el.contains(related))
|
|
1375
|
+
return; // moved onto a child, still inside
|
|
1376
|
+
if (this.rootDropActive)
|
|
1377
|
+
this.rootDropActive = false;
|
|
1121
1378
|
};
|
|
1122
1379
|
this.onRootDrop = (e) => {
|
|
1380
|
+
this.rootDropActive = false;
|
|
1123
1381
|
if (!this.singleContainer)
|
|
1124
1382
|
return;
|
|
1125
1383
|
const only = this.containers[0];
|
|
@@ -1136,7 +1394,33 @@ const MrdDocumentList = class {
|
|
|
1136
1394
|
};
|
|
1137
1395
|
}
|
|
1138
1396
|
componentDidLoad() {
|
|
1139
|
-
this.
|
|
1397
|
+
if (this.isSeededSingleContainer()) {
|
|
1398
|
+
this.seedSingleContainer();
|
|
1399
|
+
}
|
|
1400
|
+
else {
|
|
1401
|
+
this.emitContainerDistinct();
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
/** True when the view is a single-container context: a RELATED_VIEW whose
|
|
1405
|
+
* `inverseRelation` matches the archetype `container` slot, with a known
|
|
1406
|
+
* parent href. The container is then implied by context (not by distinct),
|
|
1407
|
+
* so it works even with zero documents. */
|
|
1408
|
+
isSeededSingleContainer() {
|
|
1409
|
+
var _a, _b;
|
|
1410
|
+
return (((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === ClientLayoutItemType.RELATED_VIEW &&
|
|
1411
|
+
!!((_b = this.item) === null || _b === void 0 ? void 0 : _b.inverseRelation) &&
|
|
1412
|
+
this.item.inverseRelation === this.containerField &&
|
|
1413
|
+
!!this.containerHref);
|
|
1414
|
+
}
|
|
1415
|
+
/** Seed the single implied container from context and load its folders. */
|
|
1416
|
+
seedSingleContainer() {
|
|
1417
|
+
const node = makeContainerNode(this.containerHref, this.containerField, 0);
|
|
1418
|
+
this.nodeIndex.set(node.id, node);
|
|
1419
|
+
this.containers = [node];
|
|
1420
|
+
this.rootLoading = false;
|
|
1421
|
+
this.singleContainer = true;
|
|
1422
|
+
node.open = true;
|
|
1423
|
+
this.emitFolderDistinct(node);
|
|
1140
1424
|
}
|
|
1141
1425
|
componentDidRender() {
|
|
1142
1426
|
if (this.pendingNeedsFocus && this.pendingInputEl) {
|
|
@@ -1172,50 +1456,42 @@ const MrdDocumentList = class {
|
|
|
1172
1456
|
return (_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b.date;
|
|
1173
1457
|
}
|
|
1174
1458
|
// ── Path / query building (mirrors mrd-table conventions) ────────────────
|
|
1175
|
-
/** VIEW: `/{dataClass}`; RELATED_VIEW: `/{fromClass}/{parentId}/{dataClass}`.
|
|
1459
|
+
/** VIEW: `/{dataClass}`; RELATED_VIEW: `/{fromClass}/{parentId}/{dataClass}`.
|
|
1460
|
+
* Used for reads (list/distinct): `dataClass`/`relatedClass` may be an abstract
|
|
1461
|
+
* type (e.g. "contents"), filtered down to the concrete `filterClass` via the
|
|
1462
|
+
* `type` query param — see baseParams(). */
|
|
1176
1463
|
buildDataPath() {
|
|
1464
|
+
var _a, _b;
|
|
1465
|
+
const it = this.item;
|
|
1466
|
+
return buildListPath({
|
|
1467
|
+
isRelatedView: (it === null || it === void 0 ? void 0 : it.type) === ClientLayoutItemType.RELATED_VIEW,
|
|
1468
|
+
fromClass: it === null || it === void 0 ? void 0 : it.fromClass,
|
|
1469
|
+
parentId: this.parentId,
|
|
1470
|
+
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 : '',
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
/** Path for creating a new document (file-drop). Unlike buildDataPath(), this
|
|
1474
|
+
* must target the concrete type: `dataClass`/`relatedClass` can be an abstract
|
|
1475
|
+
* base type (e.g. "contents") that cannot be POSTed to directly, so prefer
|
|
1476
|
+
* `filterClass` (e.g. "documents") when present. */
|
|
1477
|
+
buildCreatePath() {
|
|
1177
1478
|
var _a, _b, _c;
|
|
1178
1479
|
const it = this.item;
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1480
|
+
return buildListPath({
|
|
1481
|
+
isRelatedView: (it === null || it === void 0 ? void 0 : it.type) === ClientLayoutItemType.RELATED_VIEW,
|
|
1482
|
+
fromClass: it === null || it === void 0 ? void 0 : it.fromClass,
|
|
1483
|
+
parentId: this.parentId,
|
|
1484
|
+
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 : '',
|
|
1485
|
+
});
|
|
1184
1486
|
}
|
|
1185
1487
|
/** View-level static filters + filterClass, shared by every request. */
|
|
1186
1488
|
baseParams() {
|
|
1187
|
-
var _a, _b, _c
|
|
1489
|
+
var _a, _b, _c;
|
|
1188
1490
|
const p = new URLSearchParams();
|
|
1189
1491
|
const filterClass = (_a = this.item) === null || _a === void 0 ? void 0 : _a.filterClass;
|
|
1190
1492
|
if (filterClass)
|
|
1191
1493
|
p.set('type', filterClass);
|
|
1192
|
-
|
|
1193
|
-
if (!f.name)
|
|
1194
|
-
continue;
|
|
1195
|
-
if (f.operator === 'EMPTY') {
|
|
1196
|
-
p.set(f.name, '');
|
|
1197
|
-
continue;
|
|
1198
|
-
}
|
|
1199
|
-
if (f.operator === 'NOT_EMPTY') {
|
|
1200
|
-
p.set(f.name + '_notempty', 'true');
|
|
1201
|
-
continue;
|
|
1202
|
-
}
|
|
1203
|
-
if (f.operator === 'STARTS_WITH') {
|
|
1204
|
-
p.set(f.name + '_startswith', String((_e = f.value) !== null && _e !== void 0 ? _e : ''));
|
|
1205
|
-
continue;
|
|
1206
|
-
}
|
|
1207
|
-
if (f.operator === 'FROM') {
|
|
1208
|
-
p.set(f.name + '_from', String((_f = f.value) !== null && _f !== void 0 ? _f : ''));
|
|
1209
|
-
continue;
|
|
1210
|
-
}
|
|
1211
|
-
if (f.operator === 'TO') {
|
|
1212
|
-
p.set(f.name + '_to', String((_g = f.value) !== null && _g !== void 0 ? _g : ''));
|
|
1213
|
-
continue;
|
|
1214
|
-
}
|
|
1215
|
-
if (f.value != null) {
|
|
1216
|
-
p.set(f.name, String(f.value));
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1494
|
+
applyViewFilters(p, (_c = (_b = this.item) === null || _b === void 0 ? void 0 : _b.view) === null || _c === void 0 ? void 0 : _c.filter);
|
|
1219
1495
|
return p;
|
|
1220
1496
|
}
|
|
1221
1497
|
emitContainerDistinct() {
|
|
@@ -1282,7 +1558,7 @@ const MrdDocumentList = class {
|
|
|
1282
1558
|
if (!v.value || typeof v.value !== 'object')
|
|
1283
1559
|
continue;
|
|
1284
1560
|
const href = v.value.href;
|
|
1285
|
-
const node =
|
|
1561
|
+
const node = makeContainerNode(href, v.value.name, v.count);
|
|
1286
1562
|
nodes.push(node);
|
|
1287
1563
|
this.nodeIndex.set(node.id, node);
|
|
1288
1564
|
}
|
|
@@ -1300,38 +1576,7 @@ const MrdDocumentList = class {
|
|
|
1300
1576
|
const container = this.nodeIndex.get(containerId);
|
|
1301
1577
|
if (!container)
|
|
1302
1578
|
return;
|
|
1303
|
-
container
|
|
1304
|
-
container.hasDocs = false;
|
|
1305
|
-
container.docCount = 0;
|
|
1306
|
-
for (const v of values) {
|
|
1307
|
-
const raw = typeof v.value === 'string' ? v.value : v.value == null ? '' : String(v.value);
|
|
1308
|
-
const segs = this.splitFolder(raw);
|
|
1309
|
-
if (segs.length === 0) {
|
|
1310
|
-
// Root documents — the container's own direct documents.
|
|
1311
|
-
container.hasDocs = true;
|
|
1312
|
-
container.docCount = v.count;
|
|
1313
|
-
container.fullPath = raw;
|
|
1314
|
-
continue;
|
|
1315
|
-
}
|
|
1316
|
-
let node = container;
|
|
1317
|
-
const acc = [];
|
|
1318
|
-
for (const seg of segs) {
|
|
1319
|
-
acc.push(seg);
|
|
1320
|
-
let child = node.children.find(c => c.label === seg);
|
|
1321
|
-
if (!child) {
|
|
1322
|
-
child = this.makeFolderNode(container.id + '/' + acc.join('/'), seg, container.id);
|
|
1323
|
-
node.children.push(child);
|
|
1324
|
-
this.nodeIndex.set(child.id, child);
|
|
1325
|
-
}
|
|
1326
|
-
node = child;
|
|
1327
|
-
}
|
|
1328
|
-
node.hasDocs = true;
|
|
1329
|
-
node.docCount = v.count;
|
|
1330
|
-
node.fullPath = raw;
|
|
1331
|
-
}
|
|
1332
|
-
this.computeTotals(container);
|
|
1333
|
-
container.foldersLoaded = true;
|
|
1334
|
-
container.loading = false;
|
|
1579
|
+
applyFolderDistinct(container, values, this.nodeIndex);
|
|
1335
1580
|
// If the container has root documents, load them now (they show inline on expand).
|
|
1336
1581
|
if (container.hasDocs && !container.docsLoaded) {
|
|
1337
1582
|
this.emitDocuments(container, container);
|
|
@@ -1339,36 +1584,6 @@ const MrdDocumentList = class {
|
|
|
1339
1584
|
this.bump();
|
|
1340
1585
|
}
|
|
1341
1586
|
// ── Tree helpers ─────────────────────────────────────────────────────────
|
|
1342
|
-
/** Normalise a folder path: null/""/"/" → root ([]); else split on "/" dropping empties. */
|
|
1343
|
-
splitFolder(path) {
|
|
1344
|
-
if (path == null)
|
|
1345
|
-
return [];
|
|
1346
|
-
const s = String(path).trim();
|
|
1347
|
-
if (s === '' || s === '/')
|
|
1348
|
-
return [];
|
|
1349
|
-
return s.split('/').map(x => x.trim()).filter(Boolean);
|
|
1350
|
-
}
|
|
1351
|
-
makeContainerNode(href, label, count) {
|
|
1352
|
-
return {
|
|
1353
|
-
id: 'c:' + href, kind: 'container', label, href,
|
|
1354
|
-
hasDocs: false, docCount: 0, totalCount: count, children: [],
|
|
1355
|
-
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1356
|
-
};
|
|
1357
|
-
}
|
|
1358
|
-
makeFolderNode(id, label, containerId) {
|
|
1359
|
-
return {
|
|
1360
|
-
id, kind: 'folder', label, containerId,
|
|
1361
|
-
hasDocs: false, docCount: 0, totalCount: 0, children: [],
|
|
1362
|
-
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1363
|
-
};
|
|
1364
|
-
}
|
|
1365
|
-
computeTotals(node) {
|
|
1366
|
-
let total = node.docCount;
|
|
1367
|
-
for (const c of node.children)
|
|
1368
|
-
total += this.computeTotals(c);
|
|
1369
|
-
node.totalCount = total;
|
|
1370
|
-
return total;
|
|
1371
|
-
}
|
|
1372
1587
|
/** Force a re-render after mutating nodes in place. */
|
|
1373
1588
|
bump() {
|
|
1374
1589
|
this.containers = [...this.containers];
|
|
@@ -1418,14 +1633,6 @@ const MrdDocumentList = class {
|
|
|
1418
1633
|
async createFolder() {
|
|
1419
1634
|
this.startCreateFolder();
|
|
1420
1635
|
}
|
|
1421
|
-
/** Folder path segments of a node relative to its container (derived from its id). */
|
|
1422
|
-
segmentsOf(node, container) {
|
|
1423
|
-
if (node.kind === 'container')
|
|
1424
|
-
return [];
|
|
1425
|
-
const prefix = container.id + '/';
|
|
1426
|
-
const rest = node.id.startsWith(prefix) ? node.id.slice(prefix.length) : '';
|
|
1427
|
-
return rest ? rest.split('/') : [];
|
|
1428
|
-
}
|
|
1429
1636
|
commitFolder() {
|
|
1430
1637
|
const node = this.pendingNode;
|
|
1431
1638
|
const parent = this.pendingParent;
|
|
@@ -1450,7 +1657,7 @@ const MrdDocumentList = class {
|
|
|
1450
1657
|
}
|
|
1451
1658
|
// Finalise: swap the temp id for the real path-derived id so a later distinct
|
|
1452
1659
|
// value with the same folder string merges onto this node.
|
|
1453
|
-
const segs = [...
|
|
1660
|
+
const segs = [...segmentsOf(parent, container), name];
|
|
1454
1661
|
this.nodeIndex.delete(node.id);
|
|
1455
1662
|
node.id = container.id + '/' + segs.join('/');
|
|
1456
1663
|
node.fullPath = '/' + segs.join('/');
|
|
@@ -1499,10 +1706,6 @@ const MrdDocumentList = class {
|
|
|
1499
1706
|
this.bump();
|
|
1500
1707
|
this.mrdUpload.emit({ file });
|
|
1501
1708
|
}
|
|
1502
|
-
/** Strip a single trailing extension for the document title. */
|
|
1503
|
-
stripExtension(name) {
|
|
1504
|
-
return name.replace(/\.[^./\\]+$/, '');
|
|
1505
|
-
}
|
|
1506
1709
|
/** Host callback with the uploaded file reference. Builds the create payload
|
|
1507
1710
|
* from the archetype slots and requests the new document. */
|
|
1508
1711
|
async setFileReference(uri) {
|
|
@@ -1510,16 +1713,20 @@ const MrdDocumentList = class {
|
|
|
1510
1713
|
if (!up)
|
|
1511
1714
|
return;
|
|
1512
1715
|
const { file, node, container } = up;
|
|
1513
|
-
const folder =
|
|
1716
|
+
const folder = folderStringOf(node, container);
|
|
1514
1717
|
const values = {
|
|
1515
1718
|
[this.fileField]: uri,
|
|
1516
|
-
[this.titleField]:
|
|
1719
|
+
[this.titleField]: stripExtension(file.name),
|
|
1517
1720
|
[this.folderField]: folder,
|
|
1518
|
-
[this.containerField]: container.href,
|
|
1519
1721
|
};
|
|
1520
|
-
|
|
1722
|
+
// The create path already embeds the container (/{fromClass}/{parentId}/...)
|
|
1723
|
+
// when this is the seeded single-container context; omit the redundant field.
|
|
1724
|
+
if (!this.isSeededSingleContainer()) {
|
|
1725
|
+
values[this.containerField] = container.href;
|
|
1726
|
+
}
|
|
1727
|
+
this.mrdCreateObject.emit({ path: this.buildCreatePath(), values });
|
|
1521
1728
|
// Optimistically show the new document (no href until a reload).
|
|
1522
|
-
const optimistic = { [this.titleField]:
|
|
1729
|
+
const optimistic = { [this.titleField]: stripExtension(file.name), _optimistic: true };
|
|
1523
1730
|
const wasUnloadedEmpty = !node.docsLoaded && node.docCount === 0;
|
|
1524
1731
|
node.hasDocs = true;
|
|
1525
1732
|
node.pending = false;
|
|
@@ -1548,16 +1755,6 @@ const MrdDocumentList = class {
|
|
|
1548
1755
|
this.lastOptimisticDoc = null;
|
|
1549
1756
|
this.bump();
|
|
1550
1757
|
}
|
|
1551
|
-
/** Folder string a node represents: the raw distinct value when it holds
|
|
1552
|
-
* documents, else derived from its path segments; null for a container root. */
|
|
1553
|
-
folderStringOf(node, container) {
|
|
1554
|
-
if (node.kind === 'container')
|
|
1555
|
-
return null;
|
|
1556
|
-
if (node.fullPath != null && node.fullPath !== '')
|
|
1557
|
-
return node.fullPath;
|
|
1558
|
-
const segs = this.segmentsOf(node, container);
|
|
1559
|
-
return segs.length ? '/' + segs.join('/') : null;
|
|
1560
|
-
}
|
|
1561
1758
|
moveDocument(toNode, toContainer) {
|
|
1562
1759
|
var _a, _b;
|
|
1563
1760
|
const doc = this.dragDoc;
|
|
@@ -1569,26 +1766,14 @@ const MrdDocumentList = class {
|
|
|
1569
1766
|
: (fromNode.containerId ? this.nodeIndex.get(fromNode.containerId) : undefined);
|
|
1570
1767
|
if (!fromContainer)
|
|
1571
1768
|
return;
|
|
1572
|
-
const targetFolder =
|
|
1573
|
-
const sourceFolder =
|
|
1769
|
+
const targetFolder = folderStringOf(toNode, toContainer);
|
|
1770
|
+
const sourceFolder = folderStringOf(fromNode, fromContainer);
|
|
1574
1771
|
const sameContainer = toContainer === fromContainer;
|
|
1575
1772
|
// No-op: dropped back onto its own folder.
|
|
1576
1773
|
if (toNode === fromNode || (sameContainer && targetFolder === sourceFolder))
|
|
1577
1774
|
return;
|
|
1578
|
-
//
|
|
1579
|
-
|
|
1580
|
-
fromNode.docCount = Math.max(0, fromNode.docCount - 1);
|
|
1581
|
-
// A now-empty folder should stop showing an expand chevron (it disappears on
|
|
1582
|
-
// the next reload anyway, since it is derived from document folder strings).
|
|
1583
|
-
if (fromNode.docsLoaded)
|
|
1584
|
-
fromNode.hasDocs = fromNode.docs.length > 0;
|
|
1585
|
-
toNode.hasDocs = true;
|
|
1586
|
-
toNode.pending = false; // a pending folder is now materialised
|
|
1587
|
-
toNode.docCount += 1;
|
|
1588
|
-
if (toNode.kind === 'folder')
|
|
1589
|
-
toNode.fullPath = targetFolder !== null && targetFolder !== void 0 ? targetFolder : '';
|
|
1590
|
-
if (toNode.docsLoaded)
|
|
1591
|
-
toNode.docs = [...toNode.docs, doc];
|
|
1775
|
+
// Optimistic tree update (fire-and-forget; no refetch).
|
|
1776
|
+
applyDocMove(doc, fromNode, toNode, targetFolder);
|
|
1592
1777
|
this.recomputeContainerTotals(fromContainer, -1);
|
|
1593
1778
|
if (!sameContainer)
|
|
1594
1779
|
this.recomputeContainerTotals(toContainer, 1);
|
|
@@ -1606,7 +1791,7 @@ const MrdDocumentList = class {
|
|
|
1606
1791
|
* loaded; otherwise just nudge the aggregate badge by the delta. */
|
|
1607
1792
|
recomputeContainerTotals(container, delta) {
|
|
1608
1793
|
if (container.foldersLoaded) {
|
|
1609
|
-
|
|
1794
|
+
computeTotals(container);
|
|
1610
1795
|
}
|
|
1611
1796
|
else {
|
|
1612
1797
|
container.totalCount = Math.max(0, container.totalCount + delta);
|
|
@@ -1619,105 +1804,64 @@ const MrdDocumentList = class {
|
|
|
1619
1804
|
this.mrdNavigate.emit({ href, label });
|
|
1620
1805
|
}
|
|
1621
1806
|
// ── Render ───────────────────────────────────────────────────────────────
|
|
1622
|
-
|
|
1623
|
-
return
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
return (h("div", { class: "mrd-document-list__loading", key: "loading" }, this.indent(depth), h("span", { class: "mrd-document-list__spinner" }), t('loading', this.locale)));
|
|
1646
|
-
}
|
|
1647
|
-
renderChildren(container, node, depth) {
|
|
1648
|
-
const out = [];
|
|
1649
|
-
// Direct documents of this node (root docs live on the container node).
|
|
1650
|
-
if (node.hasDocs) {
|
|
1651
|
-
if (node.docsLoaded) {
|
|
1652
|
-
for (const doc of node.docs)
|
|
1653
|
-
out.push(this.renderDocRow(doc, node, container, depth));
|
|
1654
|
-
}
|
|
1655
|
-
else if (node.loading) {
|
|
1656
|
-
out.push(this.renderLoadingRow(depth));
|
|
1657
|
-
}
|
|
1658
|
-
}
|
|
1659
|
-
// Child folders.
|
|
1660
|
-
for (const child of node.children) {
|
|
1661
|
-
out.push(this.renderFolderNode(container, child, depth));
|
|
1662
|
-
}
|
|
1663
|
-
// An uploading file dropped onto this node.
|
|
1664
|
-
if (node.id === this.uploadingNodeId)
|
|
1665
|
-
out.push(this.renderUploadingRow(depth));
|
|
1666
|
-
return out;
|
|
1667
|
-
}
|
|
1668
|
-
renderUploadingRow(depth) {
|
|
1669
|
-
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)));
|
|
1670
|
-
}
|
|
1671
|
-
renderFolderEditRow(node, depth) {
|
|
1672
|
-
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))));
|
|
1673
|
-
}
|
|
1674
|
-
renderFolderNode(container, node, depth) {
|
|
1675
|
-
if (node.editing)
|
|
1676
|
-
return this.renderFolderEditRow(node, depth);
|
|
1677
|
-
const leaf = node.children.length === 0 && !node.hasDocs;
|
|
1678
|
-
const selected = node.id === this.selectedId;
|
|
1679
|
-
const cls = 'mrd-document-list__row'
|
|
1680
|
-
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1681
|
-
+ (node.pending ? ' mrd-document-list__row--pending' : '')
|
|
1682
|
-
+ (node.id === this.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1683
|
-
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))));
|
|
1684
|
-
}
|
|
1685
|
-
renderContainerNode(node, depth) {
|
|
1686
|
-
const selected = node.id === this.selectedId;
|
|
1687
|
-
const cls = 'mrd-document-list__row mrd-document-list__row--dossier'
|
|
1688
|
-
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1689
|
-
+ (node.id === this.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1690
|
-
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
|
|
1691
|
-
? this.renderLoadingRow(depth + 1)
|
|
1692
|
-
: this.renderChildren(node, node, depth + 1)))));
|
|
1807
|
+
treeCtx() {
|
|
1808
|
+
return {
|
|
1809
|
+
locale: this.locale,
|
|
1810
|
+
titleField: this.titleField,
|
|
1811
|
+
dateField: this.dateField,
|
|
1812
|
+
selectedId: this.selectedId,
|
|
1813
|
+
dropTargetId: this.dropTargetId,
|
|
1814
|
+
uploadingNodeId: this.uploadingNodeId,
|
|
1815
|
+
on: {
|
|
1816
|
+
toggleContainer: node => this.toggleContainer(node),
|
|
1817
|
+
toggleFolder: (container, node) => this.toggleFolder(container, node),
|
|
1818
|
+
openDoc: doc => this.openDoc(doc),
|
|
1819
|
+
docDragStart: this.onDocDragStart,
|
|
1820
|
+
docDragEnd: this.onDocDragEnd,
|
|
1821
|
+
nodeDragOver: this.onNodeDragOver,
|
|
1822
|
+
nodeDragLeave: this.onNodeDragLeave,
|
|
1823
|
+
nodeDrop: this.onNodeDrop,
|
|
1824
|
+
pendingInput: this.onPendingInput,
|
|
1825
|
+
pendingKeyDown: this.onPendingKeyDown,
|
|
1826
|
+
cancelFolder: () => this.cancelFolder(),
|
|
1827
|
+
setPendingInputEl: el => (this.pendingInputEl = el),
|
|
1828
|
+
},
|
|
1829
|
+
};
|
|
1693
1830
|
}
|
|
1694
1831
|
render() {
|
|
1832
|
+
const ctx = this.treeCtx();
|
|
1695
1833
|
let body;
|
|
1696
1834
|
if (this.rootLoading) {
|
|
1697
|
-
body =
|
|
1835
|
+
body = renderLoadingRow(ctx, 0);
|
|
1698
1836
|
}
|
|
1699
1837
|
else if (this.containers.length === 0) {
|
|
1700
|
-
body = h("div", { key: '
|
|
1838
|
+
body = h("div", { key: 'ce40dab51ab61447838e5059159ae4778209a6f3', class: "mrd-document-list__empty" }, t('no_results', this.locale));
|
|
1701
1839
|
}
|
|
1702
1840
|
else if (this.singleContainer) {
|
|
1703
1841
|
// Dossier context: render the single container's folder tree at the root.
|
|
1704
1842
|
const only = this.containers[0];
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1843
|
+
if (only.loading && !only.foldersLoaded) {
|
|
1844
|
+
body = renderLoadingRow(ctx, 0);
|
|
1845
|
+
}
|
|
1846
|
+
else {
|
|
1847
|
+
const kids = renderNodeChildren(ctx, only, only, 0);
|
|
1848
|
+
body = kids.length
|
|
1849
|
+
? kids
|
|
1850
|
+
: h("div", { class: "mrd-document-list__empty" }, t('doc_empty_drop', this.locale));
|
|
1851
|
+
}
|
|
1708
1852
|
}
|
|
1709
1853
|
else {
|
|
1710
|
-
body = this.containers.map(c =>
|
|
1854
|
+
body = this.containers.map(c => renderContainerNode(ctx, c, 0));
|
|
1711
1855
|
}
|
|
1712
|
-
return (h(Host, { key: '
|
|
1856
|
+
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)));
|
|
1713
1857
|
}
|
|
1714
1858
|
get el() { return getElement(this); }
|
|
1715
1859
|
};
|
|
1716
1860
|
/** Root sentinel id for the container-level distinct request. */
|
|
1717
1861
|
MrdDocumentList.ROOT = '__root__';
|
|
1718
|
-
MrdDocumentList.style =
|
|
1862
|
+
MrdDocumentList.style = mrdDocumentListCss();
|
|
1719
1863
|
|
|
1720
|
-
const
|
|
1864
|
+
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)}`;
|
|
1721
1865
|
|
|
1722
1866
|
const MrdDocumentView = class {
|
|
1723
1867
|
constructor(hostRef) {
|
|
@@ -1767,12 +1911,12 @@ const MrdDocumentView = class {
|
|
|
1767
1911
|
const date = dateRaw != null && dateRaw !== '' ? formatDate(dateRaw, this.locale) : null;
|
|
1768
1912
|
const summaryRaw = this.slotValue('summary');
|
|
1769
1913
|
const summary = summaryRaw != null && summaryRaw !== '' ? String(summaryRaw) : null;
|
|
1770
|
-
return (h(Host, { key: '
|
|
1914
|
+
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 }))))));
|
|
1771
1915
|
}
|
|
1772
1916
|
};
|
|
1773
|
-
MrdDocumentView.style =
|
|
1917
|
+
MrdDocumentView.style = mrdDocumentViewCss();
|
|
1774
1918
|
|
|
1775
|
-
const
|
|
1919
|
+
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)}`;
|
|
1776
1920
|
|
|
1777
1921
|
const MrdEmailField = class {
|
|
1778
1922
|
constructor(hostRef) {
|
|
@@ -1793,26 +1937,18 @@ const MrdEmailField = class {
|
|
|
1793
1937
|
};
|
|
1794
1938
|
this.handleBlur = (e) => {
|
|
1795
1939
|
const val = e.target.value;
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
}
|
|
1799
|
-
else if (val && !validateEmail(val)) {
|
|
1800
|
-
this.error = t('invalid_email', this.locale);
|
|
1801
|
-
}
|
|
1802
|
-
else {
|
|
1803
|
-
this.error = '';
|
|
1804
|
-
}
|
|
1940
|
+
this.error = requiredError(val, this.required, this.locale)
|
|
1941
|
+
|| (val && !validateEmail(val) ? t('invalid_email', this.locale) : '');
|
|
1805
1942
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
1806
1943
|
};
|
|
1807
1944
|
}
|
|
1808
1945
|
render() {
|
|
1809
|
-
|
|
1810
|
-
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))));
|
|
1946
|
+
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 }))));
|
|
1811
1947
|
}
|
|
1812
1948
|
};
|
|
1813
|
-
MrdEmailField.style =
|
|
1949
|
+
MrdEmailField.style = mrdEmailFieldCss();
|
|
1814
1950
|
|
|
1815
|
-
const
|
|
1951
|
+
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)}`;
|
|
1816
1952
|
|
|
1817
1953
|
const MrdField = class {
|
|
1818
1954
|
constructor(hostRef) {
|
|
@@ -1997,9 +2133,47 @@ const MrdField = class {
|
|
|
1997
2133
|
}]
|
|
1998
2134
|
}; }
|
|
1999
2135
|
};
|
|
2000
|
-
MrdField.style =
|
|
2136
|
+
MrdField.style = mrdFieldCss();
|
|
2001
2137
|
|
|
2002
|
-
|
|
2138
|
+
/**
|
|
2139
|
+
* Shared upload behaviour for mrd-file-field and mrd-image-field:
|
|
2140
|
+
* file validation, drop-zone class building and drag-drop wiring.
|
|
2141
|
+
*/
|
|
2142
|
+
/** Validates a selected/dropped file; returns a localised error message or '' when accepted. */
|
|
2143
|
+
function validateUploadFile(file, maxSize, locale, requireImage = false) {
|
|
2144
|
+
if (maxSize > 0 && file.size > maxSize)
|
|
2145
|
+
return t('file_too_large', locale);
|
|
2146
|
+
if (requireImage && !file.type.startsWith('image/'))
|
|
2147
|
+
return t('invalid_image', locale);
|
|
2148
|
+
return '';
|
|
2149
|
+
}
|
|
2150
|
+
/** BEM class string for the drop zone, e.g. base 'mrd-file-field' → 'mrd-file-field__zone …'. */
|
|
2151
|
+
function uploadZoneClass(base, opts) {
|
|
2152
|
+
return [
|
|
2153
|
+
`${base}__zone`,
|
|
2154
|
+
opts.dragging ? `${base}__zone--dragging` : '',
|
|
2155
|
+
opts.error ? `${base}__zone--error` : '',
|
|
2156
|
+
opts.disabled ? `${base}__zone--disabled` : '',
|
|
2157
|
+
].filter(Boolean).join(' ');
|
|
2158
|
+
}
|
|
2159
|
+
/** Drag-drop handlers for the drop zone; the component owns the dragging state and file handling. */
|
|
2160
|
+
function makeDragHandlers(setDragging, onFile) {
|
|
2161
|
+
return {
|
|
2162
|
+
onDragOver: (e) => {
|
|
2163
|
+
e.preventDefault();
|
|
2164
|
+
setDragging(true);
|
|
2165
|
+
},
|
|
2166
|
+
onDragLeave: () => setDragging(false),
|
|
2167
|
+
onDrop: (e) => {
|
|
2168
|
+
var _a, _b, _c;
|
|
2169
|
+
e.preventDefault();
|
|
2170
|
+
setDragging(false);
|
|
2171
|
+
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);
|
|
2172
|
+
},
|
|
2173
|
+
};
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
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)}}`;
|
|
2003
2177
|
|
|
2004
2178
|
const MrdFileField = class {
|
|
2005
2179
|
constructor(hostRef) {
|
|
@@ -2024,20 +2198,7 @@ const MrdFileField = class {
|
|
|
2024
2198
|
const files = e.target.files;
|
|
2025
2199
|
this.handleFile((_a = files === null || files === void 0 ? void 0 : files[0]) !== null && _a !== void 0 ? _a : null);
|
|
2026
2200
|
};
|
|
2027
|
-
this.
|
|
2028
|
-
e.preventDefault();
|
|
2029
|
-
this.isDragging = true;
|
|
2030
|
-
};
|
|
2031
|
-
this.handleDragLeave = () => {
|
|
2032
|
-
this.isDragging = false;
|
|
2033
|
-
};
|
|
2034
|
-
this.handleDrop = (e) => {
|
|
2035
|
-
var _a, _b, _c;
|
|
2036
|
-
e.preventDefault();
|
|
2037
|
-
this.isDragging = false;
|
|
2038
|
-
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;
|
|
2039
|
-
this.handleFile(file);
|
|
2040
|
-
};
|
|
2201
|
+
this.drag = makeDragHandlers(dragging => (this.isDragging = dragging), file => this.handleFile(file));
|
|
2041
2202
|
this.handleZoneClick = () => {
|
|
2042
2203
|
var _a;
|
|
2043
2204
|
if (!this.disabled && !this.uploading) {
|
|
@@ -2071,8 +2232,9 @@ const MrdFileField = class {
|
|
|
2071
2232
|
this.mrdChange.emit({ name: this.name, value: null });
|
|
2072
2233
|
return;
|
|
2073
2234
|
}
|
|
2074
|
-
|
|
2075
|
-
|
|
2235
|
+
const uploadError = validateUploadFile(file, this.maxSize, this.locale);
|
|
2236
|
+
if (uploadError) {
|
|
2237
|
+
this.error = uploadError;
|
|
2076
2238
|
return;
|
|
2077
2239
|
}
|
|
2078
2240
|
this.error = '';
|
|
@@ -2084,13 +2246,12 @@ const MrdFileField = class {
|
|
|
2084
2246
|
render() {
|
|
2085
2247
|
const hasFile = this.uploading || (typeof this.value === 'string' && this.value) || this.fileName;
|
|
2086
2248
|
const hasError = !!this.error;
|
|
2087
|
-
const zoneClass =
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
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))));
|
|
2249
|
+
const zoneClass = uploadZoneClass('mrd-file-field', {
|
|
2250
|
+
dragging: this.isDragging,
|
|
2251
|
+
error: hasError,
|
|
2252
|
+
disabled: this.disabled || this.uploading,
|
|
2253
|
+
});
|
|
2254
|
+
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 }))));
|
|
2094
2255
|
}
|
|
2095
2256
|
static get watchers() { return {
|
|
2096
2257
|
"value": [{
|
|
@@ -2098,9 +2259,9 @@ const MrdFileField = class {
|
|
|
2098
2259
|
}]
|
|
2099
2260
|
}; }
|
|
2100
2261
|
};
|
|
2101
|
-
MrdFileField.style =
|
|
2262
|
+
MrdFileField.style = mrdFileFieldCss();
|
|
2102
2263
|
|
|
2103
|
-
const
|
|
2264
|
+
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)}`;
|
|
2104
2265
|
|
|
2105
2266
|
const MrdForm = class {
|
|
2106
2267
|
constructor(hostRef) {
|
|
@@ -2467,9 +2628,9 @@ const MrdForm = class {
|
|
|
2467
2628
|
}]
|
|
2468
2629
|
}; }
|
|
2469
2630
|
};
|
|
2470
|
-
MrdForm.style =
|
|
2631
|
+
MrdForm.style = mrdFormCss();
|
|
2471
2632
|
|
|
2472
|
-
const
|
|
2633
|
+
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)}`;
|
|
2473
2634
|
|
|
2474
2635
|
const MrdHyperlinkField = class {
|
|
2475
2636
|
constructor(hostRef) {
|
|
@@ -2495,15 +2656,8 @@ const MrdHyperlinkField = class {
|
|
|
2495
2656
|
this.mrdChange.emit({ name: this.name, value: this.buildValue() });
|
|
2496
2657
|
};
|
|
2497
2658
|
this.handleBlur = () => {
|
|
2498
|
-
|
|
2499
|
-
this.
|
|
2500
|
-
}
|
|
2501
|
-
else if (this.internalHref && !validateUrl(this.internalHref)) {
|
|
2502
|
-
this.error = t('invalid_url', this.locale);
|
|
2503
|
-
}
|
|
2504
|
-
else {
|
|
2505
|
-
this.error = '';
|
|
2506
|
-
}
|
|
2659
|
+
this.error = requiredError(this.internalHref, this.required, this.locale)
|
|
2660
|
+
|| (this.internalHref && !validateUrl(this.internalHref) ? t('invalid_url', this.locale) : '');
|
|
2507
2661
|
this.mrdBlur.emit({ name: this.name, value: this.buildValue() });
|
|
2508
2662
|
};
|
|
2509
2663
|
}
|
|
@@ -2536,7 +2690,7 @@ const MrdHyperlinkField = class {
|
|
|
2536
2690
|
? h("a", { class: "mrd-hyperlink-field__link", href: this.internalHref, target: "_blank", rel: "noopener noreferrer" }, this.internalName || this.internalHref)
|
|
2537
2691
|
: h("span", { class: "mrd-hyperlink-field__empty" }, "\u2014"))));
|
|
2538
2692
|
}
|
|
2539
|
-
return (h(Host, null, h("div", { class: "mrd-hyperlink-field" },
|
|
2693
|
+
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 }))));
|
|
2540
2694
|
}
|
|
2541
2695
|
static get watchers() { return {
|
|
2542
2696
|
"value": [{
|
|
@@ -2544,9 +2698,9 @@ const MrdHyperlinkField = class {
|
|
|
2544
2698
|
}]
|
|
2545
2699
|
}; }
|
|
2546
2700
|
};
|
|
2547
|
-
MrdHyperlinkField.style =
|
|
2701
|
+
MrdHyperlinkField.style = mrdHyperlinkFieldCss();
|
|
2548
2702
|
|
|
2549
|
-
const
|
|
2703
|
+
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)}`;
|
|
2550
2704
|
|
|
2551
2705
|
const MrdImageField = class {
|
|
2552
2706
|
constructor(hostRef) {
|
|
@@ -2572,20 +2726,7 @@ const MrdImageField = class {
|
|
|
2572
2726
|
const files = e.target.files;
|
|
2573
2727
|
this.handleFile((_a = files === null || files === void 0 ? void 0 : files[0]) !== null && _a !== void 0 ? _a : null);
|
|
2574
2728
|
};
|
|
2575
|
-
this.
|
|
2576
|
-
e.preventDefault();
|
|
2577
|
-
this.isDragging = true;
|
|
2578
|
-
};
|
|
2579
|
-
this.handleDragLeave = () => {
|
|
2580
|
-
this.isDragging = false;
|
|
2581
|
-
};
|
|
2582
|
-
this.handleDrop = (e) => {
|
|
2583
|
-
var _a, _b, _c;
|
|
2584
|
-
e.preventDefault();
|
|
2585
|
-
this.isDragging = false;
|
|
2586
|
-
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;
|
|
2587
|
-
this.handleFile(file);
|
|
2588
|
-
};
|
|
2729
|
+
this.drag = makeDragHandlers(dragging => (this.isDragging = dragging), file => this.handleFile(file));
|
|
2589
2730
|
this.handleZoneClick = () => {
|
|
2590
2731
|
var _a;
|
|
2591
2732
|
if (!this.disabled && !this.uploading) {
|
|
@@ -2622,12 +2763,9 @@ const MrdImageField = class {
|
|
|
2622
2763
|
this.mrdChange.emit({ name: this.name, value: null });
|
|
2623
2764
|
return;
|
|
2624
2765
|
}
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
}
|
|
2629
|
-
if (!file.type.startsWith('image/')) {
|
|
2630
|
-
this.error = 'Please select an image file';
|
|
2766
|
+
const uploadError = validateUploadFile(file, this.maxSize, this.locale, true);
|
|
2767
|
+
if (uploadError) {
|
|
2768
|
+
this.error = uploadError;
|
|
2631
2769
|
return;
|
|
2632
2770
|
}
|
|
2633
2771
|
this.error = '';
|
|
@@ -2645,13 +2783,12 @@ const MrdImageField = class {
|
|
|
2645
2783
|
}
|
|
2646
2784
|
render() {
|
|
2647
2785
|
const hasError = !!this.error;
|
|
2648
|
-
const zoneClass =
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
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))));
|
|
2786
|
+
const zoneClass = uploadZoneClass('mrd-image-field', {
|
|
2787
|
+
dragging: this.isDragging,
|
|
2788
|
+
error: hasError,
|
|
2789
|
+
disabled: this.disabled || this.uploading,
|
|
2790
|
+
});
|
|
2791
|
+
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 }))));
|
|
2655
2792
|
}
|
|
2656
2793
|
static get watchers() { return {
|
|
2657
2794
|
"value": [{
|
|
@@ -2659,7 +2796,36 @@ const MrdImageField = class {
|
|
|
2659
2796
|
}]
|
|
2660
2797
|
}; }
|
|
2661
2798
|
};
|
|
2662
|
-
MrdImageField.style =
|
|
2799
|
+
MrdImageField.style = mrdImageFieldCss();
|
|
2800
|
+
|
|
2801
|
+
/** Key an embedded view is addressed by (setViewPage etc.). */
|
|
2802
|
+
function viewKeyFor(item) {
|
|
2803
|
+
var _a, _b, _c, _d;
|
|
2804
|
+
if (item.type === ClientLayoutItemType.RELATED_VIEW)
|
|
2805
|
+
return (_b = (_a = item.relatedClass) !== null && _a !== void 0 ? _a : item.name) !== null && _b !== void 0 ? _b : '';
|
|
2806
|
+
return (_d = (_c = item.dataClass) !== null && _c !== void 0 ? _c : item.name) !== null && _d !== void 0 ? _d : '';
|
|
2807
|
+
}
|
|
2808
|
+
/** Depth-first flatten of the SECTION/GROUP tree. */
|
|
2809
|
+
function flattenItems(items) {
|
|
2810
|
+
const result = [];
|
|
2811
|
+
for (const item of items) {
|
|
2812
|
+
result.push(item);
|
|
2813
|
+
if (item.items)
|
|
2814
|
+
result.push(...flattenItems(item.items));
|
|
2815
|
+
}
|
|
2816
|
+
return result;
|
|
2817
|
+
}
|
|
2818
|
+
/** Build the canonical parent href `/{base}/{tenant}/{fromClass}/{parentId}` from
|
|
2819
|
+
* the object's self href. Empty unless it is a RELATED_VIEW with a fromClass. */
|
|
2820
|
+
function buildContainerHref(item, selfHref, parentId) {
|
|
2821
|
+
if (item.type !== ClientLayoutItemType.RELATED_VIEW || !item.fromClass || !parentId)
|
|
2822
|
+
return '';
|
|
2823
|
+
const segs = selfHref.split('/').filter(Boolean);
|
|
2824
|
+
if (segs.length < 2)
|
|
2825
|
+
return '';
|
|
2826
|
+
const [base, tenant] = segs;
|
|
2827
|
+
return `/${base}/${tenant}/${item.fromClass}/${parentId}`;
|
|
2828
|
+
}
|
|
2663
2829
|
|
|
2664
2830
|
class CellRenderer {
|
|
2665
2831
|
static render(column, row, locale) {
|
|
@@ -2765,7 +2931,114 @@ class CellRenderer {
|
|
|
2765
2931
|
}
|
|
2766
2932
|
}
|
|
2767
2933
|
|
|
2768
|
-
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}`;
|
|
2934
|
+
/** FILE and IMAGE cells share the same download button. */
|
|
2935
|
+
function downloadLink(ctx, href, fileName, label) {
|
|
2936
|
+
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));
|
|
2937
|
+
}
|
|
2938
|
+
function renderSingleFieldValue(ctx, item, value) {
|
|
2939
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
2940
|
+
const dt = item.dataType;
|
|
2941
|
+
switch (dt) {
|
|
2942
|
+
case ClientLayoutItemFieldDataType.HYPERLINK: {
|
|
2943
|
+
const v = value;
|
|
2944
|
+
const href = (_a = v === null || v === void 0 ? void 0 : v.href) !== null && _a !== void 0 ? _a : String(value);
|
|
2945
|
+
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;
|
|
2946
|
+
return (h("a", { class: "mrd-layout-section__link", href: href, target: "_blank", rel: "noopener noreferrer" }, label));
|
|
2947
|
+
}
|
|
2948
|
+
case ClientLayoutItemFieldDataType.TEXTBLOCK:
|
|
2949
|
+
return h("div", { class: "mrd-layout-section__prose", innerHTML: String(value) });
|
|
2950
|
+
case ClientLayoutItemFieldDataType.LONGTEXT:
|
|
2951
|
+
return h("pre", { class: "mrd-layout-section__pre" }, String(value));
|
|
2952
|
+
case ClientLayoutItemFieldDataType.JSON:
|
|
2953
|
+
return h("pre", { class: "mrd-layout-section__pre", innerHTML: CellRenderer.formatJson(value) });
|
|
2954
|
+
case ClientLayoutItemFieldDataType.FILE: {
|
|
2955
|
+
const v = value;
|
|
2956
|
+
const fileName = (_e = v === null || v === void 0 ? void 0 : v.fileName) !== null && _e !== void 0 ? _e : String(value);
|
|
2957
|
+
const href = (_f = v === null || v === void 0 ? void 0 : v.href) !== null && _f !== void 0 ? _f : '';
|
|
2958
|
+
return downloadLink(ctx, href, fileName, t('download', ctx.locale));
|
|
2959
|
+
}
|
|
2960
|
+
case ClientLayoutItemFieldDataType.IMAGE: {
|
|
2961
|
+
const v = value;
|
|
2962
|
+
const href = (_g = v === null || v === void 0 ? void 0 : v.href) !== null && _g !== void 0 ? _g : '';
|
|
2963
|
+
const fileName = (_h = v === null || v === void 0 ? void 0 : v.fileName) !== null && _h !== void 0 ? _h : '';
|
|
2964
|
+
const previewUrl = ctx.imagePreviews[item.name];
|
|
2965
|
+
if (previewUrl) {
|
|
2966
|
+
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 })));
|
|
2967
|
+
}
|
|
2968
|
+
return downloadLink(ctx, href, fileName, fileName || href);
|
|
2969
|
+
}
|
|
2970
|
+
case ClientLayoutItemFieldDataType.BOOLEAN:
|
|
2971
|
+
return (h("span", { class: `mrd-layout-section__boolean mrd-layout-section__boolean--${value ? 'true' : 'false'}` }, value ? t('yes', ctx.locale) : t('no', ctx.locale)));
|
|
2972
|
+
case ClientLayoutItemFieldDataType.LIST: {
|
|
2973
|
+
const listItem = ((_j = item.listItems) !== null && _j !== void 0 ? _j : []).find(li => li.key === String(value));
|
|
2974
|
+
const label = (_k = listItem === null || listItem === void 0 ? void 0 : listItem.label) !== null && _k !== void 0 ? _k : String(value);
|
|
2975
|
+
const color = listItem === null || listItem === void 0 ? void 0 : listItem.color;
|
|
2976
|
+
const bg = listItem === null || listItem === void 0 ? void 0 : listItem.backgroundColor;
|
|
2977
|
+
if (color && bg) {
|
|
2978
|
+
return (h("span", { class: "mrd-layout-section__badge", style: { color, backgroundColor: bg } }, label));
|
|
2979
|
+
}
|
|
2980
|
+
if (color) {
|
|
2981
|
+
return (h("span", { class: "mrd-layout-section__badge-dot-row" }, h("span", { class: "mrd-layout-section__badge-dot", style: { backgroundColor: color } }), label));
|
|
2982
|
+
}
|
|
2983
|
+
return label;
|
|
2984
|
+
}
|
|
2985
|
+
case ClientLayoutItemFieldDataType.SECRET:
|
|
2986
|
+
return value ? h("span", { class: "mrd-layout-section__secret-masked" }, '••••••••') : null;
|
|
2987
|
+
default: {
|
|
2988
|
+
const text = CellRenderer.renderValue(dt, value, (_l = item.listItems) !== null && _l !== void 0 ? _l : [], ctx.locale);
|
|
2989
|
+
return text || null;
|
|
2990
|
+
}
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
function renderFieldValue(ctx, item, rawValue) {
|
|
2994
|
+
if (rawValue == null || rawValue === '')
|
|
2995
|
+
return null;
|
|
2996
|
+
if (item.multiple && Array.isArray(rawValue)) {
|
|
2997
|
+
const rendered = rawValue.map(v => renderSingleFieldValue(ctx, item, v));
|
|
2998
|
+
if (rendered.every(r => typeof r === 'string' || r == null)) {
|
|
2999
|
+
return rendered.filter(Boolean).join(', ') || null;
|
|
3000
|
+
}
|
|
3001
|
+
return (h("span", null, rendered.map((r, i) => (h("span", { key: String(i) }, r, i < rendered.length - 1 ? ', ' : '')))));
|
|
3002
|
+
}
|
|
3003
|
+
return renderSingleFieldValue(ctx, item, rawValue);
|
|
3004
|
+
}
|
|
3005
|
+
function renderHistoryBadge(ctx, item, raw) {
|
|
3006
|
+
var _a, _b, _c;
|
|
3007
|
+
const hist = (_a = item.historyEnabled) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.historyEnabled;
|
|
3008
|
+
if (!hist || !item.name)
|
|
3009
|
+
return null;
|
|
3010
|
+
const history = (_c = raw === null || raw === void 0 ? void 0 : raw.history) !== null && _c !== void 0 ? _c : [];
|
|
3011
|
+
if (!history.length)
|
|
3012
|
+
return null;
|
|
3013
|
+
const sorted = [...history].sort((a, b) => b.until.localeCompare(a.until));
|
|
3014
|
+
const isOpen = ctx.openHistoryField === item.name;
|
|
3015
|
+
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) => {
|
|
3016
|
+
e.stopPropagation();
|
|
3017
|
+
ctx.on.toggleHistory(isOpen ? null : item.name);
|
|
3018
|
+
} }, 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), ")")))))));
|
|
3019
|
+
}
|
|
3020
|
+
function renderField(ctx, item) {
|
|
3021
|
+
var _a, _b;
|
|
3022
|
+
if (!item.name)
|
|
3023
|
+
return null;
|
|
3024
|
+
const raw = ctx.data[item.name];
|
|
3025
|
+
const hist = (_a = item.historyEnabled) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.historyEnabled;
|
|
3026
|
+
const rawValue = hist && raw !== null && typeof raw === 'object' && 'current' in raw
|
|
3027
|
+
? raw.current
|
|
3028
|
+
: raw;
|
|
3029
|
+
const renderedValue = renderFieldValue(ctx, item, rawValue);
|
|
3030
|
+
if (item.header) {
|
|
3031
|
+
return (h("h1", { class: "mrd-layout-section__field-header", key: item.name }, typeof renderedValue === 'string' ? renderedValue : rawValue != null ? String(rawValue) : item.label));
|
|
3032
|
+
}
|
|
3033
|
+
if (renderedValue == null)
|
|
3034
|
+
return null;
|
|
3035
|
+
const isBlock = item.dataType === ClientLayoutItemFieldDataType.TEXTBLOCK
|
|
3036
|
+
|| item.dataType === ClientLayoutItemFieldDataType.LONGTEXT
|
|
3037
|
+
|| item.dataType === ClientLayoutItemFieldDataType.JSON;
|
|
3038
|
+
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))));
|
|
3039
|
+
}
|
|
3040
|
+
|
|
3041
|
+
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}`;
|
|
2769
3042
|
|
|
2770
3043
|
const MrdLayoutSection = class {
|
|
2771
3044
|
constructor(hostRef) {
|
|
@@ -2847,14 +3120,8 @@ const MrdLayoutSection = class {
|
|
|
2847
3120
|
}
|
|
2848
3121
|
}
|
|
2849
3122
|
}
|
|
2850
|
-
viewKeyFor(item) {
|
|
2851
|
-
var _a, _b, _c, _d;
|
|
2852
|
-
if (item.type === ClientLayoutItemType.RELATED_VIEW)
|
|
2853
|
-
return (_b = (_a = item.relatedClass) !== null && _a !== void 0 ? _a : item.name) !== null && _b !== void 0 ? _b : '';
|
|
2854
|
-
return (_d = (_c = item.dataClass) !== null && _c !== void 0 ? _c : item.name) !== null && _d !== void 0 ? _d : '';
|
|
2855
|
-
}
|
|
2856
3123
|
emitLoadImages() {
|
|
2857
|
-
for (const item of
|
|
3124
|
+
for (const item of flattenItems(this.items)) {
|
|
2858
3125
|
if (item.type === ClientLayoutItemType.FIELD && item.dataType === ClientLayoutItemFieldDataType.IMAGE) {
|
|
2859
3126
|
const fieldName = item.name;
|
|
2860
3127
|
const raw = this.data[fieldName];
|
|
@@ -2864,15 +3131,6 @@ const MrdLayoutSection = class {
|
|
|
2864
3131
|
}
|
|
2865
3132
|
}
|
|
2866
3133
|
}
|
|
2867
|
-
flattenItems(items) {
|
|
2868
|
-
const result = [];
|
|
2869
|
-
for (const item of items) {
|
|
2870
|
-
result.push(item);
|
|
2871
|
-
if (item.items)
|
|
2872
|
-
result.push(...this.flattenItems(item.items));
|
|
2873
|
-
}
|
|
2874
|
-
return result;
|
|
2875
|
-
}
|
|
2876
3134
|
/** Inject search results. Pass dataClass to target a specific SEARCH item; omit when there is only one. */
|
|
2877
3135
|
async setSearchResults(results, dataClass) {
|
|
2878
3136
|
const key = dataClass !== null && dataClass !== void 0 ? dataClass : this.resolveSearchKey();
|
|
@@ -2938,113 +3196,26 @@ const MrdLayoutSection = class {
|
|
|
2938
3196
|
}
|
|
2939
3197
|
resolveSearchKey() {
|
|
2940
3198
|
var _a;
|
|
2941
|
-
const items =
|
|
3199
|
+
const items = flattenItems(this.items).filter(i => i.type === ClientLayoutItemType.SEARCH);
|
|
2942
3200
|
if (items.length === 1)
|
|
2943
3201
|
return (_a = items[0].dataClass) !== null && _a !== void 0 ? _a : null;
|
|
2944
|
-
return null;
|
|
2945
|
-
}
|
|
2946
|
-
renderSingleFieldValue(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 (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)));
|
|
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 = this.imagePreviews[item.name];
|
|
2973
|
-
if (previewUrl) {
|
|
2974
|
-
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 })));
|
|
2975
|
-
}
|
|
2976
|
-
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));
|
|
2977
|
-
}
|
|
2978
|
-
case ClientLayoutItemFieldDataType.BOOLEAN:
|
|
2979
|
-
return (h("span", { class: `mrd-layout-section__boolean mrd-layout-section__boolean--${value ? 'true' : 'false'}` }, value ? t('yes', this.locale) : t('no', this.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 : [], this.locale);
|
|
2997
|
-
return text || null;
|
|
2998
|
-
}
|
|
2999
|
-
}
|
|
3000
|
-
}
|
|
3001
|
-
renderFieldValue(item, rawValue) {
|
|
3002
|
-
if (rawValue == null || rawValue === '')
|
|
3003
|
-
return null;
|
|
3004
|
-
if (item.multiple && Array.isArray(rawValue)) {
|
|
3005
|
-
const rendered = rawValue.map(v => this.renderSingleFieldValue(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 this.renderSingleFieldValue(item, rawValue);
|
|
3202
|
+
return null;
|
|
3012
3203
|
}
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
e.stopPropagation();
|
|
3026
|
-
this.openHistoryField = isOpen ? null : item.name;
|
|
3027
|
-
} }, 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), ")")))))));
|
|
3204
|
+
fieldCtx() {
|
|
3205
|
+
return {
|
|
3206
|
+
locale: this.locale,
|
|
3207
|
+
data: this.data,
|
|
3208
|
+
imagePreviews: this.imagePreviews,
|
|
3209
|
+
openHistoryField: this.openHistoryField,
|
|
3210
|
+
on: {
|
|
3211
|
+
download: detail => this.mrdDownload.emit(detail),
|
|
3212
|
+
openImage: url => { this.imagePreviewUrl = url; },
|
|
3213
|
+
toggleHistory: fieldName => { this.openHistoryField = fieldName; },
|
|
3214
|
+
},
|
|
3215
|
+
};
|
|
3028
3216
|
}
|
|
3029
3217
|
renderField(item) {
|
|
3030
|
-
|
|
3031
|
-
if (!item.name)
|
|
3032
|
-
return null;
|
|
3033
|
-
const raw = this.data[item.name];
|
|
3034
|
-
const hist = (_a = item.historyEnabled) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.historyEnabled;
|
|
3035
|
-
const rawValue = hist && raw !== null && typeof raw === 'object' && 'current' in raw
|
|
3036
|
-
? raw.current
|
|
3037
|
-
: raw;
|
|
3038
|
-
const renderedValue = this.renderFieldValue(item, rawValue);
|
|
3039
|
-
if (item.header) {
|
|
3040
|
-
return (h("h1", { class: "mrd-layout-section__field-header", key: item.name }, typeof renderedValue === 'string' ? renderedValue : rawValue != null ? String(rawValue) : item.label));
|
|
3041
|
-
}
|
|
3042
|
-
if (renderedValue == null)
|
|
3043
|
-
return null;
|
|
3044
|
-
const isBlock = item.dataType === ClientLayoutItemFieldDataType.TEXTBLOCK
|
|
3045
|
-
|| item.dataType === ClientLayoutItemFieldDataType.LONGTEXT
|
|
3046
|
-
|| item.dataType === ClientLayoutItemFieldDataType.JSON;
|
|
3047
|
-
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))));
|
|
3218
|
+
return renderField(this.fieldCtx(), item);
|
|
3048
3219
|
}
|
|
3049
3220
|
renderRelation(item) {
|
|
3050
3221
|
var _a, _b, _c;
|
|
@@ -3077,7 +3248,7 @@ const MrdLayoutSection = class {
|
|
|
3077
3248
|
}
|
|
3078
3249
|
renderRelatedView(item) {
|
|
3079
3250
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
3080
|
-
const key =
|
|
3251
|
+
const key = viewKeyFor(item);
|
|
3081
3252
|
if (!key)
|
|
3082
3253
|
return null;
|
|
3083
3254
|
if (!item.view)
|
|
@@ -3089,15 +3260,19 @@ const MrdLayoutSection = class {
|
|
|
3089
3260
|
// The API publishes `archetypes` on the VIEW/RELATED_VIEW item itself
|
|
3090
3261
|
// (sibling of `view`), not inside `view`.
|
|
3091
3262
|
const docArchetype = resolveArchetype((_g = item.archetypes) !== null && _g !== void 0 ? _g : (_h = item.view) === null || _h === void 0 ? void 0 : _h.archetypes, ARCHETYPE_DOCUMENT);
|
|
3263
|
+
// Canonical parent href for single-container seeding: use the RELATED_VIEW's
|
|
3264
|
+
// fromClass (base class) rather than the route class, so polymorphic subtypes
|
|
3265
|
+
// resolve to the same container the documents actually reference.
|
|
3266
|
+
const containerHref = buildContainerHref(item, selfHref, parentId);
|
|
3092
3267
|
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
|
|
3093
|
-
? this.renderDocumentContainer(item, key, parentId, docArchetype)
|
|
3268
|
+
? this.renderDocumentContainer(item, key, parentId, docArchetype, containerHref)
|
|
3094
3269
|
: this.renderTable(item, key, parentId)));
|
|
3095
3270
|
}
|
|
3096
3271
|
/** Document collection view: owns the view-switch + collection actions and
|
|
3097
3272
|
* swaps between the folder tree and the flat table. Events are re-emitted to
|
|
3098
3273
|
* the host with the view key, exactly as the raw list/table events were. */
|
|
3099
|
-
renderDocumentContainer(item, key, parentId, archetype) {
|
|
3100
|
-
return (h("mrd-document-container", { item: item, archetype: archetype, parentId: parentId, viewKey: key, locale: this.locale, onMrdLoadDistinct: (e) => {
|
|
3274
|
+
renderDocumentContainer(item, key, parentId, archetype, containerHref) {
|
|
3275
|
+
return (h("mrd-document-container", { item: item, archetype: archetype, parentId: parentId, containerHref: containerHref, viewKey: key, locale: this.locale, onMrdLoadDistinct: (e) => {
|
|
3101
3276
|
e.stopPropagation();
|
|
3102
3277
|
this.mrdLoadViewDistinct.emit(Object.assign({ name: key }, e.detail));
|
|
3103
3278
|
}, onMrdLoadPage: (e) => {
|
|
@@ -3193,7 +3368,7 @@ const MrdLayoutSection = class {
|
|
|
3193
3368
|
}
|
|
3194
3369
|
render() {
|
|
3195
3370
|
const docArchetype = resolveArchetype(this.archetypes, ARCHETYPE_DOCUMENT);
|
|
3196
|
-
return (h(Host, { key: '
|
|
3371
|
+
return (h(Host, { key: '5d778188356a25ea13d45745dc5ed573ab2b2ef0' }, h("div", { key: '0b673a4bcf8b36cd21662bb8a3506cc3f30edb04', class: "mrd-layout-section" }, docArchetype
|
|
3197
3372
|
? this.renderDocumentObject(docArchetype)
|
|
3198
3373
|
: this.items.map(item => this.renderItem(item))), this.renderImageModal()));
|
|
3199
3374
|
}
|
|
@@ -3204,9 +3379,9 @@ const MrdLayoutSection = class {
|
|
|
3204
3379
|
}]
|
|
3205
3380
|
}; }
|
|
3206
3381
|
};
|
|
3207
|
-
MrdLayoutSection.style =
|
|
3382
|
+
MrdLayoutSection.style = mrdLayoutSectionCss();
|
|
3208
3383
|
|
|
3209
|
-
const
|
|
3384
|
+
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}`;
|
|
3210
3385
|
|
|
3211
3386
|
const MrdListField = class {
|
|
3212
3387
|
constructor(hostRef) {
|
|
@@ -3229,22 +3404,12 @@ const MrdListField = class {
|
|
|
3229
3404
|
if (this.multiple) {
|
|
3230
3405
|
const vals = Array.from(select.selectedOptions).map(o => o.value);
|
|
3231
3406
|
this.selected = vals;
|
|
3232
|
-
|
|
3233
|
-
this.error = t('required', this.locale);
|
|
3234
|
-
}
|
|
3235
|
-
else {
|
|
3236
|
-
this.error = '';
|
|
3237
|
-
}
|
|
3407
|
+
this.error = requiredError(vals, this.required, this.locale);
|
|
3238
3408
|
this.mrdChange.emit({ name: this.name, value: vals });
|
|
3239
3409
|
}
|
|
3240
3410
|
else {
|
|
3241
3411
|
const val = select.value;
|
|
3242
|
-
|
|
3243
|
-
this.error = t('required', this.locale);
|
|
3244
|
-
}
|
|
3245
|
-
else {
|
|
3246
|
-
this.error = '';
|
|
3247
|
-
}
|
|
3412
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
3248
3413
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
3249
3414
|
}
|
|
3250
3415
|
};
|
|
@@ -3259,12 +3424,7 @@ const MrdListField = class {
|
|
|
3259
3424
|
else {
|
|
3260
3425
|
this.selected = [...this.selected, key];
|
|
3261
3426
|
}
|
|
3262
|
-
|
|
3263
|
-
this.error = t('required', this.locale);
|
|
3264
|
-
}
|
|
3265
|
-
else {
|
|
3266
|
-
this.error = '';
|
|
3267
|
-
}
|
|
3427
|
+
this.error = requiredError(this.selected, this.required, this.locale);
|
|
3268
3428
|
this.mrdChange.emit({ name: this.name, value: this.selected });
|
|
3269
3429
|
};
|
|
3270
3430
|
}
|
|
@@ -3288,22 +3448,22 @@ const MrdListField = class {
|
|
|
3288
3448
|
const hasError = !!this.error;
|
|
3289
3449
|
const currentValue = Array.isArray(this.value) ? ((_a = this.value[0]) !== null && _a !== void 0 ? _a : '') : ((_b = this.value) !== null && _b !== void 0 ? _b : '');
|
|
3290
3450
|
if (this.multiple) {
|
|
3291
|
-
return (h(Host, null, h("div", { class: "mrd-list-field" },
|
|
3451
|
+
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 => {
|
|
3292
3452
|
var _a, _b;
|
|
3293
3453
|
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)));
|
|
3294
|
-
})),
|
|
3454
|
+
})), h(FieldError, { base: "mrd-list-field", error: this.error }))));
|
|
3295
3455
|
}
|
|
3296
|
-
return (h(Host, null, h("div", { class: "mrd-list-field" },
|
|
3456
|
+
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 => {
|
|
3297
3457
|
var _a, _b;
|
|
3298
3458
|
const bg = (_b = (_a = lv.backgroundColor) !== null && _a !== void 0 ? _a : lv.color) !== null && _b !== void 0 ? _b : null;
|
|
3299
3459
|
const style = bg ? { backgroundColor: bg, color: this.getContrastColor(bg) } : {};
|
|
3300
3460
|
return (h("option", { key: lv.key, value: lv.key, selected: lv.key === currentValue, style: style }, lv.label));
|
|
3301
|
-
})),
|
|
3461
|
+
})), h(FieldError, { base: "mrd-list-field", error: this.error }))));
|
|
3302
3462
|
}
|
|
3303
3463
|
};
|
|
3304
|
-
MrdListField.style =
|
|
3464
|
+
MrdListField.style = mrdListFieldCss();
|
|
3305
3465
|
|
|
3306
|
-
const
|
|
3466
|
+
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}`;
|
|
3307
3467
|
|
|
3308
3468
|
const MrdLongtextField = class {
|
|
3309
3469
|
constructor(hostRef) {
|
|
@@ -3324,23 +3484,17 @@ const MrdLongtextField = class {
|
|
|
3324
3484
|
};
|
|
3325
3485
|
this.handleBlur = (e) => {
|
|
3326
3486
|
const val = e.target.value;
|
|
3327
|
-
|
|
3328
|
-
this.error = t('required', this.locale);
|
|
3329
|
-
}
|
|
3330
|
-
else {
|
|
3331
|
-
this.error = '';
|
|
3332
|
-
}
|
|
3487
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
3333
3488
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
3334
3489
|
};
|
|
3335
3490
|
}
|
|
3336
3491
|
render() {
|
|
3337
|
-
|
|
3338
|
-
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))));
|
|
3492
|
+
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 }))));
|
|
3339
3493
|
}
|
|
3340
3494
|
};
|
|
3341
|
-
MrdLongtextField.style =
|
|
3495
|
+
MrdLongtextField.style = mrdLongtextFieldCss();
|
|
3342
3496
|
|
|
3343
|
-
const
|
|
3497
|
+
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)}`;
|
|
3344
3498
|
|
|
3345
3499
|
const MrdNumberField = class {
|
|
3346
3500
|
constructor(hostRef) {
|
|
@@ -3411,12 +3565,12 @@ const MrdNumberField = class {
|
|
|
3411
3565
|
const hasError = !!this.error;
|
|
3412
3566
|
const suffix = this.dataType === ClientLayoutItemFieldDataType.PERCENTAGE ? '%' :
|
|
3413
3567
|
this.dataType === ClientLayoutItemFieldDataType.DECIMAL ? '' : '';
|
|
3414
|
-
return (h(Host, { key: '
|
|
3568
|
+
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 }))));
|
|
3415
3569
|
}
|
|
3416
3570
|
};
|
|
3417
|
-
MrdNumberField.style =
|
|
3571
|
+
MrdNumberField.style = mrdNumberFieldCss();
|
|
3418
3572
|
|
|
3419
|
-
const
|
|
3573
|
+
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}`;
|
|
3420
3574
|
|
|
3421
3575
|
const MrdRelationField = class {
|
|
3422
3576
|
constructor(hostRef) {
|
|
@@ -3517,12 +3671,7 @@ const MrdRelationField = class {
|
|
|
3517
3671
|
this.showResults = false;
|
|
3518
3672
|
this.mrdChange.emit({ name: this.name, value: result.id });
|
|
3519
3673
|
}
|
|
3520
|
-
|
|
3521
|
-
this.error = t('required', this.locale);
|
|
3522
|
-
}
|
|
3523
|
-
else {
|
|
3524
|
-
this.error = '';
|
|
3525
|
-
}
|
|
3674
|
+
this.error = requiredError(this.selectedItems, this.required, this.locale);
|
|
3526
3675
|
};
|
|
3527
3676
|
this.handleRemoveSelected = (id) => {
|
|
3528
3677
|
this.selectedItems = this.selectedItems.filter(i => i.id !== id);
|
|
@@ -3531,12 +3680,7 @@ const MrdRelationField = class {
|
|
|
3531
3680
|
};
|
|
3532
3681
|
this.handleDropdownChange = (e) => {
|
|
3533
3682
|
const val = e.target.value;
|
|
3534
|
-
|
|
3535
|
-
this.error = t('required', this.locale);
|
|
3536
|
-
}
|
|
3537
|
-
else {
|
|
3538
|
-
this.error = '';
|
|
3539
|
-
}
|
|
3683
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
3540
3684
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
3541
3685
|
};
|
|
3542
3686
|
this.handleBlur = () => {
|
|
@@ -3647,19 +3791,19 @@ const MrdRelationField = class {
|
|
|
3647
3791
|
const hasError = !!this.error;
|
|
3648
3792
|
if (this.editBehavior === ClientLayoutItemRelationEditBehavior.DROPDOWN) {
|
|
3649
3793
|
const currentValue = this.getValueHref();
|
|
3650
|
-
return (h(Host, null, h("div", { class: "mrd-relation-field" },
|
|
3794
|
+
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 }))));
|
|
3651
3795
|
}
|
|
3652
3796
|
if (this.displayType === ClientLayoutItemRelationDisplayType.DROPDOWN) {
|
|
3653
3797
|
const currentValue = Array.isArray(this.value) ? ((_a = this.value[0]) !== null && _a !== void 0 ? _a : '') : ((_b = this.value) !== null && _b !== void 0 ? _b : '');
|
|
3654
|
-
return (h(Host, null, h("div", { class: "mrd-relation-field" },
|
|
3798
|
+
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 }))));
|
|
3655
3799
|
}
|
|
3656
3800
|
// SEARCH mode
|
|
3657
|
-
const labelEl =
|
|
3801
|
+
const labelEl = h(FieldLabel, { base: "mrd-relation-field", label: this.label, required: this.required });
|
|
3658
3802
|
// Single selection: show selected value as a badge, hide the search input
|
|
3659
3803
|
if (!this.multiple && this.selectedItems.length > 0) {
|
|
3660
|
-
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")),
|
|
3804
|
+
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 }))));
|
|
3661
3805
|
}
|
|
3662
|
-
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)))))))),
|
|
3806
|
+
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 }))));
|
|
3663
3807
|
}
|
|
3664
3808
|
get el() { return getElement(this); }
|
|
3665
3809
|
static get watchers() { return {
|
|
@@ -3671,9 +3815,9 @@ const MrdRelationField = class {
|
|
|
3671
3815
|
}]
|
|
3672
3816
|
}; }
|
|
3673
3817
|
};
|
|
3674
|
-
MrdRelationField.style =
|
|
3818
|
+
MrdRelationField.style = mrdRelationFieldCss();
|
|
3675
3819
|
|
|
3676
|
-
const
|
|
3820
|
+
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}`;
|
|
3677
3821
|
|
|
3678
3822
|
const MrdSecretField = class {
|
|
3679
3823
|
constructor(hostRef) {
|
|
@@ -3694,38 +3838,439 @@ const MrdSecretField = class {
|
|
|
3694
3838
|
};
|
|
3695
3839
|
this.handleBlur = (e) => {
|
|
3696
3840
|
const val = e.target.value;
|
|
3697
|
-
|
|
3698
|
-
this.error = t('required', this.locale);
|
|
3699
|
-
}
|
|
3700
|
-
else {
|
|
3701
|
-
this.error = '';
|
|
3702
|
-
}
|
|
3841
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
3703
3842
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
3704
3843
|
};
|
|
3705
3844
|
}
|
|
3706
3845
|
render() {
|
|
3707
|
-
|
|
3708
|
-
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
|
|
3846
|
+
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
|
|
3709
3847
|
? (h("span", { class: "mrd-secret-field__masked", "aria-label": this.label }, this.value ? '••••••••' : ''))
|
|
3710
|
-
: (h("input", { class:
|
|
3848
|
+
: (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 }))));
|
|
3711
3849
|
}
|
|
3712
3850
|
};
|
|
3713
|
-
MrdSecretField.style =
|
|
3714
|
-
|
|
3715
|
-
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}`;
|
|
3851
|
+
MrdSecretField.style = mrdSecretFieldCss();
|
|
3716
3852
|
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
*
|
|
3720
|
-
|
|
3721
|
-
/** Breedte van de filterpopup in px — voor overflow-correctie. */
|
|
3722
|
-
const POPUP_WIDTH = 280;
|
|
3853
|
+
/**
|
|
3854
|
+
* Pure sort/filter/aggregation query logic for mrd-table.
|
|
3855
|
+
* No component state — everything is passed in.
|
|
3856
|
+
*/
|
|
3723
3857
|
const TEXT_TYPES = new Set(['TEXT', 'TEXTBLOCK', 'EMAIL', 'HYPERLINK']);
|
|
3724
3858
|
const NUMERIC_TYPES = new Set(['INTEGER', 'DECIMAL', 'PERCENTAGE', 'CURRENCY']);
|
|
3725
3859
|
const DATE_TYPES = new Set(['DATE', 'DATETIME', 'TIME']);
|
|
3726
3860
|
const NO_FILTER_TYPES = new Set(['FILE', 'IMAGE']);
|
|
3727
3861
|
/** Column types that cannot be sorted or filtered (not stored in PostgreSQL). */
|
|
3728
3862
|
const NON_INTERACTIVE_TYPES = new Set(['LONGTEXT', 'JSON', 'FILE', 'IMAGE']);
|
|
3863
|
+
function parseDefaultSort(defaultSort) {
|
|
3864
|
+
var _a;
|
|
3865
|
+
if (!defaultSort)
|
|
3866
|
+
return { field: '', dir: 'asc' };
|
|
3867
|
+
const parts = defaultSort.split(',');
|
|
3868
|
+
return { field: parts[0].trim(), dir: ((_a = parts[1]) === null || _a === void 0 ? void 0 : _a.trim()) === 'desc' ? 'desc' : 'asc' };
|
|
3869
|
+
}
|
|
3870
|
+
/** Raw sort query-param value, e.g. "name" or "name,desc". */
|
|
3871
|
+
function buildSortParam(field, dir) {
|
|
3872
|
+
if (!field)
|
|
3873
|
+
return '';
|
|
3874
|
+
return dir === 'desc' ? `${field},desc` : field;
|
|
3875
|
+
}
|
|
3876
|
+
/** Query params for a page request: page + sort + filterClass + view filters + active column filters. */
|
|
3877
|
+
function buildTableQueryParams(opts) {
|
|
3878
|
+
var _a, _b;
|
|
3879
|
+
const p = new URLSearchParams();
|
|
3880
|
+
if (opts.page > 0)
|
|
3881
|
+
p.set('page', String(opts.page));
|
|
3882
|
+
if (opts.sort)
|
|
3883
|
+
p.set('sort', opts.sort);
|
|
3884
|
+
if (opts.filterClass)
|
|
3885
|
+
p.set('type', opts.filterClass);
|
|
3886
|
+
applyViewFilters(p, opts.viewFilters);
|
|
3887
|
+
for (const f of opts.activeFilters) {
|
|
3888
|
+
if (f.operator === 'isEmpty') {
|
|
3889
|
+
p.set(f.field, '');
|
|
3890
|
+
continue;
|
|
3891
|
+
}
|
|
3892
|
+
if (f.operator === 'isNotEmpty') {
|
|
3893
|
+
p.set(f.field + '_notempty', 'true');
|
|
3894
|
+
continue;
|
|
3895
|
+
}
|
|
3896
|
+
if (f.operator === 'startsWith') {
|
|
3897
|
+
p.set(f.field + '_startswith', String((_a = f.value) !== null && _a !== void 0 ? _a : ''));
|
|
3898
|
+
continue;
|
|
3899
|
+
}
|
|
3900
|
+
if ((_b = f.values) === null || _b === void 0 ? void 0 : _b.length) {
|
|
3901
|
+
p.set(f.field, f.values.join(','));
|
|
3902
|
+
continue;
|
|
3903
|
+
}
|
|
3904
|
+
if (f.value != null)
|
|
3905
|
+
p.set(f.field, String(f.value));
|
|
3906
|
+
if (f.from != null)
|
|
3907
|
+
p.set(f.field + '_from', String(f.from));
|
|
3908
|
+
if (f.to != null)
|
|
3909
|
+
p.set(f.field + '_to', String(f.to));
|
|
3910
|
+
}
|
|
3911
|
+
return p.toString();
|
|
3912
|
+
}
|
|
3913
|
+
/** Groups aggregate columns by function; null when the view has no aggregates. */
|
|
3914
|
+
function buildAggregationParams(columns) {
|
|
3915
|
+
var _a;
|
|
3916
|
+
const groups = { sum: [], avg: [], count: [] };
|
|
3917
|
+
for (const col of columns) {
|
|
3918
|
+
if (col.type !== 'FIELD' || !col.aggregate)
|
|
3919
|
+
continue;
|
|
3920
|
+
const fn = col.aggregate.toLowerCase();
|
|
3921
|
+
if (fn in groups)
|
|
3922
|
+
groups[fn].push((_a = col.name) !== null && _a !== void 0 ? _a : '');
|
|
3923
|
+
}
|
|
3924
|
+
const params = {};
|
|
3925
|
+
if (groups.sum.length)
|
|
3926
|
+
params.sum = groups.sum;
|
|
3927
|
+
if (groups.avg.length)
|
|
3928
|
+
params.avg = groups.avg;
|
|
3929
|
+
if (groups.count.length)
|
|
3930
|
+
params.count = groups.count;
|
|
3931
|
+
return Object.keys(params).length > 0 ? params : null;
|
|
3932
|
+
}
|
|
3933
|
+
/** Aggregation query string: the page-0 query params without page/sort, plus sum/avg/count. */
|
|
3934
|
+
function buildAggregationQs(basePageQs, columns) {
|
|
3935
|
+
var _a, _b, _c;
|
|
3936
|
+
const p = new URLSearchParams(basePageQs);
|
|
3937
|
+
p.delete('page');
|
|
3938
|
+
p.delete('sort');
|
|
3939
|
+
const groups = buildAggregationParams(columns);
|
|
3940
|
+
if ((_a = groups === null || groups === void 0 ? void 0 : groups.sum) === null || _a === void 0 ? void 0 : _a.length)
|
|
3941
|
+
p.set('sum', groups.sum.join(','));
|
|
3942
|
+
if ((_b = groups === null || groups === void 0 ? void 0 : groups.avg) === null || _b === void 0 ? void 0 : _b.length)
|
|
3943
|
+
p.set('avg', groups.avg.join(','));
|
|
3944
|
+
if ((_c = groups === null || groups === void 0 ? void 0 : groups.count) === null || _c === void 0 ? void 0 : _c.length)
|
|
3945
|
+
p.set('count', groups.count.join(','));
|
|
3946
|
+
return p.toString();
|
|
3947
|
+
}
|
|
3948
|
+
/** True when the pending filter actually constrains anything. */
|
|
3949
|
+
function filterHasValue(f) {
|
|
3950
|
+
if (f.operator === 'isEmpty' || f.operator === 'isNotEmpty')
|
|
3951
|
+
return true;
|
|
3952
|
+
if (f.values !== undefined && f.values.length > 0)
|
|
3953
|
+
return true;
|
|
3954
|
+
if (f.value != null && f.value !== '')
|
|
3955
|
+
return true;
|
|
3956
|
+
if (typeof f.value === 'boolean')
|
|
3957
|
+
return true;
|
|
3958
|
+
if (f.from != null && f.from !== '')
|
|
3959
|
+
return true;
|
|
3960
|
+
if (f.to != null && f.to !== '')
|
|
3961
|
+
return true;
|
|
3962
|
+
return false;
|
|
3963
|
+
}
|
|
3964
|
+
// ── DATETIME filters: the user edits local "YYYY-MM-DD" dates, the API stores UTC ISO ──
|
|
3965
|
+
/** UTC ISO string at the start (midnight) of the given local day. */
|
|
3966
|
+
function dateLocalToUTCStart(dateStr) {
|
|
3967
|
+
if (!dateStr)
|
|
3968
|
+
return dateStr;
|
|
3969
|
+
const [year, month, day] = dateStr.split('-').map(Number);
|
|
3970
|
+
return new Date(year, month - 1, day).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
3971
|
+
}
|
|
3972
|
+
/** Start of the day AFTER the given local date (exclusive range end). */
|
|
3973
|
+
function dateLocalToUTCEndExclusive(dateStr) {
|
|
3974
|
+
if (!dateStr)
|
|
3975
|
+
return dateStr;
|
|
3976
|
+
const [year, month, day] = dateStr.split('-').map(Number);
|
|
3977
|
+
return new Date(year, month - 1, day + 1).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
3978
|
+
}
|
|
3979
|
+
/** Stored UTC ISO string back to the local "YYYY-MM-DD" date. */
|
|
3980
|
+
function utcISOToLocalDate(utcStr) {
|
|
3981
|
+
if (!utcStr)
|
|
3982
|
+
return utcStr;
|
|
3983
|
+
const d = new Date(utcStr);
|
|
3984
|
+
if (isNaN(d.getTime()))
|
|
3985
|
+
return utcStr;
|
|
3986
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
3987
|
+
}
|
|
3988
|
+
/** The stored "to" is the exclusive end (next midnight); subtract a day to recover the entered date. */
|
|
3989
|
+
function utcISOToLocalDateExclusiveEnd(utcStr) {
|
|
3990
|
+
if (!utcStr)
|
|
3991
|
+
return utcStr;
|
|
3992
|
+
const d = new Date(utcStr);
|
|
3993
|
+
if (isNaN(d.getTime()))
|
|
3994
|
+
return utcStr;
|
|
3995
|
+
d.setDate(d.getDate() - 1);
|
|
3996
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
3997
|
+
}
|
|
3998
|
+
/** Applies the local→UTC conversion when a DATETIME filter is submitted.
|
|
3999
|
+
* Exact date → range covering the full local day. */
|
|
4000
|
+
function normalizeDatetimeFilter(f) {
|
|
4001
|
+
const normalized = Object.assign({}, f);
|
|
4002
|
+
if (f.dataType === 'DATETIME' && f.operator !== 'isEmpty' && f.operator !== 'isNotEmpty') {
|
|
4003
|
+
if (typeof normalized.value === 'string' && normalized.value) {
|
|
4004
|
+
normalized.from = dateLocalToUTCStart(normalized.value);
|
|
4005
|
+
normalized.to = dateLocalToUTCEndExclusive(normalized.value);
|
|
4006
|
+
normalized.value = undefined;
|
|
4007
|
+
}
|
|
4008
|
+
else {
|
|
4009
|
+
if (typeof normalized.from === 'string' && normalized.from)
|
|
4010
|
+
normalized.from = dateLocalToUTCStart(normalized.from);
|
|
4011
|
+
if (typeof normalized.to === 'string' && normalized.to)
|
|
4012
|
+
normalized.to = dateLocalToUTCEndExclusive(normalized.to);
|
|
4013
|
+
}
|
|
4014
|
+
}
|
|
4015
|
+
return normalized;
|
|
4016
|
+
}
|
|
4017
|
+
/** Converts a stored DATETIME filter back to local dates for the popup.
|
|
4018
|
+
* A range covering a single local day is restored to exact-date mode. */
|
|
4019
|
+
function datetimeFilterToDisplay(existing) {
|
|
4020
|
+
const display = Object.assign({}, existing);
|
|
4021
|
+
if (typeof display.from === 'string' && display.from)
|
|
4022
|
+
display.from = utcISOToLocalDate(display.from);
|
|
4023
|
+
if (typeof display.to === 'string' && display.to)
|
|
4024
|
+
display.to = utcISOToLocalDateExclusiveEnd(display.to);
|
|
4025
|
+
if (display.from && display.to && display.from === display.to) {
|
|
4026
|
+
return Object.assign(Object.assign({}, display), { value: display.from, from: undefined, to: undefined });
|
|
4027
|
+
}
|
|
4028
|
+
return display;
|
|
4029
|
+
}
|
|
4030
|
+
|
|
4031
|
+
/**
|
|
4032
|
+
* Stateless render parts of mrd-table. All state and handlers stay in the
|
|
4033
|
+
* component; these components receive plain values and callbacks.
|
|
4034
|
+
*/
|
|
4035
|
+
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" }))));
|
|
4036
|
+
const TEXTBLOCK_MAX = 200;
|
|
4037
|
+
const TableCell = ({ col, row, locale, onDownload, onOpenTextblock, onOpenJson }) => {
|
|
4038
|
+
var _a, _b, _c;
|
|
4039
|
+
const dataType = (_a = col.dataType) !== null && _a !== void 0 ? _a : '';
|
|
4040
|
+
const isNumeric = col.type === 'FIELD' && NUMERIC_TYPES.has(dataType);
|
|
4041
|
+
const isFile = col.type === 'FIELD' && (dataType === 'FILE' || dataType === 'IMAGE');
|
|
4042
|
+
if (isFile) {
|
|
4043
|
+
const name = (_b = col.name) !== null && _b !== void 0 ? _b : '';
|
|
4044
|
+
const fileVal = row === null || row === void 0 ? void 0 : row[name];
|
|
4045
|
+
const href = fileVal === null || fileVal === void 0 ? void 0 : fileVal.href;
|
|
4046
|
+
const fileName = fileVal === null || fileVal === void 0 ? void 0 : fileVal.fileName;
|
|
4047
|
+
return (h("td", { class: "mrd-table__cell" }, href && fileName ? (h("button", { class: "mrd-table__file-btn", title: fileName, onClick: (e) => {
|
|
4048
|
+
e.stopPropagation();
|
|
4049
|
+
onDownload({ href, fileName });
|
|
4050
|
+
} }, 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))) : ''));
|
|
4051
|
+
}
|
|
4052
|
+
if (dataType === 'JSON') {
|
|
4053
|
+
const name = (_c = col.name) !== null && _c !== void 0 ? _c : '';
|
|
4054
|
+
const rawValue = name ? row === null || row === void 0 ? void 0 : row[name] : undefined;
|
|
4055
|
+
if (rawValue == null || rawValue === '')
|
|
4056
|
+
return h("td", { class: "mrd-table__cell" });
|
|
4057
|
+
const compactHtml = CellRenderer.formatJson(rawValue, true);
|
|
4058
|
+
const prettyHtml = CellRenderer.formatJson(rawValue, false);
|
|
4059
|
+
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")));
|
|
4060
|
+
}
|
|
4061
|
+
if (dataType === 'TEXTBLOCK') {
|
|
4062
|
+
const full = CellRenderer.render(col, row, locale);
|
|
4063
|
+
if (full.length <= TEXTBLOCK_MAX) {
|
|
4064
|
+
return h("td", { class: "mrd-table__cell" }, full);
|
|
4065
|
+
}
|
|
4066
|
+
const preview = full.slice(0, TEXTBLOCK_MAX) + '…';
|
|
4067
|
+
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")));
|
|
4068
|
+
}
|
|
4069
|
+
const value = CellRenderer.render(col, row, locale);
|
|
4070
|
+
return (h("td", { class: `mrd-table__cell${isNumeric ? ' mrd-table__cell--numeric' : ''}` }, value));
|
|
4071
|
+
};
|
|
4072
|
+
/** Formats the aggregation total for one column, '' when not applicable. */
|
|
4073
|
+
function formatAggregationValue(col, aggregations, locale) {
|
|
4074
|
+
var _a;
|
|
4075
|
+
if (col.type !== 'FIELD' || !col.aggregate || !aggregations)
|
|
4076
|
+
return '';
|
|
4077
|
+
const fn = col.aggregate.toLowerCase();
|
|
4078
|
+
const aggData = aggregations[fn];
|
|
4079
|
+
const val = typeof aggData === 'object' && aggData !== null
|
|
4080
|
+
? aggData[(_a = col.name) !== null && _a !== void 0 ? _a : '']
|
|
4081
|
+
: undefined;
|
|
4082
|
+
if (val == null)
|
|
4083
|
+
return '';
|
|
4084
|
+
const dt = col.dataType;
|
|
4085
|
+
if (dt === 'INTEGER')
|
|
4086
|
+
return formatNumber(val, locale, { maximumFractionDigits: 0 });
|
|
4087
|
+
if (dt === 'PERCENTAGE')
|
|
4088
|
+
return formatPercentage(val, locale);
|
|
4089
|
+
if (dt === 'CURRENCY' && col.currencyCode)
|
|
4090
|
+
return formatCurrency(val, col.currencyCode, locale);
|
|
4091
|
+
return formatNumber(val, locale);
|
|
4092
|
+
}
|
|
4093
|
+
const TotalsRow = ({ columns, aggregations, locale }) => {
|
|
4094
|
+
if (!aggregations)
|
|
4095
|
+
return null;
|
|
4096
|
+
if (!columns.some(c => c.type === 'FIELD' && c.aggregate))
|
|
4097
|
+
return null;
|
|
4098
|
+
return (h("tfoot", null, h("tr", { class: "mrd-table__totals-row" }, columns.map(col => {
|
|
4099
|
+
var _a;
|
|
4100
|
+
const val = formatAggregationValue(col, aggregations, locale);
|
|
4101
|
+
const isNumeric = col.type === 'FIELD' && NUMERIC_TYPES.has((_a = col.dataType) !== null && _a !== void 0 ? _a : '');
|
|
4102
|
+
return (h("td", { class: `mrd-table__totals-cell${isNumeric ? ' mrd-table__totals-cell--numeric' : ''}` }, val));
|
|
4103
|
+
}))));
|
|
4104
|
+
};
|
|
4105
|
+
const TextblockModal = ({ text, locale, onClose }) => {
|
|
4106
|
+
if (text === null)
|
|
4107
|
+
return null;
|
|
4108
|
+
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))));
|
|
4109
|
+
};
|
|
4110
|
+
const JsonModal = ({ html, locale, onClose }) => {
|
|
4111
|
+
if (html === null)
|
|
4112
|
+
return null;
|
|
4113
|
+
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 }))));
|
|
4114
|
+
};
|
|
4115
|
+
const Toolbar = ({ locale, filterMode, filterCount, actions, views, activeViewIdx, viewPopoverOpen, createPickerOpen, createTypes, cb }) => {
|
|
4116
|
+
var _a;
|
|
4117
|
+
const hasActions = actions.length > 0;
|
|
4118
|
+
const hasViewSwitcher = views.length > 1;
|
|
4119
|
+
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: () => {
|
|
4120
|
+
if (i !== activeViewIdx)
|
|
4121
|
+
cb.onViewSwitch(i);
|
|
4122
|
+
cb.onCloseViewPopover();
|
|
4123
|
+
} }, 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 => {
|
|
4124
|
+
var _a, _b;
|
|
4125
|
+
const pickerTypes = a.action === 'create' ? createTypes : null;
|
|
4126
|
+
if (pickerTypes === null || pickerTypes === void 0 ? void 0 : pickerTypes.length) {
|
|
4127
|
+
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
|
|
4128
|
+
? h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, h("use", { href: a.icon }))
|
|
4129
|
+
: 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)))))));
|
|
4130
|
+
}
|
|
4131
|
+
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
|
|
4132
|
+
? h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, h("use", { href: a.icon }))
|
|
4133
|
+
: a.label, h("span", { class: "mrd-table__action-tooltip" }, a.label)));
|
|
4134
|
+
})))));
|
|
4135
|
+
};
|
|
4136
|
+
|
|
4137
|
+
const FilterEditor = ({ col, dataType, openFilterCol, pendingFilter, locale, cb }) => {
|
|
4138
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4139
|
+
const pf = pendingFilter;
|
|
4140
|
+
if (NO_FILTER_TYPES.has(dataType)) {
|
|
4141
|
+
return h("p", { class: "mrd-table__filter-no-support" }, t('filter_no_support', locale));
|
|
4142
|
+
}
|
|
4143
|
+
if (dataType === 'BOOLEAN') {
|
|
4144
|
+
const boolOp = pf.operator;
|
|
4145
|
+
const noValueOp = boolOp === 'isEmpty' || boolOp === 'isNotEmpty';
|
|
4146
|
+
return (h("div", { class: "mrd-table__filter-radio-group" }, [
|
|
4147
|
+
{ labelKey: 'filter_all', value: null },
|
|
4148
|
+
{ labelKey: 'yes', value: true },
|
|
4149
|
+
{ labelKey: 'no', value: false },
|
|
4150
|
+
].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))));
|
|
4151
|
+
}
|
|
4152
|
+
if (dataType === 'LIST') {
|
|
4153
|
+
const items = (_a = col.listItems) !== null && _a !== void 0 ? _a : [];
|
|
4154
|
+
const selected = (_b = pf.values) !== null && _b !== void 0 ? _b : [];
|
|
4155
|
+
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)))));
|
|
4156
|
+
}
|
|
4157
|
+
if (TEXT_TYPES.has(dataType) || dataType === 'RELATION') {
|
|
4158
|
+
const op = (_c = pf.operator) !== null && _c !== void 0 ? _c : 'startsWith';
|
|
4159
|
+
const noInput = op === 'isEmpty' || op === 'isNotEmpty';
|
|
4160
|
+
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => cb.onSetPending('operator', e.target.value) }, [
|
|
4161
|
+
{ val: 'startsWith', labelKey: 'filter_starts_with' },
|
|
4162
|
+
{ val: 'equals', labelKey: 'filter_equals' },
|
|
4163
|
+
{ val: 'isEmpty', labelKey: 'filter_is_empty' },
|
|
4164
|
+
{ val: 'isNotEmpty', labelKey: 'filter_is_not_empty' },
|
|
4165
|
+
].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) }))));
|
|
4166
|
+
}
|
|
4167
|
+
if (NUMERIC_TYPES.has(dataType)) {
|
|
4168
|
+
const numOp = pf.operator;
|
|
4169
|
+
const noInput = numOp === 'isEmpty' || numOp === 'isNotEmpty';
|
|
4170
|
+
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4171
|
+
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4172
|
+
const val = e.target.value;
|
|
4173
|
+
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4174
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined }));
|
|
4175
|
+
}
|
|
4176
|
+
else {
|
|
4177
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: undefined }));
|
|
4178
|
+
}
|
|
4179
|
+
} }, 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) })))))));
|
|
4180
|
+
}
|
|
4181
|
+
if (dataType === 'DATETIME') {
|
|
4182
|
+
const dtOp = pf.operator;
|
|
4183
|
+
const noInput = dtOp === 'isEmpty' || dtOp === 'isNotEmpty';
|
|
4184
|
+
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4185
|
+
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4186
|
+
const val = e.target.value;
|
|
4187
|
+
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4188
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined }));
|
|
4189
|
+
}
|
|
4190
|
+
else {
|
|
4191
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: undefined }));
|
|
4192
|
+
}
|
|
4193
|
+
} }, 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) })))))));
|
|
4194
|
+
}
|
|
4195
|
+
if (DATE_TYPES.has(dataType)) {
|
|
4196
|
+
const inputType = dataType === 'DATE' ? 'date' : 'time';
|
|
4197
|
+
const dtdOp = pf.operator;
|
|
4198
|
+
const noInput = dtdOp === 'isEmpty' || dtdOp === 'isNotEmpty';
|
|
4199
|
+
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4200
|
+
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4201
|
+
const val = e.target.value;
|
|
4202
|
+
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4203
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined }));
|
|
4204
|
+
}
|
|
4205
|
+
else {
|
|
4206
|
+
cb.onReplacePending(Object.assign(Object.assign({}, pf), { operator: undefined }));
|
|
4207
|
+
}
|
|
4208
|
+
} }, 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) })))))));
|
|
4209
|
+
}
|
|
4210
|
+
return null;
|
|
4211
|
+
};
|
|
4212
|
+
const FilterPopup = (props) => {
|
|
4213
|
+
var _a;
|
|
4214
|
+
const { col, openFilterCol, popupPos, sortField, sortDir, locale, cb } = props;
|
|
4215
|
+
const label = (_a = col.label) !== null && _a !== void 0 ? _a : openFilterCol;
|
|
4216
|
+
const sortActive = sortField === openFilterCol;
|
|
4217
|
+
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)))));
|
|
4218
|
+
};
|
|
4219
|
+
|
|
4220
|
+
/**
|
|
4221
|
+
* Pure window/paging maths for the mrd-table virtual scroll.
|
|
4222
|
+
* The window state itself stays @State in the component; these
|
|
4223
|
+
* functions only compute values from it.
|
|
4224
|
+
*/
|
|
4225
|
+
const BUFFER = 10;
|
|
4226
|
+
/** Wait this long (ms) after the last scroll event before requesting pages,
|
|
4227
|
+
* so pages the user quickly scrolls past are skipped. */
|
|
4228
|
+
const REQUEST_DEBOUNCE_MS = 150;
|
|
4229
|
+
function visibleCount(tableHeight, rowHeight) {
|
|
4230
|
+
return Math.ceil(tableHeight / rowHeight);
|
|
4231
|
+
}
|
|
4232
|
+
/** Render window (with buffer) for the given scroll offset. */
|
|
4233
|
+
function computeWindow(scrollTop, rowHeight, tableHeight, total) {
|
|
4234
|
+
const visStart = Math.floor(scrollTop / rowHeight);
|
|
4235
|
+
const visEnd = Math.min(visStart + visibleCount(tableHeight, rowHeight), total - 1);
|
|
4236
|
+
return {
|
|
4237
|
+
renderStart: Math.max(0, visStart - BUFFER),
|
|
4238
|
+
renderEnd: Math.min(total - 1, visEnd + BUFFER),
|
|
4239
|
+
};
|
|
4240
|
+
}
|
|
4241
|
+
/** First/last page (0-based) covering the given row window. */
|
|
4242
|
+
function pageRange(start, end, pageSize) {
|
|
4243
|
+
return { firstPage: Math.floor(start / pageSize), lastPage: Math.floor(end / pageSize) };
|
|
4244
|
+
}
|
|
4245
|
+
function getRowFromPages(pages, index, pageSize) {
|
|
4246
|
+
var _a;
|
|
4247
|
+
const page = pages.get(Math.floor(index / pageSize));
|
|
4248
|
+
return (_a = page === null || page === void 0 ? void 0 : page[index % pageSize]) !== null && _a !== void 0 ? _a : null;
|
|
4249
|
+
}
|
|
4250
|
+
/** Authoritative row count: a page shorter than pageSize is the last page,
|
|
4251
|
+
* so the true total cannot exceed its end index. */
|
|
4252
|
+
function computeEffectiveTotal(loadedPages, pageSize, baseTotal) {
|
|
4253
|
+
let effectiveTotal = baseTotal;
|
|
4254
|
+
for (const [pageNum, pageRows] of loadedPages) {
|
|
4255
|
+
if (pageRows.length < pageSize) {
|
|
4256
|
+
effectiveTotal = Math.min(effectiveTotal, pageNum * pageSize + pageRows.length);
|
|
4257
|
+
}
|
|
4258
|
+
}
|
|
4259
|
+
return effectiveTotal;
|
|
4260
|
+
}
|
|
4261
|
+
/** True when some loaded page was short — the exact total is then known. */
|
|
4262
|
+
function isTotalKnownFromPages(loadedPages, pageSize) {
|
|
4263
|
+
for (const rows of loadedPages.values()) {
|
|
4264
|
+
if (rows.length < pageSize)
|
|
4265
|
+
return true;
|
|
4266
|
+
}
|
|
4267
|
+
return false;
|
|
4268
|
+
}
|
|
4269
|
+
|
|
4270
|
+
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__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}`;
|
|
4271
|
+
|
|
4272
|
+
/** Breedte van de filterpopup in px — voor overflow-correctie. */
|
|
4273
|
+
const POPUP_WIDTH = 280;
|
|
3729
4274
|
const MrdTable = class {
|
|
3730
4275
|
constructor(hostRef) {
|
|
3731
4276
|
registerInstance(this, hostRef);
|
|
@@ -3741,6 +4286,8 @@ const MrdTable = class {
|
|
|
3741
4286
|
this.keydownHandler = null;
|
|
3742
4287
|
this.createPickerClickHandler = null;
|
|
3743
4288
|
this.viewPopoverClickHandler = null;
|
|
4289
|
+
/** Guards against scheduling more than one column-width measurement per freeze. */
|
|
4290
|
+
this.colWidthMeasureScheduled = false;
|
|
3744
4291
|
// ── Props ──────────────────────────────────────────────────────────────────
|
|
3745
4292
|
/** The VIEW or RELATED_VIEW layout item. Contains view config, dataClass, fromClass, actions etc. */
|
|
3746
4293
|
this.item = null;
|
|
@@ -3797,13 +4344,10 @@ const MrdTable = class {
|
|
|
3797
4344
|
this.minKnownTotal = 0;
|
|
3798
4345
|
this.handleScroll = (e) => {
|
|
3799
4346
|
const scroller = e.currentTarget;
|
|
3800
|
-
const
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
this.scrollTop = scrollTop;
|
|
3805
|
-
this.renderStart = Math.max(0, visStart - BUFFER);
|
|
3806
|
-
this.renderEnd = Math.min(total - 1, visEnd + BUFFER);
|
|
4347
|
+
const { renderStart, renderEnd } = computeWindow(scroller.scrollTop, this.rowHeight, this.tableHeight, this.baseTotal);
|
|
4348
|
+
this.scrollTop = scroller.scrollTop;
|
|
4349
|
+
this.renderStart = renderStart;
|
|
4350
|
+
this.renderEnd = renderEnd;
|
|
3807
4351
|
this.requestPagesForWindow(this.renderStart, this.renderEnd);
|
|
3808
4352
|
};
|
|
3809
4353
|
}
|
|
@@ -3825,16 +4369,9 @@ const MrdTable = class {
|
|
|
3825
4369
|
}
|
|
3826
4370
|
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
3827
4371
|
applyDefaultSort(defaultSort) {
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
this.sortField = parts[0].trim();
|
|
3832
|
-
this.sortDir = ((_a = parts[1]) === null || _a === void 0 ? void 0 : _a.trim()) === 'desc' ? 'desc' : 'asc';
|
|
3833
|
-
}
|
|
3834
|
-
else {
|
|
3835
|
-
this.sortField = '';
|
|
3836
|
-
this.sortDir = 'asc';
|
|
3837
|
-
}
|
|
4372
|
+
const { field, dir } = parseDefaultSort(defaultSort);
|
|
4373
|
+
this.sortField = field;
|
|
4374
|
+
this.sortDir = dir;
|
|
3838
4375
|
}
|
|
3839
4376
|
// ── Public API ─────────────────────────────────────────────────────────────
|
|
3840
4377
|
/**
|
|
@@ -3851,6 +4388,7 @@ const MrdTable = class {
|
|
|
3851
4388
|
this.loadedPages = new Map();
|
|
3852
4389
|
this.requestedPages = new Set();
|
|
3853
4390
|
this.colWidths = [];
|
|
4391
|
+
this.colWidthMeasureScheduled = false;
|
|
3854
4392
|
this.scrollTop = 0;
|
|
3855
4393
|
this.renderStart = 0;
|
|
3856
4394
|
// Always fill the visible viewport on init — totalElements may be stale from a
|
|
@@ -3931,21 +4469,34 @@ const MrdTable = class {
|
|
|
3931
4469
|
}
|
|
3932
4470
|
}
|
|
3933
4471
|
componentDidRender() {
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
4472
|
+
// Freeze header widths once the first data page has rendered. The measurement
|
|
4473
|
+
// reads offsetWidth and writes the colWidths @State, which would trigger a
|
|
4474
|
+
// re-render *during* the render cycle if done synchronously here. Defer it to a
|
|
4475
|
+
// writeTask so the state mutation happens outside the render pass (avoids the
|
|
4476
|
+
// Stencil "state/prop changed during rendering" warning and potential loops).
|
|
4477
|
+
if (this.colWidths.length === 0 &&
|
|
4478
|
+
!this.colWidthMeasureScheduled &&
|
|
4479
|
+
this.loadedPages.size > 0 &&
|
|
4480
|
+
this.totalElements > 0) {
|
|
4481
|
+
this.colWidthMeasureScheduled = true;
|
|
4482
|
+
writeTask(() => {
|
|
4483
|
+
this.colWidthMeasureScheduled = false;
|
|
4484
|
+
// Re-check: state may have changed (e.g. a reset) between scheduling and running.
|
|
4485
|
+
if (this.colWidths.length !== 0)
|
|
4486
|
+
return;
|
|
4487
|
+
const ths = this.el.querySelectorAll('.mrd-table__header');
|
|
4488
|
+
if (ths.length > 0) {
|
|
4489
|
+
this.colWidths = Array.from(ths).map(th => th.offsetWidth);
|
|
4490
|
+
}
|
|
4491
|
+
});
|
|
3939
4492
|
}
|
|
3940
4493
|
}
|
|
3941
4494
|
// ── Paging / scroll helpers ────────────────────────────────────────────────
|
|
3942
4495
|
visibleCount() {
|
|
3943
|
-
return
|
|
4496
|
+
return visibleCount(this.tableHeight, this.rowHeight);
|
|
3944
4497
|
}
|
|
3945
4498
|
sortParam() {
|
|
3946
|
-
|
|
3947
|
-
return '';
|
|
3948
|
-
return this.sortDir === 'desc' ? `${this.sortField},desc` : this.sortField;
|
|
4499
|
+
return buildSortParam(this.sortField, this.sortDir);
|
|
3949
4500
|
}
|
|
3950
4501
|
/** Stable ordered list: primary view first, then alternatives (from the item prop). */
|
|
3951
4502
|
get allViews() {
|
|
@@ -3971,14 +4522,16 @@ const MrdTable = class {
|
|
|
3971
4522
|
* VIEW: /excel/{dataClass}
|
|
3972
4523
|
* RELATED_VIEW: /excel/{fromClass}/{parentId}/{dataClass} */
|
|
3973
4524
|
buildExcelPath() {
|
|
3974
|
-
var _a
|
|
4525
|
+
var _a;
|
|
3975
4526
|
const v = this.allViews[this.activeViewIdx];
|
|
3976
4527
|
if (!v)
|
|
3977
4528
|
return '';
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
4529
|
+
return '/excel' + buildListPath({
|
|
4530
|
+
isRelatedView: ((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'RELATED_VIEW',
|
|
4531
|
+
fromClass: v.fromClass,
|
|
4532
|
+
parentId: this.parentId,
|
|
4533
|
+
dataClass: v.dataClass,
|
|
4534
|
+
});
|
|
3982
4535
|
}
|
|
3983
4536
|
buildActionDetail(action, basicType) {
|
|
3984
4537
|
var _a, _b, _c;
|
|
@@ -3998,80 +4551,28 @@ const MrdTable = class {
|
|
|
3998
4551
|
* VIEW: /{dataClass}
|
|
3999
4552
|
* RELATED_VIEW: /{fromClass}/{parentId}/{dataClass} */
|
|
4000
4553
|
buildDataPath() {
|
|
4001
|
-
var _a
|
|
4554
|
+
var _a;
|
|
4002
4555
|
const v = this.allViews[this.activeViewIdx];
|
|
4003
4556
|
if (!v)
|
|
4004
4557
|
return '';
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4558
|
+
return buildListPath({
|
|
4559
|
+
isRelatedView: ((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'RELATED_VIEW',
|
|
4560
|
+
fromClass: v.fromClass,
|
|
4561
|
+
parentId: this.parentId,
|
|
4562
|
+
dataClass: v.dataClass,
|
|
4563
|
+
});
|
|
4009
4564
|
}
|
|
4010
4565
|
/** Build query params for a page request from current sort, view filters, filterClass and active column filters. */
|
|
4011
4566
|
buildQueryParams(page) {
|
|
4012
|
-
var _a
|
|
4567
|
+
var _a;
|
|
4013
4568
|
const v = this.allViews[this.activeViewIdx];
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
if (filterClass)
|
|
4022
|
-
p.set('type', filterClass);
|
|
4023
|
-
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 : [])) {
|
|
4024
|
-
if (!f.name)
|
|
4025
|
-
continue;
|
|
4026
|
-
if (f.operator === 'EMPTY') {
|
|
4027
|
-
p.set(f.name, '');
|
|
4028
|
-
continue;
|
|
4029
|
-
}
|
|
4030
|
-
if (f.operator === 'NOT_EMPTY') {
|
|
4031
|
-
p.set(f.name + '_notempty', 'true');
|
|
4032
|
-
continue;
|
|
4033
|
-
}
|
|
4034
|
-
if (f.operator === 'STARTS_WITH') {
|
|
4035
|
-
p.set(f.name + '_startswith', String((_c = f.value) !== null && _c !== void 0 ? _c : ''));
|
|
4036
|
-
continue;
|
|
4037
|
-
}
|
|
4038
|
-
if (f.operator === 'FROM') {
|
|
4039
|
-
p.set(f.name + '_from', String((_d = f.value) !== null && _d !== void 0 ? _d : ''));
|
|
4040
|
-
continue;
|
|
4041
|
-
}
|
|
4042
|
-
if (f.operator === 'TO') {
|
|
4043
|
-
p.set(f.name + '_to', String((_e = f.value) !== null && _e !== void 0 ? _e : ''));
|
|
4044
|
-
continue;
|
|
4045
|
-
}
|
|
4046
|
-
if (f.value != null) {
|
|
4047
|
-
p.set(f.name, String(f.value));
|
|
4048
|
-
}
|
|
4049
|
-
}
|
|
4050
|
-
for (const f of this.activeFilters.values()) {
|
|
4051
|
-
if (f.operator === 'isEmpty') {
|
|
4052
|
-
p.set(f.field, '');
|
|
4053
|
-
continue;
|
|
4054
|
-
}
|
|
4055
|
-
if (f.operator === 'isNotEmpty') {
|
|
4056
|
-
p.set(f.field + '_notempty', 'true');
|
|
4057
|
-
continue;
|
|
4058
|
-
}
|
|
4059
|
-
if (f.operator === 'startsWith') {
|
|
4060
|
-
p.set(f.field + '_startswith', String((_f = f.value) !== null && _f !== void 0 ? _f : ''));
|
|
4061
|
-
continue;
|
|
4062
|
-
}
|
|
4063
|
-
if ((_g = f.values) === null || _g === void 0 ? void 0 : _g.length) {
|
|
4064
|
-
p.set(f.field, f.values.join(','));
|
|
4065
|
-
continue;
|
|
4066
|
-
}
|
|
4067
|
-
if (f.value != null)
|
|
4068
|
-
p.set(f.field, String(f.value));
|
|
4069
|
-
if (f.from != null)
|
|
4070
|
-
p.set(f.field + '_from', String(f.from));
|
|
4071
|
-
if (f.to != null)
|
|
4072
|
-
p.set(f.field + '_to', String(f.to));
|
|
4073
|
-
}
|
|
4074
|
-
return p.toString();
|
|
4569
|
+
return buildTableQueryParams({
|
|
4570
|
+
page,
|
|
4571
|
+
sort: this.sortParam(),
|
|
4572
|
+
filterClass: v === null || v === void 0 ? void 0 : v.filterClass,
|
|
4573
|
+
viewFilters: (_a = v === null || v === void 0 ? void 0 : v.view) === null || _a === void 0 ? void 0 : _a.filter,
|
|
4574
|
+
activeFilters: this.activeFilters.values(),
|
|
4575
|
+
});
|
|
4075
4576
|
}
|
|
4076
4577
|
get columns() {
|
|
4077
4578
|
var _a, _b, _c;
|
|
@@ -4126,11 +4627,7 @@ const MrdTable = class {
|
|
|
4126
4627
|
isTotalKnown() {
|
|
4127
4628
|
if (this.aggregationsTotal != null)
|
|
4128
4629
|
return true;
|
|
4129
|
-
|
|
4130
|
-
if (rows.length < this.pageSize)
|
|
4131
|
-
return true;
|
|
4132
|
-
}
|
|
4133
|
-
return false;
|
|
4630
|
+
return isTotalKnownFromPages(this.loadedPages, this.pageSize);
|
|
4134
4631
|
}
|
|
4135
4632
|
/** Effective total: aggregations-response > totalElements prop > minKnownTotal from setPage(). */
|
|
4136
4633
|
get baseTotal() {
|
|
@@ -4141,61 +4638,9 @@ const MrdTable = class {
|
|
|
4141
4638
|
return this.minKnownTotal;
|
|
4142
4639
|
}
|
|
4143
4640
|
// ── Aggregation helpers ────────────────────────────────────────────────────
|
|
4144
|
-
buildAggregationParams() {
|
|
4145
|
-
var _a;
|
|
4146
|
-
const groups = { sum: [], avg: [], count: [] };
|
|
4147
|
-
for (const col of this.columns) {
|
|
4148
|
-
if (col.type !== 'FIELD' || !col.aggregate)
|
|
4149
|
-
continue;
|
|
4150
|
-
const fn = col.aggregate.toLowerCase();
|
|
4151
|
-
if (fn in groups)
|
|
4152
|
-
groups[fn].push((_a = col.name) !== null && _a !== void 0 ? _a : '');
|
|
4153
|
-
}
|
|
4154
|
-
const params = {};
|
|
4155
|
-
if (groups.sum.length)
|
|
4156
|
-
params.sum = groups.sum;
|
|
4157
|
-
if (groups.avg.length)
|
|
4158
|
-
params.avg = groups.avg;
|
|
4159
|
-
if (groups.count.length)
|
|
4160
|
-
params.count = groups.count;
|
|
4161
|
-
return Object.keys(params).length > 0 ? params : null;
|
|
4162
|
-
}
|
|
4163
|
-
buildAggregationQs() {
|
|
4164
|
-
var _a, _b, _c;
|
|
4165
|
-
const p = new URLSearchParams(this.buildQueryParams(0));
|
|
4166
|
-
p.delete('page');
|
|
4167
|
-
p.delete('sort');
|
|
4168
|
-
const groups = this.buildAggregationParams();
|
|
4169
|
-
if ((_a = groups === null || groups === void 0 ? void 0 : groups.sum) === null || _a === void 0 ? void 0 : _a.length)
|
|
4170
|
-
p.set('sum', groups.sum.join(','));
|
|
4171
|
-
if ((_b = groups === null || groups === void 0 ? void 0 : groups.avg) === null || _b === void 0 ? void 0 : _b.length)
|
|
4172
|
-
p.set('avg', groups.avg.join(','));
|
|
4173
|
-
if ((_c = groups === null || groups === void 0 ? void 0 : groups.count) === null || _c === void 0 ? void 0 : _c.length)
|
|
4174
|
-
p.set('count', groups.count.join(','));
|
|
4175
|
-
return p.toString();
|
|
4176
|
-
}
|
|
4177
4641
|
emitLoadAggregations() {
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
renderAggregationValue(col) {
|
|
4181
|
-
var _a;
|
|
4182
|
-
if (col.type !== 'FIELD' || !col.aggregate || !this.aggregations)
|
|
4183
|
-
return '';
|
|
4184
|
-
const fn = col.aggregate.toLowerCase();
|
|
4185
|
-
const aggData = this.aggregations[fn];
|
|
4186
|
-
const val = typeof aggData === 'object' && aggData !== null
|
|
4187
|
-
? aggData[(_a = col.name) !== null && _a !== void 0 ? _a : '']
|
|
4188
|
-
: undefined;
|
|
4189
|
-
if (val == null)
|
|
4190
|
-
return '';
|
|
4191
|
-
const dt = col.dataType;
|
|
4192
|
-
if (dt === 'INTEGER')
|
|
4193
|
-
return formatNumber(val, this.locale, { maximumFractionDigits: 0 });
|
|
4194
|
-
if (dt === 'PERCENTAGE')
|
|
4195
|
-
return formatPercentage(val, this.locale);
|
|
4196
|
-
if (dt === 'CURRENCY' && col.currencyCode)
|
|
4197
|
-
return formatCurrency(val, col.currencyCode, this.locale);
|
|
4198
|
-
return formatNumber(val, this.locale);
|
|
4642
|
+
const qs = this.buildQueryParams(0);
|
|
4643
|
+
this.mrdLoadAggregations.emit({ path: this.buildDataPath(), qs, aggQs: buildAggregationQs(qs, this.columns) });
|
|
4199
4644
|
}
|
|
4200
4645
|
// ── Reset pagination ───────────────────────────────────────────────────────
|
|
4201
4646
|
/** Reset pagination state and scroll to top (used after sort or filter change). */
|
|
@@ -4208,6 +4653,7 @@ const MrdTable = class {
|
|
|
4208
4653
|
this.loadedPages = new Map();
|
|
4209
4654
|
this.requestedPages = new Set();
|
|
4210
4655
|
this.colWidths = [];
|
|
4656
|
+
this.colWidthMeasureScheduled = false;
|
|
4211
4657
|
this.scrollTop = 0;
|
|
4212
4658
|
this.renderStart = 0;
|
|
4213
4659
|
this.minKnownTotal = 0;
|
|
@@ -4237,8 +4683,7 @@ const MrdTable = class {
|
|
|
4237
4683
|
this.emitPagesForWindow(this.renderStart, this.renderEnd);
|
|
4238
4684
|
}
|
|
4239
4685
|
emitPagesForWindow(start, end) {
|
|
4240
|
-
const firstPage =
|
|
4241
|
-
const lastPage = Math.floor(end / this.pageSize);
|
|
4686
|
+
const { firstPage, lastPage } = pageRange(start, end, this.pageSize);
|
|
4242
4687
|
const next = new Set(this.requestedPages);
|
|
4243
4688
|
let changed = false;
|
|
4244
4689
|
for (let p = firstPage; p <= lastPage; p++) {
|
|
@@ -4252,13 +4697,10 @@ const MrdTable = class {
|
|
|
4252
4697
|
this.requestedPages = next;
|
|
4253
4698
|
}
|
|
4254
4699
|
getRow(i) {
|
|
4255
|
-
|
|
4256
|
-
const page = this.loadedPages.get(Math.floor(i / this.pageSize));
|
|
4257
|
-
return (_a = page === null || page === void 0 ? void 0 : page[i % this.pageSize]) !== null && _a !== void 0 ? _a : null;
|
|
4700
|
+
return getRowFromPages(this.loadedPages, i, this.pageSize);
|
|
4258
4701
|
}
|
|
4259
4702
|
requestPagesForWindow(start, end) {
|
|
4260
|
-
const firstPage =
|
|
4261
|
-
const lastPage = Math.floor(end / this.pageSize);
|
|
4703
|
+
const { firstPage, lastPage } = pageRange(start, end, this.pageSize);
|
|
4262
4704
|
let anyNew = false;
|
|
4263
4705
|
for (let p = firstPage; p <= lastPage; p++) {
|
|
4264
4706
|
if (!this.loadedPages.has(p) && !this.requestedPages.has(p) && !this.pendingPages.has(p)) {
|
|
@@ -4320,17 +4762,7 @@ const MrdTable = class {
|
|
|
4320
4762
|
// If from and to cover the same local day it was an exact-date filter — restore
|
|
4321
4763
|
// to exact mode so the user sees the single-date input again.
|
|
4322
4764
|
if (dataType === 'DATETIME' && existing && existing.operator !== 'isEmpty' && existing.operator !== 'isNotEmpty') {
|
|
4323
|
-
|
|
4324
|
-
if (typeof display.from === 'string' && display.from)
|
|
4325
|
-
display.from = this.utcISOToLocalDate(display.from);
|
|
4326
|
-
if (typeof display.to === 'string' && display.to)
|
|
4327
|
-
display.to = this.utcISOToLocalDateExclusiveEnd(display.to);
|
|
4328
|
-
if (display.from && display.to && display.from === display.to) {
|
|
4329
|
-
this.pendingFilter = Object.assign(Object.assign({}, display), { value: display.from, from: undefined, to: undefined });
|
|
4330
|
-
}
|
|
4331
|
-
else {
|
|
4332
|
-
this.pendingFilter = display;
|
|
4333
|
-
}
|
|
4765
|
+
this.pendingFilter = datetimeFilterToDisplay(existing);
|
|
4334
4766
|
}
|
|
4335
4767
|
else {
|
|
4336
4768
|
this.pendingFilter = existing ? Object.assign({}, existing) : { field: name, dataType, operator: defaultOperator };
|
|
@@ -4396,81 +4828,15 @@ const MrdTable = class {
|
|
|
4396
4828
|
const current = (_b = (_a = this.pendingFilter) === null || _a === void 0 ? void 0 : _a.values) !== null && _b !== void 0 ? _b : [];
|
|
4397
4829
|
this.pendingFilter = Object.assign(Object.assign({}, this.pendingFilter), { values: checked ? [...current, key] : current.filter(k => k !== key) });
|
|
4398
4830
|
}
|
|
4399
|
-
filterHasValue(f) {
|
|
4400
|
-
if (f.operator === 'isEmpty' || f.operator === 'isNotEmpty')
|
|
4401
|
-
return true;
|
|
4402
|
-
if (f.values !== undefined && f.values.length > 0)
|
|
4403
|
-
return true;
|
|
4404
|
-
if (f.value != null && f.value !== '')
|
|
4405
|
-
return true;
|
|
4406
|
-
if (typeof f.value === 'boolean')
|
|
4407
|
-
return true;
|
|
4408
|
-
if (f.from != null && f.from !== '')
|
|
4409
|
-
return true;
|
|
4410
|
-
if (f.to != null && f.to !== '')
|
|
4411
|
-
return true;
|
|
4412
|
-
return false;
|
|
4413
|
-
}
|
|
4414
|
-
// Convert a local "YYYY-MM-DD" date string to the UTC ISO string at the
|
|
4415
|
-
// start of that local day (midnight). new Date(y, m, d) uses local time.
|
|
4416
|
-
dateLocalToUTCStart(dateStr) {
|
|
4417
|
-
if (!dateStr)
|
|
4418
|
-
return dateStr;
|
|
4419
|
-
const [year, month, day] = dateStr.split('-').map(Number);
|
|
4420
|
-
return new Date(year, month - 1, day).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
4421
|
-
}
|
|
4422
|
-
// Start of the day AFTER the given local date (exclusive range end).
|
|
4423
|
-
dateLocalToUTCEndExclusive(dateStr) {
|
|
4424
|
-
if (!dateStr)
|
|
4425
|
-
return dateStr;
|
|
4426
|
-
const [year, month, day] = dateStr.split('-').map(Number);
|
|
4427
|
-
return new Date(year, month - 1, day + 1).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
4428
|
-
}
|
|
4429
|
-
// Convert a stored UTC ISO string back to the local "YYYY-MM-DD" date.
|
|
4430
|
-
utcISOToLocalDate(utcStr) {
|
|
4431
|
-
if (!utcStr)
|
|
4432
|
-
return utcStr;
|
|
4433
|
-
const d = new Date(utcStr);
|
|
4434
|
-
if (isNaN(d.getTime()))
|
|
4435
|
-
return utcStr;
|
|
4436
|
-
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
4437
|
-
}
|
|
4438
|
-
// The stored "to" value is the exclusive end (midnight of the next day).
|
|
4439
|
-
// Subtract one day to recover the local date the user entered.
|
|
4440
|
-
utcISOToLocalDateExclusiveEnd(utcStr) {
|
|
4441
|
-
if (!utcStr)
|
|
4442
|
-
return utcStr;
|
|
4443
|
-
const d = new Date(utcStr);
|
|
4444
|
-
if (isNaN(d.getTime()))
|
|
4445
|
-
return utcStr;
|
|
4446
|
-
d.setDate(d.getDate() - 1);
|
|
4447
|
-
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
4448
|
-
}
|
|
4449
4831
|
applyFilter() {
|
|
4450
4832
|
const f = this.pendingFilter;
|
|
4451
4833
|
if (!(f === null || f === void 0 ? void 0 : f.field)) {
|
|
4452
4834
|
this.closeFilterPopup();
|
|
4453
4835
|
return;
|
|
4454
4836
|
}
|
|
4455
|
-
|
|
4456
|
-
// Exact date → range covering the full local day (from = midnight, to = next midnight).
|
|
4457
|
-
// "to" is always the exclusive end (midnight of the next local day).
|
|
4458
|
-
let normalized = Object.assign({}, f);
|
|
4459
|
-
if (f.dataType === 'DATETIME' && f.operator !== 'isEmpty' && f.operator !== 'isNotEmpty') {
|
|
4460
|
-
if (typeof normalized.value === 'string' && normalized.value) {
|
|
4461
|
-
normalized.from = this.dateLocalToUTCStart(normalized.value);
|
|
4462
|
-
normalized.to = this.dateLocalToUTCEndExclusive(normalized.value);
|
|
4463
|
-
normalized.value = undefined;
|
|
4464
|
-
}
|
|
4465
|
-
else {
|
|
4466
|
-
if (typeof normalized.from === 'string' && normalized.from)
|
|
4467
|
-
normalized.from = this.dateLocalToUTCStart(normalized.from);
|
|
4468
|
-
if (typeof normalized.to === 'string' && normalized.to)
|
|
4469
|
-
normalized.to = this.dateLocalToUTCEndExclusive(normalized.to);
|
|
4470
|
-
}
|
|
4471
|
-
}
|
|
4837
|
+
const normalized = normalizeDatetimeFilter(f);
|
|
4472
4838
|
const next = new Map(this.activeFilters);
|
|
4473
|
-
if (
|
|
4839
|
+
if (filterHasValue(normalized)) {
|
|
4474
4840
|
next.set(normalized.field, normalized);
|
|
4475
4841
|
}
|
|
4476
4842
|
else {
|
|
@@ -4525,140 +4891,53 @@ const MrdTable = class {
|
|
|
4525
4891
|
toggleViewPopover(e) {
|
|
4526
4892
|
e.stopPropagation();
|
|
4527
4893
|
if (this.viewPopoverOpen) {
|
|
4528
|
-
this.
|
|
4529
|
-
if (this.viewPopoverClickHandler) {
|
|
4530
|
-
document.removeEventListener('click', this.viewPopoverClickHandler);
|
|
4531
|
-
this.viewPopoverClickHandler = null;
|
|
4532
|
-
}
|
|
4894
|
+
this.closeViewPopover();
|
|
4533
4895
|
return;
|
|
4534
4896
|
}
|
|
4535
4897
|
this.viewPopoverOpen = true;
|
|
4536
|
-
this.viewPopoverClickHandler = () =>
|
|
4537
|
-
|
|
4898
|
+
this.viewPopoverClickHandler = () => this.closeViewPopover();
|
|
4899
|
+
document.addEventListener('click', this.viewPopoverClickHandler);
|
|
4900
|
+
}
|
|
4901
|
+
closeViewPopover() {
|
|
4902
|
+
this.viewPopoverOpen = false;
|
|
4903
|
+
if (this.viewPopoverClickHandler) {
|
|
4538
4904
|
document.removeEventListener('click', this.viewPopoverClickHandler);
|
|
4539
4905
|
this.viewPopoverClickHandler = null;
|
|
4540
|
-
}
|
|
4541
|
-
document.addEventListener('click', this.viewPopoverClickHandler);
|
|
4906
|
+
}
|
|
4542
4907
|
}
|
|
4543
4908
|
// ── Render: toolbar ────────────────────────────────────────────────────────
|
|
4544
4909
|
renderToolbar() {
|
|
4545
4910
|
var _a;
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
} }, 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 => {
|
|
4560
|
-
var _a, _b, _c;
|
|
4561
|
-
const createTypes = a.action === 'create' ? (_a = this.item) === null || _a === void 0 ? void 0 : _a.createTypes : null;
|
|
4562
|
-
if (createTypes === null || createTypes === void 0 ? void 0 : createTypes.length) {
|
|
4563
|
-
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
|
|
4564
|
-
? h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, h("use", { href: a.icon }))
|
|
4565
|
-
: 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: () => {
|
|
4566
|
-
this.mrdAction.emit(this.buildActionDetail('create', ct.type));
|
|
4567
|
-
this.closeCreatePicker();
|
|
4568
|
-
} }, ct.label)))))));
|
|
4569
|
-
}
|
|
4570
|
-
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
|
|
4571
|
-
? h("svg", { class: "mrd-table__action-icon", "aria-hidden": "true" }, h("use", { href: a.icon }))
|
|
4572
|
-
: a.label, h("span", { class: "mrd-table__action-tooltip" }, a.label)));
|
|
4573
|
-
})))));
|
|
4911
|
+
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: {
|
|
4912
|
+
onFilterToggle: () => this.handleFilterToggle(),
|
|
4913
|
+
onClearAllFilters: () => this.clearAllFilters(),
|
|
4914
|
+
onViewSwitch: idx => this.handleViewSwitch(idx),
|
|
4915
|
+
onToggleViewPopover: e => this.toggleViewPopover(e),
|
|
4916
|
+
onCloseViewPopover: () => this.closeViewPopover(),
|
|
4917
|
+
onToggleCreatePicker: () => this.toggleCreatePicker(),
|
|
4918
|
+
onCreate: basicType => {
|
|
4919
|
+
this.mrdAction.emit(this.buildActionDetail('create', basicType));
|
|
4920
|
+
this.closeCreatePicker();
|
|
4921
|
+
},
|
|
4922
|
+
onAction: action => this.mrdAction.emit(this.buildActionDetail(action)),
|
|
4923
|
+
} }));
|
|
4574
4924
|
}
|
|
4575
4925
|
// ── Render: filter popup ───────────────────────────────────────────────────
|
|
4576
|
-
renderFilterEditor(col) {
|
|
4577
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
4578
|
-
const pf = (_a = this.pendingFilter) !== null && _a !== void 0 ? _a : {};
|
|
4579
|
-
const dataType = this.colDataType(col);
|
|
4580
|
-
if (NO_FILTER_TYPES.has(dataType)) {
|
|
4581
|
-
return h("p", { class: "mrd-table__filter-no-support" }, t('filter_no_support', this.locale));
|
|
4582
|
-
}
|
|
4583
|
-
if (dataType === 'BOOLEAN') {
|
|
4584
|
-
const boolOp = pf.operator;
|
|
4585
|
-
const noValueOp = boolOp === 'isEmpty' || boolOp === 'isNotEmpty';
|
|
4586
|
-
return (h("div", { class: "mrd-table__filter-radio-group" }, [
|
|
4587
|
-
{ labelKey: 'filter_all', value: null },
|
|
4588
|
-
{ labelKey: 'yes', value: true },
|
|
4589
|
-
{ labelKey: 'no', value: false },
|
|
4590
|
-
].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))));
|
|
4591
|
-
}
|
|
4592
|
-
if (dataType === 'LIST') {
|
|
4593
|
-
const items = (_b = col.listItems) !== null && _b !== void 0 ? _b : [];
|
|
4594
|
-
const selected = (_c = pf.values) !== null && _c !== void 0 ? _c : [];
|
|
4595
|
-
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)))));
|
|
4596
|
-
}
|
|
4597
|
-
if (TEXT_TYPES.has(dataType) || dataType === 'RELATION') {
|
|
4598
|
-
const op = (_d = pf.operator) !== null && _d !== void 0 ? _d : 'startsWith';
|
|
4599
|
-
const noInput = op === 'isEmpty' || op === 'isNotEmpty';
|
|
4600
|
-
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => this.setPending('operator', e.target.value) }, [
|
|
4601
|
-
{ val: 'startsWith', labelKey: 'filter_starts_with' },
|
|
4602
|
-
{ val: 'equals', labelKey: 'filter_equals' },
|
|
4603
|
-
{ val: 'isEmpty', labelKey: 'filter_is_empty' },
|
|
4604
|
-
{ val: 'isNotEmpty', labelKey: 'filter_is_not_empty' },
|
|
4605
|
-
].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) }))));
|
|
4606
|
-
}
|
|
4607
|
-
if (NUMERIC_TYPES.has(dataType)) {
|
|
4608
|
-
const numOp = pf.operator;
|
|
4609
|
-
const noInput = numOp === 'isEmpty' || numOp === 'isNotEmpty';
|
|
4610
|
-
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4611
|
-
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4612
|
-
const val = e.target.value;
|
|
4613
|
-
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4614
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined });
|
|
4615
|
-
}
|
|
4616
|
-
else {
|
|
4617
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined });
|
|
4618
|
-
}
|
|
4619
|
-
} }, 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) })))))));
|
|
4620
|
-
}
|
|
4621
|
-
if (dataType === 'DATETIME') {
|
|
4622
|
-
const dtOp = pf.operator;
|
|
4623
|
-
const noInput = dtOp === 'isEmpty' || dtOp === 'isNotEmpty';
|
|
4624
|
-
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4625
|
-
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4626
|
-
const val = e.target.value;
|
|
4627
|
-
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4628
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined });
|
|
4629
|
-
}
|
|
4630
|
-
else {
|
|
4631
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined });
|
|
4632
|
-
}
|
|
4633
|
-
} }, 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) })))))));
|
|
4634
|
-
}
|
|
4635
|
-
if (DATE_TYPES.has(dataType)) {
|
|
4636
|
-
const inputType = dataType === 'DATE' ? 'date' : 'time';
|
|
4637
|
-
const dtdOp = pf.operator;
|
|
4638
|
-
const noInput = dtdOp === 'isEmpty' || dtdOp === 'isNotEmpty';
|
|
4639
|
-
const rangeMode = !noInput && (pf.from !== undefined || pf.to !== undefined);
|
|
4640
|
-
return (h("div", { class: "mrd-table__filter-editor" }, h("select", { class: "mrd-table__filter-select", onChange: (e) => {
|
|
4641
|
-
const val = e.target.value;
|
|
4642
|
-
if (val === 'isEmpty' || val === 'isNotEmpty') {
|
|
4643
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: val, value: undefined, from: undefined, to: undefined });
|
|
4644
|
-
}
|
|
4645
|
-
else {
|
|
4646
|
-
this.pendingFilter = Object.assign(Object.assign({}, pf), { operator: undefined });
|
|
4647
|
-
}
|
|
4648
|
-
} }, 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) })))))));
|
|
4649
|
-
}
|
|
4650
|
-
return null;
|
|
4651
|
-
}
|
|
4652
4926
|
renderFilterPopup() {
|
|
4653
|
-
var _a;
|
|
4654
4927
|
if (!this.openFilterCol || !this.pendingFilter)
|
|
4655
4928
|
return null;
|
|
4656
4929
|
const col = this.columns.find(c => this.colName(c) === this.openFilterCol);
|
|
4657
4930
|
if (!col)
|
|
4658
4931
|
return null;
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4932
|
+
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: {
|
|
4933
|
+
onSetPending: (key, val) => this.setPending(key, val),
|
|
4934
|
+
onReplacePending: pf => (this.pendingFilter = pf),
|
|
4935
|
+
onToggleValue: (key, checked) => this.togglePendingValue(key, checked),
|
|
4936
|
+
onApplySort: dir => this.applySort(col, dir),
|
|
4937
|
+
onApply: () => this.applyFilter(),
|
|
4938
|
+
onClear: () => this.clearFilter(),
|
|
4939
|
+
onClose: () => this.closeFilterPopup(),
|
|
4940
|
+
} }));
|
|
4662
4941
|
}
|
|
4663
4942
|
// ── Render: footer ────────────────────────────────────────────────────────
|
|
4664
4943
|
renderFooter(rowCount, effectiveTotal, isTotalKnown = true) {
|
|
@@ -4683,54 +4962,11 @@ const MrdTable = class {
|
|
|
4683
4962
|
}
|
|
4684
4963
|
// ── Render: cell ──────────────────────────────────────────────────────────
|
|
4685
4964
|
renderCell(col, row) {
|
|
4686
|
-
|
|
4687
|
-
const numericTypes = new Set(['INTEGER', 'DECIMAL', 'PERCENTAGE', 'CURRENCY']);
|
|
4688
|
-
const dataType = (_a = col.dataType) !== null && _a !== void 0 ? _a : '';
|
|
4689
|
-
const isNumeric = col.type === 'FIELD' && numericTypes.has(dataType);
|
|
4690
|
-
const isFile = col.type === 'FIELD' && (dataType === 'FILE' || dataType === 'IMAGE');
|
|
4691
|
-
if (isFile) {
|
|
4692
|
-
const name = (_b = col.name) !== null && _b !== void 0 ? _b : '';
|
|
4693
|
-
const fileVal = row === null || row === void 0 ? void 0 : row[name];
|
|
4694
|
-
const href = fileVal === null || fileVal === void 0 ? void 0 : fileVal.href;
|
|
4695
|
-
const fileName = fileVal === null || fileVal === void 0 ? void 0 : fileVal.fileName;
|
|
4696
|
-
return (h("td", { class: "mrd-table__cell" }, href && fileName ? (h("button", { class: "mrd-table__file-btn", title: fileName, onClick: (e) => {
|
|
4697
|
-
e.stopPropagation();
|
|
4698
|
-
this.mrdDownload.emit({ href, fileName });
|
|
4699
|
-
} }, 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))) : ''));
|
|
4700
|
-
}
|
|
4701
|
-
if (dataType === 'JSON') {
|
|
4702
|
-
const name = (_c = col.name) !== null && _c !== void 0 ? _c : '';
|
|
4703
|
-
const rawValue = name ? row === null || row === void 0 ? void 0 : row[name] : undefined;
|
|
4704
|
-
if (rawValue == null || rawValue === '')
|
|
4705
|
-
return h("td", { class: "mrd-table__cell" });
|
|
4706
|
-
const compactHtml = CellRenderer.formatJson(rawValue, true);
|
|
4707
|
-
const prettyHtml = CellRenderer.formatJson(rawValue, false);
|
|
4708
|
-
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")));
|
|
4709
|
-
}
|
|
4710
|
-
const TEXTBLOCK_MAX = 200;
|
|
4711
|
-
if (dataType === 'TEXTBLOCK') {
|
|
4712
|
-
const full = CellRenderer.render(col, row, this.locale);
|
|
4713
|
-
if (full.length <= TEXTBLOCK_MAX) {
|
|
4714
|
-
return h("td", { class: "mrd-table__cell" }, full);
|
|
4715
|
-
}
|
|
4716
|
-
const preview = full.slice(0, TEXTBLOCK_MAX) + '…';
|
|
4717
|
-
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")));
|
|
4718
|
-
}
|
|
4719
|
-
const value = CellRenderer.render(col, row, this.locale);
|
|
4720
|
-
return (h("td", { class: `mrd-table__cell${isNumeric ? ' mrd-table__cell--numeric' : ''}` }, value));
|
|
4965
|
+
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) }));
|
|
4721
4966
|
}
|
|
4722
4967
|
// ── Render: totals row ────────────────────────────────────────────────────
|
|
4723
4968
|
renderTotalsRow() {
|
|
4724
|
-
|
|
4725
|
-
return null;
|
|
4726
|
-
if (!this.columns.some(c => c.type === 'FIELD' && c.aggregate))
|
|
4727
|
-
return null;
|
|
4728
|
-
return (h("tfoot", null, h("tr", { class: "mrd-table__totals-row" }, this.columns.map(col => {
|
|
4729
|
-
var _a;
|
|
4730
|
-
const val = this.renderAggregationValue(col);
|
|
4731
|
-
const isNumeric = col.type === 'FIELD' && NUMERIC_TYPES.has((_a = col.dataType) !== null && _a !== void 0 ? _a : '');
|
|
4732
|
-
return (h("td", { class: `mrd-table__totals-cell${isNumeric ? ' mrd-table__totals-cell--numeric' : ''}` }, val));
|
|
4733
|
-
}))));
|
|
4969
|
+
return h(TotalsRow, { columns: this.columns, aggregations: this.aggregations, locale: this.locale });
|
|
4734
4970
|
}
|
|
4735
4971
|
// ── Render ─────────────────────────────────────────────────────────────────
|
|
4736
4972
|
render() {
|
|
@@ -4750,7 +4986,7 @@ const MrdTable = class {
|
|
|
4750
4986
|
isFiltered ? 'mrd-table__header--filtered' : '',
|
|
4751
4987
|
this.filterMode ? 'mrd-table__header--sortable' : '',
|
|
4752
4988
|
].filter(Boolean).join(' ');
|
|
4753
|
-
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 &&
|
|
4989
|
+
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)));
|
|
4754
4990
|
}))), 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()));
|
|
4755
4991
|
}
|
|
4756
4992
|
// ── Paginated / virtual-scroll mode ────────────────────────────────────
|
|
@@ -4758,12 +4994,7 @@ const MrdTable = class {
|
|
|
4758
4994
|
// if any loaded page is shorter than pageSize it is the last page,
|
|
4759
4995
|
// so the true total cannot exceed (pageNum * pageSize + pageRows.length).
|
|
4760
4996
|
// aggregationsTotal (from setAggregations) takes priority over the totalElements prop.
|
|
4761
|
-
|
|
4762
|
-
for (const [pageNum, pageRows] of this.loadedPages) {
|
|
4763
|
-
if (pageRows.length < this.pageSize) {
|
|
4764
|
-
effectiveTotal = Math.min(effectiveTotal, pageNum * this.pageSize + pageRows.length);
|
|
4765
|
-
}
|
|
4766
|
-
}
|
|
4997
|
+
const effectiveTotal = computeEffectiveTotal(this.loadedPages, this.pageSize, this.baseTotal);
|
|
4767
4998
|
// Clamp renderEnd to what we actually know exists (-1 when empty)
|
|
4768
4999
|
const clampedEnd = Math.min(this.renderEnd, effectiveTotal - 1);
|
|
4769
5000
|
const colCount = this.columns.length;
|
|
@@ -4794,21 +5025,14 @@ const MrdTable = class {
|
|
|
4794
5025
|
isActive ? `mrd-table__header--sorted-${this.sortDir}` : '',
|
|
4795
5026
|
isFiltered ? 'mrd-table__header--filtered' : '',
|
|
4796
5027
|
].filter(Boolean).join(' ');
|
|
4797
|
-
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 &&
|
|
4798
|
-
}))), 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()));
|
|
4799
|
-
}
|
|
4800
|
-
renderFilterIcon() {
|
|
4801
|
-
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" }))));
|
|
5028
|
+
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)));
|
|
5029
|
+
}))), 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()));
|
|
4802
5030
|
}
|
|
4803
5031
|
renderTextblockModal() {
|
|
4804
|
-
|
|
4805
|
-
return null;
|
|
4806
|
-
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))));
|
|
5032
|
+
return h(TextblockModal, { text: this.textblockModal, locale: this.locale, onClose: () => this.closeTextblockModal() });
|
|
4807
5033
|
}
|
|
4808
5034
|
renderJsonModal() {
|
|
4809
|
-
|
|
4810
|
-
return null;
|
|
4811
|
-
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 }))));
|
|
5035
|
+
return h(JsonModal, { html: this.jsonModal, locale: this.locale, onClose: () => this.closeJsonModal() });
|
|
4812
5036
|
}
|
|
4813
5037
|
get el() { return getElement(this); }
|
|
4814
5038
|
static get watchers() { return {
|
|
@@ -4820,9 +5044,9 @@ const MrdTable = class {
|
|
|
4820
5044
|
}]
|
|
4821
5045
|
}; }
|
|
4822
5046
|
};
|
|
4823
|
-
MrdTable.style =
|
|
5047
|
+
MrdTable.style = mrdTableCss();
|
|
4824
5048
|
|
|
4825
|
-
const
|
|
5049
|
+
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)}`;
|
|
4826
5050
|
|
|
4827
5051
|
const MrdTextField = class {
|
|
4828
5052
|
constructor(hostRef) {
|
|
@@ -4843,23 +5067,17 @@ const MrdTextField = class {
|
|
|
4843
5067
|
};
|
|
4844
5068
|
this.handleBlur = (e) => {
|
|
4845
5069
|
const val = e.target.value;
|
|
4846
|
-
|
|
4847
|
-
this.error = t('required', this.locale);
|
|
4848
|
-
}
|
|
4849
|
-
else {
|
|
4850
|
-
this.error = '';
|
|
4851
|
-
}
|
|
5070
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
4852
5071
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
4853
5072
|
};
|
|
4854
5073
|
}
|
|
4855
5074
|
render() {
|
|
4856
|
-
|
|
4857
|
-
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))));
|
|
5075
|
+
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 }))));
|
|
4858
5076
|
}
|
|
4859
5077
|
};
|
|
4860
|
-
MrdTextField.style =
|
|
5078
|
+
MrdTextField.style = mrdTextFieldCss();
|
|
4861
5079
|
|
|
4862
|
-
const
|
|
5080
|
+
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}`;
|
|
4863
5081
|
|
|
4864
5082
|
const MrdTextareaField = class {
|
|
4865
5083
|
constructor(hostRef) {
|
|
@@ -4912,12 +5130,7 @@ const MrdTextareaField = class {
|
|
|
4912
5130
|
var _a, _b;
|
|
4913
5131
|
if (!range) {
|
|
4914
5132
|
const html = (_b = (_a = this.editorEl.querySelector('.ql-editor')) === null || _a === void 0 ? void 0 : _a.innerHTML) !== null && _b !== void 0 ? _b : '';
|
|
4915
|
-
|
|
4916
|
-
this.error = t('required', this.locale);
|
|
4917
|
-
}
|
|
4918
|
-
else {
|
|
4919
|
-
this.error = '';
|
|
4920
|
-
}
|
|
5133
|
+
this.error = requiredError(html, this.required, this.locale);
|
|
4921
5134
|
this.mrdBlur.emit({ name: this.name, value: html });
|
|
4922
5135
|
}
|
|
4923
5136
|
});
|
|
@@ -4928,13 +5141,13 @@ const MrdTextareaField = class {
|
|
|
4928
5141
|
}
|
|
4929
5142
|
}
|
|
4930
5143
|
render() {
|
|
4931
|
-
return (h(Host, { key: '
|
|
5144
|
+
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 }))));
|
|
4932
5145
|
}
|
|
4933
5146
|
get el() { return getElement(this); }
|
|
4934
5147
|
};
|
|
4935
|
-
MrdTextareaField.style =
|
|
5148
|
+
MrdTextareaField.style = mrdTextareaFieldCss();
|
|
4936
5149
|
|
|
4937
|
-
const
|
|
5150
|
+
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}`;
|
|
4938
5151
|
|
|
4939
5152
|
const MrdTimeField = class {
|
|
4940
5153
|
constructor(hostRef) {
|
|
@@ -4950,12 +5163,7 @@ const MrdTimeField = class {
|
|
|
4950
5163
|
this.error = '';
|
|
4951
5164
|
this.handleChange = (e) => {
|
|
4952
5165
|
const val = e.target.value;
|
|
4953
|
-
|
|
4954
|
-
this.error = t('required', this.locale);
|
|
4955
|
-
}
|
|
4956
|
-
else {
|
|
4957
|
-
this.error = '';
|
|
4958
|
-
}
|
|
5166
|
+
this.error = requiredError(val, this.required, this.locale);
|
|
4959
5167
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
4960
5168
|
};
|
|
4961
5169
|
this.handleBlur = (e) => {
|
|
@@ -4964,10 +5172,9 @@ const MrdTimeField = class {
|
|
|
4964
5172
|
};
|
|
4965
5173
|
}
|
|
4966
5174
|
render() {
|
|
4967
|
-
|
|
4968
|
-
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))));
|
|
5175
|
+
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 }))));
|
|
4969
5176
|
}
|
|
4970
5177
|
};
|
|
4971
|
-
MrdTimeField.style =
|
|
5178
|
+
MrdTimeField.style = mrdTimeFieldCss();
|
|
4972
5179
|
|
|
4973
5180
|
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 };
|