@mmlogic/components 0.5.14 → 0.5.16

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.
Files changed (91) hide show
  1. package/dist/cjs/{cell-renderer-mjS630f1.js → cell-renderer-CLVKTVVQ.js} +105 -1
  2. package/dist/cjs/{client-layout-CqVuJumR.js → client-layout-Eg2VwW-7.js} +2 -0
  3. package/dist/cjs/index.cjs.js +2 -1
  4. package/dist/cjs/loader.cjs.js +1 -1
  5. package/dist/cjs/mosterdcomponents.cjs.js +1 -1
  6. package/dist/cjs/{mrd-boolean-field_25.cjs.entry.js → mrd-boolean-field_28.cjs.entry.js} +1168 -314
  7. package/dist/cjs/mrd-merge-view.cjs.entry.js +4 -4
  8. package/dist/collection/collection-manifest.json +3 -0
  9. package/dist/collection/components/fields/mrd-textarea-field/mrd-textarea-field.js +47 -2
  10. package/dist/collection/components/form/mrd-field/mrd-field.css +69 -0
  11. package/dist/collection/components/form/mrd-field/mrd-field.js +95 -25
  12. package/dist/collection/components/form/mrd-form/mrd-form.css +29 -0
  13. package/dist/collection/components/form/mrd-form/mrd-form.js +44 -8
  14. package/dist/collection/components/layout/mrd-layout-section/field-value.js +19 -2
  15. package/dist/collection/components/layout/mrd-layout-section/layout-helpers.js +10 -0
  16. package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.css +4 -3
  17. package/dist/collection/components/layout/mrd-layout-section/mrd-layout-section.js +169 -18
  18. package/dist/collection/components/memo/mrd-memo-container/mrd-memo-container.css +204 -0
  19. package/dist/collection/components/memo/mrd-memo-container/mrd-memo-container.js +769 -0
  20. package/dist/collection/components/memo/mrd-memo-list/mrd-memo-list.css +164 -0
  21. package/dist/collection/components/memo/mrd-memo-list/mrd-memo-list.js +559 -0
  22. package/dist/collection/components/memo/mrd-memo-view/mrd-memo-view.css +108 -0
  23. package/dist/collection/components/memo/mrd-memo-view/mrd-memo-view.js +204 -0
  24. package/dist/collection/components/merge/mrd-merge-view/mrd-merge-view.js +2 -2
  25. package/dist/collection/components/table/mrd-table/mrd-table.js +9 -6
  26. package/dist/collection/dev/app.js +30 -15
  27. package/dist/collection/dev/example-data.js +15 -1
  28. package/dist/collection/types/client-layout.js +1 -0
  29. package/dist/collection/utils/i18n.js +104 -0
  30. package/dist/collection/utils/query-params.js +9 -0
  31. package/dist/components/client-layout.js +1 -1
  32. package/dist/components/i18n.js +1 -1
  33. package/dist/components/index.js +1 -1
  34. package/dist/components/mrd-field2.js +1 -1
  35. package/dist/components/mrd-form.js +1 -1
  36. package/dist/components/mrd-layout-section.js +1 -1
  37. package/dist/components/mrd-memo-container.d.ts +11 -0
  38. package/dist/components/mrd-memo-container.js +1 -0
  39. package/dist/components/mrd-memo-container2.js +1 -0
  40. package/dist/components/mrd-memo-list.d.ts +11 -0
  41. package/dist/components/mrd-memo-list.js +1 -0
  42. package/dist/components/mrd-memo-list2.js +1 -0
  43. package/dist/components/mrd-memo-view.d.ts +11 -0
  44. package/dist/components/mrd-memo-view.js +1 -0
  45. package/dist/components/mrd-memo-view2.js +1 -0
  46. package/dist/components/mrd-merge-view.js +1 -1
  47. package/dist/components/mrd-table2.js +1 -1
  48. package/dist/components/mrd-textarea-field2.js +1 -1
  49. package/dist/components/query-params.js +1 -1
  50. package/dist/components/table-query.js +1 -0
  51. package/dist/esm/{cell-renderer-BDY8UXkH.js → cell-renderer-4NKEzZWw.js} +105 -1
  52. package/dist/esm/{client-layout-Bc42CfJB.js → client-layout-BJkVeSq6.js} +2 -1
  53. package/dist/esm/index.js +1 -1
  54. package/dist/esm/loader.js +1 -1
  55. package/dist/esm/mosterdcomponents.js +1 -1
  56. package/dist/esm/{mrd-boolean-field_25.entry.js → mrd-boolean-field_28.entry.js} +1166 -315
  57. package/dist/esm/mrd-merge-view.entry.js +4 -4
  58. package/dist/mosterdcomponents/{cell-renderer-B8u5BCK-.js.map → cell-renderer-CMUxFREW.js.map} +1 -1
  59. package/dist/mosterdcomponents/client-layout-BJkVeSq6.js.map +1 -0
  60. package/dist/mosterdcomponents/{field-helpers-CNQcI3Hf.js.map → field-helpers-BWAp5fD8.js.map} +1 -1
  61. package/dist/mosterdcomponents/{file-upload-common-C9wp47CB.js.map → file-upload-common-DDWuC9-3.js.map} +1 -1
  62. package/dist/mosterdcomponents/i18n-OzbszktW.js.map +1 -0
  63. package/dist/mosterdcomponents/index-CkcFwdPc.js.map +1 -0
  64. package/dist/mosterdcomponents/index.esm.js +1 -1
  65. package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
  66. package/dist/mosterdcomponents/p-8a7fa81d.entry.js +3 -0
  67. package/dist/mosterdcomponents/{p-Bc42CfJB.js → p-BJkVeSq6.js} +1 -1
  68. package/dist/mosterdcomponents/p-BMx6VAJ6.js +1 -0
  69. package/dist/mosterdcomponents/{p-e8b0880f.entry.js → p-e68dfbb0.entry.js} +1 -1
  70. package/dist/mosterdcomponents/query-params-3TXd5CUO.js.map +1 -0
  71. package/dist/mosterdcomponents/table-query-DJq1uKqJ.js.map +1 -0
  72. package/dist/mosterdcomponents/{validation-CjjTt66G.js.map → validation-B_0Lx9DE.js.map} +1 -1
  73. package/dist/types/components/fields/mrd-textarea-field/mrd-textarea-field.d.ts +10 -0
  74. package/dist/types/components/form/mrd-field/mrd-field.d.ts +16 -0
  75. package/dist/types/components/form/mrd-form/mrd-form.d.ts +6 -0
  76. package/dist/types/components/layout/mrd-layout-section/field-value.d.ts +4 -0
  77. package/dist/types/components/layout/mrd-layout-section/layout-helpers.d.ts +3 -0
  78. package/dist/types/components/layout/mrd-layout-section/mrd-layout-section.d.ts +25 -1
  79. package/dist/types/components/memo/mrd-memo-container/mrd-memo-container.d.ts +173 -0
  80. package/dist/types/components/memo/mrd-memo-list/mrd-memo-list.d.ts +91 -0
  81. package/dist/types/components/memo/mrd-memo-view/mrd-memo-view.d.ts +33 -0
  82. package/dist/types/components.d.ts +571 -1
  83. package/dist/types/types/client-layout.d.ts +1 -0
  84. package/dist/types/utils/query-params.d.ts +16 -0
  85. package/package.json +1 -1
  86. package/dist/mosterdcomponents/client-layout-Bc42CfJB.js.map +0 -1
  87. package/dist/mosterdcomponents/i18n-ydNM87-Q.js.map +0 -1
  88. package/dist/mosterdcomponents/index-DhffneUF.js.map +0 -1
  89. package/dist/mosterdcomponents/p-Dkm4WxMy.js +0 -1
  90. package/dist/mosterdcomponents/p-c834951a.entry.js +0 -3
  91. package/dist/mosterdcomponents/query-params-BZbQoeYF.js.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import { Host, h } from "@stencil/core";
