@mmlogic/components 0.3.3 → 0.3.5

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.
Files changed (66) hide show
  1. package/dist/cjs/index.cjs.js +1 -0
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/mosterdcomponents.cjs.js +1 -1
  4. package/dist/cjs/{mrd-boolean-field_19.cjs.entry.js → mrd-boolean-field_20.cjs.entry.js} +313 -55
  5. package/dist/collection/collection-manifest.json +1 -0
  6. package/dist/collection/components/mrd-field/mrd-field.js +14 -2
  7. package/dist/collection/components/mrd-form/mrd-form.js +79 -0
  8. package/dist/collection/components/mrd-hyperlink-field/mrd-hyperlink-field.js +79 -18
  9. package/dist/collection/components/mrd-hyperlink-field/mrd-hyperlink-field.scss +22 -0
  10. package/dist/collection/components/mrd-image-field/mrd-image-field.js +1 -1
  11. package/dist/collection/components/mrd-layout-section/mrd-layout-section.js +15 -12
  12. package/dist/collection/components/mrd-layout-section/mrd-layout-section.scss +9 -0
  13. package/dist/collection/components/mrd-longtext-field/mrd-longtext-field.js +1 -1
  14. package/dist/collection/components/mrd-number-field/mrd-number-field.js +2 -2
  15. package/dist/collection/components/mrd-relation-field/mrd-relation-field.js +42 -13
  16. package/dist/collection/components/mrd-secret-field/mrd-secret-field.js +229 -0
  17. package/dist/collection/components/mrd-secret-field/mrd-secret-field.scss +73 -0
  18. package/dist/collection/components/mrd-table/mrd-table.js +82 -11
  19. package/dist/collection/components/mrd-table/mrd-table.scss +106 -3
  20. package/dist/collection/components/mrd-text-field/mrd-text-field.js +1 -1
  21. package/dist/collection/components/mrd-textarea-field/mrd-textarea-field.js +1 -1
  22. package/dist/collection/components/mrd-textarea-field/mrd-textarea-field.scss +56 -0
  23. package/dist/collection/components/mrd-time-field/mrd-time-field.js +1 -1
  24. package/dist/collection/dev/api.js +10 -1
  25. package/dist/collection/dev/app.js +56 -34
  26. package/dist/collection/dev/example-data.js +12 -2
  27. package/dist/collection/types/client-layout.js +1 -0
  28. package/dist/collection/utils/cell-renderer.js +2 -0
  29. package/dist/collection/utils/i18n.js +8 -0
  30. package/dist/collection/utils/validation.js +6 -2
  31. package/dist/components/client-layout.js +1 -1
  32. package/dist/components/i18n.js +1 -1
  33. package/dist/components/mrd-field2.js +1 -1
  34. package/dist/components/mrd-form.js +1 -1
  35. package/dist/components/mrd-hyperlink-field2.js +1 -1
  36. package/dist/components/mrd-image-field2.js +1 -1
  37. package/dist/components/mrd-layout-section.js +1 -1
  38. package/dist/components/mrd-longtext-field2.js +1 -1
  39. package/dist/components/mrd-number-field2.js +1 -1
  40. package/dist/components/mrd-relation-field2.js +1 -1
  41. package/dist/components/mrd-secret-field.d.ts +11 -0
  42. package/dist/components/mrd-secret-field.js +1 -0
  43. package/dist/components/mrd-secret-field2.js +1 -0
  44. package/dist/components/mrd-table2.js +1 -1
  45. package/dist/components/mrd-text-field2.js +1 -1
  46. package/dist/components/mrd-textarea-field2.js +1 -1
  47. package/dist/components/mrd-time-field2.js +1 -1
  48. package/dist/components/validation.js +1 -1
  49. package/dist/esm/index.js +1 -0
  50. package/dist/esm/loader.js +1 -1
  51. package/dist/esm/mosterdcomponents.js +1 -1
  52. package/dist/esm/{mrd-boolean-field_19.entry.js → mrd-boolean-field_20.entry.js} +313 -56
  53. package/dist/mosterdcomponents/index.esm.js +1 -1
  54. package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
  55. package/dist/mosterdcomponents/p-e477187c.entry.js +1 -0
  56. package/dist/types/components/mrd-form/mrd-form.d.ts +13 -1
  57. package/dist/types/components/mrd-hyperlink-field/mrd-hyperlink-field.d.ts +12 -4
  58. package/dist/types/components/mrd-layout-section/mrd-layout-section.d.ts +1 -0
  59. package/dist/types/components/mrd-relation-field/mrd-relation-field.d.ts +3 -0
  60. package/dist/types/components/mrd-secret-field/mrd-secret-field.d.ts +22 -0
  61. package/dist/types/components/mrd-table/mrd-table.d.ts +10 -0
  62. package/dist/types/components.d.ts +126 -20
  63. package/dist/types/types/client-layout.d.ts +12 -1
  64. package/dist/types/utils/cell-renderer.d.ts +1 -0
  65. package/package.json +1 -1
  66. package/dist/mosterdcomponents/p-74d100dd.entry.js +0 -1
@@ -15,6 +15,7 @@
15
15
  "components/mrd-longtext-field/mrd-longtext-field.js",
16
16
  "components/mrd-number-field/mrd-number-field.js",
17
17
  "components/mrd-relation-field/mrd-relation-field.js",
18
+ "components/mrd-secret-field/mrd-secret-field.js",
18
19
  "components/mrd-table/mrd-table.js",
19
20
  "components/mrd-text-field/mrd-text-field.js",
