@mmlogic/components 0.5.14 → 0.5.15
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-mjS630f1.js → cell-renderer-CLVKTVVQ.js} +105 -1
- package/dist/cjs/{client-layout-CqVuJumR.js → client-layout-Eg2VwW-7.js} +2 -0
- package/dist/cjs/index.cjs.js +2 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/mosterdcomponents.cjs.js +1 -1
- package/dist/cjs/{mrd-boolean-field_25.cjs.entry.js → mrd-boolean-field_28.cjs.entry.js} +1022 -335
- package/dist/cjs/mrd-merge-view.cjs.entry.js +4 -4
- package/dist/collection/collection-manifest.json +3 -0
- package/dist/collection/components/fields/mrd-textarea-field/mrd-textarea-field.js +47 -2
- package/dist/collection/components/form/mrd-form/mrd-form.css +29 -0
- package/dist/collection/components/form/mrd-form/mrd-form.js +44 -8
- package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.js +126 -13
- package/dist/collection/components/memo/mrd-memo-container/mrd-memo-container.css +204 -0
- package/dist/collection/components/memo/mrd-memo-container/mrd-memo-container.js +694 -0
- package/dist/collection/components/memo/mrd-memo-list/mrd-memo-list.css +150 -0
- package/dist/collection/components/memo/mrd-memo-list/mrd-memo-list.js +511 -0
- package/dist/collection/components/memo/mrd-memo-view/mrd-memo-view.css +108 -0
- package/dist/collection/components/memo/mrd-memo-view/mrd-memo-view.js +204 -0
- package/dist/collection/components/merge/mrd-merge-view/mrd-merge-view.js +2 -2
- package/dist/collection/components/table/mrd-table/mrd-table.js +9 -6
- package/dist/collection/dev/app.js +17 -0
- package/dist/collection/types/client-layout.js +1 -0
- package/dist/collection/utils/i18n.js +104 -0
- package/dist/collection/utils/query-params.js +9 -0
- package/dist/components/client-layout.js +1 -1
- package/dist/components/i18n.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/mrd-form.js +1 -1
- package/dist/components/mrd-layout-section.js +1 -1
- package/dist/components/mrd-memo-container.d.ts +11 -0
- package/dist/components/mrd-memo-container.js +1 -0
- package/dist/components/mrd-memo-container2.js +1 -0
- package/dist/components/mrd-memo-list.d.ts +11 -0
- package/dist/components/mrd-memo-list.js +1 -0
- package/dist/components/mrd-memo-list2.js +1 -0
- package/dist/components/mrd-memo-view.d.ts +11 -0
- package/dist/components/mrd-memo-view.js +1 -0
- package/dist/components/mrd-memo-view2.js +1 -0
- package/dist/components/mrd-merge-view.js +1 -1
- package/dist/components/mrd-table2.js +1 -1
- package/dist/components/mrd-textarea-field2.js +1 -1
- package/dist/components/query-params.js +1 -1
- package/dist/components/table-query.js +1 -0
- package/dist/esm/{cell-renderer-BDY8UXkH.js → cell-renderer-4NKEzZWw.js} +105 -1
- package/dist/esm/{client-layout-Bc42CfJB.js → client-layout-BJkVeSq6.js} +2 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/mosterdcomponents.js +1 -1
- package/dist/esm/{mrd-boolean-field_25.entry.js → mrd-boolean-field_28.entry.js} +1020 -336
- package/dist/esm/mrd-merge-view.entry.js +4 -4
- package/dist/mosterdcomponents/index.esm.js +1 -1
- package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
- package/dist/mosterdcomponents/{p-Bc42CfJB.js → p-BJkVeSq6.js} +1 -1
- package/dist/mosterdcomponents/p-BMx6VAJ6.js +1 -0
- package/dist/mosterdcomponents/p-d64ba1f2.entry.js +3 -0
- package/dist/mosterdcomponents/{p-e8b0880f.entry.js → p-e68dfbb0.entry.js} +1 -1
- package/dist/types/components/fields/mrd-textarea-field/mrd-textarea-field.d.ts +10 -0
- package/dist/types/components/form/mrd-form/mrd-form.d.ts +6 -0
- package/dist/types/components/layout/mrd-layout-section/mrd-layout-section.d.ts +20 -1
- package/dist/types/components/memo/mrd-memo-container/mrd-memo-container.d.ts +152 -0
- package/dist/types/components/memo/mrd-memo-list/mrd-memo-list.d.ts +79 -0
- package/dist/types/components/memo/mrd-memo-view/mrd-memo-view.d.ts +33 -0
- package/dist/types/components.d.ts +528 -1
- package/dist/types/types/client-layout.d.ts +1 -0
- package/dist/types/utils/query-params.d.ts +16 -0
- package/package.json +1 -1
- package/dist/mosterdcomponents/cell-renderer-B8u5BCK-.js.map +0 -1
- package/dist/mosterdcomponents/client-layout-Bc42CfJB.js.map +0 -1
- package/dist/mosterdcomponents/document-attachments-BufPmMRv.js.map +0 -1
- package/dist/mosterdcomponents/field-helpers-CNQcI3Hf.js.map +0 -1
- package/dist/mosterdcomponents/file-upload-common-C9wp47CB.js.map +0 -1
- package/dist/mosterdcomponents/format-gcecItcD.js.map +0 -1
- package/dist/mosterdcomponents/i18n-ydNM87-Q.js.map +0 -1
- package/dist/mosterdcomponents/index-1ayBojyN.js.map +0 -1
- package/dist/mosterdcomponents/index-DhffneUF.js.map +0 -1
- package/dist/mosterdcomponents/index.esm.js.map +0 -1
- package/dist/mosterdcomponents/mosterdcomponents.esm.js.map +0 -1
- package/dist/mosterdcomponents/p-Dkm4WxMy.js +0 -1
- package/dist/mosterdcomponents/p-c834951a.entry.js +0 -3
- package/dist/mosterdcomponents/purify.es-_duHfPgC.js.map +0 -1
- package/dist/mosterdcomponents/query-params-BZbQoeYF.js.map +0 -1
- package/dist/mosterdcomponents/quill-C9pgw_k-.js.map +0 -1
- package/dist/mosterdcomponents/validation-CjjTt66G.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var index = require('./index-DVbdkYO3.js');
|
|
4
|
-
var clientLayout = require('./client-layout-
|
|
5
|
-
var cellRenderer = require('./cell-renderer-
|
|
4
|
+
var clientLayout = require('./client-layout-Eg2VwW-7.js');
|
|
5
|
+
var cellRenderer = require('./cell-renderer-CLVKTVVQ.js');
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Whether a layout item can appear in the merge diff at all. m-n relations
|
|
@@ -257,14 +257,14 @@ const MrdMergeView = class {
|
|
|
257
257
|
var _a, _b;
|
|
258
258
|
let stepContent;
|
|
259
259
|
if (this.step === 'search') {
|
|
260
|
-
stepContent = (index.h(MergeSearchStep, { key: '
|
|
260
|
+
stepContent = (index.h(MergeSearchStep, { key: '88ddac4f8f60a736bc6bc898b553e24771023b82', locale: this.locale, searchQuery: this.searchQuery, searchResults: this.searchResults, isLoading: this.isLoading, onSearchInput: this.handleSearchInput, onSelect: this.handleSelect }));
|
|
261
261
|
}
|
|
262
262
|
else {
|
|
263
263
|
const diff = diffFields(this.fields, this.currentRecord, this.candidate);
|
|
264
264
|
const bLabel = candidateLabel(this.candidate);
|
|
265
265
|
stepContent = this.step === 'compare' ? (index.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 })) : (index.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 }));
|
|
266
266
|
}
|
|
267
|
-
return (index.h(index.Host, { key: '
|
|
267
|
+
return (index.h(index.Host, { key: '3606faba4c86ae1d981b7c40e4f1cb9cde19cf50' }, index.h("div", { key: '9605009fec0a7c79a5cd32141d930ea04e5efaad', class: "mrd-merge-view" }, stepContent)));
|
|
268
268
|
}
|
|
269
269
|
get el() { return index.getElement(this); }
|
|
270
270
|
};
|
|
@@ -24,6 +24,9 @@
|
|
|
24
24
|
"components/form/mrd-form/mrd-form.js",
|
|
25
25
|
"components/invoice/mrd-invoice-view/mrd-invoice-view.js",
|
|
26
26
|
"components/layout/mrd-layout-section/mrd-layout-section.js",
|
|
27
|
+
"components/memo/mrd-memo-container/mrd-memo-container.js",
|
|
28
|
+
"components/memo/mrd-memo-list/mrd-memo-list.js",
|
|
29
|
+
"components/memo/mrd-memo-view/mrd-memo-view.js",
|
|
27
30
|
"components/merge/mrd-merge-view/mrd-merge-view.js",
|
|
28
31
|
"components/table/mrd-table/mrd-table.js"
|
|
29
32
|
],
|
|
@@ -10,12 +10,29 @@ export class MrdTextareaField {
|
|
|
10
10
|
this.required = false;
|
|
11
11
|
this.disabled = false;
|
|
12
12
|
this.locale = navigator.language;
|
|
13
|
+
/** Focus the editor as soon as it's ready — opt-in, since auto-focusing every
|
|
14
|
+
* textarea field on mount would be wrong for a regular multi-field form. */
|
|
15
|
+
this.autofocus = false;
|
|
13
16
|
this.error = '';
|
|
14
17
|
this.editorReady = false;
|
|
15
18
|
}
|
|
16
19
|
componentDidLoad() {
|
|
17
20
|
this.initQuill();
|
|
18
21
|
}
|
|
22
|
+
/** The host may reuse the same element for a different record (e.g. mrd-memo-
|
|
23
|
+
* container's quick-create/edit dialog editing a second memo without the
|
|
24
|
+
* dialog itself remounting) — Quill only reads `value` once at construction,
|
|
25
|
+
* so re-apply it here when it changes to something the editor doesn't already
|
|
26
|
+
* hold. Guarded against our own emitted mrdChange feeding back in as a no-op. */
|
|
27
|
+
valueChanged(newValue) {
|
|
28
|
+
if (!this.editorReady || !this.quill)
|
|
29
|
+
return;
|
|
30
|
+
if (newValue === this.getSanitizedHtml())
|
|
31
|
+
return;
|
|
32
|
+
this.quill.setText('');
|
|
33
|
+
if (newValue)
|
|
34
|
+
this.quill.clipboard.dangerouslyPasteHTML(newValue);
|
|
35
|
+
}
|
|
19
36
|
async initQuill() {
|
|
20
37
|
try {
|
|
21
38
|
// Dynamically import Quill
|
|
@@ -37,6 +54,7 @@ export class MrdTextareaField {
|
|
|
37
54
|
],
|
|
38
55
|
},
|
|
39
56
|
});
|
|
57
|
+
this.quill = quill;
|
|
40
58
|
if (this.value) {
|
|
41
59
|
quill.clipboard.dangerouslyPasteHTML(this.value);
|
|
42
60
|
}
|
|
@@ -51,8 +69,9 @@ export class MrdTextareaField {
|
|
|
51
69
|
this.mrdBlur.emit({ name: this.name, value: html });
|
|
52
70
|
}
|
|
53
71
|
});
|
|
54
|
-
void quill; // hold reference if needed later
|
|
55
72
|
this.editorReady = true;
|
|
73
|
+
if (this.autofocus)
|
|
74
|
+
quill.focus();
|
|
56
75
|
}
|
|
57
76
|
catch (err) {
|
|
58
77
|
console.error('Failed to load Quill editor:', err);
|
|
@@ -64,7 +83,7 @@ export class MrdTextareaField {
|
|
|
64
83
|
return DOMPurify.sanitize(html);
|
|
65
84
|
}
|
|
66
85
|
render() {
|
|
67
|
-
return (h(Host, { key: '
|
|
86
|
+
return (h(Host, { key: '5dad54667601fce064107311e741e4e0dad94298' }, h("div", { key: 'bd7bd538155ec3172fa8cc1cf4cf66ad23d07a3b', class: "mrd-textarea-field" }, h(FieldLabel, { key: 'a3fe2c714340bbdcd3521e9782f87f3773c65e62', base: "mrd-textarea-field", label: this.label, required: this.required }), h("div", { key: 'a7a628f94bc628fd358c7fc876ee1bdd2c7ef520', class: controlClass('mrd-textarea-field', !!this.error, 'container') }, h("div", { key: '30ecd27d9e928094178f8f011524ff5633cb875e', class: "mrd-textarea-field__editor" })), h(FieldError, { key: '589d5cbf28c3ae1bdbe5f663aaf6cae840bdcffe', base: "mrd-textarea-field", error: this.error }))));
|
|
68
87
|
}
|
|
69
88
|
static get is() { return "mrd-textarea-field"; }
|
|
70
89
|
static get encapsulation() { return "scoped"; }
|
|
@@ -219,6 +238,26 @@ export class MrdTextareaField {
|
|
|
219
238
|
"reflect": false,
|
|
220
239
|
"attribute": "locale",
|
|
221
240
|
"defaultValue": "navigator.language"
|
|
241
|
+
},
|
|
242
|
+
"autofocus": {
|
|
243
|
+
"type": "boolean",
|
|
244
|
+
"mutable": false,
|
|
245
|
+
"complexType": {
|
|
246
|
+
"original": "boolean",
|
|
247
|
+
"resolved": "boolean",
|
|
248
|
+
"references": {}
|
|
249
|
+
},
|
|
250
|
+
"required": false,
|
|
251
|
+
"optional": false,
|
|
252
|
+
"docs": {
|
|
253
|
+
"tags": [],
|
|
254
|
+
"text": "Focus the editor as soon as it's ready \u2014 opt-in, since auto-focusing every\ntextarea field on mount would be wrong for a regular multi-field form."
|
|
255
|
+
},
|
|
256
|
+
"getter": false,
|
|
257
|
+
"setter": false,
|
|
258
|
+
"reflect": false,
|
|
259
|
+
"attribute": "autofocus",
|
|
260
|
+
"defaultValue": "false"
|
|
222
261
|
}
|
|
223
262
|
};
|
|
224
263
|
}
|
|
@@ -262,4 +301,10 @@ export class MrdTextareaField {
|
|
|
262
301
|
}];
|
|
263
302
|
}
|
|
264
303
|
static get elementRef() { return "el"; }
|
|
304
|
+
static get watchers() {
|
|
305
|
+
return [{
|
|
306
|
+
"propName": "value",
|
|
307
|
+
"methodName": "valueChanged"
|
|
308
|
+
}];
|
|
309
|
+
}
|
|
265
310
|
}
|
|
@@ -126,4 +126,33 @@
|
|
|
126
126
|
}
|
|
127
127
|
.mrd-form__cancel:active {
|
|
128
128
|
background-color: var(--mrd-color-neutral-200);
|
|
129
|
+
}
|
|
130
|
+
.mrd-form__delete {
|
|
131
|
+
display: inline-flex;
|
|
132
|
+
align-items: center;
|
|
133
|
+
justify-content: center;
|
|
134
|
+
height: var(--mrd-input-height);
|
|
135
|
+
padding: 0 var(--mrd-space-6);
|
|
136
|
+
margin-right: auto;
|
|
137
|
+
background-color: transparent;
|
|
138
|
+
color: var(--mrd-color-danger);
|
|
139
|
+
font-family: var(--mrd-font-family);
|
|
140
|
+
font-size: var(--mrd-font-size-base);
|
|
141
|
+
font-weight: var(--mrd-font-weight-medium);
|
|
142
|
+
border: var(--mrd-border-width) solid var(--mrd-color-danger);
|
|
143
|
+
border-radius: var(--mrd-border-radius);
|
|
144
|
+
cursor: pointer;
|
|
145
|
+
transition: background-color var(--mrd-transition), color var(--mrd-transition);
|
|
146
|
+
}
|
|
147
|
+
.mrd-form__delete:hover {
|
|
148
|
+
background-color: var(--mrd-color-danger-light);
|
|
149
|
+
color: var(--mrd-color-danger-dark);
|
|
150
|
+
}
|
|
151
|
+
.mrd-form__delete:focus {
|
|
152
|
+
outline: none;
|
|
153
|
+
box-shadow: 0 0 0 3px var(--mrd-color-danger-light);
|
|
154
|
+
}
|
|
155
|
+
.mrd-form__delete:active {
|
|
156
|
+
background-color: var(--mrd-color-danger-light);
|
|
157
|
+
border-color: var(--mrd-color-danger-dark);
|
|
129
158
|
}
|
|
@@ -27,6 +27,11 @@ 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
|
+
/** When true, a delete button is shown next to the submit button (edit mode only —
|
|
31
|
+
* the host decides when a delete affordance makes sense, e.g. only for an existing
|
|
32
|
+
* record). Deletion itself (confirmation, the actual API call) is entirely the
|
|
33
|
+
* host's responsibility; mrd-form only emits the request via mrdDelete. */
|
|
34
|
+
this.showDelete = false;
|
|
30
35
|
/**
|
|
31
36
|
* The currently logged-in user, resolved by the host via /accounts/me.
|
|
32
37
|
* Used to pre-fill RELATION fields whose defaultValue is "@me".
|
|
@@ -314,15 +319,11 @@ export class MrdForm {
|
|
|
314
319
|
normalizeRelationValue(value) {
|
|
315
320
|
if (value == null || value === '')
|
|
316
321
|
return null;
|
|
317
|
-
if (typeof value === 'string')
|
|
318
|
-
return value || null;
|
|
319
322
|
if (Array.isArray(value)) {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
if (typeof value === 'object' && 'id' in value) {
|
|
323
|
-
return value.id || null;
|
|
323
|
+
const hrefs = value.map(v => this.getHref(v)).filter(v => v !== '');
|
|
324
|
+
return hrefs.length ? hrefs : null;
|
|
324
325
|
}
|
|
325
|
-
return null;
|
|
326
|
+
return this.getHref(value) || null;
|
|
326
327
|
}
|
|
327
328
|
deepEqual(a, b) {
|
|
328
329
|
if (a === b)
|
|
@@ -395,7 +396,7 @@ export class MrdForm {
|
|
|
395
396
|
return h(Host, null);
|
|
396
397
|
}
|
|
397
398
|
const dir = this.locale.startsWith('ar') ? 'rtl' : 'ltr';
|
|
398
|
-
return (h(Host, null, h("form", { class: "mrd-form", dir: dir, onSubmit: this.handleSubmit, noValidate: true }, this.layout.title && h("h2", { class: "mrd-form__title" }, this.layout.title), h("div", { class: "mrd-form__body" }, this.renderItems(this.layout.items)), h("div", { class: "mrd-form__footer" }, h("button", { type: "submit", class: "mrd-form__submit" }, t('submit', this.locale)), this.showCancel && (h("button", { type: "button", class: "mrd-form__cancel", onClick: () => this.mrdCancel.emit() }, t('cancel', this.locale)))))));
|
|
399
|
+
return (h(Host, null, h("form", { class: "mrd-form", dir: dir, onSubmit: this.handleSubmit, noValidate: true }, this.layout.title && h("h2", { class: "mrd-form__title" }, this.layout.title), h("div", { class: "mrd-form__body" }, this.renderItems(this.layout.items)), h("div", { class: "mrd-form__footer" }, this.showDelete && (h("button", { type: "button", class: "mrd-form__delete", onClick: () => this.mrdDelete.emit() }, t('delete', this.locale))), h("button", { type: "submit", class: "mrd-form__submit" }, t('submit', this.locale)), this.showCancel && (h("button", { type: "button", class: "mrd-form__cancel", onClick: () => this.mrdCancel.emit() }, t('cancel', this.locale)))))));
|
|
399
400
|
}
|
|
400
401
|
static get is() { return "mrd-form"; }
|
|
401
402
|
static get encapsulation() { return "scoped"; }
|
|
@@ -538,6 +539,26 @@ export class MrdForm {
|
|
|
538
539
|
"attribute": "show-cancel",
|
|
539
540
|
"defaultValue": "false"
|
|
540
541
|
},
|
|
542
|
+
"showDelete": {
|
|
543
|
+
"type": "boolean",
|
|
544
|
+
"mutable": false,
|
|
545
|
+
"complexType": {
|
|
546
|
+
"original": "boolean",
|
|
547
|
+
"resolved": "boolean",
|
|
548
|
+
"references": {}
|
|
549
|
+
},
|
|
550
|
+
"required": false,
|
|
551
|
+
"optional": false,
|
|
552
|
+
"docs": {
|
|
553
|
+
"tags": [],
|
|
554
|
+
"text": "When true, a delete button is shown next to the submit button (edit mode only \u2014\nthe host decides when a delete affordance makes sense, e.g. only for an existing\nrecord). Deletion itself (confirmation, the actual API call) is entirely the\nhost's responsibility; mrd-form only emits the request via mrdDelete."
|
|
555
|
+
},
|
|
556
|
+
"getter": false,
|
|
557
|
+
"setter": false,
|
|
558
|
+
"reflect": false,
|
|
559
|
+
"attribute": "show-delete",
|
|
560
|
+
"defaultValue": "false"
|
|
561
|
+
},
|
|
541
562
|
"me": {
|
|
542
563
|
"type": "unknown",
|
|
543
564
|
"mutable": false,
|
|
@@ -608,6 +629,21 @@ export class MrdForm {
|
|
|
608
629
|
"resolved": "void",
|
|
609
630
|
"references": {}
|
|
610
631
|
}
|
|
632
|
+
}, {
|
|
633
|
+
"method": "mrdDelete",
|
|
634
|
+
"name": "mrdDelete",
|
|
635
|
+
"bubbles": true,
|
|
636
|
+
"cancelable": true,
|
|
637
|
+
"composed": true,
|
|
638
|
+
"docs": {
|
|
639
|
+
"tags": [],
|
|
640
|
+
"text": ""
|
|
641
|
+
},
|
|
642
|
+
"complexType": {
|
|
643
|
+
"original": "void",
|
|
644
|
+
"resolved": "void",
|
|
645
|
+
"references": {}
|
|
646
|
+
}
|
|
611
647
|
}, {
|
|
612
648
|
"method": "mrdSearch",
|
|
613
649
|
"name": "mrdSearch",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Host, h } from "@stencil/core";
|
|
2
|
-
import { ClientLayoutItemType, ClientLayoutItemFieldDataType, ClientLayoutNavigateBehaviour, resolveArchetype, ARCHETYPE_DOCUMENT, ARCHETYPE_INVOICE, ARCHETYPE_EMAIL, ARCHETYPE_INVOICE_LINE, } from "../../../types/client-layout";
|
|
2
|
+
import { ClientLayoutItemType, ClientLayoutItemFieldDataType, ClientLayoutNavigateBehaviour, resolveArchetype, ARCHETYPE_DOCUMENT, ARCHETYPE_INVOICE, ARCHETYPE_EMAIL, ARCHETYPE_INVOICE_LINE, ARCHETYPE_MEMO, } from "../../../types/client-layout";
|
|
3
3
|
import { t } from "../../../utils/i18n";
|
|
4
4
|
import { viewKeyFor, flattenItems, buildContainerHref, showsEmpty } from "./layout-helpers";
|
|
5
5
|
import { renderField } from "./field-value";
|
|
@@ -21,6 +21,11 @@ export class MrdLayoutSection {
|
|
|
21
21
|
* create ("+") action and the documents view's New folder / Upload are disabled
|
|
22
22
|
* with a tooltip explaining why, so it's clear at a glance the user can't mutate data. */
|
|
23
23
|
this.readOnly = false;
|
|
24
|
+
/** The active account's linked person record (userProfile.links.person), if any.
|
|
25
|
+
* Threaded to mrd-memo-container so a top-level memo VIEW (no parent record to
|
|
26
|
+
* attach a new memo to) can still offer "New memo" by falling back to the
|
|
27
|
+
* account's own record as the container. */
|
|
28
|
+
this.me = null;
|
|
24
29
|
this.searchQueryMap = {};
|
|
25
30
|
this.searchResultsMap = {};
|
|
26
31
|
this.imagePreviewUrl = null;
|
|
@@ -74,6 +79,14 @@ export class MrdLayoutSection {
|
|
|
74
79
|
await table.init();
|
|
75
80
|
}
|
|
76
81
|
}
|
|
82
|
+
// mrd-memo-container's card mode has no <mrd-table> — mrd-memo-list needs the
|
|
83
|
+
// same init() call to request its first page.
|
|
84
|
+
const memoLists = this.el.querySelectorAll('mrd-memo-list[data-view]');
|
|
85
|
+
for (const list of Array.from(memoLists)) {
|
|
86
|
+
if (typeof list.init === 'function') {
|
|
87
|
+
await list.init();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
77
90
|
}
|
|
78
91
|
emitLoadImages() {
|
|
79
92
|
for (const item of flattenItems(this.items)) {
|
|
@@ -107,12 +120,18 @@ export class MrdLayoutSection {
|
|
|
107
120
|
return;
|
|
108
121
|
}
|
|
109
122
|
const table = this.el.querySelector(`mrd-table[data-view="${name}"]`);
|
|
110
|
-
if (
|
|
123
|
+
if (table) {
|
|
124
|
+
if (totalElements !== undefined) {
|
|
125
|
+
table.totalElements = totalElements;
|
|
126
|
+
}
|
|
127
|
+
await table.setPage(page, rows, hasNext);
|
|
111
128
|
return;
|
|
112
|
-
if (totalElements !== undefined) {
|
|
113
|
-
table.totalElements = totalElements;
|
|
114
129
|
}
|
|
115
|
-
|
|
130
|
+
// Cards mode: mrd-memo-container mounts mrd-memo-list instead of mrd-table.
|
|
131
|
+
const memoList = this.el.querySelector(`mrd-memo-list[data-view="${name}"]`);
|
|
132
|
+
if (memoList) {
|
|
133
|
+
await memoList.setPage(page, rows, hasNext);
|
|
134
|
+
}
|
|
116
135
|
}
|
|
117
136
|
/** Inject aggregation totals into an embedded mrd-table for a VIEW or RELATED_VIEW item. */
|
|
118
137
|
async setViewAggregations(name, data) {
|
|
@@ -135,11 +154,18 @@ export class MrdLayoutSection {
|
|
|
135
154
|
await list.setFileReference(uri);
|
|
136
155
|
}
|
|
137
156
|
/** Inject the created document's href after a file-drop create, so the
|
|
138
|
-
* optimistic row becomes navigable (see mrdCreateObject).
|
|
157
|
+
* optimistic row becomes navigable (see mrdCreateObject). For a memo
|
|
158
|
+
* quick-create there is no optimistic row to resolve — simply reload the
|
|
159
|
+
* container's current body so the new memo shows up. */
|
|
139
160
|
async setViewCreatedObject(name, href) {
|
|
140
161
|
const list = this.el.querySelector(`mrd-document-list[data-doclist="${name}"]`);
|
|
141
|
-
if (list === null || list === void 0 ? void 0 : list.setCreatedHref)
|
|
162
|
+
if (list === null || list === void 0 ? void 0 : list.setCreatedHref) {
|
|
142
163
|
await list.setCreatedHref(href);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const memoContainer = this.el.querySelector(`mrd-memo-container[data-view="${name}"]`);
|
|
167
|
+
if (memoContainer === null || memoContainer === void 0 ? void 0 : memoContainer.refresh)
|
|
168
|
+
await memoContainer.refresh();
|
|
143
169
|
}
|
|
144
170
|
/** Provide a resolved URL for an IMAGE field. Shows as thumbnail; clicking opens the lightbox. */
|
|
145
171
|
async setImagePreview(fieldName, url) {
|
|
@@ -201,7 +227,7 @@ export class MrdLayoutSection {
|
|
|
201
227
|
return (h("div", { class: "mrd-layout-section__search", key: `search-${dataClass}` }, h("div", { class: "mrd-layout-section__search-wrap" }, h("svg", { class: "mrd-layout-section__search-icon", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, h("path", { "fill-rule": "evenodd", d: "M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z", "clip-rule": "evenodd" })), h("input", { class: "mrd-layout-section__search-input", type: "text", value: query, placeholder: (_c = item.label) !== null && _c !== void 0 ? _c : '', onInput: e => this.handleSearchInput(dataClass, e.target.value) })), results.length > 0 && (h("ul", { class: "mrd-layout-section__search-results" }, results.map(r => (h("li", { key: r.id, class: "mrd-layout-section__search-result" }, h("button", { class: "mrd-layout-section__search-result-btn", onClick: () => this.mrdNavigate.emit({ href: r.id, label: r.label }) }, h("span", { class: "mrd-layout-section__search-result-label" }, r.label), r.description && h("span", { class: "mrd-layout-section__search-result-desc" }, r.description)))))))));
|
|
202
228
|
}
|
|
203
229
|
renderRelatedView(item) {
|
|
204
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
230
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
205
231
|
const key = viewKeyFor(item);
|
|
206
232
|
if (!key)
|
|
207
233
|
return null;
|
|
@@ -214,13 +240,12 @@ export class MrdLayoutSection {
|
|
|
214
240
|
// The API publishes `archetypes` on the VIEW/RELATED_VIEW item itself
|
|
215
241
|
// (sibling of `view`), not inside `view`.
|
|
216
242
|
const docArchetype = resolveArchetype((_g = item.archetypes) !== null && _g !== void 0 ? _g : (_h = item.view) === null || _h === void 0 ? void 0 : _h.archetypes, ARCHETYPE_DOCUMENT);
|
|
243
|
+
const memoArchetype = !docArchetype ? resolveArchetype((_j = item.archetypes) !== null && _j !== void 0 ? _j : (_k = item.view) === null || _k === void 0 ? void 0 : _k.archetypes, ARCHETYPE_MEMO) : undefined;
|
|
217
244
|
// Canonical parent href for single-container seeding: use the RELATED_VIEW's
|
|
218
245
|
// fromClass (base class) rather than the route class, so polymorphic subtypes
|
|
219
246
|
// resolve to the same container the documents actually reference.
|
|
220
247
|
const containerHref = buildContainerHref(item, selfHref, parentId);
|
|
221
|
-
return (h("div", { class: "mrd-layout-section__related-view", key: `view-${key}` }, showTitle && item.label && h("h3", { class: "mrd-layout-section__related-view-title" }, item.label), docArchetype
|
|
222
|
-
? this.renderDocumentContainer(item, key, parentId, docArchetype, containerHref)
|
|
223
|
-
: this.renderTable(item, key, parentId)));
|
|
248
|
+
return (h("div", { class: "mrd-layout-section__related-view", key: `view-${key}` }, showTitle && item.label && h("h3", { class: "mrd-layout-section__related-view-title" }, item.label), docArchetype && this.renderDocumentContainer(item, key, parentId, docArchetype, containerHref), memoArchetype && this.renderMemoContainer(item, key, parentId, memoArchetype, containerHref), !docArchetype && !memoArchetype && this.renderTable(item, key, parentId)));
|
|
224
249
|
}
|
|
225
250
|
/** Document collection view: owns the view-switch + collection actions and
|
|
226
251
|
* swaps between the folder tree and the flat table. Events are re-emitted to
|
|
@@ -258,6 +283,33 @@ export class MrdLayoutSection {
|
|
|
258
283
|
this.mrdCreateObject.emit(Object.assign({ name: key }, e.detail));
|
|
259
284
|
} }));
|
|
260
285
|
}
|
|
286
|
+
/** Memo collection view: owns the view-switch + "New memo" and swaps between
|
|
287
|
+
* the card list and the flat table, mirroring renderDocumentContainer(). */
|
|
288
|
+
renderMemoContainer(item, key, parentId, archetype, containerHref) {
|
|
289
|
+
var _a, _b, _c, _d;
|
|
290
|
+
const labelsListItems = (_d = (_c = (_b = (_a = item.view) === null || _a === void 0 ? void 0 : _a.values) === null || _b === void 0 ? void 0 : _b.find(v => { var _a; return v.name === ((_a = archetype.slots) === null || _a === void 0 ? void 0 : _a.labels); })) === null || _c === void 0 ? void 0 : _c.listItems) !== null && _d !== void 0 ? _d : null;
|
|
291
|
+
return (h("mrd-memo-container", { "data-view": key, item: item, archetype: archetype, parentId: parentId, containerHref: containerHref, viewKey: key, locale: this.locale, readOnly: this.readOnly, me: this.me, labelsListItems: labelsListItems, onMrdLoadPage: (e) => {
|
|
292
|
+
e.stopPropagation();
|
|
293
|
+
this.mrdLoadViewPage.emit(Object.assign({ name: key }, e.detail));
|
|
294
|
+
}, onMrdLoadAggregations: (e) => {
|
|
295
|
+
var _a;
|
|
296
|
+
e.stopPropagation();
|
|
297
|
+
this.mrdLoadViewAggregations.emit(Object.assign({ name: key, dataClass: (_a = item.dataClass) !== null && _a !== void 0 ? _a : key }, e.detail));
|
|
298
|
+
}, onMrdAction: (e) => {
|
|
299
|
+
var _a;
|
|
300
|
+
e.stopPropagation();
|
|
301
|
+
this.mrdViewAction.emit(Object.assign({ name: key, dataClass: (_a = item.dataClass) !== null && _a !== void 0 ? _a : key }, e.detail));
|
|
302
|
+
}, onMrdCreateObject: (e) => {
|
|
303
|
+
e.stopPropagation();
|
|
304
|
+
this.mrdCreateObject.emit(Object.assign({ name: key }, e.detail));
|
|
305
|
+
}, onMrdUpdateObject: (e) => {
|
|
306
|
+
e.stopPropagation();
|
|
307
|
+
this.mrdUpdateObject.emit(e.detail);
|
|
308
|
+
}, onMrdDeleteObject: (e) => {
|
|
309
|
+
e.stopPropagation();
|
|
310
|
+
this.mrdDeleteObject.emit(e.detail);
|
|
311
|
+
} }));
|
|
312
|
+
}
|
|
261
313
|
renderTable(item, key, parentId) {
|
|
262
314
|
return (h("mrd-table", { "data-view": key, item: item, parentId: parentId, locale: this.locale, readOnly: this.readOnly, onMrdLoadPage: (e) => this.handleViewLoadPage(e, key), onMrdLoadAggregations: (e) => {
|
|
263
315
|
var _a;
|
|
@@ -359,11 +411,24 @@ export class MrdLayoutSection {
|
|
|
359
411
|
...this.relatedItems().map(it => this.renderItem(it)),
|
|
360
412
|
];
|
|
361
413
|
}
|
|
414
|
+
/** Single-memo view: the record's own type carries commons.memo. Renders a
|
|
415
|
+
* recognisable memo (title/body prominent, author/date subtle) instead of
|
|
416
|
+
* generic fields, keeping any related views/searches below it. */
|
|
417
|
+
renderMemoObject(archetype) {
|
|
418
|
+
var _a, _b;
|
|
419
|
+
const labelsListItems = (_b = (_a = this.items.find(it => { var _a; return it.name === ((_a = archetype.slots) === null || _a === void 0 ? void 0 : _a.labels); })) === null || _a === void 0 ? void 0 : _a.listItems) !== null && _b !== void 0 ? _b : null;
|
|
420
|
+
return [
|
|
421
|
+
h("mrd-memo-view", { archetype: archetype, data: this.data, locale: this.locale, labelsListItems: labelsListItems, onMrdNavigate: (e) => { e.stopPropagation(); this.mrdNavigate.emit(e.detail); } }),
|
|
422
|
+
...this.relatedItems().map(it => this.renderItem(it)),
|
|
423
|
+
];
|
|
424
|
+
}
|
|
362
425
|
render() {
|
|
363
426
|
const docArchetype = resolveArchetype(this.archetypes, ARCHETYPE_DOCUMENT);
|
|
364
427
|
const invoiceArchetype = !docArchetype ? resolveArchetype(this.archetypes, ARCHETYPE_INVOICE) : undefined;
|
|
365
428
|
const emailArchetype = !docArchetype && !invoiceArchetype ? resolveArchetype(this.archetypes, ARCHETYPE_EMAIL) : undefined;
|
|
366
|
-
|
|
429
|
+
const memoArchetype = !docArchetype && !invoiceArchetype && !emailArchetype ? resolveArchetype(this.archetypes, ARCHETYPE_MEMO) : undefined;
|
|
430
|
+
const anyArchetype = docArchetype || invoiceArchetype || emailArchetype || memoArchetype;
|
|
431
|
+
return (h(Host, { key: '730654d745992b9607f15fcaf2bb54a725429e4d' }, h("div", { key: '72a2e7bb767992aa6f206a10f8b2a3a572e86115', class: "mrd-layout-section" }, docArchetype && this.renderDocumentObject(docArchetype), invoiceArchetype && this.renderInvoiceObject(invoiceArchetype), emailArchetype && this.renderEmailObject(emailArchetype), memoArchetype && this.renderMemoObject(memoArchetype), !anyArchetype && this.items.map(item => this.renderItem(item))), this.renderImageModal()));
|
|
367
432
|
}
|
|
368
433
|
static get is() { return "mrd-layout-section"; }
|
|
369
434
|
static get encapsulation() { return "scoped"; }
|
|
@@ -543,6 +608,31 @@ export class MrdLayoutSection {
|
|
|
543
608
|
"reflect": false,
|
|
544
609
|
"attribute": "read-only",
|
|
545
610
|
"defaultValue": "false"
|
|
611
|
+
},
|
|
612
|
+
"me": {
|
|
613
|
+
"type": "unknown",
|
|
614
|
+
"mutable": false,
|
|
615
|
+
"complexType": {
|
|
616
|
+
"original": "RelationSearchResult | null",
|
|
617
|
+
"resolved": "RelationSearchResult | null",
|
|
618
|
+
"references": {
|
|
619
|
+
"RelationSearchResult": {
|
|
620
|
+
"location": "import",
|
|
621
|
+
"path": "../../../types/client-layout",
|
|
622
|
+
"id": "src/types/client-layout.ts::RelationSearchResult",
|
|
623
|
+
"referenceLocation": "RelationSearchResult"
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
},
|
|
627
|
+
"required": false,
|
|
628
|
+
"optional": false,
|
|
629
|
+
"docs": {
|
|
630
|
+
"tags": [],
|
|
631
|
+
"text": "The active account's linked person record (userProfile.links.person), if any.\nThreaded to mrd-memo-container so a top-level memo VIEW (no parent record to\nattach a new memo to) can still offer \"New memo\" by falling back to the\naccount's own record as the container."
|
|
632
|
+
},
|
|
633
|
+
"getter": false,
|
|
634
|
+
"setter": false,
|
|
635
|
+
"defaultValue": "null"
|
|
546
636
|
}
|
|
547
637
|
};
|
|
548
638
|
}
|
|
@@ -743,6 +833,21 @@ export class MrdLayoutSection {
|
|
|
743
833
|
}
|
|
744
834
|
}
|
|
745
835
|
}
|
|
836
|
+
}, {
|
|
837
|
+
"method": "mrdDeleteObject",
|
|
838
|
+
"name": "mrdDeleteObject",
|
|
839
|
+
"bubbles": true,
|
|
840
|
+
"cancelable": true,
|
|
841
|
+
"composed": true,
|
|
842
|
+
"docs": {
|
|
843
|
+
"tags": [],
|
|
844
|
+
"text": "Confirmed delete from an embedded memo dialog. Host DELETEs `href` \u2014 fire-\nand-forget, the row is already removed optimistically on the component side."
|
|
845
|
+
},
|
|
846
|
+
"complexType": {
|
|
847
|
+
"original": "{ href: string }",
|
|
848
|
+
"resolved": "{ href: string; }",
|
|
849
|
+
"references": {}
|
|
850
|
+
}
|
|
746
851
|
}, {
|
|
747
852
|
"method": "mrdViewUpload",
|
|
748
853
|
"name": "mrdViewUpload",
|
|
@@ -858,6 +963,10 @@ export class MrdLayoutSection {
|
|
|
858
963
|
"HTMLMrdTableElement": {
|
|
859
964
|
"location": "global",
|
|
860
965
|
"id": "global::HTMLMrdTableElement"
|
|
966
|
+
},
|
|
967
|
+
"HTMLMrdMemoListElement": {
|
|
968
|
+
"location": "global",
|
|
969
|
+
"id": "global::HTMLMrdMemoListElement"
|
|
861
970
|
}
|
|
862
971
|
},
|
|
863
972
|
"return": "Promise<void>"
|
|
@@ -984,12 +1093,16 @@ export class MrdLayoutSection {
|
|
|
984
1093
|
"HTMLMrdDocumentListElement": {
|
|
985
1094
|
"location": "global",
|
|
986
1095
|
"id": "global::HTMLMrdDocumentListElement"
|
|
1096
|
+
},
|
|
1097
|
+
"HTMLMrdMemoContainerElement": {
|
|
1098
|
+
"location": "global",
|
|
1099
|
+
"id": "global::HTMLMrdMemoContainerElement"
|
|
987
1100
|
}
|
|
988
1101
|
},
|
|
989
1102
|
"return": "Promise<void>"
|
|
990
1103
|
},
|
|
991
1104
|
"docs": {
|
|
992
|
-
"text": "Inject the created document's href after a file-drop create, so the\noptimistic row becomes navigable (see mrdCreateObject).",
|
|
1105
|
+
"text": "Inject the created document's href after a file-drop create, so the\noptimistic row becomes navigable (see mrdCreateObject). For a memo\nquick-create there is no optimistic row to resolve \u2014 simply reload the\ncontainer's current body so the new memo shows up.",
|
|
993
1106
|
"tags": []
|
|
994
1107
|
}
|
|
995
1108
|
},
|