@mmlogic/components 0.5.13 → 0.5.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{cell-renderer-BBebjBVz.js → cell-renderer-CLVKTVVQ.js} +113 -1
- package/dist/cjs/{client-layout-CqVuJumR.js → client-layout-Eg2VwW-7.js} +2 -0
- package/dist/cjs/index.cjs.js +2 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/mosterdcomponents.cjs.js +1 -1
- package/dist/cjs/{mrd-boolean-field_25.cjs.entry.js → mrd-boolean-field_28.cjs.entry.js} +1163 -356
- package/dist/cjs/mrd-merge-view.cjs.entry.js +4 -4
- package/dist/collection/collection-manifest.json +3 -0
- package/dist/collection/components/fields/mrd-textarea-field/mrd-textarea-field.js +47 -2
- package/dist/collection/components/form/mrd-form/mrd-form.css +29 -0
- package/dist/collection/components/form/mrd-form/mrd-form.js +44 -8
- package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.js +126 -13
- package/dist/collection/components/memo/mrd-memo-container/mrd-memo-container.css +204 -0
- package/dist/collection/components/memo/mrd-memo-container/mrd-memo-container.js +694 -0
- package/dist/collection/components/memo/mrd-memo-list/mrd-memo-list.css +150 -0
- package/dist/collection/components/memo/mrd-memo-list/mrd-memo-list.js +511 -0
- package/dist/collection/components/memo/mrd-memo-view/mrd-memo-view.css +108 -0
- package/dist/collection/components/memo/mrd-memo-view/mrd-memo-view.js +204 -0
- package/dist/collection/components/merge/mrd-merge-view/mrd-merge-view.js +2 -2
- package/dist/collection/components/table/mrd-table/mrd-table.css +36 -0
- package/dist/collection/components/table/mrd-table/mrd-table.js +146 -31
- package/dist/collection/components/table/mrd-table/table-parts.js +6 -2
- package/dist/collection/components/table/mrd-table/table-query.js +6 -0
- package/dist/collection/dev/app.js +17 -0
- package/dist/collection/types/client-layout.js +1 -0
- package/dist/collection/utils/i18n.js +112 -0
- package/dist/collection/utils/query-params.js +9 -0
- package/dist/components/client-layout.js +1 -1
- package/dist/components/i18n.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/mrd-form.js +1 -1
- package/dist/components/mrd-layout-section.js +1 -1
- package/dist/components/mrd-memo-container.d.ts +11 -0
- package/dist/components/mrd-memo-container.js +1 -0
- package/dist/components/mrd-memo-container2.js +1 -0
- package/dist/components/mrd-memo-list.d.ts +11 -0
- package/dist/components/mrd-memo-list.js +1 -0
- package/dist/components/mrd-memo-list2.js +1 -0
- package/dist/components/mrd-memo-view.d.ts +11 -0
- package/dist/components/mrd-memo-view.js +1 -0
- package/dist/components/mrd-memo-view2.js +1 -0
- package/dist/components/mrd-merge-view.js +1 -1
- package/dist/components/mrd-table2.js +1 -1
- package/dist/components/mrd-textarea-field2.js +1 -1
- package/dist/components/query-params.js +1 -1
- package/dist/components/table-query.js +1 -0
- package/dist/esm/{cell-renderer-CC8-MtvQ.js → cell-renderer-4NKEzZWw.js} +113 -1
- package/dist/esm/{client-layout-Bc42CfJB.js → client-layout-BJkVeSq6.js} +2 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/mosterdcomponents.js +1 -1
- package/dist/esm/{mrd-boolean-field_25.entry.js → mrd-boolean-field_28.entry.js} +1161 -357
- package/dist/esm/mrd-merge-view.entry.js +4 -4
- package/dist/mosterdcomponents/index.esm.js +1 -1
- package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
- package/dist/mosterdcomponents/{p-Bc42CfJB.js → p-BJkVeSq6.js} +1 -1
- package/dist/mosterdcomponents/p-BMx6VAJ6.js +1 -0
- package/dist/mosterdcomponents/p-d64ba1f2.entry.js +3 -0
- package/dist/mosterdcomponents/{p-a7e8f6a3.entry.js → p-e68dfbb0.entry.js} +1 -1
- package/dist/types/components/fields/mrd-textarea-field/mrd-textarea-field.d.ts +10 -0
- package/dist/types/components/form/mrd-form/mrd-form.d.ts +6 -0
- package/dist/types/components/layout/mrd-layout-section/mrd-layout-section.d.ts +20 -1
- package/dist/types/components/memo/mrd-memo-container/mrd-memo-container.d.ts +152 -0
- package/dist/types/components/memo/mrd-memo-list/mrd-memo-list.d.ts +79 -0
- package/dist/types/components/memo/mrd-memo-view/mrd-memo-view.d.ts +33 -0
- package/dist/types/components/table/mrd-table/mrd-table.d.ts +48 -1
- package/dist/types/components/table/mrd-table/table-parts.d.ts +15 -0
- package/dist/types/components/table/mrd-table/table-query.d.ts +6 -0
- package/dist/types/components.d.ts +528 -1
- package/dist/types/types/client-layout.d.ts +1 -0
- package/dist/types/utils/query-params.d.ts +16 -0
- package/package.json +1 -1
- package/dist/mosterdcomponents/p-07b148b2.entry.js +0 -3
- package/dist/mosterdcomponents/p-D5ZPfX3-.js +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as registerInstance, c as createEvent, h, H as Host, g as getElement, w as writeTask } from './index-CDiBvvJU.js';
|
|
2
|
-
import { t, p as parseLocalizedNumber, f as formatNumber, a as formatDate, b as formatDateTime, c as formatCurrency, C as CellRenderer, d as formatPercentage } from './cell-renderer-
|
|
3
|
-
import { b as ClientLayoutItemFieldDataType, e as ClientLayoutNavigateBehaviour, a as ClientLayoutItemType, c as ClientLayoutItemRelationDisplayType, d as ClientLayoutItemRelationEditBehavior, r as resolveArchetype, A as ARCHETYPE_DOCUMENT, h as ARCHETYPE_INVOICE_LINE, f as ARCHETYPE_INVOICE, g as ARCHETYPE_EMAIL } from './client-layout-
|
|
2
|
+
import { t, p as parseLocalizedNumber, f as formatNumber, a as formatDate, b as formatDateTime, c as formatCurrency, C as CellRenderer, d as formatPercentage } from './cell-renderer-4NKEzZWw.js';
|
|
3
|
+
import { b as ClientLayoutItemFieldDataType, e as ClientLayoutNavigateBehaviour, a as ClientLayoutItemType, c as ClientLayoutItemRelationDisplayType, d as ClientLayoutItemRelationEditBehavior, r as resolveArchetype, A as ARCHETYPE_DOCUMENT, i as ARCHETYPE_MEMO, h as ARCHETYPE_INVOICE_LINE, f as ARCHETYPE_INVOICE, g as ARCHETYPE_EMAIL } from './client-layout-BJkVeSq6.js';
|
|
4
4
|
|
|
5
5
|
const mrdBooleanFieldCss = () => `.sc-mrd-boolean-field-h{display:block}.mrd-boolean-field.sc-mrd-boolean-field{display:flex;align-items:center;width:100%}.mrd-boolean-field__toggle-label.sc-mrd-boolean-field{display:flex;align-items:center;gap:var(--mrd-space-3);cursor:pointer;user-select:none}.mrd-boolean-field__checkbox.sc-mrd-boolean-field{position:absolute;opacity:0;width:0;height:0;pointer-events:none}.mrd-boolean-field__checkbox.sc-mrd-boolean-field:checked+.mrd-boolean-field__toggle.sc-mrd-boolean-field{background-color:var(--mrd-color-primary)}.mrd-boolean-field__checkbox.sc-mrd-boolean-field:checked+.mrd-boolean-field__toggle.sc-mrd-boolean-field::after{transform:translateX(20px)}.mrd-boolean-field__checkbox.sc-mrd-boolean-field:focus+.mrd-boolean-field__toggle.sc-mrd-boolean-field{box-shadow:var(--mrd-shadow-focus)}.mrd-boolean-field__checkbox.sc-mrd-boolean-field:disabled+.mrd-boolean-field__toggle.sc-mrd-boolean-field{opacity:0.5;cursor:not-allowed}.mrd-boolean-field__toggle.sc-mrd-boolean-field{position:relative;display:inline-block;width:44px;height:24px;background-color:var(--mrd-color-neutral-300);border-radius:var(--mrd-border-radius-full);transition:background-color var(--mrd-transition);flex-shrink:0}.mrd-boolean-field__toggle.sc-mrd-boolean-field::after{content:"";position:absolute;top:2px;left:2px;width:20px;height:20px;background-color:var(--mrd-color-white);border-radius:50%;transition:transform var(--mrd-transition);box-shadow:var(--mrd-shadow-sm)}.mrd-boolean-field__text.sc-mrd-boolean-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-800)}.mrd-boolean-field__text--required.sc-mrd-boolean-field::after{content:" *";color:var(--mrd-color-danger)}`;
|
|
6
6
|
|
|
@@ -520,6 +520,15 @@ function buildListPath(opts) {
|
|
|
520
520
|
}
|
|
521
521
|
return `/${(_c = opts.dataClass) !== null && _c !== void 0 ? _c : ''}`;
|
|
522
522
|
}
|
|
523
|
+
/** The `mrdAction` detail for a toolbar "create" action: `parentPath` locates the
|
|
524
|
+
* RELATED_VIEW's parent (`/{fromClass}/{parentId}`) so the host can route to
|
|
525
|
+
* `.../{parentPath}/{dataClass}/new`; `null` for a top-level VIEW. Shared by
|
|
526
|
+
* mrd-table and mrd-memo-container so both toolbars build an identical payload. */
|
|
527
|
+
function buildCreateActionDetail(opts) {
|
|
528
|
+
var _a, _b;
|
|
529
|
+
const parentPath = opts.isRelatedView ? `/${(_a = opts.fromClass) !== null && _a !== void 0 ? _a : ''}/${opts.parentId}` : null;
|
|
530
|
+
return Object.assign({ action: 'create', dataClass: (_b = opts.dataClass) !== null && _b !== void 0 ? _b : '', parentPath }, (opts.basicType ? { basicType: opts.basicType } : {}));
|
|
531
|
+
}
|
|
523
532
|
|
|
524
533
|
/**
|
|
525
534
|
* Tree model and pure tree logic for mrd-document-list.
|
|
@@ -4442,13 +4451,14 @@ const MrdFileField = class {
|
|
|
4442
4451
|
};
|
|
4443
4452
|
MrdFileField.style = mrdFileFieldCss();
|
|
4444
4453
|
|
|
4445
|
-
const mrdFormCss = () => `.sc-mrd-form-h{display:block}.mrd-form.sc-mrd-form{font-family:var(--mrd-font-family);width:100%}.mrd-form__title.sc-mrd-form{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-6) 0}.mrd-form__body.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-5)}.mrd-form__field.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-1)}.mrd-form__field-error.sc-mrd-form{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-form__section.sc-mrd-form{border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);padding:var(--mrd-space-4) var(--mrd-space-5);margin:0}.mrd-form__section-legend.sc-mrd-form{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-700);padding:0 var(--mrd-space-2)}.mrd-form__section-body.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-4);margin-top:var(--mrd-space-2)}.mrd-form__group.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-2)}.mrd-form__group-label.sc-mrd-form{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-500);text-transform:uppercase;letter-spacing:0.05em}.mrd-form__group-body.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-4);padding-left:var(--mrd-space-4);border-left:3px solid var(--mrd-color-neutral-200)}.mrd-form__footer.sc-mrd-form{margin-top:var(--mrd-space-8);padding-top:var(--mrd-space-5);border-top:var(--mrd-border-width) solid var(--mrd-border-color);display:flex;justify-content:flex-end;gap:var(--mrd-space-3)}.mrd-form__submit.sc-mrd-form{display:inline-flex;align-items:center;justify-content:center;height:var(--mrd-input-height);padding:0 var(--mrd-space-6);background-color:var(--mrd-color-primary);color:var(--mrd-color-white);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);border:none;border-radius:var(--mrd-border-radius);cursor:pointer;transition:background-color var(--mrd-transition)}.mrd-form__submit.sc-mrd-form:hover{background-color:var(--mrd-color-primary-hover)}.mrd-form__submit.sc-mrd-form:focus{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-form__submit.sc-mrd-form:active{background-color:var(--mrd-color-primary-dark)}.mrd-form__cancel.sc-mrd-form{display:inline-flex;align-items:center;justify-content:center;height:var(--mrd-input-height);padding:0 var(--mrd-space-6);background-color:transparent;color:var(--mrd-color-neutral-600);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);cursor:pointer;transition:background-color var(--mrd-transition), color var(--mrd-transition)}.mrd-form__cancel.sc-mrd-form:hover{background-color:var(--mrd-color-neutral-100);color:var(--mrd-color-neutral-800)}.mrd-form__cancel.sc-mrd-form:focus{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-form__cancel.sc-mrd-form:active{background-color:var(--mrd-color-neutral-200)}`;
|
|
4454
|
+
const mrdFormCss = () => `.sc-mrd-form-h{display:block}.mrd-form.sc-mrd-form{font-family:var(--mrd-font-family);width:100%}.mrd-form__title.sc-mrd-form{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-6) 0}.mrd-form__body.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-5)}.mrd-form__field.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-1)}.mrd-form__field-error.sc-mrd-form{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-form__section.sc-mrd-form{border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);padding:var(--mrd-space-4) var(--mrd-space-5);margin:0}.mrd-form__section-legend.sc-mrd-form{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-700);padding:0 var(--mrd-space-2)}.mrd-form__section-body.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-4);margin-top:var(--mrd-space-2)}.mrd-form__group.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-2)}.mrd-form__group-label.sc-mrd-form{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-500);text-transform:uppercase;letter-spacing:0.05em}.mrd-form__group-body.sc-mrd-form{display:flex;flex-direction:column;gap:var(--mrd-space-4);padding-left:var(--mrd-space-4);border-left:3px solid var(--mrd-color-neutral-200)}.mrd-form__footer.sc-mrd-form{margin-top:var(--mrd-space-8);padding-top:var(--mrd-space-5);border-top:var(--mrd-border-width) solid var(--mrd-border-color);display:flex;justify-content:flex-end;gap:var(--mrd-space-3)}.mrd-form__submit.sc-mrd-form{display:inline-flex;align-items:center;justify-content:center;height:var(--mrd-input-height);padding:0 var(--mrd-space-6);background-color:var(--mrd-color-primary);color:var(--mrd-color-white);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);border:none;border-radius:var(--mrd-border-radius);cursor:pointer;transition:background-color var(--mrd-transition)}.mrd-form__submit.sc-mrd-form:hover{background-color:var(--mrd-color-primary-hover)}.mrd-form__submit.sc-mrd-form:focus{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-form__submit.sc-mrd-form:active{background-color:var(--mrd-color-primary-dark)}.mrd-form__cancel.sc-mrd-form{display:inline-flex;align-items:center;justify-content:center;height:var(--mrd-input-height);padding:0 var(--mrd-space-6);background-color:transparent;color:var(--mrd-color-neutral-600);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);cursor:pointer;transition:background-color var(--mrd-transition), color var(--mrd-transition)}.mrd-form__cancel.sc-mrd-form:hover{background-color:var(--mrd-color-neutral-100);color:var(--mrd-color-neutral-800)}.mrd-form__cancel.sc-mrd-form:focus{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-form__cancel.sc-mrd-form:active{background-color:var(--mrd-color-neutral-200)}.mrd-form__delete.sc-mrd-form{display:inline-flex;align-items:center;justify-content:center;height:var(--mrd-input-height);padding:0 var(--mrd-space-6);margin-right:auto;background-color:transparent;color:var(--mrd-color-danger);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);border:var(--mrd-border-width) solid var(--mrd-color-danger);border-radius:var(--mrd-border-radius);cursor:pointer;transition:background-color var(--mrd-transition), color var(--mrd-transition)}.mrd-form__delete.sc-mrd-form:hover{background-color:var(--mrd-color-danger-light);color:var(--mrd-color-danger-dark)}.mrd-form__delete.sc-mrd-form:focus{outline:none;box-shadow:0 0 0 3px var(--mrd-color-danger-light)}.mrd-form__delete.sc-mrd-form:active{background-color:var(--mrd-color-danger-light);border-color:var(--mrd-color-danger-dark)}`;
|
|
4446
4455
|
|
|
4447
4456
|
const MrdForm = class {
|
|
4448
4457
|
constructor(hostRef) {
|
|
4449
4458
|
registerInstance(this, hostRef);
|
|
4450
4459
|
this.mrdSubmit = createEvent(this, "mrdSubmit");
|
|
4451
4460
|
this.mrdCancel = createEvent(this, "mrdCancel");
|
|
4461
|
+
this.mrdDelete = createEvent(this, "mrdDelete");
|
|
4452
4462
|
this.mrdSearch = createEvent(this, "mrdSearch");
|
|
4453
4463
|
this.mrdFetchAll = createEvent(this, "mrdFetchAll");
|
|
4454
4464
|
this.mrdUpload = createEvent(this, "mrdUpload");
|
|
@@ -4475,6 +4485,11 @@ const MrdForm = class {
|
|
|
4475
4485
|
this.referenceClass = '';
|
|
4476
4486
|
/** When true, a cancel button is shown next to the submit button. */
|
|
4477
4487
|
this.showCancel = false;
|
|
4488
|
+
/** When true, a delete button is shown next to the submit button (edit mode only —
|
|
4489
|
+
* the host decides when a delete affordance makes sense, e.g. only for an existing
|
|
4490
|
+
* record). Deletion itself (confirmation, the actual API call) is entirely the
|
|
4491
|
+
* host's responsibility; mrd-form only emits the request via mrdDelete. */
|
|
4492
|
+
this.showDelete = false;
|
|
4478
4493
|
/**
|
|
4479
4494
|
* The currently logged-in user, resolved by the host via /accounts/me.
|
|
4480
4495
|
* Used to pre-fill RELATION fields whose defaultValue is "@me".
|
|
@@ -4762,15 +4777,11 @@ const MrdForm = class {
|
|
|
4762
4777
|
normalizeRelationValue(value) {
|
|
4763
4778
|
if (value == null || value === '')
|
|
4764
4779
|
return null;
|
|
4765
|
-
if (typeof value === 'string')
|
|
4766
|
-
return value || null;
|
|
4767
4780
|
if (Array.isArray(value)) {
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
if (typeof value === 'object' && 'id' in value) {
|
|
4771
|
-
return value.id || null;
|
|
4781
|
+
const hrefs = value.map(v => this.getHref(v)).filter(v => v !== '');
|
|
4782
|
+
return hrefs.length ? hrefs : null;
|
|
4772
4783
|
}
|
|
4773
|
-
return null;
|
|
4784
|
+
return this.getHref(value) || null;
|
|
4774
4785
|
}
|
|
4775
4786
|
deepEqual(a, b) {
|
|
4776
4787
|
if (a === b)
|
|
@@ -4843,7 +4854,7 @@ const MrdForm = class {
|
|
|
4843
4854
|
return h(Host, null);
|
|
4844
4855
|
}
|
|
4845
4856
|
const dir = this.locale.startsWith('ar') ? 'rtl' : 'ltr';
|
|
4846
|
-
return (h(Host, null, h("form", { class: "mrd-form", dir: dir, onSubmit: this.handleSubmit, noValidate: true }, this.layout.title && h("h2", { class: "mrd-form__title" }, this.layout.title), h("div", { class: "mrd-form__body" }, this.renderItems(this.layout.items)), h("div", { class: "mrd-form__footer" }, h("button", { type: "submit", class: "mrd-form__submit" }, t('submit', this.locale)), this.showCancel && (h("button", { type: "button", class: "mrd-form__cancel", onClick: () => this.mrdCancel.emit() }, t('cancel', this.locale)))))));
|
|
4857
|
+
return (h(Host, null, h("form", { class: "mrd-form", dir: dir, onSubmit: this.handleSubmit, noValidate: true }, this.layout.title && h("h2", { class: "mrd-form__title" }, this.layout.title), h("div", { class: "mrd-form__body" }, this.renderItems(this.layout.items)), h("div", { class: "mrd-form__footer" }, this.showDelete && (h("button", { type: "button", class: "mrd-form__delete", onClick: () => this.mrdDelete.emit() }, t('delete', this.locale))), h("button", { type: "submit", class: "mrd-form__submit" }, t('submit', this.locale)), this.showCancel && (h("button", { type: "button", class: "mrd-form__cancel", onClick: () => this.mrdCancel.emit() }, t('cancel', this.locale)))))));
|
|
4847
4858
|
}
|
|
4848
4859
|
static get watchers() { return {
|
|
4849
4860
|
"values": [{
|
|
@@ -5337,6 +5348,7 @@ const MrdLayoutSection = class {
|
|
|
5337
5348
|
this.mrdLoadViewAggregations = createEvent(this, "mrdLoadViewAggregations");
|
|
5338
5349
|
this.mrdLoadViewDistinct = createEvent(this, "mrdLoadViewDistinct");
|
|
5339
5350
|
this.mrdUpdateObject = createEvent(this, "mrdUpdateObject");
|
|
5351
|
+
this.mrdDeleteObject = createEvent(this, "mrdDeleteObject");
|
|
5340
5352
|
this.mrdViewUpload = createEvent(this, "mrdViewUpload");
|
|
5341
5353
|
this.mrdCreateObject = createEvent(this, "mrdCreateObject");
|
|
5342
5354
|
/** Items from one layout entry in ClientDashboardMetadata.layouts[]. */
|
|
@@ -5355,6 +5367,11 @@ const MrdLayoutSection = class {
|
|
|
5355
5367
|
* create ("+") action and the documents view's New folder / Upload are disabled
|
|
5356
5368
|
* with a tooltip explaining why, so it's clear at a glance the user can't mutate data. */
|
|
5357
5369
|
this.readOnly = false;
|
|
5370
|
+
/** The active account's linked person record (userProfile.links.person), if any.
|
|
5371
|
+
* Threaded to mrd-memo-container so a top-level memo VIEW (no parent record to
|
|
5372
|
+
* attach a new memo to) can still offer "New memo" by falling back to the
|
|
5373
|
+
* account's own record as the container. */
|
|
5374
|
+
this.me = null;
|
|
5358
5375
|
this.searchQueryMap = {};
|
|
5359
5376
|
this.searchResultsMap = {};
|
|
5360
5377
|
this.imagePreviewUrl = null;
|
|
@@ -5408,6 +5425,14 @@ const MrdLayoutSection = class {
|
|
|
5408
5425
|
await table.init();
|
|
5409
5426
|
}
|
|
5410
5427
|
}
|
|
5428
|
+
// mrd-memo-container's card mode has no <mrd-table> — mrd-memo-list needs the
|
|
5429
|
+
// same init() call to request its first page.
|
|
5430
|
+
const memoLists = this.el.querySelectorAll('mrd-memo-list[data-view]');
|
|
5431
|
+
for (const list of Array.from(memoLists)) {
|
|
5432
|
+
if (typeof list.init === 'function') {
|
|
5433
|
+
await list.init();
|
|
5434
|
+
}
|
|
5435
|
+
}
|
|
5411
5436
|
}
|
|
5412
5437
|
emitLoadImages() {
|
|
5413
5438
|
for (const item of flattenItems(this.items)) {
|
|
@@ -5441,12 +5466,18 @@ const MrdLayoutSection = class {
|
|
|
5441
5466
|
return;
|
|
5442
5467
|
}
|
|
5443
5468
|
const table = this.el.querySelector(`mrd-table[data-view="${name}"]`);
|
|
5444
|
-
if (
|
|
5469
|
+
if (table) {
|
|
5470
|
+
if (totalElements !== undefined) {
|
|
5471
|
+
table.totalElements = totalElements;
|
|
5472
|
+
}
|
|
5473
|
+
await table.setPage(page, rows, hasNext);
|
|
5445
5474
|
return;
|
|
5446
|
-
if (totalElements !== undefined) {
|
|
5447
|
-
table.totalElements = totalElements;
|
|
5448
5475
|
}
|
|
5449
|
-
|
|
5476
|
+
// Cards mode: mrd-memo-container mounts mrd-memo-list instead of mrd-table.
|
|
5477
|
+
const memoList = this.el.querySelector(`mrd-memo-list[data-view="${name}"]`);
|
|
5478
|
+
if (memoList) {
|
|
5479
|
+
await memoList.setPage(page, rows, hasNext);
|
|
5480
|
+
}
|
|
5450
5481
|
}
|
|
5451
5482
|
/** Inject aggregation totals into an embedded mrd-table for a VIEW or RELATED_VIEW item. */
|
|
5452
5483
|
async setViewAggregations(name, data) {
|
|
@@ -5469,11 +5500,18 @@ const MrdLayoutSection = class {
|
|
|
5469
5500
|
await list.setFileReference(uri);
|
|
5470
5501
|
}
|
|
5471
5502
|
/** Inject the created document's href after a file-drop create, so the
|
|
5472
|
-
* optimistic row becomes navigable (see mrdCreateObject).
|
|
5503
|
+
* optimistic row becomes navigable (see mrdCreateObject). For a memo
|
|
5504
|
+
* quick-create there is no optimistic row to resolve — simply reload the
|
|
5505
|
+
* container's current body so the new memo shows up. */
|
|
5473
5506
|
async setViewCreatedObject(name, href) {
|
|
5474
5507
|
const list = this.el.querySelector(`mrd-document-list[data-doclist="${name}"]`);
|
|
5475
|
-
if (list === null || list === void 0 ? void 0 : list.setCreatedHref)
|
|
5508
|
+
if (list === null || list === void 0 ? void 0 : list.setCreatedHref) {
|
|
5476
5509
|
await list.setCreatedHref(href);
|
|
5510
|
+
return;
|
|
5511
|
+
}
|
|
5512
|
+
const memoContainer = this.el.querySelector(`mrd-memo-container[data-view="${name}"]`);
|
|
5513
|
+
if (memoContainer === null || memoContainer === void 0 ? void 0 : memoContainer.refresh)
|
|
5514
|
+
await memoContainer.refresh();
|
|
5477
5515
|
}
|
|
5478
5516
|
/** Provide a resolved URL for an IMAGE field. Shows as thumbnail; clicking opens the lightbox. */
|
|
5479
5517
|
async setImagePreview(fieldName, url) {
|
|
@@ -5535,7 +5573,7 @@ const MrdLayoutSection = class {
|
|
|
5535
5573
|
return (h("div", { class: "mrd-layout-section__search", key: `search-${dataClass}` }, h("div", { class: "mrd-layout-section__search-wrap" }, h("svg", { class: "mrd-layout-section__search-icon", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, h("path", { "fill-rule": "evenodd", d: "M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z", "clip-rule": "evenodd" })), h("input", { class: "mrd-layout-section__search-input", type: "text", value: query, placeholder: (_c = item.label) !== null && _c !== void 0 ? _c : '', onInput: e => this.handleSearchInput(dataClass, e.target.value) })), results.length > 0 && (h("ul", { class: "mrd-layout-section__search-results" }, results.map(r => (h("li", { key: r.id, class: "mrd-layout-section__search-result" }, h("button", { class: "mrd-layout-section__search-result-btn", onClick: () => this.mrdNavigate.emit({ href: r.id, label: r.label }) }, h("span", { class: "mrd-layout-section__search-result-label" }, r.label), r.description && h("span", { class: "mrd-layout-section__search-result-desc" }, r.description)))))))));
|
|
5536
5574
|
}
|
|
5537
5575
|
renderRelatedView(item) {
|
|
5538
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
5576
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
5539
5577
|
const key = viewKeyFor(item);
|
|
5540
5578
|
if (!key)
|
|
5541
5579
|
return null;
|
|
@@ -5548,13 +5586,12 @@ const MrdLayoutSection = class {
|
|
|
5548
5586
|
// The API publishes `archetypes` on the VIEW/RELATED_VIEW item itself
|
|
5549
5587
|
// (sibling of `view`), not inside `view`.
|
|
5550
5588
|
const docArchetype = resolveArchetype((_g = item.archetypes) !== null && _g !== void 0 ? _g : (_h = item.view) === null || _h === void 0 ? void 0 : _h.archetypes, ARCHETYPE_DOCUMENT);
|
|
5589
|
+
const memoArchetype = !docArchetype ? resolveArchetype((_j = item.archetypes) !== null && _j !== void 0 ? _j : (_k = item.view) === null || _k === void 0 ? void 0 : _k.archetypes, ARCHETYPE_MEMO) : undefined;
|
|
5551
5590
|
// Canonical parent href for single-container seeding: use the RELATED_VIEW's
|
|
5552
5591
|
// fromClass (base class) rather than the route class, so polymorphic subtypes
|
|
5553
5592
|
// resolve to the same container the documents actually reference.
|
|
5554
5593
|
const containerHref = buildContainerHref(item, selfHref, parentId);
|
|
5555
|
-
return (h("div", { class: "mrd-layout-section__related-view", key: `view-${key}` }, showTitle && item.label && h("h3", { class: "mrd-layout-section__related-view-title" }, item.label), docArchetype
|
|
5556
|
-
? this.renderDocumentContainer(item, key, parentId, docArchetype, containerHref)
|
|
5557
|
-
: this.renderTable(item, key, parentId)));
|
|
5594
|
+
return (h("div", { class: "mrd-layout-section__related-view", key: `view-${key}` }, showTitle && item.label && h("h3", { class: "mrd-layout-section__related-view-title" }, item.label), docArchetype && this.renderDocumentContainer(item, key, parentId, docArchetype, containerHref), memoArchetype && this.renderMemoContainer(item, key, parentId, memoArchetype, containerHref), !docArchetype && !memoArchetype && this.renderTable(item, key, parentId)));
|
|
5558
5595
|
}
|
|
5559
5596
|
/** Document collection view: owns the view-switch + collection actions and
|
|
5560
5597
|
* swaps between the folder tree and the flat table. Events are re-emitted to
|
|
@@ -5592,6 +5629,33 @@ const MrdLayoutSection = class {
|
|
|
5592
5629
|
this.mrdCreateObject.emit(Object.assign({ name: key }, e.detail));
|
|
5593
5630
|
} }));
|
|
5594
5631
|
}
|
|
5632
|
+
/** Memo collection view: owns the view-switch + "New memo" and swaps between
|
|
5633
|
+
* the card list and the flat table, mirroring renderDocumentContainer(). */
|
|
5634
|
+
renderMemoContainer(item, key, parentId, archetype, containerHref) {
|
|
5635
|
+
var _a, _b, _c, _d;
|
|
5636
|
+
const labelsListItems = (_d = (_c = (_b = (_a = item.view) === null || _a === void 0 ? void 0 : _a.values) === null || _b === void 0 ? void 0 : _b.find(v => { var _a; return v.name === ((_a = archetype.slots) === null || _a === void 0 ? void 0 : _a.labels); })) === null || _c === void 0 ? void 0 : _c.listItems) !== null && _d !== void 0 ? _d : null;
|
|
5637
|
+
return (h("mrd-memo-container", { "data-view": key, item: item, archetype: archetype, parentId: parentId, containerHref: containerHref, viewKey: key, locale: this.locale, readOnly: this.readOnly, me: this.me, labelsListItems: labelsListItems, onMrdLoadPage: (e) => {
|
|
5638
|
+
e.stopPropagation();
|
|
5639
|
+
this.mrdLoadViewPage.emit(Object.assign({ name: key }, e.detail));
|
|
5640
|
+
}, onMrdLoadAggregations: (e) => {
|
|
5641
|
+
var _a;
|
|
5642
|
+
e.stopPropagation();
|
|
5643
|
+
this.mrdLoadViewAggregations.emit(Object.assign({ name: key, dataClass: (_a = item.dataClass) !== null && _a !== void 0 ? _a : key }, e.detail));
|
|
5644
|
+
}, onMrdAction: (e) => {
|
|
5645
|
+
var _a;
|
|
5646
|
+
e.stopPropagation();
|
|
5647
|
+
this.mrdViewAction.emit(Object.assign({ name: key, dataClass: (_a = item.dataClass) !== null && _a !== void 0 ? _a : key }, e.detail));
|
|
5648
|
+
}, onMrdCreateObject: (e) => {
|
|
5649
|
+
e.stopPropagation();
|
|
5650
|
+
this.mrdCreateObject.emit(Object.assign({ name: key }, e.detail));
|
|
5651
|
+
}, onMrdUpdateObject: (e) => {
|
|
5652
|
+
e.stopPropagation();
|
|
5653
|
+
this.mrdUpdateObject.emit(e.detail);
|
|
5654
|
+
}, onMrdDeleteObject: (e) => {
|
|
5655
|
+
e.stopPropagation();
|
|
5656
|
+
this.mrdDeleteObject.emit(e.detail);
|
|
5657
|
+
} }));
|
|
5658
|
+
}
|
|
5595
5659
|
renderTable(item, key, parentId) {
|
|
5596
5660
|
return (h("mrd-table", { "data-view": key, item: item, parentId: parentId, locale: this.locale, readOnly: this.readOnly, onMrdLoadPage: (e) => this.handleViewLoadPage(e, key), onMrdLoadAggregations: (e) => {
|
|
5597
5661
|
var _a;
|
|
@@ -5693,11 +5757,24 @@ const MrdLayoutSection = class {
|
|
|
5693
5757
|
...this.relatedItems().map(it => this.renderItem(it)),
|
|
5694
5758
|
];
|
|
5695
5759
|
}
|
|
5760
|
+
/** Single-memo view: the record's own type carries commons.memo. Renders a
|
|
5761
|
+
* recognisable memo (title/body prominent, author/date subtle) instead of
|
|
5762
|
+
* generic fields, keeping any related views/searches below it. */
|
|
5763
|
+
renderMemoObject(archetype) {
|
|
5764
|
+
var _a, _b;
|
|
5765
|
+
const labelsListItems = (_b = (_a = this.items.find(it => { var _a; return it.name === ((_a = archetype.slots) === null || _a === void 0 ? void 0 : _a.labels); })) === null || _a === void 0 ? void 0 : _a.listItems) !== null && _b !== void 0 ? _b : null;
|
|
5766
|
+
return [
|
|
5767
|
+
h("mrd-memo-view", { archetype: archetype, data: this.data, locale: this.locale, labelsListItems: labelsListItems, onMrdNavigate: (e) => { e.stopPropagation(); this.mrdNavigate.emit(e.detail); } }),
|
|
5768
|
+
...this.relatedItems().map(it => this.renderItem(it)),
|
|
5769
|
+
];
|
|
5770
|
+
}
|
|
5696
5771
|
render() {
|
|
5697
5772
|
const docArchetype = resolveArchetype(this.archetypes, ARCHETYPE_DOCUMENT);
|
|
5698
5773
|
const invoiceArchetype = !docArchetype ? resolveArchetype(this.archetypes, ARCHETYPE_INVOICE) : undefined;
|
|
5699
5774
|
const emailArchetype = !docArchetype && !invoiceArchetype ? resolveArchetype(this.archetypes, ARCHETYPE_EMAIL) : undefined;
|
|
5700
|
-
|
|
5775
|
+
const memoArchetype = !docArchetype && !invoiceArchetype && !emailArchetype ? resolveArchetype(this.archetypes, ARCHETYPE_MEMO) : undefined;
|
|
5776
|
+
const anyArchetype = docArchetype || invoiceArchetype || emailArchetype || memoArchetype;
|
|
5777
|
+
return (h(Host, { key: '730654d745992b9607f15fcaf2bb54a725429e4d' }, h("div", { key: '72a2e7bb767992aa6f206a10f8b2a3a572e86115', class: "mrd-layout-section" }, docArchetype && this.renderDocumentObject(docArchetype), invoiceArchetype && this.renderInvoiceObject(invoiceArchetype), emailArchetype && this.renderEmailObject(emailArchetype), memoArchetype && this.renderMemoObject(memoArchetype), !anyArchetype && this.items.map(item => this.renderItem(item))), this.renderImageModal()));
|
|
5701
5778
|
}
|
|
5702
5779
|
get el() { return getElement(this); }
|
|
5703
5780
|
static get watchers() { return {
|
|
@@ -5821,153 +5898,916 @@ const MrdLongtextField = class {
|
|
|
5821
5898
|
};
|
|
5822
5899
|
MrdLongtextField.style = mrdLongtextFieldCss();
|
|
5823
5900
|
|
|
5824
|
-
const
|
|
5901
|
+
const mrdMemoContainerCss = () => `.sc-mrd-memo-container-h{display:block}.mrd-memo-container__toolbar.sc-mrd-memo-container{display:flex;align-items:center;justify-content:flex-end;gap:var(--mrd-space-2);padding:var(--mrd-space-2) 0;border-bottom:1px solid var(--mrd-color-neutral-100)}.mrd-memo-container__action.sc-mrd-memo-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-memo-container__action.sc-mrd-memo-container svg.sc-mrd-memo-container{width:1rem;height:1rem}.mrd-memo-container__action.sc-mrd-memo-container:hover:not(:disabled){background:var(--mrd-color-neutral-50);border-color:var(--mrd-color-neutral-300)}.mrd-memo-container__action.sc-mrd-memo-container:disabled{opacity:0.5;cursor:not-allowed}.mrd-memo-container__seg.sc-mrd-memo-container{display:inline-flex;gap:2px;padding:2px;background:var(--mrd-color-neutral-100);border-radius:var(--mrd-border-radius)}.mrd-memo-container__seg-btn.sc-mrd-memo-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-memo-container__seg-btn.sc-mrd-memo-container:hover{color:var(--mrd-color-neutral-800)}.mrd-memo-container__seg-btn[aria-pressed=true].sc-mrd-memo-container{background:var(--mrd-color-white);color:var(--mrd-color-primary-dark);box-shadow:var(--mrd-shadow-sm)}.mrd-memo-container__seg-btn.sc-mrd-memo-container svg.sc-mrd-memo-container{width:1rem;height:1rem}.mrd-memo-container__body.sc-mrd-memo-container{padding-top:var(--mrd-space-3)}.mrd-memo-container__modal-backdrop.sc-mrd-memo-container{position:fixed;inset:0;background:rgba(0, 0, 0, 0.6);z-index:300;display:flex;align-items:center;justify-content:center;padding:var(--mrd-space-4)}.mrd-memo-container__modal.sc-mrd-memo-container{width:100%;max-width:960px;max-height:90vh;overflow-y:auto;display:flex;flex-direction:column;gap:var(--mrd-space-4);background:var(--mrd-color-white);border-radius:var(--mrd-border-radius-md);padding:var(--mrd-space-5);box-shadow:var(--mrd-shadow-lg)}.mrd-memo-container__modal-title.sc-mrd-memo-container{font-size:var(--mrd-font-size-lg);font-weight:var(--mrd-font-weight-bold);color:var(--mrd-color-neutral-900);margin:0}.mrd-memo-container__modal-field.sc-mrd-memo-container{display:flex;flex-direction:column;gap:var(--mrd-space-1)}.mrd-memo-container__modal-error.sc-mrd-memo-container{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-memo-container__modal-warning.sc-mrd-memo-container{margin:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-600)}.mrd-memo-container__modal-actions.sc-mrd-memo-container{display:flex;justify-content:flex-end;gap:var(--mrd-space-3);margin-top:var(--mrd-space-2);padding-top:var(--mrd-space-4);border-top:var(--mrd-border-width) solid var(--mrd-border-color)}.mrd-memo-container__modal-delete.sc-mrd-memo-container{display:inline-flex;align-items:center;justify-content:center;height:var(--mrd-input-height);padding:0 var(--mrd-space-6);margin-right:auto;background-color:transparent;color:var(--mrd-color-danger);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);border:var(--mrd-border-width) solid var(--mrd-color-danger);border-radius:var(--mrd-border-radius);cursor:pointer;transition:background-color var(--mrd-transition), color var(--mrd-transition)}.mrd-memo-container__modal-delete.sc-mrd-memo-container:hover{background-color:var(--mrd-color-danger-light);color:var(--mrd-color-danger-dark)}.mrd-memo-container__modal-delete-confirm.sc-mrd-memo-container{display:inline-flex;align-items:center;justify-content:center;height:var(--mrd-input-height);padding:0 var(--mrd-space-6);background-color:var(--mrd-color-danger);color:var(--mrd-color-white);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);border:none;border-radius:var(--mrd-border-radius);cursor:pointer;transition:background-color var(--mrd-transition)}.mrd-memo-container__modal-delete-confirm.sc-mrd-memo-container:hover{background-color:var(--mrd-color-danger-dark)}.mrd-memo-container__modal-cancel.sc-mrd-memo-container{display:inline-flex;align-items:center;justify-content:center;height:var(--mrd-input-height);padding:0 var(--mrd-space-6);background-color:transparent;color:var(--mrd-color-neutral-600);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);cursor:pointer;transition:background-color var(--mrd-transition), color var(--mrd-transition)}.mrd-memo-container__modal-cancel.sc-mrd-memo-container:hover{background-color:var(--mrd-color-neutral-100);color:var(--mrd-color-neutral-800)}.mrd-memo-container__modal-submit.sc-mrd-memo-container{display:inline-flex;align-items:center;justify-content:center;height:var(--mrd-input-height);padding:0 var(--mrd-space-6);background-color:var(--mrd-color-primary);color:var(--mrd-color-white);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);border:none;border-radius:var(--mrd-border-radius);cursor:pointer;transition:background-color var(--mrd-transition)}.mrd-memo-container__modal-submit.sc-mrd-memo-container:hover{background-color:var(--mrd-color-primary-hover)}`;
|
|
5825
5902
|
|
|
5826
|
-
const
|
|
5903
|
+
const MrdMemoContainer = class {
|
|
5827
5904
|
constructor(hostRef) {
|
|
5828
5905
|
registerInstance(this, hostRef);
|
|
5829
|
-
this.
|
|
5830
|
-
this.
|
|
5831
|
-
this.
|
|
5832
|
-
this.
|
|
5833
|
-
this.
|
|
5834
|
-
this.
|
|
5835
|
-
|
|
5836
|
-
this.
|
|
5906
|
+
this.mrdLoadPage = createEvent(this, "mrdLoadPage");
|
|
5907
|
+
this.mrdLoadAggregations = createEvent(this, "mrdLoadAggregations");
|
|
5908
|
+
this.mrdAction = createEvent(this, "mrdAction");
|
|
5909
|
+
this.mrdCreateObject = createEvent(this, "mrdCreateObject");
|
|
5910
|
+
this.mrdUpdateObject = createEvent(this, "mrdUpdateObject");
|
|
5911
|
+
this.mrdDeleteObject = createEvent(this, "mrdDeleteObject");
|
|
5912
|
+
/** The VIEW or RELATED_VIEW layout item (dataClass, fromClass, view config). */
|
|
5913
|
+
this.item = null;
|
|
5914
|
+
/** Parent record id — required for RELATED_VIEW path building. */
|
|
5915
|
+
this.parentId = '';
|
|
5916
|
+
/** Canonical parent href — set when this is a RELATED_VIEW embedded under a
|
|
5917
|
+
* parent record, which already gives a new memo something to attach to. */
|
|
5918
|
+
this.containerHref = '';
|
|
5919
|
+
/** Lookup key used for the embedded `data-view` attribute. */
|
|
5920
|
+
this.viewKey = '';
|
|
5837
5921
|
this.locale = navigator.language;
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
this.
|
|
5841
|
-
this
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
this.
|
|
5845
|
-
|
|
5922
|
+
/** listItems of the FIELD bound to the `labels` slot; forwarded to whichever
|
|
5923
|
+
* body is mounted and used to render the dialog's label checkboxes. */
|
|
5924
|
+
this.labelsListItems = null;
|
|
5925
|
+
/** When true, this dashboard is read-only: "New memo" is disabled with a
|
|
5926
|
+
* tooltip, cards/rows are not clickable, and the embedded table's own
|
|
5927
|
+
* create action is disabled too. */
|
|
5928
|
+
this.readOnly = false;
|
|
5929
|
+
/** The active account's linked person record (userProfile.links.person), if any.
|
|
5930
|
+
* Used both to gate "New memo" (see effectiveContainerHref) and, on submit, to
|
|
5931
|
+
* fill the author slot. */
|
|
5932
|
+
this.me = null;
|
|
5933
|
+
/** Active body: card list or flat table. */
|
|
5934
|
+
this.mode = 'cards';
|
|
5935
|
+
this.dialogOpen = false;
|
|
5936
|
+
/** Href of the memo being edited; null while creating. */
|
|
5937
|
+
this.editingHref = null;
|
|
5938
|
+
this.dialogBody = '';
|
|
5939
|
+
this.dialogTitle = '';
|
|
5940
|
+
this.dialogLabels = [];
|
|
5941
|
+
this.dialogImportant = false;
|
|
5942
|
+
this.dialogTouched = false;
|
|
5943
|
+
/** True while the dialog shows the delete confirmation step in place of the
|
|
5944
|
+
* form fields — mirrors mrd-merge-view's MergeConfirmStep (same panel,
|
|
5945
|
+
* swapped content) rather than stacking a second modal. */
|
|
5946
|
+
this.deleteConfirmOpen = false;
|
|
5947
|
+
/** Whether the currently mounted body has been init()'d. Reset on every mode switch. */
|
|
5948
|
+
this.listInited = false;
|
|
5949
|
+
this.tableInited = false;
|
|
5950
|
+
this.escapeHandler = null;
|
|
5951
|
+
this.openCreate = () => {
|
|
5952
|
+
if (!this.canAdd)
|
|
5953
|
+
return;
|
|
5954
|
+
this.editingHref = null;
|
|
5955
|
+
this.dialogBody = '';
|
|
5956
|
+
this.dialogTitle = '';
|
|
5957
|
+
this.dialogLabels = [];
|
|
5958
|
+
this.dialogImportant = false;
|
|
5959
|
+
this.dialogTouched = false;
|
|
5960
|
+
this.deleteConfirmOpen = false;
|
|
5961
|
+
this.dialogOpen = true;
|
|
5846
5962
|
};
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
if (this.
|
|
5852
|
-
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5963
|
+
/** Opens the same dialog pre-filled from an existing memo row/record —
|
|
5964
|
+
* triggered by clicking a card or a table row. No separate detail page. */
|
|
5965
|
+
this.openEdit = (row) => {
|
|
5966
|
+
var _a, _b;
|
|
5967
|
+
if (this.readOnly)
|
|
5968
|
+
return;
|
|
5969
|
+
const 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;
|
|
5970
|
+
if (!href)
|
|
5971
|
+
return;
|
|
5972
|
+
this.editingHref = href;
|
|
5973
|
+
const bodyRaw = this.slotValue(row, 'body');
|
|
5974
|
+
this.dialogBody = bodyRaw != null ? String(bodyRaw) : '';
|
|
5975
|
+
const titleRaw = this.slotValue(row, 'title');
|
|
5976
|
+
this.dialogTitle = titleRaw != null ? String(titleRaw) : '';
|
|
5977
|
+
const labelsRaw = this.slotValue(row, 'labels');
|
|
5978
|
+
this.dialogLabels = Array.isArray(labelsRaw)
|
|
5979
|
+
? labelsRaw.map(String)
|
|
5980
|
+
: (labelsRaw != null && labelsRaw !== '' ? [String(labelsRaw)] : []);
|
|
5981
|
+
this.dialogImportant = !!this.slotValue(row, 'important');
|
|
5982
|
+
this.dialogTouched = false;
|
|
5983
|
+
this.deleteConfirmOpen = false;
|
|
5984
|
+
this.dialogOpen = true;
|
|
5985
|
+
};
|
|
5986
|
+
this.closeDialog = () => {
|
|
5987
|
+
this.dialogOpen = false;
|
|
5988
|
+
this.deleteConfirmOpen = false;
|
|
5989
|
+
};
|
|
5990
|
+
this.openDeleteConfirm = () => {
|
|
5991
|
+
this.deleteConfirmOpen = true;
|
|
5992
|
+
};
|
|
5993
|
+
this.cancelDeleteConfirm = () => {
|
|
5994
|
+
this.deleteConfirmOpen = false;
|
|
5995
|
+
};
|
|
5996
|
+
this.confirmDelete = () => {
|
|
5997
|
+
var _a;
|
|
5998
|
+
if (!this.editingHref)
|
|
5999
|
+
return;
|
|
6000
|
+
const href = this.editingHref;
|
|
6001
|
+
this.mrdDeleteObject.emit({ href });
|
|
6002
|
+
if (this.mode === 'cards') {
|
|
6003
|
+
(_a = this.listEl) === null || _a === void 0 ? void 0 : _a.removeRow(href);
|
|
5856
6004
|
}
|
|
5857
6005
|
else {
|
|
5858
|
-
this.
|
|
5859
|
-
}
|
|
5860
|
-
if (parsed !== null && validateRequired(raw)) {
|
|
5861
|
-
this.displayValue = this.formatForDisplay(parsed);
|
|
6006
|
+
this.refresh();
|
|
5862
6007
|
}
|
|
5863
|
-
this.
|
|
5864
|
-
this.
|
|
6008
|
+
this.deleteConfirmOpen = false;
|
|
6009
|
+
this.dialogOpen = false;
|
|
5865
6010
|
};
|
|
5866
|
-
this.
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
6011
|
+
this.submitDialog = () => {
|
|
6012
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
6013
|
+
this.dialogTouched = true;
|
|
6014
|
+
if (!this.dialogBody.trim())
|
|
6015
|
+
return;
|
|
6016
|
+
const slots = (_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) !== null && _b !== void 0 ? _b : {};
|
|
6017
|
+
if (this.editingHref) {
|
|
6018
|
+
// Every shown field is sent explicitly, even when cleared/unchecked —
|
|
6019
|
+
// this is a PATCH, so omitting a field would leave its old value intact.
|
|
6020
|
+
const values = { [(_c = slots.body) !== null && _c !== void 0 ? _c : 'body']: this.dialogBody };
|
|
6021
|
+
if (this.hasTitleSlot)
|
|
6022
|
+
values[(_d = slots.title) !== null && _d !== void 0 ? _d : 'title'] = this.dialogTitle.trim() || null;
|
|
6023
|
+
if (((_e = this.labelsListItems) !== null && _e !== void 0 ? _e : []).length)
|
|
6024
|
+
values[(_f = slots.labels) !== null && _f !== void 0 ? _f : 'labels'] = this.dialogLabels;
|
|
6025
|
+
if (this.hasImportantSlot)
|
|
6026
|
+
values[(_g = slots.important) !== null && _g !== void 0 ? _g : 'important'] = this.dialogImportant;
|
|
6027
|
+
this.mrdUpdateObject.emit({ href: this.editingHref, values });
|
|
6028
|
+
if (this.mode === 'cards') {
|
|
6029
|
+
(_h = this.listEl) === null || _h === void 0 ? void 0 : _h.patchRow(this.editingHref, values);
|
|
6030
|
+
}
|
|
6031
|
+
else {
|
|
6032
|
+
this.refresh();
|
|
6033
|
+
}
|
|
6034
|
+
}
|
|
6035
|
+
else {
|
|
6036
|
+
if (!this.canAdd)
|
|
6037
|
+
return;
|
|
6038
|
+
const values = {
|
|
6039
|
+
[(_j = slots.body) !== null && _j !== void 0 ? _j : 'body']: this.dialogBody,
|
|
6040
|
+
// now(), same token/format mrd-form's own defaultValue resolution uses.
|
|
6041
|
+
[(_k = slots.date) !== null && _k !== void 0 ? _k : 'date']: new Date().toISOString().replace(/\.\d{3}Z$/, 'Z'),
|
|
6042
|
+
};
|
|
6043
|
+
if (this.hasTitleSlot && this.dialogTitle.trim())
|
|
6044
|
+
values[(_l = slots.title) !== null && _l !== void 0 ? _l : 'title'] = this.dialogTitle.trim();
|
|
6045
|
+
if (((_m = this.labelsListItems) !== null && _m !== void 0 ? _m : []).length && this.dialogLabels.length)
|
|
6046
|
+
values[(_o = slots.labels) !== null && _o !== void 0 ? _o : 'labels'] = this.dialogLabels;
|
|
6047
|
+
if (this.hasImportantSlot && this.dialogImportant)
|
|
6048
|
+
values[(_p = slots.important) !== null && _p !== void 0 ? _p : 'important'] = true;
|
|
6049
|
+
if (this.meHref())
|
|
6050
|
+
values[(_q = slots.author) !== null && _q !== void 0 ? _q : 'author'] = this.meHref();
|
|
6051
|
+
// Always explicit — relation values are never inferred from the URL elsewhere
|
|
6052
|
+
// in this codebase (e.g. mrd-form's own submit payload), so don't assume it here.
|
|
6053
|
+
values[(_r = slots.container) !== null && _r !== void 0 ? _r : 'container'] = this.effectiveContainerHref;
|
|
6054
|
+
this.mrdCreateObject.emit({ path: this.buildCreatePath(), values });
|
|
5873
6055
|
}
|
|
6056
|
+
this.dialogOpen = false;
|
|
5874
6057
|
};
|
|
5875
6058
|
}
|
|
5876
|
-
|
|
5877
|
-
this.
|
|
5878
|
-
}
|
|
5879
|
-
/**
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
6059
|
+
disconnectedCallback() {
|
|
6060
|
+
this.unbindEscape();
|
|
6061
|
+
}
|
|
6062
|
+
/** Escape backs out of the delete-confirm step first (matches Cancel there),
|
|
6063
|
+
* or closes the whole dialog. Bound to `document` — bubbling from inside the
|
|
6064
|
+
* Quill editor is not reliable enough to rely on a local key handler. */
|
|
6065
|
+
dialogOpenChanged(open) {
|
|
6066
|
+
if (open) {
|
|
6067
|
+
this.escapeHandler = (e) => {
|
|
6068
|
+
if (e.key !== 'Escape')
|
|
6069
|
+
return;
|
|
6070
|
+
if (this.deleteConfirmOpen)
|
|
6071
|
+
this.cancelDeleteConfirm();
|
|
6072
|
+
else
|
|
6073
|
+
this.closeDialog();
|
|
6074
|
+
};
|
|
6075
|
+
document.addEventListener('keydown', this.escapeHandler);
|
|
6076
|
+
}
|
|
6077
|
+
else {
|
|
6078
|
+
this.unbindEscape();
|
|
6079
|
+
}
|
|
5887
6080
|
}
|
|
5888
|
-
|
|
5889
|
-
this.
|
|
5890
|
-
|
|
6081
|
+
unbindEscape() {
|
|
6082
|
+
if (this.escapeHandler) {
|
|
6083
|
+
document.removeEventListener('keydown', this.escapeHandler);
|
|
6084
|
+
this.escapeHandler = null;
|
|
6085
|
+
}
|
|
5891
6086
|
}
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
6087
|
+
/** Neither body self-loads: like mrd-table, both wait for init(). mrd-layout-section
|
|
6088
|
+
* init()s whichever is mounted at load time via its own querySelector pass; when the
|
|
6089
|
+
* user switches mode here, the freshly mounted body needs the same treatment. */
|
|
6090
|
+
componentDidRender() {
|
|
6091
|
+
var _a, _b;
|
|
6092
|
+
if (this.mode === 'cards' && this.listEl && !this.listInited) {
|
|
6093
|
+
this.listInited = true;
|
|
6094
|
+
const list = this.listEl;
|
|
6095
|
+
Promise.resolve((_a = list.componentOnReady) === null || _a === void 0 ? void 0 : _a.call(list)).then(() => list.init());
|
|
5898
6096
|
}
|
|
5899
|
-
if (this.
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
});
|
|
6097
|
+
if (this.mode === 'table' && this.tableEl && !this.tableInited) {
|
|
6098
|
+
this.tableInited = true;
|
|
6099
|
+
const table = this.tableEl;
|
|
6100
|
+
Promise.resolve((_b = table.componentOnReady) === null || _b === void 0 ? void 0 : _b.call(table)).then(() => table.init());
|
|
5904
6101
|
}
|
|
5905
|
-
|
|
6102
|
+
}
|
|
6103
|
+
setMode(mode) {
|
|
6104
|
+
if (mode === this.mode)
|
|
6105
|
+
return;
|
|
6106
|
+
this.listInited = false;
|
|
6107
|
+
this.tableInited = false;
|
|
6108
|
+
this.mode = mode;
|
|
6109
|
+
}
|
|
6110
|
+
/** Re-request page 0 of whichever body is currently mounted — called by
|
|
6111
|
+
* mrd-layout-section after a successful mrdCreateObject, and by this
|
|
6112
|
+
* component itself after an edit to a table row (which has no per-row
|
|
6113
|
+
* optimistic-patch method the way mrd-memo-list does). */
|
|
6114
|
+
async refresh() {
|
|
6115
|
+
if (this.mode === 'cards' && this.listEl) {
|
|
6116
|
+
await this.listEl.init();
|
|
6117
|
+
}
|
|
6118
|
+
else if (this.mode === 'table' && this.tableEl) {
|
|
6119
|
+
await this.tableEl.init();
|
|
6120
|
+
}
|
|
6121
|
+
}
|
|
6122
|
+
/** `me` is typed as RelationSearchResult ({ id, label }) but hosts differ on
|
|
6123
|
+
* which shape they actually populate: this repo's own dev preview resolves
|
|
6124
|
+
* it via /accounts/me as a real { id, label } RelationSearchResult, while
|
|
6125
|
+
* content-app feeds it from userProfile.links.person, the raw API link shape
|
|
6126
|
+
* ({ href, name }). Both occur in practice — same dual tolerance as
|
|
6127
|
+
* mrd-form's own getHref(). */
|
|
6128
|
+
meHref() {
|
|
6129
|
+
var _a, _b;
|
|
6130
|
+
const m = this.me;
|
|
6131
|
+
return (_b = (_a = m === null || m === void 0 ? void 0 : m.id) !== null && _a !== void 0 ? _a : m === null || m === void 0 ? void 0 : m.href) !== null && _b !== void 0 ? _b : '';
|
|
6132
|
+
}
|
|
6133
|
+
/** Value of a value-slot: reads row[field] via the slot→field map. */
|
|
6134
|
+
slotValue(row, slot) {
|
|
6135
|
+
var _a, _b;
|
|
6136
|
+
const field = (_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b[slot];
|
|
6137
|
+
if (!field)
|
|
6138
|
+
return undefined;
|
|
6139
|
+
return row[field];
|
|
6140
|
+
}
|
|
6141
|
+
get hasTitleSlot() {
|
|
6142
|
+
var _a, _b;
|
|
6143
|
+
return !!((_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b.title);
|
|
6144
|
+
}
|
|
6145
|
+
get hasImportantSlot() {
|
|
6146
|
+
var _a, _b;
|
|
6147
|
+
return !!((_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b.important);
|
|
6148
|
+
}
|
|
6149
|
+
/** A parent record already gives a new memo somewhere to attach to (RELATED_VIEW);
|
|
6150
|
+
* otherwise fall back to the account's own linked person (top-level VIEW). */
|
|
6151
|
+
get effectiveContainerHref() {
|
|
6152
|
+
return this.containerHref || this.meHref();
|
|
6153
|
+
}
|
|
6154
|
+
/** The author slot is always filled from `me` (there is no author picker in
|
|
6155
|
+
* the dialog), so without it there is nothing valid to create — regardless
|
|
6156
|
+
* of whether a parent record already supplies a container. */
|
|
6157
|
+
get canAdd() {
|
|
6158
|
+
return !this.readOnly && !!this.meHref() && !!this.effectiveContainerHref;
|
|
6159
|
+
}
|
|
6160
|
+
/** Path for creating a new memo: `/{dataClass}` for a top-level VIEW, or
|
|
6161
|
+
* `/{fromClass}/{parentId}/{dataClass}` when nested under a parent record. */
|
|
6162
|
+
buildCreatePath() {
|
|
6163
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
6164
|
+
return buildListPath({
|
|
6165
|
+
isRelatedView: ((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === ClientLayoutItemType.RELATED_VIEW,
|
|
6166
|
+
fromClass: (_b = this.item) === null || _b === void 0 ? void 0 : _b.fromClass,
|
|
6167
|
+
parentId: this.parentId,
|
|
6168
|
+
dataClass: (_f = (_d = (_c = this.item) === null || _c === void 0 ? void 0 : _c.filterClass) !== null && _d !== void 0 ? _d : (_e = this.item) === null || _e === void 0 ? void 0 : _e.dataClass) !== null && _f !== void 0 ? _f : (_g = this.item) === null || _g === void 0 ? void 0 : _g.relatedClass,
|
|
6169
|
+
});
|
|
6170
|
+
}
|
|
6171
|
+
renderToolbar() {
|
|
6172
|
+
return (h("div", { class: "mrd-memo-container__toolbar" }, this.mode === 'cards' && (h("button", { type: "button", class: "mrd-memo-container__action", disabled: !this.canAdd, title: this.readOnly ? t('readonly_access', this.locale) : undefined, onClick: this.openCreate }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("path", { d: "M12 5v14M5 12h14" })), t('memo_new', this.locale))), h("div", { class: "mrd-memo-container__seg", role: "group", "aria-label": t('doc_view_switch', this.locale) }, h("button", { class: "mrd-memo-container__seg-btn", "aria-pressed": String(this.mode === 'cards'), title: t('memo_view_cards', this.locale), "aria-label": t('memo_view_cards', this.locale), onClick: () => this.setMode('cards') }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("rect", { x: "3", y: "4", width: "7", height: "7", rx: "1" }), h("rect", { x: "14", y: "4", width: "7", height: "7", rx: "1" }), h("rect", { x: "3", y: "15", width: "7", height: "5", rx: "1" }), h("rect", { x: "14", y: "15", width: "7", height: "5", rx: "1" }))), h("button", { class: "mrd-memo-container__seg-btn", "aria-pressed": String(this.mode === 'table'), title: t('memo_view_table', this.locale), "aria-label": t('memo_view_table', this.locale), onClick: () => this.setMode('table') }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, h("path", { d: "M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" }))))));
|
|
6173
|
+
}
|
|
6174
|
+
renderDeleteConfirm() {
|
|
6175
|
+
return (h("div", null, h("h2", { class: "mrd-memo-container__modal-title" }, t('memo_delete_confirm_title', this.locale)), h("p", { class: "mrd-memo-container__modal-warning" }, t('memo_delete_confirm_body', this.locale)), h("div", { class: "mrd-memo-container__modal-actions" }, h("button", { type: "button", class: "mrd-memo-container__modal-cancel", onClick: this.cancelDeleteConfirm }, t('cancel', this.locale)), h("button", { type: "button", class: "mrd-memo-container__modal-delete-confirm", onClick: this.confirmDelete }, t('delete', this.locale)))));
|
|
6176
|
+
}
|
|
6177
|
+
renderForm() {
|
|
6178
|
+
var _a, _b, _c;
|
|
6179
|
+
const bodyMissing = this.dialogTouched && !this.dialogBody.trim();
|
|
6180
|
+
return [
|
|
6181
|
+
h("h2", { class: "mrd-memo-container__modal-title" }, t(this.editingHref ? 'memo_edit' : 'memo_new', this.locale)),
|
|
6182
|
+
h("div", { class: "mrd-memo-container__modal-field" }, h("mrd-textarea-field", { key: (_a = this.editingHref) !== null && _a !== void 0 ? _a : 'new', name: "body", value: this.dialogBody, required: true, autofocus: true, locale: this.locale, onMrdChange: (e) => { this.dialogBody = e.detail.value; } }), bodyMissing && h("span", { class: "mrd-memo-container__modal-error" }, t('required', this.locale))),
|
|
6183
|
+
this.hasTitleSlot && (h("div", { class: "mrd-memo-container__modal-field" }, h("mrd-text-field", { name: "title", label: t('memo_field_title', this.locale), value: this.dialogTitle, locale: this.locale, onMrdChange: (e) => { this.dialogTitle = e.detail.value; } }))),
|
|
6184
|
+
!!((_b = this.labelsListItems) !== null && _b !== void 0 ? _b : []).length && (h("div", { class: "mrd-memo-container__modal-field" }, h("mrd-list-field", { name: "labels", label: t('memo_field_labels', this.locale), value: this.dialogLabels, multiple: true, listItems: (_c = this.labelsListItems) !== null && _c !== void 0 ? _c : [], locale: this.locale, onMrdChange: (e) => {
|
|
6185
|
+
this.dialogLabels = Array.isArray(e.detail.value) ? e.detail.value : [e.detail.value].filter(Boolean);
|
|
6186
|
+
} }))),
|
|
6187
|
+
this.hasImportantSlot && (h("div", { class: "mrd-memo-container__modal-field" }, h("mrd-boolean-field", { name: "important", label: t('memo_important', this.locale), value: this.dialogImportant, locale: this.locale, onMrdChange: (e) => { this.dialogImportant = e.detail.value; } }))),
|
|
6188
|
+
h("div", { class: "mrd-memo-container__modal-actions" }, this.editingHref && (h("button", { type: "button", class: "mrd-memo-container__modal-delete", onClick: this.openDeleteConfirm }, t('delete', this.locale))), h("button", { type: "button", class: "mrd-memo-container__modal-cancel", onClick: this.closeDialog }, t('cancel', this.locale)), h("button", { type: "button", class: "mrd-memo-container__modal-submit", onClick: this.submitDialog }, t('submit', this.locale))),
|
|
6189
|
+
];
|
|
6190
|
+
}
|
|
6191
|
+
renderDialog() {
|
|
6192
|
+
if (!this.dialogOpen)
|
|
6193
|
+
return null;
|
|
6194
|
+
return (h("div", { class: "mrd-memo-container__modal-backdrop", onClick: this.closeDialog }, h("div", { class: "mrd-memo-container__modal", onClick: (e) => e.stopPropagation() }, this.deleteConfirmOpen ? this.renderDeleteConfirm() : this.renderForm())));
|
|
6195
|
+
}
|
|
6196
|
+
renderCards() {
|
|
6197
|
+
return (h("mrd-memo-list", { "data-view": this.viewKey, ref: el => (this.listEl = el), item: this.item, archetype: this.archetype, parentId: this.parentId, locale: this.locale, readOnly: this.readOnly, labelsListItems: this.labelsListItems, onMrdLoadPage: (e) => {
|
|
6198
|
+
e.stopPropagation();
|
|
6199
|
+
this.mrdLoadPage.emit(e.detail);
|
|
6200
|
+
}, onMrdEdit: (e) => {
|
|
6201
|
+
e.stopPropagation();
|
|
6202
|
+
this.openEdit(e.detail.row);
|
|
6203
|
+
} }));
|
|
6204
|
+
}
|
|
6205
|
+
renderTable() {
|
|
6206
|
+
return (h("mrd-table", { "data-view": this.viewKey, ref: el => (this.tableEl = el), item: this.item, parentId: this.parentId, locale: this.locale, readOnly: this.readOnly, onMrdLoadPage: (e) => {
|
|
6207
|
+
e.stopPropagation();
|
|
6208
|
+
this.mrdLoadPage.emit(e.detail);
|
|
6209
|
+
}, onMrdLoadAggregations: (e) => {
|
|
6210
|
+
e.stopPropagation();
|
|
6211
|
+
this.mrdLoadAggregations.emit(e.detail);
|
|
6212
|
+
}, onMrdRowClick: (e) => {
|
|
6213
|
+
e.stopPropagation();
|
|
6214
|
+
this.openEdit(e.detail.row);
|
|
6215
|
+
}, onMrdAction: (e) => {
|
|
6216
|
+
e.stopPropagation();
|
|
6217
|
+
this.mrdAction.emit(e.detail);
|
|
6218
|
+
} }));
|
|
5906
6219
|
}
|
|
5907
6220
|
render() {
|
|
5908
|
-
|
|
5909
|
-
const suffix = this.dataType === ClientLayoutItemFieldDataType.PERCENTAGE ? '%' :
|
|
5910
|
-
this.dataType === ClientLayoutItemFieldDataType.DECIMAL ? '' : '';
|
|
5911
|
-
return (h(Host, { key: '7343dbca882b5054f22de17672ac748a8e3eca11' }, h("div", { key: 'cef10b39515b48fc9c44e651910c6a0c2a847628', class: "mrd-number-field" }, h(FieldLabel, { key: '66f178cf20f1f2f0587bd9614db150d6ae63023e', base: "mrd-number-field", label: this.label, required: this.required }), h("div", { key: 'c57c22e663a570f6e5a70b07b817970f135e850c', class: "mrd-number-field__input-wrapper" }, h("input", { key: '388b20ac11fa4aaf78df124c858b579e12f53619', class: controlClass('mrd-number-field', hasError), 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 })), h(FieldError, { key: 'f99bb85668b047a97162ffee2582eb45dc0589ae', base: "mrd-number-field", error: this.error }))));
|
|
6221
|
+
return (h(Host, { key: 'cf5e9a23e1e8496d061c00218029ec49d92700fe' }, this.renderToolbar(), h("div", { key: '5a15a60ea4cc68c77a8928068f7d6d6c3cb91434', class: "mrd-memo-container__body" }, this.mode === 'cards' ? this.renderCards() : this.renderTable()), this.renderDialog()));
|
|
5912
6222
|
}
|
|
5913
6223
|
static get watchers() { return {
|
|
5914
|
-
"
|
|
5915
|
-
"
|
|
5916
|
-
}],
|
|
5917
|
-
"locale": [{
|
|
5918
|
-
"localeChanged": 0
|
|
6224
|
+
"dialogOpen": [{
|
|
6225
|
+
"dialogOpenChanged": 0
|
|
5919
6226
|
}]
|
|
5920
6227
|
}; }
|
|
5921
6228
|
};
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
const mrdRelationFieldCss = () => `.sc-mrd-relation-field-h{display:block}.mrd-relation-field.sc-mrd-relation-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%;position:relative}.mrd-relation-field__label.sc-mrd-relation-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-relation-field__label--required.sc-mrd-relation-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-relation-field__select.sc-mrd-relation-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);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);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-relation-field__select.sc-mrd-relation-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-relation-field__select.sc-mrd-relation-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-relation-field__select.sc-mrd-relation-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-relation-field__select--error.sc-mrd-relation-field{border-color:var(--mrd-border-color-error)}.mrd-relation-field__select--error.sc-mrd-relation-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-relation-field__select.sc-mrd-relation-field{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right var(--mrd-space-3) center;padding-right:calc(var(--mrd-input-padding-x) + 1.5rem);cursor:pointer}.mrd-relation-field__search.sc-mrd-relation-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);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);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-relation-field__search.sc-mrd-relation-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-relation-field__search.sc-mrd-relation-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-relation-field__search.sc-mrd-relation-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-relation-field__search--error.sc-mrd-relation-field{border-color:var(--mrd-border-color-error)}.mrd-relation-field__search--error.sc-mrd-relation-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-relation-field__error.sc-mrd-relation-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-relation-field__tags.sc-mrd-relation-field{display:flex;flex-wrap:wrap;gap:var(--mrd-space-1);margin-bottom:var(--mrd-space-1)}.mrd-relation-field__tag.sc-mrd-relation-field{display:inline-flex;align-items:center;gap:var(--mrd-space-1);padding:var(--mrd-space-1) var(--mrd-space-2);background-color:var(--mrd-color-primary-light);color:var(--mrd-color-primary-dark);border-radius:var(--mrd-border-radius-full);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium)}.mrd-relation-field__tag-remove.sc-mrd-relation-field{background:none;border:none;cursor:pointer;color:var(--mrd-color-primary-dark);font-size:var(--mrd-font-size-xs);padding:0;line-height:1;opacity:0.7}.mrd-relation-field__tag-remove.sc-mrd-relation-field:hover{opacity:1}.mrd-relation-field__search-wrapper.sc-mrd-relation-field{position:relative;display:flex;align-items:center}.mrd-relation-field__spinner.sc-mrd-relation-field{position:absolute;right:var(--mrd-space-3);width:16px;height:16px;border:2px solid var(--mrd-color-neutral-200);border-top-color:var(--mrd-color-primary);border-radius:50%;animation:mrd-spin 0.7s linear infinite}.mrd-relation-field__results.sc-mrd-relation-field{position:absolute;top:calc(100% + var(--mrd-space-1));left:0;right:0;background-color:var(--mrd-color-white);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);box-shadow:var(--mrd-shadow-md);z-index:var(--mrd-z-dropdown);max-height:240px;overflow-y:auto}.mrd-relation-field__result-item.sc-mrd-relation-field{display:flex;flex-direction:column;padding:var(--mrd-space-2) var(--mrd-space-3);cursor:pointer;transition:background-color var(--mrd-transition-fast)}.mrd-relation-field__result-item.sc-mrd-relation-field:hover{background-color:var(--mrd-color-neutral-50)}.mrd-relation-field__result-item.sc-mrd-relation-field:not(:last-child){border-bottom:var(--mrd-border-width) solid var(--mrd-color-neutral-100)}.mrd-relation-field__result-item--highlighted.sc-mrd-relation-field{background-color:var(--mrd-color-primary-light)}.mrd-relation-field__result-label.sc-mrd-relation-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-800);font-weight:var(--mrd-font-weight-medium)}.mrd-relation-field__result-desc.sc-mrd-relation-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);margin-top:var(--mrd-space-1)}.mrd-relation-field__selected-value.sc-mrd-relation-field{display:flex;align-items:center;gap:var(--mrd-space-2);height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);background-color:var(--mrd-color-primary-light);border:var(--mrd-border-width) solid var(--mrd-color-primary);border-radius:var(--mrd-border-radius);box-sizing:border-box}.mrd-relation-field__selected-value--error.sc-mrd-relation-field{border-color:var(--mrd-border-color-error);background-color:var(--mrd-color-danger-light)}.mrd-relation-field__selected-name.sc-mrd-relation-field{flex:1;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-primary-dark);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mrd-relation-field__selected-clear.sc-mrd-relation-field{flex-shrink:0;background:none;border:none;cursor:pointer;color:var(--mrd-color-primary-dark);font-size:var(--mrd-font-size-sm);padding:0;line-height:1;opacity:0.6;transition:opacity var(--mrd-transition-fast)}.mrd-relation-field__selected-clear.sc-mrd-relation-field:hover{opacity:1}.mrd-relation-field__no-results.sc-mrd-relation-field{padding:var(--mrd-space-4);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-500);text-align:center}@keyframes mrd-spin{to{transform:rotate(360deg)}}`;
|
|
6229
|
+
MrdMemoContainer.style = mrdMemoContainerCss();
|
|
5925
6230
|
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
6231
|
+
/**
|
|
6232
|
+
* Pure sort/filter/aggregation query logic for mrd-table.
|
|
6233
|
+
* No component state — everything is passed in.
|
|
6234
|
+
*/
|
|
6235
|
+
const TEXT_TYPES = new Set(['TEXT', 'TEXTBLOCK', 'EMAIL', 'HYPERLINK']);
|
|
6236
|
+
const NUMERIC_TYPES = new Set(['INTEGER', 'DECIMAL', 'PERCENTAGE', 'CURRENCY']);
|
|
6237
|
+
const DATE_TYPES = new Set(['DATE', 'DATETIME', 'TIME']);
|
|
6238
|
+
const NO_FILTER_TYPES = new Set(['FILE', 'IMAGE']);
|
|
6239
|
+
/** Column types that cannot be sorted or filtered (not stored in PostgreSQL). */
|
|
6240
|
+
const NON_INTERACTIVE_TYPES = new Set(['LONGTEXT', 'JSON', 'FILE', 'IMAGE']);
|
|
6241
|
+
/** Wait this long (ms) after the user stops typing in the free-text search box
|
|
6242
|
+
* before firing the search request — mirrors REQUEST_DEBOUNCE_MS's purpose
|
|
6243
|
+
* (skip intermediate keystrokes) but is tuned for typing, not scrolling. */
|
|
6244
|
+
const SEARCH_DEBOUNCE_MS = 400;
|
|
6245
|
+
function parseDefaultSort(defaultSort) {
|
|
6246
|
+
var _a;
|
|
6247
|
+
if (!defaultSort)
|
|
6248
|
+
return { field: '', dir: 'asc' };
|
|
6249
|
+
const parts = defaultSort.split(',');
|
|
6250
|
+
return { field: parts[0].trim(), dir: ((_a = parts[1]) === null || _a === void 0 ? void 0 : _a.trim()) === 'desc' ? 'desc' : 'asc' };
|
|
6251
|
+
}
|
|
6252
|
+
/** Raw sort query-param value, e.g. "name" or "name,desc". */
|
|
6253
|
+
function buildSortParam(field, dir) {
|
|
6254
|
+
if (!field)
|
|
6255
|
+
return '';
|
|
6256
|
+
return dir === 'desc' ? `${field},desc` : field;
|
|
6257
|
+
}
|
|
6258
|
+
/** Query params for a page request: page + sort + filterClass + view filters + active column filters. */
|
|
6259
|
+
function buildTableQueryParams(opts) {
|
|
6260
|
+
var _a, _b;
|
|
6261
|
+
const p = new URLSearchParams();
|
|
6262
|
+
if (opts.page > 0)
|
|
6263
|
+
p.set('page', String(opts.page));
|
|
6264
|
+
if (opts.sort)
|
|
6265
|
+
p.set('sort', opts.sort);
|
|
6266
|
+
if (opts.filterClass)
|
|
6267
|
+
p.set('type', opts.filterClass);
|
|
6268
|
+
applyViewFilters(p, opts.viewFilters);
|
|
6269
|
+
if (opts.query)
|
|
6270
|
+
p.set('q', opts.query);
|
|
6271
|
+
for (const f of opts.activeFilters) {
|
|
6272
|
+
if (f.operator === 'isEmpty') {
|
|
6273
|
+
p.set(f.field, '');
|
|
6274
|
+
continue;
|
|
6275
|
+
}
|
|
6276
|
+
if (f.operator === 'isNotEmpty') {
|
|
6277
|
+
p.set(f.field + '_notempty', 'true');
|
|
6278
|
+
continue;
|
|
6279
|
+
}
|
|
6280
|
+
if (f.operator === 'startsWith') {
|
|
6281
|
+
p.set(f.field + '_startswith', String((_a = f.value) !== null && _a !== void 0 ? _a : ''));
|
|
6282
|
+
continue;
|
|
6283
|
+
}
|
|
6284
|
+
if ((_b = f.values) === null || _b === void 0 ? void 0 : _b.length) {
|
|
6285
|
+
p.set(f.field, f.values.join(','));
|
|
6286
|
+
continue;
|
|
6287
|
+
}
|
|
6288
|
+
if (f.value != null)
|
|
6289
|
+
p.set(f.field, String(f.value));
|
|
6290
|
+
if (f.from != null)
|
|
6291
|
+
p.set(f.field + '_from', String(f.from));
|
|
6292
|
+
if (f.to != null)
|
|
6293
|
+
p.set(f.field + '_to', String(f.to));
|
|
6294
|
+
}
|
|
6295
|
+
return p.toString();
|
|
6296
|
+
}
|
|
6297
|
+
/** Groups aggregate columns by function; null when the view has no aggregates. */
|
|
6298
|
+
function buildAggregationParams(columns) {
|
|
6299
|
+
var _a;
|
|
6300
|
+
const groups = { sum: [], avg: [], count: [] };
|
|
6301
|
+
for (const col of columns) {
|
|
6302
|
+
if (col.type !== 'FIELD' || !col.aggregate)
|
|
6303
|
+
continue;
|
|
6304
|
+
const fn = col.aggregate.toLowerCase();
|
|
6305
|
+
if (fn in groups)
|
|
6306
|
+
groups[fn].push((_a = col.name) !== null && _a !== void 0 ? _a : '');
|
|
6307
|
+
}
|
|
6308
|
+
const params = {};
|
|
6309
|
+
if (groups.sum.length)
|
|
6310
|
+
params.sum = groups.sum;
|
|
6311
|
+
if (groups.avg.length)
|
|
6312
|
+
params.avg = groups.avg;
|
|
6313
|
+
if (groups.count.length)
|
|
6314
|
+
params.count = groups.count;
|
|
6315
|
+
return Object.keys(params).length > 0 ? params : null;
|
|
6316
|
+
}
|
|
6317
|
+
/** Aggregation query string: the page-0 query params without page/sort, plus sum/avg/count. */
|
|
6318
|
+
function buildAggregationQs(basePageQs, columns) {
|
|
6319
|
+
var _a, _b, _c;
|
|
6320
|
+
const p = new URLSearchParams(basePageQs);
|
|
6321
|
+
p.delete('page');
|
|
6322
|
+
p.delete('sort');
|
|
6323
|
+
const groups = buildAggregationParams(columns);
|
|
6324
|
+
if ((_a = groups === null || groups === void 0 ? void 0 : groups.sum) === null || _a === void 0 ? void 0 : _a.length)
|
|
6325
|
+
p.set('sum', groups.sum.join(','));
|
|
6326
|
+
if ((_b = groups === null || groups === void 0 ? void 0 : groups.avg) === null || _b === void 0 ? void 0 : _b.length)
|
|
6327
|
+
p.set('avg', groups.avg.join(','));
|
|
6328
|
+
if ((_c = groups === null || groups === void 0 ? void 0 : groups.count) === null || _c === void 0 ? void 0 : _c.length)
|
|
6329
|
+
p.set('count', groups.count.join(','));
|
|
6330
|
+
return p.toString();
|
|
6331
|
+
}
|
|
6332
|
+
/** True when the pending filter actually constrains anything. */
|
|
6333
|
+
function filterHasValue(f) {
|
|
6334
|
+
if (f.operator === 'isEmpty' || f.operator === 'isNotEmpty')
|
|
6335
|
+
return true;
|
|
6336
|
+
if (f.values !== undefined && f.values.length > 0)
|
|
6337
|
+
return true;
|
|
6338
|
+
if (f.value != null && f.value !== '')
|
|
6339
|
+
return true;
|
|
6340
|
+
if (typeof f.value === 'boolean')
|
|
6341
|
+
return true;
|
|
6342
|
+
if (f.from != null && f.from !== '')
|
|
6343
|
+
return true;
|
|
6344
|
+
if (f.to != null && f.to !== '')
|
|
6345
|
+
return true;
|
|
6346
|
+
return false;
|
|
6347
|
+
}
|
|
6348
|
+
// ── DATETIME filters: the user edits local "YYYY-MM-DD" dates, the API stores UTC ISO ──
|
|
6349
|
+
/** UTC ISO string at the start (midnight) of the given local day. */
|
|
6350
|
+
function dateLocalToUTCStart(dateStr) {
|
|
6351
|
+
if (!dateStr)
|
|
6352
|
+
return dateStr;
|
|
6353
|
+
const [year, month, day] = dateStr.split('-').map(Number);
|
|
6354
|
+
return new Date(year, month - 1, day).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
6355
|
+
}
|
|
6356
|
+
/** Start of the day AFTER the given local date (exclusive range end). */
|
|
6357
|
+
function dateLocalToUTCEndExclusive(dateStr) {
|
|
6358
|
+
if (!dateStr)
|
|
6359
|
+
return dateStr;
|
|
6360
|
+
const [year, month, day] = dateStr.split('-').map(Number);
|
|
6361
|
+
return new Date(year, month - 1, day + 1).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
6362
|
+
}
|
|
6363
|
+
/** Stored UTC ISO string back to the local "YYYY-MM-DD" date. */
|
|
6364
|
+
function utcISOToLocalDate(utcStr) {
|
|
6365
|
+
if (!utcStr)
|
|
6366
|
+
return utcStr;
|
|
6367
|
+
const d = new Date(utcStr);
|
|
6368
|
+
if (isNaN(d.getTime()))
|
|
6369
|
+
return utcStr;
|
|
6370
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
6371
|
+
}
|
|
6372
|
+
/** The stored "to" is the exclusive end (next midnight); subtract a day to recover the entered date. */
|
|
6373
|
+
function utcISOToLocalDateExclusiveEnd(utcStr) {
|
|
6374
|
+
if (!utcStr)
|
|
6375
|
+
return utcStr;
|
|
6376
|
+
const d = new Date(utcStr);
|
|
6377
|
+
if (isNaN(d.getTime()))
|
|
6378
|
+
return utcStr;
|
|
6379
|
+
d.setDate(d.getDate() - 1);
|
|
6380
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
6381
|
+
}
|
|
6382
|
+
/** Applies the local→UTC conversion when a DATETIME filter is submitted.
|
|
6383
|
+
* Exact date → range covering the full local day. */
|
|
6384
|
+
function normalizeDatetimeFilter(f) {
|
|
6385
|
+
const normalized = Object.assign({}, f);
|
|
6386
|
+
if (f.dataType === 'DATETIME' && f.operator !== 'isEmpty' && f.operator !== 'isNotEmpty') {
|
|
6387
|
+
if (typeof normalized.value === 'string' && normalized.value) {
|
|
6388
|
+
normalized.from = dateLocalToUTCStart(normalized.value);
|
|
6389
|
+
normalized.to = dateLocalToUTCEndExclusive(normalized.value);
|
|
6390
|
+
normalized.value = undefined;
|
|
6391
|
+
}
|
|
6392
|
+
else {
|
|
6393
|
+
if (typeof normalized.from === 'string' && normalized.from)
|
|
6394
|
+
normalized.from = dateLocalToUTCStart(normalized.from);
|
|
6395
|
+
if (typeof normalized.to === 'string' && normalized.to)
|
|
6396
|
+
normalized.to = dateLocalToUTCEndExclusive(normalized.to);
|
|
6397
|
+
}
|
|
6398
|
+
}
|
|
6399
|
+
return normalized;
|
|
6400
|
+
}
|
|
6401
|
+
/** Converts a stored DATETIME filter back to local dates for the popup.
|
|
6402
|
+
* A range covering a single local day is restored to exact-date mode. */
|
|
6403
|
+
function datetimeFilterToDisplay(existing) {
|
|
6404
|
+
const display = Object.assign({}, existing);
|
|
6405
|
+
if (typeof display.from === 'string' && display.from)
|
|
6406
|
+
display.from = utcISOToLocalDate(display.from);
|
|
6407
|
+
if (typeof display.to === 'string' && display.to)
|
|
6408
|
+
display.to = utcISOToLocalDateExclusiveEnd(display.to);
|
|
6409
|
+
if (display.from && display.to && display.from === display.to) {
|
|
6410
|
+
return Object.assign(Object.assign({}, display), { value: display.from, from: undefined, to: undefined });
|
|
6411
|
+
}
|
|
6412
|
+
return display;
|
|
6413
|
+
}
|
|
6414
|
+
|
|
6415
|
+
const mrdMemoListCss = () => `@charset "UTF-8";.sc-mrd-memo-list-h{display:block}.mrd-memo-list.sc-mrd-memo-list{display:flex;flex-direction:column;gap:var(--mrd-space-3)}.mrd-memo-list__card.sc-mrd-memo-list{display:flex;flex-direction:column;gap:var(--mrd-space-2);width:100%;padding:var(--mrd-space-4);background:var(--mrd-color-white);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-md);font-family:var(--mrd-font-family);text-align:left;cursor:pointer;transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition)}.mrd-memo-list__card.sc-mrd-memo-list:hover{border-color:var(--mrd-color-primary);box-shadow:var(--mrd-shadow-sm, 0 1px 2px rgba(0, 0, 0, 0.06))}.mrd-memo-list__card.sc-mrd-memo-list:focus-visible{outline:none;box-shadow:var(--mrd-shadow-focus)}.mrd-memo-list__card--readonly.sc-mrd-memo-list{cursor:default}.mrd-memo-list__card--readonly.sc-mrd-memo-list:hover{border-color:var(--mrd-border-color);box-shadow:none}.mrd-memo-list__card-header.sc-mrd-memo-list{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--mrd-space-2)}.mrd-memo-list__card-title.sc-mrd-memo-list{font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-neutral-900)}.mrd-memo-list__card-important.sc-mrd-memo-list{display:inline-flex;flex-shrink:0;color:var(--mrd-color-warning)}.mrd-memo-list__card-important.sc-mrd-memo-list svg.sc-mrd-memo-list{width:1rem;height:1rem}.mrd-memo-list__card-body-wrap.sc-mrd-memo-list{display:flex;flex-direction:column;align-items:flex-start;gap:var(--mrd-space-1)}.mrd-memo-list__card-body.sc-mrd-memo-list{margin:0;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-600);line-height:var(--mrd-line-height-relaxed);word-break:break-word}.mrd-memo-list__card-body.sc-mrd-memo-list p.sc-mrd-memo-list,.mrd-memo-list__card-body.sc-mrd-memo-list ul.sc-mrd-memo-list,.mrd-memo-list__card-body.sc-mrd-memo-list ol.sc-mrd-memo-list{margin:0 0 var(--mrd-space-1) 0}.mrd-memo-list__card-body--clamped.sc-mrd-memo-list{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.mrd-memo-list__card-toggle.sc-mrd-memo-list{background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-primary);cursor:pointer}.mrd-memo-list__card-toggle.sc-mrd-memo-list:hover{text-decoration:underline}.mrd-memo-list__labels.sc-mrd-memo-list{display:flex;flex-wrap:wrap;gap:var(--mrd-space-2)}.mrd-memo-list__badge.sc-mrd-memo-list{display:inline-flex;align-items:center;height:1.25rem;padding:0 var(--mrd-space-2);border-radius:var(--mrd-border-radius-full, 999px);font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium)}.mrd-memo-list__badge--plain.sc-mrd-memo-list{background:var(--mrd-color-neutral-100);color:var(--mrd-color-neutral-600)}.mrd-memo-list__card-meta.sc-mrd-memo-list{display:flex;align-items:center;gap:var(--mrd-space-2);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-400)}.mrd-memo-list__card-author.sc-mrd-memo-list+.mrd-memo-list__card-date.sc-mrd-memo-list::before{content:"·";margin-right:var(--mrd-space-2)}.mrd-memo-list__empty.sc-mrd-memo-list{padding:var(--mrd-space-6);text-align:center;color:var(--mrd-color-neutral-400);font-size:var(--mrd-font-size-sm)}.mrd-memo-list__load-more.sc-mrd-memo-list{align-self:center;height:var(--mrd-input-height);padding:0 var(--mrd-space-6);background:transparent;color:var(--mrd-color-neutral-600);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);cursor:pointer;transition:background-color var(--mrd-transition)}.mrd-memo-list__load-more.sc-mrd-memo-list:hover:not(:disabled){background-color:var(--mrd-color-neutral-100)}.mrd-memo-list__load-more.sc-mrd-memo-list:disabled{opacity:0.6;cursor:default}`;
|
|
6416
|
+
|
|
6417
|
+
/** Plain-text length above which a card's body is clamped with a show-more toggle. */
|
|
6418
|
+
const BODY_PREVIEW_THRESHOLD = 220;
|
|
6419
|
+
const MrdMemoList = class {
|
|
6420
|
+
constructor(hostRef) {
|
|
6421
|
+
registerInstance(this, hostRef);
|
|
6422
|
+
this.mrdLoadPage = createEvent(this, "mrdLoadPage");
|
|
6423
|
+
this.mrdEdit = createEvent(this, "mrdEdit");
|
|
6424
|
+
/** The VIEW or RELATED_VIEW layout item (dataClass, fromClass, view config). */
|
|
6425
|
+
this.item = null;
|
|
6426
|
+
/** Parent record id — required for RELATED_VIEW path building. */
|
|
6427
|
+
this.parentId = '';
|
|
6428
|
+
/** Records per page (must match API page size). */
|
|
6429
|
+
this.pageSize = 20;
|
|
6430
|
+
this.locale = navigator.language;
|
|
6431
|
+
/** When true, cards are not clickable (no mrdEdit) — matches mrd-table's own
|
|
6432
|
+
* readOnly gating on its create action. */
|
|
6433
|
+
this.readOnly = false;
|
|
6434
|
+
/** listItems of the FIELD bound to the `labels` slot, resolved by mrd-layout-section
|
|
6435
|
+
* from its own items array, same reason mrd-memo-view needs it. */
|
|
6436
|
+
this.labelsListItems = null;
|
|
6437
|
+
this.rows = [];
|
|
6438
|
+
this.loading = false;
|
|
6439
|
+
this.exhausted = false;
|
|
6440
|
+
this.started = false;
|
|
6441
|
+
this.expandedHrefs = new Set();
|
|
6442
|
+
this.nextPage = 0;
|
|
6443
|
+
this.loadMore = () => {
|
|
6444
|
+
if (this.loading || this.exhausted)
|
|
6445
|
+
return;
|
|
6446
|
+
this.emitLoadPage(this.nextPage);
|
|
6447
|
+
};
|
|
6448
|
+
this.toggleExpanded = (e, href) => {
|
|
6449
|
+
e.stopPropagation();
|
|
6450
|
+
const next = new Set(this.expandedHrefs);
|
|
6451
|
+
if (next.has(href))
|
|
6452
|
+
next.delete(href);
|
|
6453
|
+
else
|
|
6454
|
+
next.add(href);
|
|
6455
|
+
this.expandedHrefs = next;
|
|
6456
|
+
};
|
|
6457
|
+
}
|
|
6458
|
+
buildDataPath() {
|
|
6459
|
+
var _a, _b, _c, _d, _e;
|
|
6460
|
+
return buildListPath({
|
|
6461
|
+
isRelatedView: ((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'RELATED_VIEW',
|
|
6462
|
+
fromClass: (_b = this.item) === null || _b === void 0 ? void 0 : _b.fromClass,
|
|
6463
|
+
parentId: this.parentId,
|
|
6464
|
+
dataClass: (_d = (_c = this.item) === null || _c === void 0 ? void 0 : _c.dataClass) !== null && _d !== void 0 ? _d : (_e = this.item) === null || _e === void 0 ? void 0 : _e.relatedClass,
|
|
6465
|
+
});
|
|
6466
|
+
}
|
|
6467
|
+
sortParam() {
|
|
6468
|
+
var _a, _b, _c;
|
|
6469
|
+
const { field, dir } = parseDefaultSort((_c = (_b = (_a = this.item) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.defaultSort) !== null && _c !== void 0 ? _c : '');
|
|
6470
|
+
return buildSortParam(field, dir);
|
|
6471
|
+
}
|
|
6472
|
+
emitLoadPage(page) {
|
|
6473
|
+
var _a, _b, _c;
|
|
6474
|
+
this.loading = true;
|
|
6475
|
+
this.mrdLoadPage.emit({
|
|
6476
|
+
page,
|
|
6477
|
+
sort: this.sortParam(),
|
|
6478
|
+
path: this.buildDataPath(),
|
|
6479
|
+
qs: buildTableQueryParams({
|
|
6480
|
+
page,
|
|
6481
|
+
sort: this.sortParam(),
|
|
6482
|
+
filterClass: (_a = this.item) === null || _a === void 0 ? void 0 : _a.filterClass,
|
|
6483
|
+
viewFilters: (_c = (_b = this.item) === null || _b === void 0 ? void 0 : _b.view) === null || _c === void 0 ? void 0 : _c.filter,
|
|
6484
|
+
activeFilters: [],
|
|
6485
|
+
}),
|
|
6486
|
+
});
|
|
6487
|
+
}
|
|
6488
|
+
/** Reset and request page 0. Call after setting all props, mirrors mrd-table.init(). */
|
|
6489
|
+
async init() {
|
|
6490
|
+
this.rows = [];
|
|
6491
|
+
this.loading = false;
|
|
6492
|
+
this.exhausted = false;
|
|
6493
|
+
this.started = true;
|
|
6494
|
+
this.nextPage = 0;
|
|
6495
|
+
this.emitLoadPage(0);
|
|
6496
|
+
}
|
|
6497
|
+
/** Inject the rows for a page (0-based); page 0 replaces, later pages append. */
|
|
6498
|
+
async setPage(pageNumber, rows, hasNext) {
|
|
6499
|
+
this.loading = false;
|
|
6500
|
+
this.rows = pageNumber === 0 ? rows : [...this.rows, ...rows];
|
|
6501
|
+
this.nextPage = pageNumber + 1;
|
|
6502
|
+
this.exhausted = hasNext !== undefined ? !hasNext : rows.length < this.pageSize;
|
|
6503
|
+
}
|
|
6504
|
+
/** Optimistically merge an edit into the matching row — mrdUpdateObject's PATCH
|
|
6505
|
+
* is fire-and-forget on the host side, so this is what makes an edit visible
|
|
6506
|
+
* immediately rather than only after the next full reload. */
|
|
6507
|
+
async patchRow(href, values) {
|
|
6508
|
+
this.rows = this.rows.map(row => { var _a, _b; return ((_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) === href ? Object.assign(Object.assign({}, row), values) : row; });
|
|
6509
|
+
}
|
|
6510
|
+
/** Optimistically drop a deleted row — mrdDeleteObject's DELETE is fire-and-
|
|
6511
|
+
* forget on the host side, same reasoning as patchRow(). */
|
|
6512
|
+
async removeRow(href) {
|
|
6513
|
+
this.rows = this.rows.filter(row => { var _a, _b; return ((_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) !== href; });
|
|
6514
|
+
}
|
|
6515
|
+
/** Value of a value-slot: reads row[field] via the slot→field map. */
|
|
6516
|
+
slotValue(row, slot) {
|
|
6517
|
+
var _a, _b;
|
|
6518
|
+
const field = (_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b[slot];
|
|
6519
|
+
if (!field)
|
|
6520
|
+
return undefined;
|
|
6521
|
+
return row[field];
|
|
6522
|
+
}
|
|
6523
|
+
/** Relation link for a relation-slot: reads row._links[field]. */
|
|
6524
|
+
slotLink(row, slot) {
|
|
6525
|
+
var _a, _b, _c;
|
|
6526
|
+
const field = (_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b[slot];
|
|
6527
|
+
if (!field)
|
|
6528
|
+
return undefined;
|
|
6529
|
+
const links = ((_c = row === null || row === void 0 ? void 0 : row._links) !== null && _c !== void 0 ? _c : {});
|
|
6530
|
+
return links[field];
|
|
6531
|
+
}
|
|
6532
|
+
plainTextLength(row) {
|
|
6533
|
+
const raw = this.slotValue(row, 'body');
|
|
6534
|
+
if (raw == null || raw === '')
|
|
6535
|
+
return 0;
|
|
6536
|
+
return String(raw).replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim().length;
|
|
6537
|
+
}
|
|
6538
|
+
renderLabels(row) {
|
|
6539
|
+
const raw = this.slotValue(row, 'labels');
|
|
6540
|
+
const keys = Array.isArray(raw) ? raw.map(String) : (raw != null && raw !== '' ? [String(raw)] : []);
|
|
6541
|
+
if (!keys.length)
|
|
6542
|
+
return null;
|
|
6543
|
+
return (h("div", { class: "mrd-memo-list__labels" }, keys.map(key => {
|
|
6544
|
+
var _a, _b;
|
|
6545
|
+
const listItem = ((_a = this.labelsListItems) !== null && _a !== void 0 ? _a : []).find(li => li.key === key);
|
|
6546
|
+
const label = (_b = listItem === null || listItem === void 0 ? void 0 : listItem.label) !== null && _b !== void 0 ? _b : key;
|
|
6547
|
+
if ((listItem === null || listItem === void 0 ? void 0 : listItem.color) && (listItem === null || listItem === void 0 ? void 0 : listItem.backgroundColor)) {
|
|
6548
|
+
return (h("span", { key: key, class: "mrd-memo-list__badge", style: { color: listItem.color, backgroundColor: listItem.backgroundColor } }, label));
|
|
6549
|
+
}
|
|
6550
|
+
return h("span", { key: key, class: "mrd-memo-list__badge mrd-memo-list__badge--plain" }, label);
|
|
6551
|
+
})));
|
|
6552
|
+
}
|
|
6553
|
+
renderBody(row, href) {
|
|
6554
|
+
const raw = this.slotValue(row, 'body');
|
|
6555
|
+
if (raw == null || raw === '')
|
|
6556
|
+
return null;
|
|
6557
|
+
const expanded = this.expandedHrefs.has(href);
|
|
6558
|
+
const needsToggle = this.plainTextLength(row) > BODY_PREVIEW_THRESHOLD;
|
|
6559
|
+
return (h("div", { class: "mrd-memo-list__card-body-wrap" }, h("div", { class: {
|
|
6560
|
+
'mrd-memo-list__card-body': true,
|
|
6561
|
+
'mrd-memo-list__card-body--clamped': needsToggle && !expanded,
|
|
6562
|
+
}, innerHTML: purify.sanitize(String(raw)) }), needsToggle && (h("button", { type: "button", class: "mrd-memo-list__card-toggle", onClick: e => this.toggleExpanded(e, href) }, t(expanded ? 'textblock_show_less' : 'textblock_show_more', this.locale)))));
|
|
6563
|
+
}
|
|
6564
|
+
renderCard(row, index) {
|
|
6565
|
+
var _a, _b, _c;
|
|
6566
|
+
const titleRaw = this.slotValue(row, 'title');
|
|
6567
|
+
const title = titleRaw != null && titleRaw !== '' ? String(titleRaw) : null;
|
|
6568
|
+
const dateRaw = this.slotValue(row, 'date');
|
|
6569
|
+
const author = this.slotLink(row, 'author');
|
|
6570
|
+
const important = !!this.slotValue(row, 'important');
|
|
6571
|
+
const href = (_c = (_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) !== null && _c !== void 0 ? _c : '';
|
|
6572
|
+
return (h("div", { key: href || index, class: { 'mrd-memo-list__card': true, 'mrd-memo-list__card--readonly': this.readOnly }, role: this.readOnly ? undefined : 'button', tabIndex: this.readOnly ? undefined : 0, onClick: () => {
|
|
6573
|
+
if (!this.readOnly)
|
|
6574
|
+
this.mrdEdit.emit({ row });
|
|
6575
|
+
}, onKeyDown: e => {
|
|
6576
|
+
if (this.readOnly)
|
|
6577
|
+
return;
|
|
6578
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
6579
|
+
e.preventDefault();
|
|
6580
|
+
this.mrdEdit.emit({ row });
|
|
6581
|
+
}
|
|
6582
|
+
} }, h("div", { class: "mrd-memo-list__card-header" }, title && h("span", { class: "mrd-memo-list__card-title" }, title), important && (h("span", { class: "mrd-memo-list__card-important", title: t('memo_important', this.locale) }, h("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true" }, h("path", { d: "M12 2l2.9 6.26L22 9.27l-5 4.87L18.18 21 12 17.27 5.82 21 7 14.14l-5-4.87 7.1-1.01z" }))))), this.renderBody(row, href), this.renderLabels(row), h("div", { class: "mrd-memo-list__card-meta" }, (author === null || author === void 0 ? void 0 : author.name) && h("span", { class: "mrd-memo-list__card-author" }, author.name), dateRaw != null && dateRaw !== '' && (h("span", { class: "mrd-memo-list__card-date" }, formatDateTime(dateRaw, this.locale))))));
|
|
6583
|
+
}
|
|
6584
|
+
render() {
|
|
6585
|
+
return (h(Host, { key: 'c4c5ce4e96bf2aa754d85b260db8920fdde9311d' }, h("div", { key: '0db49511231edbf946f98734e0bab91cbdf31795', class: "mrd-memo-list" }, this.rows.map((row, i) => this.renderCard(row, i)), this.started && !this.loading && this.rows.length === 0 && (h("div", { key: '2a7a027673d01d63523ce252fe2fbff8ba0515fd', class: "mrd-memo-list__empty" }, t('no_results', this.locale))), !this.exhausted && this.rows.length > 0 && (h("button", { key: '45dfd4a9ccab721d422935c48509d46989c9a360', type: "button", class: "mrd-memo-list__load-more", disabled: this.loading, onClick: this.loadMore }, t('load_more', this.locale))))));
|
|
6586
|
+
}
|
|
6587
|
+
};
|
|
6588
|
+
MrdMemoList.style = mrdMemoListCss();
|
|
6589
|
+
|
|
6590
|
+
const mrdMemoViewCss = () => `@charset "UTF-8";.sc-mrd-memo-view-h{display:block}.mrd-memo-view.sc-mrd-memo-view{max-width:720px;display:flex;flex-direction:column;gap:var(--mrd-space-3)}.mrd-memo-view__header.sc-mrd-memo-view{display:flex;align-items:baseline;flex-wrap:wrap;gap:var(--mrd-space-3)}.mrd-memo-view__title.sc-mrd-memo-view{font-size:var(--mrd-font-size-2xl);font-weight:var(--mrd-font-weight-bold);color:var(--mrd-color-neutral-900);letter-spacing:-0.02em;margin:0}.mrd-memo-view__important.sc-mrd-memo-view{display:inline-flex;align-items:center;gap:var(--mrd-space-1);font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-semibold);color:var(--mrd-color-warning);text-transform:uppercase;letter-spacing:0.04em}.mrd-memo-view__important.sc-mrd-memo-view svg.sc-mrd-memo-view{width:0.875rem;height:0.875rem}.mrd-memo-view__meta.sc-mrd-memo-view{display:flex;align-items:center;gap:var(--mrd-space-2);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-400)}.mrd-memo-view__meta-author.sc-mrd-memo-view{background:none;border:none;padding:0;font-family:var(--mrd-font-family);font-size:inherit;font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-500);cursor:pointer}.mrd-memo-view__meta-author.sc-mrd-memo-view:hover{color:var(--mrd-color-primary);text-decoration:underline}.mrd-memo-view__meta-date.sc-mrd-memo-view::before{content:"·";margin-right:var(--mrd-space-2)}.mrd-memo-view__meta-author.sc-mrd-memo-view+.mrd-memo-view__meta-date.sc-mrd-memo-view::before{content:"·"}.mrd-memo-view__labels.sc-mrd-memo-view{display:flex;flex-wrap:wrap;gap:var(--mrd-space-2)}.mrd-memo-view__badge.sc-mrd-memo-view{display:inline-flex;align-items:center;height:1.375rem;padding:0 var(--mrd-space-2);border-radius:var(--mrd-border-radius-full, 999px);font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium)}.mrd-memo-view__badge--plain.sc-mrd-memo-view{background:var(--mrd-color-neutral-100);color:var(--mrd-color-neutral-600)}.mrd-memo-view__container-link.sc-mrd-memo-view{align-self:flex-start;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}.mrd-memo-view__container-link.sc-mrd-memo-view:hover{text-decoration:underline}.mrd-memo-view__divider.sc-mrd-memo-view{height:var(--mrd-border-width);background:var(--mrd-color-neutral-200)}.mrd-memo-view__body.sc-mrd-memo-view{font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-800);line-height:var(--mrd-line-height-relaxed);word-break:break-word}`;
|
|
6591
|
+
|
|
6592
|
+
const MrdMemoView = class {
|
|
6593
|
+
constructor(hostRef) {
|
|
6594
|
+
registerInstance(this, hostRef);
|
|
6595
|
+
this.mrdNavigate = createEvent(this, "mrdNavigate");
|
|
6596
|
+
/** The data record from the /data endpoint. Fields keyed by name; relations under `_links`. */
|
|
6597
|
+
this.data = {};
|
|
6598
|
+
this.locale = navigator.language;
|
|
6599
|
+
/** listItems of the FIELD bound to the `labels` slot, resolved by mrd-layout-section
|
|
6600
|
+
* from its own items array (archetype metadata does not publish listItems), so the
|
|
6601
|
+
* label badges get a real label/color instead of the raw stored key. */
|
|
6602
|
+
this.labelsListItems = null;
|
|
6603
|
+
}
|
|
6604
|
+
/** Value of a value-slot: reads data[field] via the slot→field map. */
|
|
6605
|
+
slotValue(slot) {
|
|
6606
|
+
var _a, _b;
|
|
6607
|
+
const field = (_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b[slot];
|
|
6608
|
+
if (!field)
|
|
6609
|
+
return undefined;
|
|
6610
|
+
return this.data[field];
|
|
6611
|
+
}
|
|
6612
|
+
/** Relation link for a relation-slot: reads data._links[field]. */
|
|
6613
|
+
slotLink(slot) {
|
|
6614
|
+
var _a, _b, _c, _d;
|
|
6615
|
+
const field = (_b = (_a = this.archetype) === null || _a === void 0 ? void 0 : _a.slots) === null || _b === void 0 ? void 0 : _b[slot];
|
|
6616
|
+
if (!field)
|
|
6617
|
+
return undefined;
|
|
6618
|
+
const links = ((_d = (_c = this.data) === null || _c === void 0 ? void 0 : _c._links) !== null && _d !== void 0 ? _d : {});
|
|
6619
|
+
return links[field];
|
|
6620
|
+
}
|
|
6621
|
+
renderAuthor() {
|
|
6622
|
+
const link = this.slotLink('author');
|
|
6623
|
+
if (!(link === null || link === void 0 ? void 0 : link.href) || !link.name)
|
|
6624
|
+
return null;
|
|
6625
|
+
return (h("button", { type: "button", class: "mrd-memo-view__meta-author", onClick: () => this.mrdNavigate.emit({ href: link.href, label: link.name }) }, link.name));
|
|
6626
|
+
}
|
|
6627
|
+
renderContainer() {
|
|
6628
|
+
const link = this.slotLink('container');
|
|
6629
|
+
if (!(link === null || link === void 0 ? void 0 : link.href) || !link.name)
|
|
6630
|
+
return null;
|
|
6631
|
+
return (h("button", { type: "button", class: "mrd-memo-view__container-link", onClick: () => this.mrdNavigate.emit({ href: link.href, label: link.name }) }, link.name));
|
|
6632
|
+
}
|
|
6633
|
+
renderLabels() {
|
|
6634
|
+
const raw = this.slotValue('labels');
|
|
6635
|
+
const keys = Array.isArray(raw) ? raw.map(String) : (raw != null && raw !== '' ? [String(raw)] : []);
|
|
6636
|
+
if (!keys.length)
|
|
6637
|
+
return null;
|
|
6638
|
+
return (h("div", { class: "mrd-memo-view__labels" }, keys.map(key => {
|
|
6639
|
+
var _a, _b;
|
|
6640
|
+
const listItem = ((_a = this.labelsListItems) !== null && _a !== void 0 ? _a : []).find(li => li.key === key);
|
|
6641
|
+
const label = (_b = listItem === null || listItem === void 0 ? void 0 : listItem.label) !== null && _b !== void 0 ? _b : key;
|
|
6642
|
+
if ((listItem === null || listItem === void 0 ? void 0 : listItem.color) && (listItem === null || listItem === void 0 ? void 0 : listItem.backgroundColor)) {
|
|
6643
|
+
return (h("span", { key: key, class: "mrd-memo-view__badge", style: { color: listItem.color, backgroundColor: listItem.backgroundColor } }, label));
|
|
6644
|
+
}
|
|
6645
|
+
return h("span", { key: key, class: "mrd-memo-view__badge mrd-memo-view__badge--plain" }, label);
|
|
6646
|
+
})));
|
|
6647
|
+
}
|
|
6648
|
+
renderBody() {
|
|
6649
|
+
const bodyRaw = this.slotValue('body');
|
|
6650
|
+
if (bodyRaw == null || bodyRaw === '')
|
|
6651
|
+
return null;
|
|
6652
|
+
return h("div", { class: "mrd-memo-view__body", innerHTML: purify.sanitize(String(bodyRaw)) });
|
|
6653
|
+
}
|
|
6654
|
+
render() {
|
|
6655
|
+
const titleRaw = this.slotValue('title');
|
|
6656
|
+
const title = titleRaw != null && titleRaw !== '' ? String(titleRaw) : null;
|
|
6657
|
+
const dateRaw = this.slotValue('date');
|
|
6658
|
+
const important = !!this.slotValue('important');
|
|
6659
|
+
return (h(Host, { key: '4d8ed14c54449fbcfddc94a34dcfb220338f8bba' }, h("div", { key: '0e0456277715607580e5373ada10706db1067c7d', class: "mrd-memo-view" }, h("div", { key: 'd5c548617eca9a99eb34409b2082be025cfce2f4', class: "mrd-memo-view__header" }, title && h("h1", { key: '2ecd2eae3f8fdba310679515aa2fe76e02f0c2b2', class: "mrd-memo-view__title" }, title), important && (h("span", { key: 'e5e8284310ab6040f1677bc1241d04d65784c2da', class: "mrd-memo-view__important", title: t('memo_important', this.locale) }, h("svg", { key: 'babe987244b384330533721276b5392c9fe72c5a', viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true" }, h("path", { key: '511956710ae8e440328f9e477551ba1c2d478f1a', d: "M12 2l2.9 6.26L22 9.27l-5 4.87L18.18 21 12 17.27 5.82 21 7 14.14l-5-4.87 7.1-1.01z" })), t('memo_important', this.locale)))), h("div", { key: '41c25e5376d94078debaf62121b8bdf400511d16', class: "mrd-memo-view__meta" }, this.renderAuthor(), dateRaw != null && dateRaw !== '' && (h("span", { key: 'caff8047249745ca98da77b374438e58d150ad7f', class: "mrd-memo-view__meta-date" }, formatDateTime(dateRaw, this.locale)))), this.renderLabels(), this.renderContainer(), h("div", { key: 'bfa4c55458ea19fb920338df9478006b1883e606', class: "mrd-memo-view__divider" }), this.renderBody())));
|
|
6660
|
+
}
|
|
6661
|
+
};
|
|
6662
|
+
MrdMemoView.style = mrdMemoViewCss();
|
|
6663
|
+
|
|
6664
|
+
const mrdNumberFieldCss = () => `.sc-mrd-number-field-h{display:block}.mrd-number-field.sc-mrd-number-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%}.mrd-number-field__label.sc-mrd-number-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-number-field__label--required.sc-mrd-number-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-number-field__input-wrapper.sc-mrd-number-field{position:relative;display:flex;align-items:center}.mrd-number-field__input.sc-mrd-number-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);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);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-number-field__input.sc-mrd-number-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-number-field__input.sc-mrd-number-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-number-field__input.sc-mrd-number-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-number-field__input--error.sc-mrd-number-field{border-color:var(--mrd-border-color-error)}.mrd-number-field__input--error.sc-mrd-number-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-number-field__input.sc-mrd-number-field{text-align:right}.mrd-number-field__input.sc-mrd-number-field::placeholder{text-align:left}.mrd-number-field__error.sc-mrd-number-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}`;
|
|
6665
|
+
|
|
6666
|
+
const MrdNumberField = class {
|
|
6667
|
+
constructor(hostRef) {
|
|
6668
|
+
registerInstance(this, hostRef);
|
|
6669
|
+
this.mrdChange = createEvent(this, "mrdChange");
|
|
6670
|
+
this.mrdBlur = createEvent(this, "mrdBlur");
|
|
6671
|
+
this.name = '';
|
|
6672
|
+
this.label = '';
|
|
6673
|
+
this.value = null;
|
|
6674
|
+
this.placeholder = '';
|
|
6675
|
+
this.required = false;
|
|
6676
|
+
this.disabled = false;
|
|
6677
|
+
this.locale = navigator.language;
|
|
6678
|
+
this.dataType = ClientLayoutItemFieldDataType.INTEGER;
|
|
6679
|
+
this.decimalPrecision = 2;
|
|
6680
|
+
this.displayValue = '';
|
|
6681
|
+
this.error = '';
|
|
6682
|
+
/** While focused the user owns the text; prop updates must not overwrite it. */
|
|
6683
|
+
this.focused = false;
|
|
6684
|
+
this.handleInput = (e) => {
|
|
6685
|
+
this.displayValue = e.target.value;
|
|
6686
|
+
};
|
|
6687
|
+
this.handleBlur = (e) => {
|
|
6688
|
+
this.focused = false;
|
|
6689
|
+
const raw = e.target.value;
|
|
6690
|
+
const parsed = parseLocalizedNumber(raw, this.locale);
|
|
6691
|
+
if (this.required && (parsed === null || raw === '')) {
|
|
6692
|
+
this.error = t('required', this.locale);
|
|
6693
|
+
}
|
|
6694
|
+
else if (raw !== '' && !validateNumber(parsed, this.dataType)) {
|
|
6695
|
+
this.error = t('invalid_number', this.locale);
|
|
6696
|
+
}
|
|
6697
|
+
else {
|
|
6698
|
+
this.error = '';
|
|
6699
|
+
}
|
|
6700
|
+
if (parsed !== null && validateRequired(raw)) {
|
|
6701
|
+
this.displayValue = this.formatForDisplay(parsed);
|
|
6702
|
+
}
|
|
6703
|
+
this.mrdChange.emit({ name: this.name, value: parsed });
|
|
6704
|
+
this.mrdBlur.emit({ name: this.name, value: parsed });
|
|
6705
|
+
};
|
|
6706
|
+
this.handleFocus = () => {
|
|
6707
|
+
this.focused = true;
|
|
6708
|
+
// Drop the grouping separators while editing, but keep the locale's decimal
|
|
6709
|
+
// separator: String(1234.56) would be re-read as 123456 where '.' groups.
|
|
6710
|
+
const parsed = parseLocalizedNumber(this.displayValue, this.locale);
|
|
6711
|
+
if (parsed !== null) {
|
|
6712
|
+
this.displayValue = formatNumber(parsed, this.locale, { useGrouping: false, maximumFractionDigits: 20 });
|
|
6713
|
+
}
|
|
6714
|
+
};
|
|
6715
|
+
}
|
|
6716
|
+
componentWillLoad() {
|
|
6717
|
+
this.syncFromValue();
|
|
6718
|
+
}
|
|
6719
|
+
/** Edit mode loads the record after mount, so the incoming value must re-sync. */
|
|
6720
|
+
valueChanged() {
|
|
6721
|
+
if (!this.focused)
|
|
6722
|
+
this.syncFromValue();
|
|
6723
|
+
}
|
|
6724
|
+
localeChanged() {
|
|
6725
|
+
if (!this.focused)
|
|
6726
|
+
this.syncFromValue();
|
|
6727
|
+
}
|
|
6728
|
+
syncFromValue() {
|
|
6729
|
+
this.displayValue =
|
|
6730
|
+
this.value !== null && this.value !== undefined ? this.formatForDisplay(this.value) : '';
|
|
6731
|
+
}
|
|
6732
|
+
formatForDisplay(val) {
|
|
6733
|
+
if (this.dataType === ClientLayoutItemFieldDataType.PERCENTAGE) {
|
|
6734
|
+
return formatNumber(val, this.locale, {
|
|
6735
|
+
minimumFractionDigits: 0,
|
|
6736
|
+
maximumFractionDigits: this.decimalPrecision,
|
|
6737
|
+
}) + '%';
|
|
6738
|
+
}
|
|
6739
|
+
if (this.dataType === ClientLayoutItemFieldDataType.DECIMAL) {
|
|
6740
|
+
return formatNumber(val, this.locale, {
|
|
6741
|
+
minimumFractionDigits: this.decimalPrecision,
|
|
6742
|
+
maximumFractionDigits: this.decimalPrecision,
|
|
6743
|
+
});
|
|
6744
|
+
}
|
|
6745
|
+
return formatNumber(val, this.locale, { maximumFractionDigits: 0 });
|
|
6746
|
+
}
|
|
6747
|
+
render() {
|
|
6748
|
+
const hasError = !!this.error;
|
|
6749
|
+
const suffix = this.dataType === ClientLayoutItemFieldDataType.PERCENTAGE ? '%' :
|
|
6750
|
+
this.dataType === ClientLayoutItemFieldDataType.DECIMAL ? '' : '';
|
|
6751
|
+
return (h(Host, { key: '7343dbca882b5054f22de17672ac748a8e3eca11' }, h("div", { key: 'cef10b39515b48fc9c44e651910c6a0c2a847628', class: "mrd-number-field" }, h(FieldLabel, { key: '66f178cf20f1f2f0587bd9614db150d6ae63023e', base: "mrd-number-field", label: this.label, required: this.required }), h("div", { key: 'c57c22e663a570f6e5a70b07b817970f135e850c', class: "mrd-number-field__input-wrapper" }, h("input", { key: '388b20ac11fa4aaf78df124c858b579e12f53619', class: controlClass('mrd-number-field', hasError), 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 })), h(FieldError, { key: 'f99bb85668b047a97162ffee2582eb45dc0589ae', base: "mrd-number-field", error: this.error }))));
|
|
6752
|
+
}
|
|
6753
|
+
static get watchers() { return {
|
|
6754
|
+
"value": [{
|
|
6755
|
+
"valueChanged": 0
|
|
6756
|
+
}],
|
|
6757
|
+
"locale": [{
|
|
6758
|
+
"localeChanged": 0
|
|
6759
|
+
}]
|
|
6760
|
+
}; }
|
|
6761
|
+
};
|
|
6762
|
+
MrdNumberField.style = mrdNumberFieldCss();
|
|
6763
|
+
|
|
6764
|
+
const mrdRelationFieldCss = () => `.sc-mrd-relation-field-h{display:block}.mrd-relation-field.sc-mrd-relation-field{display:flex;flex-direction:column;gap:var(--mrd-space-1);width:100%;position:relative}.mrd-relation-field__label.sc-mrd-relation-field{display:block;font-family:var(--mrd-font-family);font-size:var(--mrd-label-font-size);font-weight:var(--mrd-label-font-weight);color:var(--mrd-label-color)}.mrd-relation-field__label--required.sc-mrd-relation-field::after{content:" *";color:var(--mrd-color-danger)}.mrd-relation-field__select.sc-mrd-relation-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);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);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-relation-field__select.sc-mrd-relation-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-relation-field__select.sc-mrd-relation-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-relation-field__select.sc-mrd-relation-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-relation-field__select--error.sc-mrd-relation-field{border-color:var(--mrd-border-color-error)}.mrd-relation-field__select--error.sc-mrd-relation-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-relation-field__select.sc-mrd-relation-field{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right var(--mrd-space-3) center;padding-right:calc(var(--mrd-input-padding-x) + 1.5rem);cursor:pointer}.mrd-relation-field__search.sc-mrd-relation-field{display:block;width:100%;height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);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);transition:border-color var(--mrd-transition), box-shadow var(--mrd-transition);outline:none;appearance:none;box-sizing:border-box}.mrd-relation-field__search.sc-mrd-relation-field::placeholder{color:var(--mrd-input-placeholder-color)}.mrd-relation-field__search.sc-mrd-relation-field:focus{border-color:var(--mrd-border-color-focus);box-shadow:var(--mrd-shadow-focus)}.mrd-relation-field__search.sc-mrd-relation-field:disabled{background-color:var(--mrd-input-bg-disabled);cursor:not-allowed;opacity:0.7}.mrd-relation-field__search--error.sc-mrd-relation-field{border-color:var(--mrd-border-color-error)}.mrd-relation-field__search--error.sc-mrd-relation-field:focus{box-shadow:var(--mrd-shadow-focus-error)}.mrd-relation-field__error.sc-mrd-relation-field{font-family:var(--mrd-font-family);font-size:var(--mrd-error-font-size);color:var(--mrd-error-color)}.mrd-relation-field__tags.sc-mrd-relation-field{display:flex;flex-wrap:wrap;gap:var(--mrd-space-1);margin-bottom:var(--mrd-space-1)}.mrd-relation-field__tag.sc-mrd-relation-field{display:inline-flex;align-items:center;gap:var(--mrd-space-1);padding:var(--mrd-space-1) var(--mrd-space-2);background-color:var(--mrd-color-primary-light);color:var(--mrd-color-primary-dark);border-radius:var(--mrd-border-radius-full);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);font-weight:var(--mrd-font-weight-medium)}.mrd-relation-field__tag-remove.sc-mrd-relation-field{background:none;border:none;cursor:pointer;color:var(--mrd-color-primary-dark);font-size:var(--mrd-font-size-xs);padding:0;line-height:1;opacity:0.7}.mrd-relation-field__tag-remove.sc-mrd-relation-field:hover{opacity:1}.mrd-relation-field__search-wrapper.sc-mrd-relation-field{position:relative;display:flex;align-items:center}.mrd-relation-field__spinner.sc-mrd-relation-field{position:absolute;right:var(--mrd-space-3);width:16px;height:16px;border:2px solid var(--mrd-color-neutral-200);border-top-color:var(--mrd-color-primary);border-radius:50%;animation:mrd-spin 0.7s linear infinite}.mrd-relation-field__results.sc-mrd-relation-field{position:absolute;top:calc(100% + var(--mrd-space-1));left:0;right:0;background-color:var(--mrd-color-white);border:var(--mrd-border-width) solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);box-shadow:var(--mrd-shadow-md);z-index:var(--mrd-z-dropdown);max-height:240px;overflow-y:auto}.mrd-relation-field__result-item.sc-mrd-relation-field{display:flex;flex-direction:column;padding:var(--mrd-space-2) var(--mrd-space-3);cursor:pointer;transition:background-color var(--mrd-transition-fast)}.mrd-relation-field__result-item.sc-mrd-relation-field:hover{background-color:var(--mrd-color-neutral-50)}.mrd-relation-field__result-item.sc-mrd-relation-field:not(:last-child){border-bottom:var(--mrd-border-width) solid var(--mrd-color-neutral-100)}.mrd-relation-field__result-item--highlighted.sc-mrd-relation-field{background-color:var(--mrd-color-primary-light)}.mrd-relation-field__result-label.sc-mrd-relation-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);color:var(--mrd-color-neutral-800);font-weight:var(--mrd-font-weight-medium)}.mrd-relation-field__result-desc.sc-mrd-relation-field{font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);margin-top:var(--mrd-space-1)}.mrd-relation-field__selected-value.sc-mrd-relation-field{display:flex;align-items:center;gap:var(--mrd-space-2);height:var(--mrd-input-height);padding:var(--mrd-input-padding-y) var(--mrd-input-padding-x);background-color:var(--mrd-color-primary-light);border:var(--mrd-border-width) solid var(--mrd-color-primary);border-radius:var(--mrd-border-radius);box-sizing:border-box}.mrd-relation-field__selected-value--error.sc-mrd-relation-field{border-color:var(--mrd-border-color-error);background-color:var(--mrd-color-danger-light)}.mrd-relation-field__selected-name.sc-mrd-relation-field{flex:1;font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-base);font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-primary-dark);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mrd-relation-field__selected-clear.sc-mrd-relation-field{flex-shrink:0;background:none;border:none;cursor:pointer;color:var(--mrd-color-primary-dark);font-size:var(--mrd-font-size-sm);padding:0;line-height:1;opacity:0.6;transition:opacity var(--mrd-transition-fast)}.mrd-relation-field__selected-clear.sc-mrd-relation-field:hover{opacity:1}.mrd-relation-field__no-results.sc-mrd-relation-field{padding:var(--mrd-space-4);font-family:var(--mrd-font-family);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-500);text-align:center}@keyframes mrd-spin{to{transform:rotate(360deg)}}`;
|
|
6765
|
+
|
|
6766
|
+
const MrdRelationField = class {
|
|
6767
|
+
constructor(hostRef) {
|
|
6768
|
+
registerInstance(this, hostRef);
|
|
6769
|
+
this.mrdChange = createEvent(this, "mrdChange");
|
|
6770
|
+
this.mrdBlur = createEvent(this, "mrdBlur");
|
|
6771
|
+
this.mrdSearch = createEvent(this, "mrdSearch");
|
|
6772
|
+
this.mrdFetchAll = createEvent(this, "mrdFetchAll");
|
|
6773
|
+
this.name = '';
|
|
6774
|
+
this.label = '';
|
|
6775
|
+
this.required = false;
|
|
6776
|
+
this.disabled = false;
|
|
6777
|
+
this.locale = navigator.language;
|
|
6778
|
+
this.relatedClass = '';
|
|
6779
|
+
/** When set, used instead of relatedClass for search queries (mostSignificantClass from API). */
|
|
6780
|
+
this.mostSignificantClass = '';
|
|
6781
|
+
this.displayType = ClientLayoutItemRelationDisplayType.SEARCH;
|
|
6782
|
+
this.multiple = false;
|
|
6783
|
+
this.dropdownValues = [];
|
|
6784
|
+
/** Plain href string/array for normal use; pass { id, label } objects to pre-fill a loaded record. */
|
|
6785
|
+
this.value = null;
|
|
6786
|
+
this.searchQuery = '';
|
|
6787
|
+
this.searchResults = [];
|
|
6788
|
+
this.allRecords = [];
|
|
6789
|
+
this.isLoading = false;
|
|
6790
|
+
this.selectedItems = [];
|
|
6791
|
+
this.showResults = false;
|
|
6792
|
+
this.error = '';
|
|
6793
|
+
this.highlightedIndex = -1;
|
|
6794
|
+
this.searchDebounce = null;
|
|
6795
|
+
this.handleKeyDown = (e) => {
|
|
6796
|
+
if (!this.showResults || this.searchResults.length === 0) {
|
|
6797
|
+
if (e.key === 'Escape') {
|
|
6798
|
+
this.showResults = false;
|
|
6799
|
+
this.highlightedIndex = -1;
|
|
6800
|
+
}
|
|
6801
|
+
return;
|
|
6802
|
+
}
|
|
6803
|
+
if (e.key === 'ArrowDown') {
|
|
6804
|
+
e.preventDefault();
|
|
6805
|
+
this.highlightedIndex = Math.min(this.highlightedIndex + 1, this.searchResults.length - 1);
|
|
6806
|
+
}
|
|
6807
|
+
else if (e.key === 'ArrowUp') {
|
|
6808
|
+
e.preventDefault();
|
|
6809
|
+
this.highlightedIndex = Math.max(this.highlightedIndex - 1, 0);
|
|
6810
|
+
}
|
|
5971
6811
|
else if (e.key === 'Enter') {
|
|
5972
6812
|
e.preventDefault();
|
|
5973
6813
|
if (this.highlightedIndex >= 0) {
|
|
@@ -6211,189 +7051,12 @@ const MrdSecretField = class {
|
|
|
6211
7051
|
};
|
|
6212
7052
|
MrdSecretField.style = mrdSecretFieldCss();
|
|
6213
7053
|
|
|
6214
|
-
/**
|
|
6215
|
-
* Pure sort/filter/aggregation query logic for mrd-table.
|
|
6216
|
-
* No component state — everything is passed in.
|
|
6217
|
-
*/
|
|
6218
|
-
const TEXT_TYPES = new Set(['TEXT', 'TEXTBLOCK', 'EMAIL', 'HYPERLINK']);
|
|
6219
|
-
const NUMERIC_TYPES = new Set(['INTEGER', 'DECIMAL', 'PERCENTAGE', 'CURRENCY']);
|
|
6220
|
-
const DATE_TYPES = new Set(['DATE', 'DATETIME', 'TIME']);
|
|
6221
|
-
const NO_FILTER_TYPES = new Set(['FILE', 'IMAGE']);
|
|
6222
|
-
/** Column types that cannot be sorted or filtered (not stored in PostgreSQL). */
|
|
6223
|
-
const NON_INTERACTIVE_TYPES = new Set(['LONGTEXT', 'JSON', 'FILE', 'IMAGE']);
|
|
6224
|
-
function parseDefaultSort(defaultSort) {
|
|
6225
|
-
var _a;
|
|
6226
|
-
if (!defaultSort)
|
|
6227
|
-
return { field: '', dir: 'asc' };
|
|
6228
|
-
const parts = defaultSort.split(',');
|
|
6229
|
-
return { field: parts[0].trim(), dir: ((_a = parts[1]) === null || _a === void 0 ? void 0 : _a.trim()) === 'desc' ? 'desc' : 'asc' };
|
|
6230
|
-
}
|
|
6231
|
-
/** Raw sort query-param value, e.g. "name" or "name,desc". */
|
|
6232
|
-
function buildSortParam(field, dir) {
|
|
6233
|
-
if (!field)
|
|
6234
|
-
return '';
|
|
6235
|
-
return dir === 'desc' ? `${field},desc` : field;
|
|
6236
|
-
}
|
|
6237
|
-
/** Query params for a page request: page + sort + filterClass + view filters + active column filters. */
|
|
6238
|
-
function buildTableQueryParams(opts) {
|
|
6239
|
-
var _a, _b;
|
|
6240
|
-
const p = new URLSearchParams();
|
|
6241
|
-
if (opts.page > 0)
|
|
6242
|
-
p.set('page', String(opts.page));
|
|
6243
|
-
if (opts.sort)
|
|
6244
|
-
p.set('sort', opts.sort);
|
|
6245
|
-
if (opts.filterClass)
|
|
6246
|
-
p.set('type', opts.filterClass);
|
|
6247
|
-
applyViewFilters(p, opts.viewFilters);
|
|
6248
|
-
for (const f of opts.activeFilters) {
|
|
6249
|
-
if (f.operator === 'isEmpty') {
|
|
6250
|
-
p.set(f.field, '');
|
|
6251
|
-
continue;
|
|
6252
|
-
}
|
|
6253
|
-
if (f.operator === 'isNotEmpty') {
|
|
6254
|
-
p.set(f.field + '_notempty', 'true');
|
|
6255
|
-
continue;
|
|
6256
|
-
}
|
|
6257
|
-
if (f.operator === 'startsWith') {
|
|
6258
|
-
p.set(f.field + '_startswith', String((_a = f.value) !== null && _a !== void 0 ? _a : ''));
|
|
6259
|
-
continue;
|
|
6260
|
-
}
|
|
6261
|
-
if ((_b = f.values) === null || _b === void 0 ? void 0 : _b.length) {
|
|
6262
|
-
p.set(f.field, f.values.join(','));
|
|
6263
|
-
continue;
|
|
6264
|
-
}
|
|
6265
|
-
if (f.value != null)
|
|
6266
|
-
p.set(f.field, String(f.value));
|
|
6267
|
-
if (f.from != null)
|
|
6268
|
-
p.set(f.field + '_from', String(f.from));
|
|
6269
|
-
if (f.to != null)
|
|
6270
|
-
p.set(f.field + '_to', String(f.to));
|
|
6271
|
-
}
|
|
6272
|
-
return p.toString();
|
|
6273
|
-
}
|
|
6274
|
-
/** Groups aggregate columns by function; null when the view has no aggregates. */
|
|
6275
|
-
function buildAggregationParams(columns) {
|
|
6276
|
-
var _a;
|
|
6277
|
-
const groups = { sum: [], avg: [], count: [] };
|
|
6278
|
-
for (const col of columns) {
|
|
6279
|
-
if (col.type !== 'FIELD' || !col.aggregate)
|
|
6280
|
-
continue;
|
|
6281
|
-
const fn = col.aggregate.toLowerCase();
|
|
6282
|
-
if (fn in groups)
|
|
6283
|
-
groups[fn].push((_a = col.name) !== null && _a !== void 0 ? _a : '');
|
|
6284
|
-
}
|
|
6285
|
-
const params = {};
|
|
6286
|
-
if (groups.sum.length)
|
|
6287
|
-
params.sum = groups.sum;
|
|
6288
|
-
if (groups.avg.length)
|
|
6289
|
-
params.avg = groups.avg;
|
|
6290
|
-
if (groups.count.length)
|
|
6291
|
-
params.count = groups.count;
|
|
6292
|
-
return Object.keys(params).length > 0 ? params : null;
|
|
6293
|
-
}
|
|
6294
|
-
/** Aggregation query string: the page-0 query params without page/sort, plus sum/avg/count. */
|
|
6295
|
-
function buildAggregationQs(basePageQs, columns) {
|
|
6296
|
-
var _a, _b, _c;
|
|
6297
|
-
const p = new URLSearchParams(basePageQs);
|
|
6298
|
-
p.delete('page');
|
|
6299
|
-
p.delete('sort');
|
|
6300
|
-
const groups = buildAggregationParams(columns);
|
|
6301
|
-
if ((_a = groups === null || groups === void 0 ? void 0 : groups.sum) === null || _a === void 0 ? void 0 : _a.length)
|
|
6302
|
-
p.set('sum', groups.sum.join(','));
|
|
6303
|
-
if ((_b = groups === null || groups === void 0 ? void 0 : groups.avg) === null || _b === void 0 ? void 0 : _b.length)
|
|
6304
|
-
p.set('avg', groups.avg.join(','));
|
|
6305
|
-
if ((_c = groups === null || groups === void 0 ? void 0 : groups.count) === null || _c === void 0 ? void 0 : _c.length)
|
|
6306
|
-
p.set('count', groups.count.join(','));
|
|
6307
|
-
return p.toString();
|
|
6308
|
-
}
|
|
6309
|
-
/** True when the pending filter actually constrains anything. */
|
|
6310
|
-
function filterHasValue(f) {
|
|
6311
|
-
if (f.operator === 'isEmpty' || f.operator === 'isNotEmpty')
|
|
6312
|
-
return true;
|
|
6313
|
-
if (f.values !== undefined && f.values.length > 0)
|
|
6314
|
-
return true;
|
|
6315
|
-
if (f.value != null && f.value !== '')
|
|
6316
|
-
return true;
|
|
6317
|
-
if (typeof f.value === 'boolean')
|
|
6318
|
-
return true;
|
|
6319
|
-
if (f.from != null && f.from !== '')
|
|
6320
|
-
return true;
|
|
6321
|
-
if (f.to != null && f.to !== '')
|
|
6322
|
-
return true;
|
|
6323
|
-
return false;
|
|
6324
|
-
}
|
|
6325
|
-
// ── DATETIME filters: the user edits local "YYYY-MM-DD" dates, the API stores UTC ISO ──
|
|
6326
|
-
/** UTC ISO string at the start (midnight) of the given local day. */
|
|
6327
|
-
function dateLocalToUTCStart(dateStr) {
|
|
6328
|
-
if (!dateStr)
|
|
6329
|
-
return dateStr;
|
|
6330
|
-
const [year, month, day] = dateStr.split('-').map(Number);
|
|
6331
|
-
return new Date(year, month - 1, day).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
6332
|
-
}
|
|
6333
|
-
/** Start of the day AFTER the given local date (exclusive range end). */
|
|
6334
|
-
function dateLocalToUTCEndExclusive(dateStr) {
|
|
6335
|
-
if (!dateStr)
|
|
6336
|
-
return dateStr;
|
|
6337
|
-
const [year, month, day] = dateStr.split('-').map(Number);
|
|
6338
|
-
return new Date(year, month - 1, day + 1).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
6339
|
-
}
|
|
6340
|
-
/** Stored UTC ISO string back to the local "YYYY-MM-DD" date. */
|
|
6341
|
-
function utcISOToLocalDate(utcStr) {
|
|
6342
|
-
if (!utcStr)
|
|
6343
|
-
return utcStr;
|
|
6344
|
-
const d = new Date(utcStr);
|
|
6345
|
-
if (isNaN(d.getTime()))
|
|
6346
|
-
return utcStr;
|
|
6347
|
-
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
6348
|
-
}
|
|
6349
|
-
/** The stored "to" is the exclusive end (next midnight); subtract a day to recover the entered date. */
|
|
6350
|
-
function utcISOToLocalDateExclusiveEnd(utcStr) {
|
|
6351
|
-
if (!utcStr)
|
|
6352
|
-
return utcStr;
|
|
6353
|
-
const d = new Date(utcStr);
|
|
6354
|
-
if (isNaN(d.getTime()))
|
|
6355
|
-
return utcStr;
|
|
6356
|
-
d.setDate(d.getDate() - 1);
|
|
6357
|
-
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
6358
|
-
}
|
|
6359
|
-
/** Applies the local→UTC conversion when a DATETIME filter is submitted.
|
|
6360
|
-
* Exact date → range covering the full local day. */
|
|
6361
|
-
function normalizeDatetimeFilter(f) {
|
|
6362
|
-
const normalized = Object.assign({}, f);
|
|
6363
|
-
if (f.dataType === 'DATETIME' && f.operator !== 'isEmpty' && f.operator !== 'isNotEmpty') {
|
|
6364
|
-
if (typeof normalized.value === 'string' && normalized.value) {
|
|
6365
|
-
normalized.from = dateLocalToUTCStart(normalized.value);
|
|
6366
|
-
normalized.to = dateLocalToUTCEndExclusive(normalized.value);
|
|
6367
|
-
normalized.value = undefined;
|
|
6368
|
-
}
|
|
6369
|
-
else {
|
|
6370
|
-
if (typeof normalized.from === 'string' && normalized.from)
|
|
6371
|
-
normalized.from = dateLocalToUTCStart(normalized.from);
|
|
6372
|
-
if (typeof normalized.to === 'string' && normalized.to)
|
|
6373
|
-
normalized.to = dateLocalToUTCEndExclusive(normalized.to);
|
|
6374
|
-
}
|
|
6375
|
-
}
|
|
6376
|
-
return normalized;
|
|
6377
|
-
}
|
|
6378
|
-
/** Converts a stored DATETIME filter back to local dates for the popup.
|
|
6379
|
-
* A range covering a single local day is restored to exact-date mode. */
|
|
6380
|
-
function datetimeFilterToDisplay(existing) {
|
|
6381
|
-
const display = Object.assign({}, existing);
|
|
6382
|
-
if (typeof display.from === 'string' && display.from)
|
|
6383
|
-
display.from = utcISOToLocalDate(display.from);
|
|
6384
|
-
if (typeof display.to === 'string' && display.to)
|
|
6385
|
-
display.to = utcISOToLocalDateExclusiveEnd(display.to);
|
|
6386
|
-
if (display.from && display.to && display.from === display.to) {
|
|
6387
|
-
return Object.assign(Object.assign({}, display), { value: display.from, from: undefined, to: undefined });
|
|
6388
|
-
}
|
|
6389
|
-
return display;
|
|
6390
|
-
}
|
|
6391
|
-
|
|
6392
7054
|
/**
|
|
6393
7055
|
* Stateless render parts of mrd-table. All state and handlers stay in the
|
|
6394
7056
|
* component; these components receive plain values and callbacks.
|
|
6395
7057
|
*/
|
|
6396
7058
|
const FilterIcon = () => (h("span", { class: "mrd-table__filter-icon", "aria-hidden": "true" }, h("svg", { viewBox: "0 0 24 24", width: "14", height: "14", fill: "currentColor" }, h("path", { d: "M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" }))));
|
|
7059
|
+
const SearchIcon = ({ class: cls }) => (h("svg", { class: cls, viewBox: "0 0 24 24", width: "16", height: "16", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M15.5 14h-.79l-.28-.27a6.5 6.5 0 1 0-.7.7l.27.28v.79l5 4.99L20.49 19zM9.5 14A4.5 4.5 0 1 1 14 9.5 4.5 4.5 0 0 1 9.5 14" })));
|
|
6397
7060
|
const TEXTBLOCK_MAX = 200;
|
|
6398
7061
|
const TableCell = ({ col, row, locale, onDownload, onOpenTextblock, onOpenJson }) => {
|
|
6399
7062
|
var _a, _b, _c;
|
|
@@ -6473,11 +7136,14 @@ const JsonModal = ({ html, locale, onClose }) => {
|
|
|
6473
7136
|
return null;
|
|
6474
7137
|
return (h("div", { class: "mrd-table__modal-backdrop", onClick: onClose, role: "dialog", "aria-modal": "true" }, h("div", { class: "mrd-table__modal", onClick: (e) => e.stopPropagation() }, h("button", { class: "mrd-table__modal-close", onClick: onClose, "aria-label": t('close', locale) }, "\u2715"), h("pre", { class: "mrd-table__modal-json", innerHTML: html }))));
|
|
6475
7138
|
};
|
|
6476
|
-
const Toolbar = ({ locale, filterCount, actions, views, activeViewIdx, viewPopoverOpen, createPickerOpen, createTypes, readOnly, cb }) => {
|
|
7139
|
+
const Toolbar = ({ locale, filterCount, actions, views, activeViewIdx, viewPopoverOpen, createPickerOpen, createTypes, readOnly, searchEnabled, searchOpen, searchQuery, cb }) => {
|
|
6477
7140
|
var _a;
|
|
6478
7141
|
const hasActions = actions.length > 0;
|
|
6479
7142
|
const hasViewSwitcher = views.length > 1;
|
|
6480
|
-
return (h("div", { class: "mrd-table__toolbar" }, h("div", { class: "mrd-table__toolbar-left" },
|
|
7143
|
+
return (h("div", { class: "mrd-table__toolbar" }, h("div", { class: "mrd-table__toolbar-left" }, searchEnabled && (searchOpen ? (h("span", { class: "mrd-table__search-box" }, h(SearchIcon, null), h("input", { type: "text", class: "mrd-table__search-input", value: searchQuery !== null && searchQuery !== void 0 ? searchQuery : '', placeholder: t('search_placeholder', locale), ref: cb.onSearchInputRef, onInput: (e) => cb.onSearchInput(e.target.value), onKeyDown: (e) => {
|
|
7144
|
+
if (e.key === 'Escape')
|
|
7145
|
+
cb.onCloseSearch();
|
|
7146
|
+
} }), h("button", { type: "button", class: "mrd-table__search-clear", "aria-label": t('clear', locale), onClick: cb.onCloseSearch }, "\u2715"))) : (h("button", { type: "button", class: "mrd-table__action mrd-table__action--secondary mrd-table__search-toggle", onClick: cb.onToggleSearch }, h(SearchIcon, { class: "mrd-table__action-icon" }), h("span", { class: "mrd-table__action-tooltip" }, t('table_search', locale))))), filterCount > 0 && (h("button", { class: "mrd-table__action mrd-table__action--secondary mrd-table__filter-clear", onClick: cb.onClearAllFilters }, h("svg", { class: "mrd-table__action-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" })), h("span", { class: "mrd-table__filter-clear-label" }, t('table_filter_clear_all', locale), " (", filterCount, ")")))), hasViewSwitcher && (h("div", { class: "mrd-table__toolbar-center" }, h("div", { class: "mrd-table__view-switcher" }, h("button", { class: "mrd-table__view-arrow", "aria-label": "Previous view", onClick: () => cb.onViewSwitch((activeViewIdx - 1 + views.length) % views.length) }, "\u25C0"), h("div", { class: "mrd-table__view-title-wrap" }, h("button", { class: "mrd-table__view-title", onClick: (e) => cb.onToggleViewPopover(e) }, (_a = views[activeViewIdx]) === null || _a === void 0 ? void 0 : _a.label), viewPopoverOpen && (h("div", { class: "mrd-table__view-popover", onClick: (e) => e.stopPropagation() }, views.map((v, i) => (h("button", { key: String(i), class: `mrd-table__view-popover-item${i === activeViewIdx ? ' mrd-table__view-popover-item--active' : ''}`, onClick: () => {
|
|
6481
7147
|
if (i !== activeViewIdx)
|
|
6482
7148
|
cb.onViewSwitch(i);
|
|
6483
7149
|
cb.onCloseViewPopover();
|
|
@@ -6651,7 +7317,7 @@ function getStalePages(requestedAt, now, timeoutMs) {
|
|
|
6651
7317
|
return stale;
|
|
6652
7318
|
}
|
|
6653
7319
|
|
|
6654
|
-
const mrdTableCss = () => `.sc-mrd-table-h{display:block;width:100%}.mrd-table.sc-mrd-table{overflow-x:auto}.mrd-table__scroll.sc-mrd-table{overflow-y:auto;overflow-x:auto;border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);overflow-anchor:none}.mrd-table__table.sc-mrd-table{width:auto;min-width:100%;border-collapse:collapse;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-900)}.mrd-table__scroll.sc-mrd-table .mrd-table__table.sc-mrd-table{min-width:max-content}.mrd-table__header.sc-mrd-table{position:sticky;top:0;z-index:1;background:var(--mrd-color-white);text-align:left;padding:var(--mrd-space-2) var(--mrd-space-4);border-bottom:2px solid var(--mrd-border-color);color:var(--mrd-color-neutral-600);font-weight:var(--mrd-font-weight-medium);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:var(--mrd-font-size-xs);text-transform:uppercase;letter-spacing:0.04em}.mrd-table__header--sortable.sc-mrd-table{cursor:pointer;user-select:none}.mrd-table__header--sortable.sc-mrd-table:hover{background:var(--mrd-color-neutral-50);color:var(--mrd-color-neutral-800)}.mrd-table__header--sorted-asc.sc-mrd-table,.mrd-table__header--sorted-desc.sc-mrd-table{color:var(--mrd-color-primary);border-bottom-color:var(--mrd-color-primary)}.mrd-table__header--filtered.sc-mrd-table{color:var(--mrd-color-primary);border-bottom-color:var(--mrd-color-primary)}.mrd-table__header-label.sc-mrd-table{margin-right:var(--mrd-space-1)}.mrd-table__col-resizer.sc-mrd-table{position:absolute;top:0;right:0;width:9px;height:100%;cursor:col-resize;touch-action:none;user-select:none}.mrd-table__col-resizer.sc-mrd-table::after{content:"";position:absolute;top:25%;right:4px;width:1px;height:50%;background:var(--mrd-border-color)}.mrd-table__col-resizer.sc-mrd-table:hover::after{width:2px;right:3px;background:var(--mrd-color-primary)}.mrd-table__col-resizer--active.sc-mrd-table::after{width:2px;right:3px;height:100%;top:0;background:var(--mrd-color-primary)}.mrd-table--resizing.sc-mrd-table{cursor:col-resize;user-select:none}.mrd-table__sort-icon.sc-mrd-table{font-size:0.85rem;opacity:0.4;vertical-align:middle}.mrd-table__header--sorted-asc.sc-mrd-table .mrd-table__sort-icon.sc-mrd-table,.mrd-table__header--sorted-desc.sc-mrd-table .mrd-table__sort-icon.sc-mrd-table{opacity:1;color:var(--mrd-color-primary)}.mrd-table__filter-icon.sc-mrd-table{display:inline-flex;align-items:center;vertical-align:middle;margin-left:var(--mrd-space-1);color:var(--mrd-color-primary)}.mrd-table__row.sc-mrd-table{border-bottom:1px solid var(--mrd-border-color)}.mrd-table__row.sc-mrd-table:hover{background:var(--mrd-color-neutral-200) !important}.mrd-table__row--clickable.sc-mrd-table{cursor:pointer}.mrd-table__row--loading.sc-mrd-table{background:transparent}.mrd-table__row--failed.sc-mrd-table{background:transparent}.mrd-table__spacer.sc-mrd-table{border:none}.mrd-table__spacer.sc-mrd-table td.sc-mrd-table{padding:0;border:none}.mrd-table__cell.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-4);vertical-align:top;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mrd-table__cell--numeric.sc-mrd-table{text-align:right;font-variant-numeric:tabular-nums}.mrd-table__cell--placeholder.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-4);border-bottom:1px solid var(--mrd-border-color)}.mrd-table__cell--failed.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-4);border-bottom:1px solid var(--mrd-border-color)}.mrd-table__placeholder-bar.sc-mrd-table{display:block;height:0.75rem;width:55%;border-radius:var(--mrd-border-radius-sm);background:linear-gradient(90deg, var(--mrd-color-neutral-200) 25%, var(--mrd-color-neutral-100) 50%, var(--mrd-color-neutral-200) 75%);background-size:200% 100%;animation:mrd-shimmer 1.4s ease infinite}.mrd-table__retry-button.sc-mrd-table{border:none;background:none;padding:0;color:var(--mrd-color-danger);font-size:inherit;cursor:pointer;text-decoration:underline}.mrd-table__toolbar.sc-mrd-table{display:flex;align-items:center;justify-content:space-between;padding-bottom:var(--mrd-space-2)}.mrd-table__toolbar-left.sc-mrd-table,.mrd-table__toolbar-right.sc-mrd-table{display:flex;gap:var(--mrd-space-2);align-items:center}.mrd-table__toolbar-center.sc-mrd-table{flex:1;display:flex;justify-content:center;align-items:center;gap:var(--mrd-space-1)}.mrd-table__view-switcher.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1)}.mrd-table__view-arrow.sc-mrd-table{background:none;border:none;cursor:pointer;padding:0 var(--mrd-space-1);color:var(--mrd-color-neutral-500);font-size:var(--mrd-font-size-xs);line-height:1}.mrd-table__view-arrow.sc-mrd-table:hover{color:var(--mrd-color-neutral-800)}.mrd-table__view-title-wrap.sc-mrd-table{position:relative}.mrd-table__view-title.sc-mrd-table{font-size:var(--mrd-font-size-sm);font-weight:600;color:var(--mrd-color-neutral-800);font-family:var(--mrd-font-family);background:none;border:none;outline:none;cursor:pointer;padding:0 var(--mrd-space-1);max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mrd-table__view-title.sc-mrd-table:hover{color:var(--mrd-color-primary)}.mrd-table__view-popover.sc-mrd-table{position:absolute;top:calc(100% + var(--mrd-space-1));left:50%;transform:translateX(-50%);background:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-radius-md);box-shadow:var(--mrd-shadow-md);z-index:100;min-width:160px;padding:var(--mrd-space-1) 0}.mrd-table__view-popover-item.sc-mrd-table{display:block;width:100%;text-align:left;background:none;border:none;cursor:pointer;padding:var(--mrd-space-2) var(--mrd-space-3);font-size:var(--mrd-font-size-sm);font-family:var(--mrd-font-family);color:var(--mrd-color-neutral-700);white-space:nowrap}.mrd-table__view-popover-item.sc-mrd-table:hover{background:var(--mrd-color-neutral-50)}.mrd-table__view-popover-item--active.sc-mrd-table{font-weight:600;color:var(--mrd-color-primary)}.mrd-table__action.sc-mrd-table{position:relative;display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid transparent;border-radius:var(--mrd-border-radius);cursor:pointer;color:var(--mrd-color-neutral-400);transition:background-color 0.15s, border-color 0.15s, color 0.15s}.mrd-table__action.sc-mrd-table:hover{background-color:var(--mrd-color-neutral-100);border-color:var(--mrd-color-neutral-300);color:var(--mrd-color-neutral-700)}.mrd-table__action.sc-mrd-table:hover .mrd-table__action-tooltip.sc-mrd-table{display:block}.mrd-table__action.sc-mrd-table:disabled{opacity:0.4;cursor:not-allowed}.mrd-table__action--primary.sc-mrd-table{color:var(--mrd-color-neutral-500)}.mrd-table__action--primary.sc-mrd-table:hover{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__action--danger.sc-mrd-table{color:var(--mrd-color-error)}.mrd-table__action--danger.sc-mrd-table:hover{background-color:var(--mrd-color-error-light, #fef2f2);border-color:var(--mrd-color-error)}.mrd-table__action-icon.sc-mrd-table{width:1.25rem;height:1.25rem;pointer-events:none;fill:currentColor}.mrd-table__action-tooltip.sc-mrd-table{display:none;position:absolute;bottom:calc(100% + 6px);right:0;padding:var(--mrd-space-1) var(--mrd-space-2);font-size:var(--mrd-font-size-xs);white-space:nowrap;background:var(--mrd-color-tooltip, #fffce1);color:var(--mrd-color-neutral-900);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-sm, var(--mrd-border-radius));pointer-events:none;z-index:10}.mrd-table__create-picker-wrap.sc-mrd-table{position:relative}.mrd-table__create-picker.sc-mrd-table{position:absolute;right:0;top:calc(100% + 4px);background:var(--mrd-color-white, #fff);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);box-shadow:var(--mrd-shadow-md, 0 4px 12px rgba(0, 0, 0, 0.12));z-index:10;min-width:10rem;padding:var(--mrd-space-1) 0}.mrd-table__create-picker-item.sc-mrd-table{display:block;width:100%;text-align:left;padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:none;cursor:pointer;font-size:var(--mrd-font-size-sm);font-family:var(--mrd-font-family);color:var(--mrd-color-neutral-800)}.mrd-table__create-picker-item.sc-mrd-table:hover{background:var(--mrd-color-neutral-50);color:var(--mrd-color-neutral-900)}.mrd-table__filter-clear.sc-mrd-table{width:auto;gap:var(--mrd-space-1);padding:0 var(--mrd-space-2);color:var(--mrd-color-primary);border-color:var(--mrd-color-primary)}.mrd-table__filter-clear.sc-mrd-table:hover{color:var(--mrd-color-primary);border-color:var(--mrd-color-primary)}.mrd-table__filter-clear-label.sc-mrd-table{font-size:var(--mrd-font-size-sm);white-space:nowrap}.mrd-table__filter-popup.sc-mrd-table{position:fixed;width:280px;background:var(--mrd-color-white);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);box-shadow:var(--mrd-shadow-md, 0 4px 12px rgba(0, 0, 0, 0.12));z-index:var(--mrd-z-dropdown, 200);font-size:var(--mrd-font-size-sm)}.mrd-table__filter-popup-header.sc-mrd-table{display:flex;align-items:center;justify-content:space-between;padding:var(--mrd-space-2) var(--mrd-space-3);border-bottom:1px solid var(--mrd-border-color)}.mrd-table__filter-popup-title.sc-mrd-table{font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800);font-size:var(--mrd-font-size-sm)}.mrd-table__filter-close.sc-mrd-table{background:transparent;border:none;cursor:pointer;color:var(--mrd-color-neutral-500);font-size:0.9rem;padding:2px 4px;border-radius:3px;line-height:1}.mrd-table__filter-close.sc-mrd-table:hover{background:var(--mrd-color-neutral-100);color:var(--mrd-color-neutral-800)}.mrd-table__filter-section.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-3)}.mrd-table__filter-section-label.sc-mrd-table{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium);text-transform:uppercase;letter-spacing:0.04em;color:var(--mrd-color-neutral-500);margin-bottom:var(--mrd-space-2)}.mrd-table__filter-sort-buttons.sc-mrd-table{display:flex;gap:var(--mrd-space-2)}.mrd-table__filter-sort-btn.sc-mrd-table{flex:1;padding:var(--mrd-space-1) var(--mrd-space-2);background:transparent;border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);cursor:pointer;font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-700)}.mrd-table__filter-sort-btn.sc-mrd-table:hover{background:var(--mrd-color-neutral-100)}.mrd-table__filter-sort-btn--active.sc-mrd-table{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__filter-divider.sc-mrd-table{height:1px;background:var(--mrd-border-color);margin:0}.mrd-table__filter-editor.sc-mrd-table{display:flex;flex-direction:column;gap:var(--mrd-space-2)}.mrd-table__filter-select.sc-mrd-table,.mrd-table__filter-input.sc-mrd-table{width:100%;padding:var(--mrd-space-1) var(--mrd-space-2);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-900);background:var(--mrd-color-white);box-sizing:border-box}.mrd-table__filter-select.sc-mrd-table:focus,.mrd-table__filter-input.sc-mrd-table:focus{outline:none;border-color:var(--mrd-color-primary);box-shadow:0 0 0 2px rgba(0, 0, 0, 0.06)}.mrd-table__filter-range.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1)}.mrd-table__filter-range.sc-mrd-table .mrd-table__filter-input.sc-mrd-table{flex:1;min-width:0}.mrd-table__filter-range--stacked.sc-mrd-table{flex-direction:column;align-items:stretch;gap:var(--mrd-space-2)}.mrd-table__filter-range-sep.sc-mrd-table{color:var(--mrd-color-neutral-400);flex-shrink:0}.mrd-table__filter-range-label.sc-mrd-table{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);margin-bottom:2px}.mrd-table__filter-radio-group.sc-mrd-table{display:flex;flex-direction:column;gap:var(--mrd-space-1)}.mrd-table__filter-radio-group--inline.sc-mrd-table{flex-direction:row;gap:var(--mrd-space-3)}.mrd-table__filter-radio-label.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1);cursor:pointer;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-800)}.mrd-table__filter-list.sc-mrd-table{display:flex;flex-direction:column;gap:var(--mrd-space-1);max-height:180px;overflow-y:auto}.mrd-table__filter-list-controls.sc-mrd-table{display:flex;gap:var(--mrd-space-2);margin-bottom:var(--mrd-space-1)}.mrd-table__filter-list-btn.sc-mrd-table{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-primary);background:transparent;border:none;cursor:pointer;padding:0;text-decoration:underline}.mrd-table__filter-checkbox-label.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1);cursor:pointer;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-800)}.mrd-table__filter-no-support.sc-mrd-table{font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-500);margin:0;font-style:italic}.mrd-table__filter-popup-footer.sc-mrd-table{display:flex;justify-content:flex-end;gap:var(--mrd-space-2);padding:var(--mrd-space-2) var(--mrd-space-3);border-top:1px solid var(--mrd-border-color)}.mrd-table__filter-btn.sc-mrd-table{padding:var(--mrd-space-1) var(--mrd-space-3);border-radius:var(--mrd-border-radius);border:1px solid var(--mrd-border-color);font-size:var(--mrd-font-size-sm);cursor:pointer}.mrd-table__filter-btn--clear.sc-mrd-table{background:transparent;color:var(--mrd-color-neutral-600)}.mrd-table__filter-btn--clear.sc-mrd-table:hover{background:var(--mrd-color-neutral-100)}.mrd-table__filter-btn--apply.sc-mrd-table{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__filter-btn--apply.sc-mrd-table:hover{background:var(--mrd-color-primary-dark, var(--mrd-color-primary));border-color:var(--mrd-color-primary-dark, var(--mrd-color-primary))}.mrd-table__totals-row.sc-mrd-table{border-top:2px solid var(--mrd-border-color)}.mrd-table__totals-cell.sc-mrd-table{position:sticky;bottom:0;z-index:2;padding:var(--mrd-space-2) var(--mrd-space-4);background:var(--mrd-color-white);font-weight:var(--mrd-font-weight-medium);font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-top:2px solid var(--mrd-border-color)}.mrd-table__totals-cell--numeric.sc-mrd-table{text-align:right}.mrd-table__footer.sc-mrd-table{padding:var(--mrd-space-1) var(--mrd-space-2);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);text-align:right}.mrd-table__empty.sc-mrd-table{padding:var(--mrd-space-4) var(--mrd-space-3);color:var(--mrd-color-neutral-500);font-size:var(--mrd-font-size-sm);text-align:center;margin:0}.mrd-table__file-btn.sc-mrd-table{display:inline-flex;align-items:center;gap:var(--mrd-space-1);background:none;border:none;padding:0;cursor:pointer;color:var(--mrd-color-primary);font-size:var(--mrd-font-size-sm);font-family:inherit;max-width:100%;overflow:hidden}.mrd-table__file-btn.sc-mrd-table:hover{text-decoration:underline;color:var(--mrd-color-primary-dark)}.mrd-table__file-icon.sc-mrd-table{flex-shrink:0;width:1rem;height:1rem}.mrd-table__textblock-btn.sc-mrd-table{display:inline;background:none;border:none;padding:0 0 0 var(--mrd-space-1);cursor:pointer;color:var(--mrd-color-primary);font-size:var(--mrd-font-size-sm);font-family:inherit;line-height:inherit;vertical-align:middle}.mrd-table__textblock-btn.sc-mrd-table:hover{color:var(--mrd-color-primary-dark)}.mrd-table__modal-backdrop.sc-mrd-table{position:fixed;inset:0;background:rgba(0, 0, 0, 0.4);z-index:var(--mrd-z-modal, 300);display:flex;align-items:center;justify-content:center}.mrd-table__modal.sc-mrd-table{background:#fff;border-radius:var(--mrd-radius-md, 0.5rem);padding:var(--mrd-space-6);max-width:min(600px, 90vw);max-height:70vh;overflow-y:auto;position:relative;box-shadow:var(--mrd-shadow-lg)}.mrd-table__modal-close.sc-mrd-table{position:absolute;top:var(--mrd-space-3);right:var(--mrd-space-3);background:none;border:none;cursor:pointer;font-size:1.25rem;line-height:1;color:var(--mrd-color-text-muted, #6b7280);padding:0}.mrd-table__modal-close.sc-mrd-table:hover{color:var(--mrd-color-text, #111827)}.mrd-table__modal-text.sc-mrd-table{margin:0;padding-right:var(--mrd-space-6);white-space:pre-wrap;word-break:break-word;font-size:var(--mrd-font-size-sm);line-height:1.6}.mrd-table__json-preview.sc-mrd-table{font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:inline-block;max-width:calc(100% - 1.5rem);vertical-align:middle}.mrd-table__modal-json.sc-mrd-table{margin:0;padding-right:var(--mrd-space-6);font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);white-space:pre-wrap;word-break:break-word;line-height:1.6;background:none;border:none}@keyframes mrd-shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}`;
|
|
7320
|
+
const mrdTableCss = () => `.sc-mrd-table-h{display:block;width:100%}.mrd-table.sc-mrd-table{overflow-x:auto}.mrd-table__scroll.sc-mrd-table{overflow-y:auto;overflow-x:auto;border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);overflow-anchor:none}.mrd-table__table.sc-mrd-table{width:auto;min-width:100%;border-collapse:collapse;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-900)}.mrd-table__scroll.sc-mrd-table .mrd-table__table.sc-mrd-table{min-width:max-content}.mrd-table__header.sc-mrd-table{position:sticky;top:0;z-index:1;background:var(--mrd-color-white);text-align:left;padding:var(--mrd-space-2) var(--mrd-space-4);border-bottom:2px solid var(--mrd-border-color);color:var(--mrd-color-neutral-600);font-weight:var(--mrd-font-weight-medium);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:var(--mrd-font-size-xs);text-transform:uppercase;letter-spacing:0.04em}.mrd-table__header--sortable.sc-mrd-table{cursor:pointer;user-select:none}.mrd-table__header--sortable.sc-mrd-table:hover{background:var(--mrd-color-neutral-50);color:var(--mrd-color-neutral-800)}.mrd-table__header--sorted-asc.sc-mrd-table,.mrd-table__header--sorted-desc.sc-mrd-table{color:var(--mrd-color-primary);border-bottom-color:var(--mrd-color-primary)}.mrd-table__header--filtered.sc-mrd-table{color:var(--mrd-color-primary);border-bottom-color:var(--mrd-color-primary)}.mrd-table__header-label.sc-mrd-table{margin-right:var(--mrd-space-1)}.mrd-table__col-resizer.sc-mrd-table{position:absolute;top:0;right:0;width:9px;height:100%;cursor:col-resize;touch-action:none;user-select:none}.mrd-table__col-resizer.sc-mrd-table::after{content:"";position:absolute;top:25%;right:4px;width:1px;height:50%;background:var(--mrd-border-color)}.mrd-table__col-resizer.sc-mrd-table:hover::after{width:2px;right:3px;background:var(--mrd-color-primary)}.mrd-table__col-resizer--active.sc-mrd-table::after{width:2px;right:3px;height:100%;top:0;background:var(--mrd-color-primary)}.mrd-table--resizing.sc-mrd-table{cursor:col-resize;user-select:none}.mrd-table__sort-icon.sc-mrd-table{font-size:0.85rem;opacity:0.4;vertical-align:middle}.mrd-table__header--sorted-asc.sc-mrd-table .mrd-table__sort-icon.sc-mrd-table,.mrd-table__header--sorted-desc.sc-mrd-table .mrd-table__sort-icon.sc-mrd-table{opacity:1;color:var(--mrd-color-primary)}.mrd-table__filter-icon.sc-mrd-table{display:inline-flex;align-items:center;vertical-align:middle;margin-left:var(--mrd-space-1);color:var(--mrd-color-primary)}.mrd-table__row.sc-mrd-table{border-bottom:1px solid var(--mrd-border-color)}.mrd-table__row.sc-mrd-table:hover{background:var(--mrd-color-neutral-200) !important}.mrd-table__row--clickable.sc-mrd-table{cursor:pointer}.mrd-table__row--loading.sc-mrd-table{background:transparent}.mrd-table__row--failed.sc-mrd-table{background:transparent}.mrd-table__spacer.sc-mrd-table{border:none}.mrd-table__spacer.sc-mrd-table td.sc-mrd-table{padding:0;border:none}.mrd-table__cell.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-4);vertical-align:top;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mrd-table__cell--numeric.sc-mrd-table{text-align:right;font-variant-numeric:tabular-nums}.mrd-table__cell--placeholder.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-4);border-bottom:1px solid var(--mrd-border-color)}.mrd-table__cell--failed.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-4);border-bottom:1px solid var(--mrd-border-color)}.mrd-table__placeholder-bar.sc-mrd-table{display:block;height:0.75rem;width:55%;border-radius:var(--mrd-border-radius-sm);background:linear-gradient(90deg, var(--mrd-color-neutral-200) 25%, var(--mrd-color-neutral-100) 50%, var(--mrd-color-neutral-200) 75%);background-size:200% 100%;animation:mrd-shimmer 1.4s ease infinite}.mrd-table__retry-button.sc-mrd-table{border:none;background:none;padding:0;color:var(--mrd-color-danger);font-size:inherit;cursor:pointer;text-decoration:underline}.mrd-table__toolbar.sc-mrd-table{display:flex;align-items:center;justify-content:space-between;padding-bottom:var(--mrd-space-2)}.mrd-table__toolbar-left.sc-mrd-table,.mrd-table__toolbar-right.sc-mrd-table{display:flex;gap:var(--mrd-space-2);align-items:center}.mrd-table__toolbar-center.sc-mrd-table{flex:1;display:flex;justify-content:center;align-items:center;gap:var(--mrd-space-1)}.mrd-table__view-switcher.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1)}.mrd-table__view-arrow.sc-mrd-table{background:none;border:none;cursor:pointer;padding:0 var(--mrd-space-1);color:var(--mrd-color-neutral-500);font-size:var(--mrd-font-size-xs);line-height:1}.mrd-table__view-arrow.sc-mrd-table:hover{color:var(--mrd-color-neutral-800)}.mrd-table__view-title-wrap.sc-mrd-table{position:relative}.mrd-table__view-title.sc-mrd-table{font-size:var(--mrd-font-size-sm);font-weight:600;color:var(--mrd-color-neutral-800);font-family:var(--mrd-font-family);background:none;border:none;outline:none;cursor:pointer;padding:0 var(--mrd-space-1);max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mrd-table__view-title.sc-mrd-table:hover{color:var(--mrd-color-primary)}.mrd-table__view-popover.sc-mrd-table{position:absolute;top:calc(100% + var(--mrd-space-1));left:50%;transform:translateX(-50%);background:var(--mrd-color-white);border:1px solid var(--mrd-color-neutral-200);border-radius:var(--mrd-radius-md);box-shadow:var(--mrd-shadow-md);z-index:100;min-width:160px;padding:var(--mrd-space-1) 0}.mrd-table__view-popover-item.sc-mrd-table{display:block;width:100%;text-align:left;background:none;border:none;cursor:pointer;padding:var(--mrd-space-2) var(--mrd-space-3);font-size:var(--mrd-font-size-sm);font-family:var(--mrd-font-family);color:var(--mrd-color-neutral-700);white-space:nowrap}.mrd-table__view-popover-item.sc-mrd-table:hover{background:var(--mrd-color-neutral-50)}.mrd-table__view-popover-item--active.sc-mrd-table{font-weight:600;color:var(--mrd-color-primary)}.mrd-table__action.sc-mrd-table{position:relative;display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;background:transparent;border:1px solid transparent;border-radius:var(--mrd-border-radius);cursor:pointer;color:var(--mrd-color-neutral-400);transition:background-color 0.15s, border-color 0.15s, color 0.15s}.mrd-table__action.sc-mrd-table:hover{background-color:var(--mrd-color-neutral-100);border-color:var(--mrd-color-neutral-300);color:var(--mrd-color-neutral-700)}.mrd-table__action.sc-mrd-table:hover .mrd-table__action-tooltip.sc-mrd-table{display:block}.mrd-table__action.sc-mrd-table:disabled{opacity:0.4;cursor:not-allowed}.mrd-table__action--primary.sc-mrd-table{color:var(--mrd-color-neutral-500)}.mrd-table__action--primary.sc-mrd-table:hover{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__action--danger.sc-mrd-table{color:var(--mrd-color-error)}.mrd-table__action--danger.sc-mrd-table:hover{background-color:var(--mrd-color-error-light, #fef2f2);border-color:var(--mrd-color-error)}.mrd-table__action-icon.sc-mrd-table{width:1.25rem;height:1.25rem;pointer-events:none;fill:currentColor}.mrd-table__action-tooltip.sc-mrd-table{display:none;position:absolute;bottom:calc(100% + 6px);right:0;padding:var(--mrd-space-1) var(--mrd-space-2);font-size:var(--mrd-font-size-xs);white-space:nowrap;background:var(--mrd-color-tooltip, #fffce1);color:var(--mrd-color-neutral-900);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius-sm, var(--mrd-border-radius));pointer-events:none;z-index:10}.mrd-table__search-box.sc-mrd-table{display:inline-flex;align-items:center;gap:var(--mrd-space-1);height:2rem;padding:0 var(--mrd-space-2);border:1px solid var(--mrd-border-color-focus, var(--mrd-color-primary));border-radius:var(--mrd-border-radius);background:var(--mrd-color-white, #fff);box-shadow:var(--mrd-shadow-focus, none);color:var(--mrd-color-neutral-400)}.mrd-table__search-input.sc-mrd-table{border:none;outline:none;background:transparent;font-size:var(--mrd-font-size-sm);font-family:var(--mrd-font-family);color:var(--mrd-color-neutral-800);width:12rem}.mrd-table__search-clear.sc-mrd-table{display:inline-flex;align-items:center;justify-content:center;background:none;border:none;padding:0;cursor:pointer;color:var(--mrd-color-neutral-400);font-size:var(--mrd-font-size-xs);line-height:1}.mrd-table__search-clear.sc-mrd-table:hover{color:var(--mrd-color-neutral-700)}.mrd-table__create-picker-wrap.sc-mrd-table{position:relative}.mrd-table__create-picker.sc-mrd-table{position:absolute;right:0;top:calc(100% + 4px);background:var(--mrd-color-white, #fff);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);box-shadow:var(--mrd-shadow-md, 0 4px 12px rgba(0, 0, 0, 0.12));z-index:10;min-width:10rem;padding:var(--mrd-space-1) 0}.mrd-table__create-picker-item.sc-mrd-table{display:block;width:100%;text-align:left;padding:var(--mrd-space-2) var(--mrd-space-3);background:none;border:none;cursor:pointer;font-size:var(--mrd-font-size-sm);font-family:var(--mrd-font-family);color:var(--mrd-color-neutral-800)}.mrd-table__create-picker-item.sc-mrd-table:hover{background:var(--mrd-color-neutral-50);color:var(--mrd-color-neutral-900)}.mrd-table__filter-clear.sc-mrd-table{width:auto;gap:var(--mrd-space-1);padding:0 var(--mrd-space-2);color:var(--mrd-color-primary);border-color:var(--mrd-color-primary)}.mrd-table__filter-clear.sc-mrd-table:hover{color:var(--mrd-color-primary);border-color:var(--mrd-color-primary)}.mrd-table__filter-clear-label.sc-mrd-table{font-size:var(--mrd-font-size-sm);white-space:nowrap}.mrd-table__filter-popup.sc-mrd-table{position:fixed;width:280px;background:var(--mrd-color-white);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);box-shadow:var(--mrd-shadow-md, 0 4px 12px rgba(0, 0, 0, 0.12));z-index:var(--mrd-z-dropdown, 200);font-size:var(--mrd-font-size-sm)}.mrd-table__filter-popup-header.sc-mrd-table{display:flex;align-items:center;justify-content:space-between;padding:var(--mrd-space-2) var(--mrd-space-3);border-bottom:1px solid var(--mrd-border-color)}.mrd-table__filter-popup-title.sc-mrd-table{font-weight:var(--mrd-font-weight-medium);color:var(--mrd-color-neutral-800);font-size:var(--mrd-font-size-sm)}.mrd-table__filter-close.sc-mrd-table{background:transparent;border:none;cursor:pointer;color:var(--mrd-color-neutral-500);font-size:0.9rem;padding:2px 4px;border-radius:3px;line-height:1}.mrd-table__filter-close.sc-mrd-table:hover{background:var(--mrd-color-neutral-100);color:var(--mrd-color-neutral-800)}.mrd-table__filter-section.sc-mrd-table{padding:var(--mrd-space-2) var(--mrd-space-3)}.mrd-table__filter-section-label.sc-mrd-table{font-size:var(--mrd-font-size-xs);font-weight:var(--mrd-font-weight-medium);text-transform:uppercase;letter-spacing:0.04em;color:var(--mrd-color-neutral-500);margin-bottom:var(--mrd-space-2)}.mrd-table__filter-sort-buttons.sc-mrd-table{display:flex;gap:var(--mrd-space-2)}.mrd-table__filter-sort-btn.sc-mrd-table{flex:1;padding:var(--mrd-space-1) var(--mrd-space-2);background:transparent;border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);cursor:pointer;font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-700)}.mrd-table__filter-sort-btn.sc-mrd-table:hover{background:var(--mrd-color-neutral-100)}.mrd-table__filter-sort-btn--active.sc-mrd-table{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__filter-divider.sc-mrd-table{height:1px;background:var(--mrd-border-color);margin:0}.mrd-table__filter-editor.sc-mrd-table{display:flex;flex-direction:column;gap:var(--mrd-space-2)}.mrd-table__filter-select.sc-mrd-table,.mrd-table__filter-input.sc-mrd-table{width:100%;padding:var(--mrd-space-1) var(--mrd-space-2);border:1px solid var(--mrd-border-color);border-radius:var(--mrd-border-radius);font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-900);background:var(--mrd-color-white);box-sizing:border-box}.mrd-table__filter-select.sc-mrd-table:focus,.mrd-table__filter-input.sc-mrd-table:focus{outline:none;border-color:var(--mrd-color-primary);box-shadow:0 0 0 2px rgba(0, 0, 0, 0.06)}.mrd-table__filter-range.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1)}.mrd-table__filter-range.sc-mrd-table .mrd-table__filter-input.sc-mrd-table{flex:1;min-width:0}.mrd-table__filter-range--stacked.sc-mrd-table{flex-direction:column;align-items:stretch;gap:var(--mrd-space-2)}.mrd-table__filter-range-sep.sc-mrd-table{color:var(--mrd-color-neutral-400);flex-shrink:0}.mrd-table__filter-range-label.sc-mrd-table{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);margin-bottom:2px}.mrd-table__filter-radio-group.sc-mrd-table{display:flex;flex-direction:column;gap:var(--mrd-space-1)}.mrd-table__filter-radio-group--inline.sc-mrd-table{flex-direction:row;gap:var(--mrd-space-3)}.mrd-table__filter-radio-label.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1);cursor:pointer;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-800)}.mrd-table__filter-list.sc-mrd-table{display:flex;flex-direction:column;gap:var(--mrd-space-1);max-height:180px;overflow-y:auto}.mrd-table__filter-list-controls.sc-mrd-table{display:flex;gap:var(--mrd-space-2);margin-bottom:var(--mrd-space-1)}.mrd-table__filter-list-btn.sc-mrd-table{font-size:var(--mrd-font-size-xs);color:var(--mrd-color-primary);background:transparent;border:none;cursor:pointer;padding:0;text-decoration:underline}.mrd-table__filter-checkbox-label.sc-mrd-table{display:flex;align-items:center;gap:var(--mrd-space-1);cursor:pointer;font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-800)}.mrd-table__filter-no-support.sc-mrd-table{font-size:var(--mrd-font-size-sm);color:var(--mrd-color-neutral-500);margin:0;font-style:italic}.mrd-table__filter-popup-footer.sc-mrd-table{display:flex;justify-content:flex-end;gap:var(--mrd-space-2);padding:var(--mrd-space-2) var(--mrd-space-3);border-top:1px solid var(--mrd-border-color)}.mrd-table__filter-btn.sc-mrd-table{padding:var(--mrd-space-1) var(--mrd-space-3);border-radius:var(--mrd-border-radius);border:1px solid var(--mrd-border-color);font-size:var(--mrd-font-size-sm);cursor:pointer}.mrd-table__filter-btn--clear.sc-mrd-table{background:transparent;color:var(--mrd-color-neutral-600)}.mrd-table__filter-btn--clear.sc-mrd-table:hover{background:var(--mrd-color-neutral-100)}.mrd-table__filter-btn--apply.sc-mrd-table{background:var(--mrd-color-primary);border-color:var(--mrd-color-primary);color:var(--mrd-color-white)}.mrd-table__filter-btn--apply.sc-mrd-table:hover{background:var(--mrd-color-primary-dark, var(--mrd-color-primary));border-color:var(--mrd-color-primary-dark, var(--mrd-color-primary))}.mrd-table__totals-row.sc-mrd-table{border-top:2px solid var(--mrd-border-color)}.mrd-table__totals-cell.sc-mrd-table{position:sticky;bottom:0;z-index:2;padding:var(--mrd-space-2) var(--mrd-space-4);background:var(--mrd-color-white);font-weight:var(--mrd-font-weight-medium);font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-top:2px solid var(--mrd-border-color)}.mrd-table__totals-cell--numeric.sc-mrd-table{text-align:right}.mrd-table__footer.sc-mrd-table{padding:var(--mrd-space-1) var(--mrd-space-2);font-size:var(--mrd-font-size-xs);color:var(--mrd-color-neutral-500);text-align:right}.mrd-table__empty.sc-mrd-table{padding:var(--mrd-space-4) var(--mrd-space-3);color:var(--mrd-color-neutral-500);font-size:var(--mrd-font-size-sm);text-align:center;margin:0}.mrd-table__file-btn.sc-mrd-table{display:inline-flex;align-items:center;gap:var(--mrd-space-1);background:none;border:none;padding:0;cursor:pointer;color:var(--mrd-color-primary);font-size:var(--mrd-font-size-sm);font-family:inherit;max-width:100%;overflow:hidden}.mrd-table__file-btn.sc-mrd-table:hover{text-decoration:underline;color:var(--mrd-color-primary-dark)}.mrd-table__file-icon.sc-mrd-table{flex-shrink:0;width:1rem;height:1rem}.mrd-table__textblock-btn.sc-mrd-table{display:inline;background:none;border:none;padding:0 0 0 var(--mrd-space-1);cursor:pointer;color:var(--mrd-color-primary);font-size:var(--mrd-font-size-sm);font-family:inherit;line-height:inherit;vertical-align:middle}.mrd-table__textblock-btn.sc-mrd-table:hover{color:var(--mrd-color-primary-dark)}.mrd-table__modal-backdrop.sc-mrd-table{position:fixed;inset:0;background:rgba(0, 0, 0, 0.4);z-index:var(--mrd-z-modal, 300);display:flex;align-items:center;justify-content:center}.mrd-table__modal.sc-mrd-table{background:#fff;border-radius:var(--mrd-radius-md, 0.5rem);padding:var(--mrd-space-6);max-width:min(600px, 90vw);max-height:70vh;overflow-y:auto;position:relative;box-shadow:var(--mrd-shadow-lg)}.mrd-table__modal-close.sc-mrd-table{position:absolute;top:var(--mrd-space-3);right:var(--mrd-space-3);background:none;border:none;cursor:pointer;font-size:1.25rem;line-height:1;color:var(--mrd-color-text-muted, #6b7280);padding:0}.mrd-table__modal-close.sc-mrd-table:hover{color:var(--mrd-color-text, #111827)}.mrd-table__modal-text.sc-mrd-table{margin:0;padding-right:var(--mrd-space-6);white-space:pre-wrap;word-break:break-word;font-size:var(--mrd-font-size-sm);line-height:1.6}.mrd-table__json-preview.sc-mrd-table{font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:inline-block;max-width:calc(100% - 1.5rem);vertical-align:middle}.mrd-table__modal-json.sc-mrd-table{margin:0;padding-right:var(--mrd-space-6);font-family:var(--mrd-font-family-mono);font-size:var(--mrd-font-size-xs);white-space:pre-wrap;word-break:break-word;line-height:1.6;background:none;border:none}@keyframes mrd-shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}`;
|
|
6655
7321
|
|
|
6656
7322
|
/** How often (ms) to scan outstanding page requests for staleness. */
|
|
6657
7323
|
const STALE_CHECK_INTERVAL_MS = 2000;
|
|
@@ -6682,6 +7348,17 @@ const MrdTable = class {
|
|
|
6682
7348
|
this.keydownHandler = null;
|
|
6683
7349
|
this.createPickerClickHandler = null;
|
|
6684
7350
|
this.viewPopoverClickHandler = null;
|
|
7351
|
+
/** Debounce timer for the free-text search box — separate from debounceTimer
|
|
7352
|
+
* (pending-page requests), since typing and scrolling debounce independently. */
|
|
7353
|
+
this.searchDebounceTimer = null;
|
|
7354
|
+
/** The rendered search <input>, captured so it can be focused the instant it mounts. */
|
|
7355
|
+
this.searchInputEl = null;
|
|
7356
|
+
/** Set by toggleSearch() when the box just expanded; consumed and cleared in componentDidRender(). */
|
|
7357
|
+
this.searchNeedsFocus = false;
|
|
7358
|
+
/** Column filters stashed by stashFiltersForSearch() while the search box is open — the
|
|
7359
|
+
* backend can't combine `q` with column filters. Restored by restoreFiltersAfterSearch()
|
|
7360
|
+
* on close, unless the user applied a fresh filter of their own in the meantime. */
|
|
7361
|
+
this.stashedFilters = null;
|
|
6685
7362
|
/** Watches the host for gaining a box (e.g. its tab pane being shown) — see componentDidLoad. */
|
|
6686
7363
|
this.resizeObserver = null;
|
|
6687
7364
|
/** Guards against scheduling more than one column-width measurement per freeze. */
|
|
@@ -6736,6 +7413,10 @@ const MrdTable = class {
|
|
|
6736
7413
|
this.sortDir = 'asc';
|
|
6737
7414
|
/** Active filters keyed by field name. */
|
|
6738
7415
|
this.activeFilters = new Map();
|
|
7416
|
+
/** True while the toolbar's magnifying glass is expanded into the search input. */
|
|
7417
|
+
this.searchOpen = false;
|
|
7418
|
+
/** Current free-text search query — sent as `q` on every mrdLoadPage/aggregations request. */
|
|
7419
|
+
this.searchQuery = '';
|
|
6739
7420
|
/** Field name of the currently open filter popup (null = closed). */
|
|
6740
7421
|
this.openFilterCol = null;
|
|
6741
7422
|
/** Filter state being edited in the open popup. */
|
|
@@ -6789,6 +7470,11 @@ const MrdTable = class {
|
|
|
6789
7470
|
this.colWidthMeasureScheduled = false;
|
|
6790
7471
|
this.colWidthsUserSet = false;
|
|
6791
7472
|
this.fixedContentMeasured = false;
|
|
7473
|
+
// A new item is a different table (possibly not even a VIEW any more) — a leftover
|
|
7474
|
+
// query from the old one should not silently keep filtering it.
|
|
7475
|
+
this.searchOpen = false;
|
|
7476
|
+
this.searchQuery = '';
|
|
7477
|
+
this.stashedFilters = null;
|
|
6792
7478
|
}
|
|
6793
7479
|
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
6794
7480
|
componentWillLoad() {
|
|
@@ -6896,7 +7582,12 @@ const MrdTable = class {
|
|
|
6896
7582
|
if (pageNumber === 0 && this.aggregationsPending) {
|
|
6897
7583
|
this.aggregationsPending = false;
|
|
6898
7584
|
const hasAggColumns = this.columns.some(c => c.type === 'FIELD' && c.aggregate);
|
|
6899
|
-
|
|
7585
|
+
// The aggregations endpoint doesn't support the `q` free-text param, so a request
|
|
7586
|
+
// sent while searching would silently return unfiltered totals. Leave aggregations
|
|
7587
|
+
// (and aggregationsTotal) at null instead — TotalsRow already renders nothing when
|
|
7588
|
+
// aggregations is null, so the totals row just disappears for the duration of the
|
|
7589
|
+
// search rather than showing numbers that don't match the filtered rows.
|
|
7590
|
+
if (!this.searchQuery && (!isLastPage || hasAggColumns)) {
|
|
6900
7591
|
this.emitLoadAggregations();
|
|
6901
7592
|
}
|
|
6902
7593
|
}
|
|
@@ -6935,10 +7626,18 @@ const MrdTable = class {
|
|
|
6935
7626
|
document.removeEventListener('click', this.viewPopoverClickHandler);
|
|
6936
7627
|
this.viewPopoverClickHandler = null;
|
|
6937
7628
|
}
|
|
7629
|
+
if (this.searchDebounceTimer !== null) {
|
|
7630
|
+
clearTimeout(this.searchDebounceTimer);
|
|
7631
|
+
this.searchDebounceTimer = null;
|
|
7632
|
+
}
|
|
6938
7633
|
}
|
|
6939
7634
|
componentDidRender() {
|
|
6940
7635
|
this.freezeColWidths();
|
|
6941
7636
|
this.growToFixedContent();
|
|
7637
|
+
if (this.searchNeedsFocus && this.searchInputEl) {
|
|
7638
|
+
this.searchInputEl.focus();
|
|
7639
|
+
this.searchNeedsFocus = false;
|
|
7640
|
+
}
|
|
6942
7641
|
}
|
|
6943
7642
|
/** Freeze the column widths once the first data page has rendered.
|
|
6944
7643
|
*
|
|
@@ -7229,16 +7928,19 @@ const MrdTable = class {
|
|
|
7229
7928
|
});
|
|
7230
7929
|
}
|
|
7231
7930
|
buildActionDetail(action, basicType) {
|
|
7232
|
-
var _a
|
|
7931
|
+
var _a;
|
|
7233
7932
|
if (action === 'export') {
|
|
7234
7933
|
return { action, path: this.buildExcelPath(), qs: this.buildQueryParams(0) };
|
|
7235
7934
|
}
|
|
7236
7935
|
if (action === 'create') {
|
|
7237
7936
|
const v = this.allViews[this.activeViewIdx];
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
: null
|
|
7241
|
-
|
|
7937
|
+
return buildCreateActionDetail({
|
|
7938
|
+
isRelatedView: ((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'RELATED_VIEW',
|
|
7939
|
+
fromClass: v === null || v === void 0 ? void 0 : v.fromClass,
|
|
7940
|
+
parentId: this.parentId,
|
|
7941
|
+
dataClass: v === null || v === void 0 ? void 0 : v.dataClass,
|
|
7942
|
+
basicType,
|
|
7943
|
+
});
|
|
7242
7944
|
}
|
|
7243
7945
|
return { action };
|
|
7244
7946
|
}
|
|
@@ -7257,7 +7959,13 @@ const MrdTable = class {
|
|
|
7257
7959
|
dataClass: v.dataClass,
|
|
7258
7960
|
});
|
|
7259
7961
|
}
|
|
7260
|
-
/** Build query params for a page request from current sort, view filters, filterClass and active column filters.
|
|
7962
|
+
/** Build query params for a page request from current sort, view filters, filterClass and active column filters.
|
|
7963
|
+
*
|
|
7964
|
+
* `q` and column filters are mutually exclusive on the backend — combining them breaks
|
|
7965
|
+
* the search. stashFiltersForSearch() already empties activeFilters for the duration of
|
|
7966
|
+
* a search, but this guard is the actual guarantee: even if a filter is applied through
|
|
7967
|
+
* a column header while the search box is still open (before the query is cleared),
|
|
7968
|
+
* activeFilters is dropped from the request rather than sent alongside `q`. */
|
|
7261
7969
|
buildQueryParams(page) {
|
|
7262
7970
|
var _a;
|
|
7263
7971
|
const v = this.allViews[this.activeViewIdx];
|
|
@@ -7266,7 +7974,8 @@ const MrdTable = class {
|
|
|
7266
7974
|
sort: this.sortParam(),
|
|
7267
7975
|
filterClass: v === null || v === void 0 ? void 0 : v.filterClass,
|
|
7268
7976
|
viewFilters: (_a = v === null || v === void 0 ? void 0 : v.view) === null || _a === void 0 ? void 0 : _a.filter,
|
|
7269
|
-
activeFilters: this.activeFilters.values(),
|
|
7977
|
+
activeFilters: this.searchQuery ? [] : this.activeFilters.values(),
|
|
7978
|
+
query: this.searchQuery,
|
|
7270
7979
|
});
|
|
7271
7980
|
}
|
|
7272
7981
|
/** True when the table is in paginated / virtual-scroll mode rather than driven by the
|
|
@@ -7572,6 +8281,18 @@ const MrdTable = class {
|
|
|
7572
8281
|
const current = (_b = (_a = this.pendingFilter) === null || _a === void 0 ? void 0 : _a.values) !== null && _b !== void 0 ? _b : [];
|
|
7573
8282
|
this.pendingFilter = Object.assign(Object.assign({}, this.pendingFilter), { values: checked ? [...current, key] : current.filter(k => k !== key) });
|
|
7574
8283
|
}
|
|
8284
|
+
/** Common reload after activeFilters or searchQuery changed: drop stale aggregations
|
|
8285
|
+
* (the next setPage(0) re-requests them, guarded against `q` in setPage() itself) and
|
|
8286
|
+
* re-fetch page 0. Shared by the filter popup, clear-all, and free-text search. */
|
|
8287
|
+
reloadAfterQueryChange() {
|
|
8288
|
+
this.aggregations = null;
|
|
8289
|
+
this.aggregationsTotal = null;
|
|
8290
|
+
this.aggregationsPending = true;
|
|
8291
|
+
if (this.isPaginated) {
|
|
8292
|
+
this.resetPages();
|
|
8293
|
+
this.emitPagesForWindow(this.renderStart, this.renderEnd);
|
|
8294
|
+
}
|
|
8295
|
+
}
|
|
7575
8296
|
applyFilter() {
|
|
7576
8297
|
const f = this.pendingFilter;
|
|
7577
8298
|
if (!(f === null || f === void 0 ? void 0 : f.field)) {
|
|
@@ -7588,13 +8309,7 @@ const MrdTable = class {
|
|
|
7588
8309
|
}
|
|
7589
8310
|
this.activeFilters = next;
|
|
7590
8311
|
this.closeFilterPopup();
|
|
7591
|
-
this.
|
|
7592
|
-
this.aggregationsTotal = null;
|
|
7593
|
-
this.aggregationsPending = true;
|
|
7594
|
-
if (this.isPaginated) {
|
|
7595
|
-
this.resetPages();
|
|
7596
|
-
this.emitPagesForWindow(this.renderStart, this.renderEnd);
|
|
7597
|
-
}
|
|
8312
|
+
this.reloadAfterQueryChange();
|
|
7598
8313
|
}
|
|
7599
8314
|
clearFilter() {
|
|
7600
8315
|
const name = this.openFilterCol;
|
|
@@ -7603,23 +8318,80 @@ const MrdTable = class {
|
|
|
7603
8318
|
next.delete(name);
|
|
7604
8319
|
this.activeFilters = next;
|
|
7605
8320
|
this.closeFilterPopup();
|
|
7606
|
-
this.
|
|
7607
|
-
this.aggregationsTotal = null;
|
|
7608
|
-
this.aggregationsPending = true;
|
|
7609
|
-
if (this.isPaginated) {
|
|
7610
|
-
this.resetPages();
|
|
7611
|
-
this.emitPagesForWindow(this.renderStart, this.renderEnd);
|
|
7612
|
-
}
|
|
8321
|
+
this.reloadAfterQueryChange();
|
|
7613
8322
|
}
|
|
7614
8323
|
clearAllFilters() {
|
|
7615
8324
|
this.activeFilters = new Map();
|
|
7616
|
-
this.
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
8325
|
+
this.reloadAfterQueryChange();
|
|
8326
|
+
}
|
|
8327
|
+
// ── Free-text search ───────────────────────────────────────────────────────
|
|
8328
|
+
/** Search is a VIEW-only affordance — a RELATED_VIEW table is already scoped to
|
|
8329
|
+
* its parent record, so a free-text box there would invite confusion about what
|
|
8330
|
+
* it searches across. */
|
|
8331
|
+
get searchEnabled() {
|
|
8332
|
+
var _a;
|
|
8333
|
+
return ((_a = this.item) === null || _a === void 0 ? void 0 : _a.type) === 'VIEW';
|
|
8334
|
+
}
|
|
8335
|
+
toggleSearch() {
|
|
8336
|
+
if (this.searchOpen) {
|
|
8337
|
+
this.closeSearch();
|
|
8338
|
+
}
|
|
8339
|
+
else {
|
|
8340
|
+
this.searchOpen = true;
|
|
8341
|
+
this.searchNeedsFocus = true;
|
|
8342
|
+
this.stashFiltersForSearch();
|
|
8343
|
+
}
|
|
8344
|
+
}
|
|
8345
|
+
/** Collapses the box back to the icon. Clearing a non-empty query and restoring any
|
|
8346
|
+
* stashed filters can each independently require a reload — reloadAfterQueryChange()
|
|
8347
|
+
* is called at most once here regardless of how many of the two actually changed. */
|
|
8348
|
+
closeSearch() {
|
|
8349
|
+
this.searchOpen = false;
|
|
8350
|
+
if (this.searchDebounceTimer !== null) {
|
|
8351
|
+
clearTimeout(this.searchDebounceTimer);
|
|
8352
|
+
this.searchDebounceTimer = null;
|
|
7622
8353
|
}
|
|
8354
|
+
const hadQuery = this.searchQuery !== '';
|
|
8355
|
+
this.searchQuery = '';
|
|
8356
|
+
const filtersRestored = this.restoreFiltersAfterSearch();
|
|
8357
|
+
if (hadQuery || filtersRestored)
|
|
8358
|
+
this.reloadAfterQueryChange();
|
|
8359
|
+
}
|
|
8360
|
+
handleSearchInput(value) {
|
|
8361
|
+
this.searchQuery = value;
|
|
8362
|
+
if (this.searchDebounceTimer !== null)
|
|
8363
|
+
clearTimeout(this.searchDebounceTimer);
|
|
8364
|
+
this.searchDebounceTimer = setTimeout(() => this.applySearch(), SEARCH_DEBOUNCE_MS);
|
|
8365
|
+
}
|
|
8366
|
+
/** Reloads from page 0 with the current searchQuery, same reset as applyFilter(). */
|
|
8367
|
+
applySearch() {
|
|
8368
|
+
this.searchDebounceTimer = null;
|
|
8369
|
+
this.reloadAfterQueryChange();
|
|
8370
|
+
}
|
|
8371
|
+
/** Column filters and the free-text `q` param are mutually exclusive on the backend —
|
|
8372
|
+
* sending both breaks the search. Opening the search box stashes any active filters
|
|
8373
|
+
* and clears them (the header filter icons and the clear-all button disappear along
|
|
8374
|
+
* with activeFilters, so there is nothing extra to hide) and reloads unfiltered. */
|
|
8375
|
+
stashFiltersForSearch() {
|
|
8376
|
+
if (this.activeFilters.size === 0)
|
|
8377
|
+
return;
|
|
8378
|
+
this.stashedFilters = this.activeFilters;
|
|
8379
|
+
this.activeFilters = new Map();
|
|
8380
|
+
this.reloadAfterQueryChange();
|
|
8381
|
+
}
|
|
8382
|
+
/** Restores filters stashed by stashFiltersForSearch(), unless the user applied a fresh
|
|
8383
|
+
* filter of their own while the search box was open — that explicit choice wins over
|
|
8384
|
+
* reinstating the old one. Returns whether activeFilters actually changed, so the
|
|
8385
|
+
* caller can decide whether a reload is needed. */
|
|
8386
|
+
restoreFiltersAfterSearch() {
|
|
8387
|
+
if (!this.stashedFilters)
|
|
8388
|
+
return false;
|
|
8389
|
+
const stashed = this.stashedFilters;
|
|
8390
|
+
this.stashedFilters = null;
|
|
8391
|
+
if (this.activeFilters.size > 0)
|
|
8392
|
+
return false;
|
|
8393
|
+
this.activeFilters = stashed;
|
|
8394
|
+
return true;
|
|
7623
8395
|
}
|
|
7624
8396
|
// ── View switcher ──────────────────────────────────────────────────────────
|
|
7625
8397
|
handleViewSwitch(targetIdx) {
|
|
@@ -7630,6 +8402,9 @@ const MrdTable = class {
|
|
|
7630
8402
|
this.activeViewIdx = targetIdx;
|
|
7631
8403
|
this.applyDefaultSort((_b = (_a = target.view) === null || _a === void 0 ? void 0 : _a.defaultSort) !== null && _b !== void 0 ? _b : '');
|
|
7632
8404
|
this.activeFilters = new Map();
|
|
8405
|
+
this.searchOpen = false;
|
|
8406
|
+
this.searchQuery = '';
|
|
8407
|
+
this.stashedFilters = null;
|
|
7633
8408
|
this.init();
|
|
7634
8409
|
}
|
|
7635
8410
|
toggleViewPopover(e) {
|
|
@@ -7652,7 +8427,7 @@ const MrdTable = class {
|
|
|
7652
8427
|
// ── Render: toolbar ────────────────────────────────────────────────────────
|
|
7653
8428
|
renderToolbar() {
|
|
7654
8429
|
var _a;
|
|
7655
|
-
return (h(Toolbar, { locale: this.locale, filterCount: this.activeFilters.size, actions: this.tableActions, views: this.allViews, activeViewIdx: this.activeViewIdx, viewPopoverOpen: this.viewPopoverOpen, createPickerOpen: this.createPickerOpen, createTypes: (_a = this.item) === null || _a === void 0 ? void 0 : _a.createTypes, readOnly: this.readOnly, cb: {
|
|
8430
|
+
return (h(Toolbar, { locale: this.locale, filterCount: this.activeFilters.size, actions: this.tableActions, views: this.allViews, activeViewIdx: this.activeViewIdx, viewPopoverOpen: this.viewPopoverOpen, createPickerOpen: this.createPickerOpen, createTypes: (_a = this.item) === null || _a === void 0 ? void 0 : _a.createTypes, readOnly: this.readOnly, searchEnabled: this.searchEnabled, searchOpen: this.searchOpen, searchQuery: this.searchQuery, cb: {
|
|
7656
8431
|
onClearAllFilters: () => this.clearAllFilters(),
|
|
7657
8432
|
onViewSwitch: idx => this.handleViewSwitch(idx),
|
|
7658
8433
|
onToggleViewPopover: e => this.toggleViewPopover(e),
|
|
@@ -7663,6 +8438,10 @@ const MrdTable = class {
|
|
|
7663
8438
|
this.closeCreatePicker();
|
|
7664
8439
|
},
|
|
7665
8440
|
onAction: action => this.mrdAction.emit(this.buildActionDetail(action)),
|
|
8441
|
+
onToggleSearch: () => this.toggleSearch(),
|
|
8442
|
+
onSearchInput: value => this.handleSearchInput(value),
|
|
8443
|
+
onCloseSearch: () => this.closeSearch(),
|
|
8444
|
+
onSearchInputRef: el => (this.searchInputEl = el !== null && el !== void 0 ? el : null),
|
|
7666
8445
|
} }));
|
|
7667
8446
|
}
|
|
7668
8447
|
// ── Render: filter popup ───────────────────────────────────────────────────
|
|
@@ -7853,12 +8632,29 @@ const MrdTextareaField = class {
|
|
|
7853
8632
|
this.required = false;
|
|
7854
8633
|
this.disabled = false;
|
|
7855
8634
|
this.locale = navigator.language;
|
|
8635
|
+
/** Focus the editor as soon as it's ready — opt-in, since auto-focusing every
|
|
8636
|
+
* textarea field on mount would be wrong for a regular multi-field form. */
|
|
8637
|
+
this.autofocus = false;
|
|
7856
8638
|
this.error = '';
|
|
7857
8639
|
this.editorReady = false;
|
|
7858
8640
|
}
|
|
7859
8641
|
componentDidLoad() {
|
|
7860
8642
|
this.initQuill();
|
|
7861
8643
|
}
|
|
8644
|
+
/** The host may reuse the same element for a different record (e.g. mrd-memo-
|
|
8645
|
+
* container's quick-create/edit dialog editing a second memo without the
|
|
8646
|
+
* dialog itself remounting) — Quill only reads `value` once at construction,
|
|
8647
|
+
* so re-apply it here when it changes to something the editor doesn't already
|
|
8648
|
+
* hold. Guarded against our own emitted mrdChange feeding back in as a no-op. */
|
|
8649
|
+
valueChanged(newValue) {
|
|
8650
|
+
if (!this.editorReady || !this.quill)
|
|
8651
|
+
return;
|
|
8652
|
+
if (newValue === this.getSanitizedHtml())
|
|
8653
|
+
return;
|
|
8654
|
+
this.quill.setText('');
|
|
8655
|
+
if (newValue)
|
|
8656
|
+
this.quill.clipboard.dangerouslyPasteHTML(newValue);
|
|
8657
|
+
}
|
|
7862
8658
|
async initQuill() {
|
|
7863
8659
|
try {
|
|
7864
8660
|
// Dynamically import Quill
|
|
@@ -7880,6 +8676,7 @@ const MrdTextareaField = class {
|
|
|
7880
8676
|
],
|
|
7881
8677
|
},
|
|
7882
8678
|
});
|
|
8679
|
+
this.quill = quill;
|
|
7883
8680
|
if (this.value) {
|
|
7884
8681
|
quill.clipboard.dangerouslyPasteHTML(this.value);
|
|
7885
8682
|
}
|
|
@@ -7895,6 +8692,8 @@ const MrdTextareaField = class {
|
|
|
7895
8692
|
}
|
|
7896
8693
|
});
|
|
7897
8694
|
this.editorReady = true;
|
|
8695
|
+
if (this.autofocus)
|
|
8696
|
+
quill.focus();
|
|
7898
8697
|
}
|
|
7899
8698
|
catch (err) {
|
|
7900
8699
|
console.error('Failed to load Quill editor:', err);
|
|
@@ -7906,9 +8705,14 @@ const MrdTextareaField = class {
|
|
|
7906
8705
|
return purify.sanitize(html);
|
|
7907
8706
|
}
|
|
7908
8707
|
render() {
|
|
7909
|
-
return (h(Host, { key: '
|
|
8708
|
+
return (h(Host, { key: '5dad54667601fce064107311e741e4e0dad94298' }, h("div", { key: 'bd7bd538155ec3172fa8cc1cf4cf66ad23d07a3b', class: "mrd-textarea-field" }, h(FieldLabel, { key: 'a3fe2c714340bbdcd3521e9782f87f3773c65e62', base: "mrd-textarea-field", label: this.label, required: this.required }), h("div", { key: 'a7a628f94bc628fd358c7fc876ee1bdd2c7ef520', class: controlClass('mrd-textarea-field', !!this.error, 'container') }, h("div", { key: '30ecd27d9e928094178f8f011524ff5633cb875e', class: "mrd-textarea-field__editor" })), h(FieldError, { key: '589d5cbf28c3ae1bdbe5f663aaf6cae840bdcffe', base: "mrd-textarea-field", error: this.error }))));
|
|
7910
8709
|
}
|
|
7911
8710
|
get el() { return getElement(this); }
|
|
8711
|
+
static get watchers() { return {
|
|
8712
|
+
"value": [{
|
|
8713
|
+
"valueChanged": 0
|
|
8714
|
+
}]
|
|
8715
|
+
}; }
|
|
7912
8716
|
};
|
|
7913
8717
|
MrdTextareaField.style = mrdTextareaFieldCss();
|
|
7914
8718
|
|
|
@@ -7942,4 +8746,4 @@ const MrdTimeField = class {
|
|
|
7942
8746
|
};
|
|
7943
8747
|
MrdTimeField.style = mrdTimeFieldCss();
|
|
7944
8748
|
|
|
7945
|
-
export { MrdBooleanField as mrd_boolean_field, MrdCurrencyField as mrd_currency_field, MrdDateField as mrd_date_field, MrdDatetimeField as mrd_datetime_field, MrdDocumentContainer as mrd_document_container, MrdDocumentList as mrd_document_list, MrdDocumentView as mrd_document_view, MrdEmailField as mrd_email_field, MrdEmailView as mrd_email_view, MrdField as mrd_field, MrdFileField as mrd_file_field, MrdForm as mrd_form, MrdHyperlinkField as mrd_hyperlink_field, MrdImageField as mrd_image_field, MrdInvoiceView as mrd_invoice_view, MrdLayoutSection as mrd_layout_section, MrdListField as mrd_list_field, MrdLongtextField as mrd_longtext_field, MrdNumberField as mrd_number_field, MrdRelationField as mrd_relation_field, MrdSecretField as mrd_secret_field, MrdTable as mrd_table, MrdTextField as mrd_text_field, MrdTextareaField as mrd_textarea_field, MrdTimeField as mrd_time_field };
|
|
8749
|
+
export { MrdBooleanField as mrd_boolean_field, MrdCurrencyField as mrd_currency_field, MrdDateField as mrd_date_field, MrdDatetimeField as mrd_datetime_field, MrdDocumentContainer as mrd_document_container, MrdDocumentList as mrd_document_list, MrdDocumentView as mrd_document_view, MrdEmailField as mrd_email_field, MrdEmailView as mrd_email_view, MrdField as mrd_field, MrdFileField as mrd_file_field, MrdForm as mrd_form, MrdHyperlinkField as mrd_hyperlink_field, MrdImageField as mrd_image_field, MrdInvoiceView as mrd_invoice_view, MrdLayoutSection as mrd_layout_section, MrdListField as mrd_list_field, MrdLongtextField as mrd_longtext_field, MrdMemoContainer as mrd_memo_container, MrdMemoList as mrd_memo_list, MrdMemoView as mrd_memo_view, MrdNumberField as mrd_number_field, MrdRelationField as mrd_relation_field, MrdSecretField as mrd_secret_field, MrdTable as mrd_table, MrdTextField as mrd_text_field, MrdTextareaField as mrd_textarea_field, MrdTimeField as mrd_time_field };
|