20
21
  "components/mrd-textarea-field/mrd-textarea-field.js",
@@ -22,8 +22,18 @@ export class MrdField {
22
22
  }
23
23
  };
24
24
  this.handleBlur = (e) => {
25
+ var _a, _b, _c, _d;
25
26
  e.stopPropagation();
26
- this.mrdBlur.emit(e.detail);
27
+ 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;
28
+ if (hist) {
29
+ this.mrdBlur.emit({
30
+ name: e.detail.name,
31
+ value: { current: this.currentValue, history: this.historyEntries },
32
+ });
33
+ }
34
+ else {
35
+ this.mrdBlur.emit(e.detail);
36
+ }
27
37
  };
28
38
  this.handleSearch = (e) => {
29
39
  e.stopPropagation();
@@ -101,7 +111,7 @@ export class MrdField {
101
111
  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
112
  }
103
113
  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;
114
+ 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, _3, _4;
105
115
  const { item, locale } = this;
106
116
  const commonProps = {
107
117
  name: item.name,
@@ -143,6 +153,8 @@ export class MrdField {
143
153
  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 })));
144
154
  case ClientLayoutItemFieldDataType.LONGTEXT:
145
155
  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 : '' })));
156
+ case ClientLayoutItemFieldDataType.SECRET:
157
+ return (h("mrd-secret-field", Object.assign({}, commonProps, { value: (_3 = displayValue) !== null && _3 !== void 0 ? _3 : '', placeholder: (_4 = item.placeholder) !== null && _4 !== void 0 ? _4 : '' })));
146
158
  default:
147
159
  return null;
148
160
  }