2
- import { ClientLayoutItemType, ClientLayoutItemFieldDataType, ClientLayoutNavigateBehaviour, resolveArchetype, ARCHETYPE_DOCUMENT, ARCHETYPE_INVOICE, ARCHETYPE_EMAIL, ARCHETYPE_INVOICE_LINE, } from "../../../types/client-layout";
2
+ import { ClientLayoutItemType, ClientLayoutItemFieldDataType, ClientLayoutNavigateBehaviour, resolveArchetype, ARCHETYPE_DOCUMENT, ARCHETYPE_INVOICE, ARCHETYPE_EMAIL, ARCHETYPE_INVOICE_LINE, ARCHETYPE_MEMO, } from "../../../types/client-layout";
3
3
  import { t } from "../../../utils/i18n";
4
- import { viewKeyFor, flattenItems, buildContainerHref, showsEmpty } from "./layout-helpers";
5
- import { renderField } from "./field-value";
4
+ import { viewKeyFor, flattenItems, buildContainerHref, showsEmpty, hasRelationValue } from "./layout-helpers";
5
+ import { renderField, isFieldVisible } from "./field-value";
6
6
  export class MrdLayoutSection {
7
7
  constructor() {
8
8
  /** Items from one layout entry in ClientDashboardMetadata.layouts[]. */
@@ -21,6 +21,11 @@ export class MrdLayoutSection {
21
21
  * create ("+") action and the documents view's New folder / Upload are disabled
22
22
  * with a tooltip explaining why, so it's clear at a glance the user can't mutate data. */
23
23
  this.readOnly = false;
24
+ /** The active account's linked person record (userProfile.links.person), if any.
25
+ * Threaded to mrd-memo-container so a top-level memo VIEW (no parent record to
26
+ * attach a new memo to) can still offer "New memo" by falling back to the
27
+ * account's own record as the container. */
28
+ this.me = null;
24
29
  this.searchQueryMap = {};
25
30
  this.searchResultsMap = {};
26
31
  this.imagePreviewUrl = null;
@@ -74,6 +79,14 @@ export class MrdLayoutSection {
74
79
  await table.init();
75
80
  }
76
81
  }
82
+ // mrd-memo-container's card mode has no <mrd-table> — mrd-memo-list needs the
83
+ // same init() call to request its first page.
84
+ const memoLists = this.el.querySelectorAll('mrd-memo-list[data-view]');
85
+ for (const list of Array.from(memoLists)) {
86
+ if (typeof list.init === 'function') {
87
+ await list.init();
88
+ }
89
+ }
77
90
  }
78
91
  emitLoadImages() {
79
92
  for (const item of flattenItems(this.items)) {
@@ -107,12 +120,18 @@ export class MrdLayoutSection {
107
120
  return;
108
121
  }
109
122
  const table = this.el.querySelector(`mrd-table[data-view="${name}"]`);
110
- if (!table)
123
+ if (table) {
124
+ if (totalElements !== undefined) {
125
+ table.totalElements = totalElements;
126
+ }
127
+ await table.setPage(page, rows, hasNext);
111
128
  return;
112
- if (totalElements !== undefined) {
113
- table.totalElements = totalElements;
114
129
  }
115
- await table.setPage(page, rows, hasNext);
130
+ // Cards mode: mrd-memo-container mounts mrd-memo-list instead of mrd-table.
131
+ const memoList = this.el.querySelector(`mrd-memo-list[data-view="${name}"]`);
132
+ if (memoList) {
133
+ await memoList.setPage(page, rows, hasNext);
134
+ }
116
135
  }
117
136
  /** Inject aggregation totals into an embedded mrd-table for a VIEW or RELATED_VIEW item. */
118
137
  async setViewAggregations(name, data) {
@@ -135,11 +154,18 @@ export class MrdLayoutSection {
135
154
  await list.setFileReference(uri);
136
155
  }
137
156
  /** Inject the created document's href after a file-drop create, so the
138
- * optimistic row becomes navigable (see mrdCreateObject). */
157
+ * optimistic row becomes navigable (see mrdCreateObject). For a memo
158
+ * quick-create there is no optimistic row to resolve — simply reload the
159
+ * container's current body so the new memo shows up. */
139
160
  async setViewCreatedObject(name, href) {
140
161
  const list = this.el.querySelector(`mrd-document-list[data-doclist="${name}"]`);
141
- if (list === null || list === void 0 ? void 0 : list.setCreatedHref)
162
+ if (list === null || list === void 0 ? void 0 : list.setCreatedHref) {
142
163
  await list.setCreatedHref(href);
164
+ return;
165
+ }
166
+ const memoContainer = this.el.querySelector(`mrd-memo-container[data-view="${name}"]`);
167
+ if (memoContainer === null || memoContainer === void 0 ? void 0 : memoContainer.refresh)
168
+ await memoContainer.refresh();
143
169
  }
144
170
  /** Provide a resolved URL for an IMAGE field. Shows as thumbnail; clicking opens the lightbox. */
145
171
  async setImagePreview(fieldName, url) {
@@ -186,7 +212,7 @@ export class MrdLayoutSection {
186
212
  else if (link === null || link === void 0 ? void 0 : link.name) {
187
213
  valueContent = makeBtn(link.href, link.name);
188
214
  }
189
- const isEmpty = !valueContent;
215
+ const isEmpty = !hasRelationValue(item, this.data);
190
216
  if (isEmpty && !showsEmpty(item))
191
217
  return null;
192
218
  return (h("div", { class: `mrd-layout-section__field${isEmpty ? ' mrd-layout-section__field--empty' : ''}`, key: item.name }, h("span", { class: "mrd-layout-section__field-label" }, item.label), h("span", { class: "mrd-layout-section__field-value" }, isEmpty ? t('value_empty', this.locale) : valueContent)));
@@ -201,7 +227,7 @@ export class MrdLayoutSection {
201
227
  return (h("div", { class: "mrd-layout-section__search", key: `search-${dataClass}` }, h("div", { class: "mrd-layout-section__search-wrap" }, h("svg", { class: "mrd-layout-section__search-icon", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true" }, h("path", { "fill-rule": "evenodd", d: "M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z", "clip-rule": "evenodd" })), h("input", { class: "mrd-layout-section__search-input", type: "text", value: query, placeholder: (_c = item.label) !== null && _c !== void 0 ? _c : '', onInput: e => this.handleSearchInput(dataClass, e.target.value) })), results.length > 0 && (h("ul", { class: "mrd-layout-section__search-results" }, results.map(r => (h("li", { key: r.id, class: "mrd-layout-section__search-result" }, h("button", { class: "mrd-layout-section__search-result-btn", onClick: () => this.mrdNavigate.emit({ href: r.id, label: r.label }) }, h("span", { class: "mrd-layout-section__search-result-label" }, r.label), r.description && h("span", { class: "mrd-layout-section__search-result-desc" }, r.description)))))))));
202
228
  }
203
229
  renderRelatedView(item) {
204
- var _a, _b, _c, _d, _e, _f, _g, _h;
230
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
205
231
  const key = viewKeyFor(item);
206
232
  if (!key)
207
233
  return null;
@@ -214,13 +240,25 @@ export class MrdLayoutSection {
214
240
  // The API publishes `archetypes` on the VIEW/RELATED_VIEW item itself
215
241
  // (sibling of `view`), not inside `view`.
216
242
  const docArchetype = resolveArchetype((_g = item.archetypes) !== null && _g !== void 0 ? _g : (_h = item.view) === null || _h === void 0 ? void 0 : _h.archetypes, ARCHETYPE_DOCUMENT);
243
+ const memoArchetype = !docArchetype ? resolveArchetype((_j = item.archetypes) !== null && _j !== void 0 ? _j : (_k = item.view) === null || _k === void 0 ? void 0 : _k.archetypes, ARCHETYPE_MEMO) : undefined;
217
244
  // Canonical parent href for single-container seeding: use the RELATED_VIEW's
218
245
  // fromClass (base class) rather than the route class, so polymorphic subtypes
219
246
  // resolve to the same container the documents actually reference.
220
247
  const containerHref = buildContainerHref(item, selfHref, parentId);
221
- return (h("div", { class: "mrd-layout-section__related-view", key: `view-${key}` }, showTitle && item.label && h("h3", { class: "mrd-layout-section__related-view-title" }, item.label), docArchetype
222
- ? this.renderDocumentContainer(item, key, parentId, docArchetype, containerHref)
223
- : this.renderTable(item, key, parentId)));
248
+ // A memo RELATED_VIEW isn't necessarily scoped by the container relation
249
+ // e.g. a person's dashboard can show "memos I authored" via the author
250
+ // relation instead. inverseRelation names which relation on the memo points
251
+ // back to this parent; only when it matches the container slot does the
252
+ // parent's own href double as the memo's container.
253
+ const memoContainerRelated = item.type !== ClientLayoutItemType.RELATED_VIEW
254
+ || item.inverseRelation === ((_l = memoArchetype === null || memoArchetype === void 0 ? void 0 : memoArchetype.slots) === null || _l === void 0 ? void 0 : _l.container);
255
+ const memoContainerHref = memoContainerRelated ? containerHref : '';
256
+ // Distinct from memoContainerRelated: only a genuine container-scoped
257
+ // RELATED_VIEW (a company's own memo tab) makes every card's container
258
+ // obvious from the page itself. A top-level VIEW or an author-scoped
259
+ // RELATED_VIEW both still need the per-card container link.
260
+ const memoContainerImplied = item.type === ClientLayoutItemType.RELATED_VIEW && memoContainerRelated;
261
+ 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, memoContainerHref, memoContainerRelated, !memoContainerImplied), !docArchetype && !memoArchetype && this.renderTable(item, key, parentId)));
224
262
  }
225
263
  /** Document collection view: owns the view-switch + collection actions and
226
264
  * swaps between the folder tree and the flat table. Events are re-emitted to
@@ -258,6 +296,37 @@ export class MrdLayoutSection {
258
296
  this.mrdCreateObject.emit(Object.assign({ name: key }, e.detail));
259
297
  } }));
260
298
  }
299
+ /** Memo collection view: owns the view-switch + "New memo" and swaps between
300
+ * the card list and the flat table, mirroring renderDocumentContainer(). */
301
+ renderMemoContainer(item, key, parentId, archetype, containerHref, containerRelated, showContainerLink) {
302
+ var _a, _b, _c, _d;
303
+ 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;
304
+ return (h("mrd-memo-container", { "data-view": key, item: item, archetype: archetype, parentId: parentId, containerHref: containerHref, containerRelated: containerRelated, showContainerLink: showContainerLink, viewKey: key, locale: this.locale, readOnly: this.readOnly, me: this.me, labelsListItems: labelsListItems, onMrdNavigate: (e) => {
305
+ var _a;
306
+ e.stopPropagation();
307
+ this.mrdNavigate.emit(Object.assign(Object.assign({}, e.detail), { navigateBehaviour: (_a = item.navigateBehaviour) !== null && _a !== void 0 ? _a : ClientLayoutNavigateBehaviour.PAGE }));
308
+ }, onMrdLoadPage: (e) => {
309
+ e.stopPropagation();
310
+ this.mrdLoadViewPage.emit(Object.assign({ name: key }, e.detail));
311
+ }, onMrdLoadAggregations: (e) => {
312
+ var _a;
313
+ e.stopPropagation();
314
+ this.mrdLoadViewAggregations.emit(Object.assign({ name: key, dataClass: (_a = item.dataClass) !== null && _a !== void 0 ? _a : key }, e.detail));
315
+ }, onMrdAction: (e) => {
316
+ var _a;
317
+ e.stopPropagation();
318
+ this.mrdViewAction.emit(Object.assign({ name: key, dataClass: (_a = item.dataClass) !== null && _a !== void 0 ? _a : key }, e.detail));
319
+ }, onMrdCreateObject: (e) => {
320
+ e.stopPropagation();
321
+ this.mrdCreateObject.emit(Object.assign({ name: key }, e.detail));
322
+ }, onMrdUpdateObject: (e) => {
323
+ e.stopPropagation();
324
+ this.mrdUpdateObject.emit(e.detail);
325
+ }, onMrdDeleteObject: (e) => {
326
+ e.stopPropagation();
327
+ this.mrdDeleteObject.emit(e.detail);
328
+ } }));
329
+ }
261
330
  renderTable(item, key, parentId) {
262
331
  return (h("mrd-table", { "data-view": key, item: item, parentId: parentId, locale: this.locale, readOnly: this.readOnly, onMrdLoadPage: (e) => this.handleViewLoadPage(e, key), onMrdLoadAggregations: (e) => {
263
332
  var _a;
@@ -287,7 +356,26 @@ export class MrdLayoutSection {
287
356
  });
288
357
  } }));
289
358
  }
290
- renderItem(item) {
359
+ /** Whether every FIELD/RELATION item following a HEADER (up to the next
360
+ * HEADER/SECTION/GROUP or the end of `siblings`) would itself render
361
+ * nothing — i.e. the HEADER would introduce an empty block. Other item
362
+ * types (VIEW, NAVIGATE, TEXT, ...) always count as visible. */
363
+ isHeaderBlockEmpty(siblings, index) {
364
+ const ctx = this.fieldCtx();
365
+ for (let i = index + 1; i < siblings.length; i++) {
366
+ const sib = siblings[i];
367
+ if (sib.type === ClientLayoutItemType.HEADER || sib.type === ClientLayoutItemType.SECTION || sib.type === ClientLayoutItemType.GROUP)
368
+ break;
369
+ if (sib.type === ClientLayoutItemType.FIELD && isFieldVisible(ctx, sib))
370
+ return false;
371
+ if (sib.type === ClientLayoutItemType.RELATION && (hasRelationValue(sib, this.data) || showsEmpty(sib)))
372
+ return false;
373
+ if (sib.type !== ClientLayoutItemType.FIELD && sib.type !== ClientLayoutItemType.RELATION)
374
+ return false;
375
+ }
376
+ return true;
377
+ }
378
+ renderItem(item, siblings = this.items, index = -1) {
291
379
  var _a, _b;
292
380
  switch (item.type) {
293
381
  case ClientLayoutItemType.FIELD:
@@ -295,6 +383,8 @@ export class MrdLayoutSection {
295
383
  case ClientLayoutItemType.RELATION:
296
384
  return this.renderRelation(item);
297
385
  case ClientLayoutItemType.HEADER:
386
+ if (index >= 0 && this.isHeaderBlockEmpty(siblings, index))
387
+ return null;
298
388
  return (h("h2", { class: "mrd-layout-section__header", key: `header-${item.label}` }, item.label));
299
389
  case ClientLayoutItemType.TEXT:
300
390
  return h("div", { class: "mrd-layout-section__text", key: `text-${item.label}`, innerHTML: (_a = item.label) !== null && _a !== void 0 ? _a : '' });
@@ -304,7 +394,7 @@ export class MrdLayoutSection {
304
394
  return this.renderSearch(item);
305
395
  case ClientLayoutItemType.SECTION:
306
396
  case ClientLayoutItemType.GROUP:
307
- return (h("div", { class: "mrd-layout-section__group", key: `group-${item.label}` }, item.label && h("h3", { class: "mrd-layout-section__group-title" }, item.label), ((_b = item.items) !== null && _b !== void 0 ? _b : []).map(child => this.renderItem(child))));
397
+ return (h("div", { class: "mrd-layout-section__group", key: `group-${item.label}` }, item.label && h("h3", { class: "mrd-layout-section__group-title" }, item.label), ((_b = item.items) !== null && _b !== void 0 ? _b : []).map((child, i) => { var _a; return this.renderItem(child, (_a = item.items) !== null && _a !== void 0 ? _a : [], i); })));
308
398
  case ClientLayoutItemType.RELATED_VIEW:
309
399
  case ClientLayoutItemType.VIEW:
310
400
  return this.renderRelatedView(item);
@@ -359,11 +449,24 @@ export class MrdLayoutSection {
359
449
  ...this.relatedItems().map(it => this.renderItem(it)),
360
450
  ];
361
451
  }
452
+ /** Single-memo view: the record's own type carries commons.memo. Renders a
453
+ * recognisable memo (title/body prominent, author/date subtle) instead of
454
+ * generic fields, keeping any related views/searches below it. */
455
+ renderMemoObject(archetype) {
456
+ var _a, _b;
457
+ 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;
458
+ return [
459
+ h("mrd-memo-view", { archetype: archetype, data: this.data, locale: this.locale, labelsListItems: labelsListItems, onMrdNavigate: (e) => { e.stopPropagation(); this.mrdNavigate.emit(e.detail); } }),
460
+ ...this.relatedItems().map(it => this.renderItem(it)),
461
+ ];
462
+ }
362
463
  render() {
363
464
  const docArchetype = resolveArchetype(this.archetypes, ARCHETYPE_DOCUMENT);
364
465
  const invoiceArchetype = !docArchetype ? resolveArchetype(this.archetypes, ARCHETYPE_INVOICE) : undefined;
365
466
  const emailArchetype = !docArchetype && !invoiceArchetype ? resolveArchetype(this.archetypes, ARCHETYPE_EMAIL) : undefined;
366
- return (h(Host, { key: '07b1d61b170a5ae971ba54eaf775e1787dea1642' }, h("div", { key: 'd146e0542b1de11bd130eb3d36d54e4faf055309', class: "mrd-layout-section" }, docArchetype && this.renderDocumentObject(docArchetype), invoiceArchetype && this.renderInvoiceObject(invoiceArchetype), emailArchetype && this.renderEmailObject(emailArchetype), !docArchetype && !invoiceArchetype && !emailArchetype && this.items.map(item => this.renderItem(item))), this.renderImageModal()));
467
+ const memoArchetype = !docArchetype && !invoiceArchetype && !emailArchetype ? resolveArchetype(this.archetypes, ARCHETYPE_MEMO) : undefined;
468
+ const anyArchetype = docArchetype || invoiceArchetype || emailArchetype || memoArchetype;
469
+ return (h(Host, { key: '057d145da172e68f84b6ff34f71ae649d6d6bf92' }, h("div", { key: 'e03a1761dc6bcd9ff54b264fee56130270bddc2f', 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, i) => this.renderItem(item, this.items, i))), this.renderImageModal()));
367
470
  }
368
471
  static get is() { return "mrd-layout-section"; }
369
472
  static get encapsulation() { return "scoped"; }
@@ -543,6 +646,31 @@ export class MrdLayoutSection {
543
646
  "reflect": false,
544
647
  "attribute": "read-only",
545
648
  "defaultValue": "false"
649
+ },
650
+ "me": {
651
+ "type": "unknown",
652
+ "mutable": false,
653
+ "complexType": {
654
+ "original": "RelationSearchResult | null",
655
+ "resolved": "RelationSearchResult | null",
656
+ "references": {
657
+ "RelationSearchResult": {
658
+ "location": "import",
659
+ "path": "../../../types/client-layout",
660
+ "id": "src/types/client-layout.ts::RelationSearchResult",
661
+ "referenceLocation": "RelationSearchResult"
662
+ }
663
+ }
664
+ },
665
+ "required": false,
666
+ "optional": false,
667
+ "docs": {
668
+ "tags": [],
669
+ "text": "The active account's linked person record (userProfile.links.person), if any.\nThreaded to mrd-memo-container so a top-level memo VIEW (no parent record to\nattach a new memo to) can still offer \"New memo\" by falling back to the\naccount's own record as the container."
670
+ },
671
+ "getter": false,
672
+ "setter": false,
673
+ "defaultValue": "null"
546
674
  }
547
675
  };
548
676
  }
@@ -743,6 +871,21 @@ export class MrdLayoutSection {
743
871
  }
744
872
  }
745
873
  }
874
+ }, {
875
+ "method": "mrdDeleteObject",
876
+ "name": "mrdDeleteObject",
877
+ "bubbles": true,
878
+ "cancelable": true,
879
+ "composed": true,
880
+ "docs": {
881
+ "tags": [],
882
+ "text": "Confirmed delete from an embedded memo dialog. Host DELETEs `href` \u2014 fire-\nand-forget, the row is already removed optimistically on the component side."
883
+ },
884
+ "complexType": {
885
+ "original": "{ href: string }",
886
+ "resolved": "{ href: string; }",
887
+ "references": {}
888
+ }
746
889
  }, {
747
890
  "method": "mrdViewUpload",
748
891
  "name": "mrdViewUpload",
@@ -858,6 +1001,10 @@ export class MrdLayoutSection {
858
1001
  "HTMLMrdTableElement": {
859
1002
  "location": "global",
860
1003
  "id": "global::HTMLMrdTableElement"
1004
+ },
1005
+ "HTMLMrdMemoListElement": {
1006
+ "location": "global",
1007
+ "id": "global::HTMLMrdMemoListElement"
861
1008
  }
862
1009
  },
863
1010
  "return": "Promise<void>"
@@ -984,12 +1131,16 @@ export class MrdLayoutSection {
984
1131
  "HTMLMrdDocumentListElement": {
985
1132
  "location": "global",
986
1133
  "id": "global::HTMLMrdDocumentListElement"
1134
+ },
1135
+ "HTMLMrdMemoContainerElement": {
1136
+ "location": "global",
1137
+ "id": "global::HTMLMrdMemoContainerElement"
987
1138
  }
988
1139
  },
989
1140
  "return": "Promise<void>"
990
1141
  },
991
1142
  "docs": {
992
- "text": "Inject the created document's href after a file-drop create, so the\noptimistic row becomes navigable (see mrdCreateObject).",
1143
+ "text": "Inject the created document's href after a file-drop create, so the\noptimistic row becomes navigable (see mrdCreateObject). For a memo\nquick-create there is no optimistic row to resolve \u2014 simply reload the\ncontainer's current body so the new memo shows up.",
993
1144
  "tags": []
994
1145
  }
995
1146
  },
@@ -0,0 +1,204 @@
1
+ :host {
2
+ display: block;
3
+ }
4
+
5
+ .mrd-memo-container__toolbar {
6
+ display: flex;
7
+ align-items: center;
8
+ justify-content: flex-end;
9
+ gap: var(--mrd-space-2);
10
+ padding: var(--mrd-space-2) 0;
11
+ border-bottom: 1px solid var(--mrd-color-neutral-100);
12
+ }
13
+ .mrd-memo-container__action {
14
+ display: inline-flex;
15
+ align-items: center;
16
+ gap: var(--mrd-space-2);
17
+ height: 1.625rem;
18
+ padding: 0 var(--mrd-space-3);
19
+ font-size: var(--mrd-font-size-sm);
20
+ color: var(--mrd-color-neutral-700);
21
+ background: var(--mrd-color-white);
22
+ border: 1px solid var(--mrd-color-neutral-200);
23
+ border-radius: var(--mrd-border-radius);
24
+ cursor: pointer;
25
+ transition: background var(--mrd-transition-fast), border-color var(--mrd-transition-fast);
26
+ }
27
+ .mrd-memo-container__action svg {
28
+ width: 1rem;
29
+ height: 1rem;
30
+ }
31
+ .mrd-memo-container__action:hover:not(:disabled) {
32
+ background: var(--mrd-color-neutral-50);
33
+ border-color: var(--mrd-color-neutral-300);
34
+ }
35
+ .mrd-memo-container__action:disabled {
36
+ opacity: 0.5;
37
+ cursor: not-allowed;
38
+ }
39
+ .mrd-memo-container__seg {
40
+ display: inline-flex;
41
+ gap: 2px;
42
+ padding: 2px;
43
+ background: var(--mrd-color-neutral-100);
44
+ border-radius: var(--mrd-border-radius);
45
+ }
46
+ .mrd-memo-container__seg-btn {
47
+ width: 1.875rem;
48
+ height: 1.625rem;
49
+ display: grid;
50
+ place-items: center;
51
+ border: none;
52
+ background: none;
53
+ border-radius: var(--mrd-border-radius-sm);
54
+ color: var(--mrd-color-neutral-500);
55
+ cursor: pointer;
56
+ transition: color var(--mrd-transition-fast), background var(--mrd-transition-fast);
57
+ }
58
+ .mrd-memo-container__seg-btn:hover {
59
+ color: var(--mrd-color-neutral-800);
60
+ }
61
+ .mrd-memo-container__seg-btn[aria-pressed=true] {
62
+ background: var(--mrd-color-white);
63
+ color: var(--mrd-color-primary-dark);
64
+ box-shadow: var(--mrd-shadow-sm);
65
+ }
66
+ .mrd-memo-container__seg-btn svg {
67
+ width: 1rem;
68
+ height: 1rem;
69
+ }
70
+ .mrd-memo-container__body {
71
+ padding-top: var(--mrd-space-3);
72
+ }
73
+ .mrd-memo-container__modal-backdrop {
74
+ position: fixed;
75
+ inset: 0;
76
+ background: rgba(0, 0, 0, 0.6);
77
+ z-index: 300;
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: center;
81
+ padding: var(--mrd-space-4);
82
+ }
83
+ .mrd-memo-container__modal {
84
+ width: 100%;
85
+ max-width: 960px;
86
+ max-height: 90vh;
87
+ overflow-y: auto;
88
+ display: flex;
89
+ flex-direction: column;
90
+ gap: var(--mrd-space-4);
91
+ background: var(--mrd-color-white);
92
+ border-radius: var(--mrd-border-radius-md);
93
+ padding: var(--mrd-space-5);
94
+ box-shadow: var(--mrd-shadow-lg);
95
+ }
96
+ .mrd-memo-container__modal-title {
97
+ font-size: var(--mrd-font-size-lg);
98
+ font-weight: var(--mrd-font-weight-bold);
99
+ color: var(--mrd-color-neutral-900);
100
+ margin: 0;
101
+ }
102
+ .mrd-memo-container__modal-field {
103
+ display: flex;
104
+ flex-direction: column;
105
+ gap: var(--mrd-space-1);
106
+ }
107
+ .mrd-memo-container__modal-error {
108
+ font-family: var(--mrd-font-family);
109
+ font-size: var(--mrd-error-font-size);
110
+ color: var(--mrd-error-color);
111
+ }
112
+ .mrd-memo-container__modal-warning {
113
+ margin: 0;
114
+ font-family: var(--mrd-font-family);
115
+ font-size: var(--mrd-font-size-base);
116
+ color: var(--mrd-color-neutral-600);
117
+ }
118
+ .mrd-memo-container__modal-actions {
119
+ display: flex;
120
+ justify-content: flex-end;
121
+ gap: var(--mrd-space-3);
122
+ margin-top: var(--mrd-space-2);
123
+ padding-top: var(--mrd-space-4);
124
+ border-top: var(--mrd-border-width) solid var(--mrd-border-color);
125
+ }
126
+ .mrd-memo-container__modal-delete {
127
+ display: inline-flex;
128
+ align-items: center;
129
+ justify-content: center;
130
+ height: var(--mrd-input-height);
131
+ padding: 0 var(--mrd-space-6);
132
+ margin-right: auto;
133
+ background-color: transparent;
134
+ color: var(--mrd-color-danger);
135
+ font-family: var(--mrd-font-family);
136
+ font-size: var(--mrd-font-size-base);
137
+ font-weight: var(--mrd-font-weight-medium);
138
+ border: var(--mrd-border-width) solid var(--mrd-color-danger);
139
+ border-radius: var(--mrd-border-radius);
140
+ cursor: pointer;
141
+ transition: background-color var(--mrd-transition), color var(--mrd-transition);
142
+ }
143
+ .mrd-memo-container__modal-delete:hover {
144
+ background-color: var(--mrd-color-danger-light);
145
+ color: var(--mrd-color-danger-dark);
146
+ }
147
+ .mrd-memo-container__modal-delete-confirm {
148
+ display: inline-flex;
149
+ align-items: center;
150
+ justify-content: center;
151
+ height: var(--mrd-input-height);
152
+ padding: 0 var(--mrd-space-6);
153
+ background-color: var(--mrd-color-danger);
154
+ color: var(--mrd-color-white);
155
+ font-family: var(--mrd-font-family);
156
+ font-size: var(--mrd-font-size-base);
157
+ font-weight: var(--mrd-font-weight-medium);
158
+ border: none;
159
+ border-radius: var(--mrd-border-radius);
160
+ cursor: pointer;
161
+ transition: background-color var(--mrd-transition);
162
+ }
163
+ .mrd-memo-container__modal-delete-confirm:hover {
164
+ background-color: var(--mrd-color-danger-dark);
165
+ }
166
+ .mrd-memo-container__modal-cancel {
167
+ display: inline-flex;
168
+ align-items: center;
169
+ justify-content: center;
170
+ height: var(--mrd-input-height);
171
+ padding: 0 var(--mrd-space-6);
172
+ background-color: transparent;
173
+ color: var(--mrd-color-neutral-600);
174
+ font-family: var(--mrd-font-family);
175
+ font-size: var(--mrd-font-size-base);
176
+ font-weight: var(--mrd-font-weight-medium);
177
+ border: var(--mrd-border-width) solid var(--mrd-border-color);
178
+ border-radius: var(--mrd-border-radius);
179
+ cursor: pointer;
180
+ transition: background-color var(--mrd-transition), color var(--mrd-transition);
181
+ }
182
+ .mrd-memo-container__modal-cancel:hover {
183
+ background-color: var(--mrd-color-neutral-100);
184
+ color: var(--mrd-color-neutral-800);
185
+ }
186
+ .mrd-memo-container__modal-submit {
187
+ display: inline-flex;
188
+ align-items: center;
189
+ justify-content: center;
190
+ height: var(--mrd-input-height);
191
+ padding: 0 var(--mrd-space-6);
192
+ background-color: var(--mrd-color-primary);
193
+ color: var(--mrd-color-white);
194
+ font-family: var(--mrd-font-family);
195
+ font-size: var(--mrd-font-size-base);
196
+ font-weight: var(--mrd-font-weight-medium);
197
+ border: none;
198
+ border-radius: var(--mrd-border-radius);
199
+ cursor: pointer;
200
+ transition: background-color var(--mrd-transition);
201
+ }
202
+ .mrd-memo-container__modal-submit:hover {
203
+ background-color: var(--mrd-color-primary-hover);
204
+ }