@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Host, h } from "@stencil/core";
|
|
2
|
-
import { ClientLayoutItemType, ClientLayoutItemFieldDataType, ClientLayoutNavigateBehaviour, resolveArchetype, ARCHETYPE_DOCUMENT, } from "../../../types/client-layout";
|
|
2
|
+
import { ClientLayoutItemType, ClientLayoutItemFieldDataType, ClientLayoutNavigateBehaviour, resolveArchetype, ARCHETYPE_DOCUMENT, ARCHETYPE_INVOICE, ARCHETYPE_EMAIL, ARCHETYPE_INVOICE_LINE, } from "../../../types/client-layout";
|
|
3
3
|
import { viewKeyFor, flattenItems, buildContainerHref } from "./layout-helpers";
|
|
4
4
|
import { renderField } from "./field-value";
|
|
5
5
|
export class MrdLayoutSection {
|
|
@@ -313,23 +313,53 @@ export class MrdLayoutSection {
|
|
|
313
313
|
return null;
|
|
314
314
|
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: "" }))));
|
|
315
315
|
}
|
|
316
|
+
/** Related VIEW/RELATED_VIEW/SEARCH items to keep rendering below an archetype's
|
|
317
|
+
* single-object view, excluding any item already consumed by that view itself
|
|
318
|
+
* (e.g. invoice's `lines`, see renderInvoiceObject). */
|
|
319
|
+
relatedItems(exclude) {
|
|
320
|
+
return this.items.filter(it => it !== exclude &&
|
|
321
|
+
(it.type === ClientLayoutItemType.VIEW || it.type === ClientLayoutItemType.RELATED_VIEW || it.type === ClientLayoutItemType.SEARCH));
|
|
322
|
+
}
|
|
316
323
|
/** Single-document view: the record's own type carries commons.document. Renders
|
|
317
324
|
* a recognisable document instead of generic fields, keeping any related views/
|
|
318
325
|
* searches below it. */
|
|
319
326
|
renderDocumentObject(archetype) {
|
|
320
|
-
const related = this.items.filter(it => it.type === ClientLayoutItemType.VIEW ||
|
|
321
|
-
it.type === ClientLayoutItemType.RELATED_VIEW ||
|
|
322
|
-
it.type === ClientLayoutItemType.SEARCH);
|
|
323
327
|
return [
|
|
324
328
|
h("mrd-document-view", { archetype: archetype, data: this.data, locale: this.locale, onMrdNavigate: (e) => { e.stopPropagation(); this.mrdNavigate.emit(e.detail); }, onMrdDownload: (e) => { e.stopPropagation(); this.mrdDownload.emit(e.detail); }, onMrdAttachments: (e) => { e.stopPropagation(); this.mrdAttachments.emit(e.detail); } }),
|
|
325
|
-
...
|
|
329
|
+
...this.relatedItems().map(it => this.renderItem(it)),
|
|
330
|
+
];
|
|
331
|
+
}
|
|
332
|
+
/** Single-invoice view: the record's own type carries commons.invoice. The `lines`
|
|
333
|
+
* RELATED_VIEW (matched generically by the commons.invoiceLine archetype on the
|
|
334
|
+
* item, not by name) is rendered *inside* mrd-invoice-view via its `slot="lines"` —
|
|
335
|
+
* reusing the existing renderRelatedView()/renderTable() wiring unchanged, so all
|
|
336
|
+
* page/sort/aggregation state stays owned here, only the DOM placement moves. */
|
|
337
|
+
renderInvoiceObject(archetype) {
|
|
338
|
+
var _a, _b, _c;
|
|
339
|
+
const linesItem = (_a = this.items.find(it => {
|
|
340
|
+
var _a, _b;
|
|
341
|
+
return (it.type === ClientLayoutItemType.VIEW || it.type === ClientLayoutItemType.RELATED_VIEW) &&
|
|
342
|
+
!!resolveArchetype((_a = it.archetypes) !== null && _a !== void 0 ? _a : (_b = it.view) === null || _b === void 0 ? void 0 : _b.archetypes, ARCHETYPE_INVOICE_LINE);
|
|
343
|
+
})) !== null && _a !== void 0 ? _a : null;
|
|
344
|
+
const statusListItems = (_c = (_b = this.items.find(it => { var _a; return it.name === ((_a = archetype.slots) === null || _a === void 0 ? void 0 : _a.status); })) === null || _b === void 0 ? void 0 : _b.listItems) !== null && _c !== void 0 ? _c : null;
|
|
345
|
+
return [
|
|
346
|
+
h("mrd-invoice-view", { archetype: archetype, data: this.data, locale: this.locale, statusListItems: statusListItems, onMrdNavigate: (e) => { e.stopPropagation(); this.mrdNavigate.emit(e.detail); }, onMrdDownload: (e) => { e.stopPropagation(); this.mrdDownload.emit(e.detail); }, onMrdAttachments: (e) => { e.stopPropagation(); this.mrdAttachments.emit(e.detail); } }, linesItem && h("div", { slot: "lines" }, this.renderRelatedView(linesItem))),
|
|
347
|
+
...this.relatedItems(linesItem).map(it => this.renderItem(it)),
|
|
348
|
+
];
|
|
349
|
+
}
|
|
350
|
+
/** Single-email view: the record's own type carries commons.email. Fully read-only —
|
|
351
|
+
* emails have no editable child collection, so this mirrors renderDocumentObject. */
|
|
352
|
+
renderEmailObject(archetype) {
|
|
353
|
+
return [
|
|
354
|
+
h("mrd-email-view", { archetype: archetype, data: this.data, locale: this.locale, onMrdNavigate: (e) => { e.stopPropagation(); this.mrdNavigate.emit(e.detail); }, onMrdDownload: (e) => { e.stopPropagation(); this.mrdDownload.emit(e.detail); }, onMrdAttachments: (e) => { e.stopPropagation(); this.mrdAttachments.emit(e.detail); } }),
|
|
355
|
+
...this.relatedItems().map(it => this.renderItem(it)),
|
|
326
356
|
];
|
|
327
357
|
}
|
|
328
358
|
render() {
|
|
329
359
|
const docArchetype = resolveArchetype(this.archetypes, ARCHETYPE_DOCUMENT);
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
360
|
+
const invoiceArchetype = !docArchetype ? resolveArchetype(this.archetypes, ARCHETYPE_INVOICE) : undefined;
|
|
361
|
+
const emailArchetype = !docArchetype && !invoiceArchetype ? resolveArchetype(this.archetypes, ARCHETYPE_EMAIL) : undefined;
|
|
362
|
+
return (h(Host, { key: '0078764a136e7ca9561632718c1b527ec3bc01c5' }, h("div", { key: '0c1428ce20bd7d2bbce467a36b6c25ffa0e6367e', class: "mrd-layout-section" }, docArchetype && this.renderDocumentObject(docArchetype), invoiceArchetype && this.renderInvoiceObject(invoiceArchetype), emailArchetype && this.renderEmailObject(emailArchetype), !docArchetype && !invoiceArchetype && !emailArchetype && this.items.map(item => this.renderItem(item))), this.renderImageModal()));
|
|
333
363
|
}
|
|
334
364
|
static get is() { return "mrd-layout-section"; }
|
|
335
365
|
static get encapsulation() { return "scoped"; }
|
|
@@ -121,14 +121,14 @@ export class MrdMergeView {
|
|
|
121
121
|
var _a, _b;
|
|
122
122
|
let stepContent;
|
|
123
123
|
if (this.step === 'search') {
|
|
124
|
-
stepContent = (h(MergeSearchStep, { key: '
|
|
124
|
+
stepContent = (h(MergeSearchStep, { key: '3adb36fb46aa7260641a46a2cf27cc0ef320876f', locale: this.locale, searchQuery: this.searchQuery, searchResults: this.searchResults, isLoading: this.isLoading, onSearchInput: this.handleSearchInput, onSelect: this.handleSelect }));
|
|
125
125
|
}
|
|
126
126
|
else {
|
|
127
127
|
const diff = diffFields(this.fields, this.currentRecord, this.candidate);
|
|
128
128
|
const bLabel = candidateLabel(this.candidate);
|
|
129
129
|
stepContent = this.step === 'compare' ? (h(MergeCompareStep, { locale: this.locale, currentLabel: this.currentLabel, candidateLabel: bLabel, conflicts: diff.conflicts, autoFilled: diff.autoFilled, recordA: this.currentRecord, recordB: (_a = this.candidate) !== null && _a !== void 0 ? _a : {}, resolutions: this.resolutions, openHistoryKey: this.openHistoryKey, onResolve: this.handleResolve, onToggleHistory: this.handleToggleHistory, onChangeCandidate: this.handleChangeCandidate, onContinue: this.handleContinue })) : (h(MergeConfirmStep, { locale: this.locale, candidateLabel: bLabel, conflicts: diff.conflicts, autoFilled: diff.autoFilled, resolutions: this.resolutions, recordB: (_b = this.candidate) !== null && _b !== void 0 ? _b : {}, openHistoryKey: this.openHistoryKey, onToggleHistory: this.handleToggleHistory, onBack: this.handleBack, onConfirm: this.handleConfirm }));
|
|
130
130
|
}
|
|
131
|
-
return (h(Host, { key: '
|
|
131
|
+
return (h(Host, { key: 'e33a6d66a220b28cc9533da78dc274e2d7ec5c4a' }, h("div", { key: 'b5fb1390d86192f9f6f15e3ccb89e2d21d9c7c8b', class: "mrd-merge-view" }, stepContent)));
|
|
132
132
|
}
|
|
133
133
|
static get is() { return "mrd-merge-view"; }
|
|
134
134
|
static get encapsulation() { return "scoped"; }
|
|
@@ -19,7 +19,21 @@ async function apiRequest(method, path, token, body) {
|
|
|
19
19
|
const text = await resp.text();
|
|
20
20
|
let json;
|
|
21
21
|
try { json = JSON.parse(text); } catch (_) { json = text; }
|
|
22
|
-
return { status: resp.status, ok: resp.ok, body: json };
|
|
22
|
+
return { status: resp.status, ok: resp.ok, body: json, location: resp.headers.get('Location') };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Write (POST/PATCH) that returns no body — only a Location header
|
|
27
|
+
* (create/patch/merge on /data/**, per TASK-0203). Follows the Location
|
|
28
|
+
* header with a GET to hand callers the current record, mirroring
|
|
29
|
+
* content-app's ApiClientService create/update methods.
|
|
30
|
+
*/
|
|
31
|
+
async function apiWriteAndFetch(method, path, token, payload) {
|
|
32
|
+
const write = await apiRequest(method, path, token, payload);
|
|
33
|
+
if (!write.ok) return write;
|
|
34
|
+
const href = write.location || path;
|
|
35
|
+
const { body } = await apiRequest('GET', href, token);
|
|
36
|
+
return { ...write, body };
|
|
23
37
|
}
|
|
24
38
|
|
|
25
39
|
/** Resolve a file/image reference href to a signed, directly-usable URL.
|
|
@@ -95,7 +109,7 @@ async function apiFetchPage(token, baseHref, pageNumber, sort = '') {
|
|
|
95
109
|
}
|
|
96
110
|
|
|
97
111
|
async function apiSubmitForm(token, tenantCode, pluralName, values) {
|
|
98
|
-
const { status, ok, body } = await
|
|
112
|
+
const { status, ok, body } = await apiWriteAndFetch('POST', `/data/${tenantCode}/${pluralName}`, token, values);
|
|
99
113
|
return { status, ok, body };
|
|
100
114
|
}
|
|
101
115
|
|
|
@@ -150,11 +164,12 @@ async function apiSearchMergeCandidates(token, tenantCode, mostSignificantClass,
|
|
|
150
164
|
|
|
151
165
|
/**
|
|
152
166
|
* Merge two DataObjects of the same basic type. Mirrors DataController.merge():
|
|
153
|
-
* POST {winnerHref}/merge with { loser: loserHref, patch }. Returns
|
|
154
|
-
*
|
|
167
|
+
* POST {winnerHref}/merge with { loser: loserHref, patch }. Returns no body
|
|
168
|
+
* (204 + Location, per TASK-0203) — follows Location with a GET for the
|
|
169
|
+
* patched winner record.
|
|
155
170
|
*/
|
|
156
171
|
async function apiMerge(token, winnerHref, loserHref, patch) {
|
|
157
|
-
const { ok, status, body } = await
|
|
172
|
+
const { ok, status, body } = await apiWriteAndFetch('POST', `${winnerHref}/merge`, token, { loser: loserHref, patch });
|
|
158
173
|
if (!ok) throw new Error(`${status}: ${typeof body === 'string' ? body : JSON.stringify(body)}`);
|
|
159
174
|
return body;
|
|
160
175
|
}
|
|
@@ -266,6 +266,41 @@ function initFilePreviewTab() {
|
|
|
266
266
|
section.addEventListener('mrdDownload', (e) => logEvent('mrdDownload', e.detail));
|
|
267
267
|
section.addEventListener('mrdNavigate', (e) => logEvent('mrdNavigate', e.detail));
|
|
268
268
|
});
|
|
269
|
+
|
|
270
|
+
// Invoice View demo (commons.invoice archetype, TASK-0199) — the `lines`
|
|
271
|
+
// RELATED_VIEW is rendered inside mrd-invoice-view via slot="lines", but the
|
|
272
|
+
// page/sort data-loading stays owned by mrd-layout-section, exactly like any
|
|
273
|
+
// other RELATED_VIEW: answer mrdLoadViewPage the same way the Detail View tab
|
|
274
|
+
// does for appointments/share classes.
|
|
275
|
+
const invoiceSection = document.getElementById('invoice-view');
|
|
276
|
+
const invoicePreviewEl = document.getElementById('invoice-view-preview');
|
|
277
|
+
invoiceSection.items = window.EXAMPLE_INVOICE_ITEMS;
|
|
278
|
+
invoiceSection.data = window.EXAMPLE_INVOICE_DATA;
|
|
279
|
+
invoiceSection.archetypes = [window.EXAMPLE_INVOICE_ARCHETYPE];
|
|
280
|
+
invoiceSection.addEventListener('mrdLoadViewPage', async (e) => {
|
|
281
|
+
const { name, page } = e.detail;
|
|
282
|
+
logEvent('mrdLoadViewPage', e.detail);
|
|
283
|
+
await invoiceSection.setViewPage(name, page, window.EXAMPLE_INVOICE_LINES, window.EXAMPLE_INVOICE_LINES.length);
|
|
284
|
+
});
|
|
285
|
+
invoiceSection.addEventListener('mrdAttachments', (e) => {
|
|
286
|
+
logEvent('mrdAttachments', e.detail);
|
|
287
|
+
renderAttachmentPreview(invoicePreviewEl, e.detail.attachments);
|
|
288
|
+
});
|
|
289
|
+
invoiceSection.addEventListener('mrdDownload', (e) => logEvent('mrdDownload', e.detail));
|
|
290
|
+
invoiceSection.addEventListener('mrdNavigate', (e) => logEvent('mrdNavigate', e.detail));
|
|
291
|
+
|
|
292
|
+
// Email View demo (commons.email archetype, TASK-0199) — fully read-only, no
|
|
293
|
+
// RELATED_VIEW/table involved.
|
|
294
|
+
const emailSection = document.getElementById('email-view');
|
|
295
|
+
const emailPreviewEl = document.getElementById('email-view-preview');
|
|
296
|
+
emailSection.data = window.EXAMPLE_EMAIL_DATA;
|
|
297
|
+
emailSection.archetypes = [window.EXAMPLE_EMAIL_ARCHETYPE];
|
|
298
|
+
emailSection.addEventListener('mrdAttachments', (e) => {
|
|
299
|
+
logEvent('mrdAttachments', e.detail);
|
|
300
|
+
renderAttachmentPreview(emailPreviewEl, e.detail.attachments);
|
|
301
|
+
});
|
|
302
|
+
emailSection.addEventListener('mrdDownload', (e) => logEvent('mrdDownload', e.detail));
|
|
303
|
+
emailSection.addEventListener('mrdNavigate', (e) => logEvent('mrdNavigate', e.detail));
|
|
269
304
|
}
|
|
270
305
|
|
|
271
306
|
/* =====================================================================
|
|
@@ -620,7 +655,7 @@ async function renderSection(index) {
|
|
|
620
655
|
try {
|
|
621
656
|
const result = await apiRequest('POST', `${_baseHref}${path}`, authGetToken(), values);
|
|
622
657
|
if (result.ok) {
|
|
623
|
-
const href = result.
|
|
658
|
+
const href = result.location;
|
|
624
659
|
if (href) await section.setViewCreatedObject(name, href);
|
|
625
660
|
} else {
|
|
626
661
|
console.error('[mrdCreateObject] mislukt', result.status, result.body);
|
|
@@ -873,17 +908,20 @@ async function renderForm(layout, record = null, selfHref = null, containerEl =
|
|
|
873
908
|
if (_meUser) form.me = _meUser;
|
|
874
909
|
form.values = record ? initialValues : {};
|
|
875
910
|
|
|
876
|
-
// Upload
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
}
|
|
886
|
-
})
|
|
911
|
+
// Upload each selected file immediately (fires once per file for `multiple` fields);
|
|
912
|
+
// pass `file` back into setFieldValue so mrd-form can resolve the right array entry.
|
|
913
|
+
// The resolved value is { href, fileName } — same shape mrd-table/mrd-layout-section
|
|
914
|
+
// already expect when reading FILE/IMAGE data back — so the filename displays correctly
|
|
915
|
+
// instead of falling back to the upload URI's UUID.
|
|
916
|
+
form.addEventListener('mrdUpload', async (e) => {
|
|
917
|
+
const { name, file } = e.detail;
|
|
918
|
+
try {
|
|
919
|
+
const uri = await apiUploadFile(authGetToken(), _selectedTenant, file);
|
|
920
|
+
await form.setFieldValue(name, { href: uri, fileName: file.name }, file);
|
|
921
|
+
} catch (err) {
|
|
922
|
+
console.error(`[upload] mislukt voor veld "${name}":`, err);
|
|
923
|
+
}
|
|
924
|
+
});
|
|
887
925
|
|
|
888
926
|
form.addEventListener('mrdSubmit', async (e) => {
|
|
889
927
|
document.getElementById('panel-response').innerHTML =
|
|
@@ -922,7 +960,7 @@ async function renderForm(layout, record = null, selfHref = null, containerEl =
|
|
|
922
960
|
renderResponse(200, 'Geen wijzigingen.');
|
|
923
961
|
return;
|
|
924
962
|
}
|
|
925
|
-
const result = await
|
|
963
|
+
const result = await apiWriteAndFetch('PATCH', selfHref, authGetToken(), patch);
|
|
926
964
|
renderResponse(result.status, result.body);
|
|
927
965
|
} else {
|
|
928
966
|
// POST mode: new record
|
|
@@ -69,7 +69,7 @@ window.EXAMPLE_LAYOUT = {
|
|
|
69
69
|
label: "Assets",
|
|
70
70
|
items: [
|
|
71
71
|
{ type: "FIELD", name: "projectLogo", label: "Project Logo", dataType: "IMAGE", required: false, accept: "image/*", maxSize: 5242880 },
|
|
72
|
-
{ type: "FIELD", name: "attachments", label: "Attachments", dataType: "FILE", required: false, accept: ".pdf,.doc,.docx,.zip", maxSize: 10485760 }
|
|
72
|
+
{ type: "FIELD", name: "attachments", label: "Attachments", dataType: "FILE", required: false, accept: ".pdf,.doc,.docx,.zip", maxSize: 10485760, multiple: true }
|
|
73
73
|
]
|
|
74
74
|
},
|
|
75
75
|
{ type: "RELATION", name: "projectManager", label: "Project Manager", relatedClass: "Employee", displayType: "SEARCH", required: true, multiple: false },
|
|
@@ -91,7 +91,15 @@ window.EXAMPLE_VALUES = {
|
|
|
91
91
|
budget: { amount: 150000, currency: "EUR" },
|
|
92
92
|
isPublic: true,
|
|
93
93
|
startDate: "2026-01-15",
|
|
94
|
-
contactEmail: "team@mosterd.nl"
|
|
94
|
+
contactEmail: "team@mosterd.nl",
|
|
95
|
+
// FILE/IMAGE values from the API are { href, fileName } — same shape as everywhere
|
|
96
|
+
// else in this library (mrd-table, mrd-document-view) — so the field shows the real
|
|
97
|
+
// filename instead of the href's UUID.
|
|
98
|
+
projectLogo: { href: "/uploads/proj-9f2c/logo.png", fileName: "mosterd-logo.png" },
|
|
99
|
+
attachments: [
|
|
100
|
+
{ href: "/uploads/proj-9f2c/9f2c-contract.pdf", fileName: "contract-2026.pdf" },
|
|
101
|
+
{ href: "/uploads/proj-9f2c/1a3b-invoice.pdf", fileName: "invoice-042.pdf" },
|
|
102
|
+
],
|
|
95
103
|
};
|
|
96
104
|
|
|
97
105
|
// ─── Companies detail view demo ────────────────────────────────────────────────
|
|
@@ -441,3 +449,119 @@ window.EXAMPLE_DOCUMENT_DATA = {
|
|
|
441
449
|
dossier: { href: '/data/demo/dossiers/42', name: 'Acme Corp — Dossier 2026' },
|
|
442
450
|
},
|
|
443
451
|
};
|
|
452
|
+
|
|
453
|
+
// ─── Invoice View demo (commons.invoice archetype, TASK-0199) ────────────────
|
|
454
|
+
// Exercises mrd-invoice-view via mrd-layout-section's archetype path. `lines`
|
|
455
|
+
// is a real RELATED_VIEW item bound to the commons.invoiceLine archetype — it
|
|
456
|
+
// is rendered *inside* mrd-invoice-view via slot="lines" (mrd-layout-section
|
|
457
|
+
// still owns the table's own page/sort wiring, see renderInvoiceObject()).
|
|
458
|
+
|
|
459
|
+
window.EXAMPLE_INVOICE_ARCHETYPE = {
|
|
460
|
+
archetype: 'commons.invoice',
|
|
461
|
+
slots: {
|
|
462
|
+
invoiceNumber: 'invoiceNumber', invoiceDate: 'invoiceDate', dueDate: 'dueDate',
|
|
463
|
+
netAmount: 'netAmount', taxAmount: 'taxAmount', amount: 'amount', status: 'status',
|
|
464
|
+
customer: 'customer', supplier: 'supplier', lines: 'lines', attachments: 'attachments', container: 'dossier',
|
|
465
|
+
},
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
window.EXAMPLE_INVOICE_ITEMS = [
|
|
469
|
+
{
|
|
470
|
+
type: 'FIELD', name: 'status', label: 'Status', dataType: 'LIST', required: false,
|
|
471
|
+
listItems: [
|
|
472
|
+
{ key: 'draft', label: 'Concept', color: '#6b7280', backgroundColor: '#f3f4f6' },
|
|
473
|
+
{ key: 'sent', label: 'Verzonden', color: '#1d4ed8', backgroundColor: '#dbeafe' },
|
|
474
|
+
{ key: 'paid', label: 'Betaald', color: '#15803d', backgroundColor: '#dcfce7' },
|
|
475
|
+
],
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
type: 'RELATED_VIEW', label: 'Factuurregels', name: 'lines',
|
|
479
|
+
relatedClass: 'demo.invoiceLine', fromClass: 'demo.invoice', showTitle: true,
|
|
480
|
+
archetypes: [{ archetype: 'commons.invoiceLine', slots: { description: 'description', quantity: 'quantity', unitPrice: 'unitPrice', amount: 'amount' } }],
|
|
481
|
+
view: {
|
|
482
|
+
name: null,
|
|
483
|
+
defaultView: true,
|
|
484
|
+
values: [
|
|
485
|
+
{ type: 'FIELD', label: 'Omschrijving', name: 'description', dataType: 'TEXT', required: true },
|
|
486
|
+
{ type: 'FIELD', label: 'Aantal', name: 'quantity', dataType: 'DECIMAL', required: true },
|
|
487
|
+
{ type: 'FIELD', label: 'Prijs', name: 'unitPrice', dataType: 'CURRENCY', required: true },
|
|
488
|
+
{ type: 'FIELD', label: 'Bedrag', name: 'amount', dataType: 'CURRENCY', required: true, aggregate: 'sum' },
|
|
489
|
+
],
|
|
490
|
+
type: 'demo.invoiceLine',
|
|
491
|
+
singularLabel: 'Factuurregel',
|
|
492
|
+
pluralLabel: 'Factuurregels',
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
];
|
|
496
|
+
|
|
497
|
+
window.EXAMPLE_INVOICE_DATA = {
|
|
498
|
+
invoiceNumber: 'INV-2026-0142',
|
|
499
|
+
invoiceDate: '2026-06-01',
|
|
500
|
+
dueDate: '2026-06-30',
|
|
501
|
+
status: 'sent',
|
|
502
|
+
netAmount: { amount: 1000, currency: 'EUR' },
|
|
503
|
+
taxAmount: { amount: 210, currency: 'EUR' },
|
|
504
|
+
amount: { amount: 1210, currency: 'EUR' },
|
|
505
|
+
attachments: [
|
|
506
|
+
{ href: '/data/demo/invoices/142/attachments/0', fileName: 'invoice-142.pdf', mimeType: 'application/pdf' },
|
|
507
|
+
],
|
|
508
|
+
_links: {
|
|
509
|
+
self: { href: '/data/demo/invoices/142' },
|
|
510
|
+
customer: { href: '/data/demo/entities/acme', name: 'Acme Corp.' },
|
|
511
|
+
supplier: { href: '/data/demo/entities/mosterd', name: 'Mosterd B.V.' },
|
|
512
|
+
dossier: { href: '/data/demo/dossiers/42', name: 'Acme Corp — Dossier 2026' },
|
|
513
|
+
},
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
window.EXAMPLE_INVOICE_LINES = [
|
|
517
|
+
{
|
|
518
|
+
description: 'Consultancy — juni 2026',
|
|
519
|
+
quantity: 10,
|
|
520
|
+
unitPrice: { amount: 80, currency: 'EUR' },
|
|
521
|
+
amount: { amount: 800, currency: 'EUR' },
|
|
522
|
+
_links: { self: { href: '/data/demo/invoiceLines/1' } },
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
description: 'Projectmanagement',
|
|
526
|
+
quantity: 4,
|
|
527
|
+
unitPrice: { amount: 50, currency: 'EUR' },
|
|
528
|
+
amount: { amount: 200, currency: 'EUR' },
|
|
529
|
+
_links: { self: { href: '/data/demo/invoiceLines/2' } },
|
|
530
|
+
},
|
|
531
|
+
];
|
|
532
|
+
|
|
533
|
+
// ─── Email View demo (commons.email archetype, TASK-0199) ────────────────────
|
|
534
|
+
// Exercises mrd-email-view via mrd-layout-section's archetype path. Fully
|
|
535
|
+
// read-only — no RELATED_VIEW/table involved.
|
|
536
|
+
|
|
537
|
+
window.EXAMPLE_EMAIL_ARCHETYPE = {
|
|
538
|
+
archetype: 'commons.email',
|
|
539
|
+
slots: {
|
|
540
|
+
subject: 'subject', date: 'date', from: 'from', to: 'to', cc: 'cc',
|
|
541
|
+
bodyHtml: 'bodyHtml', bodyText: 'bodyText', headers: 'headers',
|
|
542
|
+
attachments: 'attachments', container: 'dossier',
|
|
543
|
+
},
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
window.EXAMPLE_EMAIL_DATA = {
|
|
547
|
+
subject: 'RE: Contract 2026 — laatste versie bijgevoegd',
|
|
548
|
+
date: '2026-06-02T14:32:00',
|
|
549
|
+
bodyHtml: '<p>Beste Jan,</p><p>Bijgaand de laatste versie van het contract, inclusief de besproken wijzigingen in artikel 4.</p><p>Met vriendelijke groet,<br>Anne</p>',
|
|
550
|
+
headers: 'Message-ID: <abc123@mail.example.com>\nReceived: from mail.example.com by mx.mosterd.com',
|
|
551
|
+
attachments: [
|
|
552
|
+
{ href: '/data/demo/emails/9/attachments/0', fileName: 'contract-2026-v3.pdf', mimeType: 'application/pdf' },
|
|
553
|
+
{ href: '/data/demo/emails/9/attachments/1', fileName: 'wijzigingen.docx' },
|
|
554
|
+
],
|
|
555
|
+
_links: {
|
|
556
|
+
from: { href: '/data/demo/entities/anne', name: 'Anne de Vries <anne@mosterd.com>' },
|
|
557
|
+
to: {
|
|
558
|
+
href: '/data/demo/entities/jan', name: 'Jan Bakker <jan@acme.com>',
|
|
559
|
+
values: [{ href: '/data/demo/entities/jan', name: 'Jan Bakker <jan@acme.com>' }],
|
|
560
|
+
},
|
|
561
|
+
cc: {
|
|
562
|
+
href: '/data/demo/entities/pietcc', name: 'Piet Claassen <piet@acme.com>',
|
|
563
|
+
values: [{ href: '/data/demo/entities/pietcc', name: 'Piet Claassen <piet@acme.com>' }],
|
|
564
|
+
},
|
|
565
|
+
dossier: { href: '/data/demo/dossiers/42', name: 'Acme Corp — Dossier 2026' },
|
|
566
|
+
},
|
|
567
|
+
};
|
|
@@ -72,6 +72,12 @@ export var ClientLayoutNavigateBehaviour;
|
|
|
72
72
|
})(ClientLayoutNavigateBehaviour || (ClientLayoutNavigateBehaviour = {}));
|
|
73
73
|
/** Well-known archetype ids the client renders specially. */
|
|
74
74
|
export const ARCHETYPE_DOCUMENT = 'commons.document';
|
|
75
|
+
export const ARCHETYPE_INVOICE = 'commons.invoice';
|
|
76
|
+
export const ARCHETYPE_EMAIL = 'commons.email';
|
|
77
|
+
/** Bound by a `commons.invoice`'s `lines` relation target class. Used to find the
|
|
78
|
+
* RELATED_VIEW item for the line items generically, by archetype id rather than
|
|
79
|
+
* by name/class string. */
|
|
80
|
+
export const ARCHETYPE_INVOICE_LINE = 'commons.invoiceLine';
|
|
75
81
|
/**
|
|
76
82
|
* Find a binding for `archetypeId` in a published `archetypes` list.
|
|
77
83
|
* Returns `undefined` when the archetype is absent — callers fall back to the
|
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Extract
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Extract an archetype's file slot from a data record as a `DocumentAttachment[]` —
|
|
3
|
+
* empty when the slot is unmapped or has no value. `slot` defaults to `'file'` (the
|
|
4
|
+
* commons.document single-file slot); pass `'attachments'` for the multi-file slots
|
|
5
|
+
* on commons.email / commons.invoice. A single-object slot value yields a one-entry
|
|
6
|
+
* array, an array-valued slot yields one entry per item.
|
|
7
|
+
* Shared by mrd-document-view / mrd-invoice-view / mrd-email-view (on load/data-change)
|
|
8
|
+
* and mrd-document-container (row-click prefetch on mrdNavigate), so all report the
|
|
9
|
+
* exact same shape.
|
|
6
10
|
*/
|
|
7
|
-
export function attachmentsFromRecord(archetype, record) {
|
|
8
|
-
var _a
|
|
9
|
-
const field = (_a = archetype === null || archetype === void 0 ? void 0 : archetype.slots) === null || _a === void 0 ? void 0 : _a[
|
|
11
|
+
export function attachmentsFromRecord(archetype, record, slot = 'file') {
|
|
12
|
+
var _a;
|
|
13
|
+
const field = (_a = archetype === null || archetype === void 0 ? void 0 : archetype.slots) === null || _a === void 0 ? void 0 : _a[slot];
|
|
10
14
|
if (!field)
|
|
11
15
|
return [];
|
|
12
|
-
const
|
|
13
|
-
if (!
|
|
16
|
+
const raw = record === null || record === void 0 ? void 0 : record[field];
|
|
17
|
+
if (!raw)
|
|
14
18
|
return [];
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
const items = Array.isArray(raw) ? raw : [raw];
|
|
20
|
+
return items.filter(Boolean).map(item => {
|
|
21
|
+
var _a, _b, _c;
|
|
22
|
+
return ({
|
|
23
|
+
href: item.href,
|
|
24
|
+
fileName: (_a = item.fileName) !== null && _a !== void 0 ? _a : String(item),
|
|
25
|
+
mimeType: (_c = (_b = item.mimeType) !== null && _b !== void 0 ? _b : item.contentType) !== null && _c !== void 0 ? _c : undefined,
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/** Dedup key for the componentDidLoad/@Watch('data') "emit mrdAttachments only on
|
|
30
|
+
* change" guard shared by mrd-document-view / mrd-invoice-view / mrd-email-view. */
|
|
31
|
+
export function attachmentsKey(attachments) {
|
|
32
|
+
return attachments.map(a => a.href).join('|');
|
|
20
33
|
}
|
|
@@ -85,6 +85,21 @@ const translations = {
|
|
|
85
85
|
merge_confirm_heading: 'Bevestig samenvoegen',
|
|
86
86
|
merge_confirm_warning: 'Dit kan niet ongedaan worden gemaakt: de kandidaat wordt definitief verwijderd.',
|
|
87
87
|
merge_confirm_button: 'Samenvoegen bevestigen',
|
|
88
|
+
// mrd-invoice-view
|
|
89
|
+
invoice_title: 'Factuur',
|
|
90
|
+
invoice_date: 'Factuurdatum',
|
|
91
|
+
invoice_due_date: 'Vervaldatum',
|
|
92
|
+
invoice_subtotal: 'Subtotaal',
|
|
93
|
+
invoice_tax: 'BTW',
|
|
94
|
+
invoice_total: 'Totaal',
|
|
95
|
+
invoice_customer: 'Klant',
|
|
96
|
+
invoice_supplier: 'Leverancier',
|
|
97
|
+
// mrd-email-view
|
|
98
|
+
email_from: 'Van',
|
|
99
|
+
email_to: 'Aan',
|
|
100
|
+
email_cc: 'Cc',
|
|
101
|
+
email_date: 'Datum',
|
|
102
|
+
email_show_headers: 'Toon technische headers',
|
|
88
103
|
},
|
|
89
104
|
en: {
|
|
90
105
|
required: 'This field is required',
|
|
@@ -172,6 +187,21 @@ const translations = {
|
|
|
172
187
|
merge_confirm_heading: 'Confirm merge',
|
|
173
188
|
merge_confirm_warning: 'This cannot be undone: the candidate will be permanently deleted.',
|
|
174
189
|
merge_confirm_button: 'Confirm merge',
|
|
190
|
+
// mrd-invoice-view
|
|
191
|
+
invoice_title: 'Invoice',
|
|
192
|
+
invoice_date: 'Invoice date',
|
|
193
|
+
invoice_due_date: 'Due date',
|
|
194
|
+
invoice_subtotal: 'Subtotal',
|
|
195
|
+
invoice_tax: 'Tax',
|
|
196
|
+
invoice_total: 'Total',
|
|
197
|
+
invoice_customer: 'Customer',
|
|
198
|
+
invoice_supplier: 'Supplier',
|
|
199
|
+
// mrd-email-view
|
|
200
|
+
email_from: 'From',
|
|
201
|
+
email_to: 'To',
|
|
202
|
+
email_cc: 'Cc',
|
|
203
|
+
email_date: 'Date',
|
|
204
|
+
email_show_headers: 'Show technical headers',
|
|
175
205
|
},
|
|
176
206
|
ar: {
|
|
177
207
|
required: 'هذا الحقل مطلوب',
|
|
@@ -253,6 +283,21 @@ const translations = {
|
|
|
253
283
|
merge_confirm_heading: 'تأكيد الدمج',
|
|
254
284
|
merge_confirm_warning: 'لا يمكن التراجع عن هذا الإجراء: سيتم حذف المرشح نهائياً.',
|
|
255
285
|
merge_confirm_button: 'تأكيد الدمج',
|
|
286
|
+
// mrd-invoice-view
|
|
287
|
+
invoice_title: 'فاتورة',
|
|
288
|
+
invoice_date: 'تاريخ الفاتورة',
|
|
289
|
+
invoice_due_date: 'تاريخ الاستحقاق',
|
|
290
|
+
invoice_subtotal: 'المجموع الفرعي',
|
|
291
|
+
invoice_tax: 'الضريبة',
|
|
292
|
+
invoice_total: 'الإجمالي',
|
|
293
|
+
invoice_customer: 'العميل',
|
|
294
|
+
invoice_supplier: 'المورد',
|
|
295
|
+
// mrd-email-view
|
|
296
|
+
email_from: 'من',
|
|
297
|
+
email_to: 'إلى',
|
|
298
|
+
email_cc: 'نسخة',
|
|
299
|
+
email_date: 'التاريخ',
|
|
300
|
+
email_show_headers: 'إظهار الترويسات التقنية',
|
|
256
301
|
},
|
|
257
302
|
fr: {
|
|
258
303
|
required: 'Ce champ est obligatoire',
|
|
@@ -334,6 +379,21 @@ const translations = {
|
|
|
334
379
|
merge_confirm_heading: 'Confirmer la fusion',
|
|
335
380
|
merge_confirm_warning: 'Cette action est irréversible : le candidat sera définitivement supprimé.',
|
|
336
381
|
merge_confirm_button: 'Confirmer la fusion',
|
|
382
|
+
// mrd-invoice-view
|
|
383
|
+
invoice_title: 'Facture',
|
|
384
|
+
invoice_date: 'Date de facture',
|
|
385
|
+
invoice_due_date: "Date d'échéance",
|
|
386
|
+
invoice_subtotal: 'Sous-total',
|
|
387
|
+
invoice_tax: 'TVA',
|
|
388
|
+
invoice_total: 'Total',
|
|
389
|
+
invoice_customer: 'Client',
|
|
390
|
+
invoice_supplier: 'Fournisseur',
|
|
391
|
+
// mrd-email-view
|
|
392
|
+
email_from: 'De',
|
|
393
|
+
email_to: 'À',
|
|
394
|
+
email_cc: 'Cc',
|
|
395
|
+
email_date: 'Date',
|
|
396
|
+
email_show_headers: 'Afficher les en-têtes techniques',
|
|
337
397
|
},
|
|
338
398
|
de: {
|
|
339
399
|
required: 'Dieses Feld ist erforderlich',
|
|
@@ -415,6 +475,21 @@ const translations = {
|
|
|
415
475
|
merge_confirm_heading: 'Zusammenführung bestätigen',
|
|
416
476
|
merge_confirm_warning: 'Dies kann nicht rückgängig gemacht werden: der Kandidat wird endgültig gelöscht.',
|
|
417
477
|
merge_confirm_button: 'Zusammenführung bestätigen',
|
|
478
|
+
// mrd-invoice-view
|
|
479
|
+
invoice_title: 'Rechnung',
|
|
480
|
+
invoice_date: 'Rechnungsdatum',
|
|
481
|
+
invoice_due_date: 'Fälligkeitsdatum',
|
|
482
|
+
invoice_subtotal: 'Zwischensumme',
|
|
483
|
+
invoice_tax: 'MwSt.',
|
|
484
|
+
invoice_total: 'Gesamt',
|
|
485
|
+
invoice_customer: 'Kunde',
|
|
486
|
+
invoice_supplier: 'Lieferant',
|
|
487
|
+
// mrd-email-view
|
|
488
|
+
email_from: 'Von',
|
|
489
|
+
email_to: 'An',
|
|
490
|
+
email_cc: 'Cc',
|
|
491
|
+
email_date: 'Datum',
|
|
492
|
+
email_show_headers: 'Technische Header anzeigen',
|
|
418
493
|
},
|
|
419
494
|
es: {
|
|
420
495
|
required: 'Este campo es obligatorio',
|
|
@@ -496,6 +571,21 @@ const translations = {
|
|
|
496
571
|
merge_confirm_heading: 'Confirmar fusión',
|
|
497
572
|
merge_confirm_warning: 'Esto no se puede deshacer: el candidato se eliminará permanentemente.',
|
|
498
573
|
merge_confirm_button: 'Confirmar fusión',
|
|
574
|
+
// mrd-invoice-view
|
|
575
|
+
invoice_title: 'Factura',
|
|
576
|
+
invoice_date: 'Fecha de factura',
|
|
577
|
+
invoice_due_date: 'Fecha de vencimiento',
|
|
578
|
+
invoice_subtotal: 'Subtotal',
|
|
579
|
+
invoice_tax: 'Impuesto',
|
|
580
|
+
invoice_total: 'Total',
|
|
581
|
+
invoice_customer: 'Cliente',
|
|
582
|
+
invoice_supplier: 'Proveedor',
|
|
583
|
+
// mrd-email-view
|
|
584
|
+
email_from: 'De',
|
|
585
|
+
email_to: 'Para',
|
|
586
|
+
email_cc: 'Cc',
|
|
587
|
+
email_date: 'Fecha',
|
|
588
|
+
email_show_headers: 'Mostrar encabezados técnicos',
|
|
499
589
|
},
|
|
500
590
|
it: {
|
|
501
591
|
required: 'Questo campo è obbligatorio',
|
|
@@ -577,6 +667,21 @@ const translations = {
|
|
|
577
667
|
merge_confirm_heading: 'Conferma unione',
|
|
578
668
|
merge_confirm_warning: "Questa azione non può essere annullata: il candidato verrà eliminato definitivamente.",
|
|
579
669
|
merge_confirm_button: 'Conferma unione',
|
|
670
|
+
// mrd-invoice-view
|
|
671
|
+
invoice_title: 'Fattura',
|
|
672
|
+
invoice_date: 'Data fattura',
|
|
673
|
+
invoice_due_date: 'Data di scadenza',
|
|
674
|
+
invoice_subtotal: 'Subtotale',
|
|
675
|
+
invoice_tax: 'IVA',
|
|
676
|
+
invoice_total: 'Totale',
|
|
677
|
+
invoice_customer: 'Cliente',
|
|
678
|
+
invoice_supplier: 'Fornitore',
|
|
679
|
+
// mrd-email-view
|
|
680
|
+
email_from: 'Da',
|
|
681
|
+
email_to: 'A',
|
|
682
|
+
email_cc: 'Cc',
|
|
683
|
+
email_date: 'Data',
|
|
684
|
+
email_show_headers: 'Mostra intestazioni tecniche',
|
|
580
685
|
},
|
|
581
686
|
uk: {
|
|
582
687
|
required: "Це поле обов'язкове",
|
|
@@ -658,6 +763,21 @@ const translations = {
|
|
|
658
763
|
merge_confirm_heading: 'Підтвердити об\'єднання',
|
|
659
764
|
merge_confirm_warning: 'Цю дію не можна скасувати: кандидат буде остаточно видалено.',
|
|
660
765
|
merge_confirm_button: 'Підтвердити об\'єднання',
|
|
766
|
+
// mrd-invoice-view
|
|
767
|
+
invoice_title: 'Рахунок-фактура',
|
|
768
|
+
invoice_date: 'Дата рахунку',
|
|
769
|
+
invoice_due_date: 'Термін оплати',
|
|
770
|
+
invoice_subtotal: 'Проміжний підсумок',
|
|
771
|
+
invoice_tax: 'ПДВ',
|
|
772
|
+
invoice_total: 'Разом',
|
|
773
|
+
invoice_customer: 'Клієнт',
|
|
774
|
+
invoice_supplier: 'Постачальник',
|
|
775
|
+
// mrd-email-view
|
|
776
|
+
email_from: 'Від',
|
|
777
|
+
email_to: 'Кому',
|
|
778
|
+
email_cc: 'Копія',
|
|
779
|
+
email_date: 'Дата',
|
|
780
|
+
email_show_headers: 'Показати технічні заголовки',
|
|
661
781
|
},
|
|
662
782
|
};
|
|
663
783
|
export function t(key, locale) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{e as r,a as e,f as t,b as n,c as u,d as a}from"./format.js";import{a as l}from"./client-layout.js";class o{static render(r,e,t){var n,u,a,c;if(r.type===l.RELATION){const t=null!==(n=r.name)&&void 0!==n?n:"",l=null===(u=null==e?void 0:e._links)||void 0===u?void 0:u[t];return l?Array.isArray(l)?l.map((r=>{var e;return null!==(e=r.name)&&void 0!==e?e:""})).filter(Boolean).join(", "):null!==(a=l.name)&&void 0!==a?a:"":""}if(r.type!==l.FIELD)return"";const s=null!==(c=r.name)&&void 0!==c?c:"",i=r.dataType,d=r.listItems;let E=null==e?void 0:e[s];return r.historyEnabled&&null!=E&&"object"==typeof E&&!Array.isArray(E)&&"current"in E&&(E=E.current),null==E||""===E?"":(Array.isArray(E)?E:[E]).map((r=>o.renderValue(null!=i?i:"TEXT",r,null!=d?d:[],t))).filter((r=>""!==r)).join(", ")}static renderValue(l,o,c,s){var i,d;switch(l){case"INTEGER":return u(Number(o),s,{maximumFractionDigits:0});case"DECIMAL":return u(Number(o),s);case"PERCENTAGE":return a(Number(o),s);case"CURRENCY":{const{amount:r,currency:e}="object"==typeof o&&null!==o?o:{amount:o,currency:""};return e?n(Number(r),e,s):u(Number(r),s)}case"DATE":return t(o,s);case"DATETIME":return e(o,s);case"TIME":return r(o,s);case"BOOLEAN":return o?"✓":"";case"FILE":case"IMAGE":return"object"==typeof o&&null!==o&&null!==(i=o.fileName)&&void 0!==i?i:"";case"LIST":{const r=c.find((r=>r.key===String(o)));return null!==(d=null==r?void 0:r.label)&&void 0!==d?d:String(o)}case"TEXTBLOCK":{const r=String(o).replace(/<[^>]*>/g,""),e=document.createElement("textarea");return e.innerHTML=r,e.value.trim()}case"LONGTEXT":return String(o).replace(/[\r\n]+/g," ").trim();case"JSON":return("object"==typeof o?JSON.stringify(o):String(o)).replace(/[\r\n]+/g," ").trim();case"SECRET":return o?"••••••••":"";default:return String(o)}}static formatJson(r,e=!1){try{const t="string"==typeof r?JSON.parse(r):r;return(e?JSON.stringify(t):JSON.stringify(t,null,2)).replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,(r=>{let e="color:#2aa198";return/^"/.test(r)?e=/:$/.test(r)?"color:#881391":"color:#268bd2":/true|false/.test(r)?e="color:#b58900":/null/.test(r)&&(e="color:#dc322f"),`<span style="${e}">${r}</span>`}))}catch(e){return String(r)}}}export{o as C}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var E,A,T,O,R
|
|
1
|
+
var E,A,n,T,O,R;!function(E){E.OBJECT_FORM_DASHBOARD="OBJECT_FORM_DASHBOARD",E.CLASS_DASHBOARD="CLASS_DASHBOARD",E.GENERAL_DASHBOARD="GENERAL_DASHBOARD",E.NAVIGATION_PANE="NAVIGATION_PANE"}(E||(E={})),function(E){E.FIELD="FIELD",E.RELATION="RELATION",E.SECTION="SECTION",E.GROUP="GROUP",E.HEADER="HEADER",E.TEXT="TEXT",E.NAVIGATE="NAVIGATE",E.ACTION="ACTION",E.SEARCH="SEARCH",E.VIEW="VIEW",E.RELATED_VIEW="RELATED_VIEW",E.RELATED_OBJECT="RELATED_OBJECT"}(A||(A={})),function(E){E.TEXT="TEXT",E.TEXTBLOCK="TEXTBLOCK",E.INTEGER="INTEGER",E.DECIMAL="DECIMAL",E.PERCENTAGE="PERCENTAGE",E.CURRENCY="CURRENCY",E.BOOLEAN="BOOLEAN",E.DATE="DATE",E.DATETIME="DATETIME",E.TIME="TIME",E.EMAIL="EMAIL",E.HYPERLINK="HYPERLINK",E.LIST="LIST",E.FILE="FILE",E.IMAGE="IMAGE",E.LONGTEXT="LONGTEXT",E.JSON="JSON",E.SECRET="SECRET"}(n||(n={})),function(E){E.SEARCH="SEARCH",E.DROPDOWN="DROPDOWN",E.CHECKBOX="CHECKBOX"}(T||(T={})),function(E){E.SEARCH="SEARCH",E.DROPDOWN="DROPDOWN",E.CHECKBOX="CHECKBOX"}(O||(O={})),function(E){E.PAGE="PAGE",E.OVERLAY_PAGE="OVERLAY_PAGE"}(R||(R={}));const o="commons.document",C="commons.invoice",I="commons.email",D="commons.invoiceLine";function N(E,A){return(null!=E?E:[]).find((E=>E.archetype===A))}export{o as A,E as C,A as a,n as b,T as c,O as d,R as e,C as f,I as g,D as h,N as r}
|