@@ -27,6 +27,12 @@ export class MrdForm {
27
27
  this.referenceClass = '';
28
28
  /** When true, a cancel button is shown next to the submit button. */
29
29
  this.showCancel = false;
30
+ /**
31
+ * The currently logged-in user, resolved by the host via /accounts/me.
32
+ * Used to pre-fill RELATION fields whose defaultValue is "@me".
33
+ * May be null when not authenticated or not yet resolved.
34
+ */
35
+ this.me = null;
30
36
  this.formValues = {};
31
37
  this.errors = {};
32
38
  this.submitted = false;
@@ -84,6 +90,7 @@ export class MrdForm {
84
90
  var _a, _b;
85
91
  this.initialValues = Object.assign({}, ((_a = this.values) !== null && _a !== void 0 ? _a : {}));
86
92
  this.formValues = Object.assign({}, ((_b = this.values) !== null && _b !== void 0 ? _b : {}));
93
+ this.applyDefaultValues();
87
94
  }
88
95
  componentDidLoad() {
89
96
  // Apply reference pre-fill and emit mrdFetchAll for dependent DROPDOWN fields.
@@ -99,11 +106,55 @@ export class MrdForm {
99
106
  this.initialValues = Object.assign({}, (newValues !== null && newValues !== void 0 ? newValues : {}));
100
107
  this.formValues = Object.assign({}, (newValues !== null && newValues !== void 0 ? newValues : {}));
101
108
  this.applyReferenceValue();
109
+ this.applyDefaultValues();
102
110
  this.errors = {};
103
111
  this.submitted = false;
104
112
  // Re-check DROPDOWN dependencies now that formValues are updated
105
113
  setTimeout(() => this.emitDependentFetchAll(), 0);
106
114
  }
115
+ /** Re-apply @me defaults when the me prop arrives after mount. */
116
+ meChanged() {
117
+ this.applyDefaultValues();
118
+ }
119
+ /** Apply defaultValue from layout items to fields that have no value yet.
120
+ * Tokens: today() → YYYY-MM-DD, now() → YYYY-MM-DDTHH:mm, @me → this.me. */
121
+ applyDefaultValues() {
122
+ var _a, _b, _c, _d, _e, _f, _g, _h;
123
+ const allFields = this.collectFields((_b = (_a = this.layout) === null || _a === void 0 ? void 0 : _a.items) !== null && _b !== void 0 ? _b : []);
124
+ const updates = {};
125
+ for (const item of allFields) {
126
+ if (!item.name)
127
+ continue;
128
+ const current = this.formValues[item.name];
129
+ if (current != null && current !== '')
130
+ continue;
131
+ const dv = (_e = (_c = item.defaultValue) !== null && _c !== void 0 ? _c : (_d = item.field) === null || _d === void 0 ? void 0 : _d.defaultValue) !== null && _e !== void 0 ? _e : (_f = item.relation) === null || _f === void 0 ? void 0 : _f.defaultValue;
132
+ if (!dv)
133
+ continue;
134
+ if (item.type === ClientLayoutItemType.FIELD) {
135
+ const resolved = this.resolveFieldDefault(dv, (_g = item.dataType) !== null && _g !== void 0 ? _g : (_h = item.field) === null || _h === void 0 ? void 0 : _h.dataType);
136
+ if (resolved != null)
137
+ updates[item.name] = resolved;
138
+ }
139
+ else if (item.type === ClientLayoutItemType.RELATION) {
140
+ if (dv === 'me()' && this.me) {
141
+ updates[item.name] = this.me;
142
+ }
143
+ }
144
+ }
145
+ if (Object.keys(updates).length > 0) {
146
+ this.formValues = Object.assign(Object.assign({}, this.formValues), updates);
147
+ }
148
+ }
149
+ resolveFieldDefault(dv, _dataType) {
150
+ if (dv === 'today()') {
151
+ return new Date().toISOString().slice(0, 10);
152
+ }
153
+ if (dv === 'now()') {
154
+ return new Date().toISOString().replace(/\.\d{3}Z$/, 'Z');
155
+ }
156
+ return dv;
157
+ }
107
158
  /**
108
159
  * When referenceHref + referenceClass are set, find the matching layout field
109
160
  * and inject its value into formValues. This allows dependent DROPDOWN fields
@@ -441,6 +492,31 @@ export class MrdForm {
441
492
  "reflect": false,
442
493
  "attribute": "show-cancel",
443
494
  "defaultValue": "false"
495
+ },
496
+ "me": {
497
+ "type": "unknown",
498
+ "mutable": false,
499
+ "complexType": {
500
+ "original": "RelationSearchResult | null",
501
+ "resolved": "RelationSearchResult | null",
502
+ "references": {
503
+ "RelationSearchResult": {
504
+ "location": "import",
505
+ "path": "../../types",
506
+ "id": "src/types/index.ts::RelationSearchResult",
507
+ "referenceLocation": "RelationSearchResult"
508
+ }
509
+ }
510
+ },
511
+ "required": false,
512
+ "optional": false,
513
+ "docs": {
514
+ "tags": [],
515
+ "text": "The currently logged-in user, resolved by the host via /accounts/me.\nUsed to pre-fill RELATION fields whose defaultValue is \"@me\".\nMay be null when not authenticated or not yet resolved."
516
+ },
517
+ "getter": false,
518
+ "setter": false,
519
+ "defaultValue": "null"
444
520
  }
445
521
  };
446
522
  }
@@ -572,6 +648,9 @@ export class MrdForm {
572
648
  return [{
573
649
  "propName": "values",
574
650
  "methodName": "valuesChanged"
651
+ }, {
652
+ "propName": "me",
653
+ "methodName": "meChanged"
575
654
  }];
576
655
  }
577
656
  }
@@ -10,28 +10,60 @@ export class MrdHyperlinkField {
10
10
  this.required = false;
11
11
  this.disabled = false;
12
12
  this.locale = navigator.language;
13
+ this.internalHref = '';
14
+ this.internalName = '';
13
15
  this.error = '';
14
- this.handleInput = (e) => {
15
- const val = e.target.value;
16
- this.mrdChange.emit({ name: this.name, value: val });
16
+ this.handleHrefInput = (e) => {
17
+ this.internalHref = e.target.value;
18
+ this.mrdChange.emit({ name: this.name, value: this.buildValue() });
17
19
  };
18
- this.handleBlur = (e) => {
19
- const val = e.target.value;
20
- if (this.required && !validateRequired(val)) {
20
+ this.handleNameInput = (e) => {
21
+ this.internalName = e.target.value;
22
+ this.mrdChange.emit({ name: this.name, value: this.buildValue() });
23
+ };
24
+ this.handleBlur = () => {
25
+ if (this.required && !validateRequired(this.internalHref)) {
21
26
  this.error = t('required', this.locale);
22
27
  }
23
- else if (val && !validateUrl(val)) {
28
+ else if (this.internalHref && !validateUrl(this.internalHref)) {
24
29
  this.error = t('invalid_url', this.locale);
25
30
  }
26
31
  else {
27
32
  this.error = '';
28
33
  }
29
- this.mrdBlur.emit({ name: this.name, value: val });
34
+ this.mrdBlur.emit({ name: this.name, value: this.buildValue() });
30
35
  };
31
36
  }
37
+ componentWillLoad() {
38
+ this.parseValue(this.value);
39
+ }
40
+ valueChanged(val) {
41
+ this.parseValue(val);
42
+ }
43
+ parseValue(val) {
44
+ var _a, _b, _c;
45
+ if (val !== null && val !== undefined && typeof val === 'object' && 'href' in val) {
46
+ this.internalHref = (_a = val.href) !== null && _a !== void 0 ? _a : '';
47
+ this.internalName = (_b = val.name) !== null && _b !== void 0 ? _b : '';
48
+ }
49
+ else {
50
+ this.internalHref = (_c = val) !== null && _c !== void 0 ? _c : '';
51
+ this.internalName = '';
52
+ }
53
+ }
54
+ buildValue() {
55
+ return this.internalName.trim()
56
+ ? { href: this.internalHref, name: this.internalName }
57
+ : { href: this.internalHref };
58
+ }
32
59
  render() {
33
60
  const hasError = !!this.error;
34
- return (h(Host, { key: '4f642cb037c6e25786593dbf0cbead71ce34580c' }, h("div", { key: 'c679d95924bc2d22089c435ec15a35132a4a062d', class: "mrd-hyperlink-field" }, this.label && (h("label", { key: 'b391dd2d152c68fe75517926c40779313a23b9d9', class: `mrd-hyperlink-field__label${this.required ? ' mrd-hyperlink-field__label--required' : ''}` }, this.label)), h("input", { key: 'ea0d2aba8520ecbde4df8e4507e0f16bd497baa9', class: `mrd-hyperlink-field__input${hasError ? ' mrd-hyperlink-field__input--error' : ''}`, type: "url", name: this.name, value: this.value, placeholder: this.placeholder || 'https://', required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur }), hasError && h("span", { key: 'fab1d90c726b69c6c43c7997fd1b7480678c2c78', class: "mrd-hyperlink-field__error" }, this.error))));
61
+ if (this.disabled) {
62
+ return (h(Host, null, h("div", { class: "mrd-hyperlink-field" }, this.label && h("span", { class: "mrd-hyperlink-field__label" }, this.label), this.internalHref
63
+ ? h("a", { class: "mrd-hyperlink-field__link", href: this.internalHref, target: "_blank", rel: "noopener noreferrer" }, this.internalName || this.internalHref)
64
+ : h("span", { class: "mrd-hyperlink-field__empty" }, "\u2014"))));
65
+ }
66
+ return (h(Host, null, h("div", { class: "mrd-hyperlink-field" }, this.label && (h("label", { class: `mrd-hyperlink-field__label${this.required ? ' mrd-hyperlink-field__label--required' : ''}` }, this.label)), h("input", { class: `mrd-hyperlink-field__input${hasError ? ' mrd-hyperlink-field__input--error' : ''}`, type: "url", name: this.name, value: this.internalHref, placeholder: this.placeholder || 'https://', required: this.required, onInput: this.handleHrefInput, onBlur: this.handleBlur }), h("input", { class: "mrd-hyperlink-field__input mrd-hyperlink-field__input--name", type: "text", value: this.internalName, placeholder: t('hyperlink_name', this.locale), onInput: this.handleNameInput, onBlur: this.handleBlur }), hasError && h("span", { class: "mrd-hyperlink-field__error" }, this.error))));
35
67
  }
36
68
  static get is() { return "mrd-hyperlink-field"; }
37
69
  static get encapsulation() { return "scoped"; }
@@ -91,9 +123,16 @@ export class MrdHyperlinkField {
91
123
  "type": "string",
92
124
  "mutable": false,
93
125
  "complexType": {
94
- "original": "string",
95
- "resolved": "string",
96
- "references": {}
126
+ "original": "HyperlinkValue | string",
127
+ "resolved": "HyperlinkValue | string",
128
+ "references": {
129
+ "HyperlinkValue": {
130
+ "location": "import",
131
+ "path": "../../types/client-layout",
132
+ "id": "src/types/client-layout.ts::HyperlinkValue",
133
+ "referenceLocation": "HyperlinkValue"
134
+ }
135
+ }
97
136
  },
98
137
  "required": false,
99
138
  "optional": false,
@@ -191,6 +230,8 @@ export class MrdHyperlinkField {
191
230
  }
192
231
  static get states() {
193
232
  return {
233
+ "internalHref": {},
234
+ "internalName": {},
194
235
  "error": {}
195
236
  };
196
237
  }
@@ -206,9 +247,16 @@ export class MrdHyperlinkField {
206
247
  "text": ""
207
248
  },
208
249
  "complexType": {
209
- "original": "{ name: string; value: string }",
210
- "resolved": "{ name: string; value: string; }",
211
- "references": {}
250
+ "original": "{ name: string; value: HyperlinkValue }",
251
+ "resolved": "{ name: string; value: HyperlinkValue; }",
252
+ "references": {
253
+ "HyperlinkValue": {
254
+ "location": "import",
255
+ "path": "../../types/client-layout",
256
+ "id": "src/types/client-layout.ts::HyperlinkValue",
257
+ "referenceLocation": "HyperlinkValue"
258
+ }
259
+ }
212
260
  }
213
261
  }, {
214
262
  "method": "mrdBlur",
@@ -221,10 +269,23 @@ export class MrdHyperlinkField {
221
269
  "text": ""
222
270
  },
223
271
  "complexType": {
224
- "original": "{ name: string; value: string }",
225
- "resolved": "{ name: string; value: string; }",
226
- "references": {}
272
+ "original": "{ name: string; value: HyperlinkValue }",
273
+ "resolved": "{ name: string; value: HyperlinkValue; }",
274
+ "references": {
275
+ "HyperlinkValue": {
276
+ "location": "import",
277
+ "path": "../../types/client-layout",
278
+ "id": "src/types/client-layout.ts::HyperlinkValue",
279
+ "referenceLocation": "HyperlinkValue"
280
+ }
281
+ }
227
282
  }
228
283
  }];
229
284
  }
285
+ static get watchers() {
286
+ return [{
287
+ "propName": "value",
288
+ "methodName": "valueChanged"
289
+ }];
290
+ }
230
291
  }
@@ -62,6 +62,28 @@
62
62
  box-shadow: var(--mrd-shadow-focus-error);
63
63
  }
64
64
 
65
+ .mrd-hyperlink-field__input--name {
66
+ margin-top: var(--mrd-space-1);
67
+ }
68
+
69
+ .mrd-hyperlink-field__link {
70
+ font-family: var(--mrd-font-family);
71
+ font-size: var(--mrd-font-size-base);
72
+ color: var(--mrd-color-primary);
73
+ text-decoration: underline;
74
+ word-break: break-all;
75
+ }
76
+
77
+ .mrd-hyperlink-field__link:hover {
78
+ opacity: 0.8;
79
+ }
80
+
81
+ .mrd-hyperlink-field__empty {
82
+ font-family: var(--mrd-font-family);
83
+ font-size: var(--mrd-font-size-base);
84
+ color: var(--mrd-color-neutral-400);
85
+ }
86
+
65
87
  .mrd-hyperlink-field__error {
66
88
  font-family: var(--mrd-font-family);
67
89
  font-size: var(--mrd-error-font-size);
@@ -99,7 +99,7 @@ export class MrdImageField {
99
99
  hasError ? 'mrd-image-field__zone--error' : '',
100
100
  this.disabled || this.uploading ? 'mrd-image-field__zone--disabled' : '',
101
101
  ].filter(Boolean).join(' ');
102
- return (h(Host, { key: '76b5a36a7f5a420ded3400c8a1481843363d1cbe' }, h("div", { key: '3544df84aaf427a25518bafe13d60cf89ed28537', class: "mrd-image-field" }, this.label && (h("label", { key: 'dca64c1600cb98526eb4b91a908106087f099ad1', class: `mrd-image-field__label${this.required ? ' mrd-image-field__label--required' : ''}` }, this.label)), h("div", { key: 'ce07f32126f0956e47ff6fc41ff231590e0503d3', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, h("input", { key: '660fbae5f730834c465522a11dd674fc8e50a54e', ref: el => (this.fileInputRef = el), class: "mrd-image-field__input", type: "file", name: this.name, accept: this.accept, disabled: this.disabled || this.uploading, required: this.required && !this.previewUrl, onChange: this.handleInputChange }), this.previewUrl ? (h("div", { class: "mrd-image-field__preview-container" }, h("div", { class: "mrd-image-field__preview-thumb" }, h("img", { class: "mrd-image-field__preview", src: this.previewUrl, alt: this.fileName }), this.uploading && h("div", { class: "mrd-image-field__preview-overlay" }, h("span", { class: "mrd-image-field__spinner" }))), h("div", { class: "mrd-image-field__preview-info" }, h("span", { class: "mrd-image-field__preview-name" }, this.fileName), this.uploading && (h("span", { class: "mrd-image-field__upload-status" }, t('loading', this.locale)))), !this.uploading && (h("button", { class: "mrd-image-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, t('remove', this.locale))))) : (h("div", { class: "mrd-image-field__prompt" }, h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), h("polyline", { points: "21 15 16 10 5 21" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-image-field__browse" }, t('browse', this.locale)))))), hasError && h("span", { key: '9b8f9563fea63bd12c38f5c480e9cbd24106c3af', class: "mrd-image-field__error" }, this.error))));
102
+ return (h(Host, { key: '71be4c1df559cff87280cac30be58beab3149064' }, h("div", { key: '9d0811d87068ce258aca9b2c5223a5594af9f6a3', class: "mrd-image-field" }, this.label && (h("label", { key: '63e129db968a2edfcc04fcac466d908ba4715158', class: `mrd-image-field__label${this.required ? ' mrd-image-field__label--required' : ''}` }, this.label)), h("div", { key: 'c7e560ad4dda43499707a2d1771a8eb561653a1b', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, h("input", { key: 'd325ee1aa3baccd689cc579e4cfa21abe977a575', ref: el => (this.fileInputRef = el), class: "mrd-image-field__input", type: "file", name: this.name, accept: this.accept, disabled: this.disabled || this.uploading, required: this.required && !this.previewUrl, onChange: this.handleInputChange }), this.previewUrl ? (h("div", { class: "mrd-image-field__preview-container" }, h("div", { class: "mrd-image-field__preview-thumb" }, h("img", { class: "mrd-image-field__preview", src: this.previewUrl, alt: this.fileName }), this.uploading && h("div", { class: "mrd-image-field__preview-overlay" }, h("span", { class: "mrd-image-field__spinner" }))), h("div", { class: "mrd-image-field__preview-info" }, h("span", { class: "mrd-image-field__preview-name" }, this.fileName), this.uploading && (h("span", { class: "mrd-image-field__upload-status" }, t('loading', this.locale)))), !this.uploading && (h("button", { class: "mrd-image-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, t('remove', this.locale))))) : (h("div", { class: "mrd-image-field__prompt" }, h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), h("polyline", { points: "21 15 16 10 5 21" })), h("span", null, t('drop_file_here', this.locale), ' ', h("span", { class: "mrd-image-field__browse" }, t('browse', this.locale)))))), hasError && h("span", { key: 'b0442d6f5c07ef22443194b3f1a95d2dfc409c4e', class: "mrd-image-field__error" }, this.error))));
103
103
  }
104
104
  static get is() { return "mrd-image-field"; }
105
105
  static get encapsulation() { return "scoped"; }
@@ -138,13 +138,13 @@ export class MrdLayoutSection {
138
138
  return null;
139
139
  }
140
140
  renderSingleFieldValue(item, value) {
141
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
141
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
142
142
  const dt = item.dataType;
143
143
  switch (dt) {
144
144
  case ClientLayoutItemFieldDataType.HYPERLINK: {
145
145
  const v = value;
146
146
  const href = (_a = v === null || v === void 0 ? void 0 : v.href) !== null && _a !== void 0 ? _a : String(value);
147
- const label = (_c = (_b = v === null || v === void 0 ? void 0 : v.text) !== null && _b !== void 0 ? _b : v === null || v === void 0 ? void 0 : v.label) !== null && _c !== void 0 ? _c : href;
147
+ 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;
148
148
  return (h("a", { class: "mrd-layout-section__link", href: href, target: "_blank", rel: "noopener noreferrer" }, label));
149
149
  }
150
150
  case ClientLayoutItemFieldDataType.TEXTBLOCK:
@@ -155,14 +155,14 @@ export class MrdLayoutSection {
155
155
  return h("pre", { class: "mrd-layout-section__pre", innerHTML: CellRenderer.formatJson(value) });
156
156
  case ClientLayoutItemFieldDataType.FILE: {
157
157
  const v = value;
158
- const fileName = (_d = v === null || v === void 0 ? void 0 : v.fileName) !== null && _d !== void 0 ? _d : String(value);
159
- const href = (_e = v === null || v === void 0 ? void 0 : v.href) !== null && _e !== void 0 ? _e : '';
158
+ const fileName = (_e = v === null || v === void 0 ? void 0 : v.fileName) !== null && _e !== void 0 ? _e : String(value);
159
+ const href = (_f = v === null || v === void 0 ? void 0 : v.href) !== null && _f !== void 0 ? _f : '';
160
160
  return (h("button", { class: "mrd-layout-section__download-link", onClick: () => href && this.mrdDownload.emit({ href, fileName }) }, h("svg", { class: "mrd-layout-section__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 7V3.5L18.5 9H13zm-3 8l-3-3 1.41-1.41L10 14.17l4.59-4.58L16 11l-6 6z" })), t('download', this.locale)));
161
161
  }
162
162
  case ClientLayoutItemFieldDataType.IMAGE: {
163
163
  const v = value;
164
- const href = (_f = v === null || v === void 0 ? void 0 : v.href) !== null && _f !== void 0 ? _f : '';
165
- const fileName = (_g = v === null || v === void 0 ? void 0 : v.fileName) !== null && _g !== void 0 ? _g : '';
164
+ const href = (_g = v === null || v === void 0 ? void 0 : v.href) !== null && _g !== void 0 ? _g : '';
165
+ const fileName = (_h = v === null || v === void 0 ? void 0 : v.fileName) !== null && _h !== void 0 ? _h : '';
166
166
  const previewUrl = this.imagePreviews[item.name];
167
167
  if (previewUrl) {
168
168
  return (h("button", { class: "mrd-layout-section__image-thumb-btn", onClick: () => { this.imagePreviewUrl = previewUrl; }, title: fileName || undefined }, h("img", { class: "mrd-layout-section__image-thumb", src: previewUrl, alt: fileName })));
@@ -172,8 +172,8 @@ export class MrdLayoutSection {
172
172
  case ClientLayoutItemFieldDataType.BOOLEAN:
173
173
  return (h("span", { class: `mrd-layout-section__boolean mrd-layout-section__boolean--${value ? 'true' : 'false'}` }, value ? t('yes', this.locale) : t('no', this.locale)));
174
174
  case ClientLayoutItemFieldDataType.LIST: {
175
- const listItem = ((_h = item.listItems) !== null && _h !== void 0 ? _h : []).find(li => li.key === String(value));
176
- const label = (_j = listItem === null || listItem === void 0 ? void 0 : listItem.label) !== null && _j !== void 0 ? _j : String(value);
175
+ const listItem = ((_j = item.listItems) !== null && _j !== void 0 ? _j : []).find(li => li.key === String(value));
176
+ const label = (_k = listItem === null || listItem === void 0 ? void 0 : listItem.label) !== null && _k !== void 0 ? _k : String(value);
177
177
  const color = listItem === null || listItem === void 0 ? void 0 : listItem.color;
178
178
  const bg = listItem === null || listItem === void 0 ? void 0 : listItem.backgroundColor;
179
179
  if (color && bg) {
@@ -184,8 +184,10 @@ export class MrdLayoutSection {
184
184
  }
185
185
  return label;
186
186
  }
187
+ case ClientLayoutItemFieldDataType.SECRET:
188
+ return value ? h("span", { class: "mrd-layout-section__secret-masked" }, '••••••••') : null;
187
189
  default: {
188
- const text = CellRenderer.renderValue(dt, value, (_k = item.listItems) !== null && _k !== void 0 ? _k : [], this.locale);
190
+ const text = CellRenderer.renderValue(dt, value, (_l = item.listItems) !== null && _l !== void 0 ? _l : [], this.locale);
189
191
  return text || null;
190
192
  }
191
193
  }
@@ -297,6 +299,7 @@ export class MrdLayoutSection {
297
299
  path: e.detail.path,
298
300
  qs: e.detail.qs,
299
301
  parentPath: e.detail.parentPath,
302
+ basicType: e.detail.basicType,
300
303
  });
301
304
  } })));
302
305
  }
@@ -331,7 +334,7 @@ export class MrdLayoutSection {
331
334
  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: "" }))));
332
335
  }
333
336
  render() {
334
- return (h(Host, { key: '39ba6fc1fc823864025ca6a8df4c97b0f4cb96e6' }, h("div", { key: 'b1af15adfec5c699e00546b03b535149b834b6e4', class: "mrd-layout-section" }, this.items.map(item => this.renderItem(item))), this.renderImageModal()));
337
+ return (h(Host, { key: '8966198eebd98570d2db2f4d2fe9ef3f8b466ec6' }, h("div", { key: '645ddbfdd829a0f9c1a4eab18105662af6c078b2', class: "mrd-layout-section" }, this.items.map(item => this.renderItem(item))), this.renderImageModal()));
335
338
  }
336
339
  static get is() { return "mrd-layout-section"; }
337
340
  static get encapsulation() { return "scoped"; }
@@ -572,8 +575,8 @@ export class MrdLayoutSection {
572
575
  "text": "Re-emitted from an embedded mrd-table's mrdAction; host builds the target URL from dataClass."
573
576
  },
574
577
  "complexType": {
575
- "original": "{ name: string; action: string; dataClass: string; path?: string; qs?: string; parentPath?: string | null }",
576
- "resolved": "{ name: string; action: string; dataClass: string; path?: string | undefined; qs?: string | undefined; parentPath?: string | null | undefined; }",
578
+ "original": "{ name: string; action: string; dataClass: string; path?: string; qs?: string; parentPath?: string | null; basicType?: string }",
579
+ "resolved": "{ name: string; action: string; dataClass: string; path?: string | undefined; qs?: string | undefined; parentPath?: string | null | undefined; basicType?: string | undefined; }",
577
580
  "references": {}
578
581
  }
579
582
  }, {
@@ -221,6 +221,15 @@
221
221
  flex-shrink: 0;
222
222
  }
223
223
 
224
+ .mrd-layout-section__secret-masked {
225
+ font-family: var(--mrd-font-family);
226
+ font-size: var(--mrd-font-size-base);
227
+ color: var(--mrd-label-color);
228
+ letter-spacing: 0.15em;
229
+ user-select: none;
230
+ pointer-events: none;
231
+ }
232
+
224
233
  .mrd-layout-section__pre {
225
234
  font-family: var(--mrd-font-family-mono);
226
235
  font-size: var(--mrd-font-size-xs);
@@ -28,7 +28,7 @@ export class MrdLongtextField {
28
28
  }
29
29
  render() {
30
30
  const hasError = !!this.error;
31
- return (h(Host, { key: '3142f97e26fdef5547c8dd9d236ed8bc40d5c65f' }, h("div", { key: 'b78567596d8c6459c8e9b28ea6b02d3fe65fd16c', class: "mrd-longtext-field" }, this.label && (h("label", { key: 'e85d8657fcc49fc7e15c06b8a98b34c03738ef5b', class: `mrd-longtext-field__label${this.required ? ' mrd-longtext-field__label--required' : ''}` }, this.label)), this.disabled ? (h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (h("textarea", { class: `mrd-longtext-field__input${hasError ? ' mrd-longtext-field__input--error' : ''}`, name: this.name, placeholder: this.placeholder, required: this.required, rows: 10, onInput: this.handleInput, onBlur: this.handleBlur }, this.value)), hasError && h("span", { key: '63cdcaf136e345197c42516f150752ec1d8665fa', class: "mrd-longtext-field__error" }, this.error))));
31
+ return (h(Host, { key: '10d998b80f54cf7b10be26bf451d808c78579e69' }, h("div", { key: 'af45fe94a41f668bf6ddca670b42e065ee83ef23', class: "mrd-longtext-field" }, this.label && (h("label", { key: '31a08490d695ac9f4bbe5dff6a1ae3bb2a94337d', class: `mrd-longtext-field__label${this.required ? ' mrd-longtext-field__label--required' : ''}` }, this.label)), this.disabled ? (h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (h("textarea", { class: `mrd-longtext-field__input${hasError ? ' mrd-longtext-field__input--error' : ''}`, name: this.name, placeholder: this.placeholder, required: this.required, rows: 10, onInput: this.handleInput, onBlur: this.handleBlur }, this.value)), hasError && h("span", { key: '7f133e72a882a8aaf33245445829754da1e6377b', class: "mrd-longtext-field__error" }, this.error))));
32
32
  }
33
33
  static get is() { return "mrd-longtext-field"; }
34
34
  static get encapsulation() { return "scoped"; }
@@ -69,7 +69,7 @@ export class MrdNumberField {
69
69
  const hasError = !!this.error;
70
70
  const suffix = this.dataType === ClientLayoutItemFieldDataType.PERCENTAGE ? '%' :
71
71
  this.dataType === ClientLayoutItemFieldDataType.DECIMAL ? '' : '';
72
- return (h(Host, { key: 'ba3488fb12f72bb04164e3e94c028fb8a085f1f2' }, h("div", { key: '582e30a2a256c16cc3b0cab6e64460a0a5ec1fa2', class: "mrd-number-field" }, this.label && (h("label", { key: '87fe77ce80e888406ecedaa450e8c3d2a61c790a', class: `mrd-number-field__label${this.required ? ' mrd-number-field__label--required' : ''}` }, this.label)), h("div", { key: 'e3d8cf06f585add372e385d6e6ef7d60ece8071b', class: "mrd-number-field__input-wrapper" }, h("input", { key: '04710b67ee0dcb9db327e25b2467b1b3499bc9a8', class: `mrd-number-field__input${hasError ? ' mrd-number-field__input--error' : ''}`, 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 })), hasError && h("span", { key: '9713244d784c82213ea835a5a6d47d468ccb0bb9', class: "mrd-number-field__error" }, this.error))));
72
+ return (h(Host, { key: '195beed4d6453597320b79654feaabe8f742eff2' }, h("div", { key: 'c641d7a4d27ba28dd34acda98d38f245945d20bb', class: "mrd-number-field" }, this.label && (h("label", { key: '2a5f6eb48889a3ab0aa76d6b2ca5d59b20625bb2', class: `mrd-number-field__label${this.required ? ' mrd-number-field__label--required' : ''}` }, this.label)), h("div", { key: 'a844b89e6a278629a8aefa4ac72e5e18e5904cab', class: "mrd-number-field__input-wrapper" }, h("input", { key: '1ce9c3d67b458601a0de95b3b8478ef05df73069', class: `mrd-number-field__input${hasError ? ' mrd-number-field__input--error' : ''}`, 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 })), hasError && h("span", { key: '4226614a65a8d27543d1287e2c1f61f67c427e63', class: "mrd-number-field__error" }, this.error))));
73
73
  }
74
74
  static get is() { return "mrd-number-field"; }
75
75
  static get encapsulation() { return "scoped"; }
@@ -230,7 +230,7 @@ export class MrdNumberField {
230
230
  "mutable": false,
231
231
  "complexType": {
232
232
  "original": "ClientLayoutItemFieldDataType",
233
- "resolved": "ClientLayoutItemFieldDataType.BOOLEAN | ClientLayoutItemFieldDataType.CURRENCY | ClientLayoutItemFieldDataType.DATE | ClientLayoutItemFieldDataType.DATETIME | ClientLayoutItemFieldDataType.DECIMAL | ClientLayoutItemFieldDataType.EMAIL | ClientLayoutItemFieldDataType.FILE | ClientLayoutItemFieldDataType.HYPERLINK | ClientLayoutItemFieldDataType.IMAGE | ClientLayoutItemFieldDataType.INTEGER | ClientLayoutItemFieldDataType.JSON | ClientLayoutItemFieldDataType.LIST | ClientLayoutItemFieldDataType.LONGTEXT | ClientLayoutItemFieldDataType.PERCENTAGE | ClientLayoutItemFieldDataType.TEXT | ClientLayoutItemFieldDataType.TEXTBLOCK | ClientLayoutItemFieldDataType.TIME",
233
+ "resolved": "ClientLayoutItemFieldDataType.BOOLEAN | ClientLayoutItemFieldDataType.CURRENCY | ClientLayoutItemFieldDataType.DATE | ClientLayoutItemFieldDataType.DATETIME | ClientLayoutItemFieldDataType.DECIMAL | ClientLayoutItemFieldDataType.EMAIL | ClientLayoutItemFieldDataType.FILE | ClientLayoutItemFieldDataType.HYPERLINK | ClientLayoutItemFieldDataType.IMAGE | ClientLayoutItemFieldDataType.INTEGER | ClientLayoutItemFieldDataType.JSON | ClientLayoutItemFieldDataType.LIST | ClientLayoutItemFieldDataType.LONGTEXT | ClientLayoutItemFieldDataType.PERCENTAGE | ClientLayoutItemFieldDataType.SECRET | ClientLayoutItemFieldDataType.TEXT | ClientLayoutItemFieldDataType.TEXTBLOCK | ClientLayoutItemFieldDataType.TIME",
234
234
  "references": {
235
235
  "ClientLayoutItemFieldDataType": {
236
236
  "location": "import",
@@ -165,23 +165,49 @@ export class MrdRelationField {
165
165
  async setLoading(loading) {
166
166
  this.isLoading = loading;
167
167
  }
168
- componentWillLoad() {
169
- var _a;
170
- // Pre-fill selectedItems when value is passed as { id, label } objects
171
- // (e.g. when editing an existing record fetched from the API).
172
- if (this.value) {
173
- if (Array.isArray(this.value)) {
174
- if (this.value.length > 0 && typeof this.value[0] === 'object') {
175
- this.selectedItems = this.value;
176
- this.searchQuery = '';
177
- }
168
+ toSearchResult(v) {
169
+ var _a, _b, _c, _d;
170
+ return {
171
+ id: (_b = (_a = v.id) !== null && _a !== void 0 ? _a : v.href) !== null && _b !== void 0 ? _b : '',
172
+ label: (_d = (_c = v.label) !== null && _c !== void 0 ? _c : v.name) !== null && _d !== void 0 ? _d : '',
173
+ description: v.description,
174
+ };
175
+ }
176
+ applyValuePrefill(v) {
177
+ if (!v)
178
+ return;
179
+ if (Array.isArray(v)) {
180
+ if (v.length > 0 && typeof v[0] === 'object') {
181
+ this.selectedItems = v.map(item => this.toSearchResult(item));
182
+ this.searchQuery = '';
178
183
  }
179
- else if (typeof this.value === 'object') {
180
- this.selectedItems = [this.value];
181
- this.searchQuery = (_a = this.value.label) !== null && _a !== void 0 ? _a : '';
184
+ // array of strings user interaction, ignore
185
+ }
186
+ else if (typeof v === 'object') {
187
+ const obj = v;
188
+ if (Array.isArray(obj.values)) {
189
+ // Multiple relation: API embeds selected items in values[]
190
+ this.selectedItems = obj.values.map((item) => this.toSearchResult(item));
191
+ this.searchQuery = '';
192
+ }
193
+ else if (!this.multiple && (obj.id || obj.name || obj.label)) {
194
+ // Single relation: { href, name } or already { id, label }
195
+ const result = this.toSearchResult(obj);
196
+ this.selectedItems = [result];
197
+ this.searchQuery = result.label;
182
198
  }
199
+ // else: collection href (multiple without values) or unrecognised — skip
183
200
  }
184
201
  }
202
+ componentWillLoad() {
203
+ this.applyValuePrefill(this.value);
204
+ }
205
+ // Handles edit-mode: values prop on mrd-form is often set async after mount.
206
+ // Only updates selectedItems when the new value contains { id, label } objects
207
+ // (host pre-fill). Plain href strings from user interaction are ignored.
208
+ valueChanged(newValue) {
209
+ this.applyValuePrefill(newValue);
210
+ }
185
211
  componentDidLoad() {
186
212
  // Only emit when there is no commonRelation dependency — the form orchestrates those.
187
213
  if (this.editBehavior === ClientLayoutItemRelationEditBehavior.DROPDOWN && !this.commonRelation) {
@@ -673,6 +699,9 @@ export class MrdRelationField {
673
699
  return [{
674
700
  "propName": "allRecords",
675
701
  "methodName": "allRecordsChanged"
702
+ }, {
703
+ "propName": "value",
704
+ "methodName": "valueChanged"
676
705
  }];
677
706
  }
678
707
  }