@mmlogic/components 0.3.2 → 0.3.3
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/loader.cjs.js +1 -1
- package/dist/cjs/mosterdcomponents.cjs.js +1 -1
- package/dist/cjs/mrd-boolean-field_19.cjs.entry.js +416 -34
- package/dist/collection/components/mrd-field/mrd-field.js +129 -26
- package/dist/collection/components/mrd-field/mrd-field.scss +118 -0
- package/dist/collection/components/mrd-form/mrd-form.js +3 -3
- package/dist/collection/components/mrd-layout-section/mrd-layout-section.js +40 -4
- package/dist/collection/components/mrd-layout-section/mrd-layout-section.scss +67 -0
- package/dist/collection/dev/app.js +9 -4
- package/dist/collection/utils/i18n.js +261 -1
- package/dist/components/format.js +1 -1
- package/dist/components/i18n.js +1 -1
- package/dist/components/mrd-field2.js +1 -1
- package/dist/components/mrd-layout-section.js +1 -1
- package/dist/components/mrd-table2.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/mosterdcomponents.js +1 -1
- package/dist/esm/mrd-boolean-field_19.entry.js +416 -34
- package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
- package/dist/mosterdcomponents/p-74d100dd.entry.js +1 -0
- package/dist/types/components/mrd-field/mrd-field.d.ts +14 -0
- package/dist/types/components/mrd-layout-section/mrd-layout-section.d.ts +4 -0
- package/dist/types/types/client-layout.d.ts +2 -0
- package/package.json +1 -1
- package/dist/mosterdcomponents/p-2a099635.entry.js +0 -1
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import { Host, h } from "@stencil/core";
|
|
2
2
|
import { ClientLayoutItemType, ClientLayoutItemFieldDataType, ClientLayoutItemRelationDisplayType, } from "../../types";
|
|
3
|
+
import { t } from "../../utils/i18n";
|
|
3
4
|
export class MrdField {
|
|
4
5
|
constructor() {
|
|
5
6
|
this.locale = navigator.language;
|
|
7
|
+
this.historyEntries = [];
|
|
8
|
+
this.currentValue = undefined;
|
|
6
9
|
this.handleChange = (e) => {
|
|
10
|
+
var _a, _b, _c, _d;
|
|
7
11
|
e.stopPropagation();
|
|
8
|
-
this.
|
|
12
|
+
const hist = (_b = (_a = this.item) === null || _a === void 0 ? void 0 : _a.historyEnabled) !== null && _b !== void 0 ? _b : (_d = (_c = this.item) === null || _c === void 0 ? void 0 : _c.field) === null || _d === void 0 ? void 0 : _d.historyEnabled;
|
|
13
|
+
if (hist) {
|
|
14
|
+
this.currentValue = e.detail.value;
|
|
15
|
+
this.mrdChange.emit({
|
|
16
|
+
name: e.detail.name,
|
|
17
|
+
value: { current: e.detail.value, history: this.historyEntries },
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
this.mrdChange.emit(e.detail);
|
|
22
|
+
}
|
|
9
23
|
};
|
|
10
24
|
this.handleBlur = (e) => {
|
|
11
25
|
e.stopPropagation();
|
|
@@ -24,63 +38,139 @@ export class MrdField {
|
|
|
24
38
|
this.mrdUpload.emit(e.detail);
|
|
25
39
|
};
|
|
26
40
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
41
|
+
componentWillLoad() {
|
|
42
|
+
this.initHistoryState();
|
|
43
|
+
}
|
|
44
|
+
valueChanged() {
|
|
45
|
+
this.initHistoryState();
|
|
46
|
+
}
|
|
47
|
+
initHistoryState() {
|
|
48
|
+
var _a, _b, _c, _d, _e;
|
|
49
|
+
const hist = (_b = (_a = this.item) === null || _a === void 0 ? void 0 : _a.historyEnabled) !== null && _b !== void 0 ? _b : (_d = (_c = this.item) === null || _c === void 0 ? void 0 : _c.field) === null || _d === void 0 ? void 0 : _d.historyEnabled;
|
|
50
|
+
if (!hist)
|
|
51
|
+
return;
|
|
52
|
+
const raw = this.value;
|
|
53
|
+
this.currentValue = (_e = raw === null || raw === void 0 ? void 0 : raw.current) !== null && _e !== void 0 ? _e : raw;
|
|
54
|
+
this.historyEntries = Array.isArray(raw === null || raw === void 0 ? void 0 : raw.history) ? [...raw.history] : [];
|
|
55
|
+
}
|
|
56
|
+
getDisplayValue() {
|
|
57
|
+
var _a, _b, _c, _d;
|
|
58
|
+
const hist = (_b = (_a = this.item) === null || _a === void 0 ? void 0 : _a.historyEnabled) !== null && _b !== void 0 ? _b : (_d = (_c = this.item) === null || _c === void 0 ? void 0 : _c.field) === null || _d === void 0 ? void 0 : _d.historyEnabled;
|
|
59
|
+
if (hist && this.value !== null && typeof this.value === 'object' && 'current' in this.value) {
|
|
60
|
+
return this.value.current;
|
|
32
61
|
}
|
|
33
|
-
|
|
34
|
-
|
|
62
|
+
return this.value;
|
|
63
|
+
}
|
|
64
|
+
historyValueInputType() {
|
|
65
|
+
var _a;
|
|
66
|
+
switch ((_a = this.item) === null || _a === void 0 ? void 0 : _a.dataType) {
|
|
67
|
+
case ClientLayoutItemFieldDataType.DATE: return 'date';
|
|
68
|
+
case ClientLayoutItemFieldDataType.DATETIME: return 'datetime-local';
|
|
69
|
+
case ClientLayoutItemFieldDataType.TIME: return 'time';
|
|
70
|
+
case ClientLayoutItemFieldDataType.INTEGER:
|
|
71
|
+
case ClientLayoutItemFieldDataType.DECIMAL:
|
|
72
|
+
case ClientLayoutItemFieldDataType.PERCENTAGE: return 'number';
|
|
73
|
+
case ClientLayoutItemFieldDataType.EMAIL: return 'email';
|
|
74
|
+
default: return 'text';
|
|
35
75
|
}
|
|
76
|
+
}
|
|
77
|
+
emitHistoryChange(entries) {
|
|
78
|
+
this.historyEntries = entries;
|
|
79
|
+
this.mrdChange.emit({
|
|
80
|
+
name: this.item.name,
|
|
81
|
+
value: { current: this.currentValue, history: entries },
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
renderHistoryEditor() {
|
|
85
|
+
var _a, _b, _c, _d;
|
|
86
|
+
const hist = (_b = (_a = this.item) === null || _a === void 0 ? void 0 : _a.historyEnabled) !== null && _b !== void 0 ? _b : (_d = (_c = this.item) === null || _c === void 0 ? void 0 : _c.field) === null || _d === void 0 ? void 0 : _d.historyEnabled;
|
|
87
|
+
if (!hist)
|
|
88
|
+
return null;
|
|
89
|
+
const { locale } = this;
|
|
90
|
+
const valueType = this.historyValueInputType();
|
|
91
|
+
const updateEntry = (i, field, val) => {
|
|
92
|
+
const updated = this.historyEntries.map((e, idx) => idx === i ? Object.assign(Object.assign({}, e), { [field]: val }) : e);
|
|
93
|
+
this.emitHistoryChange(updated);
|
|
94
|
+
};
|
|
95
|
+
const removeEntry = (i) => {
|
|
96
|
+
this.emitHistoryChange(this.historyEntries.filter((_, idx) => idx !== i));
|
|
97
|
+
};
|
|
98
|
+
const addEntry = () => {
|
|
99
|
+
this.emitHistoryChange([...this.historyEntries, { value: '', until: '' }]);
|
|
100
|
+
};
|
|
101
|
+
return (h("div", { class: "mrd-field__history-editor" }, this.historyEntries.length > 0 && (h("span", { class: "mrd-field__history-editor-label" }, t('history_badge_tooltip', locale))), this.historyEntries.map((entry, i) => (h("div", { key: String(i), class: "mrd-field__history-editor-row" }, h("input", { class: "mrd-field__history-editor-value", type: valueType, value: entry.value, onInput: (e) => updateEntry(i, 'value', e.target.value) }), h("span", { class: "mrd-field__history-editor-sep" }, t('history_until', locale)), h("input", { class: "mrd-field__history-editor-until", type: "date", value: entry.until, onInput: (e) => updateEntry(i, 'until', e.target.value) }), h("button", { type: "button", class: "mrd-field__history-editor-remove", onClick: () => removeEntry(i), "aria-label": t('remove', locale) }, h("svg", { viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, h("path", { "fill-rule": "evenodd", d: "M8.75 1A2.75 2.75 0 006 3.75v.443c-.795.077-1.584.176-2.365.298a.75.75 0 10.23 1.482l.149-.022.841 10.518A2.75 2.75 0 007.596 19h4.807a2.75 2.75 0 002.742-2.53l.841-10.52.149.023a.75.75 0 00.23-1.482A41.03 41.03 0 0014 4.193V3.75A2.75 2.75 0 0011.25 1h-2.5zM10 4c.84 0 1.673.025 2.5.075V3.75c0-.69-.56-1.25-1.25-1.25h-2.5c-.69 0-1.25.56-1.25 1.25v.325C8.327 4.025 9.16 4 10 4zM8.58 7.72a.75.75 0 00-1.5.06l.3 7.5a.75.75 0 101.5-.06l-.3-7.5zm4.34.06a.75.75 0 10-1.5-.06l-.3 7.5a.75.75 0 101.5.06l.3-7.5z", "clip-rule": "evenodd" })))))), h("button", { type: "button", class: "mrd-field__history-editor-add", onClick: addEntry }, "+ ", t('add', locale))));
|
|
102
|
+
}
|
|
103
|
+
renderLeafField(displayValue) {
|
|
104
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
|
|
105
|
+
const { item, locale } = this;
|
|
36
106
|
const commonProps = {
|
|
37
107
|
name: item.name,
|
|
38
108
|
label: item.label,
|
|
39
109
|
required: item.required,
|
|
40
|
-
disabled: (
|
|
110
|
+
disabled: (_a = item.disabled) !== null && _a !== void 0 ? _a : false,
|
|
41
111
|
locale,
|
|
42
112
|
onMrdChange: this.handleChange,
|
|
43
113
|
onMrdBlur: this.handleBlur,
|
|
44
114
|
};
|
|
45
115
|
switch (item.dataType) {
|
|
46
116
|
case ClientLayoutItemFieldDataType.TEXT:
|
|
47
|
-
return (h(
|
|
117
|
+
return (h("mrd-text-field", Object.assign({}, commonProps, { value: (_b = displayValue) !== null && _b !== void 0 ? _b : '', placeholder: (_c = item.placeholder) !== null && _c !== void 0 ? _c : '' })));
|
|
48
118
|
case ClientLayoutItemFieldDataType.TEXTBLOCK:
|
|
49
|
-
return (h(
|
|
119
|
+
return (h("mrd-textarea-field", Object.assign({}, commonProps, { value: (_d = displayValue) !== null && _d !== void 0 ? _d : '', placeholder: (_e = item.placeholder) !== null && _e !== void 0 ? _e : '' })));
|
|
50
120
|
case ClientLayoutItemFieldDataType.INTEGER:
|
|
51
121
|
case ClientLayoutItemFieldDataType.DECIMAL:
|
|
52
122
|
case ClientLayoutItemFieldDataType.PERCENTAGE:
|
|
53
|
-
return (h(
|
|
123
|
+
return (h("mrd-number-field", Object.assign({}, commonProps, { value: (_f = displayValue) !== null && _f !== void 0 ? _f : null, dataType: item.dataType, decimalPrecision: (_g = item.decimalPrecision) !== null && _g !== void 0 ? _g : 2, placeholder: (_h = item.placeholder) !== null && _h !== void 0 ? _h : '' })));
|
|
54
124
|
case ClientLayoutItemFieldDataType.CURRENCY:
|
|
55
|
-
return (h(
|
|
125
|
+
return (h("mrd-currency-field", Object.assign({}, commonProps, { value: (_j = displayValue) !== null && _j !== void 0 ? _j : { amount: null, currency: (_k = item.currencyCode) !== null && _k !== void 0 ? _k : 'EUR' } })));
|
|
56
126
|
case ClientLayoutItemFieldDataType.BOOLEAN:
|
|
57
|
-
return (h(
|
|
127
|
+
return (h("mrd-boolean-field", Object.assign({}, commonProps, { value: (_l = displayValue) !== null && _l !== void 0 ? _l : false })));
|
|
58
128
|
case ClientLayoutItemFieldDataType.DATE:
|
|
59
|
-
return (h(
|
|
129
|
+
return (h("mrd-date-field", Object.assign({}, commonProps, { value: (_m = displayValue) !== null && _m !== void 0 ? _m : '' })));
|
|
60
130
|
case ClientLayoutItemFieldDataType.DATETIME:
|
|
61
|
-
return (h(
|
|
131
|
+
return (h("mrd-datetime-field", Object.assign({}, commonProps, { value: (_o = displayValue) !== null && _o !== void 0 ? _o : '' })));
|
|
62
132
|
case ClientLayoutItemFieldDataType.TIME:
|
|
63
|
-
return (h(
|
|
133
|
+
return (h("mrd-time-field", Object.assign({}, commonProps, { value: (_p = displayValue) !== null && _p !== void 0 ? _p : '' })));
|
|
64
134
|
case ClientLayoutItemFieldDataType.EMAIL:
|
|
65
|
-
return (h(
|
|
135
|
+
return (h("mrd-email-field", Object.assign({}, commonProps, { value: (_q = displayValue) !== null && _q !== void 0 ? _q : '', placeholder: (_r = item.placeholder) !== null && _r !== void 0 ? _r : '' })));
|
|
66
136
|
case ClientLayoutItemFieldDataType.HYPERLINK:
|
|
67
|
-
return (h(
|
|
137
|
+
return (h("mrd-hyperlink-field", Object.assign({}, commonProps, { value: (_s = displayValue) !== null && _s !== void 0 ? _s : '', placeholder: (_t = item.placeholder) !== null && _t !== void 0 ? _t : '' })));
|
|
68
138
|
case ClientLayoutItemFieldDataType.LIST:
|
|
69
|
-
return (h(
|
|
139
|
+
return (h("mrd-list-field", Object.assign({}, commonProps, { value: (_u = displayValue) !== null && _u !== void 0 ? _u : '', multiple: (_v = item.multiple) !== null && _v !== void 0 ? _v : false, listItems: (_w = item.listItems) !== null && _w !== void 0 ? _w : [] })));
|
|
70
140
|
case ClientLayoutItemFieldDataType.FILE:
|
|
71
|
-
return (h(
|
|
141
|
+
return (h("mrd-file-field", Object.assign({}, commonProps, { value: displayValue, accept: (_x = item.accept) !== null && _x !== void 0 ? _x : '', maxSize: (_y = item.maxSize) !== null && _y !== void 0 ? _y : 0, onMrdUpload: this.handleUpload })));
|
|
72
142
|
case ClientLayoutItemFieldDataType.IMAGE:
|
|
73
|
-
return (h(
|
|
143
|
+
return (h("mrd-image-field", Object.assign({}, commonProps, { value: displayValue, accept: (_z = item.accept) !== null && _z !== void 0 ? _z : 'image/*', maxSize: (_0 = item.maxSize) !== null && _0 !== void 0 ? _0 : 0, onMrdUpload: this.handleUpload })));
|
|
74
144
|
case ClientLayoutItemFieldDataType.LONGTEXT:
|
|
75
|
-
return (h(
|
|
76
|
-
case ClientLayoutItemFieldDataType.JSON:
|
|
77
|
-
return h(Host, null);
|
|
145
|
+
return (h("mrd-longtext-field", Object.assign({}, commonProps, { value: (_1 = displayValue) !== null && _1 !== void 0 ? _1 : '', placeholder: (_2 = item.placeholder) !== null && _2 !== void 0 ? _2 : '' })));
|
|
78
146
|
default:
|
|
79
|
-
return
|
|
147
|
+
return null;
|
|
80
148
|
}
|
|
81
149
|
}
|
|
150
|
+
render() {
|
|
151
|
+
var _a, _b, _c, _d, _e, _f;
|
|
152
|
+
const { item, locale, value } = this;
|
|
153
|
+
if (item.type === ClientLayoutItemType.RELATION) {
|
|
154
|
+
return (h(Host, null, h("mrd-relation-field", { name: item.name, label: item.label, required: item.required, disabled: (_a = item.disabled) !== null && _a !== void 0 ? _a : false, locale: locale, relatedClass: item.relatedClass, mostSignificantClass: (_b = item.mostSignificantClass) !== null && _b !== void 0 ? _b : '', displayType: (_c = item.displayType) !== null && _c !== void 0 ? _c : ClientLayoutItemRelationDisplayType.SEARCH, editBehavior: (_d = item.editBehavior) !== null && _d !== void 0 ? _d : null, commonRelation: item.commonRelation, multiple: (_e = item.multiple) !== null && _e !== void 0 ? _e : false, dropdownValues: (_f = item.dropdownValues) !== null && _f !== void 0 ? _f : [], value: value, onMrdChange: this.handleChange, onMrdBlur: this.handleBlur, onMrdSearch: this.handleSearch, onMrdFetchAll: this.handleFetchAll })));
|
|
155
|
+
}
|
|
156
|
+
if (item.type !== ClientLayoutItemType.FIELD) {
|
|
157
|
+
return h(Host, null);
|
|
158
|
+
}
|
|
159
|
+
const displayValue = this.getDisplayValue();
|
|
160
|
+
return (h(Host, null, h("div", { class: "mrd-field__inner" }, this.renderLeafField(displayValue), this.renderHistoryEditor())));
|
|
161
|
+
}
|
|
82
162
|
static get is() { return "mrd-field"; }
|
|
83
163
|
static get encapsulation() { return "scoped"; }
|
|
164
|
+
static get originalStyleUrls() {
|
|
165
|
+
return {
|
|
166
|
+
"$": ["mrd-field.scss"]
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
static get styleUrls() {
|
|
170
|
+
return {
|
|
171
|
+
"$": ["mrd-field.css"]
|
|
172
|
+
};
|
|
173
|
+
}
|
|
84
174
|
static get properties() {
|
|
85
175
|
return {
|
|
86
176
|
"item": {
|
|
@@ -146,6 +236,12 @@ export class MrdField {
|
|
|
146
236
|
}
|
|
147
237
|
};
|
|
148
238
|
}
|
|
239
|
+
static get states() {
|
|
240
|
+
return {
|
|
241
|
+
"historyEntries": {},
|
|
242
|
+
"currentValue": {}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
149
245
|
static get events() {
|
|
150
246
|
return [{
|
|
151
247
|
"method": "mrdChange",
|
|
@@ -229,4 +325,11 @@ export class MrdField {
|
|
|
229
325
|
}
|
|
230
326
|
}];
|
|
231
327
|
}
|
|
328
|
+
static get elementRef() { return "el"; }
|
|
329
|
+
static get watchers() {
|
|
330
|
+
return [{
|
|
331
|
+
"propName": "value",
|
|
332
|
+
"methodName": "valueChanged"
|
|
333
|
+
}];
|
|
334
|
+
}
|
|
232
335
|
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: block;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.mrd-field__inner {
|
|
6
|
+
display: block;
|
|
7
|
+
width: 100%;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.mrd-field__history-editor {
|
|
11
|
+
margin-top: var(--mrd-space-2);
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
gap: var(--mrd-space-1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.mrd-field__history-editor-label {
|
|
18
|
+
font-family: var(--mrd-font-family);
|
|
19
|
+
font-size: var(--mrd-font-size-xs);
|
|
20
|
+
font-weight: var(--mrd-font-weight-medium);
|
|
21
|
+
color: var(--mrd-color-neutral-500);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.mrd-field__history-editor-row {
|
|
25
|
+
display: flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
gap: var(--mrd-space-2);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.mrd-field__history-editor-sep {
|
|
31
|
+
flex-shrink: 0;
|
|
32
|
+
font-family: var(--mrd-font-family);
|
|
33
|
+
font-size: var(--mrd-font-size-xs);
|
|
34
|
+
color: var(--mrd-color-neutral-500);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.mrd-field__history-editor-value {
|
|
38
|
+
flex: 1 1 0;
|
|
39
|
+
min-width: 0;
|
|
40
|
+
height: var(--mrd-input-height);
|
|
41
|
+
padding: 0 var(--mrd-space-3);
|
|
42
|
+
font-family: var(--mrd-font-family);
|
|
43
|
+
font-size: var(--mrd-font-size-sm);
|
|
44
|
+
color: var(--mrd-color-neutral-800);
|
|
45
|
+
background-color: var(--mrd-color-white);
|
|
46
|
+
border: var(--mrd-border-width) solid var(--mrd-border-color);
|
|
47
|
+
border-radius: var(--mrd-border-radius-md);
|
|
48
|
+
outline: none;
|
|
49
|
+
transition: border-color var(--mrd-transition-fast), box-shadow var(--mrd-transition-fast);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.mrd-field__history-editor-value:focus {
|
|
53
|
+
border-color: var(--mrd-color-primary);
|
|
54
|
+
box-shadow: var(--mrd-shadow-focus);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.mrd-field__history-editor-until {
|
|
58
|
+
flex: 0 0 10rem;
|
|
59
|
+
height: var(--mrd-input-height);
|
|
60
|
+
padding: 0 var(--mrd-space-3);
|
|
61
|
+
font-family: var(--mrd-font-family);
|
|
62
|
+
font-size: var(--mrd-font-size-sm);
|
|
63
|
+
color: var(--mrd-color-neutral-800);
|
|
64
|
+
background-color: var(--mrd-color-white);
|
|
65
|
+
border: var(--mrd-border-width) solid var(--mrd-border-color);
|
|
66
|
+
border-radius: var(--mrd-border-radius-md);
|
|
67
|
+
outline: none;
|
|
68
|
+
transition: border-color var(--mrd-transition-fast), box-shadow var(--mrd-transition-fast);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.mrd-field__history-editor-until:focus {
|
|
72
|
+
border-color: var(--mrd-color-primary);
|
|
73
|
+
box-shadow: var(--mrd-shadow-focus);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.mrd-field__history-editor-remove {
|
|
77
|
+
display: inline-flex;
|
|
78
|
+
align-items: center;
|
|
79
|
+
justify-content: center;
|
|
80
|
+
flex-shrink: 0;
|
|
81
|
+
width: 2rem;
|
|
82
|
+
height: 2rem;
|
|
83
|
+
padding: 0;
|
|
84
|
+
background: transparent;
|
|
85
|
+
border: none;
|
|
86
|
+
border-radius: var(--mrd-border-radius-sm);
|
|
87
|
+
color: var(--mrd-color-neutral-400);
|
|
88
|
+
cursor: pointer;
|
|
89
|
+
transition: color var(--mrd-transition-fast), background-color var(--mrd-transition-fast);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.mrd-field__history-editor-remove:hover {
|
|
93
|
+
color: var(--mrd-color-danger);
|
|
94
|
+
background-color: var(--mrd-color-danger-light);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.mrd-field__history-editor-remove svg {
|
|
98
|
+
width: 1rem;
|
|
99
|
+
height: 1rem;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.mrd-field__history-editor-add {
|
|
103
|
+
align-self: flex-start;
|
|
104
|
+
padding: var(--mrd-space-1) var(--mrd-space-3);
|
|
105
|
+
font-family: var(--mrd-font-family);
|
|
106
|
+
font-size: var(--mrd-font-size-xs);
|
|
107
|
+
font-weight: var(--mrd-font-weight-medium);
|
|
108
|
+
color: var(--mrd-color-primary);
|
|
109
|
+
background: transparent;
|
|
110
|
+
border: var(--mrd-border-width) solid var(--mrd-color-primary);
|
|
111
|
+
border-radius: var(--mrd-border-radius-md);
|
|
112
|
+
cursor: pointer;
|
|
113
|
+
transition: background-color var(--mrd-transition-fast), color var(--mrd-transition-fast);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.mrd-field__history-editor-add:hover {
|
|
117
|
+
background-color: var(--mrd-color-primary-light);
|
|
118
|
+
}
|
|
@@ -261,10 +261,10 @@ export class MrdForm {
|
|
|
261
261
|
continue;
|
|
262
262
|
const name = item.name;
|
|
263
263
|
if (item.type === ClientLayoutItemType.FIELD) {
|
|
264
|
-
const
|
|
265
|
-
if (
|
|
264
|
+
const rawValue = this.formValues[name];
|
|
265
|
+
if (rawValue instanceof File)
|
|
266
266
|
continue;
|
|
267
|
-
const current = this.normalizeFieldValue(
|
|
267
|
+
const current = this.normalizeFieldValue(rawValue);
|
|
268
268
|
const initial = this.normalizeFieldValue(this.initialValues[name]);
|
|
269
269
|
if (this.deepEqual(current, initial))
|
|
270
270
|
continue;
|
|
@@ -2,6 +2,7 @@ import { Host, h } from "@stencil/core";
|
|
|
2
2
|
import { ClientLayoutItemType, ClientLayoutItemFieldDataType, } from "../../types/client-layout";
|
|
3
3
|
import { CellRenderer } from "../../utils/cell-renderer";
|
|
4
4
|
import { t } from "../../utils/i18n";
|
|
5
|
+
import { formatDate } from "../../utils/format";
|
|
5
6
|
export class MrdLayoutSection {
|
|
6
7
|
constructor() {
|
|
7
8
|
/** Items from one layout entry in ClientDashboardMetadata.layouts[]. */
|
|
@@ -17,6 +18,8 @@ export class MrdLayoutSection {
|
|
|
17
18
|
this.searchResultsMap = {};
|
|
18
19
|
this.imagePreviewUrl = null;
|
|
19
20
|
this.imagePreviews = {};
|
|
21
|
+
this.openHistoryField = null;
|
|
22
|
+
this.historyClickOutside = null;
|
|
20
23
|
this.searchTimers = {};
|
|
21
24
|
this.handleViewLoadPage = (e, name) => {
|
|
22
25
|
e.stopPropagation();
|
|
@@ -40,6 +43,17 @@ export class MrdLayoutSection {
|
|
|
40
43
|
this.initEmbeddedTables();
|
|
41
44
|
this.emitLoadImages();
|
|
42
45
|
}, 0);
|
|
46
|
+
this.historyClickOutside = (e) => {
|
|
47
|
+
if (!this.el.contains(e.target))
|
|
48
|
+
this.openHistoryField = null;
|
|
49
|
+
};
|
|
50
|
+
document.addEventListener('mousedown', this.historyClickOutside);
|
|
51
|
+
}
|
|
52
|
+
disconnectedCallback() {
|
|
53
|
+
if (this.historyClickOutside) {
|
|
54
|
+
document.removeEventListener('mousedown', this.historyClickOutside);
|
|
55
|
+
this.historyClickOutside = null;
|
|
56
|
+
}
|
|
43
57
|
}
|
|
44
58
|
dataChanged(newVal) {
|
|
45
59
|
if (newVal && Object.keys(newVal).length > 0) {
|
|
@@ -188,10 +202,31 @@ export class MrdLayoutSection {
|
|
|
188
202
|
}
|
|
189
203
|
return this.renderSingleFieldValue(item, rawValue);
|
|
190
204
|
}
|
|
205
|
+
renderHistoryBadge(item, raw) {
|
|
206
|
+
var _a, _b, _c;
|
|
207
|
+
const hist = (_a = item.historyEnabled) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.historyEnabled;
|
|
208
|
+
if (!hist || !item.name)
|
|
209
|
+
return null;
|
|
210
|
+
const history = (_c = raw === null || raw === void 0 ? void 0 : raw.history) !== null && _c !== void 0 ? _c : [];
|
|
211
|
+
if (!history.length)
|
|
212
|
+
return null;
|
|
213
|
+
const sorted = [...history].sort((a, b) => b.until.localeCompare(a.until));
|
|
214
|
+
const isOpen = this.openHistoryField === item.name;
|
|
215
|
+
const { locale } = this;
|
|
216
|
+
return (h("span", { class: "mrd-layout-section__history-wrap" }, h("button", { type: "button", class: "mrd-layout-section__history-btn", title: t('history_badge_tooltip', locale), "aria-label": t('history_badge_tooltip', locale), onClick: (e) => {
|
|
217
|
+
e.stopPropagation();
|
|
218
|
+
this.openHistoryField = isOpen ? null : item.name;
|
|
219
|
+
} }, h("svg", { class: "mrd-layout-section__history-icon", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, h("path", { "fill-rule": "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm.75-13a.75.75 0 00-1.5 0v5c0 .207.085.394.22.53l2.5 2.5a.75.75 0 101.06-1.06L10.75 9.69V5z", "clip-rule": "evenodd" }))), isOpen && (h("div", { class: "mrd-layout-section__history-popover", role: "listbox" }, sorted.map((entry, i) => (h("div", { key: String(i), class: "mrd-layout-section__history-entry" }, entry.value, " (", t('history_until', locale), " ", formatDate(entry.until, locale), ")")))))));
|
|
220
|
+
}
|
|
191
221
|
renderField(item) {
|
|
222
|
+
var _a, _b;
|
|
192
223
|
if (!item.name)
|
|
193
224
|
return null;
|
|
194
|
-
const
|
|
225
|
+
const raw = this.data[item.name];
|
|
226
|
+
const hist = (_a = item.historyEnabled) !== null && _a !== void 0 ? _a : (_b = item.field) === null || _b === void 0 ? void 0 : _b.historyEnabled;
|
|
227
|
+
const rawValue = hist && raw !== null && typeof raw === 'object' && 'current' in raw
|
|
228
|
+
? raw.current
|
|
229
|
+
: raw;
|
|
195
230
|
const renderedValue = this.renderFieldValue(item, rawValue);
|
|
196
231
|
if (item.header) {
|
|
197
232
|
return (h("h1", { class: "mrd-layout-section__field-header", key: item.name }, typeof renderedValue === 'string' ? renderedValue : rawValue != null ? String(rawValue) : item.label));
|
|
@@ -201,7 +236,7 @@ export class MrdLayoutSection {
|
|
|
201
236
|
const isBlock = item.dataType === ClientLayoutItemFieldDataType.TEXTBLOCK
|
|
202
237
|
|| item.dataType === ClientLayoutItemFieldDataType.LONGTEXT
|
|
203
238
|
|| item.dataType === ClientLayoutItemFieldDataType.JSON;
|
|
204
|
-
return (h("div", { class: `mrd-layout-section__field${isBlock ? ' mrd-layout-section__field--block' : ''}`, key: item.name }, h("span", { class: "mrd-layout-section__field-label" }, item.label), h("span", { class: "mrd-layout-section__field-value" }, renderedValue)));
|
|
239
|
+
return (h("div", { class: `mrd-layout-section__field${isBlock ? ' mrd-layout-section__field--block' : ''}`, key: item.name }, h("span", { class: "mrd-layout-section__field-label" }, item.label), h("span", { class: "mrd-layout-section__field-value" }, renderedValue, this.renderHistoryBadge(item, raw))));
|
|
205
240
|
}
|
|
206
241
|
renderRelation(item) {
|
|
207
242
|
var _a, _b, _c;
|
|
@@ -296,7 +331,7 @@ export class MrdLayoutSection {
|
|
|
296
331
|
return (h("div", { class: "mrd-layout-section__modal-backdrop", onClick: () => { this.imagePreviewUrl = null; } }, h("div", { class: "mrd-layout-section__modal", onClick: (e) => e.stopPropagation() }, h("button", { class: "mrd-layout-section__modal-close", onClick: () => { this.imagePreviewUrl = null; } }, "\u2715"), h("img", { class: "mrd-layout-section__modal-image", src: this.imagePreviewUrl, alt: "" }))));
|
|
297
332
|
}
|
|
298
333
|
render() {
|
|
299
|
-
return (h(Host, { key: '
|
|
334
|
+
return (h(Host, { key: '39ba6fc1fc823864025ca6a8df4c97b0f4cb96e6' }, h("div", { key: 'b1af15adfec5c699e00546b03b535149b834b6e4', class: "mrd-layout-section" }, this.items.map(item => this.renderItem(item))), this.renderImageModal()));
|
|
300
335
|
}
|
|
301
336
|
static get is() { return "mrd-layout-section"; }
|
|
302
337
|
static get encapsulation() { return "scoped"; }
|
|
@@ -439,7 +474,8 @@ export class MrdLayoutSection {
|
|
|
439
474
|
"searchQueryMap": {},
|
|
440
475
|
"searchResultsMap": {},
|
|
441
476
|
"imagePreviewUrl": {},
|
|
442
|
-
"imagePreviews": {}
|
|
477
|
+
"imagePreviews": {},
|
|
478
|
+
"openHistoryField": {}
|
|
443
479
|
};
|
|
444
480
|
}
|
|
445
481
|
static get events() {
|
|
@@ -24,6 +24,73 @@
|
|
|
24
24
|
font-weight: var(--mrd-font-weight-medium);
|
|
25
25
|
color: var(--mrd-color-neutral-800);
|
|
26
26
|
word-break: break-word;
|
|
27
|
+
display: inline-flex;
|
|
28
|
+
align-items: center;
|
|
29
|
+
gap: var(--mrd-space-1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.mrd-layout-section__history-wrap {
|
|
33
|
+
position: relative;
|
|
34
|
+
display: inline-flex;
|
|
35
|
+
align-items: center;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.mrd-layout-section__history-btn {
|
|
39
|
+
display: inline-flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
justify-content: center;
|
|
42
|
+
width: 1.25rem;
|
|
43
|
+
height: 1.25rem;
|
|
44
|
+
padding: 0;
|
|
45
|
+
background: transparent;
|
|
46
|
+
border: none;
|
|
47
|
+
border-radius: var(--mrd-border-radius-sm);
|
|
48
|
+
color: var(--mrd-color-neutral-400);
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
flex-shrink: 0;
|
|
51
|
+
transition: color var(--mrd-transition-fast), background-color var(--mrd-transition-fast);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.mrd-layout-section__history-btn:hover {
|
|
55
|
+
color: var(--mrd-color-neutral-700);
|
|
56
|
+
background-color: var(--mrd-color-neutral-100);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.mrd-layout-section__history-btn:focus {
|
|
60
|
+
outline: none;
|
|
61
|
+
box-shadow: var(--mrd-shadow-focus);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.mrd-layout-section__history-icon {
|
|
65
|
+
width: 0.875rem;
|
|
66
|
+
height: 0.875rem;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.mrd-layout-section__history-popover {
|
|
70
|
+
position: absolute;
|
|
71
|
+
top: calc(100% + 0.25rem);
|
|
72
|
+
left: 0;
|
|
73
|
+
min-width: 24rem;
|
|
74
|
+
max-width: 24rem;
|
|
75
|
+
background-color: var(--mrd-color-white);
|
|
76
|
+
border: var(--mrd-border-width) solid var(--mrd-border-color);
|
|
77
|
+
border-radius: var(--mrd-border-radius-md);
|
|
78
|
+
box-shadow: var(--mrd-shadow-md);
|
|
79
|
+
padding: var(--mrd-space-1) 0;
|
|
80
|
+
z-index: var(--mrd-z-dropdown);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.mrd-layout-section__history-entry {
|
|
84
|
+
font-family: var(--mrd-font-family);
|
|
85
|
+
font-size: var(--mrd-font-size-sm);
|
|
86
|
+
font-weight: var(--mrd-font-weight-normal);
|
|
87
|
+
color: var(--mrd-color-neutral-700);
|
|
88
|
+
padding: var(--mrd-space-2) var(--mrd-space-3);
|
|
89
|
+
line-height: var(--mrd-line-height-normal);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.mrd-layout-section__history-entry:not(:last-child) {
|
|
93
|
+
border-bottom: var(--mrd-border-width) solid var(--mrd-color-neutral-100);
|
|
27
94
|
}
|
|
28
95
|
|
|
29
96
|
.mrd-layout-section__field-header {
|
|
@@ -344,7 +344,7 @@ function renderSectionTabs(layouts) {
|
|
|
344
344
|
});
|
|
345
345
|
}
|
|
346
346
|
|
|
347
|
-
function renderSection(index) {
|
|
347
|
+
async function renderSection(index) {
|
|
348
348
|
_activeLayoutIndex = index;
|
|
349
349
|
const generation = ++_sectionGeneration; // snapshot for stale-fetch detection
|
|
350
350
|
|
|
@@ -357,6 +357,11 @@ function renderSection(index) {
|
|
|
357
357
|
const container = document.getElementById('sections-container');
|
|
358
358
|
container.innerHTML = '';
|
|
359
359
|
|
|
360
|
+
if (_dashboardType === 'form') {
|
|
361
|
+
await renderForm(layout, _dashboardRecord, _dashboardRecord?._links?.self?.href ?? null, container);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
|
|
360
365
|
const section = document.createElement('mrd-layout-section');
|
|
361
366
|
section.items = layout.items;
|
|
362
367
|
section.data = _dashboardRecord ?? { _links: _dashboardData._links ?? {} };
|
|
@@ -581,7 +586,7 @@ async function loadForm() {
|
|
|
581
586
|
* @param record - existing record for edit mode (null = new record)
|
|
582
587
|
* @param selfHref - absolute URL for PATCH; null = POST (new record)
|
|
583
588
|
*/
|
|
584
|
-
async function renderForm(layout, record = null, selfHref = null) {
|
|
589
|
+
async function renderForm(layout, record = null, selfHref = null, containerEl = null) {
|
|
585
590
|
// Build relation metadata map keyed by both relatedClass and mostSignificantClass
|
|
586
591
|
// so lookups work regardless of which value arrives in events (mrdSearch uses mostSignificantClass).
|
|
587
592
|
_relationMeta = {};
|
|
@@ -623,10 +628,10 @@ async function renderForm(layout, record = null, selfHref = null) {
|
|
|
623
628
|
}
|
|
624
629
|
}
|
|
625
630
|
|
|
626
|
-
const formPanel = document.getElementById('panel-form');
|
|
631
|
+
const formPanel = containerEl ?? document.getElementById('panel-form');
|
|
627
632
|
formPanel.innerHTML = `<mrd-form id="live-form" locale="${escHtml(_locale)}"></mrd-form>`;
|
|
628
633
|
|
|
629
|
-
const form = document.getElementById('live-form');
|
|
634
|
+
const form = formPanel.querySelector('#live-form') ?? document.getElementById('live-form');
|
|
630
635
|
// Wait for Stencil to fully initialize this specific instance before setting props.
|
|
631
636
|
// componentOnReady() resolves after componentDidLoad — more reliable than customElements.whenDefined.
|
|
632
637
|
if (typeof form.componentOnReady === 'function') {
|