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