@mmlogic/components 0.5.2 → 0.5.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/{cell-renderer-CmaO0CZT.js → cell-renderer-7KX9Qbml.js} +122 -1
- package/dist/cjs/{client-layout-RZ3Ix-4a.js → client-layout-CqVuJumR.js} +9 -0
- package/dist/cjs/{index-DzRfoAPz.js → index-DVbdkYO3.js} +468 -6
- package/dist/cjs/index.cjs.js +4 -1
- 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 → mrd-boolean-field_25.cjs.entry.js} +5618 -5225
- package/dist/cjs/mrd-merge-view.cjs.entry.js +5 -5
- package/dist/collection/collection-manifest.json +2 -0
- package/dist/collection/components/documents/mrd-document-view/mrd-document-view.js +7 -8
- package/dist/collection/components/email/mrd-email-view/mrd-email-view.css +126 -0
- package/dist/collection/components/email/mrd-email-view/mrd-email-view.js +247 -0
- package/dist/collection/components/fields/file-upload-common.js +23 -7
- package/dist/collection/components/fields/mrd-boolean-field/mrd-boolean-field.js +1 -1
- package/dist/collection/components/fields/mrd-currency-field/mrd-currency-field.js +1 -1
- package/dist/collection/components/fields/mrd-date-field/mrd-date-field.js +1 -1
- package/dist/collection/components/fields/mrd-datetime-field/mrd-datetime-field.js +1 -1
- package/dist/collection/components/fields/mrd-email-field/mrd-email-field.js +1 -1
- package/dist/collection/components/fields/mrd-file-field/mrd-file-field.css +20 -1
- package/dist/collection/components/fields/mrd-file-field/mrd-file-field.js +108 -47
- package/dist/collection/components/fields/mrd-image-field/mrd-image-field.css +44 -0
- package/dist/collection/components/fields/mrd-image-field/mrd-image-field.js +126 -58
- package/dist/collection/components/fields/mrd-longtext-field/mrd-longtext-field.js +1 -1
- package/dist/collection/components/fields/mrd-number-field/mrd-number-field.js +1 -1
- package/dist/collection/components/fields/mrd-secret-field/mrd-secret-field.js +2 -2
- package/dist/collection/components/fields/mrd-text-field/mrd-text-field.js +1 -1
- package/dist/collection/components/fields/mrd-textarea-field/mrd-textarea-field.js +1 -1
- package/dist/collection/components/fields/mrd-time-field/mrd-time-field.js +1 -1
- package/dist/collection/components/form/mrd-field/mrd-field.js +5 -5
- package/dist/collection/components/form/mrd-form/mrd-form.js +55 -6
- package/dist/collection/components/invoice/mrd-invoice-view/mrd-invoice-view.css +145 -0
- package/dist/collection/components/invoice/mrd-invoice-view/mrd-invoice-view.js +281 -0
- package/dist/collection/components/layout/mrd-layout-section/field-value.js +5 -1
- package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.css +10 -0
- package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.js +38 -8
- package/dist/collection/components/merge/mrd-merge-view/mrd-merge-view.js +2 -2
- package/dist/collection/dev/api.js +20 -5
- package/dist/collection/dev/app.js +51 -13
- package/dist/collection/dev/example-data.js +126 -2
- package/dist/collection/types/client-layout.js +6 -0
- package/dist/collection/utils/document-attachments.js +27 -14
- package/dist/collection/utils/i18n.js +120 -0
- package/dist/components/cell-renderer.js +1 -1
- package/dist/components/client-layout.js +1 -1
- package/dist/components/document-attachments.js +1 -1
- package/dist/components/file-upload-common.js +1 -1
- package/dist/components/format.js +1 -1
- package/dist/components/i18n.js +1 -1
- package/dist/components/index.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-view2.js +1 -1
- package/dist/components/mrd-email-field2.js +1 -1
- package/dist/components/mrd-email-view.d.ts +11 -0
- package/dist/components/mrd-email-view.js +1 -0
- package/dist/components/mrd-email-view2.js +1 -0
- package/dist/components/mrd-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-image-field2.js +1 -1
- package/dist/components/mrd-invoice-view.d.ts +11 -0
- package/dist/components/mrd-invoice-view.js +1 -0
- package/dist/components/mrd-invoice-view2.js +1 -0
- package/dist/components/mrd-layout-section.js +1 -1
- package/dist/components/mrd-longtext-field2.js +1 -1
- package/dist/components/mrd-merge-view.js +1 -1
- package/dist/components/mrd-number-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 -2
- package/dist/components/mrd-time-field2.js +1 -1
- package/dist/components/purify.es.js +2 -0
- package/dist/esm/{cell-renderer-D63AUZxa.js → cell-renderer-DIsNX9D7.js} +122 -2
- package/dist/esm/{client-layout-DCOAAH92.js → client-layout-Bc42CfJB.js} +7 -1
- package/dist/esm/{index-DiSe6vjv.js → index-CDiBvvJU.js} +468 -6
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/mosterdcomponents.js +3 -3
- package/dist/esm/{mrd-boolean-field_23.entry.js → mrd-boolean-field_25.entry.js} +5617 -5226
- package/dist/esm/mrd-merge-view.entry.js +5 -5
- package/dist/mosterdcomponents/index.esm.js +1 -1
- package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
- package/dist/mosterdcomponents/{p-2e16a7d0.entry.js → p-4e061416.entry.js} +1 -1
- package/dist/mosterdcomponents/p-910ebfee.entry.js +3 -0
- package/dist/mosterdcomponents/{p-DCOAAH92.js → p-Bc42CfJB.js} +1 -1
- package/dist/mosterdcomponents/p-CDiBvvJU.js +2 -0
- package/dist/mosterdcomponents/p-Ce2QDq0t.js +1 -0
- package/dist/types/components/documents/mrd-document-view/mrd-document-view.d.ts +2 -2
- package/dist/types/components/email/mrd-email-view/mrd-email-view.d.ts +52 -0
- package/dist/types/components/fields/file-upload-common.d.ts +19 -1
- package/dist/types/components/fields/mrd-file-field/mrd-file-field.d.ts +24 -10
- package/dist/types/components/fields/mrd-image-field/mrd-image-field.d.ts +27 -11
- package/dist/types/components/form/mrd-form/mrd-form.d.ts +16 -1
- package/dist/types/components/invoice/mrd-invoice-view/mrd-invoice-view.d.ts +60 -0
- package/dist/types/components/layout/mrd-layout-section/mrd-layout-section.d.ts +13 -0
- package/dist/types/components.d.ts +294 -19
- package/dist/types/types/client-layout.d.ts +6 -0
- package/dist/types/utils/document-attachments.d.ts +12 -5
- package/package.json +1 -1
- package/dist/mosterdcomponents/p-CnqDM0Gb.js +0 -1
- package/dist/mosterdcomponents/p-DiSe6vjv.js +0 -2
- package/dist/mosterdcomponents/p-b5f38707.entry.js +0 -3
|
@@ -20,7 +20,7 @@ export class MrdTimeField {
|
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
render() {
|
|
23
|
-
return (h(Host, { key: '
|
|
23
|
+
return (h(Host, { key: 'd521c654bc7beda71a31542a25198edaaf53b838' }, h("div", { key: '084ab16ac8aed952bd0ec50e0430591d4db5bd4b', class: "mrd-time-field" }, h(FieldLabel, { key: '43938ad7c5a9765353f6523d399d4b74cbb9ec6f', base: "mrd-time-field", label: this.label, required: this.required }), h("input", { key: 'e46eda620e7a5f1bb3b433a4c051e913675c33f9', class: controlClass('mrd-time-field', !!this.error), type: "time", name: this.name, value: this.value, required: this.required, disabled: this.disabled, onChange: this.handleChange, onBlur: this.handleBlur }), h(FieldError, { key: '34bc1eaa1b969951dffaaacad73af532b6d290fb', base: "mrd-time-field", error: this.error }))));
|
|
24
24
|
}
|
|
25
25
|
static get is() { return "mrd-time-field"; }
|
|
26
26
|
static get encapsulation() { return "scoped"; }
|
|
@@ -111,7 +111,7 @@ export class MrdField {
|
|
|
111
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))));
|
|
112
112
|
}
|
|
113
113
|
renderLeafField(displayValue) {
|
|
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;
|
|
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, _5, _6;
|
|
115
115
|
const { item, locale } = this;
|
|
116
116
|
const commonProps = {
|
|
117
117
|
name: item.name,
|
|
@@ -148,13 +148,13 @@ export class MrdField {
|
|
|
148
148
|
case ClientLayoutItemFieldDataType.LIST:
|
|
149
149
|
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 : [] })));
|
|
150
150
|
case ClientLayoutItemFieldDataType.FILE:
|
|
151
|
-
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 })));
|
|
151
|
+
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, multiple: (_z = item.multiple) !== null && _z !== void 0 ? _z : false, onMrdUpload: this.handleUpload })));
|
|
152
152
|
case ClientLayoutItemFieldDataType.IMAGE:
|
|
153
|
-
return (h("mrd-image-field", Object.assign({}, commonProps, { value: displayValue, accept: (
|
|
153
|
+
return (h("mrd-image-field", Object.assign({}, commonProps, { value: displayValue, accept: (_0 = item.accept) !== null && _0 !== void 0 ? _0 : 'image/*', maxSize: (_1 = item.maxSize) !== null && _1 !== void 0 ? _1 : 0, multiple: (_2 = item.multiple) !== null && _2 !== void 0 ? _2 : false, onMrdUpload: this.handleUpload })));
|
|
154
154
|
case ClientLayoutItemFieldDataType.LONGTEXT:
|
|
155
|
-
return (h("mrd-longtext-field", Object.assign({}, commonProps, { value: (
|
|
155
|
+
return (h("mrd-longtext-field", Object.assign({}, commonProps, { value: (_3 = displayValue) !== null && _3 !== void 0 ? _3 : '', placeholder: (_4 = item.placeholder) !== null && _4 !== void 0 ? _4 : '' })));
|
|
156
156
|
case ClientLayoutItemFieldDataType.SECRET:
|
|
157
|
-
return (h("mrd-secret-field", Object.assign({}, commonProps, { value: (
|
|
157
|
+
return (h("mrd-secret-field", Object.assign({}, commonProps, { value: (_5 = displayValue) !== null && _5 !== void 0 ? _5 : '', placeholder: (_6 = item.placeholder) !== null && _6 !== void 0 ? _6 : '' })));
|
|
158
158
|
default:
|
|
159
159
|
return null;
|
|
160
160
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Host, h } from "@stencil/core";
|
|
2
|
-
import { ClientLayoutItemType, ClientLayoutItemRelationEditBehavior } from "../../../types";
|
|
2
|
+
import { ClientLayoutItemFieldDataType, ClientLayoutItemType, ClientLayoutItemRelationEditBehavior } from "../../../types";
|
|
3
3
|
import { t } from "../../../utils/i18n";
|
|
4
4
|
import { validateRequired } from "../../../utils/validation";
|
|
5
5
|
export class MrdForm {
|
|
@@ -199,7 +199,31 @@ export class MrdForm {
|
|
|
199
199
|
}
|
|
200
200
|
return null;
|
|
201
201
|
}
|
|
202
|
-
|
|
202
|
+
/**
|
|
203
|
+
* Inject a value from outside (e.g. after a file upload completes).
|
|
204
|
+
* `file` is optional and only meaningful for `multiple` FILE/IMAGE fields: when
|
|
205
|
+
* the field's current value is an array, mrd-form replaces the array entry that
|
|
206
|
+
* `=== file` with `value`, leaving other pending/resolved entries untouched —
|
|
207
|
+
* this is how mrd-file-field/mrd-image-field resolve concurrent per-file uploads.
|
|
208
|
+
* Pass the `file` from the originating mrdUpload event back unchanged.
|
|
209
|
+
*/
|
|
210
|
+
async setFieldValue(name, value, file) {
|
|
211
|
+
if (file) {
|
|
212
|
+
const current = this.formValues[name];
|
|
213
|
+
if (Array.isArray(current)) {
|
|
214
|
+
const index = current.indexOf(file);
|
|
215
|
+
if (index === -1)
|
|
216
|
+
return; // the file was removed from the field before its upload resolved
|
|
217
|
+
const next = [...current];
|
|
218
|
+
next[index] = value;
|
|
219
|
+
this.formValues = Object.assign(Object.assign({}, this.formValues), { [name]: next });
|
|
220
|
+
if (this.errors[name])
|
|
221
|
+
this.errors = Object.assign(Object.assign({}, this.errors), { [name]: '' });
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (current !== file)
|
|
225
|
+
return; // stale resolution for a value that was since cleared/replaced
|
|
226
|
+
}
|
|
203
227
|
this.formValues = Object.assign(Object.assign({}, this.formValues), { [name]: value });
|
|
204
228
|
if (this.errors[name]) {
|
|
205
229
|
this.errors = Object.assign(Object.assign({}, this.errors), { [name]: '' });
|
|
@@ -269,6 +293,20 @@ export class MrdForm {
|
|
|
269
293
|
normalizeFieldValue(value) {
|
|
270
294
|
return (value === '' || value == null) ? null : value;
|
|
271
295
|
}
|
|
296
|
+
/** FILE/IMAGE entries render as `{ href, fileName, contentType?, size? }` — the same
|
|
297
|
+
* shape the API returns for an already-persisted file — or a bare href string for
|
|
298
|
+
* freshly-resolved uploads. Only `href` is meaningful to the API, so unwrap before
|
|
299
|
+
* submit (mirrors normalizeRelationValue). Do NOT fall back to any other key (e.g.
|
|
300
|
+
* `id`) as a stand-in for `href` — a bare id is not a valid/complete reference on its
|
|
301
|
+
* own; if `href` is ever missing that's an API bug to fix upstream, not to paper over here. */
|
|
302
|
+
normalizeFileFieldValue(value) {
|
|
303
|
+
const toHref = (v) => v && typeof v === 'object' && 'href' in v ? v.href : v;
|
|
304
|
+
if (Array.isArray(value)) {
|
|
305
|
+
const hrefs = value.map(toHref).filter(v => v != null && v !== '');
|
|
306
|
+
return hrefs.length ? hrefs : null;
|
|
307
|
+
}
|
|
308
|
+
return this.normalizeFieldValue(toHref(value));
|
|
309
|
+
}
|
|
272
310
|
normalizeRelationValue(value) {
|
|
273
311
|
if (value == null || value === '')
|
|
274
312
|
return null;
|
|
@@ -315,8 +353,11 @@ export class MrdForm {
|
|
|
315
353
|
const rawValue = this.formValues[name];
|
|
316
354
|
if (rawValue instanceof File)
|
|
317
355
|
continue;
|
|
318
|
-
|
|
319
|
-
|
|
356
|
+
if (Array.isArray(rawValue) && rawValue.some(v => v instanceof File))
|
|
357
|
+
continue;
|
|
358
|
+
const isFileField = item.dataType === ClientLayoutItemFieldDataType.FILE || item.dataType === ClientLayoutItemFieldDataType.IMAGE;
|
|
359
|
+
const current = isFileField ? this.normalizeFileFieldValue(rawValue) : this.normalizeFieldValue(rawValue);
|
|
360
|
+
const initial = isFileField ? this.normalizeFileFieldValue(this.initialValues[name]) : this.normalizeFieldValue(this.initialValues[name]);
|
|
320
361
|
if (this.deepEqual(current, initial))
|
|
321
362
|
continue;
|
|
322
363
|
payload[name] = current;
|
|
@@ -619,7 +660,7 @@ export class MrdForm {
|
|
|
619
660
|
return {
|
|
620
661
|
"setFieldValue": {
|
|
621
662
|
"complexType": {
|
|
622
|
-
"signature": "(name: string, value: unknown) => Promise<void>",
|
|
663
|
+
"signature": "(name: string, value: unknown, file?: File) => Promise<void>",
|
|
623
664
|
"parameters": [{
|
|
624
665
|
"name": "name",
|
|
625
666
|
"type": "string",
|
|
@@ -628,17 +669,25 @@ export class MrdForm {
|
|
|
628
669
|
"name": "value",
|
|
629
670
|
"type": "unknown",
|
|
630
671
|
"docs": ""
|
|
672
|
+
}, {
|
|
673
|
+
"name": "file",
|
|
674
|
+
"type": "File | undefined",
|
|
675
|
+
"docs": ""
|
|
631
676
|
}],
|
|
632
677
|
"references": {
|
|
633
678
|
"Promise": {
|
|
634
679
|
"location": "global",
|
|
635
680
|
"id": "global::Promise"
|
|
681
|
+
},
|
|
682
|
+
"File": {
|
|
683
|
+
"location": "global",
|
|
684
|
+
"id": "global::File"
|
|
636
685
|
}
|
|
637
686
|
},
|
|
638
687
|
"return": "Promise<void>"
|
|
639
688
|
},
|
|
640
689
|
"docs": {
|
|
641
|
-
"text": "",
|
|
690
|
+
"text": "Inject a value from outside (e.g. after a file upload completes).\n`file` is optional and only meaningful for `multiple` FILE/IMAGE fields: when\nthe field's current value is an array, mrd-form replaces the array entry that\n`=== file` with `value`, leaving other pending/resolved entries untouched \u2014\nthis is how mrd-file-field/mrd-image-field resolve concurrent per-file uploads.\nPass the `file` from the originating mrdUpload event back unchanged.",
|
|
642
691
|
"tags": []
|
|
643
692
|
}
|
|
644
693
|
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: block;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.mrd-invoice-view {
|
|
6
|
+
max-width: 720px;
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
gap: var(--mrd-space-6);
|
|
10
|
+
}
|
|
11
|
+
.mrd-invoice-view__title-row {
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
gap: var(--mrd-space-3);
|
|
15
|
+
flex-wrap: wrap;
|
|
16
|
+
}
|
|
17
|
+
.mrd-invoice-view__title {
|
|
18
|
+
font-size: var(--mrd-font-size-2xl);
|
|
19
|
+
font-weight: var(--mrd-font-weight-bold);
|
|
20
|
+
color: var(--mrd-color-neutral-900);
|
|
21
|
+
letter-spacing: -0.02em;
|
|
22
|
+
margin: 0;
|
|
23
|
+
}
|
|
24
|
+
.mrd-invoice-view__badge {
|
|
25
|
+
display: inline-block;
|
|
26
|
+
font-size: var(--mrd-font-size-xs);
|
|
27
|
+
font-weight: var(--mrd-font-weight-medium);
|
|
28
|
+
padding: 2px var(--mrd-space-3);
|
|
29
|
+
border-radius: var(--mrd-border-radius-full);
|
|
30
|
+
}
|
|
31
|
+
.mrd-invoice-view__badge--plain {
|
|
32
|
+
color: var(--mrd-color-neutral-600);
|
|
33
|
+
background: var(--mrd-color-neutral-100);
|
|
34
|
+
}
|
|
35
|
+
.mrd-invoice-view__dates {
|
|
36
|
+
display: flex;
|
|
37
|
+
gap: var(--mrd-space-4);
|
|
38
|
+
font-size: var(--mrd-font-size-sm);
|
|
39
|
+
color: var(--mrd-color-neutral-400);
|
|
40
|
+
font-variant-numeric: tabular-nums;
|
|
41
|
+
margin-top: var(--mrd-space-1);
|
|
42
|
+
}
|
|
43
|
+
.mrd-invoice-view__container-link {
|
|
44
|
+
display: inline-block;
|
|
45
|
+
margin-top: var(--mrd-space-3);
|
|
46
|
+
background: none;
|
|
47
|
+
border: none;
|
|
48
|
+
padding: 0;
|
|
49
|
+
font-family: var(--mrd-font-family);
|
|
50
|
+
font-size: var(--mrd-font-size-sm);
|
|
51
|
+
font-weight: var(--mrd-font-weight-semibold);
|
|
52
|
+
color: var(--mrd-color-primary);
|
|
53
|
+
cursor: pointer;
|
|
54
|
+
text-align: left;
|
|
55
|
+
}
|
|
56
|
+
.mrd-invoice-view__container-link:hover {
|
|
57
|
+
text-decoration: underline;
|
|
58
|
+
}
|
|
59
|
+
.mrd-invoice-view__parties {
|
|
60
|
+
display: flex;
|
|
61
|
+
gap: var(--mrd-space-8);
|
|
62
|
+
flex-wrap: wrap;
|
|
63
|
+
}
|
|
64
|
+
.mrd-invoice-view__party {
|
|
65
|
+
display: flex;
|
|
66
|
+
flex-direction: column;
|
|
67
|
+
gap: var(--mrd-space-1);
|
|
68
|
+
}
|
|
69
|
+
.mrd-invoice-view__party-label {
|
|
70
|
+
font-size: var(--mrd-font-size-xs);
|
|
71
|
+
font-weight: var(--mrd-font-weight-medium);
|
|
72
|
+
color: var(--mrd-color-neutral-400);
|
|
73
|
+
text-transform: uppercase;
|
|
74
|
+
letter-spacing: 0.04em;
|
|
75
|
+
}
|
|
76
|
+
.mrd-invoice-view__link {
|
|
77
|
+
background: none;
|
|
78
|
+
border: none;
|
|
79
|
+
padding: 0;
|
|
80
|
+
font-family: var(--mrd-font-family);
|
|
81
|
+
font-size: var(--mrd-font-size-sm);
|
|
82
|
+
font-weight: var(--mrd-font-weight-semibold);
|
|
83
|
+
color: var(--mrd-color-primary);
|
|
84
|
+
cursor: pointer;
|
|
85
|
+
text-align: left;
|
|
86
|
+
}
|
|
87
|
+
.mrd-invoice-view__link:hover {
|
|
88
|
+
text-decoration: underline;
|
|
89
|
+
}
|
|
90
|
+
.mrd-invoice-view__lines {
|
|
91
|
+
border-top: var(--mrd-border-width) solid var(--mrd-color-neutral-200);
|
|
92
|
+
border-bottom: var(--mrd-border-width) solid var(--mrd-color-neutral-200);
|
|
93
|
+
padding: var(--mrd-space-4) 0;
|
|
94
|
+
}
|
|
95
|
+
.mrd-invoice-view__amounts {
|
|
96
|
+
align-self: flex-end;
|
|
97
|
+
display: flex;
|
|
98
|
+
flex-direction: column;
|
|
99
|
+
gap: var(--mrd-space-2);
|
|
100
|
+
min-width: 16rem;
|
|
101
|
+
}
|
|
102
|
+
.mrd-invoice-view__amount-row {
|
|
103
|
+
display: flex;
|
|
104
|
+
justify-content: space-between;
|
|
105
|
+
gap: var(--mrd-space-6);
|
|
106
|
+
font-size: var(--mrd-font-size-sm);
|
|
107
|
+
color: var(--mrd-color-neutral-700);
|
|
108
|
+
}
|
|
109
|
+
.mrd-invoice-view__amount-row--total {
|
|
110
|
+
padding-top: var(--mrd-space-2);
|
|
111
|
+
border-top: var(--mrd-border-width) solid var(--mrd-color-neutral-200);
|
|
112
|
+
font-size: var(--mrd-font-size-base);
|
|
113
|
+
font-weight: var(--mrd-font-weight-bold);
|
|
114
|
+
color: var(--mrd-color-neutral-900);
|
|
115
|
+
}
|
|
116
|
+
.mrd-invoice-view__attachments {
|
|
117
|
+
display: flex;
|
|
118
|
+
flex-direction: column;
|
|
119
|
+
gap: var(--mrd-space-2);
|
|
120
|
+
}
|
|
121
|
+
.mrd-invoice-view__attachment {
|
|
122
|
+
display: inline-flex;
|
|
123
|
+
align-items: center;
|
|
124
|
+
gap: var(--mrd-space-2);
|
|
125
|
+
align-self: flex-start;
|
|
126
|
+
height: 2rem;
|
|
127
|
+
padding: 0 var(--mrd-space-3);
|
|
128
|
+
background: var(--mrd-color-white);
|
|
129
|
+
border: 1px solid var(--mrd-color-neutral-300);
|
|
130
|
+
border-radius: var(--mrd-border-radius);
|
|
131
|
+
font-family: var(--mrd-font-family);
|
|
132
|
+
font-size: var(--mrd-font-size-sm);
|
|
133
|
+
font-weight: var(--mrd-font-weight-medium);
|
|
134
|
+
color: var(--mrd-color-neutral-700);
|
|
135
|
+
cursor: pointer;
|
|
136
|
+
}
|
|
137
|
+
.mrd-invoice-view__attachment:hover {
|
|
138
|
+
background: var(--mrd-color-neutral-100);
|
|
139
|
+
color: var(--mrd-color-neutral-900);
|
|
140
|
+
}
|
|
141
|
+
.mrd-invoice-view__attachment-icon {
|
|
142
|
+
width: 0.9375rem;
|
|
143
|
+
height: 0.9375rem;
|
|
144
|
+
flex-shrink: 0;
|
|
145
|
+
}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { Host, h } from "@stencil/core";
|
|
2
|
+
import { t } from "../../../utils/i18n";
|
|
3
|
+
import { formatCurrency, formatDate } from "../../../utils/format";
|
|
4
|
+
import { attachmentsFromRecord, attachmentsKey } from "../../../utils/document-attachments";
|
|
5
|
+
/**
|
|
6
|
+
* Archetype-driven single-invoice view. Given a `commons.invoice` binding and a data
|
|
7
|
+
* record, renders a clear, recognisable invoice summary — number, status, dates,
|
|
8
|
+
* customer/supplier, totals and attachments — instead of a generic field form.
|
|
9
|
+
*
|
|
10
|
+
* The line items (`lines` slot, the `commons.invoiceLine` sub-archetype) are NOT
|
|
11
|
+
* rendered here: this component only reserves a `slot="lines"` at the right spot in
|
|
12
|
+
* the layout. The host (`mrd-layout-section`) still owns all the actual RELATED_VIEW
|
|
13
|
+
* table data-loading/event wiring — via its existing `renderRelatedView()` — and
|
|
14
|
+
* projects the resulting `<mrd-table>` into that slot, so line editing keeps using
|
|
15
|
+
* the same generic create/edit-navigation mechanism every other relation already has.
|
|
16
|
+
*
|
|
17
|
+
* Like `mrd-document-view`, this component never resolves file hrefs itself — it only
|
|
18
|
+
* exposes the attachment references via `mrdAttachments` (now possibly more than one)
|
|
19
|
+
* and a plain download button; the host decides how/whether to render them.
|
|
20
|
+
*/
|
|
21
|
+
export class MrdInvoiceView {
|
|
22
|
+
constructor() {
|
|
23
|
+
/** The data record from the /data endpoint. Fields keyed by name; relations under `_links`. */
|
|
24
|
+
this.data = {};
|
|
25
|
+
this.locale = navigator.language;
|
|
26
|
+
/** listItems of the FIELD bound to the `status` slot, resolved by mrd-layout-section
|
|
27
|
+
* from its own items array (archetype metadata does not publish listItems), so the
|
|
28
|
+
* status badge can get a real label/color instead of the raw stored key. */
|
|
29
|
+
this.statusListItems = null;
|
|
30
|
+
/** Tracks the key attachments were last emitted for, so componentDidLoad and the
|
|
31
|
+
* data watcher don't emit duplicate events for the same set of files. */
|
|
32
|
+
this.lastAttachmentKey = null;
|
|
33
|
+
}
|
|
34
|
+
componentDidLoad() {
|
|
35
|
+
this.emitAttachmentsIfNeeded();
|
|
36
|
+
}
|
|
37
|
+
dataChanged() {
|
|
38
|
+
this.emitAttachmentsIfNeeded();
|
|
39
|
+
}
|
|
40
|
+
emitAttachmentsIfNeeded() {
|
|
41
|
+
const attachments = attachmentsFromRecord(this.archetype, this.data, 'attachments');
|
|
42
|
+
const key = attachmentsKey(attachments);
|
|
43
|
+
if (key === this.lastAttachmentKey)
|
|
44
|
+
return;
|
|
45
|
+
this.lastAttachmentKey = key;
|
|
46
|
+
this.mrdAttachments.emit({ attachments });
|
|
47
|
+
}
|
|
48
|
+
/** Value of a value-slot: reads data[field] via the slot→field map. */
|
|
49
|
+
slotValue(slot) {
|
|
50
|
+
var _a, _b;
|
|
51
|
+
const field = (_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b[slot];
|
|
52
|
+
if (!field)
|
|
53
|
+
return undefined;
|
|
54
|
+
return this.data[field];
|
|
55
|
+
}
|
|
56
|
+
/** Relation link for a relation-slot: reads data._links[field]. */
|
|
57
|
+
slotLink(slot) {
|
|
58
|
+
var _a, _b, _c, _d;
|
|
59
|
+
const field = (_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b[slot];
|
|
60
|
+
if (!field)
|
|
61
|
+
return undefined;
|
|
62
|
+
const links = ((_d = (_c = this.data) === null || _c === void 0 ? void 0 : _c._links) !== null && _d !== void 0 ? _d : {});
|
|
63
|
+
return links[field];
|
|
64
|
+
}
|
|
65
|
+
renderPartyLink(slot, label) {
|
|
66
|
+
const link = this.slotLink(slot);
|
|
67
|
+
if (!(link === null || link === void 0 ? void 0 : link.href) || !link.name)
|
|
68
|
+
return null;
|
|
69
|
+
return (h("div", { class: "mrd-invoice-view__party" }, h("span", { class: "mrd-invoice-view__party-label" }, label), h("button", { type: "button", class: "mrd-invoice-view__link", onClick: () => this.mrdNavigate.emit({ href: link.href, label: link.name }) }, link.name)));
|
|
70
|
+
}
|
|
71
|
+
renderContainer() {
|
|
72
|
+
const link = this.slotLink('container');
|
|
73
|
+
if (!(link === null || link === void 0 ? void 0 : link.href) || !link.name)
|
|
74
|
+
return null;
|
|
75
|
+
return (h("button", { type: "button", class: "mrd-invoice-view__container-link", onClick: () => this.mrdNavigate.emit({ href: link.href, label: link.name }) }, link.name));
|
|
76
|
+
}
|
|
77
|
+
renderStatus() {
|
|
78
|
+
var _a, _b;
|
|
79
|
+
const statusRaw = this.slotValue('status');
|
|
80
|
+
if (statusRaw == null || statusRaw === '')
|
|
81
|
+
return null;
|
|
82
|
+
const listItem = ((_a = this.statusListItems) !== null && _a !== void 0 ? _a : []).find(li => li.key === String(statusRaw));
|
|
83
|
+
const label = (_b = listItem === null || listItem === void 0 ? void 0 : listItem.label) !== null && _b !== void 0 ? _b : String(statusRaw);
|
|
84
|
+
if ((listItem === null || listItem === void 0 ? void 0 : listItem.color) && (listItem === null || listItem === void 0 ? void 0 : listItem.backgroundColor)) {
|
|
85
|
+
return (h("span", { class: "mrd-invoice-view__badge", style: { color: listItem.color, backgroundColor: listItem.backgroundColor } }, label));
|
|
86
|
+
}
|
|
87
|
+
return h("span", { class: "mrd-invoice-view__badge mrd-invoice-view__badge--plain" }, label);
|
|
88
|
+
}
|
|
89
|
+
renderAmounts() {
|
|
90
|
+
const net = this.slotValue('netAmount');
|
|
91
|
+
const tax = this.slotValue('taxAmount');
|
|
92
|
+
const total = this.slotValue('amount');
|
|
93
|
+
if ((net === null || net === void 0 ? void 0 : net.amount) == null && (tax === null || tax === void 0 ? void 0 : tax.amount) == null && (total === null || total === void 0 ? void 0 : total.amount) == null)
|
|
94
|
+
return null;
|
|
95
|
+
return (h("div", { class: "mrd-invoice-view__amounts" }, (net === null || net === void 0 ? void 0 : net.amount) != null && (h("div", { class: "mrd-invoice-view__amount-row" }, h("span", null, t('invoice_subtotal', this.locale)), h("span", null, formatCurrency(net.amount, net.currency, this.locale)))), (tax === null || tax === void 0 ? void 0 : tax.amount) != null && (h("div", { class: "mrd-invoice-view__amount-row" }, h("span", null, t('invoice_tax', this.locale)), h("span", null, formatCurrency(tax.amount, tax.currency, this.locale)))), (total === null || total === void 0 ? void 0 : total.amount) != null && (h("div", { class: "mrd-invoice-view__amount-row mrd-invoice-view__amount-row--total" }, h("span", null, t('invoice_total', this.locale)), h("span", null, formatCurrency(total.amount, total.currency, this.locale))))));
|
|
96
|
+
}
|
|
97
|
+
renderAttachments() {
|
|
98
|
+
const attachments = attachmentsFromRecord(this.archetype, this.data, 'attachments');
|
|
99
|
+
if (!attachments.length)
|
|
100
|
+
return null;
|
|
101
|
+
return (h("div", { class: "mrd-invoice-view__attachments" }, attachments.map(a => (h("button", { type: "button", key: a.href, class: "mrd-invoice-view__attachment", onClick: () => this.mrdDownload.emit({ href: a.href, fileName: a.fileName }) }, h("svg", { class: "mrd-invoice-view__attachment-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("path", { d: "M21.44 11.05l-9.19 9.19a5 5 0 01-7.07-7.07l9.19-9.19a3 3 0 014.24 4.24l-9.2 9.19a1 1 0 01-1.41-1.41l8.49-8.48" })), a.fileName)))));
|
|
102
|
+
}
|
|
103
|
+
render() {
|
|
104
|
+
var _a, _b;
|
|
105
|
+
const invoiceNumberRaw = this.slotValue('invoiceNumber');
|
|
106
|
+
const invoiceNumber = invoiceNumberRaw != null && invoiceNumberRaw !== '' ? String(invoiceNumberRaw) : null;
|
|
107
|
+
const invoiceDateRaw = this.slotValue('invoiceDate');
|
|
108
|
+
const dueDateRaw = this.slotValue('dueDate');
|
|
109
|
+
const hasLines = !!((_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b['lines']);
|
|
110
|
+
return (h(Host, { key: 'a97c51e53e39ace913c902ad2ba6813eb85e4561' }, h("div", { key: '6938267848bceed5b28b56c3cdd6d6693e57cdbf', class: "mrd-invoice-view" }, h("div", { key: '7a0b3346232abfc1e35805e4e92c19d35698f881', class: "mrd-invoice-view__header" }, h("div", { key: '5c0471dd8ebd94dd9b374897268c7c03bec66ec7', class: "mrd-invoice-view__title-row" }, invoiceNumber && h("h1", { key: '86b4c0ebd0a5b83ae03b731b7e41394645aae954', class: "mrd-invoice-view__title" }, t('invoice_title', this.locale), " ", invoiceNumber), this.renderStatus()), h("div", { key: 'd209bc34d989146b5f510f2bcdc4c484d723378c', class: "mrd-invoice-view__dates" }, invoiceDateRaw != null && invoiceDateRaw !== '' && (h("span", { key: '8fffcd1ab10e511c9d939c351ea93e4d8a902688' }, t('invoice_date', this.locale), ": ", formatDate(invoiceDateRaw, this.locale))), dueDateRaw != null && dueDateRaw !== '' && (h("span", { key: '8d13c6660798108cc2f54137c8415173326d5bf2' }, t('invoice_due_date', this.locale), ": ", formatDate(dueDateRaw, this.locale)))), this.renderContainer()), h("div", { key: 'cb08c6fd7e6b46a46a69f11aafa960ab5cb35544', class: "mrd-invoice-view__parties" }, this.renderPartyLink('customer', t('invoice_customer', this.locale)), this.renderPartyLink('supplier', t('invoice_supplier', this.locale))), hasLines && (h("div", { key: '8321e74171fe933a4e10fc202b66cd3720ba959e', class: "mrd-invoice-view__lines" }, h("slot", { key: 'eb31d97080173413e74e5b0024984a4b06aa5bdd', name: "lines" }))), this.renderAmounts(), this.renderAttachments())));
|
|
111
|
+
}
|
|
112
|
+
static get is() { return "mrd-invoice-view"; }
|
|
113
|
+
static get encapsulation() { return "scoped"; }
|
|
114
|
+
static get originalStyleUrls() {
|
|
115
|
+
return {
|
|
116
|
+
"$": ["mrd-invoice-view.scss"]
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
static get styleUrls() {
|
|
120
|
+
return {
|
|
121
|
+
"$": ["mrd-invoice-view.css"]
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
static get properties() {
|
|
125
|
+
return {
|
|
126
|
+
"archetype": {
|
|
127
|
+
"type": "unknown",
|
|
128
|
+
"mutable": false,
|
|
129
|
+
"complexType": {
|
|
130
|
+
"original": "ClientArchetype",
|
|
131
|
+
"resolved": "ClientArchetype",
|
|
132
|
+
"references": {
|
|
133
|
+
"ClientArchetype": {
|
|
134
|
+
"location": "import",
|
|
135
|
+
"path": "../../../types/client-layout",
|
|
136
|
+
"id": "src/types/client-layout.ts::ClientArchetype",
|
|
137
|
+
"referenceLocation": "ClientArchetype"
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"required": true,
|
|
142
|
+
"optional": false,
|
|
143
|
+
"docs": {
|
|
144
|
+
"tags": [],
|
|
145
|
+
"text": "Resolved `commons.invoice` binding: slot name \u2192 concrete field/relation name."
|
|
146
|
+
},
|
|
147
|
+
"getter": false,
|
|
148
|
+
"setter": false
|
|
149
|
+
},
|
|
150
|
+
"data": {
|
|
151
|
+
"type": "unknown",
|
|
152
|
+
"mutable": false,
|
|
153
|
+
"complexType": {
|
|
154
|
+
"original": "Record<string, unknown>",
|
|
155
|
+
"resolved": "string | unknown",
|
|
156
|
+
"references": {
|
|
157
|
+
"Record": {
|
|
158
|
+
"location": "global",
|
|
159
|
+
"id": "global::Record"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
"required": false,
|
|
164
|
+
"optional": false,
|
|
165
|
+
"docs": {
|
|
166
|
+
"tags": [],
|
|
167
|
+
"text": "The data record from the /data endpoint. Fields keyed by name; relations under `_links`."
|
|
168
|
+
},
|
|
169
|
+
"getter": false,
|
|
170
|
+
"setter": false,
|
|
171
|
+
"defaultValue": "{}"
|
|
172
|
+
},
|
|
173
|
+
"locale": {
|
|
174
|
+
"type": "string",
|
|
175
|
+
"mutable": false,
|
|
176
|
+
"complexType": {
|
|
177
|
+
"original": "string",
|
|
178
|
+
"resolved": "string",
|
|
179
|
+
"references": {}
|
|
180
|
+
},
|
|
181
|
+
"required": false,
|
|
182
|
+
"optional": false,
|
|
183
|
+
"docs": {
|
|
184
|
+
"tags": [],
|
|
185
|
+
"text": ""
|
|
186
|
+
},
|
|
187
|
+
"getter": false,
|
|
188
|
+
"setter": false,
|
|
189
|
+
"reflect": false,
|
|
190
|
+
"attribute": "locale",
|
|
191
|
+
"defaultValue": "navigator.language"
|
|
192
|
+
},
|
|
193
|
+
"statusListItems": {
|
|
194
|
+
"type": "unknown",
|
|
195
|
+
"mutable": false,
|
|
196
|
+
"complexType": {
|
|
197
|
+
"original": "ClientListValue[] | null",
|
|
198
|
+
"resolved": "ClientListValue[] | null",
|
|
199
|
+
"references": {
|
|
200
|
+
"ClientListValue": {
|
|
201
|
+
"location": "import",
|
|
202
|
+
"path": "../../../types/client-layout",
|
|
203
|
+
"id": "src/types/client-layout.ts::ClientListValue",
|
|
204
|
+
"referenceLocation": "ClientListValue"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"required": false,
|
|
209
|
+
"optional": false,
|
|
210
|
+
"docs": {
|
|
211
|
+
"tags": [],
|
|
212
|
+
"text": "listItems of the FIELD bound to the `status` slot, resolved by mrd-layout-section\nfrom its own items array (archetype metadata does not publish listItems), so the\nstatus badge can get a real label/color instead of the raw stored key."
|
|
213
|
+
},
|
|
214
|
+
"getter": false,
|
|
215
|
+
"setter": false,
|
|
216
|
+
"defaultValue": "null"
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
static get events() {
|
|
221
|
+
return [{
|
|
222
|
+
"method": "mrdNavigate",
|
|
223
|
+
"name": "mrdNavigate",
|
|
224
|
+
"bubbles": true,
|
|
225
|
+
"cancelable": true,
|
|
226
|
+
"composed": true,
|
|
227
|
+
"docs": {
|
|
228
|
+
"tags": [],
|
|
229
|
+
"text": "Navigate to the customer/supplier/container. Host resolves the href and routes."
|
|
230
|
+
},
|
|
231
|
+
"complexType": {
|
|
232
|
+
"original": "{ href?: string; label: string }",
|
|
233
|
+
"resolved": "{ href?: string | undefined; label: string; }",
|
|
234
|
+
"references": {}
|
|
235
|
+
}
|
|
236
|
+
}, {
|
|
237
|
+
"method": "mrdDownload",
|
|
238
|
+
"name": "mrdDownload",
|
|
239
|
+
"bubbles": true,
|
|
240
|
+
"cancelable": true,
|
|
241
|
+
"composed": true,
|
|
242
|
+
"docs": {
|
|
243
|
+
"tags": [],
|
|
244
|
+
"text": "Download an attachment. Host resolves the href to a signed URL."
|
|
245
|
+
},
|
|
246
|
+
"complexType": {
|
|
247
|
+
"original": "{ href: string; fileName: string }",
|
|
248
|
+
"resolved": "{ href: string; fileName: string; }",
|
|
249
|
+
"references": {}
|
|
250
|
+
}
|
|
251
|
+
}, {
|
|
252
|
+
"method": "mrdAttachments",
|
|
253
|
+
"name": "mrdAttachments",
|
|
254
|
+
"bubbles": true,
|
|
255
|
+
"cancelable": true,
|
|
256
|
+
"composed": true,
|
|
257
|
+
"docs": {
|
|
258
|
+
"tags": [],
|
|
259
|
+
"text": "The file(s) belonging to this invoice, fired once on load and again whenever the\nattachments slot's value changes. The host resolves the href(s) itself."
|
|
260
|
+
},
|
|
261
|
+
"complexType": {
|
|
262
|
+
"original": "{ attachments: DocumentAttachment[] }",
|
|
263
|
+
"resolved": "{ attachments: DocumentAttachment[]; }",
|
|
264
|
+
"references": {
|
|
265
|
+
"DocumentAttachment": {
|
|
266
|
+
"location": "import",
|
|
267
|
+
"path": "../../../types/client-layout",
|
|
268
|
+
"id": "src/types/client-layout.ts::DocumentAttachment",
|
|
269
|
+
"referenceLocation": "DocumentAttachment"
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}];
|
|
274
|
+
}
|
|
275
|
+
static get watchers() {
|
|
276
|
+
return [{
|
|
277
|
+
"propName": "data",
|
|
278
|
+
"methodName": "dataChanged"
|
|
279
|
+
}];
|
|
280
|
+
}
|
|
281
|
+
}
|
|
@@ -27,7 +27,7 @@ function renderSingleFieldValue(ctx, item, value) {
|
|
|
27
27
|
const v = value;
|
|
28
28
|
const fileName = (_e = v === null || v === void 0 ? void 0 : v.fileName) !== null && _e !== void 0 ? _e : String(value);
|
|
29
29
|
const href = (_f = v === null || v === void 0 ? void 0 : v.href) !== null && _f !== void 0 ? _f : '';
|
|
30
|
-
return downloadLink(ctx, href, fileName, t('download', ctx.locale));
|
|
30
|
+
return downloadLink(ctx, href, fileName, fileName || t('download', ctx.locale));
|
|
31
31
|
}
|
|
32
32
|
case ClientLayoutItemFieldDataType.IMAGE: {
|
|
33
33
|
const v = value;
|
|
@@ -66,6 +66,10 @@ export function renderFieldValue(ctx, item, rawValue) {
|
|
|
66
66
|
if (rawValue == null || rawValue === '')
|
|
67
67
|
return null;
|
|
68
68
|
if (item.multiple && Array.isArray(rawValue)) {
|
|
69
|
+
const isFileType = item.dataType === ClientLayoutItemFieldDataType.FILE || item.dataType === ClientLayoutItemFieldDataType.IMAGE;
|
|
70
|
+
if (isFileType) {
|
|
71
|
+
return (h("div", { class: "mrd-layout-section__file-list" }, rawValue.map((v, i) => (h("div", { class: "mrd-layout-section__file-list-item", key: String(i) }, renderSingleFieldValue(ctx, item, v))))));
|
|
72
|
+
}
|
|
69
73
|
const rendered = rawValue.map(v => renderSingleFieldValue(ctx, item, v));
|
|
70
74
|
if (rendered.every(r => typeof r === 'string' || r == null)) {
|
|
71
75
|
return rendered.filter(Boolean).join(', ') || null;
|
|
@@ -170,6 +170,16 @@
|
|
|
170
170
|
width: 1rem;
|
|
171
171
|
height: 1rem;
|
|
172
172
|
}
|
|
173
|
+
.mrd-layout-section__file-list {
|
|
174
|
+
display: flex;
|
|
175
|
+
flex-direction: column;
|
|
176
|
+
align-items: flex-start;
|
|
177
|
+
gap: var(--mrd-space-1);
|
|
178
|
+
}
|
|
179
|
+
.mrd-layout-section__file-list-item {
|
|
180
|
+
min-width: 0;
|
|
181
|
+
max-width: 100%;
|
|
182
|
+
}
|
|
173
183
|
.mrd-layout-section__boolean--true {
|
|
174
184
|
color: var(--mrd-color-success);
|
|
175
185
|
font-weight: var(--mrd-font-weight-semibold);
|