@mmlogic/components 0.3.9 → 0.3.11
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/loader.cjs.js +1 -1
- package/dist/cjs/mosterdcomponents.cjs.js +1 -1
- package/dist/cjs/{mrd-boolean-field_22.cjs.entry.js → mrd-boolean-field_23.cjs.entry.js} +684 -41
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/mrd-document-container/mrd-document-container.js +421 -0
- package/dist/collection/components/mrd-document-container/mrd-document-container.scss +79 -0
- package/dist/collection/components/mrd-document-list/mrd-document-list.js +653 -16
- package/dist/collection/components/mrd-document-list/mrd-document-list.scss +66 -0
- package/dist/collection/components/mrd-document-view/mrd-document-view.js +1 -1
- package/dist/collection/components/mrd-email-field/mrd-email-field.js +1 -1
- package/dist/collection/components/mrd-file-field/mrd-file-field.js +1 -1
- package/dist/collection/components/mrd-image-field/mrd-image-field.js +1 -1
- package/dist/collection/components/mrd-layout-section/mrd-layout-section.js +165 -14
- package/dist/collection/components/mrd-layout-section/mrd-layout-section.scss +0 -44
- package/dist/collection/components/mrd-longtext-field/mrd-longtext-field.js +1 -1
- package/dist/collection/components/mrd-number-field/mrd-number-field.js +1 -1
- package/dist/collection/components/mrd-secret-field/mrd-secret-field.js +2 -2
- package/dist/collection/components/mrd-text-field/mrd-text-field.js +1 -1
- package/dist/collection/components/mrd-textarea-field/mrd-textarea-field.js +1 -1
- package/dist/collection/components/mrd-time-field/mrd-time-field.js +1 -1
- package/dist/collection/dev/app.js +47 -0
- package/dist/collection/utils/i18n.js +12 -0
- package/dist/components/i18n.js +1 -1
- package/dist/components/mrd-document-container.d.ts +11 -0
- package/dist/components/mrd-document-container.js +1 -0
- package/dist/components/mrd-document-container2.js +1 -0
- 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-file-field2.js +1 -1
- package/dist/components/mrd-image-field2.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-number-field2.js +1 -1
- package/dist/components/mrd-secret-field2.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/loader.js +1 -1
- package/dist/esm/mosterdcomponents.js +1 -1
- package/dist/esm/{mrd-boolean-field_22.entry.js → mrd-boolean-field_23.entry.js} +684 -42
- package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
- package/dist/mosterdcomponents/p-a9618055.entry.js +1 -0
- package/dist/types/components/mrd-document-container/mrd-document-container.d.ts +99 -0
- package/dist/types/components/mrd-document-list/mrd-document-list.d.ts +126 -1
- package/dist/types/components/mrd-layout-section/mrd-layout-section.d.ts +32 -5
- package/dist/types/components.d.ts +250 -0
- package/dist/types/types/client-layout.d.ts +5 -0
- package/package.json +1 -1
- package/dist/mosterdcomponents/p-b547291b.entry.js +0 -1
|
@@ -100,6 +100,12 @@ const translations = {
|
|
|
100
100
|
history_until: 'tot',
|
|
101
101
|
history_badge_tooltip: 'Vorige waarden',
|
|
102
102
|
hyperlink_name: 'Linktekst (optioneel)',
|
|
103
|
+
// mrd-document-list
|
|
104
|
+
new_folder: 'Nieuwe folder',
|
|
105
|
+
folder_name_placeholder: 'Foldernaam',
|
|
106
|
+
folder_no_slash: "Een foldernaam mag geen '/' bevatten",
|
|
107
|
+
folder_duplicate: 'Er bestaat al een folder met deze naam',
|
|
108
|
+
doc_empty_drop: 'Nog geen documenten — sleep bestanden hierheen',
|
|
103
109
|
},
|
|
104
110
|
en: {
|
|
105
111
|
required: 'This field is required',
|
|
@@ -166,6 +172,12 @@ const translations = {
|
|
|
166
172
|
history_until: 'until',
|
|
167
173
|
history_badge_tooltip: 'Previous values',
|
|
168
174
|
hyperlink_name: 'Link text (optional)',
|
|
175
|
+
// mrd-document-list
|
|
176
|
+
new_folder: 'New folder',
|
|
177
|
+
folder_name_placeholder: 'Folder name',
|
|
178
|
+
folder_no_slash: "A folder name cannot contain '/'",
|
|
179
|
+
folder_duplicate: 'A folder with this name already exists',
|
|
180
|
+
doc_empty_drop: 'No documents yet — drop files here',
|
|
169
181
|
},
|
|
170
182
|
ar: {
|
|
171
183
|
required: 'هذا الحقل مطلوب',
|
|
@@ -854,7 +866,118 @@ const MrdDatetimeField = class {
|
|
|
854
866
|
};
|
|
855
867
|
MrdDatetimeField.style = mrdDatetimeFieldScss();
|
|
856
868
|
|
|
857
|
-
const
|
|
869
|
+
const mrdDocumentContainerScss = () => `.sc-mrd-document-container-h{display:block}.mrd-document-container__toolbar.sc-mrd-document-container{display:flex;align-items:center;justify-content:flex-end;gap:var(--mrd-space-2);padding:var(--mrd-space-2) var(--mrd-space-4);border-bottom:1px solid var(--mrd-color-neutral-100)}.mrd-document-container__action.sc-mrd-document-container{display:inline-flex;align-items:center;gap:var(--mrd-space-2);height:1.625rem;padding:0 var(--mrd-space-3);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-700);background:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-border-radius);cursor:pointer;transition:background var(--mrd-transition-fast), border-color var(--mrd-transition-fast)}.mrd-document-container__action.sc-mrd-document-container svg.sc-mrd-document-container{width:1rem;height:1rem;color:#d9a441}.mrd-document-container__action.sc-mrd-document-container:hover:not(:disabled){background:var(--mrd-color-neutral-50);border-color:var(--mrd-color-neutral-300)}.mrd-document-container__action.sc-mrd-document-container:disabled{opacity:0.5;cursor:not-allowed}.mrd-document-container__seg.sc-mrd-document-container{display:inline-flex;gap:2px;padding:2px;background:var(--mrd-color-neutral-100);border-radius:var(--mrd-border-radius)}.mrd-document-container__seg-btn.sc-mrd-document-container{width:1.875rem;height:1.625rem;display:grid;place-items:center;border:none;background:none;border-radius:var(--mrd-border-radius-sm);color:var(--mrd-color-neutral-500);cursor:pointer;transition:color var(--mrd-transition-fast), background var(--mrd-transition-fast)}.mrd-document-container__seg-btn.sc-mrd-document-container:hover{color:var(--mrd-color-neutral-800)}.mrd-document-container__seg-btn[aria-pressed='true'].sc-mrd-document-container{background:var(--mrd-color-white);color:var(--mrd-color-primary-dark);box-shadow:var(--mrd-shadow-sm)}.mrd-document-container__seg-btn.sc-mrd-document-container svg.sc-mrd-document-container{width:1rem;height:1rem}`;
|
|
870
|
+
|
|
871
|
+
const MrdDocumentContainer = class {
|
|
872
|
+
constructor(hostRef) {
|
|
873
|
+
index.registerInstance(this, hostRef);
|
|
874
|
+
this.mrdLoadPage = index.createEvent(this, "mrdLoadPage");
|
|
875
|
+
this.mrdLoadDistinct = index.createEvent(this, "mrdLoadDistinct");
|
|
876
|
+
this.mrdLoadAggregations = index.createEvent(this, "mrdLoadAggregations");
|
|
877
|
+
this.mrdNavigate = index.createEvent(this, "mrdNavigate");
|
|
878
|
+
this.mrdAction = index.createEvent(this, "mrdAction");
|
|
879
|
+
this.mrdUpdateObject = index.createEvent(this, "mrdUpdateObject");
|
|
880
|
+
this.mrdUpload = index.createEvent(this, "mrdUpload");
|
|
881
|
+
this.mrdCreateObject = index.createEvent(this, "mrdCreateObject");
|
|
882
|
+
/** The VIEW or RELATED_VIEW layout item (dataClass, fromClass, view config). */
|
|
883
|
+
this.item = null;
|
|
884
|
+
/** Parent record id — required for RELATED_VIEW path building. */
|
|
885
|
+
this.parentId = '';
|
|
886
|
+
/** Canonical parent href, forwarded to the folder tree for single-container seeding. */
|
|
887
|
+
this.containerHref = '';
|
|
888
|
+
/** Lookup key used for the embedded `data-doclist` / `data-view` attributes. */
|
|
889
|
+
this.viewKey = '';
|
|
890
|
+
/** Fixed height (px) of the scrolling folder-tree body — the toolbar stays put
|
|
891
|
+
* on top, Finder-style. The table manages its own height. */
|
|
892
|
+
this.height = 460;
|
|
893
|
+
this.locale = navigator.language;
|
|
894
|
+
/** Active body: folder tree or flat table. */
|
|
895
|
+
this.mode = 'tree';
|
|
896
|
+
/** Whether the folder tree currently has a valid target for "New folder". */
|
|
897
|
+
this.canCreate = false;
|
|
898
|
+
/** Whether the currently mounted table has been init()'d. Reset on every mode switch. */
|
|
899
|
+
this.tableInited = false;
|
|
900
|
+
this.createFolder = () => {
|
|
901
|
+
var _a, _b;
|
|
902
|
+
(_b = (_a = this.listEl) === null || _a === void 0 ? void 0 : _a.createFolder) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
/** The embedded table does not self-load: like every mrd-table it waits for the
|
|
906
|
+
* host to call init() (which emits mrdLoadPage, and — once page 0 lands —
|
|
907
|
+
* mrdLoadAggregations). The section only init()s tables mounted at load time, so
|
|
908
|
+
* when the user switches to list view we init the freshly mounted table here. */
|
|
909
|
+
componentDidRender() {
|
|
910
|
+
var _a;
|
|
911
|
+
if (this.mode === 'list' && this.tableEl && !this.tableInited) {
|
|
912
|
+
this.tableInited = true;
|
|
913
|
+
const table = this.tableEl;
|
|
914
|
+
Promise.resolve((_a = table.componentOnReady) === null || _a === void 0 ? void 0 : _a.call(table)).then(() => { var _a; return (_a = table.init) === null || _a === void 0 ? void 0 : _a.call(table); });
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
setMode(mode) {
|
|
918
|
+
if (mode === this.mode)
|
|
919
|
+
return;
|
|
920
|
+
// The tree remounts on switch and re-emits mrdCanCreate; until then, disable.
|
|
921
|
+
this.canCreate = false;
|
|
922
|
+
// The table remounts on switch; re-init it once it is back in the DOM.
|
|
923
|
+
this.tableInited = false;
|
|
924
|
+
this.mode = mode;
|
|
925
|
+
}
|
|
926
|
+
// ── Toolbar ────────────────────────────────────────────────────────────────
|
|
927
|
+
renderToolbar() {
|
|
928
|
+
return (index.h("div", { class: "mrd-document-container__toolbar" }, this.mode === 'tree' && (index.h("button", { type: "button", class: "mrd-document-container__action", disabled: !this.canCreate, onClick: this.createFolder }, index.h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.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" }), index.h("path", { d: "M12 11v4M10 13h4" })), t('new_folder', this.locale))), index.h("div", { class: "mrd-document-container__seg", role: "group", "aria-label": t('doc_view_switch', this.locale) }, index.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') }, index.h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.h("path", { d: "M3 5h6M3 12h9M3 19h6" }), index.h("circle", { cx: "18", cy: "5", r: "1.6" }), index.h("circle", { cx: "18", cy: "19", r: "1.6" }), index.h("path", { d: "M16 12h4" }))), index.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') }, index.h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, index.h("path", { d: "M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" }))))));
|
|
929
|
+
}
|
|
930
|
+
// ── Bodies ───────────────────────────────────────────────────────────────
|
|
931
|
+
renderTree() {
|
|
932
|
+
return (index.h("mrd-document-list", { "data-doclist": this.viewKey, ref: el => (this.listEl = el), item: this.item, archetype: this.archetype, parentId: this.parentId, containerHref: this.containerHref, locale: this.locale, onMrdLoadDistinct: (e) => {
|
|
933
|
+
e.stopPropagation();
|
|
934
|
+
this.mrdLoadDistinct.emit(e.detail);
|
|
935
|
+
}, onMrdLoadPage: (e) => {
|
|
936
|
+
e.stopPropagation();
|
|
937
|
+
this.mrdLoadPage.emit(e.detail);
|
|
938
|
+
}, onMrdNavigate: (e) => {
|
|
939
|
+
e.stopPropagation();
|
|
940
|
+
this.mrdNavigate.emit(e.detail);
|
|
941
|
+
}, onMrdCanCreate: (e) => {
|
|
942
|
+
e.stopPropagation();
|
|
943
|
+
this.canCreate = e.detail;
|
|
944
|
+
}, onMrdUpdateObject: (e) => {
|
|
945
|
+
e.stopPropagation();
|
|
946
|
+
this.mrdUpdateObject.emit(e.detail);
|
|
947
|
+
}, onMrdUpload: (e) => {
|
|
948
|
+
e.stopPropagation();
|
|
949
|
+
this.mrdUpload.emit(e.detail);
|
|
950
|
+
}, onMrdCreateObject: (e) => {
|
|
951
|
+
e.stopPropagation();
|
|
952
|
+
this.mrdCreateObject.emit(e.detail);
|
|
953
|
+
} }));
|
|
954
|
+
}
|
|
955
|
+
renderList() {
|
|
956
|
+
return (index.h("mrd-table", { "data-view": this.viewKey, ref: el => (this.tableEl = el), item: this.item, parentId: this.parentId, locale: this.locale, onMrdLoadPage: (e) => {
|
|
957
|
+
e.stopPropagation();
|
|
958
|
+
this.mrdLoadPage.emit(e.detail);
|
|
959
|
+
}, onMrdLoadAggregations: (e) => {
|
|
960
|
+
e.stopPropagation();
|
|
961
|
+
this.mrdLoadAggregations.emit(e.detail);
|
|
962
|
+
}, onMrdRowClick: (e) => {
|
|
963
|
+
var _a, _b, _c;
|
|
964
|
+
e.stopPropagation();
|
|
965
|
+
const row = e.detail;
|
|
966
|
+
this.mrdNavigate.emit({ href: (_b = (_a = row === null || row === void 0 ? void 0 : row._links) === null || _a === void 0 ? void 0 : _a.self) === null || _b === void 0 ? void 0 : _b.href, label: (_c = row === null || row === void 0 ? void 0 : row.name) !== null && _c !== void 0 ? _c : '' });
|
|
967
|
+
}, onMrdAction: (e) => {
|
|
968
|
+
e.stopPropagation();
|
|
969
|
+
this.mrdAction.emit(e.detail);
|
|
970
|
+
} }));
|
|
971
|
+
}
|
|
972
|
+
render() {
|
|
973
|
+
const treeMode = this.mode === 'tree';
|
|
974
|
+
return (index.h(index.Host, { key: '5d8a9a9bb4f1126a304b796aff9d1cb0100b8fc6' }, this.renderToolbar(), index.h("div", { key: '80ac7e5dd39ffcc4161059447221045a6e035099', class: "mrd-document-container__body", style: treeMode ? { height: `${this.height}px`, overflowY: 'auto' } : {} }, treeMode ? this.renderTree() : this.renderList())));
|
|
975
|
+
}
|
|
976
|
+
get el() { return index.getElement(this); }
|
|
977
|
+
};
|
|
978
|
+
MrdDocumentContainer.style = mrdDocumentContainerScss();
|
|
979
|
+
|
|
980
|
+
const mrdDocumentListScss = () => `.sc-mrd-document-list-h{display:block;height:100%}.mrd-document-list.sc-mrd-document-list{padding:var(--mrd-space-2) 0;min-height:100%;box-sizing:border-box}.mrd-document-list--drop-active.sc-mrd-document-list{outline:2px dashed var(--mrd-color-primary);outline-offset:-4px;background:var(--mrd-color-primary-50, rgba(22, 163, 74, 0.06))}.mrd-document-list__row.sc-mrd-document-list{display:flex;align-items:center;gap:var(--mrd-space-2);height:2.125rem;padding:0 var(--mrd-space-4);cursor:pointer;user-select:none;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-800)}.mrd-document-list__row.sc-mrd-document-list:hover{background:var(--mrd-color-neutral-50)}.mrd-document-list__row--selected.sc-mrd-document-list{background:var(--mrd-color-primary-50, rgba(22, 163, 74, 0.1))}.mrd-document-list__row--selected.sc-mrd-document-list:hover{background:var(--mrd-color-primary-50, rgba(22, 163, 74, 0.1))}.mrd-document-list__row--pending.sc-mrd-document-list .mrd-document-list__label.sc-mrd-document-list{font-style:italic;color:var(--mrd-color-neutral-500)}.mrd-document-list__row--doc.sc-mrd-document-list{cursor:grab}.mrd-document-list__row--doc.sc-mrd-document-list:active{cursor:grabbing}.mrd-document-list__row--drop.sc-mrd-document-list{background:var(--mrd-color-primary-50, rgba(22, 163, 74, 0.1));box-shadow:inset 0 0 0 1px var(--mrd-color-primary)}.mrd-document-list__row--drop.sc-mrd-document-list:hover{background:var(--mrd-color-primary-50, rgba(22, 163, 74, 0.1))}.mrd-document-list__row--edit.sc-mrd-document-list{cursor:default}.mrd-document-list__name-input.sc-mrd-document-list{flex:1;min-width:0;height:1.625rem;padding:0 var(--mrd-space-2);font-size:var(--mrd-font-size-sm);font-family:inherit;color:var(--mrd-color-neutral-800);border:1px solid var(--mrd-color-primary);border-radius:var(--mrd-border-radius);outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-document-list__error.sc-mrd-document-list{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-danger, #dc2626);padding-top:0.125rem;padding-bottom:0.25rem}.mrd-document-list__row--dossier.sc-mrd-document-list .mrd-document-list__label.sc-mrd-document-list{font-weight:var(--mrd-font-weight-semibold)}.mrd-document-list__indent.sc-mrd-document-list{flex:none}.mrd-document-list__chev.sc-mrd-document-list{width:1rem;height:1rem;flex:none;display:grid;place-items:center;color:var(--mrd-color-neutral-400);transition:transform var(--mrd-transition-fast)}.mrd-document-list__chev.sc-mrd-document-list svg.sc-mrd-document-list{width:0.6875rem;height:0.6875rem}.mrd-document-list__chev--open.sc-mrd-document-list{transform:rotate(90deg)}.mrd-document-list__chev--leaf.sc-mrd-document-list{visibility:hidden}.mrd-document-list__icon.sc-mrd-document-list{width:1.0625rem;height:1.0625rem;flex:none}.mrd-document-list__icon--dossier.sc-mrd-document-list{color:var(--mrd-color-primary)}.mrd-document-list__icon--folder.sc-mrd-document-list{color:#d9a441}.mrd-document-list__icon--doc.sc-mrd-document-list{color:var(--mrd-color-neutral-400)}.mrd-document-list__label.sc-mrd-document-list{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mrd-document-list__count.sc-mrd-document-list{flex:none;font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);background:var(--mrd-color-neutral-100);border-radius:var(--mrd-border-radius-full);padding:0.0625rem 0.5rem}.mrd-document-list__date.sc-mrd-document-list{flex:none;font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-400);font-variant-numeric:tabular-nums}.mrd-document-list__loading.sc-mrd-document-list{display:flex;align-items:center;gap:var(--mrd-space-2);height:1.875rem;padding:0 var(--mrd-space-4);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-400)}.mrd-document-list__spinner.sc-mrd-document-list{width:0.75rem;height:0.75rem;border:2px solid var(--mrd-color-neutral-300);border-top-color:var(--mrd-color-primary);border-radius:50%;animation:mrd-document-list-spin 0.7s linear infinite}@keyframes mrd-document-list-spin{to{transform:rotate(360deg)}}.mrd-document-list__empty.sc-mrd-document-list{padding:var(--mrd-space-8) var(--mrd-space-4);text-align:center;color:var(--mrd-color-neutral-400);font-size:var(--mrd-font-size-sm)}`;
|
|
858
981
|
|
|
859
982
|
const MrdDocumentList = class {
|
|
860
983
|
constructor(hostRef) {
|
|
@@ -862,19 +985,223 @@ const MrdDocumentList = class {
|
|
|
862
985
|
this.mrdLoadDistinct = index.createEvent(this, "mrdLoadDistinct");
|
|
863
986
|
this.mrdLoadPage = index.createEvent(this, "mrdLoadPage");
|
|
864
987
|
this.mrdNavigate = index.createEvent(this, "mrdNavigate");
|
|
988
|
+
this.mrdCanCreate = index.createEvent(this, "mrdCanCreate");
|
|
989
|
+
this.mrdUpdateObject = index.createEvent(this, "mrdUpdateObject");
|
|
990
|
+
this.mrdUpload = index.createEvent(this, "mrdUpload");
|
|
991
|
+
this.mrdCreateObject = index.createEvent(this, "mrdCreateObject");
|
|
865
992
|
/** The VIEW or RELATED_VIEW layout item (dataClass, fromClass, view config). */
|
|
866
993
|
this.item = null;
|
|
867
994
|
/** Parent record id — required for RELATED_VIEW path building. */
|
|
868
995
|
this.parentId = '';
|
|
996
|
+
/** Canonical parent href (`/{base}/{tenant}/{fromClass}/{parentId}`) supplied by
|
|
997
|
+
* the host. When the RELATED_VIEW's `inverseRelation` equals the archetype
|
|
998
|
+
* `container` slot, this seeds a single container so an empty dossier still
|
|
999
|
+
* accepts file drops and folder creation. */
|
|
1000
|
+
this.containerHref = '';
|
|
869
1001
|
this.locale = navigator.language;
|
|
870
1002
|
this.containers = [];
|
|
871
1003
|
this.rootLoading = true;
|
|
872
1004
|
/** True when the single-container level is collapsed away (dossier context). */
|
|
873
1005
|
this.singleContainer = false;
|
|
1006
|
+
/** Currently selected node id — the target for "New folder" and (later) drops. */
|
|
1007
|
+
this.selectedId = null;
|
|
1008
|
+
/** Node id currently highlighted as a drag-drop target (null = none). */
|
|
1009
|
+
this.dropTargetId = null;
|
|
1010
|
+
/** Node id showing an "uploading…" indicator while a dropped file is processed. */
|
|
1011
|
+
this.uploadingNodeId = null;
|
|
1012
|
+
/** Whether a drag is hovering the root drop-zone (single-container area highlight). */
|
|
1013
|
+
this.rootDropActive = false;
|
|
874
1014
|
this.nodeIndex = new Map();
|
|
1015
|
+
// ── New-folder editing state ───────────────────────────────────────────────
|
|
1016
|
+
/** The pending node whose inline name input is open (null = not creating). */
|
|
1017
|
+
this.pendingNode = null;
|
|
1018
|
+
/** The node the pending folder is being created under. */
|
|
1019
|
+
this.pendingParent = null;
|
|
1020
|
+
/** The container the pending folder belongs to. */
|
|
1021
|
+
this.pendingContainer = null;
|
|
1022
|
+
/** Current text in the inline name input. */
|
|
1023
|
+
this.pendingName = '';
|
|
1024
|
+
/** Ref to the inline input, so we can focus it after it mounts. */
|
|
1025
|
+
this.pendingInputEl = null;
|
|
1026
|
+
/** Set when a fresh input needs focus on the next render. */
|
|
1027
|
+
this.pendingNeedsFocus = false;
|
|
1028
|
+
/** Monotonic counter for unique temporary pending-node ids. */
|
|
1029
|
+
this.newFolderSeq = 0;
|
|
1030
|
+
/** Last emitted canCreateFolder value, to only emit mrdCanCreate on change. */
|
|
1031
|
+
this.lastCanCreate = false;
|
|
1032
|
+
// ── Drag & drop (move a document into another folder) ──────────────────────
|
|
1033
|
+
/** The document row currently being dragged. */
|
|
1034
|
+
this.dragDoc = null;
|
|
1035
|
+
/** Id of the node the dragged document currently lives in. */
|
|
1036
|
+
this.dragFromId = null;
|
|
1037
|
+
/** External file dropped onto a node, awaiting its upload to complete. */
|
|
1038
|
+
this.pendingUpload = null;
|
|
1039
|
+
/** The optimistic document row awaiting its self href from the create POST. */
|
|
1040
|
+
this.lastOptimisticDoc = null;
|
|
1041
|
+
this.startCreateFolder = () => {
|
|
1042
|
+
const resolved = this.resolveTarget();
|
|
1043
|
+
if (!resolved || this.pendingNode)
|
|
1044
|
+
return;
|
|
1045
|
+
const { target, container } = resolved;
|
|
1046
|
+
const tempId = `${container.id}/__new__${this.newFolderSeq++}`;
|
|
1047
|
+
const node = this.makeFolderNode(tempId, '', container.id);
|
|
1048
|
+
node.pending = true;
|
|
1049
|
+
node.editing = true;
|
|
1050
|
+
target.children = [...target.children, node];
|
|
1051
|
+
target.open = true;
|
|
1052
|
+
this.nodeIndex.set(node.id, node);
|
|
1053
|
+
this.pendingNode = node;
|
|
1054
|
+
this.pendingParent = target;
|
|
1055
|
+
this.pendingContainer = container;
|
|
1056
|
+
this.pendingName = '';
|
|
1057
|
+
this.pendingNeedsFocus = true;
|
|
1058
|
+
this.bump();
|
|
1059
|
+
};
|
|
1060
|
+
this.onPendingInput = (e) => {
|
|
1061
|
+
var _a;
|
|
1062
|
+
this.pendingName = e.target.value;
|
|
1063
|
+
if ((_a = this.pendingNode) === null || _a === void 0 ? void 0 : _a.error) {
|
|
1064
|
+
this.pendingNode.error = undefined;
|
|
1065
|
+
this.bump();
|
|
1066
|
+
}
|
|
1067
|
+
};
|
|
1068
|
+
this.onPendingKeyDown = (e) => {
|
|
1069
|
+
if (e.key === 'Enter') {
|
|
1070
|
+
e.preventDefault();
|
|
1071
|
+
this.commitFolder();
|
|
1072
|
+
}
|
|
1073
|
+
else if (e.key === 'Escape') {
|
|
1074
|
+
e.preventDefault();
|
|
1075
|
+
this.cancelFolder();
|
|
1076
|
+
}
|
|
1077
|
+
};
|
|
1078
|
+
// ── Drag & drop: move a document into another folder / container ────────────
|
|
1079
|
+
this.onDocDragStart = (e, doc, node) => {
|
|
1080
|
+
var _a, _b, _c;
|
|
1081
|
+
this.dragDoc = doc;
|
|
1082
|
+
this.dragFromId = node.id;
|
|
1083
|
+
if (e.dataTransfer) {
|
|
1084
|
+
e.dataTransfer.effectAllowed = 'move';
|
|
1085
|
+
// A payload is required for a drag to start in some browsers.
|
|
1086
|
+
e.dataTransfer.setData('text/plain', (_c = (_b = (_a = doc === null || doc === void 0 ? void 0 : doc._links) === null || _a === void 0 ? void 0 : _a.self) === null || _b === void 0 ? void 0 : _b.href) !== null && _c !== void 0 ? _c : '');
|
|
1087
|
+
}
|
|
1088
|
+
};
|
|
1089
|
+
this.onDocDragEnd = () => {
|
|
1090
|
+
this.dragDoc = null;
|
|
1091
|
+
this.dragFromId = null;
|
|
1092
|
+
if (this.dropTargetId !== null)
|
|
1093
|
+
this.dropTargetId = null;
|
|
1094
|
+
};
|
|
1095
|
+
/** A folder/container node (or a document inside it) accepts an internal move
|
|
1096
|
+
* or an external file drop. Always claims the event so it never bubbles to the
|
|
1097
|
+
* root drop-zone; a different node is highlighted (its own folder = no-op). */
|
|
1098
|
+
this.onNodeDragOver = (e, node) => {
|
|
1099
|
+
const file = this.isFileDrag(e);
|
|
1100
|
+
if (!this.dragDoc && !file)
|
|
1101
|
+
return;
|
|
1102
|
+
e.preventDefault();
|
|
1103
|
+
e.stopPropagation();
|
|
1104
|
+
if (e.dataTransfer)
|
|
1105
|
+
e.dataTransfer.dropEffect = file ? 'copy' : 'move';
|
|
1106
|
+
const target = !file && node.id === this.dragFromId ? null : node.id;
|
|
1107
|
+
if (this.dropTargetId !== target)
|
|
1108
|
+
this.dropTargetId = target;
|
|
1109
|
+
};
|
|
1110
|
+
this.onNodeDragLeave = (node) => {
|
|
1111
|
+
if (this.dropTargetId === node.id)
|
|
1112
|
+
this.dropTargetId = null;
|
|
1113
|
+
};
|
|
1114
|
+
this.onNodeDrop = (e, node, container) => {
|
|
1115
|
+
if (this.isFileDrag(e)) {
|
|
1116
|
+
e.preventDefault();
|
|
1117
|
+
e.stopPropagation();
|
|
1118
|
+
this.startFileUpload(e, node, container);
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1121
|
+
if (!this.dragDoc)
|
|
1122
|
+
return;
|
|
1123
|
+
e.preventDefault();
|
|
1124
|
+
e.stopPropagation();
|
|
1125
|
+
this.moveDocument(node, container);
|
|
1126
|
+
this.onDocDragEnd();
|
|
1127
|
+
};
|
|
1128
|
+
/** Root-zone drop (dossier context): target the single container's root. */
|
|
1129
|
+
this.onRootDragOver = (e) => {
|
|
1130
|
+
if (!this.singleContainer)
|
|
1131
|
+
return;
|
|
1132
|
+
const file = this.isFileDrag(e);
|
|
1133
|
+
if (!this.dragDoc && !file)
|
|
1134
|
+
return;
|
|
1135
|
+
e.preventDefault();
|
|
1136
|
+
if (e.dataTransfer)
|
|
1137
|
+
e.dataTransfer.dropEffect = file ? 'copy' : 'move';
|
|
1138
|
+
if (!this.rootDropActive)
|
|
1139
|
+
this.rootDropActive = true;
|
|
1140
|
+
};
|
|
1141
|
+
this.onRootDragLeave = (e) => {
|
|
1142
|
+
const related = e.relatedTarget;
|
|
1143
|
+
if (related && this.el.contains(related))
|
|
1144
|
+
return; // moved onto a child, still inside
|
|
1145
|
+
if (this.rootDropActive)
|
|
1146
|
+
this.rootDropActive = false;
|
|
1147
|
+
};
|
|
1148
|
+
this.onRootDrop = (e) => {
|
|
1149
|
+
this.rootDropActive = false;
|
|
1150
|
+
if (!this.singleContainer)
|
|
1151
|
+
return;
|
|
1152
|
+
const only = this.containers[0];
|
|
1153
|
+
if (this.isFileDrag(e)) {
|
|
1154
|
+
e.preventDefault();
|
|
1155
|
+
this.startFileUpload(e, only, only);
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
1158
|
+
if (!this.dragDoc)
|
|
1159
|
+
return;
|
|
1160
|
+
e.preventDefault();
|
|
1161
|
+
this.moveDocument(only, only);
|
|
1162
|
+
this.onDocDragEnd();
|
|
1163
|
+
};
|
|
875
1164
|
}
|
|
876
1165
|
componentDidLoad() {
|
|
877
|
-
this.
|
|
1166
|
+
if (this.isSeededSingleContainer()) {
|
|
1167
|
+
this.seedSingleContainer();
|
|
1168
|
+
}
|
|
1169
|
+
else {
|
|
1170
|
+
this.emitContainerDistinct();
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
/** True when the view is a single-container context: a RELATED_VIEW whose
|
|
1174
|
+
* `inverseRelation` matches the archetype `container` slot, with a known
|
|
1175
|
+
* parent href. The container is then implied by context (not by distinct),
|
|
1176
|
+
* so it works even with zero documents. */
|
|
1177
|
+
isSeededSingleContainer() {
|
|
1178
|
+
var _a, _b;
|
|
1179
|
+
return (((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === index$1.ClientLayoutItemType.RELATED_VIEW &&
|
|
1180
|
+
!!((_b = this.item) === null || _b === void 0 ? void 0 : _b.inverseRelation) &&
|
|
1181
|
+
this.item.inverseRelation === this.containerField &&
|
|
1182
|
+
!!this.containerHref);
|
|
1183
|
+
}
|
|
1184
|
+
/** Seed the single implied container from context and load its folders. */
|
|
1185
|
+
seedSingleContainer() {
|
|
1186
|
+
const node = this.makeContainerNode(this.containerHref, this.containerField, 0);
|
|
1187
|
+
this.nodeIndex.set(node.id, node);
|
|
1188
|
+
this.containers = [node];
|
|
1189
|
+
this.rootLoading = false;
|
|
1190
|
+
this.singleContainer = true;
|
|
1191
|
+
node.open = true;
|
|
1192
|
+
this.emitFolderDistinct(node);
|
|
1193
|
+
}
|
|
1194
|
+
componentDidRender() {
|
|
1195
|
+
if (this.pendingNeedsFocus && this.pendingInputEl) {
|
|
1196
|
+
this.pendingInputEl.focus();
|
|
1197
|
+
this.pendingInputEl.select();
|
|
1198
|
+
this.pendingNeedsFocus = false;
|
|
1199
|
+
}
|
|
1200
|
+
const can = this.canCreateFolder;
|
|
1201
|
+
if (can !== this.lastCanCreate) {
|
|
1202
|
+
this.lastCanCreate = can;
|
|
1203
|
+
this.mrdCanCreate.emit(can);
|
|
1204
|
+
}
|
|
878
1205
|
}
|
|
879
1206
|
// ── Slot field names ─────────────────────────────────────────────────────
|
|
880
1207
|
get containerField() {
|
|
@@ -889,12 +1216,19 @@ const MrdDocumentList = class {
|
|
|
889
1216
|
var _a, _b, _c;
|
|
890
1217
|
return (_c = (_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b.title) !== null && _c !== void 0 ? _c : 'name';
|
|
891
1218
|
}
|
|
1219
|
+
get fileField() {
|
|
1220
|
+
var _a, _b, _c;
|
|
1221
|
+
return (_c = (_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b.file) !== null && _c !== void 0 ? _c : 'file';
|
|
1222
|
+
}
|
|
892
1223
|
get dateField() {
|
|
893
1224
|
var _a, _b;
|
|
894
1225
|
return (_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b.date;
|
|
895
1226
|
}
|
|
896
1227
|
// ── Path / query building (mirrors mrd-table conventions) ────────────────
|
|
897
|
-
/** VIEW: `/{dataClass}`; RELATED_VIEW: `/{fromClass}/{parentId}/{dataClass}`.
|
|
1228
|
+
/** VIEW: `/{dataClass}`; RELATED_VIEW: `/{fromClass}/{parentId}/{dataClass}`.
|
|
1229
|
+
* Used for reads (list/distinct): `dataClass`/`relatedClass` may be an abstract
|
|
1230
|
+
* type (e.g. "contents"), filtered down to the concrete `filterClass` via the
|
|
1231
|
+
* `type` query param — see baseParams(). */
|
|
898
1232
|
buildDataPath() {
|
|
899
1233
|
var _a, _b, _c;
|
|
900
1234
|
const it = this.item;
|
|
@@ -904,6 +1238,19 @@ const MrdDocumentList = class {
|
|
|
904
1238
|
}
|
|
905
1239
|
return `/${dataClass}`;
|
|
906
1240
|
}
|
|
1241
|
+
/** Path for creating a new document (file-drop). Unlike buildDataPath(), this
|
|
1242
|
+
* must target the concrete type: `dataClass`/`relatedClass` can be an abstract
|
|
1243
|
+
* base type (e.g. "contents") that cannot be POSTed to directly, so prefer
|
|
1244
|
+
* `filterClass` (e.g. "documents") when present. */
|
|
1245
|
+
buildCreatePath() {
|
|
1246
|
+
var _a, _b, _c, _d;
|
|
1247
|
+
const it = this.item;
|
|
1248
|
+
const dataClass = (_c = (_b = (_a = it === null || it === void 0 ? void 0 : it.filterClass) !== null && _a !== void 0 ? _a : it === null || it === void 0 ? void 0 : it.dataClass) !== null && _b !== void 0 ? _b : it === null || it === void 0 ? void 0 : it.relatedClass) !== null && _c !== void 0 ? _c : '';
|
|
1249
|
+
if ((it === null || it === void 0 ? void 0 : it.type) === index$1.ClientLayoutItemType.RELATED_VIEW) {
|
|
1250
|
+
return `/${(_d = it.fromClass) !== null && _d !== void 0 ? _d : ''}/${this.parentId}/${dataClass}`;
|
|
1251
|
+
}
|
|
1252
|
+
return `/${dataClass}`;
|
|
1253
|
+
}
|
|
907
1254
|
/** View-level static filters + filterClass, shared by every request. */
|
|
908
1255
|
baseParams() {
|
|
909
1256
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -1041,7 +1388,7 @@ const MrdDocumentList = class {
|
|
|
1041
1388
|
acc.push(seg);
|
|
1042
1389
|
let child = node.children.find(c => c.label === seg);
|
|
1043
1390
|
if (!child) {
|
|
1044
|
-
child = this.makeFolderNode(container.id + '/' + acc.join('/'), seg);
|
|
1391
|
+
child = this.makeFolderNode(container.id + '/' + acc.join('/'), seg, container.id);
|
|
1045
1392
|
node.children.push(child);
|
|
1046
1393
|
this.nodeIndex.set(child.id, child);
|
|
1047
1394
|
}
|
|
@@ -1077,9 +1424,9 @@ const MrdDocumentList = class {
|
|
|
1077
1424
|
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1078
1425
|
};
|
|
1079
1426
|
}
|
|
1080
|
-
makeFolderNode(id, label) {
|
|
1427
|
+
makeFolderNode(id, label, containerId) {
|
|
1081
1428
|
return {
|
|
1082
|
-
id, kind: 'folder', label,
|
|
1429
|
+
id, kind: 'folder', label, containerId,
|
|
1083
1430
|
hasDocs: false, docCount: 0, totalCount: 0, children: [],
|
|
1084
1431
|
open: false, loading: false, foldersLoaded: false, docsLoaded: false, docs: [],
|
|
1085
1432
|
};
|
|
@@ -1097,6 +1444,7 @@ const MrdDocumentList = class {
|
|
|
1097
1444
|
}
|
|
1098
1445
|
// ── Interaction ──────────────────────────────────────────────────────────
|
|
1099
1446
|
toggleContainer(node) {
|
|
1447
|
+
this.selectedId = node.id;
|
|
1100
1448
|
node.open = !node.open;
|
|
1101
1449
|
if (node.open && !node.foldersLoaded && !node.loading) {
|
|
1102
1450
|
this.emitFolderDistinct(node);
|
|
@@ -1104,12 +1452,235 @@ const MrdDocumentList = class {
|
|
|
1104
1452
|
this.bump();
|
|
1105
1453
|
}
|
|
1106
1454
|
toggleFolder(container, node) {
|
|
1455
|
+
this.selectedId = node.id;
|
|
1107
1456
|
node.open = !node.open;
|
|
1108
1457
|
if (node.open && node.hasDocs && !node.docsLoaded && !node.loading) {
|
|
1109
1458
|
this.emitDocuments(container, node);
|
|
1110
1459
|
}
|
|
1111
1460
|
this.bump();
|
|
1112
1461
|
}
|
|
1462
|
+
// ── New folder (client-side pending, materialises on document drop) ─────────
|
|
1463
|
+
/** Resolve the node a new folder should be created under, and its container.
|
|
1464
|
+
* Uses the current selection; falls back to the single container (dossier). */
|
|
1465
|
+
resolveTarget() {
|
|
1466
|
+
if (this.selectedId) {
|
|
1467
|
+
const n = this.nodeIndex.get(this.selectedId);
|
|
1468
|
+
if (n && n.kind === 'container')
|
|
1469
|
+
return { target: n, container: n };
|
|
1470
|
+
if (n && n.kind === 'folder') {
|
|
1471
|
+
const container = n.containerId ? this.nodeIndex.get(n.containerId) : undefined;
|
|
1472
|
+
if (container)
|
|
1473
|
+
return { target: n, container };
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
if (this.singleContainer && this.containers[0]) {
|
|
1477
|
+
const only = this.containers[0];
|
|
1478
|
+
return { target: only, container: only };
|
|
1479
|
+
}
|
|
1480
|
+
return null;
|
|
1481
|
+
}
|
|
1482
|
+
get canCreateFolder() {
|
|
1483
|
+
return !this.pendingNode && this.resolveTarget() !== null;
|
|
1484
|
+
}
|
|
1485
|
+
/** Start creating a folder under the current target. Called by the host toolbar
|
|
1486
|
+
* (mrd-document-container). No-op when there is no valid target. */
|
|
1487
|
+
async createFolder() {
|
|
1488
|
+
this.startCreateFolder();
|
|
1489
|
+
}
|
|
1490
|
+
/** Folder path segments of a node relative to its container (derived from its id). */
|
|
1491
|
+
segmentsOf(node, container) {
|
|
1492
|
+
if (node.kind === 'container')
|
|
1493
|
+
return [];
|
|
1494
|
+
const prefix = container.id + '/';
|
|
1495
|
+
const rest = node.id.startsWith(prefix) ? node.id.slice(prefix.length) : '';
|
|
1496
|
+
return rest ? rest.split('/') : [];
|
|
1497
|
+
}
|
|
1498
|
+
commitFolder() {
|
|
1499
|
+
const node = this.pendingNode;
|
|
1500
|
+
const parent = this.pendingParent;
|
|
1501
|
+
const container = this.pendingContainer;
|
|
1502
|
+
if (!node || !parent || !container)
|
|
1503
|
+
return;
|
|
1504
|
+
const name = this.pendingName.trim();
|
|
1505
|
+
if (!name) {
|
|
1506
|
+
this.cancelFolder();
|
|
1507
|
+
return;
|
|
1508
|
+
}
|
|
1509
|
+
if (name.includes('/')) {
|
|
1510
|
+
node.error = t('folder_no_slash', this.locale);
|
|
1511
|
+
this.bump();
|
|
1512
|
+
return;
|
|
1513
|
+
}
|
|
1514
|
+
const dup = parent.children.some(c => c !== node && c.label.toLowerCase() === name.toLowerCase());
|
|
1515
|
+
if (dup) {
|
|
1516
|
+
node.error = t('folder_duplicate', this.locale);
|
|
1517
|
+
this.bump();
|
|
1518
|
+
return;
|
|
1519
|
+
}
|
|
1520
|
+
// Finalise: swap the temp id for the real path-derived id so a later distinct
|
|
1521
|
+
// value with the same folder string merges onto this node.
|
|
1522
|
+
const segs = [...this.segmentsOf(parent, container), name];
|
|
1523
|
+
this.nodeIndex.delete(node.id);
|
|
1524
|
+
node.id = container.id + '/' + segs.join('/');
|
|
1525
|
+
node.fullPath = '/' + segs.join('/');
|
|
1526
|
+
node.label = name;
|
|
1527
|
+
node.editing = false;
|
|
1528
|
+
node.error = undefined;
|
|
1529
|
+
node.open = true;
|
|
1530
|
+
this.nodeIndex.set(node.id, node);
|
|
1531
|
+
this.selectedId = node.id;
|
|
1532
|
+
this.clearPending();
|
|
1533
|
+
this.bump();
|
|
1534
|
+
}
|
|
1535
|
+
cancelFolder() {
|
|
1536
|
+
const node = this.pendingNode;
|
|
1537
|
+
const parent = this.pendingParent;
|
|
1538
|
+
if (node && parent) {
|
|
1539
|
+
parent.children = parent.children.filter(c => c !== node);
|
|
1540
|
+
this.nodeIndex.delete(node.id);
|
|
1541
|
+
}
|
|
1542
|
+
this.clearPending();
|
|
1543
|
+
this.bump();
|
|
1544
|
+
}
|
|
1545
|
+
clearPending() {
|
|
1546
|
+
this.pendingNode = null;
|
|
1547
|
+
this.pendingParent = null;
|
|
1548
|
+
this.pendingContainer = null;
|
|
1549
|
+
this.pendingName = '';
|
|
1550
|
+
this.pendingInputEl = null;
|
|
1551
|
+
this.pendingNeedsFocus = false;
|
|
1552
|
+
}
|
|
1553
|
+
/** True when the drag carries external files (an OS file drop, not an internal move). */
|
|
1554
|
+
isFileDrag(e) {
|
|
1555
|
+
return !this.dragDoc && !!e.dataTransfer && Array.from(e.dataTransfer.types).includes('Files');
|
|
1556
|
+
}
|
|
1557
|
+
// ── External file drop → upload → create document ──────────────────────────
|
|
1558
|
+
/** Begin an upload: emit mrdUpload; the host uploads and calls setFileReference. */
|
|
1559
|
+
startFileUpload(e, node, container) {
|
|
1560
|
+
var _a, _b;
|
|
1561
|
+
const file = (_b = (_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) === null || _b === void 0 ? void 0 : _b[0]; // single file per drop
|
|
1562
|
+
this.dropTargetId = null;
|
|
1563
|
+
if (!file)
|
|
1564
|
+
return;
|
|
1565
|
+
this.pendingUpload = { file, node, container };
|
|
1566
|
+
node.open = true;
|
|
1567
|
+
this.uploadingNodeId = node.id;
|
|
1568
|
+
this.bump();
|
|
1569
|
+
this.mrdUpload.emit({ file });
|
|
1570
|
+
}
|
|
1571
|
+
/** Strip a single trailing extension for the document title. */
|
|
1572
|
+
stripExtension(name) {
|
|
1573
|
+
return name.replace(/\.[^./\\]+$/, '');
|
|
1574
|
+
}
|
|
1575
|
+
/** Host callback with the uploaded file reference. Builds the create payload
|
|
1576
|
+
* from the archetype slots and requests the new document. */
|
|
1577
|
+
async setFileReference(uri) {
|
|
1578
|
+
const up = this.pendingUpload;
|
|
1579
|
+
if (!up)
|
|
1580
|
+
return;
|
|
1581
|
+
const { file, node, container } = up;
|
|
1582
|
+
const folder = this.folderStringOf(node, container);
|
|
1583
|
+
const values = {
|
|
1584
|
+
[this.fileField]: uri,
|
|
1585
|
+
[this.titleField]: this.stripExtension(file.name),
|
|
1586
|
+
[this.folderField]: folder,
|
|
1587
|
+
[this.containerField]: container.href,
|
|
1588
|
+
};
|
|
1589
|
+
this.mrdCreateObject.emit({ path: this.buildCreatePath(), values });
|
|
1590
|
+
// Optimistically show the new document (no href until a reload).
|
|
1591
|
+
const optimistic = { [this.titleField]: this.stripExtension(file.name), _optimistic: true };
|
|
1592
|
+
const wasUnloadedEmpty = !node.docsLoaded && node.docCount === 0;
|
|
1593
|
+
node.hasDocs = true;
|
|
1594
|
+
node.pending = false;
|
|
1595
|
+
node.docCount += 1;
|
|
1596
|
+
if (wasUnloadedEmpty) {
|
|
1597
|
+
node.docsLoaded = true;
|
|
1598
|
+
node.docs = [optimistic];
|
|
1599
|
+
}
|
|
1600
|
+
else if (node.docsLoaded)
|
|
1601
|
+
node.docs = [...node.docs, optimistic];
|
|
1602
|
+
this.recomputeContainerTotals(container, 1);
|
|
1603
|
+
this.lastOptimisticDoc = optimistic;
|
|
1604
|
+
this.pendingUpload = null;
|
|
1605
|
+
this.uploadingNodeId = null;
|
|
1606
|
+
this.bump();
|
|
1607
|
+
}
|
|
1608
|
+
/** Host callback with the created document's self href, so the optimistic row
|
|
1609
|
+
* becomes navigable without waiting for a reload. */
|
|
1610
|
+
async setCreatedHref(href) {
|
|
1611
|
+
var _a;
|
|
1612
|
+
const doc = this.lastOptimisticDoc;
|
|
1613
|
+
if (!doc || !href)
|
|
1614
|
+
return;
|
|
1615
|
+
doc._links = Object.assign(Object.assign({}, ((_a = doc._links) !== null && _a !== void 0 ? _a : {})), { self: { href } });
|
|
1616
|
+
doc._optimistic = false;
|
|
1617
|
+
this.lastOptimisticDoc = null;
|
|
1618
|
+
this.bump();
|
|
1619
|
+
}
|
|
1620
|
+
/** Folder string a node represents: the raw distinct value when it holds
|
|
1621
|
+
* documents, else derived from its path segments; null for a container root. */
|
|
1622
|
+
folderStringOf(node, container) {
|
|
1623
|
+
if (node.kind === 'container')
|
|
1624
|
+
return null;
|
|
1625
|
+
if (node.fullPath != null && node.fullPath !== '')
|
|
1626
|
+
return node.fullPath;
|
|
1627
|
+
const segs = this.segmentsOf(node, container);
|
|
1628
|
+
return segs.length ? '/' + segs.join('/') : null;
|
|
1629
|
+
}
|
|
1630
|
+
moveDocument(toNode, toContainer) {
|
|
1631
|
+
var _a, _b;
|
|
1632
|
+
const doc = this.dragDoc;
|
|
1633
|
+
const fromNode = this.dragFromId ? this.nodeIndex.get(this.dragFromId) : undefined;
|
|
1634
|
+
if (!doc || !fromNode)
|
|
1635
|
+
return;
|
|
1636
|
+
const fromContainer = fromNode.kind === 'container'
|
|
1637
|
+
? fromNode
|
|
1638
|
+
: (fromNode.containerId ? this.nodeIndex.get(fromNode.containerId) : undefined);
|
|
1639
|
+
if (!fromContainer)
|
|
1640
|
+
return;
|
|
1641
|
+
const targetFolder = this.folderStringOf(toNode, toContainer);
|
|
1642
|
+
const sourceFolder = this.folderStringOf(fromNode, fromContainer);
|
|
1643
|
+
const sameContainer = toContainer === fromContainer;
|
|
1644
|
+
// No-op: dropped back onto its own folder.
|
|
1645
|
+
if (toNode === fromNode || (sameContainer && targetFolder === sourceFolder))
|
|
1646
|
+
return;
|
|
1647
|
+
// ── Optimistic tree update (fire-and-forget; no refetch) ──
|
|
1648
|
+
fromNode.docs = fromNode.docs.filter(d => d !== doc);
|
|
1649
|
+
fromNode.docCount = Math.max(0, fromNode.docCount - 1);
|
|
1650
|
+
// A now-empty folder should stop showing an expand chevron (it disappears on
|
|
1651
|
+
// the next reload anyway, since it is derived from document folder strings).
|
|
1652
|
+
if (fromNode.docsLoaded)
|
|
1653
|
+
fromNode.hasDocs = fromNode.docs.length > 0;
|
|
1654
|
+
toNode.hasDocs = true;
|
|
1655
|
+
toNode.pending = false; // a pending folder is now materialised
|
|
1656
|
+
toNode.docCount += 1;
|
|
1657
|
+
if (toNode.kind === 'folder')
|
|
1658
|
+
toNode.fullPath = targetFolder !== null && targetFolder !== void 0 ? targetFolder : '';
|
|
1659
|
+
if (toNode.docsLoaded)
|
|
1660
|
+
toNode.docs = [...toNode.docs, doc];
|
|
1661
|
+
this.recomputeContainerTotals(fromContainer, -1);
|
|
1662
|
+
if (!sameContainer)
|
|
1663
|
+
this.recomputeContainerTotals(toContainer, 1);
|
|
1664
|
+
// ── Emit the generic update; host PATCHes the document ──
|
|
1665
|
+
const href = (_b = (_a = doc === null || doc === void 0 ? void 0 : doc._links) === null || _a === void 0 ? void 0 : _a.self) === null || _b === void 0 ? void 0 : _b.href;
|
|
1666
|
+
if (href) {
|
|
1667
|
+
const values = { [this.folderField]: targetFolder };
|
|
1668
|
+
if (!sameContainer)
|
|
1669
|
+
values[this.containerField] = toContainer.href;
|
|
1670
|
+
this.mrdUpdateObject.emit({ href, values });
|
|
1671
|
+
}
|
|
1672
|
+
this.bump();
|
|
1673
|
+
}
|
|
1674
|
+
/** Recompute a container's subtree totals from docCounts when its folders are
|
|
1675
|
+
* loaded; otherwise just nudge the aggregate badge by the delta. */
|
|
1676
|
+
recomputeContainerTotals(container, delta) {
|
|
1677
|
+
if (container.foldersLoaded) {
|
|
1678
|
+
this.computeTotals(container);
|
|
1679
|
+
}
|
|
1680
|
+
else {
|
|
1681
|
+
container.totalCount = Math.max(0, container.totalCount + delta);
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1113
1684
|
openDoc(doc) {
|
|
1114
1685
|
var _a, _b, _c, _d;
|
|
1115
1686
|
const href = (_b = (_a = doc === null || doc === void 0 ? void 0 : doc._links) === null || _a === void 0 ? void 0 : _a.self) === null || _b === void 0 ? void 0 : _b.href;
|
|
@@ -1132,12 +1703,12 @@ const MrdDocumentList = class {
|
|
|
1132
1703
|
indent(depth) {
|
|
1133
1704
|
return index.h("span", { class: "mrd-document-list__indent", style: { width: `${depth * 18}px` } });
|
|
1134
1705
|
}
|
|
1135
|
-
renderDocRow(doc, depth) {
|
|
1706
|
+
renderDocRow(doc, node, container, depth) {
|
|
1136
1707
|
var _a, _b, _c, _d, _e;
|
|
1137
1708
|
const label = (_b = (_a = doc === null || doc === void 0 ? void 0 : doc[this.titleField]) !== null && _a !== void 0 ? _a : doc === null || doc === void 0 ? void 0 : doc.name) !== null && _b !== void 0 ? _b : '';
|
|
1138
1709
|
const dateRaw = this.dateField ? doc === null || doc === void 0 ? void 0 : doc[this.dateField] : undefined;
|
|
1139
1710
|
const date = dateRaw ? formatDate(dateRaw, this.locale) : '';
|
|
1140
|
-
return (index.h("div", { class: "mrd-document-list__row mrd-document-list__row--doc", key: (_e = (_d = (_c = doc === null || doc === void 0 ? void 0 : doc._links) === null || _c === void 0 ? void 0 : _c.self) === null || _d === void 0 ? void 0 : _d.href) !== null && _e !== void 0 ? _e : label, onClick: () => this.openDoc(doc) }, this.indent(depth), this.renderChevron(false, true), this.renderDocIcon(), index.h("span", { class: "mrd-document-list__label" }, label), date && index.h("span", { class: "mrd-document-list__date" }, date)));
|
|
1711
|
+
return (index.h("div", { class: "mrd-document-list__row mrd-document-list__row--doc", key: (_e = (_d = (_c = doc === null || doc === void 0 ? void 0 : doc._links) === null || _c === void 0 ? void 0 : _c.self) === null || _d === void 0 ? void 0 : _d.href) !== null && _e !== void 0 ? _e : label, draggable: true, onClick: () => this.openDoc(doc), onDragStart: (e) => this.onDocDragStart(e, doc, node), onDragEnd: this.onDocDragEnd, onDragOver: (e) => this.onNodeDragOver(e, node), onDragLeave: () => this.onNodeDragLeave(node), onDrop: (e) => this.onNodeDrop(e, node, container) }, this.indent(depth), this.renderChevron(false, true), this.renderDocIcon(), index.h("span", { class: "mrd-document-list__label" }, label), date && index.h("span", { class: "mrd-document-list__date" }, date)));
|
|
1141
1712
|
}
|
|
1142
1713
|
renderLoadingRow(depth) {
|
|
1143
1714
|
return (index.h("div", { class: "mrd-document-list__loading", key: "loading" }, this.indent(depth), index.h("span", { class: "mrd-document-list__spinner" }), t('loading', this.locale)));
|
|
@@ -1148,7 +1719,7 @@ const MrdDocumentList = class {
|
|
|
1148
1719
|
if (node.hasDocs) {
|
|
1149
1720
|
if (node.docsLoaded) {
|
|
1150
1721
|
for (const doc of node.docs)
|
|
1151
|
-
out.push(this.renderDocRow(doc, depth));
|
|
1722
|
+
out.push(this.renderDocRow(doc, node, container, depth));
|
|
1152
1723
|
}
|
|
1153
1724
|
else if (node.loading) {
|
|
1154
1725
|
out.push(this.renderLoadingRow(depth));
|
|
@@ -1158,14 +1729,34 @@ const MrdDocumentList = class {
|
|
|
1158
1729
|
for (const child of node.children) {
|
|
1159
1730
|
out.push(this.renderFolderNode(container, child, depth));
|
|
1160
1731
|
}
|
|
1732
|
+
// An uploading file dropped onto this node.
|
|
1733
|
+
if (node.id === this.uploadingNodeId)
|
|
1734
|
+
out.push(this.renderUploadingRow(depth));
|
|
1161
1735
|
return out;
|
|
1162
1736
|
}
|
|
1737
|
+
renderUploadingRow(depth) {
|
|
1738
|
+
return (index.h("div", { class: "mrd-document-list__loading", key: "uploading" }, this.indent(depth), index.h("span", { class: "mrd-document-list__spinner" }), t('upload_file', this.locale)));
|
|
1739
|
+
}
|
|
1740
|
+
renderFolderEditRow(node, depth) {
|
|
1741
|
+
return (index.h("div", { class: "mrd-document-list__node", key: node.id }, index.h("div", { class: "mrd-document-list__row mrd-document-list__row--edit" }, this.indent(depth), this.renderChevron(false, true), this.renderFolderIcon(), index.h("input", { class: "mrd-document-list__name-input", type: "text", placeholder: t('folder_name_placeholder', this.locale), ref: el => (this.pendingInputEl = el), onInput: this.onPendingInput, onKeyDown: this.onPendingKeyDown, onBlur: () => this.cancelFolder() })), node.error && (index.h("div", { class: "mrd-document-list__error", style: { paddingLeft: `${depth * 18 + 52}px` } }, node.error))));
|
|
1742
|
+
}
|
|
1163
1743
|
renderFolderNode(container, node, depth) {
|
|
1744
|
+
if (node.editing)
|
|
1745
|
+
return this.renderFolderEditRow(node, depth);
|
|
1164
1746
|
const leaf = node.children.length === 0 && !node.hasDocs;
|
|
1165
|
-
|
|
1747
|
+
const selected = node.id === this.selectedId;
|
|
1748
|
+
const cls = 'mrd-document-list__row'
|
|
1749
|
+
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1750
|
+
+ (node.pending ? ' mrd-document-list__row--pending' : '')
|
|
1751
|
+
+ (node.id === this.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1752
|
+
return (index.h("div", { class: "mrd-document-list__node", key: node.id }, index.h("div", { class: cls, onClick: () => this.toggleFolder(container, node), onDragOver: (e) => this.onNodeDragOver(e, node), onDragLeave: () => this.onNodeDragLeave(node), onDrop: (e) => this.onNodeDrop(e, node, container) }, this.indent(depth), this.renderChevron(node.open, leaf), this.renderFolderIcon(), index.h("span", { class: "mrd-document-list__label" }, node.label), index.h("span", { class: "mrd-document-list__count" }, node.totalCount)), node.open && index.h("div", { class: "mrd-document-list__kids" }, this.renderChildren(container, node, depth + 1))));
|
|
1166
1753
|
}
|
|
1167
1754
|
renderContainerNode(node, depth) {
|
|
1168
|
-
|
|
1755
|
+
const selected = node.id === this.selectedId;
|
|
1756
|
+
const cls = 'mrd-document-list__row mrd-document-list__row--dossier'
|
|
1757
|
+
+ (selected ? ' mrd-document-list__row--selected' : '')
|
|
1758
|
+
+ (node.id === this.dropTargetId ? ' mrd-document-list__row--drop' : '');
|
|
1759
|
+
return (index.h("div", { class: "mrd-document-list__node", key: node.id }, index.h("div", { class: cls, onClick: () => this.toggleContainer(node), onDragOver: (e) => this.onNodeDragOver(e, node), onDragLeave: () => this.onNodeDragLeave(node), onDrop: (e) => this.onNodeDrop(e, node, node) }, this.indent(depth), this.renderChevron(node.open, false), this.renderDossierIcon(), index.h("span", { class: "mrd-document-list__label" }, node.label), index.h("span", { class: "mrd-document-list__count" }, node.totalCount)), node.open && (index.h("div", { class: "mrd-document-list__kids" }, node.loading && !node.foldersLoaded
|
|
1169
1760
|
? this.renderLoadingRow(depth + 1)
|
|
1170
1761
|
: this.renderChildren(node, node, depth + 1)))));
|
|
1171
1762
|
}
|
|
@@ -1175,19 +1766,25 @@ const MrdDocumentList = class {
|
|
|
1175
1766
|
body = this.renderLoadingRow(0);
|
|
1176
1767
|
}
|
|
1177
1768
|
else if (this.containers.length === 0) {
|
|
1178
|
-
body = index.h("div", { key: '
|
|
1769
|
+
body = index.h("div", { key: '9c38a2e26320a8173ba82cac412c1b32a8a1882e', class: "mrd-document-list__empty" }, t('no_results', this.locale));
|
|
1179
1770
|
}
|
|
1180
1771
|
else if (this.singleContainer) {
|
|
1181
1772
|
// Dossier context: render the single container's folder tree at the root.
|
|
1182
1773
|
const only = this.containers[0];
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1774
|
+
if (only.loading && !only.foldersLoaded) {
|
|
1775
|
+
body = this.renderLoadingRow(0);
|
|
1776
|
+
}
|
|
1777
|
+
else {
|
|
1778
|
+
const kids = this.renderChildren(only, only, 0);
|
|
1779
|
+
body = kids.length
|
|
1780
|
+
? kids
|
|
1781
|
+
: index.h("div", { class: "mrd-document-list__empty" }, t('doc_empty_drop', this.locale));
|
|
1782
|
+
}
|
|
1186
1783
|
}
|
|
1187
1784
|
else {
|
|
1188
1785
|
body = this.containers.map(c => this.renderContainerNode(c, 0));
|
|
1189
1786
|
}
|
|
1190
|
-
return (index.h(index.Host, { key: '
|
|
1787
|
+
return (index.h(index.Host, { key: 'dd83a6a609e01d21a2b5da5b3ab929f6f9315402' }, index.h("div", { key: 'd539d938e1efd759730cccc90c4d6c2e535db936', class: 'mrd-document-list' + (this.rootDropActive ? ' mrd-document-list--drop-active' : ''), onDragOver: this.onRootDragOver, onDragLeave: this.onRootDragLeave, onDrop: this.onRootDrop }, body)));
|
|
1191
1788
|
}
|
|
1192
1789
|
get el() { return index.getElement(this); }
|
|
1193
1790
|
};
|
|
@@ -1245,7 +1842,7 @@ const MrdDocumentView = class {
|
|
|
1245
1842
|
const date = dateRaw != null && dateRaw !== '' ? formatDate(dateRaw, this.locale) : null;
|
|
1246
1843
|
const summaryRaw = this.slotValue('summary');
|
|
1247
1844
|
const summary = summaryRaw != null && summaryRaw !== '' ? String(summaryRaw) : null;
|
|
1248
|
-
return (index.h(index.Host, { key: '
|
|
1845
|
+
return (index.h(index.Host, { key: '0a2071925ecdb21738376d66fa4babf4590e694c' }, index.h("div", { key: 'a2d29c0b6e211cab142adc780466bc885a602e96', class: "mrd-document-view" }, this.renderContainer(), title && index.h("h1", { key: '7f5ac202c21bc8a70f0dd15e2e1fa06e651b5bce', class: "mrd-document-view__title" }, title), date && index.h("p", { key: 'b1dce94d5fd8bfd5e078644f631a38f91b87e7ff', class: "mrd-document-view__date" }, date), this.renderFile(), summary && (index.h("div", { key: '588b9ca40a49ae9ea303852620bde75333b440ab', class: "mrd-document-view__summary" }, index.h("div", { key: 'd3b8adb85ac346b72451e789c10aedd539c966de', class: "mrd-document-view__summary-body", innerHTML: summary }))))));
|
|
1249
1846
|
}
|
|
1250
1847
|
};
|
|
1251
1848
|
MrdDocumentView.style = mrdDocumentViewScss();
|
|
@@ -1285,7 +1882,7 @@ const MrdEmailField = class {
|
|
|
1285
1882
|
}
|
|
1286
1883
|
render() {
|
|
1287
1884
|
const hasError = !!this.error;
|
|
1288
|
-
return (index.h(index.Host, { key: '
|
|
1885
|
+
return (index.h(index.Host, { key: '0d442ab2a711c26c83fcdbf0fd8cd006d8dd8649' }, index.h("div", { key: 'ceb2a80679514c4c5b888fe096c90ed6cc973f64', class: "mrd-email-field" }, this.label && (index.h("label", { key: '663f95eff1002ee56cfc3104514bf31b47e26750', class: `mrd-email-field__label${this.required ? ' mrd-email-field__label--required' : ''}` }, this.label)), index.h("input", { key: '42dbdec25a47b37cfd68d00d0b8a481f96fe8241', class: `mrd-email-field__input${hasError ? ' mrd-email-field__input--error' : ''}`, type: "email", name: this.name, value: this.value, placeholder: this.placeholder || 'name@example.com', required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur }), hasError && index.h("span", { key: '626ee856ceaa7051fb9dd1de8b7cbd708e83f617', class: "mrd-email-field__error" }, this.error))));
|
|
1289
1886
|
}
|
|
1290
1887
|
};
|
|
1291
1888
|
MrdEmailField.style = mrdEmailFieldScss();
|
|
@@ -1568,7 +2165,7 @@ const MrdFileField = class {
|
|
|
1568
2165
|
hasError ? 'mrd-file-field__zone--error' : '',
|
|
1569
2166
|
this.disabled || this.uploading ? 'mrd-file-field__zone--disabled' : '',
|
|
1570
2167
|
].filter(Boolean).join(' ');
|
|
1571
|
-
return (index.h(index.Host, { key: '
|
|
2168
|
+
return (index.h(index.Host, { key: '095bb39f3cb1680cf5e7e51bdfd06d8eb087f237' }, index.h("div", { key: '7e5b5fe6e63b6530221083c8bcb82bcac59a5fe7', class: "mrd-file-field" }, this.label && (index.h("label", { key: 'c34723f4199371d6fe8ea87463d878b89c038590', class: `mrd-file-field__label${this.required ? ' mrd-file-field__label--required' : ''}` }, this.label)), index.h("div", { key: '4727667345d3cd4a5c65a431744a09f366943c13', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, index.h("input", { key: '45ed41c0f094dbe269561c8586e473f908cdf4a4', ref: el => (this.fileInputRef = el), class: "mrd-file-field__input", type: "file", name: this.name, accept: this.accept, disabled: this.disabled || this.uploading, required: this.required && !hasFile, onChange: this.handleInputChange }), hasFile ? (index.h("div", { class: "mrd-file-field__selected" }, this.uploading ? (index.h("span", { class: "mrd-file-field__spinner", "aria-label": t('loading', this.locale) })) : (index.h("svg", { class: "mrd-file-field__icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }), index.h("polyline", { points: "14 2 14 8 20 8" }))), index.h("span", { class: "mrd-file-field__filename" }, this.fileName), !this.uploading && (index.h("button", { class: "mrd-file-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, "\u2715")))) : (index.h("div", { class: "mrd-file-field__prompt" }, index.h("svg", { class: "mrd-file-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("polyline", { points: "16 16 12 12 8 16" }), index.h("line", { x1: "12", y1: "12", x2: "12", y2: "21" }), index.h("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" })), index.h("span", null, t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-file-field__browse" }, t('browse', this.locale)))))), hasError && index.h("span", { key: '00ce94ead3c32ed63e903cfd9d8480084a308d84', class: "mrd-file-field__error" }, this.error))));
|
|
1572
2169
|
}
|
|
1573
2170
|
static get watchers() { return {
|
|
1574
2171
|
"value": [{
|
|
@@ -2129,7 +2726,7 @@ const MrdImageField = class {
|
|
|
2129
2726
|
hasError ? 'mrd-image-field__zone--error' : '',
|
|
2130
2727
|
this.disabled || this.uploading ? 'mrd-image-field__zone--disabled' : '',
|
|
2131
2728
|
].filter(Boolean).join(' ');
|
|
2132
|
-
return (index.h(index.Host, { key: '
|
|
2729
|
+
return (index.h(index.Host, { key: '97db2df72839f36b7a46e153a5dd1c208c52b522' }, index.h("div", { key: 'c8f2d3d858f90d322d26082aaf5adb57acfc78f4', class: "mrd-image-field" }, this.label && (index.h("label", { key: '6625e5031ff0b7c06f76c1ea0387f1bd5c1858a4', class: `mrd-image-field__label${this.required ? ' mrd-image-field__label--required' : ''}` }, this.label)), index.h("div", { key: '364216e6a96e845e21c42e821fdff02bd2612ff8', class: zoneClass, onClick: this.handleZoneClick, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave, onDrop: this.handleDrop }, index.h("input", { key: '0487706ddd9f48cda1cb0c2a178809d90674486b', ref: el => (this.fileInputRef = el), class: "mrd-image-field__input", type: "file", name: this.name, accept: this.accept, disabled: this.disabled || this.uploading, required: this.required && !this.previewUrl, onChange: this.handleInputChange }), this.previewUrl ? (index.h("div", { class: "mrd-image-field__preview-container" }, index.h("div", { class: "mrd-image-field__preview-thumb" }, index.h("img", { class: "mrd-image-field__preview", src: this.previewUrl, alt: this.fileName }), this.uploading && index.h("div", { class: "mrd-image-field__preview-overlay" }, index.h("span", { class: "mrd-image-field__spinner" }))), index.h("div", { class: "mrd-image-field__preview-info" }, index.h("span", { class: "mrd-image-field__preview-name" }, this.fileName), this.uploading && (index.h("span", { class: "mrd-image-field__upload-status" }, t('loading', this.locale)))), !this.uploading && (index.h("button", { class: "mrd-image-field__clear", type: "button", onClick: this.handleClear, "aria-label": t('clear', this.locale) }, t('remove', this.locale))))) : (index.h("div", { class: "mrd-image-field__prompt" }, index.h("svg", { class: "mrd-image-field__upload-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), index.h("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), index.h("polyline", { points: "21 15 16 10 5 21" })), index.h("span", null, t('drop_file_here', this.locale), ' ', index.h("span", { class: "mrd-image-field__browse" }, t('browse', this.locale)))))), hasError && index.h("span", { key: 'bd505ef4f4b67c4e9138d8825c6e600f583f4cab', class: "mrd-image-field__error" }, this.error))));
|
|
2133
2730
|
}
|
|
2134
2731
|
static get watchers() { return {
|
|
2135
2732
|
"value": [{
|
|
@@ -2243,7 +2840,7 @@ class CellRenderer {
|
|
|
2243
2840
|
}
|
|
2244
2841
|
}
|
|
2245
2842
|
|
|
2246
|
-
const mrdLayoutSectionScss = () => `.mrd-layout-section.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-800)}.mrd-layout-section__field.sc-mrd-layout-section{display:grid;grid-template-columns:200px 1fr;align-items:baseline;gap:0 var(--mrd-space-2);padding:var(--mrd-space-1) 0}.mrd-layout-section__field-label.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-normal);color:var(--mrd-color-neutral-500);padding-top:1px}.mrd-layout-section__field-value.sc-mrd-layout-section{font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800);word-break:break-word;display:inline-flex;align-items:center;gap:var(--mrd-space-1)}.mrd-layout-section__history-wrap.sc-mrd-layout-section{position:relative;display:inline-flex;align-items:center}.mrd-layout-section__history-btn.sc-mrd-layout-section{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;padding:0;background:transparent;border:none;border-radius:var(--mrd-border-radius-sm);color:var(--mrd-color-neutral-400);cursor:pointer;flex-shrink:0;transition:color var(--mrd-transition-fast), background-color var(--mrd-transition-fast)}.mrd-layout-section__history-btn.sc-mrd-layout-section:hover{color:var(--mrd-color-neutral-700);background-color:var(--mrd-color-neutral-100)}.mrd-layout-section__history-btn.sc-mrd-layout-section:focus{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-layout-section__history-icon.sc-mrd-layout-section{width:0.875rem;height:0.875rem}.mrd-layout-section__history-popover.sc-mrd-layout-section{position:absolute;top:calc(100% + 0.25rem);left:0;min-width:24rem;max-width:24rem;background-color:var(--mrd-color-white);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);box-shadow:var(--mrd-shadow-md);padding:var(--mrd-space-1) 0;z-index:var(--mrd-z-dropdown)}.mrd-layout-section__history-entry.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-normal);color:var(--mrd-color-neutral-700);padding:var(--mrd-space-2) var(--mrd-space-3);line-height:var(--mrd-line-height-normal)}.mrd-layout-section__history-entry.sc-mrd-layout-section:not(:last-child){border-bottom:var(--mrd-border-width) solid var(--mrd-color-neutral-100)}.mrd-layout-section__field-header.sc-mrd-layout-section{font-size:var(--mrd-font-size-2xl);font-weight:var(--mrd-font-weight-bold);color:var(--mrd-color-neutral-900);margin:0 0 var(--mrd-space-4) 0;padding:0}.mrd-layout-section__header.sc-mrd-layout-section{font-size:var(--mrd-font-size-xl);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-800);margin:var(--mrd-space-4) 0 var(--mrd-space-2) 0;padding:0}.mrd-layout-section__text.sc-mrd-layout-section{font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-700);line-height:var(--mrd-line-height-relaxed);margin:var(--mrd-space-2) 0}.mrd-layout-section__navigate.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-2);padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:1px solid var(--mrd-color-neutral-300);border-radius:var(--mrd-border-radius);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-primary);cursor:pointer;margin:var(--mrd-space-2) 0}.mrd-layout-section__navigate.sc-mrd-layout-section:hover{background-color:var(--mrd-color-primary-light);border-color:var(--mrd-color-primary)}.mrd-layout-section__link.sc-mrd-layout-section{color:var(--mrd-color-primary);text-decoration:none}.mrd-layout-section__link.sc-mrd-layout-section:hover{text-decoration:underline}.mrd-layout-section__relation-link.sc-mrd-layout-section{background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-primary);cursor:pointer;text-align:left}.mrd-layout-section__relation-link.sc-mrd-layout-section:hover{text-decoration:underline}.mrd-layout-section__download-link.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-1);background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-primary);cursor:pointer;text-align:left}.mrd-layout-section__download-link.sc-mrd-layout-section:hover{text-decoration:underline;color:var(--mrd-color-primary-dark)}.mrd-layout-section__file-icon.sc-mrd-layout-section{flex-shrink:0;width:1rem;height:1rem}.mrd-layout-section__boolean--true.sc-mrd-layout-section{color:var(--mrd-color-success);font-weight:var(--mrd-font-weight-semibold)}.mrd-layout-section__boolean--false.sc-mrd-layout-section{color:var(--mrd-color-neutral-400)}.mrd-layout-section__field--block.sc-mrd-layout-section{grid-template-columns:1fr}.mrd-layout-section__badge.sc-mrd-layout-section{display:inline-block;font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium);padding:2px var(--mrd-space-3);border-radius:10px}.mrd-layout-section__badge-dot-row.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-2)}.mrd-layout-section__badge-dot.sc-mrd-layout-section{display:inline-block;width:10px;height:10px;border-radius:50%;flex-shrink:0}.mrd-layout-section__secret-masked.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-label-color);letter-spacing:0.15em;user-select:none;pointer-events:none}.mrd-layout-section__pre.sc-mrd-layout-section{font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);background-color:var(--mrd-color-neutral-50);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-border-radius);padding:var(--mrd-space-3);margin:0;max-height:calc(10 * 1.5 * var(--mrd-font-size-xs));overflow-x:auto;overflow-y:auto;white-space:pre-wrap;word-break:break-word}.mrd-layout-section__group.sc-mrd-layout-section{margin:var(--mrd-space-4) 0}.mrd-layout-section__group-title.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-500);margin:0 0 var(--mrd-space-2) 0;padding-bottom:0;letter-spacing:0.01em}.mrd-layout-section__related-view.sc-mrd-layout-section{margin:var(--mrd-space-4) 0}.mrd-layout-section__related-view-title.sc-mrd-layout-section{font-size:var(--mrd-font-size-lg);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-800);margin:0 0 var(--mrd-space-3) 0}.mrd-layout-section__doc-toolbar.sc-mrd-layout-section{display:flex;align-items:center;justify-content:flex-end;gap:var(--mrd-space-2);padding:var(--mrd-space-2) 0}.mrd-layout-section__seg.sc-mrd-layout-section{display:inline-flex;gap:2px;padding:2px;background:var(--mrd-color-neutral-100);border-radius:var(--mrd-border-radius)}.mrd-layout-section__seg-btn.sc-mrd-layout-section{width:1.875rem;height:1.625rem;display:grid;place-items:center;border:none;background:none;border-radius:var(--mrd-border-radius-sm);color:var(--mrd-color-neutral-500);cursor:pointer;transition:color var(--mrd-transition-fast), background var(--mrd-transition-fast)}.mrd-layout-section__seg-btn.sc-mrd-layout-section:hover{color:var(--mrd-color-neutral-800)}.mrd-layout-section__seg-btn[aria-pressed='true'].sc-mrd-layout-section{background:var(--mrd-color-white);color:var(--mrd-color-primary-dark);box-shadow:var(--mrd-shadow-sm)}.mrd-layout-section__seg-btn.sc-mrd-layout-section svg.sc-mrd-layout-section{width:1rem;height:1rem}.mrd-layout-section__search.sc-mrd-layout-section{position:relative;margin:var(--mrd-space-2) 0}.mrd-layout-section__search-wrap.sc-mrd-layout-section{position:relative}.mrd-layout-section__search-icon.sc-mrd-layout-section{position:absolute;left:var(--mrd-input-padding-x);top:50%;transform:translateY(-50%);width:1rem;height:1rem;color:var(--mrd-color-neutral-400);pointer-events:none}.mrd-layout-section__search-input.sc-mrd-layout-section{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x) var(--mrd-input-padding-y) calc(var(--mrd-input-padding-x) + 1rem + var(--mrd-space-2));font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);outline:none;appearance:none;box-sizing:border-box}.mrd-layout-section__search-input.sc-mrd-layout-section:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-layout-section__search-input.sc-mrd-layout-section::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-layout-section__search-results.sc-mrd-layout-section{position:absolute;top:100%;left:0;right:0;background-color:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-300);border-top:none;border-radius:0 0 var(--mrd-border-radius) var(--mrd-border-radius);box-shadow:var(--mrd-shadow-sm);z-index:100;max-height:300px;overflow-y:auto;list-style:none;margin:0;padding:var(--mrd-space-1) 0}.mrd-layout-section__search-result.sc-mrd-layout-section{margin:0;padding:0}.mrd-layout-section__search-result-btn.sc-mrd-layout-section{display:flex;flex-direction:column;width:100%;padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:none;text-align:left;cursor:pointer;font-family:var(--mrd-font-family)}.mrd-layout-section__search-result-btn.sc-mrd-layout-section:hover{background-color:var(--mrd-color-primary-light)}.mrd-layout-section__search-result-label.sc-mrd-layout-section{font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800)}.mrd-layout-section__search-result-desc.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);margin-top:var(--mrd-space-1)}.mrd-layout-section__image-thumb-btn.sc-mrd-layout-section{background:none;border:none;padding:0;cursor:pointer;display:inline-block;border-radius:var(--mrd-border-radius);overflow:hidden;line-height:0}.mrd-layout-section__image-thumb-btn.sc-mrd-layout-section:hover .mrd-layout-section__image-thumb.sc-mrd-layout-section{opacity:0.85}.mrd-layout-section__image-thumb.sc-mrd-layout-section{display:block;max-width:160px;max-height:100px;border-radius:var(--mrd-border-radius);object-fit:cover;transition:opacity 0.15s}.mrd-layout-section__modal-backdrop.sc-mrd-layout-section{position:fixed;inset:0;background:rgba(0, 0, 0, 0.6);z-index:300;display:flex;align-items:center;justify-content:center}.mrd-layout-section__modal.sc-mrd-layout-section{position:relative;background:#fff;border-radius:var(--mrd-border-radius);padding:var(--mrd-space-3);max-width:min(90vw, 900px);max-height:90vh;display:flex;align-items:center;justify-content:center;box-shadow:var(--mrd-shadow-lg)}.mrd-layout-section__modal-close.sc-mrd-layout-section{position:absolute;top:var(--mrd-space-2);right:var(--mrd-space-2);background:rgba(0, 0, 0, 0.5);border:none;border-radius:50%;width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:#fff;cursor:pointer;font-size:var(--mrd-font-size-sm);line-height:1;z-index:1}.mrd-layout-section__modal-close.sc-mrd-layout-section:hover{background:rgba(0, 0, 0, 0.8)}.mrd-layout-section__modal-image.sc-mrd-layout-section{display:block;max-width:100%;max-height:calc(90vh - 2rem);border-radius:var(--mrd-border-radius);object-fit:contain}`;
|
|
2843
|
+
const mrdLayoutSectionScss = () => `.mrd-layout-section.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-800)}.mrd-layout-section__field.sc-mrd-layout-section{display:grid;grid-template-columns:200px 1fr;align-items:baseline;gap:0 var(--mrd-space-2);padding:var(--mrd-space-1) 0}.mrd-layout-section__field-label.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-normal);color:var(--mrd-color-neutral-500);padding-top:1px}.mrd-layout-section__field-value.sc-mrd-layout-section{font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800);word-break:break-word;display:inline-flex;align-items:center;gap:var(--mrd-space-1)}.mrd-layout-section__history-wrap.sc-mrd-layout-section{position:relative;display:inline-flex;align-items:center}.mrd-layout-section__history-btn.sc-mrd-layout-section{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;padding:0;background:transparent;border:none;border-radius:var(--mrd-border-radius-sm);color:var(--mrd-color-neutral-400);cursor:pointer;flex-shrink:0;transition:color var(--mrd-transition-fast), background-color var(--mrd-transition-fast)}.mrd-layout-section__history-btn.sc-mrd-layout-section:hover{color:var(--mrd-color-neutral-700);background-color:var(--mrd-color-neutral-100)}.mrd-layout-section__history-btn.sc-mrd-layout-section:focus{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-layout-section__history-icon.sc-mrd-layout-section{width:0.875rem;height:0.875rem}.mrd-layout-section__history-popover.sc-mrd-layout-section{position:absolute;top:calc(100% + 0.25rem);left:0;min-width:24rem;max-width:24rem;background-color:var(--mrd-color-white);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);box-shadow:var(--mrd-shadow-md);padding:var(--mrd-space-1) 0;z-index:var(--mrd-z-dropdown)}.mrd-layout-section__history-entry.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-normal);color:var(--mrd-color-neutral-700);padding:var(--mrd-space-2) var(--mrd-space-3);line-height:var(--mrd-line-height-normal)}.mrd-layout-section__history-entry.sc-mrd-layout-section:not(:last-child){border-bottom:var(--mrd-border-width) solid var(--mrd-color-neutral-100)}.mrd-layout-section__field-header.sc-mrd-layout-section{font-size:var(--mrd-font-size-2xl);font-weight:var(--mrd-font-weight-bold);color:var(--mrd-color-neutral-900);margin:0 0 var(--mrd-space-4) 0;padding:0}.mrd-layout-section__header.sc-mrd-layout-section{font-size:var(--mrd-font-size-xl);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-800);margin:var(--mrd-space-4) 0 var(--mrd-space-2) 0;padding:0}.mrd-layout-section__text.sc-mrd-layout-section{font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-700);line-height:var(--mrd-line-height-relaxed);margin:var(--mrd-space-2) 0}.mrd-layout-section__navigate.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-2);padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:1px solid var(--mrd-color-neutral-300);border-radius:var(--mrd-border-radius);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-primary);cursor:pointer;margin:var(--mrd-space-2) 0}.mrd-layout-section__navigate.sc-mrd-layout-section:hover{background-color:var(--mrd-color-primary-light);border-color:var(--mrd-color-primary)}.mrd-layout-section__link.sc-mrd-layout-section{color:var(--mrd-color-primary);text-decoration:none}.mrd-layout-section__link.sc-mrd-layout-section:hover{text-decoration:underline}.mrd-layout-section__relation-link.sc-mrd-layout-section{background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-primary);cursor:pointer;text-align:left}.mrd-layout-section__relation-link.sc-mrd-layout-section:hover{text-decoration:underline}.mrd-layout-section__download-link.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-1);background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-primary);cursor:pointer;text-align:left}.mrd-layout-section__download-link.sc-mrd-layout-section:hover{text-decoration:underline;color:var(--mrd-color-primary-dark)}.mrd-layout-section__file-icon.sc-mrd-layout-section{flex-shrink:0;width:1rem;height:1rem}.mrd-layout-section__boolean--true.sc-mrd-layout-section{color:var(--mrd-color-success);font-weight:var(--mrd-font-weight-semibold)}.mrd-layout-section__boolean--false.sc-mrd-layout-section{color:var(--mrd-color-neutral-400)}.mrd-layout-section__field--block.sc-mrd-layout-section{grid-template-columns:1fr}.mrd-layout-section__badge.sc-mrd-layout-section{display:inline-block;font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium);padding:2px var(--mrd-space-3);border-radius:10px}.mrd-layout-section__badge-dot-row.sc-mrd-layout-section{display:inline-flex;align-items:center;gap:var(--mrd-space-2)}.mrd-layout-section__badge-dot.sc-mrd-layout-section{display:inline-block;width:10px;height:10px;border-radius:50%;flex-shrink:0}.mrd-layout-section__secret-masked.sc-mrd-layout-section{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-label-color);letter-spacing:0.15em;user-select:none;pointer-events:none}.mrd-layout-section__pre.sc-mrd-layout-section{font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);background-color:var(--mrd-color-neutral-50);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-border-radius);padding:var(--mrd-space-3);margin:0;max-height:calc(10 * 1.5 * var(--mrd-font-size-xs));overflow-x:auto;overflow-y:auto;white-space:pre-wrap;word-break:break-word}.mrd-layout-section__group.sc-mrd-layout-section{margin:var(--mrd-space-4) 0}.mrd-layout-section__group-title.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-500);margin:0 0 var(--mrd-space-2) 0;padding-bottom:0;letter-spacing:0.01em}.mrd-layout-section__related-view.sc-mrd-layout-section{margin:var(--mrd-space-4) 0}.mrd-layout-section__related-view-title.sc-mrd-layout-section{font-size:var(--mrd-font-size-lg);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-800);margin:0 0 var(--mrd-space-3) 0}.mrd-layout-section__search.sc-mrd-layout-section{position:relative;margin:var(--mrd-space-2) 0}.mrd-layout-section__search-wrap.sc-mrd-layout-section{position:relative}.mrd-layout-section__search-icon.sc-mrd-layout-section{position:absolute;left:var(--mrd-input-padding-x);top:50%;transform:translateY(-50%);width:1rem;height:1rem;color:var(--mrd-color-neutral-400);pointer-events:none}.mrd-layout-section__search-input.sc-mrd-layout-section{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x) var(--mrd-input-padding-y) calc(var(--mrd-input-padding-x) + 1rem + var(--mrd-space-2));font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-input-color);background-color:var(--mrd-input-bg);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);outline:none;appearance:none;box-sizing:border-box}.mrd-layout-section__search-input.sc-mrd-layout-section:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-layout-section__search-input.sc-mrd-layout-section::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-layout-section__search-results.sc-mrd-layout-section{position:absolute;top:100%;left:0;right:0;background-color:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-300);border-top:none;border-radius:0 0 var(--mrd-border-radius) var(--mrd-border-radius);box-shadow:var(--mrd-shadow-sm);z-index:100;max-height:300px;overflow-y:auto;list-style:none;margin:0;padding:var(--mrd-space-1) 0}.mrd-layout-section__search-result.sc-mrd-layout-section{margin:0;padding:0}.mrd-layout-section__search-result-btn.sc-mrd-layout-section{display:flex;flex-direction:column;width:100%;padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:none;text-align:left;cursor:pointer;font-family:var(--mrd-font-family)}.mrd-layout-section__search-result-btn.sc-mrd-layout-section:hover{background-color:var(--mrd-color-primary-light)}.mrd-layout-section__search-result-label.sc-mrd-layout-section{font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800)}.mrd-layout-section__search-result-desc.sc-mrd-layout-section{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);margin-top:var(--mrd-space-1)}.mrd-layout-section__image-thumb-btn.sc-mrd-layout-section{background:none;border:none;padding:0;cursor:pointer;display:inline-block;border-radius:var(--mrd-border-radius);overflow:hidden;line-height:0}.mrd-layout-section__image-thumb-btn.sc-mrd-layout-section:hover .mrd-layout-section__image-thumb.sc-mrd-layout-section{opacity:0.85}.mrd-layout-section__image-thumb.sc-mrd-layout-section{display:block;max-width:160px;max-height:100px;border-radius:var(--mrd-border-radius);object-fit:cover;transition:opacity 0.15s}.mrd-layout-section__modal-backdrop.sc-mrd-layout-section{position:fixed;inset:0;background:rgba(0, 0, 0, 0.6);z-index:300;display:flex;align-items:center;justify-content:center}.mrd-layout-section__modal.sc-mrd-layout-section{position:relative;background:#fff;border-radius:var(--mrd-border-radius);padding:var(--mrd-space-3);max-width:min(90vw, 900px);max-height:90vh;display:flex;align-items:center;justify-content:center;box-shadow:var(--mrd-shadow-lg)}.mrd-layout-section__modal-close.sc-mrd-layout-section{position:absolute;top:var(--mrd-space-2);right:var(--mrd-space-2);background:rgba(0, 0, 0, 0.5);border:none;border-radius:50%;width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:#fff;cursor:pointer;font-size:var(--mrd-font-size-sm);line-height:1;z-index:1}.mrd-layout-section__modal-close.sc-mrd-layout-section:hover{background:rgba(0, 0, 0, 0.8)}.mrd-layout-section__modal-image.sc-mrd-layout-section{display:block;max-width:100%;max-height:calc(90vh - 2rem);border-radius:var(--mrd-border-radius);object-fit:contain}`;
|
|
2247
2844
|
|
|
2248
2845
|
const MrdLayoutSection = class {
|
|
2249
2846
|
constructor(hostRef) {
|
|
@@ -2256,6 +2853,9 @@ const MrdLayoutSection = class {
|
|
|
2256
2853
|
this.mrdViewAction = index.createEvent(this, "mrdViewAction");
|
|
2257
2854
|
this.mrdLoadViewAggregations = index.createEvent(this, "mrdLoadViewAggregations");
|
|
2258
2855
|
this.mrdLoadViewDistinct = index.createEvent(this, "mrdLoadViewDistinct");
|
|
2856
|
+
this.mrdUpdateObject = index.createEvent(this, "mrdUpdateObject");
|
|
2857
|
+
this.mrdViewUpload = index.createEvent(this, "mrdViewUpload");
|
|
2858
|
+
this.mrdCreateObject = index.createEvent(this, "mrdCreateObject");
|
|
2259
2859
|
/** Items from one layout entry in ClientDashboardMetadata.layouts[]. */
|
|
2260
2860
|
this.items = [];
|
|
2261
2861
|
/** Record data object; keys are field names, _links holds relation and related-view links. */
|
|
@@ -2273,8 +2873,6 @@ const MrdLayoutSection = class {
|
|
|
2273
2873
|
this.imagePreviewUrl = null;
|
|
2274
2874
|
this.imagePreviews = {};
|
|
2275
2875
|
this.openHistoryField = null;
|
|
2276
|
-
/** Per-view display mode for document collection views. Default 'tree'. */
|
|
2277
|
-
this.docViewMode = {};
|
|
2278
2876
|
this.historyClickOutside = null;
|
|
2279
2877
|
this.searchTimers = {};
|
|
2280
2878
|
this.handleViewLoadPage = (e, name) => {
|
|
@@ -2391,6 +2989,20 @@ const MrdLayoutSection = class {
|
|
|
2391
2989
|
if (list === null || list === void 0 ? void 0 : list.setDistinct)
|
|
2392
2990
|
await list.setDistinct(nodeId, values);
|
|
2393
2991
|
}
|
|
2992
|
+
/** Inject the uploaded file reference for a dropped file, so the document view
|
|
2993
|
+
* can request creation of the new document (see mrdViewUpload). */
|
|
2994
|
+
async setViewFileReference(name, uri) {
|
|
2995
|
+
const list = this.el.querySelector(`mrd-document-list[data-doclist="${name}"]`);
|
|
2996
|
+
if (list === null || list === void 0 ? void 0 : list.setFileReference)
|
|
2997
|
+
await list.setFileReference(uri);
|
|
2998
|
+
}
|
|
2999
|
+
/** Inject the created document's href after a file-drop create, so the
|
|
3000
|
+
* optimistic row becomes navigable (see mrdCreateObject). */
|
|
3001
|
+
async setViewCreatedObject(name, href) {
|
|
3002
|
+
const list = this.el.querySelector(`mrd-document-list[data-doclist="${name}"]`);
|
|
3003
|
+
if (list === null || list === void 0 ? void 0 : list.setCreatedHref)
|
|
3004
|
+
await list.setCreatedHref(href);
|
|
3005
|
+
}
|
|
2394
3006
|
/** Provide a resolved URL for an IMAGE field. Shows as thumbnail; clicking opens the lightbox. */
|
|
2395
3007
|
async setImagePreview(fieldName, url) {
|
|
2396
3008
|
this.imagePreviews = Object.assign(Object.assign({}, this.imagePreviews), { [fieldName]: url });
|
|
@@ -2539,7 +3151,7 @@ const MrdLayoutSection = class {
|
|
|
2539
3151
|
return (index.h("div", { class: "mrd-layout-section__search", key: `search-${dataClass}` }, index.h("div", { class: "mrd-layout-section__search-wrap" }, index.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" }, index.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" })), index.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 && (index.h("ul", { class: "mrd-layout-section__search-results" }, results.map(r => (index.h("li", { key: r.id, class: "mrd-layout-section__search-result" }, index.h("button", { class: "mrd-layout-section__search-result-btn", onClick: () => this.mrdNavigate.emit({ href: r.id, label: r.label }) }, index.h("span", { class: "mrd-layout-section__search-result-label" }, r.label), r.description && index.h("span", { class: "mrd-layout-section__search-result-desc" }, r.description)))))))));
|
|
2540
3152
|
}
|
|
2541
3153
|
renderRelatedView(item) {
|
|
2542
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
3154
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2543
3155
|
const key = this.viewKeyFor(item);
|
|
2544
3156
|
if (!key)
|
|
2545
3157
|
return null;
|
|
@@ -2552,25 +3164,55 @@ const MrdLayoutSection = class {
|
|
|
2552
3164
|
// The API publishes `archetypes` on the VIEW/RELATED_VIEW item itself
|
|
2553
3165
|
// (sibling of `view`), not inside `view`.
|
|
2554
3166
|
const docArchetype = index$1.resolveArchetype((_g = item.archetypes) !== null && _g !== void 0 ? _g : (_h = item.view) === null || _h === void 0 ? void 0 : _h.archetypes, index$1.ARCHETYPE_DOCUMENT);
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
3167
|
+
// Canonical parent href for single-container seeding: use the RELATED_VIEW's
|
|
3168
|
+
// fromClass (base class) rather than the route class, so polymorphic subtypes
|
|
3169
|
+
// resolve to the same container the documents actually reference.
|
|
3170
|
+
const containerHref = this.buildContainerHref(item, selfHref, parentId);
|
|
3171
|
+
return (index.h("div", { class: "mrd-layout-section__related-view", key: `view-${key}` }, showTitle && item.label && index.h("h3", { class: "mrd-layout-section__related-view-title" }, item.label), docArchetype
|
|
3172
|
+
? this.renderDocumentContainer(item, key, parentId, docArchetype, containerHref)
|
|
2558
3173
|
: this.renderTable(item, key, parentId)));
|
|
2559
3174
|
}
|
|
2560
|
-
/**
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
3175
|
+
/** Build the canonical parent href `/{base}/{tenant}/{fromClass}/{parentId}` from
|
|
3176
|
+
* the object's self href. Empty unless it is a RELATED_VIEW with a fromClass. */
|
|
3177
|
+
buildContainerHref(item, selfHref, parentId) {
|
|
3178
|
+
if (item.type !== index$1.ClientLayoutItemType.RELATED_VIEW || !item.fromClass || !parentId)
|
|
3179
|
+
return '';
|
|
3180
|
+
const segs = selfHref.split('/').filter(Boolean);
|
|
3181
|
+
if (segs.length < 2)
|
|
3182
|
+
return '';
|
|
3183
|
+
const [base, tenant] = segs;
|
|
3184
|
+
return `/${base}/${tenant}/${item.fromClass}/${parentId}`;
|
|
3185
|
+
}
|
|
3186
|
+
/** Document collection view: owns the view-switch + collection actions and
|
|
3187
|
+
* swaps between the folder tree and the flat table. Events are re-emitted to
|
|
3188
|
+
* the host with the view key, exactly as the raw list/table events were. */
|
|
3189
|
+
renderDocumentContainer(item, key, parentId, archetype, containerHref) {
|
|
3190
|
+
return (index.h("mrd-document-container", { item: item, archetype: archetype, parentId: parentId, containerHref: containerHref, viewKey: key, locale: this.locale, onMrdLoadDistinct: (e) => {
|
|
2566
3191
|
e.stopPropagation();
|
|
2567
3192
|
this.mrdLoadViewDistinct.emit(Object.assign({ name: key }, e.detail));
|
|
2568
3193
|
}, onMrdLoadPage: (e) => {
|
|
2569
3194
|
e.stopPropagation();
|
|
2570
3195
|
this.mrdLoadViewPage.emit(Object.assign({ name: key }, e.detail));
|
|
3196
|
+
}, onMrdLoadAggregations: (e) => {
|
|
3197
|
+
var _a;
|
|
3198
|
+
e.stopPropagation();
|
|
3199
|
+
this.mrdLoadViewAggregations.emit(Object.assign({ name: key, dataClass: (_a = item.dataClass) !== null && _a !== void 0 ? _a : key }, e.detail));
|
|
2571
3200
|
}, onMrdNavigate: (e) => {
|
|
2572
3201
|
e.stopPropagation();
|
|
2573
3202
|
this.mrdNavigate.emit(e.detail);
|
|
3203
|
+
}, onMrdAction: (e) => {
|
|
3204
|
+
var _a;
|
|
3205
|
+
e.stopPropagation();
|
|
3206
|
+
this.mrdViewAction.emit(Object.assign({ name: key, dataClass: (_a = item.dataClass) !== null && _a !== void 0 ? _a : key }, e.detail));
|
|
3207
|
+
}, onMrdUpdateObject: (e) => {
|
|
3208
|
+
e.stopPropagation();
|
|
3209
|
+
this.mrdUpdateObject.emit(e.detail);
|
|
3210
|
+
}, onMrdUpload: (e) => {
|
|
3211
|
+
e.stopPropagation();
|
|
3212
|
+
this.mrdViewUpload.emit(Object.assign({ name: key }, e.detail));
|
|
3213
|
+
}, onMrdCreateObject: (e) => {
|
|
3214
|
+
e.stopPropagation();
|
|
3215
|
+
this.mrdCreateObject.emit(Object.assign({ name: key }, e.detail));
|
|
2574
3216
|
} }));
|
|
2575
3217
|
}
|
|
2576
3218
|
renderTable(item, key, parentId) {
|
|
@@ -2641,7 +3283,7 @@ const MrdLayoutSection = class {
|
|
|
2641
3283
|
}
|
|
2642
3284
|
render() {
|
|
2643
3285
|
const docArchetype = index$1.resolveArchetype(this.archetypes, index$1.ARCHETYPE_DOCUMENT);
|
|
2644
|
-
return (index.h(index.Host, { key: '
|
|
3286
|
+
return (index.h(index.Host, { key: '231f5c3e282375b5850291611645fe3c904831bb' }, index.h("div", { key: '314e39ec3aa1eabeb1a98f6e6d63fcf07e13ccec', class: "mrd-layout-section" }, docArchetype
|
|
2645
3287
|
? this.renderDocumentObject(docArchetype)
|
|
2646
3288
|
: this.items.map(item => this.renderItem(item))), this.renderImageModal()));
|
|
2647
3289
|
}
|
|
@@ -2783,7 +3425,7 @@ const MrdLongtextField = class {
|
|
|
2783
3425
|
}
|
|
2784
3426
|
render() {
|
|
2785
3427
|
const hasError = !!this.error;
|
|
2786
|
-
return (index.h(index.Host, { key: '
|
|
3428
|
+
return (index.h(index.Host, { key: 'f00f81944748f8f09e22d44befe5e288456b7cc8' }, index.h("div", { key: '7b0ae9cf5b6b684cddb648fe4db6005494322535', class: "mrd-longtext-field" }, this.label && (index.h("label", { key: '3fc6a8710d0e98fe685c45d214a88ae1b0947973', class: `mrd-longtext-field__label${this.required ? ' mrd-longtext-field__label--required' : ''}` }, this.label)), this.disabled ? (index.h("pre", { class: "mrd-longtext-field__content" }, this.value)) : (index.h("textarea", { class: `mrd-longtext-field__input${hasError ? ' mrd-longtext-field__input--error' : ''}`, name: this.name, placeholder: this.placeholder, required: this.required, rows: 10, onInput: this.handleInput, onBlur: this.handleBlur }, this.value)), hasError && index.h("span", { key: 'e96f1dbc6c00a1602f4ce3c97d514a229aeb7cb7', class: "mrd-longtext-field__error" }, this.error))));
|
|
2787
3429
|
}
|
|
2788
3430
|
};
|
|
2789
3431
|
MrdLongtextField.style = mrdLongtextFieldScss();
|
|
@@ -2859,7 +3501,7 @@ const MrdNumberField = class {
|
|
|
2859
3501
|
const hasError = !!this.error;
|
|
2860
3502
|
const suffix = this.dataType === index$1.ClientLayoutItemFieldDataType.PERCENTAGE ? '%' :
|
|
2861
3503
|
this.dataType === index$1.ClientLayoutItemFieldDataType.DECIMAL ? '' : '';
|
|
2862
|
-
return (index.h(index.Host, { key: '
|
|
3504
|
+
return (index.h(index.Host, { key: 'b034a3cc8d841641c0ec167e138904586b044121' }, index.h("div", { key: '7379bfadb8bd0c4e0a945a37013053a4e22477ab', class: "mrd-number-field" }, this.label && (index.h("label", { key: '5518d40b7158e17704633c2b95ac7e3efc0c5568', class: `mrd-number-field__label${this.required ? ' mrd-number-field__label--required' : ''}` }, this.label)), index.h("div", { key: '38ad9f3c945d66c23bd77c743306e916eaefed7f', class: "mrd-number-field__input-wrapper" }, index.h("input", { key: 'ac8b4bc1ea4431cc9306664522ebfda21760ae83', class: `mrd-number-field__input${hasError ? ' mrd-number-field__input--error' : ''}`, type: "text", inputMode: "decimal", name: this.name, value: this.displayValue, placeholder: this.placeholder || (suffix ? `0${suffix}` : '0'), required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur, onFocus: this.handleFocus })), hasError && index.h("span", { key: '09f5a58b769c81acdf4bdd48f9325934c4bb875d', class: "mrd-number-field__error" }, this.error))));
|
|
2863
3505
|
}
|
|
2864
3506
|
};
|
|
2865
3507
|
MrdNumberField.style = mrdNumberFieldScss();
|
|
@@ -3153,9 +3795,9 @@ const MrdSecretField = class {
|
|
|
3153
3795
|
}
|
|
3154
3796
|
render() {
|
|
3155
3797
|
const hasError = !!this.error;
|
|
3156
|
-
return (index.h(index.Host, { key: '
|
|
3798
|
+
return (index.h(index.Host, { key: 'c850ec5bc5967ca0aefca7d7cb65ecae121a9dc1' }, index.h("div", { key: '3249ffbc441422af054a20806dd8dfce954a8ffc', class: "mrd-secret-field" }, this.label && (index.h("label", { key: '0b4a86da9cafad32f153af1bc5487a4e9b941e2f', class: `mrd-secret-field__label${this.required ? ' mrd-secret-field__label--required' : ''}` }, this.label)), this.disabled
|
|
3157
3799
|
? (index.h("span", { class: "mrd-secret-field__masked", "aria-label": this.label }, this.value ? '••••••••' : ''))
|
|
3158
|
-
: (index.h("input", { class: `mrd-secret-field__input${hasError ? ' mrd-secret-field__input--error' : ''}`, type: "password", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, autocomplete: "new-password", onInput: this.handleInput, onBlur: this.handleBlur })), hasError && index.h("span", { key: '
|
|
3800
|
+
: (index.h("input", { class: `mrd-secret-field__input${hasError ? ' mrd-secret-field__input--error' : ''}`, type: "password", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, autocomplete: "new-password", onInput: this.handleInput, onBlur: this.handleBlur })), hasError && index.h("span", { key: 'b0d0105f3d43d2e214f070b24e745dbce0e33977', class: "mrd-secret-field__error" }, this.error))));
|
|
3159
3801
|
}
|
|
3160
3802
|
};
|
|
3161
3803
|
MrdSecretField.style = mrdSecretFieldScss();
|
|
@@ -4302,7 +4944,7 @@ const MrdTextField = class {
|
|
|
4302
4944
|
}
|
|
4303
4945
|
render() {
|
|
4304
4946
|
const hasError = !!this.error;
|
|
4305
|
-
return (index.h(index.Host, { key: '
|
|
4947
|
+
return (index.h(index.Host, { key: 'e9252b251faf98ab190e643b97c13fa32d12ef22' }, index.h("div", { key: '37f4259a111c293f2fe12f321f08c00c25e77feb', class: "mrd-text-field" }, this.label && (index.h("label", { key: 'c59e0346fb71a765ea38629b03c06341567ed210', class: `mrd-text-field__label${this.required ? ' mrd-text-field__label--required' : ''}` }, this.label)), index.h("input", { key: 'dc09953a672472348719f29904d900966d945843', class: `mrd-text-field__input${hasError ? ' mrd-text-field__input--error' : ''}`, type: "text", name: this.name, value: this.value, placeholder: this.placeholder, required: this.required, disabled: this.disabled, onInput: this.handleInput, onBlur: this.handleBlur }), hasError && index.h("span", { key: '037653857a372854a16b28ebf8994b23e3e0d696', class: "mrd-text-field__error" }, this.error))));
|
|
4306
4948
|
}
|
|
4307
4949
|
};
|
|
4308
4950
|
MrdTextField.style = mrdTextFieldScss();
|
|
@@ -4376,7 +5018,7 @@ const MrdTextareaField = class {
|
|
|
4376
5018
|
}
|
|
4377
5019
|
}
|
|
4378
5020
|
render() {
|
|
4379
|
-
return (index.h(index.Host, { key: '
|
|
5021
|
+
return (index.h(index.Host, { key: 'fe7824c81e082c3f2c1cf18c11dde20cb1f40f2c' }, index.h("div", { key: 'adf394a7e146d16bc79006873a209b11d88b2e17', class: "mrd-textarea-field" }, this.label && (index.h("label", { key: '1b0dd2b4cf26c55a0af05c67a3178edc0c9d56c4', class: `mrd-textarea-field__label${this.required ? ' mrd-textarea-field__label--required' : ''}` }, this.label)), index.h("div", { key: '7c8fe88b222af0beed08db492aa9f6d890e0dc5b', class: `mrd-textarea-field__container${this.error ? ' mrd-textarea-field__container--error' : ''}` }, index.h("div", { key: '295968283e94812cb04660117c5bdeaf3647469c', class: "mrd-textarea-field__editor" })), this.error && index.h("span", { key: '5b5ab61053ab0792d4c249de04bd1d13b51469bf', class: "mrd-textarea-field__error" }, this.error))));
|
|
4380
5022
|
}
|
|
4381
5023
|
get el() { return index.getElement(this); }
|
|
4382
5024
|
};
|
|
@@ -4413,7 +5055,7 @@ const MrdTimeField = class {
|
|
|
4413
5055
|
}
|
|
4414
5056
|
render() {
|
|
4415
5057
|
const hasError = !!this.error;
|
|
4416
|
-
return (index.h(index.Host, { key: '
|
|
5058
|
+
return (index.h(index.Host, { key: '579219a478e31325b5a676465807c1d936724a2b' }, index.h("div", { key: '51b25f6e083a29989505c0ad79edbcd3b0060736', class: "mrd-time-field" }, this.label && (index.h("label", { key: '67d98bebb8803deea2d2a4a63f36706789ccd8c7', class: `mrd-time-field__label${this.required ? ' mrd-time-field__label--required' : ''}` }, this.label)), index.h("input", { key: '734741e0db1bdd5886fef37bba3b2f8d7200a0ab', class: `mrd-time-field__input${hasError ? ' mrd-time-field__input--error' : ''}`, type: "time", name: this.name, value: this.value, required: this.required, disabled: this.disabled, onChange: this.handleChange, onBlur: this.handleBlur }), hasError && index.h("span", { key: '0dbd168d14966dc56a77c97cd8fd8f9b208a4bf5', class: "mrd-time-field__error" }, this.error))));
|
|
4417
5059
|
}
|
|
4418
5060
|
};
|
|
4419
5061
|
MrdTimeField.style = mrdTimeFieldScss();
|
|
@@ -4422,6 +5064,7 @@ exports.mrd_boolean_field = MrdBooleanField;
|
|
|
4422
5064
|
exports.mrd_currency_field = MrdCurrencyField;
|
|
4423
5065
|
exports.mrd_date_field = MrdDateField;
|
|
4424
5066
|
exports.mrd_datetime_field = MrdDatetimeField;
|
|
5067
|
+
exports.mrd_document_container = MrdDocumentContainer;
|
|
4425
5068
|
exports.mrd_document_list = MrdDocumentList;
|
|
4426
5069
|
exports.mrd_document_view = MrdDocumentView;
|
|
4427
5070
|
exports.mrd_email_field = MrdEmailField;
|