@mmlogic/components 0.2.0 → 0.3.1

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.
@@ -1,13 +1,16 @@
1
1
  import { EventEmitter } from '../../stencil-public-runtime';
2
- import { AlternativeView, ColumnFilter, TableAction, TableColumn } from '../../utils/cell-renderer';
3
- import { AggregationResult } from '../../types/client-layout';
2
+ import { ColumnFilter } from '../../utils/cell-renderer';
3
+ import { AggregationResult, ClientLayoutItem } from '../../types/client-layout';
4
4
  export declare class MrdTable {
5
5
  el: HTMLElement;
6
6
  private pendingPages;
7
7
  private debounceTimer;
8
8
  private outsideClickHandler;
9
9
  private keydownHandler;
10
- columns: TableColumn[];
10
+ /** The VIEW or RELATED_VIEW layout item. Contains view config, dataClass, fromClass, actions etc. */
11
+ item: ClientLayoutItem | null;
12
+ /** Parent record id — required for RELATED_VIEW to build /{fromClass}/{parentId}/{dataClass}. */
13
+ parentId: string;
11
14
  /** Direct rows (non-paginated mode, used when totalElements === 0). */
12
15
  rows: Record<string, any>[];
13
16
  locale: string;
@@ -19,19 +22,12 @@ export declare class MrdTable {
19
22
  rowHeight: number;
20
23
  /** Height of the scroll container in px. */
21
24
  tableHeight: number;
22
- /** Initial sort applied on load, e.g. "timestamp,desc" or "name".
23
- * Parsed by init() into sortField + sortDir. */
24
- defaultSort: string;
25
- /** Toolbar action buttons rendered above the table. */
26
- actions: TableAction[];
27
- /** Display label of the current view — shown in the toolbar center as a view picker trigger. */
28
- viewLabel: string;
29
- /** Alternative views available for this table; renders a dropdown when non-empty. */
30
- alternativeViews: AlternativeView[];
31
25
  /** Clamp renderEnd when totalElements shrinks (e.g. after a filter is applied). */
32
26
  totalElementsChanged(newVal: number): void;
33
- /** Apply defaultSort when the prop changes (e.g. after a view switch). */
34
- defaultSortChanged(newVal: string): void;
27
+ /** Reset to primary view when the item prop is replaced from outside. */
28
+ itemChanged(newVal: ClientLayoutItem | null): void;
29
+ /** Index into allViews[] for the currently displayed view. 0 = primary, 1+ = alternatives. */
30
+ private activeViewIdx;
35
31
  loadedPages: Map<number, Record<string, any>[]>;
36
32
  requestedPages: Set<number>;
37
33
  renderStart: number;
@@ -60,39 +56,44 @@ export declare class MrdTable {
60
56
  jsonModal: string | null;
61
57
  /** Aggregation totals received from the host via setAggregations(). Null = not yet loaded. */
62
58
  aggregations: AggregationResult | null;
59
+ /** Record count received via setAggregations().total; overrides totalElements for display. */
60
+ private aggregationsTotal;
61
+ /** True when a fresh aggregations request is needed (set on init / filter change). */
62
+ private aggregationsPending;
63
+ /** Lower bound on total derived from setPage() hasNext info; grows as pages load. */
64
+ private minKnownTotal;
63
65
  /** Fired when a page needs to be fetched. Host fetches and calls setPage().
64
66
  * `sort` is the raw query-param value, e.g. "name" or "name,desc". */
65
67
  mrdLoadPage: EventEmitter<{
66
68
  page: number;
67
69
  sort: string;
70
+ path: string;
71
+ qs: string;
68
72
  }>;
69
73
  /** Fired when a data row is clicked. Detail is the full row object including _links. */
70
74
  mrdRowClick: EventEmitter<Record<string, any>>;
71
- /** Fired when a toolbar action button is clicked. Detail contains the action identifier. */
75
+ /** Fired when a toolbar action button is clicked.
76
+ * For 'export': includes `path` (relative excel path) and `qs` (current sort+filter params).
77
+ * For 'create': includes `dataClass` (target type) and `parentPath` (e.g. /buyers/123 for RELATED_VIEW). */
72
78
  mrdAction: EventEmitter<{
73
79
  action: string;
74
- }>;
75
- /** Fired when active filters change. Host translates filters to API query params. */
76
- mrdFilter: EventEmitter<{
77
- filters: ColumnFilter[];
80
+ path?: string;
81
+ qs?: string;
82
+ dataClass?: string;
83
+ parentPath?: string | null;
78
84
  }>;
79
85
  /** Fired when a FILE or IMAGE cell is clicked. Host resolves the href to a signed download URL. */
80
86
  mrdDownload: EventEmitter<{
81
87
  href: string;
82
88
  fileName: string;
83
89
  }>;
84
- /** Fired when the user selects an alternative view from the view switcher dropdown. */
85
- mrdSwitchView: EventEmitter<{
86
- name: string;
87
- class?: string;
88
- }>;
89
90
  /** Fired when aggregation totals need to be (re-)fetched.
90
- * Detail contains the fields grouped by aggregate function.
91
+ * `aggQs` is a ready-to-use query string: active filters (no page/sort) + sum/avg/count params.
91
92
  * Host calls the /aggregations endpoint and passes the result to setAggregations(). */
92
93
  mrdLoadAggregations: EventEmitter<{
93
- sum?: string[];
94
- avg?: string[];
95
- count?: string[];
94
+ path: string;
95
+ qs: string;
96
+ aggQs: string;
96
97
  }>;
97
98
  componentWillLoad(): void;
98
99
  private applyDefaultSort;
@@ -109,17 +110,41 @@ export declare class MrdTable {
109
110
  * When the page contains fewer rows than pageSize it is the last page.
110
111
  * renderEnd is clamped immediately so no loading-placeholder rows appear
111
112
  * beyond the actual data — without requiring the host to update totalElements.
113
+ *
114
+ * Pass hasNext (from _links.next in the API response) for accurate last-page
115
+ * detection even when rows.length === pageSize (exact multiple of page size).
112
116
  */
113
- setPage(pageNumber: number, rows: Record<string, any>[]): Promise<void>;
117
+ setPage(pageNumber: number, rows: Record<string, any>[], hasNext?: boolean): Promise<void>;
114
118
  /** Inject aggregation totals returned by the /aggregations endpoint. */
115
119
  setAggregations(data: AggregationResult): Promise<void>;
116
120
  disconnectedCallback(): void;
117
121
  componentDidRender(): void;
118
122
  private visibleCount;
119
123
  private sortParam;
124
+ /** Stable ordered list: primary view first, then alternatives (from the item prop). */
125
+ private get allViews();
126
+ /** Relative excel export path for the current view.
127
+ * VIEW: /excel/{dataClass}
128
+ * RELATED_VIEW: /excel/{fromClass}/{parentId}/{dataClass} */
129
+ private buildExcelPath;
130
+ private buildActionDetail;
131
+ /** Relative data path for the current view, without query string.
132
+ * VIEW: /{dataClass}
133
+ * RELATED_VIEW: /{fromClass}/{parentId}/{dataClass} */
134
+ private buildDataPath;
135
+ /** Build query params for a page request from current sort, view filters, filterClass and active column filters. */
136
+ private buildQueryParams;
137
+ private get columns();
138
+ private get tableActions();
120
139
  private colName;
121
140
  private colDataType;
141
+ /** True when we have a reliable total: either from the aggregations response or because
142
+ * a short page told us it was the last page (exact count from row length). */
143
+ private isTotalKnown;
144
+ /** Effective total: aggregations-response > totalElements prop > minKnownTotal from setPage(). */
145
+ private get baseTotal();
122
146
  private buildAggregationParams;
147
+ private buildAggregationQs;
123
148
  private emitLoadAggregations;
124
149
  private renderAggregationValue;
125
150
  /** Reset pagination state and scroll to top (used after sort or filter change). */
@@ -7,10 +7,8 @@
7
7
  import { HTMLStencilElement, JSXBase } from "./stencil-public-runtime";
8
8
  import { ClientLayout, ClientLayoutItem, ClientLayoutItemFieldDataType, ClientLayoutItemRelationDisplayType, ClientLayoutItemRelationEditBehavior, ClientListValue, CurrencyValue, RelationSearchResult as RelationSearchResult1 } from "./types";
9
9
  import { AggregationResult, ClientLayoutItem as ClientLayoutItem1, ClientLayoutItemNavigate, ClientViewMetadata, RelationSearchResult } from "./types/client-layout";
10
- import { AlternativeView, ColumnFilter, TableAction, TableColumn } from "./utils/cell-renderer";
11
10
  export { ClientLayout, ClientLayoutItem, ClientLayoutItemFieldDataType, ClientLayoutItemRelationDisplayType, ClientLayoutItemRelationEditBehavior, ClientListValue, CurrencyValue, RelationSearchResult as RelationSearchResult1 } from "./types";
12
11
  export { AggregationResult, ClientLayoutItem as ClientLayoutItem1, ClientLayoutItemNavigate, ClientViewMetadata, RelationSearchResult } from "./types/client-layout";
13
- export { AlternativeView, ColumnFilter, TableAction, TableColumn } from "./utils/cell-renderer";
14
12
  export namespace Components {
15
13
  interface MrdBooleanField {
16
14
  /**
@@ -291,7 +289,7 @@ export namespace Components {
291
289
  */
292
290
  "items": ClientLayoutItem1[];
293
291
  /**
294
- * Top-level _links from ClientDashboardMetadata; used to resolve hrefs for VIEW items.
292
+ * Legacy: top-level _links from ClientDashboardMetadata. Not needed in new flat format.
295
293
  * @default {}
296
294
  */
297
295
  "links": Record<string, { href: string }>;
@@ -316,11 +314,11 @@ export namespace Components {
316
314
  */
317
315
  "setViewAggregations": (name: string, data: any) => Promise<void>;
318
316
  /**
319
- * Inject data into an embedded mrd-table for a RELATED_VIEW or VIEW item. Pass totalElements on page 0 to initialise the table; omit on subsequent pages. Pass pageLinks (_links from the page response) on page 0 to enable action hrefs in mrdViewAction.
317
+ * Inject data into an embedded mrd-table for a RELATED_VIEW or VIEW item. Pass totalElements to update the pagination total (safe to pass on every page). Pass hasNext (from _links.next presence) so the table can decide whether to emit aggregations.
320
318
  */
321
- "setViewPage": (name: string, page: number, rows: any[], totalElements?: number, pageLinks?: Record<string, { href: string; }>) => Promise<void>;
319
+ "setViewPage": (name: string, page: number, rows: any[], totalElements?: number, hasNext?: boolean) => Promise<void>;
322
320
  /**
323
- * View metadata map (ClientDashboardMetadata.views) for RELATED_VIEW and VIEW items.
321
+ * Legacy: view metadata map (ClientDashboardMetadata.views). Not needed in new flat format.
324
322
  * @default {}
325
323
  */
326
324
  "views": Record<string, ClientViewMetadata>;
@@ -482,29 +480,15 @@ export namespace Components {
482
480
  "value": string | string[] | RelationSearchResult1 | RelationSearchResult1[] | null;
483
481
  }
484
482
  interface MrdTable {
485
- /**
486
- * Toolbar action buttons rendered above the table.
487
- * @default []
488
- */
489
- "actions": TableAction[];
490
- /**
491
- * Alternative views available for this table; renders a dropdown when non-empty.
492
- * @default []
493
- */
494
- "alternativeViews": AlternativeView[];
495
- /**
496
- * @default []
497
- */
498
- "columns": TableColumn[];
499
- /**
500
- * Initial sort applied on load, e.g. "timestamp,desc" or "name". Parsed by init() into sortField + sortDir.
501
- * @default ''
502
- */
503
- "defaultSort": string;
504
483
  /**
505
484
  * Initialise (or reset) the virtual scroll. Call after setting all props and registering the mrdLoadPage listener, but before calling setPage(0, rows).
506
485
  */
507
486
  "init": () => Promise<void>;
487
+ /**
488
+ * The VIEW or RELATED_VIEW layout item. Contains view config, dataClass, fromClass, actions etc.
489
+ * @default null
490
+ */
491
+ "item": ClientLayoutItem1 | null;
508
492
  /**
509
493
  * @default navigator.language
510
494
  */
@@ -514,6 +498,11 @@ export namespace Components {
514
498
  * @default 20
515
499
  */
516
500
  "pageSize": number;
501
+ /**
502
+ * Parent record id — required for RELATED_VIEW to build /{fromClass}/{parentId}/{dataClass}.
503
+ * @default ''
504
+ */
505
+ "parentId": string;
517
506
  /**
518
507
  * Row height in px — used for spacer and scroll-position maths.
519
508
  * @default 36
@@ -529,9 +518,9 @@ export namespace Components {
529
518
  */
530
519
  "setAggregations": (data: AggregationResult) => Promise<void>;
531
520
  /**
532
- * Inject the rows for a given page (0-based). Creates a new Map reference so Stencil detects the state change. When the page contains fewer rows than pageSize it is the last page. renderEnd is clamped immediately so no loading-placeholder rows appear beyond the actual data — without requiring the host to update totalElements.
521
+ * Inject the rows for a given page (0-based). Creates a new Map reference so Stencil detects the state change. When the page contains fewer rows than pageSize it is the last page. renderEnd is clamped immediately so no loading-placeholder rows appear beyond the actual data — without requiring the host to update totalElements. Pass hasNext (from _links.next in the API response) for accurate last-page detection even when rows.length === pageSize (exact multiple of page size).
533
522
  */
534
- "setPage": (pageNumber: number, rows: Record<string, any>[]) => Promise<void>;
523
+ "setPage": (pageNumber: number, rows: Record<string, any>[], hasNext?: boolean) => Promise<void>;
535
524
  /**
536
525
  * Height of the scroll container in px.
537
526
  * @default 500
@@ -542,11 +531,6 @@ export namespace Components {
542
531
  * @default 0
543
532
  */
544
533
  "totalElements": number;
545
- /**
546
- * Display label of the current view — shown in the toolbar center as a view picker trigger.
547
- * @default ''
548
- */
549
- "viewLabel": string;
550
534
  }
551
535
  interface MrdTextField {
552
536
  /**
@@ -904,11 +888,10 @@ declare global {
904
888
  "mrdNavigate": { href?: string; label: string; navigate?: ClientLayoutItemNavigate };
905
889
  "mrdSearch": { query: string; dataClass: string };
906
890
  "mrdDownload": { href: string; fileName: string };
907
- "mrdLoadView": { name: string; href?: string; viewConfig: ClientViewMetadata; sort: string; filters: ColumnFilter[] };
908
- "mrdLoadViewPage": { name: string; page: number; sort: string; filters: ColumnFilter[] };
891
+ "mrdLoadViewPage": { name: string; page: number; sort: string; path: string; qs: string };
909
892
  "mrdLoadImage": { fieldName: string; href: string };
910
- "mrdViewAction": { name: string; action: string; href?: string };
911
- "mrdLoadViewAggregations": { name: string; href?: string; filters: ColumnFilter[]; sum?: string[]; avg?: string[]; count?: string[] };
893
+ "mrdViewAction": { name: string; action: string; dataClass: string; path?: string; qs?: string; parentPath?: string | null };
894
+ "mrdLoadViewAggregations": { name: string; dataClass: string; path: string; qs: string; aggQs: string };
912
895
  }
913
896
  interface HTMLMrdLayoutSectionElement extends Components.MrdLayoutSection, HTMLStencilElement {
914
897
  addEventListener<K extends keyof HTMLMrdLayoutSectionElementEventMap>(type: K, listener: (this: HTMLMrdLayoutSectionElement, ev: MrdLayoutSectionCustomEvent<HTMLMrdLayoutSectionElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
@@ -999,13 +982,11 @@ declare global {
999
982
  new (): HTMLMrdRelationFieldElement;
1000
983
  };
1001
984
  interface HTMLMrdTableElementEventMap {
1002
- "mrdLoadPage": { page: number; sort: string };
985
+ "mrdLoadPage": { page: number; sort: string; path: string; qs: string };
1003
986
  "mrdRowClick": Record<string, any>;
1004
- "mrdAction": { action: string };
1005
- "mrdFilter": { filters: ColumnFilter[] };
987
+ "mrdAction": { action: string; path?: string; qs?: string; dataClass?: string; parentPath?: string | null };
1006
988
  "mrdDownload": { href: string; fileName: string };
1007
- "mrdSwitchView": { name: string; class?: string };
1008
- "mrdLoadAggregations": { sum?: string[]; avg?: string[]; count?: string[] };
989
+ "mrdLoadAggregations": { path: string; qs: string; aggQs: string };
1009
990
  }
1010
991
  interface HTMLMrdTableElement extends Components.MrdTable, HTMLStencilElement {
1011
992
  addEventListener<K extends keyof HTMLMrdTableElementEventMap>(type: K, listener: (this: HTMLMrdTableElement, ev: MrdTableCustomEvent<HTMLMrdTableElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
@@ -1410,7 +1391,7 @@ declare namespace LocalJSX {
1410
1391
  */
1411
1392
  "items"?: ClientLayoutItem1[];
1412
1393
  /**
1413
- * Top-level _links from ClientDashboardMetadata; used to resolve hrefs for VIEW items.
1394
+ * Legacy: top-level _links from ClientDashboardMetadata. Not needed in new flat format.
1414
1395
  * @default {}
1415
1396
  */
1416
1397
  "links"?: Record<string, { href: string }>;
@@ -1423,26 +1404,22 @@ declare namespace LocalJSX {
1423
1404
  * Fired once on load for each IMAGE field that has an href; host resolves the URL and calls setImagePreview().
1424
1405
  */
1425
1406
  "onMrdLoadImage"?: (event: MrdLayoutSectionCustomEvent<{ fieldName: string; href: string }>) => void;
1426
- /**
1427
- * Fired once on load for each RELATED_VIEW and VIEW item; host fetches page 0 and calls setViewPage().
1428
- */
1429
- "onMrdLoadView"?: (event: MrdLayoutSectionCustomEvent<{ name: string; href?: string; viewConfig: ClientViewMetadata; sort: string; filters: ColumnFilter[] }>) => void;
1430
1407
  /**
1431
1408
  * Re-emitted from an embedded mrd-table's mrdLoadAggregations; host calls setViewAggregations() with the result.
1432
1409
  */
1433
- "onMrdLoadViewAggregations"?: (event: MrdLayoutSectionCustomEvent<{ name: string; href?: string; filters: ColumnFilter[]; sum?: string[]; avg?: string[]; count?: string[] }>) => void;
1410
+ "onMrdLoadViewAggregations"?: (event: MrdLayoutSectionCustomEvent<{ name: string; dataClass: string; path: string; qs: string; aggQs: string }>) => void;
1434
1411
  /**
1435
1412
  * Re-emitted from an embedded mrd-table's mrdLoadPage; host fetches the next page and calls setViewPage().
1436
1413
  */
1437
- "onMrdLoadViewPage"?: (event: MrdLayoutSectionCustomEvent<{ name: string; page: number; sort: string; filters: ColumnFilter[] }>) => void;
1414
+ "onMrdLoadViewPage"?: (event: MrdLayoutSectionCustomEvent<{ name: string; page: number; sort: string; path: string; qs: string }>) => void;
1438
1415
  "onMrdNavigate"?: (event: MrdLayoutSectionCustomEvent<{ href?: string; label: string; navigate?: ClientLayoutItemNavigate }>) => void;
1439
1416
  "onMrdSearch"?: (event: MrdLayoutSectionCustomEvent<{ query: string; dataClass: string }>) => void;
1440
1417
  /**
1441
- * Re-emitted from an embedded mrd-table's mrdAction; includes the view name and resolved href.
1418
+ * Re-emitted from an embedded mrd-table's mrdAction; host builds the target URL from dataClass.
1442
1419
  */
1443
- "onMrdViewAction"?: (event: MrdLayoutSectionCustomEvent<{ name: string; action: string; href?: string }>) => void;
1420
+ "onMrdViewAction"?: (event: MrdLayoutSectionCustomEvent<{ name: string; action: string; dataClass: string; path?: string; qs?: string; parentPath?: string | null }>) => void;
1444
1421
  /**
1445
- * View metadata map (ClientDashboardMetadata.views) for RELATED_VIEW and VIEW items.
1422
+ * Legacy: view metadata map (ClientDashboardMetadata.views). Not needed in new flat format.
1446
1423
  * @default {}
1447
1424
  */
1448
1425
  "views"?: Record<string, ClientViewMetadata>;
@@ -1612,61 +1589,44 @@ declare namespace LocalJSX {
1612
1589
  }
1613
1590
  interface MrdTable {
1614
1591
  /**
1615
- * Toolbar action buttons rendered above the table.
1616
- * @default []
1617
- */
1618
- "actions"?: TableAction[];
1619
- /**
1620
- * Alternative views available for this table; renders a dropdown when non-empty.
1621
- * @default []
1622
- */
1623
- "alternativeViews"?: AlternativeView[];
1624
- /**
1625
- * @default []
1626
- */
1627
- "columns"?: TableColumn[];
1628
- /**
1629
- * Initial sort applied on load, e.g. "timestamp,desc" or "name". Parsed by init() into sortField + sortDir.
1630
- * @default ''
1592
+ * The VIEW or RELATED_VIEW layout item. Contains view config, dataClass, fromClass, actions etc.
1593
+ * @default null
1631
1594
  */
1632
- "defaultSort"?: string;
1595
+ "item"?: ClientLayoutItem1 | null;
1633
1596
  /**
1634
1597
  * @default navigator.language
1635
1598
  */
1636
1599
  "locale"?: string;
1637
1600
  /**
1638
- * Fired when a toolbar action button is clicked. Detail contains the action identifier.
1601
+ * Fired when a toolbar action button is clicked. For 'export': includes `path` (relative excel path) and `qs` (current sort+filter params). For 'create': includes `dataClass` (target type) and `parentPath` (e.g. /buyers/123 for RELATED_VIEW).
1639
1602
  */
1640
- "onMrdAction"?: (event: MrdTableCustomEvent<{ action: string }>) => void;
1603
+ "onMrdAction"?: (event: MrdTableCustomEvent<{ action: string; path?: string; qs?: string; dataClass?: string; parentPath?: string | null }>) => void;
1641
1604
  /**
1642
1605
  * Fired when a FILE or IMAGE cell is clicked. Host resolves the href to a signed download URL.
1643
1606
  */
1644
1607
  "onMrdDownload"?: (event: MrdTableCustomEvent<{ href: string; fileName: string }>) => void;
1645
1608
  /**
1646
- * Fired when active filters change. Host translates filters to API query params.
1647
- */
1648
- "onMrdFilter"?: (event: MrdTableCustomEvent<{ filters: ColumnFilter[] }>) => void;
1649
- /**
1650
- * Fired when aggregation totals need to be (re-)fetched. Detail contains the fields grouped by aggregate function. Host calls the /aggregations endpoint and passes the result to setAggregations().
1609
+ * Fired when aggregation totals need to be (re-)fetched. `aggQs` is a ready-to-use query string: active filters (no page/sort) + sum/avg/count params. Host calls the /aggregations endpoint and passes the result to setAggregations().
1651
1610
  */
1652
- "onMrdLoadAggregations"?: (event: MrdTableCustomEvent<{ sum?: string[]; avg?: string[]; count?: string[] }>) => void;
1611
+ "onMrdLoadAggregations"?: (event: MrdTableCustomEvent<{ path: string; qs: string; aggQs: string }>) => void;
1653
1612
  /**
1654
1613
  * Fired when a page needs to be fetched. Host fetches and calls setPage(). `sort` is the raw query-param value, e.g. "name" or "name,desc".
1655
1614
  */
1656
- "onMrdLoadPage"?: (event: MrdTableCustomEvent<{ page: number; sort: string }>) => void;
1615
+ "onMrdLoadPage"?: (event: MrdTableCustomEvent<{ page: number; sort: string; path: string; qs: string }>) => void;
1657
1616
  /**
1658
1617
  * Fired when a data row is clicked. Detail is the full row object including _links.
1659
1618
  */
1660
1619
  "onMrdRowClick"?: (event: MrdTableCustomEvent<Record<string, any>>) => void;
1661
- /**
1662
- * Fired when the user selects an alternative view from the view switcher dropdown.
1663
- */
1664
- "onMrdSwitchView"?: (event: MrdTableCustomEvent<{ name: string; class?: string }>) => void;
1665
1620
  /**
1666
1621
  * Records per page (must match the API page size).
1667
1622
  * @default 20
1668
1623
  */
1669
1624
  "pageSize"?: number;
1625
+ /**
1626
+ * Parent record id — required for RELATED_VIEW to build /{fromClass}/{parentId}/{dataClass}.
1627
+ * @default ''
1628
+ */
1629
+ "parentId"?: string;
1670
1630
  /**
1671
1631
  * Row height in px — used for spacer and scroll-position maths.
1672
1632
  * @default 36
@@ -1687,11 +1647,6 @@ declare namespace LocalJSX {
1687
1647
  * @default 0
1688
1648
  */
1689
1649
  "totalElements"?: number;
1690
- /**
1691
- * Display label of the current view — shown in the toolbar center as a view picker trigger.
1692
- * @default ''
1693
- */
1694
- "viewLabel"?: string;
1695
1650
  }
1696
1651
  interface MrdTextField {
1697
1652
  /**
@@ -1909,13 +1864,12 @@ declare namespace LocalJSX {
1909
1864
  "value": string | string[] | RelationSearchResult | RelationSearchResult[] | null;
1910
1865
  }
1911
1866
  interface MrdTableAttributes {
1867
+ "parentId": string;
1912
1868
  "locale": string;
1913
1869
  "totalElements": number;
1914
1870
  "pageSize": number;
1915
1871
  "rowHeight": number;
1916
1872
  "tableHeight": number;
1917
- "defaultSort": string;
1918
- "viewLabel": string;
1919
1873
  }
1920
1874
  interface MrdTextFieldAttributes {
1921
1875
  "name": string;
@@ -94,11 +94,13 @@ export interface ClientLayoutItemField {
94
94
  /** Aggregate function to render in the table totals row. */
95
95
  aggregate?: 'sum' | 'avg' | 'count' | null;
96
96
  }
97
- /** Response shape from the /aggregations endpoint. */
97
+ /** Response shape from the /aggregations endpoint.
98
+ * `count` is a plain number (total record count) when returned at the top level. */
98
99
  export interface AggregationResult {
100
+ total?: number;
101
+ count?: number | Record<string, number>;
99
102
  sum?: Record<string, number>;
100
103
  avg?: Record<string, number>;
101
- count?: Record<string, number>;
102
104
  }
103
105
  export interface ClientLayoutItemRelation {
104
106
  name: string;
@@ -119,12 +121,6 @@ export interface ClientLayoutItemNavigate {
119
121
  icon?: string | null;
120
122
  navigationType?: string | null;
121
123
  }
122
- export interface ClientLayoutItemView {
123
- /** Key into the `views` map of DashboardMetadata. */
124
- name: string;
125
- dataClass: string;
126
- showTitle: boolean;
127
- }
128
124
  export interface ClientLayoutItemRelatedView {
129
125
  name: string;
130
126
  fromClass?: string | null;
@@ -152,16 +148,19 @@ export interface ClientLayoutItem {
152
148
  relation?: ClientLayoutItemRelation;
153
149
  items?: ClientLayoutItem[];
154
150
  navigate?: ClientLayoutItemNavigate;
155
- view?: ClientLayoutItemView;
151
+ view?: ClientViewMetadata;
156
152
  relatedView?: ClientLayoutItemRelatedView;
157
153
  relatedObject?: ClientLayoutItemRelatedObject;
158
154
  search?: ClientLayoutItemSearch;
159
155
  name?: string;
160
156
  showTitle?: boolean;
157
+ /** Embedded alternative view configs (new flat format). */
161
158
  alternativeViews?: Array<{
162
- name: string;
163
159
  label?: string;
164
- class?: string;
160
+ dataClass?: string;
161
+ fromClass?: string | null;
162
+ filterClass?: string | null;
163
+ view?: ClientViewMetadata;
165
164
  }>;
166
165
  /** Toolbar buttons for embedded views. null/omitted = ["NEW","EXPORT"]; [] = none. */
167
166
  actions?: string[] | null;
@@ -199,6 +198,11 @@ export interface ClientLayout {
199
198
  tabPage?: boolean;
200
199
  items: ClientLayoutItem[];
201
200
  }
201
+ export interface ViewFilter {
202
+ name: string;
203
+ value?: string | null;
204
+ operator?: 'EQUALS' | 'FROM' | 'TO' | 'STARTS_WITH' | 'NOT_EMPTY' | 'EMPTY' | null;
205
+ }
202
206
  export interface ClientViewMetadata {
203
207
  name: string | null;
204
208
  defaultView: boolean;
@@ -206,11 +210,7 @@ export interface ClientViewMetadata {
206
210
  /** Column definitions — each item is a FIELD or RELATION item. */
207
211
  values: ClientLayoutItem[];
208
212
  /** Static query-param filters baked into the view definition. */
209
- filter?: Array<{
210
- name: string;
211
- value?: string | null;
212
- operator?: 'EQUALS' | 'FROM' | 'TO' | 'STARTS_WITH' | 'NOT_EMPTY' | 'EMPTY' | null;
213
- }> | null;
213
+ filter?: ViewFilter[] | null;
214
214
  type?: string;
215
215
  referenceType?: string | null;
216
216
  filterType?: string | null;
@@ -219,7 +219,8 @@ export interface ClientViewMetadata {
219
219
  }
220
220
  export interface ClientDashboardMetadata {
221
221
  layouts: ClientLayout[];
222
- views: Record<string, ClientViewMetadata>;
222
+ /** Legacy: view metadata map keyed by generated name. Absent in new flat format. */
223
+ views?: Record<string, ClientViewMetadata>;
223
224
  layoutType: ClientLayoutType;
224
225
  _links?: Record<string, {
225
226
  href: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmlogic/components",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Stencil.js web component library for dynamic forms and virtual-scroll data tables",
5
5
  "license": "MIT",
6
6
  "author": "Mosterd",