@mmlogic/components 0.5.3 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{cell-renderer-7KX9Qbml.js → cell-renderer-Mx3pwONr.js} +261 -0
- 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 +391 -77
- package/dist/cjs/mrd-merge-view.cjs.entry.js +3 -3
- package/dist/collection/components/documents/mrd-document-container/mrd-document-container.css +3 -0
- package/dist/collection/components/documents/mrd-document-container/mrd-document-container.js +23 -3
- package/dist/collection/components/documents/mrd-document-list/mrd-document-list.js +76 -2
- package/dist/collection/components/fields/mrd-currency-field/mrd-currency-field.js +56 -5
- package/dist/collection/components/fields/mrd-date-field/mrd-date-field.css +55 -4
- package/dist/collection/components/fields/mrd-date-field/mrd-date-field.js +118 -8
- package/dist/collection/components/fields/mrd-datetime-field/mrd-datetime-field.css +55 -4
- package/dist/collection/components/fields/mrd-datetime-field/mrd-datetime-field.js +117 -15
- 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.js +1 -1
- package/dist/collection/components/fields/mrd-image-field/mrd-image-field.js +1 -1
- 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 +33 -8
- package/dist/collection/components/fields/mrd-relation-field/mrd-relation-field.js +13 -3
- 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 +11 -11
- package/dist/collection/components/form/mrd-form/mrd-form.js +8 -4
- package/dist/collection/components/invoice/mrd-invoice-view/mrd-invoice-view.js +1 -1
- package/dist/collection/components/layout/mrd-layout-section/field-value.js +4 -2
- package/dist/collection/components/layout/mrd-layout-section/layout-helpers.js +6 -0
- package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.css +4 -0
- package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.js +8 -8
- package/dist/collection/components/merge/mrd-merge-view/mrd-merge-view.js +2 -2
- package/dist/collection/dev/app.js +58 -13
- package/dist/collection/dev/example-data.js +6 -1
- package/dist/collection/utils/format.js +160 -0
- package/dist/collection/utils/i18n.js +96 -0
- package/dist/components/cell-renderer.js +1 -1
- package/dist/components/format.js +1 -1
- package/dist/components/i18n.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-container2.js +1 -1
- package/dist/components/mrd-document-list2.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-view2.js +1 -1
- 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-view2.js +1 -1
- 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-relation-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 -1
- package/dist/components/mrd-time-field2.js +1 -1
- package/dist/esm/{cell-renderer-DIsNX9D7.js → cell-renderer-UQOYlDv7.js} +257 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/mosterdcomponents.js +1 -1
- package/dist/esm/mrd-boolean-field_25.entry.js +391 -77
- package/dist/esm/mrd-merge-view.entry.js +3 -3
- package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
- package/dist/mosterdcomponents/p-8cc374e0.entry.js +3 -0
- package/dist/mosterdcomponents/p-CF--ScWr.js +1 -0
- package/dist/mosterdcomponents/{p-4e061416.entry.js → p-d31b71d9.entry.js} +1 -1
- package/dist/types/components/documents/mrd-document-container/mrd-document-container.d.ts +7 -0
- package/dist/types/components/documents/mrd-document-list/mrd-document-list.d.ts +17 -0
- package/dist/types/components/fields/mrd-currency-field/mrd-currency-field.d.ts +13 -0
- package/dist/types/components/fields/mrd-date-field/mrd-date-field.d.ts +22 -1
- package/dist/types/components/fields/mrd-datetime-field/mrd-datetime-field.d.ts +21 -2
- package/dist/types/components/fields/mrd-number-field/mrd-number-field.d.ts +6 -0
- package/dist/types/components/fields/mrd-relation-field/mrd-relation-field.d.ts +7 -0
- package/dist/types/components/form/mrd-form/mrd-form.d.ts +3 -2
- package/dist/types/components/layout/mrd-layout-section/layout-helpers.d.ts +3 -0
- package/dist/types/components.d.ts +35 -0
- package/dist/types/types/client-layout.d.ts +7 -0
- package/dist/types/utils/format.d.ts +34 -0
- package/package.json +1 -1
- package/dist/mosterdcomponents/p-910ebfee.entry.js +0 -3
- package/dist/mosterdcomponents/p-Ce2QDq0t.js +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var index = require('./index-DVbdkYO3.js');
|
|
4
4
|
var clientLayout = require('./client-layout-CqVuJumR.js');
|
|
5
|
-
var cellRenderer = require('./cell-renderer-
|
|
5
|
+
var cellRenderer = require('./cell-renderer-Mx3pwONr.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: 'b965c21176faf7844e58cb156958fa1305d07cdc', 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: 'e9cffda6c5cff51f802b044f3d8e417df83b7846' }, index.h("div", { key: '26690ef2db7489cbf7994191ad19491a0fdd7002', class: "mrd-merge-view" }, stepContent)));
|
|
268
268
|
}
|
|
269
269
|
get el() { return index.getElement(this); }
|
|
270
270
|
};
|
package/dist/collection/components/documents/mrd-document-container/mrd-document-container.js
CHANGED
|
@@ -32,12 +32,28 @@ export class MrdDocumentContainer {
|
|
|
32
32
|
this.mode = 'tree';
|
|
33
33
|
/** Whether the folder tree currently has a valid target for "New folder". */
|
|
34
34
|
this.canCreate = false;
|
|
35
|
+
/** Name of that target (folder path, or the container's label), for the upload tooltip. */
|
|
36
|
+
this.targetLabel = '';
|
|
35
37
|
/** Whether the currently mounted table has been init()'d. Reset on every mode switch. */
|
|
36
38
|
this.tableInited = false;
|
|
37
39
|
this.createFolder = () => {
|
|
38
40
|
var _a;
|
|
39
41
|
(_a = this.listEl) === null || _a === void 0 ? void 0 : _a.createFolder();
|
|
40
42
|
};
|
|
43
|
+
this.pickFile = () => {
|
|
44
|
+
var _a;
|
|
45
|
+
(_a = this.fileInputEl) === null || _a === void 0 ? void 0 : _a.click();
|
|
46
|
+
};
|
|
47
|
+
/** One file per upload, matching the drop handler. Reset the input afterwards
|
|
48
|
+
* so picking the same file twice in a row still fires a change event. */
|
|
49
|
+
this.onFilePicked = (e) => {
|
|
50
|
+
var _a, _b;
|
|
51
|
+
const input = e.target;
|
|
52
|
+
const file = (_a = input.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
53
|
+
if (file)
|
|
54
|
+
(_b = this.listEl) === null || _b === void 0 ? void 0 : _b.uploadFile(file);
|
|
55
|
+
input.value = '';
|
|
56
|
+
};
|
|
41
57
|
}
|
|
42
58
|
/** The embedded table does not self-load: like every mrd-table it waits for the
|
|
43
59
|
* host to call init() (which emits mrdLoadPage, and — once page 0 lands —
|
|
@@ -62,7 +78,7 @@ export class MrdDocumentContainer {
|
|
|
62
78
|
}
|
|
63
79
|
// ── Toolbar ────────────────────────────────────────────────────────────────
|
|
64
80
|
renderToolbar() {
|
|
65
|
-
return (h("div", { class: "mrd-document-container__toolbar" }, this.mode === 'tree' && (h("button", { type: "button", class: "mrd-document-container__action", disabled: !this.canCreate, onClick: this.createFolder }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("path", { d: "M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }), h("path", { d: "M12 11v4M10 13h4" })), t('new_folder', this.locale))), h("div", { class: "mrd-document-container__seg", role: "group", "aria-label": t('doc_view_switch', this.locale) }, h("button", { class: "mrd-document-container__seg-btn", "aria-pressed": String(this.mode === 'tree'), title: t('doc_view_tree', this.locale), "aria-label": t('doc_view_tree', this.locale), onClick: () => this.setMode('tree') }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("path", { d: "M3 5h6M3 12h9M3 19h6" }), h("circle", { cx: "18", cy: "5", r: "1.6" }), h("circle", { cx: "18", cy: "19", r: "1.6" }), h("path", { d: "M16 12h4" }))), h("button", { class: "mrd-document-container__seg-btn", "aria-pressed": String(this.mode === 'list'), title: t('doc_view_list', this.locale), "aria-label": t('doc_view_list', this.locale), onClick: () => this.setMode('list') }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("path", { d: "M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" }))))));
|
|
81
|
+
return (h("div", { class: "mrd-document-container__toolbar" }, this.mode === 'tree' && (h("button", { type: "button", class: "mrd-document-container__action", disabled: !this.canCreate, onClick: this.createFolder }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("path", { d: "M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }), h("path", { d: "M12 11v4M10 13h4" })), t('new_folder', this.locale))), this.mode === 'tree' && (h("button", { type: "button", class: "mrd-document-container__action", disabled: !this.canCreate, title: this.targetLabel ? `${t('doc_upload_to', this.locale)} ${this.targetLabel}` : undefined, onClick: this.pickFile }, h("svg", { 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 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), h("path", { d: "M12 3v13M7 8l5-5 5 5" })), t('doc_upload', this.locale))), h("input", { type: "file", class: "mrd-document-container__file-input", ref: el => (this.fileInputEl = el), onChange: this.onFilePicked }), h("div", { class: "mrd-document-container__seg", role: "group", "aria-label": t('doc_view_switch', this.locale) }, h("button", { class: "mrd-document-container__seg-btn", "aria-pressed": String(this.mode === 'tree'), title: t('doc_view_tree', this.locale), "aria-label": t('doc_view_tree', this.locale), onClick: () => this.setMode('tree') }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("path", { d: "M3 5h6M3 12h9M3 19h6" }), h("circle", { cx: "18", cy: "5", r: "1.6" }), h("circle", { cx: "18", cy: "19", r: "1.6" }), h("path", { d: "M16 12h4" }))), h("button", { class: "mrd-document-container__seg-btn", "aria-pressed": String(this.mode === 'list'), title: t('doc_view_list', this.locale), "aria-label": t('doc_view_list', this.locale), onClick: () => this.setMode('list') }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("path", { d: "M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" }))))));
|
|
66
82
|
}
|
|
67
83
|
// ── Bodies ───────────────────────────────────────────────────────────────
|
|
68
84
|
renderTree() {
|
|
@@ -78,6 +94,9 @@ export class MrdDocumentContainer {
|
|
|
78
94
|
}, onMrdCanCreate: (e) => {
|
|
79
95
|
e.stopPropagation();
|
|
80
96
|
this.canCreate = e.detail;
|
|
97
|
+
}, onMrdTargetLabel: (e) => {
|
|
98
|
+
e.stopPropagation();
|
|
99
|
+
this.targetLabel = e.detail;
|
|
81
100
|
}, onMrdUpdateObject: (e) => {
|
|
82
101
|
e.stopPropagation();
|
|
83
102
|
this.mrdUpdateObject.emit(e.detail);
|
|
@@ -114,7 +133,7 @@ export class MrdDocumentContainer {
|
|
|
114
133
|
}
|
|
115
134
|
render() {
|
|
116
135
|
const treeMode = this.mode === 'tree';
|
|
117
|
-
return (h(Host, { key: '
|
|
136
|
+
return (h(Host, { key: 'ae948e2458d9087179e850b527802c489067d93f' }, this.renderToolbar(), h("div", { key: 'a04e1a78413aa794d0bda551aeb9c6245f1aafa2', class: {
|
|
118
137
|
'mrd-document-container__body': true,
|
|
119
138
|
'mrd-document-container__body--tree': treeMode,
|
|
120
139
|
}, style: treeMode ? { height: `${this.height}px`, overflowY: 'auto' } : {} }, treeMode ? this.renderTree() : this.renderList())));
|
|
@@ -287,7 +306,8 @@ export class MrdDocumentContainer {
|
|
|
287
306
|
static get states() {
|
|
288
307
|
return {
|
|
289
308
|
"mode": {},
|
|
290
|
-
"canCreate": {}
|
|
309
|
+
"canCreate": {},
|
|
310
|
+
"targetLabel": {}
|
|
291
311
|
};
|
|
292
312
|
}
|
|
293
313
|
static get events() {
|
|
@@ -64,6 +64,8 @@ export class MrdDocumentList {
|
|
|
64
64
|
this.newFolderSeq = 0;
|
|
65
65
|
/** Last emitted canCreateFolder value, to only emit mrdCanCreate on change. */
|
|
66
66
|
this.lastCanCreate = false;
|
|
67
|
+
/** Last emitted upload-target label, to only emit mrdTargetLabel on change. */
|
|
68
|
+
this.lastTargetLabel = '';
|
|
67
69
|
// ── Drag & drop (move a document into another folder) ──────────────────────
|
|
68
70
|
/** The document row currently being dragged. */
|
|
69
71
|
this.dragDoc = null;
|
|
@@ -237,6 +239,22 @@ export class MrdDocumentList {
|
|
|
237
239
|
this.lastCanCreate = can;
|
|
238
240
|
this.mrdCanCreate.emit(can);
|
|
239
241
|
}
|
|
242
|
+
const label = this.targetLabel;
|
|
243
|
+
if (label !== this.lastTargetLabel) {
|
|
244
|
+
this.lastTargetLabel = label;
|
|
245
|
+
this.mrdTargetLabel.emit(label);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/** Human-readable name of the node a new folder or upload lands in — the
|
|
249
|
+
* folder path when one is selected, otherwise the container's own label.
|
|
250
|
+
* Empty when there is no target at all. */
|
|
251
|
+
get targetLabel() {
|
|
252
|
+
var _a;
|
|
253
|
+
const resolved = this.resolveTarget();
|
|
254
|
+
if (!resolved)
|
|
255
|
+
return '';
|
|
256
|
+
const { target, container } = resolved;
|
|
257
|
+
return (_a = folderStringOf(target, container)) !== null && _a !== void 0 ? _a : target.label;
|
|
240
258
|
}
|
|
241
259
|
// ── Slot field names ─────────────────────────────────────────────────────
|
|
242
260
|
get containerField() {
|
|
@@ -510,12 +528,28 @@ export class MrdDocumentList {
|
|
|
510
528
|
this.dropTargetId = null;
|
|
511
529
|
if (!file)
|
|
512
530
|
return;
|
|
531
|
+
this.beginUpload(file, node, container);
|
|
532
|
+
}
|
|
533
|
+
/** Shared by the file drop and the host toolbar's upload button. */
|
|
534
|
+
beginUpload(file, node, container) {
|
|
513
535
|
this.pendingUpload = { file, node, container };
|
|
514
536
|
node.open = true;
|
|
515
537
|
this.uploadingNodeId = node.id;
|
|
516
538
|
this.bump();
|
|
517
539
|
this.mrdUpload.emit({ file });
|
|
518
540
|
}
|
|
541
|
+
/** Upload a file into the current target — the selected folder/container, or
|
|
542
|
+
* the only container when there is just one. Called by the host toolbar
|
|
543
|
+
* (mrd-document-container). No-op without a target, or while another upload
|
|
544
|
+
* is still awaiting its setFileReference. */
|
|
545
|
+
async uploadFile(file) {
|
|
546
|
+
if (!file || this.pendingUpload)
|
|
547
|
+
return;
|
|
548
|
+
const resolved = this.resolveTarget();
|
|
549
|
+
if (!resolved)
|
|
550
|
+
return;
|
|
551
|
+
this.beginUpload(file, resolved.target, resolved.container);
|
|
552
|
+
}
|
|
519
553
|
/** Host callback with the uploaded file reference. Builds the create payload
|
|
520
554
|
* from the archetype slots and requests the new document. */
|
|
521
555
|
async setFileReference(uri) {
|
|
@@ -650,7 +684,7 @@ export class MrdDocumentList {
|
|
|
650
684
|
body = renderLoadingRow(ctx, 0);
|
|
651
685
|
}
|
|
652
686
|
else if (this.containers.length === 0) {
|
|
653
|
-
body = h("div", { key: '
|
|
687
|
+
body = h("div", { key: '63604a99fc62d9108f61b8efc126c0cd3e8fc5ed', class: "mrd-document-list__empty" }, t('no_results', this.locale));
|
|
654
688
|
}
|
|
655
689
|
else if (this.singleContainer) {
|
|
656
690
|
// Dossier context: render the single container's folder tree at the root.
|
|
@@ -668,7 +702,7 @@ export class MrdDocumentList {
|
|
|
668
702
|
else {
|
|
669
703
|
body = this.containers.map(c => renderContainerNode(ctx, c, 0));
|
|
670
704
|
}
|
|
671
|
-
return (h(Host, { key: '
|
|
705
|
+
return (h(Host, { key: '2a092e3a7483deb1fb30753b0c0428aaf75c303a' }, h("div", { key: '2b716c912a272b925a95133de5b1ff2abedd9dbc', class: 'mrd-document-list' + (this.rootDropActive ? ' mrd-document-list--drop-active' : ''), onDragOver: this.onRootDragOver, onDragLeave: this.onRootDragLeave, onDrop: this.onRootDrop }, body)));
|
|
672
706
|
}
|
|
673
707
|
static get is() { return "mrd-document-list"; }
|
|
674
708
|
static get encapsulation() { return "scoped"; }
|
|
@@ -880,6 +914,21 @@ export class MrdDocumentList {
|
|
|
880
914
|
"resolved": "boolean",
|
|
881
915
|
"references": {}
|
|
882
916
|
}
|
|
917
|
+
}, {
|
|
918
|
+
"method": "mrdTargetLabel",
|
|
919
|
+
"name": "mrdTargetLabel",
|
|
920
|
+
"bubbles": true,
|
|
921
|
+
"cancelable": true,
|
|
922
|
+
"composed": true,
|
|
923
|
+
"docs": {
|
|
924
|
+
"tags": [],
|
|
925
|
+
"text": "Emitted whenever the current target changes: the folder path a new folder or\nupload lands in, or the container's label when no folder is selected. Empty\nwhen there is no target. Lets a host toolbar name the destination."
|
|
926
|
+
},
|
|
927
|
+
"complexType": {
|
|
928
|
+
"original": "string",
|
|
929
|
+
"resolved": "string",
|
|
930
|
+
"references": {}
|
|
931
|
+
}
|
|
883
932
|
}, {
|
|
884
933
|
"method": "mrdUpdateObject",
|
|
885
934
|
"name": "mrdUpdateObject",
|
|
@@ -1023,6 +1072,31 @@ export class MrdDocumentList {
|
|
|
1023
1072
|
"tags": []
|
|
1024
1073
|
}
|
|
1025
1074
|
},
|
|
1075
|
+
"uploadFile": {
|
|
1076
|
+
"complexType": {
|
|
1077
|
+
"signature": "(file: File) => Promise<void>",
|
|
1078
|
+
"parameters": [{
|
|
1079
|
+
"name": "file",
|
|
1080
|
+
"type": "File",
|
|
1081
|
+
"docs": ""
|
|
1082
|
+
}],
|
|
1083
|
+
"references": {
|
|
1084
|
+
"Promise": {
|
|
1085
|
+
"location": "global",
|
|
1086
|
+
"id": "global::Promise"
|
|
1087
|
+
},
|
|
1088
|
+
"File": {
|
|
1089
|
+
"location": "global",
|
|
1090
|
+
"id": "global::File"
|
|
1091
|
+
}
|
|
1092
|
+
},
|
|
1093
|
+
"return": "Promise<void>"
|
|
1094
|
+
},
|
|
1095
|
+
"docs": {
|
|
1096
|
+
"text": "Upload a file into the current target \u2014 the selected folder/container, or\nthe only container when there is just one. Called by the host toolbar\n(mrd-document-container). No-op without a target, or while another upload\nis still awaiting its setFileReference.",
|
|
1097
|
+
"tags": []
|
|
1098
|
+
}
|
|
1099
|
+
},
|
|
1026
1100
|
"setFileReference": {
|
|
1027
1101
|
"complexType": {
|
|
1028
1102
|
"signature": "(uri: string) => Promise<void>",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Host, h } from "@stencil/core";
|
|
2
|
-
import { parseLocalizedNumber } from "../../../utils/format";
|
|
2
|
+
import { formatNumber, parseLocalizedNumber } from "../../../utils/format";
|
|
3
3
|
import { FieldLabel, FieldError, controlClass, requiredError } from "../field-helpers";
|
|
4
4
|
const COMMON_CURRENCIES = [
|
|
5
5
|
'EUR', 'USD', 'GBP', 'CHF', 'JPY', 'CNY', 'AUD', 'CAD',
|
|
@@ -17,13 +17,26 @@ export class MrdCurrencyField {
|
|
|
17
17
|
this.amountDisplay = '';
|
|
18
18
|
this.currency = 'EUR';
|
|
19
19
|
this.error = '';
|
|
20
|
+
/** While focused the user owns the text; prop updates must not overwrite it. */
|
|
21
|
+
this.focused = false;
|
|
20
22
|
this.handleAmountInput = (e) => {
|
|
21
23
|
this.amountDisplay = e.target.value;
|
|
22
24
|
};
|
|
25
|
+
this.handleAmountFocus = () => {
|
|
26
|
+
this.focused = true;
|
|
27
|
+
// Drop the grouping separators while editing, but keep the locale's decimal
|
|
28
|
+
// separator: String(1234.56) would be re-read as 123456 where '.' groups.
|
|
29
|
+
const parsed = parseLocalizedNumber(this.amountDisplay, this.locale);
|
|
30
|
+
if (parsed !== null) {
|
|
31
|
+
this.amountDisplay = formatNumber(parsed, this.locale, { useGrouping: false, maximumFractionDigits: 20 });
|
|
32
|
+
}
|
|
33
|
+
};
|
|
23
34
|
this.handleAmountBlur = (e) => {
|
|
35
|
+
this.focused = false;
|
|
24
36
|
const raw = e.target.value;
|
|
25
37
|
const parsed = parseLocalizedNumber(raw, this.locale);
|
|
26
38
|
this.error = requiredError(raw, this.required, this.locale);
|
|
39
|
+
this.amountDisplay = parsed !== null ? this.formatAmount(parsed) : '';
|
|
27
40
|
const val = { amount: parsed, currency: this.currency };
|
|
28
41
|
this.mrdChange.emit({ name: this.name, value: val });
|
|
29
42
|
this.mrdBlur.emit({ name: this.name, value: val });
|
|
@@ -35,14 +48,43 @@ export class MrdCurrencyField {
|
|
|
35
48
|
};
|
|
36
49
|
}
|
|
37
50
|
componentWillLoad() {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
51
|
+
this.syncFromValue();
|
|
52
|
+
}
|
|
53
|
+
componentDidRender() {
|
|
54
|
+
// A rendered `selected` attribute is ignored once the select has an established
|
|
55
|
+
// value, so the currency is applied imperatively — same reason as the DROPDOWN
|
|
56
|
+
// preselect in mrd-relation-field. Without this an edit-mode record that loads
|
|
57
|
+
// after mount keeps showing EUR and would be saved back with the wrong currency.
|
|
58
|
+
if (this.selectEl && this.selectEl.value !== this.currency) {
|
|
59
|
+
this.selectEl.value = this.currency;
|
|
41
60
|
}
|
|
42
61
|
}
|
|
62
|
+
/** The record's own currency may sit outside the common list; never drop it. */
|
|
63
|
+
currencyOptions() {
|
|
64
|
+
return COMMON_CURRENCIES.includes(this.currency) ? COMMON_CURRENCIES : [this.currency, ...COMMON_CURRENCIES];
|
|
65
|
+
}
|
|
66
|
+
/** Edit mode loads the record after mount, so the incoming value must re-sync. */
|
|
67
|
+
valueChanged() {
|
|
68
|
+
if (!this.focused)
|
|
69
|
+
this.syncFromValue();
|
|
70
|
+
}
|
|
71
|
+
localeChanged() {
|
|
72
|
+
if (!this.focused)
|
|
73
|
+
this.syncFromValue();
|
|
74
|
+
}
|
|
75
|
+
syncFromValue() {
|
|
76
|
+
const value = this.value;
|
|
77
|
+
this.currency = (value === null || value === void 0 ? void 0 : value.currency) || 'EUR';
|
|
78
|
+
this.amountDisplay =
|
|
79
|
+
(value === null || value === void 0 ? void 0 : value.amount) !== null && (value === null || value === void 0 ? void 0 : value.amount) !== undefined ? this.formatAmount(value.amount) : '';
|
|
80
|
+
}
|
|
81
|
+
/** Display form: locale separators, always two decimals. The ISO code sits in the select. */
|
|
82
|
+
formatAmount(amount) {
|
|
83
|
+
return formatNumber(amount, this.locale, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
84
|
+
}
|
|
43
85
|
render() {
|
|
44
86
|
const hasError = !!this.error;
|
|
45
|
-
return (h(Host, { key: '
|
|
87
|
+
return (h(Host, { key: '43ef1fe660c4eaef025203544916b077975b6aa3' }, h("div", { key: '00b8e79182c8e2a353d57ad5c341024caf00d4ea', class: "mrd-currency-field" }, h(FieldLabel, { key: '96835c311e0d490864c484b818f1dcc623f488b2', base: "mrd-currency-field", label: this.label, required: this.required }), h("div", { key: '80317cfe562af00cc4cbf9aabf4bac2126cf6fe5', class: "mrd-currency-field__row" }, h("input", { key: '1983ef1e4d19e0fc529cf5e8be7d287fea36620a', class: controlClass('mrd-currency-field', hasError, 'amount'), type: "text", inputMode: "decimal", name: `${this.name}_amount`, value: this.amountDisplay, placeholder: this.formatAmount(0), required: this.required, disabled: this.disabled, onInput: this.handleAmountInput, onFocus: this.handleAmountFocus, onBlur: this.handleAmountBlur }), h("select", { key: 'b5fe3f03590bebaa564d76bc5fcb47c327eacece', class: "mrd-currency-field__currency", ref: el => (this.selectEl = el), disabled: this.disabled, onChange: this.handleCurrencyChange }, this.currencyOptions().map(c => (h("option", { key: c, value: c, selected: c === this.currency }, c))))), h(FieldError, { key: '1a128b26293170d4137f787622d4e89a23e62c0b', base: "mrd-currency-field", error: this.error }))));
|
|
46
88
|
}
|
|
47
89
|
static get is() { return "mrd-currency-field"; }
|
|
48
90
|
static get encapsulation() { return "scoped"; }
|
|
@@ -239,4 +281,13 @@ export class MrdCurrencyField {
|
|
|
239
281
|
}
|
|
240
282
|
}];
|
|
241
283
|
}
|
|
284
|
+
static get watchers() {
|
|
285
|
+
return [{
|
|
286
|
+
"propName": "value",
|
|
287
|
+
"methodName": "valueChanged"
|
|
288
|
+
}, {
|
|
289
|
+
"propName": "locale",
|
|
290
|
+
"methodName": "localeChanged"
|
|
291
|
+
}];
|
|
292
|
+
}
|
|
242
293
|
}
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
content: " *";
|
|
20
20
|
color: var(--mrd-color-danger);
|
|
21
21
|
}
|
|
22
|
+
.mrd-date-field__control {
|
|
23
|
+
position: relative;
|
|
24
|
+
display: block;
|
|
25
|
+
}
|
|
22
26
|
.mrd-date-field__input {
|
|
23
27
|
display: block;
|
|
24
28
|
width: 100%;
|
|
@@ -53,12 +57,59 @@
|
|
|
53
57
|
.mrd-date-field__input--error:focus {
|
|
54
58
|
box-shadow: var(--mrd-shadow-focus-error);
|
|
55
59
|
}
|
|
60
|
+
.mrd-date-field__input {
|
|
61
|
+
padding-inline-end: calc(var(--mrd-input-padding-x) + 1.75rem);
|
|
62
|
+
}
|
|
63
|
+
.mrd-date-field__picker {
|
|
64
|
+
position: absolute;
|
|
65
|
+
inset-inline-end: var(--mrd-space-1);
|
|
66
|
+
top: 50%;
|
|
67
|
+
transform: translateY(-50%);
|
|
68
|
+
width: 1.75rem;
|
|
69
|
+
height: 1.75rem;
|
|
70
|
+
}
|
|
71
|
+
.mrd-date-field__picker-button {
|
|
72
|
+
display: inline-flex;
|
|
73
|
+
align-items: center;
|
|
74
|
+
justify-content: center;
|
|
75
|
+
width: 100%;
|
|
76
|
+
height: 100%;
|
|
77
|
+
padding: 0;
|
|
78
|
+
border: 0;
|
|
79
|
+
border-radius: var(--mrd-border-radius-sm);
|
|
80
|
+
background: transparent;
|
|
81
|
+
color: var(--mrd-color-neutral-500);
|
|
82
|
+
cursor: pointer;
|
|
83
|
+
transition: color var(--mrd-transition), background-color var(--mrd-transition);
|
|
84
|
+
}
|
|
85
|
+
.mrd-date-field__picker-button svg {
|
|
86
|
+
width: 1.125rem;
|
|
87
|
+
height: 1.125rem;
|
|
88
|
+
}
|
|
89
|
+
.mrd-date-field__picker-button:hover:not(:disabled) {
|
|
90
|
+
color: var(--mrd-color-primary);
|
|
91
|
+
background-color: var(--mrd-color-neutral-100);
|
|
92
|
+
}
|
|
93
|
+
.mrd-date-field__picker-button:focus-visible {
|
|
94
|
+
outline: 2px solid var(--mrd-border-color-focus);
|
|
95
|
+
outline-offset: 1px;
|
|
96
|
+
}
|
|
97
|
+
.mrd-date-field__picker-button:disabled {
|
|
98
|
+
cursor: not-allowed;
|
|
99
|
+
opacity: 0.5;
|
|
100
|
+
}
|
|
101
|
+
.mrd-date-field__picker-native {
|
|
102
|
+
position: absolute;
|
|
103
|
+
inset: 0;
|
|
104
|
+
width: 100%;
|
|
105
|
+
height: 100%;
|
|
106
|
+
padding: 0;
|
|
107
|
+
border: 0;
|
|
108
|
+
opacity: 0;
|
|
109
|
+
pointer-events: none;
|
|
110
|
+
}
|
|
56
111
|
.mrd-date-field__error {
|
|
57
112
|
font-family: var(--mrd-font-family);
|
|
58
113
|
font-size: var(--mrd-error-font-size);
|
|
59
114
|
color: var(--mrd-error-color);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
.mrd-date-field__input {
|
|
63
|
-
cursor: pointer;
|
|
64
115
|
}
|
|
@@ -1,26 +1,106 @@
|
|
|
1
1
|
import { Host, h } from "@stencil/core";
|
|
2
|
+
import { t } from "../../../utils/i18n";
|
|
3
|
+
import { formatIsoDate, localeDatePattern, parseLocalizedDate } from "../../../utils/format";
|
|
2
4
|
import { FieldLabel, FieldError, controlClass, requiredError } from "../field-helpers";
|
|
3
5
|
export class MrdDateField {
|
|
4
6
|
constructor() {
|
|
5
7
|
this.name = '';
|
|
6
8
|
this.label = '';
|
|
9
|
+
/** ISO date, 'YYYY-MM-DD'. */
|
|
7
10
|
this.value = '';
|
|
11
|
+
/** Overrides the locale-derived pattern placeholder (e.g. 'dd-mm-jjjj'). */
|
|
12
|
+
this.placeholder = '';
|
|
8
13
|
this.required = false;
|
|
9
14
|
this.disabled = false;
|
|
10
15
|
this.locale = navigator.language;
|
|
16
|
+
/** What the user sees: the value formatted for `locale`, or their raw typing. */
|
|
17
|
+
this.displayValue = '';
|
|
11
18
|
this.error = '';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.
|
|
19
|
+
/** While focused the user owns the text; prop updates must not overwrite it. */
|
|
20
|
+
this.focused = false;
|
|
21
|
+
this.handleFocus = () => {
|
|
22
|
+
this.focused = true;
|
|
23
|
+
};
|
|
24
|
+
this.handleInput = (e) => {
|
|
25
|
+
this.displayValue = e.target.value;
|
|
16
26
|
};
|
|
17
27
|
this.handleBlur = (e) => {
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
this.focused = false;
|
|
29
|
+
const value = this.commit(e.target.value);
|
|
30
|
+
this.mrdChange.emit({ name: this.name, value });
|
|
31
|
+
this.mrdBlur.emit({ name: this.name, value });
|
|
32
|
+
};
|
|
33
|
+
this.handleKeyDown = (e) => {
|
|
34
|
+
// Submitting with Enter never fires blur, so commit the typed text here too.
|
|
35
|
+
if (e.key !== 'Enter')
|
|
36
|
+
return;
|
|
37
|
+
const value = this.commit(e.target.value);
|
|
38
|
+
this.mrdChange.emit({ name: this.name, value });
|
|
39
|
+
};
|
|
40
|
+
this.openPicker = () => {
|
|
41
|
+
const native = this.nativeInput;
|
|
42
|
+
if (!native || this.disabled)
|
|
43
|
+
return;
|
|
44
|
+
// The blur commit that precedes this click re-renders asynchronously, so sync by hand first.
|
|
45
|
+
native.value = this.currentIso();
|
|
46
|
+
try {
|
|
47
|
+
native.showPicker();
|
|
48
|
+
}
|
|
49
|
+
catch (_a) {
|
|
50
|
+
// Browsers without showPicker(): focusing at least surfaces the platform control.
|
|
51
|
+
native.focus();
|
|
52
|
+
}
|
|
20
53
|
};
|
|
54
|
+
this.handlePickerChange = (e) => {
|
|
55
|
+
const iso = e.target.value; // native inputs always yield 'YYYY-MM-DD'
|
|
56
|
+
this.displayValue = formatIsoDate(iso, this.locale);
|
|
57
|
+
this.error = requiredError(iso, this.required, this.locale);
|
|
58
|
+
this.mrdChange.emit({ name: this.name, value: iso });
|
|
59
|
+
this.mrdBlur.emit({ name: this.name, value: iso });
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
componentWillLoad() {
|
|
63
|
+
this.displayValue = formatIsoDate(this.value, this.locale);
|
|
64
|
+
}
|
|
65
|
+
valueChanged(newValue) {
|
|
66
|
+
if (!this.focused)
|
|
67
|
+
this.displayValue = formatIsoDate(newValue, this.locale);
|
|
68
|
+
}
|
|
69
|
+
localeChanged() {
|
|
70
|
+
if (!this.focused)
|
|
71
|
+
this.displayValue = formatIsoDate(this.value, this.locale);
|
|
72
|
+
}
|
|
73
|
+
patternPlaceholder() {
|
|
74
|
+
if (this.placeholder)
|
|
75
|
+
return this.placeholder;
|
|
76
|
+
return localeDatePattern(this.locale, {
|
|
77
|
+
day: t('date_token_day', this.locale),
|
|
78
|
+
month: t('date_token_month', this.locale),
|
|
79
|
+
year: t('date_token_year', this.locale),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/** Parse the typed text, reformat it, and emit the ISO value. */
|
|
83
|
+
commit(raw) {
|
|
84
|
+
const trimmed = raw.trim();
|
|
85
|
+
const iso = trimmed ? parseLocalizedDate(trimmed, this.locale) : '';
|
|
86
|
+
if (trimmed && iso === null) {
|
|
87
|
+
// Keep the raw text so the user can correct it instead of retyping.
|
|
88
|
+
this.error = t('invalid_date', this.locale);
|
|
89
|
+
this.displayValue = trimmed;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
this.error = requiredError(iso, this.required, this.locale);
|
|
93
|
+
this.displayValue = iso ? formatIsoDate(iso, this.locale) : '';
|
|
94
|
+
}
|
|
95
|
+
return iso !== null && iso !== void 0 ? iso : '';
|
|
96
|
+
}
|
|
97
|
+
/** The ISO value currently shown, so the picker opens on the right date. */
|
|
98
|
+
currentIso() {
|
|
99
|
+
var _a;
|
|
100
|
+
return (_a = (this.displayValue ? parseLocalizedDate(this.displayValue, this.locale) : '')) !== null && _a !== void 0 ? _a : '';
|
|
21
101
|
}
|
|
22
102
|
render() {
|
|
23
|
-
return (h(Host, { key: '
|
|
103
|
+
return (h(Host, { key: '06ba48bd538ee4c8de4e071285535451f783c259' }, h("div", { key: '73ea6ea23c85fe3325bb151afb755cc11a13cf58', class: "mrd-date-field" }, h(FieldLabel, { key: '527848cf72323aef176fc7d5bcd47dcf2f7e46f6', base: "mrd-date-field", label: this.label, required: this.required }), h("div", { key: '2ff7586f4e6298d1f9b9b131106044533de82c6d', class: "mrd-date-field__control" }, h("input", { key: '68fdf2f1f7961ca049ab6493494c8c0707e6a4af', class: controlClass('mrd-date-field', !!this.error), type: "text", name: this.name, value: this.displayValue, placeholder: this.patternPlaceholder(), autocomplete: "off", required: this.required, disabled: this.disabled, onFocus: this.handleFocus, onInput: this.handleInput, onBlur: this.handleBlur, onKeyDown: this.handleKeyDown }), h("span", { key: '9557b7a3f6780b8a05030ab8e7c941c44df9f4a5', class: "mrd-date-field__picker" }, h("button", { key: '586973e0440ed0b74e1fa0affae9e462257024c3', type: "button", class: "mrd-date-field__picker-button", title: t('open_calendar', this.locale), "aria-label": t('open_calendar', this.locale), disabled: this.disabled, onClick: this.openPicker }, h("svg", { key: '144319d3a50d0d38c75c59dd3321d4b9097322a6', viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "aria-hidden": "true" }, h("rect", { key: 'aec01ca5c620bf3116705b7a28052eb3bc210cfd', x: "3", y: "4.5", width: "14", height: "12", rx: "2" }), h("path", { key: 'a0e13dd3a2005bfbee40f5a071b6760270d0d58d', d: "M3 8.5h14M7 2.5v3M13 2.5v3", "stroke-linecap": "round" }))), h("input", { key: 'be02df44f31a59a26ce166ab9a9eab9db2635d89', class: "mrd-date-field__picker-native", type: "date", ref: el => (this.nativeInput = el), value: this.currentIso(), disabled: this.disabled, tabIndex: -1, "aria-hidden": "true", onChange: this.handlePickerChange }))), h(FieldError, { key: '2f8b2072bee32170a35f98ec5c962018774c7e8c', base: "mrd-date-field", error: this.error }))));
|
|
24
104
|
}
|
|
25
105
|
static get is() { return "mrd-date-field"; }
|
|
26
106
|
static get encapsulation() { return "scoped"; }
|
|
@@ -88,7 +168,7 @@ export class MrdDateField {
|
|
|
88
168
|
"optional": false,
|
|
89
169
|
"docs": {
|
|
90
170
|
"tags": [],
|
|
91
|
-
"text": ""
|
|
171
|
+
"text": "ISO date, 'YYYY-MM-DD'."
|
|
92
172
|
},
|
|
93
173
|
"getter": false,
|
|
94
174
|
"setter": false,
|
|
@@ -96,6 +176,26 @@ export class MrdDateField {
|
|
|
96
176
|
"attribute": "value",
|
|
97
177
|
"defaultValue": "''"
|
|
98
178
|
},
|
|
179
|
+
"placeholder": {
|
|
180
|
+
"type": "string",
|
|
181
|
+
"mutable": false,
|
|
182
|
+
"complexType": {
|
|
183
|
+
"original": "string",
|
|
184
|
+
"resolved": "string",
|
|
185
|
+
"references": {}
|
|
186
|
+
},
|
|
187
|
+
"required": false,
|
|
188
|
+
"optional": false,
|
|
189
|
+
"docs": {
|
|
190
|
+
"tags": [],
|
|
191
|
+
"text": "Overrides the locale-derived pattern placeholder (e.g. 'dd-mm-jjjj')."
|
|
192
|
+
},
|
|
193
|
+
"getter": false,
|
|
194
|
+
"setter": false,
|
|
195
|
+
"reflect": false,
|
|
196
|
+
"attribute": "placeholder",
|
|
197
|
+
"defaultValue": "''"
|
|
198
|
+
},
|
|
99
199
|
"required": {
|
|
100
200
|
"type": "boolean",
|
|
101
201
|
"mutable": false,
|
|
@@ -160,6 +260,7 @@ export class MrdDateField {
|
|
|
160
260
|
}
|
|
161
261
|
static get states() {
|
|
162
262
|
return {
|
|
263
|
+
"displayValue": {},
|
|
163
264
|
"error": {}
|
|
164
265
|
};
|
|
165
266
|
}
|
|
@@ -196,4 +297,13 @@ export class MrdDateField {
|
|
|
196
297
|
}
|
|
197
298
|
}];
|
|
198
299
|
}
|
|
300
|
+
static get watchers() {
|
|
301
|
+
return [{
|
|
302
|
+
"propName": "value",
|
|
303
|
+
"methodName": "valueChanged"
|
|
304
|
+
}, {
|
|
305
|
+
"propName": "locale",
|
|
306
|
+
"methodName": "localeChanged"
|
|
307
|
+
}];
|
|
308
|
+
}
|
|
199
309
|
}
|