@mmlogic/components 0.1.24 → 0.1.26

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 (45) hide show
  1. package/dist/cjs/loader.cjs.js +1 -1
  2. package/dist/cjs/mosterdcomponents.cjs.js +1 -1
  3. package/dist/cjs/mrd-boolean-field_19.cjs.entry.js +3142 -0
  4. package/dist/collection/collection-manifest.json +1 -0
  5. package/dist/collection/components/mrd-layout-section/mrd-layout-section.js +733 -0
  6. package/dist/collection/components/mrd-layout-section/mrd-layout-section.scss +354 -0
  7. package/dist/collection/components/mrd-longtext-field/mrd-longtext-field.js +1 -1
  8. package/dist/collection/components/mrd-number-field/mrd-number-field.js +1 -1
  9. package/dist/collection/components/mrd-table/mrd-table.js +53 -42
  10. package/dist/collection/components/mrd-table/mrd-table.scss +29 -71
  11. package/dist/collection/components/mrd-text-field/mrd-text-field.js +1 -1
  12. package/dist/collection/components/mrd-textarea-field/mrd-textarea-field.js +1 -1
  13. package/dist/collection/components/mrd-time-field/mrd-time-field.js +1 -1
  14. package/dist/collection/dev/app.js +109 -3
  15. package/dist/collection/dev/example-data.js +324 -0
  16. package/dist/collection/utils/cell-renderer.js +26 -0
  17. package/dist/components/mrd-layout-section.d.ts +11 -0
  18. package/dist/components/mrd-layout-section.js +1 -0
  19. package/dist/components/mrd-longtext-field2.js +1 -1
  20. package/dist/components/mrd-number-field2.js +1 -1
  21. package/dist/components/mrd-table.js +1 -1
  22. package/dist/components/mrd-table2.js +1 -0
  23. package/dist/components/mrd-text-field2.js +1 -1
  24. package/dist/components/mrd-textarea-field2.js +1 -1
  25. package/dist/components/mrd-time-field2.js +1 -1
  26. package/dist/esm/loader.js +1 -1
  27. package/dist/esm/mosterdcomponents.js +1 -1
  28. package/dist/esm/mrd-boolean-field_19.entry.js +3122 -0
  29. package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
  30. package/dist/mosterdcomponents/p-e1a5587b.entry.js +1 -0
  31. package/dist/types/components/mrd-layout-section/mrd-layout-section.d.ts +93 -0
  32. package/dist/types/components/mrd-table/mrd-table.d.ts +5 -6
  33. package/dist/types/components.d.ts +128 -8
  34. package/dist/types/types/client-layout.d.ts +19 -0
  35. package/dist/types/utils/cell-renderer.d.ts +9 -1
  36. package/package.json +1 -1
  37. package/dist/cjs/format-DExY8_nu.js +0 -328
  38. package/dist/cjs/mrd-boolean-field_17.cjs.entry.js +0 -1554
  39. package/dist/cjs/mrd-table.cjs.entry.js +0 -888
  40. package/dist/esm/format-CcRjWvcb.js +0 -319
  41. package/dist/esm/mrd-boolean-field_17.entry.js +0 -1536
  42. package/dist/esm/mrd-table.entry.js +0 -886
  43. package/dist/mosterdcomponents/p-17fe94c6.entry.js +0 -1
  44. package/dist/mosterdcomponents/p-3d856b27.entry.js +0 -1
  45. package/dist/mosterdcomponents/p-CcRjWvcb.js +0 -1
@@ -0,0 +1,733 @@
1
+ import { Host, h } from "@stencil/core";
2
+ import { ClientLayoutItemType, ClientLayoutItemFieldDataType, } from "../../types/client-layout";
3
+ import { CellRenderer } from "../../utils/cell-renderer";
4
+ import { t } from "../../utils/i18n";
5
+ export class MrdLayoutSection {
6
+ constructor() {
7
+ /** Items from one layout entry in ClientDashboardMetadata.layouts[]. */
8
+ this.items = [];
9
+ /** Record data object; keys are field names, _links holds relation and related-view links. */
10
+ this.data = {};
11
+ /** View metadata map (ClientDashboardMetadata.views) for RELATED_VIEW and VIEW items. */
12
+ this.views = {};
13
+ /** Top-level _links from ClientDashboardMetadata; used to resolve hrefs for VIEW items. */
14
+ this.links = {};
15
+ this.locale = navigator.language;
16
+ this.searchQueryMap = {};
17
+ this.searchResultsMap = {};
18
+ this.imagePreviewUrl = null;
19
+ this.imagePreviews = {};
20
+ this.activeViewMap = {};
21
+ this.viewLinksMap = {};
22
+ this.searchTimers = {};
23
+ this.handleViewLoadPage = (e, name) => {
24
+ e.stopPropagation();
25
+ this.mrdLoadViewPage.emit({ name, page: e.detail.page, sort: e.detail.sort });
26
+ };
27
+ this.handleSearchInput = (dataClass, query) => {
28
+ this.searchQueryMap = Object.assign(Object.assign({}, this.searchQueryMap), { [dataClass]: query });
29
+ if (this.searchTimers[dataClass])
30
+ clearTimeout(this.searchTimers[dataClass]);
31
+ if (query.length < 2) {
32
+ this.searchResultsMap = Object.assign(Object.assign({}, this.searchResultsMap), { [dataClass]: [] });
33
+ return;
34
+ }
35
+ this.searchTimers[dataClass] = setTimeout(() => {
36
+ this.mrdSearch.emit({ query, dataClass });
37
+ }, 300);
38
+ };
39
+ }
40
+ componentDidLoad() {
41
+ setTimeout(() => {
42
+ this.emitLoadViews();
43
+ this.emitLoadImages();
44
+ }, 0);
45
+ }
46
+ linksChanged(newVal) {
47
+ if (Object.keys(newVal !== null && newVal !== void 0 ? newVal : {}).length > 0) {
48
+ this.emitLoadViews();
49
+ }
50
+ }
51
+ dataChanged(newVal) {
52
+ var _a;
53
+ if (newVal && Object.keys((_a = newVal === null || newVal === void 0 ? void 0 : newVal._links) !== null && _a !== void 0 ? _a : {}).length > 0) {
54
+ this.emitLoadViews();
55
+ }
56
+ }
57
+ emitLoadViews() {
58
+ var _a, _b, _c, _d, _e, _f;
59
+ const dataLinks = ((_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a._links) !== null && _b !== void 0 ? _b : {});
60
+ for (const item of this.flattenItems(this.items)) {
61
+ if (item.type === ClientLayoutItemType.RELATED_VIEW && item.relatedView) {
62
+ const rv = item.relatedView;
63
+ const viewConfig = this.views[rv.name];
64
+ if (!viewConfig)
65
+ continue;
66
+ const href = (_c = dataLinks[rv.relatedClass]) === null || _c === void 0 ? void 0 : _c.href;
67
+ this.mrdLoadView.emit({ name: rv.name, href, viewConfig });
68
+ }
69
+ else if (item.type === ClientLayoutItemType.VIEW) {
70
+ const viewName = (_e = (_d = item.view) === null || _d === void 0 ? void 0 : _d.name) !== null && _e !== void 0 ? _e : item.name;
71
+ if (!viewName)
72
+ continue;
73
+ const viewConfig = this.views[viewName];
74
+ if (!viewConfig)
75
+ continue;
76
+ const href = (_f = this.links[viewName]) === null || _f === void 0 ? void 0 : _f.href;
77
+ this.mrdLoadView.emit({ name: viewName, href, viewConfig });
78
+ }
79
+ }
80
+ }
81
+ emitLoadImages() {
82
+ var _a;
83
+ for (const item of this.flattenItems(this.items)) {
84
+ if (item.type === ClientLayoutItemType.FIELD && ((_a = item.field) === null || _a === void 0 ? void 0 : _a.dataType) === ClientLayoutItemFieldDataType.IMAGE) {
85
+ const fieldName = item.field.name;
86
+ const raw = this.data[fieldName];
87
+ const href = raw === null || raw === void 0 ? void 0 : raw.href;
88
+ if (href)
89
+ this.mrdLoadImage.emit({ fieldName, href });
90
+ }
91
+ }
92
+ }
93
+ flattenItems(items) {
94
+ const result = [];
95
+ for (const item of items) {
96
+ result.push(item);
97
+ if (item.items)
98
+ result.push(...this.flattenItems(item.items));
99
+ }
100
+ return result;
101
+ }
102
+ /** Inject search results. Pass dataClass to target a specific SEARCH item; omit when there is only one. */
103
+ async setSearchResults(results, dataClass) {
104
+ const key = dataClass !== null && dataClass !== void 0 ? dataClass : this.resolveSearchKey();
105
+ if (key) {
106
+ this.searchResultsMap = Object.assign(Object.assign({}, this.searchResultsMap), { [key]: results });
107
+ }
108
+ }
109
+ /**
110
+ * Inject data into an embedded mrd-table for a RELATED_VIEW or VIEW item.
111
+ * Pass totalElements on page 0 to initialise the table; omit on subsequent pages.
112
+ * Pass pageLinks (_links from the page response) on page 0 to enable action hrefs in mrdViewAction.
113
+ */
114
+ async setViewPage(name, page, rows, totalElements, pageLinks) {
115
+ if (pageLinks) {
116
+ this.viewLinksMap = Object.assign(Object.assign({}, this.viewLinksMap), { [name]: pageLinks });
117
+ }
118
+ const table = this.el.querySelector(`mrd-table[data-view="${name}"]`);
119
+ if (!table)
120
+ return;
121
+ if (totalElements !== undefined) {
122
+ table.totalElements = totalElements;
123
+ await table.init();
124
+ }
125
+ await table.setPage(page, rows);
126
+ }
127
+ /** Provide a resolved URL for an IMAGE field. Shows as thumbnail; clicking opens the lightbox. */
128
+ async setImagePreview(fieldName, url) {
129
+ this.imagePreviews = Object.assign(Object.assign({}, this.imagePreviews), { [fieldName]: url });
130
+ }
131
+ /** Open the lightbox directly with a URL (e.g. after mrdDownload on a FILE field). */
132
+ async openImagePreview(url) {
133
+ this.imagePreviewUrl = url;
134
+ }
135
+ resolveSearchKey() {
136
+ const items = this.flattenItems(this.items).filter(i => i.type === ClientLayoutItemType.SEARCH);
137
+ if (items.length === 1 && items[0].search)
138
+ return items[0].search.dataClass;
139
+ return null;
140
+ }
141
+ renderSingleFieldValue(item, value) {
142
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
143
+ const field = item.field;
144
+ const dt = field.dataType;
145
+ switch (dt) {
146
+ case ClientLayoutItemFieldDataType.HYPERLINK: {
147
+ const v = value;
148
+ const href = (_a = v === null || v === void 0 ? void 0 : v.href) !== null && _a !== void 0 ? _a : String(value);
149
+ const label = (_c = (_b = v === null || v === void 0 ? void 0 : v.text) !== null && _b !== void 0 ? _b : v === null || v === void 0 ? void 0 : v.label) !== null && _c !== void 0 ? _c : href;
150
+ return (h("a", { class: "mrd-layout-section__link", href: href, target: "_blank", rel: "noopener noreferrer" }, label));
151
+ }
152
+ case ClientLayoutItemFieldDataType.TEXTBLOCK:
153
+ return h("span", { innerHTML: String(value) });
154
+ case ClientLayoutItemFieldDataType.LONGTEXT:
155
+ return h("pre", { class: "mrd-layout-section__pre" }, String(value));
156
+ case ClientLayoutItemFieldDataType.JSON:
157
+ return h("pre", { class: "mrd-layout-section__pre", innerHTML: CellRenderer.formatJson(value) });
158
+ case ClientLayoutItemFieldDataType.FILE: {
159
+ const v = value;
160
+ const fileName = (_d = v === null || v === void 0 ? void 0 : v.fileName) !== null && _d !== void 0 ? _d : String(value);
161
+ const href = (_e = v === null || v === void 0 ? void 0 : v.href) !== null && _e !== void 0 ? _e : '';
162
+ return (h("button", { class: "mrd-layout-section__download-link", onClick: () => href && this.mrdDownload.emit({ href, fileName }) }, h("svg", { class: "mrd-layout-section__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 7V3.5L18.5 9H13zm-3 8l-3-3 1.41-1.41L10 14.17l4.59-4.58L16 11l-6 6z" })), t('download', this.locale)));
163
+ }
164
+ case ClientLayoutItemFieldDataType.IMAGE: {
165
+ const v = value;
166
+ const href = (_f = v === null || v === void 0 ? void 0 : v.href) !== null && _f !== void 0 ? _f : '';
167
+ const fileName = (_g = v === null || v === void 0 ? void 0 : v.fileName) !== null && _g !== void 0 ? _g : '';
168
+ const previewUrl = this.imagePreviews[field.name];
169
+ if (previewUrl) {
170
+ return (h("button", { class: "mrd-layout-section__image-thumb-btn", onClick: () => { this.imagePreviewUrl = previewUrl; }, title: fileName || undefined }, h("img", { class: "mrd-layout-section__image-thumb", src: previewUrl, alt: fileName })));
171
+ }
172
+ return (h("button", { class: "mrd-layout-section__download-link", onClick: () => href && this.mrdDownload.emit({ href, fileName }) }, h("svg", { class: "mrd-layout-section__file-icon", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { fill: "currentColor", d: "M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 7V3.5L18.5 9H13zm-3 8l-3-3 1.41-1.41L10 14.17l4.59-4.58L16 11l-6 6z" })), fileName || href));
173
+ }
174
+ case ClientLayoutItemFieldDataType.BOOLEAN:
175
+ return (h("span", { class: `mrd-layout-section__boolean mrd-layout-section__boolean--${value ? 'true' : 'false'}` }, value ? t('yes', this.locale) : t('no', this.locale)));
176
+ case ClientLayoutItemFieldDataType.LIST: {
177
+ const listItem = ((_h = field.listItems) !== null && _h !== void 0 ? _h : []).find(li => li.key === String(value));
178
+ const label = (_j = listItem === null || listItem === void 0 ? void 0 : listItem.label) !== null && _j !== void 0 ? _j : String(value);
179
+ const color = listItem === null || listItem === void 0 ? void 0 : listItem.color;
180
+ const bg = listItem === null || listItem === void 0 ? void 0 : listItem.backgroundColor;
181
+ if (color && bg) {
182
+ return (h("span", { class: "mrd-layout-section__badge", style: { color, backgroundColor: bg } }, label));
183
+ }
184
+ if (color) {
185
+ return (h("span", { class: "mrd-layout-section__badge-dot-row" }, h("span", { class: "mrd-layout-section__badge-dot", style: { backgroundColor: color } }), label));
186
+ }
187
+ return label;
188
+ }
189
+ default: {
190
+ const text = CellRenderer.renderValue(dt, value, (_k = field.listItems) !== null && _k !== void 0 ? _k : [], this.locale);
191
+ return text || null;
192
+ }
193
+ }
194
+ }
195
+ renderFieldValue(item, rawValue) {
196
+ if (rawValue == null || rawValue === '')
197
+ return null;
198
+ const field = item.field;
199
+ if (field.multiple && Array.isArray(rawValue)) {
200
+ const rendered = rawValue.map(v => this.renderSingleFieldValue(item, v));
201
+ if (rendered.every(r => typeof r === 'string' || r == null)) {
202
+ return rendered.filter(Boolean).join(', ') || null;
203
+ }
204
+ return (h("span", null, rendered.map((r, i) => (h("span", { key: String(i) }, r, i < rendered.length - 1 ? ', ' : '')))));
205
+ }
206
+ return this.renderSingleFieldValue(item, rawValue);
207
+ }
208
+ renderField(item) {
209
+ if (!item.field)
210
+ return null;
211
+ const field = item.field;
212
+ const rawValue = this.data[field.name];
213
+ const renderedValue = this.renderFieldValue(item, rawValue);
214
+ if (field.header) {
215
+ return (h("h1", { class: "mrd-layout-section__field-header", key: field.name }, typeof renderedValue === 'string' ? renderedValue : rawValue != null ? String(rawValue) : item.label));
216
+ }
217
+ if (renderedValue == null)
218
+ return null;
219
+ const isBlock = field.dataType === ClientLayoutItemFieldDataType.TEXTBLOCK
220
+ || field.dataType === ClientLayoutItemFieldDataType.LONGTEXT
221
+ || field.dataType === ClientLayoutItemFieldDataType.JSON;
222
+ return (h("div", { class: `mrd-layout-section__field${isBlock ? ' mrd-layout-section__field--block' : ''}`, key: field.name }, h("span", { class: "mrd-layout-section__field-label" }, item.label), h("span", { class: "mrd-layout-section__field-value" }, renderedValue)));
223
+ }
224
+ renderRelation(item) {
225
+ var _a, _b, _c;
226
+ if (!item.relation)
227
+ return null;
228
+ const links = ((_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a._links) !== null && _b !== void 0 ? _b : {});
229
+ const link = links[item.relation.name];
230
+ if (!link)
231
+ return null;
232
+ const makeBtn = (href, name) => (h("button", { key: href, class: "mrd-layout-section__relation-link", onClick: () => this.mrdNavigate.emit({ href, label: name }) }, name));
233
+ let valueContent;
234
+ if ((_c = link.values) === null || _c === void 0 ? void 0 : _c.length) {
235
+ valueContent = link.values.map(v => makeBtn(v.href, v.name));
236
+ }
237
+ else if (link.name) {
238
+ valueContent = makeBtn(link.href, link.name);
239
+ }
240
+ if (!valueContent)
241
+ return null;
242
+ return (h("div", { class: "mrd-layout-section__field", key: item.relation.name }, h("span", { class: "mrd-layout-section__field-label" }, item.label), h("span", { class: "mrd-layout-section__field-value" }, valueContent)));
243
+ }
244
+ renderSearch(item) {
245
+ var _a, _b, _c;
246
+ if (!item.search)
247
+ return null;
248
+ const dataClass = item.search.dataClass;
249
+ const query = (_a = this.searchQueryMap[dataClass]) !== null && _a !== void 0 ? _a : '';
250
+ const results = (_b = this.searchResultsMap[dataClass]) !== null && _b !== void 0 ? _b : [];
251
+ return (h("div", { class: "mrd-layout-section__search", key: `search-${dataClass}` }, 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)))))))));
252
+ }
253
+ renderRelatedView(item) {
254
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
255
+ const isRelated = item.type === ClientLayoutItemType.RELATED_VIEW;
256
+ // Support both nested (item.view / item.relatedView) and flat API format (item.name)
257
+ const name = isRelated
258
+ ? (_a = item.relatedView) === null || _a === void 0 ? void 0 : _a.name
259
+ : ((_c = (_b = item.view) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : item.name);
260
+ if (!name)
261
+ return null;
262
+ const viewConfig = this.views[name];
263
+ if (!viewConfig)
264
+ return null;
265
+ const showTitle = isRelated
266
+ ? (_d = item.relatedView) === null || _d === void 0 ? void 0 : _d.showTitle
267
+ : ((_g = (_f = (_e = item.view) === null || _e === void 0 ? void 0 : _e.showTitle) !== null && _f !== void 0 ? _f : item.showTitle) !== null && _g !== void 0 ? _g : false);
268
+ const altViews = item.alternativeViews;
269
+ const activeName = (_h = this.activeViewMap[name]) !== null && _h !== void 0 ? _h : name;
270
+ const activeViewConfig = (_j = this.views[activeName]) !== null && _j !== void 0 ? _j : viewConfig;
271
+ const viewLabel = (_m = (_l = (_k = item.label) !== null && _k !== void 0 ? _k : activeViewConfig.pluralLabel) !== null && _l !== void 0 ? _l : activeViewConfig.singularLabel) !== null && _m !== void 0 ? _m : '';
272
+ const rawActions = (_o = item.actions) !== null && _o !== void 0 ? _o : ['NEW', 'EXPORT'];
273
+ const tableActions = rawActions.reduce((acc, a) => {
274
+ if (a === 'NEW')
275
+ acc.push({ action: 'create', label: t('table_new_record', this.locale), icon: 'assets/sprites.svg#icon-plus', variant: 'primary' });
276
+ if (a === 'EXPORT')
277
+ acc.push({ action: 'export', label: t('table_export_excel', this.locale), icon: 'assets/sprites.svg#icon-file-excel' });
278
+ return acc;
279
+ }, []);
280
+ return (h("div", { class: "mrd-layout-section__related-view", key: `view-${name}` }, showTitle && item.label && h("h3", { class: "mrd-layout-section__related-view-title" }, item.label), h("mrd-table", { "data-view": name, columns: activeViewConfig.values, locale: this.locale, defaultSort: (_p = activeViewConfig.defaultSort) !== null && _p !== void 0 ? _p : '', viewLabel: viewLabel, alternativeViews: altViews, actions: tableActions, onMrdLoadPage: (e) => this.handleViewLoadPage(e, name), onMrdSwitchView: (e) => {
281
+ var _a, _b, _c, _d, _e, _f;
282
+ e.stopPropagation();
283
+ const newViewName = e.detail.name;
284
+ const newViewConfig = this.views[newViewName];
285
+ if (!newViewConfig)
286
+ return;
287
+ this.activeViewMap = Object.assign(Object.assign({}, this.activeViewMap), { [name]: newViewName });
288
+ const dataLinks = ((_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a._links) !== null && _b !== void 0 ? _b : {});
289
+ const href = isRelated
290
+ ? (_c = dataLinks[item.relatedView.relatedClass]) === null || _c === void 0 ? void 0 : _c.href
291
+ : ((_e = (_d = this.links[newViewName]) === null || _d === void 0 ? void 0 : _d.href) !== null && _e !== void 0 ? _e : (_f = this.links[name]) === null || _f === void 0 ? void 0 : _f.href);
292
+ this.mrdLoadView.emit({ name, href, viewConfig: newViewConfig });
293
+ }, onMrdAction: (e) => {
294
+ var _a, _b, _c;
295
+ e.stopPropagation();
296
+ const pl = (_a = this.viewLinksMap[name]) !== null && _a !== void 0 ? _a : {};
297
+ const href = e.detail.action === 'export' ? (_b = pl['excel']) === null || _b === void 0 ? void 0 : _b.href : (_c = pl['self']) === null || _c === void 0 ? void 0 : _c.href;
298
+ this.mrdViewAction.emit({ name, action: e.detail.action, href });
299
+ } })));
300
+ }
301
+ renderItem(item) {
302
+ var _a, _b;
303
+ switch (item.type) {
304
+ case ClientLayoutItemType.FIELD:
305
+ return this.renderField(item);
306
+ case ClientLayoutItemType.RELATION:
307
+ return this.renderRelation(item);
308
+ case ClientLayoutItemType.HEADER:
309
+ return (h("h2", { class: "mrd-layout-section__header", key: `header-${item.label}` }, item.label));
310
+ case ClientLayoutItemType.TEXT:
311
+ return h("div", { class: "mrd-layout-section__text", key: `text-${item.label}`, innerHTML: (_a = item.label) !== null && _a !== void 0 ? _a : '' });
312
+ case ClientLayoutItemType.NAVIGATE:
313
+ return (h("button", { class: "mrd-layout-section__navigate", key: `nav-${item.label}`, onClick: () => { var _a; return this.mrdNavigate.emit({ label: (_a = item.label) !== null && _a !== void 0 ? _a : '', navigate: item.navigate }); } }, item.label));
314
+ case ClientLayoutItemType.SEARCH:
315
+ return this.renderSearch(item);
316
+ case ClientLayoutItemType.SECTION:
317
+ case ClientLayoutItemType.GROUP:
318
+ 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))));
319
+ case ClientLayoutItemType.RELATED_VIEW:
320
+ case ClientLayoutItemType.VIEW:
321
+ return this.renderRelatedView(item);
322
+ default:
323
+ return null;
324
+ }
325
+ }
326
+ renderImageModal() {
327
+ if (!this.imagePreviewUrl)
328
+ return null;
329
+ return (h("div", { class: "mrd-layout-section__modal-backdrop", onClick: () => { this.imagePreviewUrl = null; } }, h("div", { class: "mrd-layout-section__modal", onClick: (e) => e.stopPropagation() }, h("button", { class: "mrd-layout-section__modal-close", onClick: () => { this.imagePreviewUrl = null; } }, "\u2715"), h("img", { class: "mrd-layout-section__modal-image", src: this.imagePreviewUrl, alt: "" }))));
330
+ }
331
+ render() {
332
+ return (h(Host, { key: 'd489c4a7810477f52ecfd664ac5d0614bef2509e' }, h("div", { key: 'e6b1478990ac8ae6adeea11adaca591b3e680e0d', class: "mrd-layout-section" }, this.items.map(item => this.renderItem(item))), this.renderImageModal()));
333
+ }
334
+ static get is() { return "mrd-layout-section"; }
335
+ static get encapsulation() { return "scoped"; }
336
+ static get originalStyleUrls() {
337
+ return {
338
+ "$": ["mrd-layout-section.scss"]
339
+ };
340
+ }
341
+ static get styleUrls() {
342
+ return {
343
+ "$": ["mrd-layout-section.css"]
344
+ };
345
+ }
346
+ static get properties() {
347
+ return {
348
+ "items": {
349
+ "type": "unknown",
350
+ "mutable": false,
351
+ "complexType": {
352
+ "original": "ClientLayoutItem[]",
353
+ "resolved": "ClientLayoutItem[]",
354
+ "references": {
355
+ "ClientLayoutItem": {
356
+ "location": "import",
357
+ "path": "../../types/client-layout",
358
+ "id": "src/types/client-layout.ts::ClientLayoutItem",
359
+ "referenceLocation": "ClientLayoutItem"
360
+ }
361
+ }
362
+ },
363
+ "required": false,
364
+ "optional": false,
365
+ "docs": {
366
+ "tags": [],
367
+ "text": "Items from one layout entry in ClientDashboardMetadata.layouts[]."
368
+ },
369
+ "getter": false,
370
+ "setter": false,
371
+ "defaultValue": "[]"
372
+ },
373
+ "data": {
374
+ "type": "unknown",
375
+ "mutable": false,
376
+ "complexType": {
377
+ "original": "Record<string, unknown>",
378
+ "resolved": "string | unknown",
379
+ "references": {
380
+ "Record": {
381
+ "location": "global",
382
+ "id": "global::Record"
383
+ }
384
+ }
385
+ },
386
+ "required": false,
387
+ "optional": false,
388
+ "docs": {
389
+ "tags": [],
390
+ "text": "Record data object; keys are field names, _links holds relation and related-view links."
391
+ },
392
+ "getter": false,
393
+ "setter": false,
394
+ "defaultValue": "{}"
395
+ },
396
+ "views": {
397
+ "type": "unknown",
398
+ "mutable": false,
399
+ "complexType": {
400
+ "original": "Record<string, ClientViewMetadata>",
401
+ "resolved": "ClientViewMetadata | string",
402
+ "references": {
403
+ "Record": {
404
+ "location": "global",
405
+ "id": "global::Record"
406
+ },
407
+ "ClientViewMetadata": {
408
+ "location": "import",
409
+ "path": "../../types/client-layout",
410
+ "id": "src/types/client-layout.ts::ClientViewMetadata",
411
+ "referenceLocation": "ClientViewMetadata"
412
+ }
413
+ }
414
+ },
415
+ "required": false,
416
+ "optional": false,
417
+ "docs": {
418
+ "tags": [],
419
+ "text": "View metadata map (ClientDashboardMetadata.views) for RELATED_VIEW and VIEW items."
420
+ },
421
+ "getter": false,
422
+ "setter": false,
423
+ "defaultValue": "{}"
424
+ },
425
+ "links": {
426
+ "type": "unknown",
427
+ "mutable": false,
428
+ "complexType": {
429
+ "original": "Record<string, { href: string }>",
430
+ "resolved": "string | { href: string; }",
431
+ "references": {
432
+ "Record": {
433
+ "location": "global",
434
+ "id": "global::Record"
435
+ }
436
+ }
437
+ },
438
+ "required": false,
439
+ "optional": false,
440
+ "docs": {
441
+ "tags": [],
442
+ "text": "Top-level _links from ClientDashboardMetadata; used to resolve hrefs for VIEW items."
443
+ },
444
+ "getter": false,
445
+ "setter": false,
446
+ "defaultValue": "{}"
447
+ },
448
+ "locale": {
449
+ "type": "string",
450
+ "mutable": false,
451
+ "complexType": {
452
+ "original": "string",
453
+ "resolved": "string",
454
+ "references": {}
455
+ },
456
+ "required": false,
457
+ "optional": false,
458
+ "docs": {
459
+ "tags": [],
460
+ "text": ""
461
+ },
462
+ "getter": false,
463
+ "setter": false,
464
+ "reflect": false,
465
+ "attribute": "locale",
466
+ "defaultValue": "navigator.language"
467
+ }
468
+ };
469
+ }
470
+ static get states() {
471
+ return {
472
+ "searchQueryMap": {},
473
+ "searchResultsMap": {},
474
+ "imagePreviewUrl": {},
475
+ "imagePreviews": {},
476
+ "activeViewMap": {}
477
+ };
478
+ }
479
+ static get events() {
480
+ return [{
481
+ "method": "mrdNavigate",
482
+ "name": "mrdNavigate",
483
+ "bubbles": true,
484
+ "cancelable": true,
485
+ "composed": true,
486
+ "docs": {
487
+ "tags": [],
488
+ "text": ""
489
+ },
490
+ "complexType": {
491
+ "original": "{ href?: string; label: string; navigate?: ClientLayoutItemNavigate }",
492
+ "resolved": "{ href?: string | undefined; label: string; navigate?: ClientLayoutItemNavigate | undefined; }",
493
+ "references": {
494
+ "ClientLayoutItemNavigate": {
495
+ "location": "import",
496
+ "path": "../../types/client-layout",
497
+ "id": "src/types/client-layout.ts::ClientLayoutItemNavigate",
498
+ "referenceLocation": "ClientLayoutItemNavigate"
499
+ }
500
+ }
501
+ }
502
+ }, {
503
+ "method": "mrdSearch",
504
+ "name": "mrdSearch",
505
+ "bubbles": true,
506
+ "cancelable": true,
507
+ "composed": true,
508
+ "docs": {
509
+ "tags": [],
510
+ "text": ""
511
+ },
512
+ "complexType": {
513
+ "original": "{ query: string; dataClass: string }",
514
+ "resolved": "{ query: string; dataClass: string; }",
515
+ "references": {}
516
+ }
517
+ }, {
518
+ "method": "mrdDownload",
519
+ "name": "mrdDownload",
520
+ "bubbles": true,
521
+ "cancelable": true,
522
+ "composed": true,
523
+ "docs": {
524
+ "tags": [],
525
+ "text": ""
526
+ },
527
+ "complexType": {
528
+ "original": "{ href: string; fileName: string }",
529
+ "resolved": "{ href: string; fileName: string; }",
530
+ "references": {}
531
+ }
532
+ }, {
533
+ "method": "mrdLoadView",
534
+ "name": "mrdLoadView",
535
+ "bubbles": true,
536
+ "cancelable": true,
537
+ "composed": true,
538
+ "docs": {
539
+ "tags": [],
540
+ "text": "Fired once on load for each RELATED_VIEW and VIEW item; host fetches page 0 and calls setViewPage()."
541
+ },
542
+ "complexType": {
543
+ "original": "{ name: string; href?: string; viewConfig: ClientViewMetadata }",
544
+ "resolved": "{ name: string; href?: string | undefined; viewConfig: ClientViewMetadata; }",
545
+ "references": {
546
+ "ClientViewMetadata": {
547
+ "location": "import",
548
+ "path": "../../types/client-layout",
549
+ "id": "src/types/client-layout.ts::ClientViewMetadata",
550
+ "referenceLocation": "ClientViewMetadata"
551
+ }
552
+ }
553
+ }
554
+ }, {
555
+ "method": "mrdLoadViewPage",
556
+ "name": "mrdLoadViewPage",
557
+ "bubbles": true,
558
+ "cancelable": true,
559
+ "composed": true,
560
+ "docs": {
561
+ "tags": [],
562
+ "text": "Re-emitted from an embedded mrd-table's mrdLoadPage; host fetches the next page and calls setViewPage()."
563
+ },
564
+ "complexType": {
565
+ "original": "{ name: string; page: number; sort: string }",
566
+ "resolved": "{ name: string; page: number; sort: string; }",
567
+ "references": {}
568
+ }
569
+ }, {
570
+ "method": "mrdLoadImage",
571
+ "name": "mrdLoadImage",
572
+ "bubbles": true,
573
+ "cancelable": true,
574
+ "composed": true,
575
+ "docs": {
576
+ "tags": [],
577
+ "text": "Fired once on load for each IMAGE field that has an href; host resolves the URL and calls setImagePreview()."
578
+ },
579
+ "complexType": {
580
+ "original": "{ fieldName: string; href: string }",
581
+ "resolved": "{ fieldName: string; href: string; }",
582
+ "references": {}
583
+ }
584
+ }, {
585
+ "method": "mrdViewAction",
586
+ "name": "mrdViewAction",
587
+ "bubbles": true,
588
+ "cancelable": true,
589
+ "composed": true,
590
+ "docs": {
591
+ "tags": [],
592
+ "text": "Re-emitted from an embedded mrd-table's mrdAction; includes the view name and resolved href."
593
+ },
594
+ "complexType": {
595
+ "original": "{ name: string; action: string; href?: string }",
596
+ "resolved": "{ name: string; action: string; href?: string | undefined; }",
597
+ "references": {}
598
+ }
599
+ }];
600
+ }
601
+ static get methods() {
602
+ return {
603
+ "setSearchResults": {
604
+ "complexType": {
605
+ "signature": "(results: RelationSearchResult[], dataClass?: string) => Promise<void>",
606
+ "parameters": [{
607
+ "name": "results",
608
+ "type": "RelationSearchResult[]",
609
+ "docs": ""
610
+ }, {
611
+ "name": "dataClass",
612
+ "type": "string | undefined",
613
+ "docs": ""
614
+ }],
615
+ "references": {
616
+ "Promise": {
617
+ "location": "global",
618
+ "id": "global::Promise"
619
+ },
620
+ "RelationSearchResult": {
621
+ "location": "import",
622
+ "path": "../../types/client-layout",
623
+ "id": "src/types/client-layout.ts::RelationSearchResult",
624
+ "referenceLocation": "RelationSearchResult"
625
+ }
626
+ },
627
+ "return": "Promise<void>"
628
+ },
629
+ "docs": {
630
+ "text": "Inject search results. Pass dataClass to target a specific SEARCH item; omit when there is only one.",
631
+ "tags": []
632
+ }
633
+ },
634
+ "setViewPage": {
635
+ "complexType": {
636
+ "signature": "(name: string, page: number, rows: any[], totalElements?: number, pageLinks?: Record<string, { href: string; }>) => Promise<void>",
637
+ "parameters": [{
638
+ "name": "name",
639
+ "type": "string",
640
+ "docs": ""
641
+ }, {
642
+ "name": "page",
643
+ "type": "number",
644
+ "docs": ""
645
+ }, {
646
+ "name": "rows",
647
+ "type": "any[]",
648
+ "docs": ""
649
+ }, {
650
+ "name": "totalElements",
651
+ "type": "number | undefined",
652
+ "docs": ""
653
+ }, {
654
+ "name": "pageLinks",
655
+ "type": "Record<string, { href: string; }> | undefined",
656
+ "docs": ""
657
+ }],
658
+ "references": {
659
+ "Promise": {
660
+ "location": "global",
661
+ "id": "global::Promise"
662
+ },
663
+ "Record": {
664
+ "location": "global",
665
+ "id": "global::Record"
666
+ }
667
+ },
668
+ "return": "Promise<void>"
669
+ },
670
+ "docs": {
671
+ "text": "Inject data into an embedded mrd-table for a RELATED_VIEW or VIEW item.\nPass totalElements on page 0 to initialise the table; omit on subsequent pages.\nPass pageLinks (_links from the page response) on page 0 to enable action hrefs in mrdViewAction.",
672
+ "tags": []
673
+ }
674
+ },
675
+ "setImagePreview": {
676
+ "complexType": {
677
+ "signature": "(fieldName: string, url: string) => Promise<void>",
678
+ "parameters": [{
679
+ "name": "fieldName",
680
+ "type": "string",
681
+ "docs": ""
682
+ }, {
683
+ "name": "url",
684
+ "type": "string",
685
+ "docs": ""
686
+ }],
687
+ "references": {
688
+ "Promise": {
689
+ "location": "global",
690
+ "id": "global::Promise"
691
+ }
692
+ },
693
+ "return": "Promise<void>"
694
+ },
695
+ "docs": {
696
+ "text": "Provide a resolved URL for an IMAGE field. Shows as thumbnail; clicking opens the lightbox.",
697
+ "tags": []
698
+ }
699
+ },
700
+ "openImagePreview": {
701
+ "complexType": {
702
+ "signature": "(url: string) => Promise<void>",
703
+ "parameters": [{
704
+ "name": "url",
705
+ "type": "string",
706
+ "docs": ""
707
+ }],
708
+ "references": {
709
+ "Promise": {
710
+ "location": "global",
711
+ "id": "global::Promise"
712
+ }
713
+ },
714
+ "return": "Promise<void>"
715
+ },
716
+ "docs": {
717
+ "text": "Open the lightbox directly with a URL (e.g. after mrdDownload on a FILE field).",
718
+ "tags": []
719
+ }
720
+ }
721
+ };
722
+ }
723
+ static get elementRef() { return "el"; }
724
+ static get watchers() {
725
+ return [{
726
+ "propName": "links",
727
+ "methodName": "linksChanged"
728
+ }, {
729
+ "propName": "data",
730
+ "methodName": "dataChanged"
731
+ }];
732
+ }
733
+ }