@mmlogic/components 0.3.8 → 0.3.10

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 (82) hide show
  1. package/dist/cjs/index.cjs.js +13 -0
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/mosterdcomponents.cjs.js +1 -1
  4. package/dist/cjs/{mrd-boolean-field_20.cjs.entry.js → mrd-boolean-field_23.cjs.entry.js} +1059 -23
  5. package/dist/collection/collection-manifest.json +3 -0
  6. package/dist/collection/components/mrd-boolean-field/mrd-boolean-field.js +1 -1
  7. package/dist/collection/components/mrd-currency-field/mrd-currency-field.js +1 -1
  8. package/dist/collection/components/mrd-date-field/mrd-date-field.js +1 -1
  9. package/dist/collection/components/mrd-datetime-field/mrd-datetime-field.js +1 -1
  10. package/dist/collection/components/mrd-document-container/mrd-document-container.js +375 -0
  11. package/dist/collection/components/mrd-document-container/mrd-document-container.scss +79 -0
  12. package/dist/collection/components/mrd-document-list/mrd-document-list.js +1129 -0
  13. package/dist/collection/components/mrd-document-list/mrd-document-list.scss +181 -0
  14. package/dist/collection/components/mrd-document-view/mrd-document-view.js +177 -0
  15. package/dist/collection/components/mrd-document-view/mrd-document-view.scss +121 -0
  16. package/dist/collection/components/mrd-email-field/mrd-email-field.js +1 -1
  17. package/dist/collection/components/mrd-file-field/mrd-file-field.js +1 -1
  18. package/dist/collection/components/mrd-image-field/mrd-image-field.js +1 -1
  19. package/dist/collection/components/mrd-layout-section/mrd-layout-section.js +288 -14
  20. package/dist/collection/components/mrd-layout-section/mrd-layout-section.scss +2 -3
  21. package/dist/collection/components/mrd-longtext-field/mrd-longtext-field.js +1 -1
  22. package/dist/collection/components/mrd-number-field/mrd-number-field.js +1 -1
  23. package/dist/collection/components/mrd-secret-field/mrd-secret-field.js +2 -2
  24. package/dist/collection/components/mrd-text-field/mrd-text-field.js +1 -1
  25. package/dist/collection/components/mrd-textarea-field/mrd-textarea-field.js +1 -1
  26. package/dist/collection/components/mrd-time-field/mrd-time-field.js +1 -1
  27. package/dist/collection/dev/app.js +66 -2
  28. package/dist/collection/types/client-layout.js +10 -0
  29. package/dist/collection/utils/i18n.js +34 -0
  30. package/dist/components/client-layout.js +1 -1
  31. package/dist/components/format.js +1 -1
  32. package/dist/components/i18n.js +1 -1
  33. package/dist/components/index.js +1 -1
  34. package/dist/components/mrd-boolean-field2.js +1 -1
  35. package/dist/components/mrd-currency-field2.js +1 -1
  36. package/dist/components/mrd-date-field2.js +1 -1
  37. package/dist/components/mrd-datetime-field2.js +1 -1
  38. package/dist/components/mrd-document-container.d.ts +11 -0
  39. package/dist/components/mrd-document-container.js +1 -0
  40. package/dist/components/mrd-document-container2.js +1 -0
  41. package/dist/components/mrd-document-list.d.ts +11 -0
  42. package/dist/components/mrd-document-list.js +1 -0
  43. package/dist/components/mrd-document-list2.js +1 -0
  44. package/dist/components/mrd-document-view.d.ts +11 -0
  45. package/dist/components/mrd-document-view.js +1 -0
  46. package/dist/components/mrd-document-view2.js +1 -0
  47. package/dist/components/mrd-email-field2.js +1 -1
  48. package/dist/components/mrd-file-field2.js +1 -1
  49. package/dist/components/mrd-image-field2.js +1 -1
  50. package/dist/components/mrd-layout-section.js +1 -1
  51. package/dist/components/mrd-longtext-field2.js +1 -1
  52. package/dist/components/mrd-number-field2.js +1 -1
  53. package/dist/components/mrd-secret-field2.js +1 -1
  54. package/dist/components/mrd-table2.js +1 -1
  55. package/dist/components/mrd-text-field2.js +1 -1
  56. package/dist/components/mrd-textarea-field2.js +1 -1
  57. package/dist/components/mrd-time-field2.js +1 -1
  58. package/dist/esm/index.js +11 -1
  59. package/dist/esm/loader.js +1 -1
  60. package/dist/esm/mosterdcomponents.js +1 -1
  61. package/dist/esm/{mrd-boolean-field_20.entry.js → mrd-boolean-field_23.entry.js} +1058 -25
  62. package/dist/mosterdcomponents/{cell-renderer-CbRwLOo8.js.map → cell-renderer-B-AJDBcj.js.map} +1 -1
  63. package/dist/mosterdcomponents/{client-layout-D88nn5zf.js.map → client-layout-ChqRA3AF.js.map} +1 -1
  64. package/dist/mosterdcomponents/i18n-s1XrKcD2.js.map +1 -0
  65. package/dist/mosterdcomponents/index-DkY-NQj0.js.map +1 -0
  66. package/dist/mosterdcomponents/index-DwF_Sp__.js.map +1 -0
  67. package/dist/mosterdcomponents/index.esm.js +1 -1
  68. package/dist/mosterdcomponents/mosterdcomponents.css +1 -1
  69. package/dist/mosterdcomponents/mosterdcomponents.esm.js +1 -1
  70. package/dist/mosterdcomponents/p-69452249.entry.js +1 -0
  71. package/dist/mosterdcomponents/{validation-ixb43cqU.js.map → validation-Br9k2Ztw.js.map} +1 -1
  72. package/dist/types/components/mrd-document-container/mrd-document-container.d.ts +94 -0
  73. package/dist/types/components/mrd-document-list/mrd-document-list.d.ts +210 -0
  74. package/dist/types/components/mrd-document-view/mrd-document-view.d.ts +36 -0
  75. package/dist/types/components/mrd-layout-section/mrd-layout-section.d.ts +57 -6
  76. package/dist/types/components.d.ts +507 -15
  77. package/dist/types/types/client-layout.d.ts +38 -0
  78. package/package.json +1 -1
  79. package/dist/mosterdcomponents/i18n-hoGGKbKU.js.map +0 -1
  80. package/dist/mosterdcomponents/index-6yQUNVww.js.map +0 -1
  81. package/dist/mosterdcomponents/index-I5SuYv7a.js.map +0 -1
  82. package/dist/mosterdcomponents/p-7bfaee51.entry.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"validation-ixb43cqU.js","sources":["src/utils/validation.ts"],"sourcesContent":["import { ClientLayoutItemFieldDataType } from '../types';\n\nexport function validateRequired(value: unknown): boolean {\n if (value === null || value === undefined) return false;\n if (typeof value === 'string') return value.trim().length > 0;\n if (Array.isArray(value)) return value.length > 0;\n if (typeof value === 'object') {\n // HyperlinkValue check\n const hv = value as { href?: unknown };\n if ('href' in hv) return typeof hv.href === 'string' && hv.href.trim().length > 0;\n // CurrencyValue check\n const cv = value as { amount?: unknown };\n if ('amount' in cv) return cv.amount !== null && cv.amount !== undefined && cv.amount !== '';\n }\n return true;\n}\n\nexport function validateEmail(value: string): boolean {\n if (!value) return true;\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value);\n}\n\nexport function validateUrl(value: string): boolean {\n if (!value) return true;\n try {\n const url = new URL(value);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\nexport function validateNumber(value: unknown, dataType: ClientLayoutItemFieldDataType): boolean {\n if (value === null || value === undefined || value === '') return true;\n const num = Number(value);\n if (isNaN(num)) return false;\n if (dataType === ClientLayoutItemFieldDataType.INTEGER) {\n return Number.isInteger(num);\n }\n if (dataType === ClientLayoutItemFieldDataType.PERCENTAGE) {\n return num >= 0 && num <= 100;\n }\n return true;\n}\n"],"names":[],"mappings":";;;AAEM,SAAU,gBAAgB,CAAC,KAAc,EAAA;AAC7C,IAAA,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;AAAE,QAAA,OAAO,KAAK;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;AAC7D,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC;AACjD,IAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;;QAE7B,MAAM,EAAE,GAAG,KAA2B;QACtC,IAAI,MAAM,IAAI,EAAE;AAAE,YAAA,OAAO,OAAO,EAAE,CAAC,IAAI,KAAK,QAAQ,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;;QAEjF,MAAM,EAAE,GAAG,KAA6B;QACxC,IAAI,QAAQ,IAAI,EAAE;AAAE,YAAA,OAAO,EAAE,CAAC,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,CAAC,MAAM,KAAK,EAAE;;AAE9F,IAAA,OAAO,IAAI;AACb;AAEM,SAAU,aAAa,CAAC,KAAa,EAAA;AACzC,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,IAAI;AACvB,IAAA,OAAO,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC;AACjD;AAEM,SAAU,WAAW,CAAC,KAAa,EAAA;AACvC,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,IAAI;AACvB,IAAA,IAAI;AACF,QAAA,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC;QAC1B,OAAO,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;;IAC5D,OAAA,EAAA,EAAM;AACN,QAAA,OAAO,KAAK;;AAEhB;AAEM,SAAU,cAAc,CAAC,KAAc,EAAE,QAAuC,EAAA;IACpF,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;AAAE,QAAA,OAAO,IAAI;AACtE,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;IACzB,IAAI,KAAK,CAAC,GAAG,CAAC;AAAE,QAAA,OAAO,KAAK;AAC5B,IAAA,IAAI,QAAQ,KAAK,6BAA6B,CAAC,OAAO,EAAE;AACtD,QAAA,OAAO,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC;;AAE9B,IAAA,IAAI,QAAQ,KAAK,6BAA6B,CAAC,UAAU,EAAE;AACzD,QAAA,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG;;AAE/B,IAAA,OAAO,IAAI;AACb;;;;"}
1
+ {"version":3,"file":"validation-Br9k2Ztw.js","sources":["src/utils/validation.ts"],"sourcesContent":["import { ClientLayoutItemFieldDataType } from '../types';\n\nexport function validateRequired(value: unknown): boolean {\n if (value === null || value === undefined) return false;\n if (typeof value === 'string') return value.trim().length > 0;\n if (Array.isArray(value)) return value.length > 0;\n if (typeof value === 'object') {\n // HyperlinkValue check\n const hv = value as { href?: unknown };\n if ('href' in hv) return typeof hv.href === 'string' && hv.href.trim().length > 0;\n // CurrencyValue check\n const cv = value as { amount?: unknown };\n if ('amount' in cv) return cv.amount !== null && cv.amount !== undefined && cv.amount !== '';\n }\n return true;\n}\n\nexport function validateEmail(value: string): boolean {\n if (!value) return true;\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value);\n}\n\nexport function validateUrl(value: string): boolean {\n if (!value) return true;\n try {\n const url = new URL(value);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\nexport function validateNumber(value: unknown, dataType: ClientLayoutItemFieldDataType): boolean {\n if (value === null || value === undefined || value === '') return true;\n const num = Number(value);\n if (isNaN(num)) return false;\n if (dataType === ClientLayoutItemFieldDataType.INTEGER) {\n return Number.isInteger(num);\n }\n if (dataType === ClientLayoutItemFieldDataType.PERCENTAGE) {\n return num >= 0 && num <= 100;\n }\n return true;\n}\n"],"names":[],"mappings":";;;AAEM,SAAU,gBAAgB,CAAC,KAAc,EAAA;AAC7C,IAAA,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;AAAE,QAAA,OAAO,KAAK;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;AAC7D,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC;AACjD,IAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;;QAE7B,MAAM,EAAE,GAAG,KAA2B;QACtC,IAAI,MAAM,IAAI,EAAE;AAAE,YAAA,OAAO,OAAO,EAAE,CAAC,IAAI,KAAK,QAAQ,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;;QAEjF,MAAM,EAAE,GAAG,KAA6B;QACxC,IAAI,QAAQ,IAAI,EAAE;AAAE,YAAA,OAAO,EAAE,CAAC,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,CAAC,MAAM,KAAK,EAAE;;AAE9F,IAAA,OAAO,IAAI;AACb;AAEM,SAAU,aAAa,CAAC,KAAa,EAAA;AACzC,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,IAAI;AACvB,IAAA,OAAO,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC;AACjD;AAEM,SAAU,WAAW,CAAC,KAAa,EAAA;AACvC,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,IAAI;AACvB,IAAA,IAAI;AACF,QAAA,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC;QAC1B,OAAO,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;;IAC5D,OAAA,EAAA,EAAM;AACN,QAAA,OAAO,KAAK;;AAEhB;AAEM,SAAU,cAAc,CAAC,KAAc,EAAE,QAAuC,EAAA;IACpF,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;AAAE,QAAA,OAAO,IAAI;AACtE,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;IACzB,IAAI,KAAK,CAAC,GAAG,CAAC;AAAE,QAAA,OAAO,KAAK;AAC5B,IAAA,IAAI,QAAQ,KAAK,6BAA6B,CAAC,OAAO,EAAE;AACtD,QAAA,OAAO,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC;;AAE9B,IAAA,IAAI,QAAQ,KAAK,6BAA6B,CAAC,UAAU,EAAE;AACzD,QAAA,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG;;AAE/B,IAAA,OAAO,IAAI;AACb;;;;"}
@@ -0,0 +1,94 @@
1
+ import { EventEmitter } from '../../stencil-public-runtime';
2
+ import { ClientArchetype, ClientLayoutItem } from '../../types/client-layout';
3
+ /**
4
+ * Owns a document collection view: a single toolbar (view switch + collection
5
+ * actions like "New folder", and — later — upload / drag-drop) plus the two
6
+ * interchangeable bodies, the folder tree (`mrd-document-list`) and the flat
7
+ * table (`mrd-table`).
8
+ *
9
+ * `mrd-layout-section` renders one of these per document VIEW / RELATED_VIEW and
10
+ * forwards the re-emitted load/navigate/action events to the host. The embedded
11
+ * table/list keep their `data-view` / `data-doclist` attributes so the host's
12
+ * existing `setViewPage` / `setViewDistinct` / `setViewAggregations` lookups
13
+ * (recursive querySelector) still resolve them unchanged.
14
+ */
15
+ export declare class MrdDocumentContainer {
16
+ el: HTMLElement;
17
+ /** The VIEW or RELATED_VIEW layout item (dataClass, fromClass, view config). */
18
+ item: ClientLayoutItem | null;
19
+ /** Resolved `commons.document` archetype binding for the folder tree. */
20
+ archetype: ClientArchetype;
21
+ /** Parent record id — required for RELATED_VIEW path building. */
22
+ parentId: string;
23
+ /** Lookup key used for the embedded `data-doclist` / `data-view` attributes. */
24
+ viewKey: string;
25
+ locale: string;
26
+ /** Re-emitted from the embedded list/table. `nodeId` present for a folder load. */
27
+ mrdLoadPage: EventEmitter<{
28
+ page: number;
29
+ sort: string;
30
+ path: string;
31
+ qs: string;
32
+ nodeId?: string;
33
+ }>;
34
+ /** Re-emitted from the embedded folder tree. */
35
+ mrdLoadDistinct: EventEmitter<{
36
+ nodeId: string;
37
+ distinct: string;
38
+ path: string;
39
+ qs: string;
40
+ }>;
41
+ /** Re-emitted from the embedded table. */
42
+ mrdLoadAggregations: EventEmitter<{
43
+ path: string;
44
+ qs: string;
45
+ aggQs: string;
46
+ }>;
47
+ /** A row / document was activated. Host routes to the object page. */
48
+ mrdNavigate: EventEmitter<{
49
+ href?: string;
50
+ label: string;
51
+ }>;
52
+ /** A table toolbar action was triggered. */
53
+ mrdAction: EventEmitter<{
54
+ action: string;
55
+ path?: string;
56
+ qs?: string;
57
+ parentPath?: string | null;
58
+ basicType?: string;
59
+ }>;
60
+ /** Generic "update an existing object" request, re-emitted from the folder tree
61
+ * (a document was dragged into another folder/container). */
62
+ mrdUpdateObject: EventEmitter<{
63
+ href: string;
64
+ values: Record<string, unknown>;
65
+ }>;
66
+ /** An external file was dropped on a folder; host uploads and calls back. */
67
+ mrdUpload: EventEmitter<{
68
+ file: File;
69
+ }>;
70
+ /** Create a new document from an uploaded file; host POSTs `values` to `path`. */
71
+ mrdCreateObject: EventEmitter<{
72
+ path: string;
73
+ values: Record<string, unknown>;
74
+ }>;
75
+ /** Active body: folder tree or flat table. */
76
+ private mode;
77
+ /** Whether the folder tree currently has a valid target for "New folder". */
78
+ private canCreate;
79
+ private listEl?;
80
+ private tableEl?;
81
+ /** Whether the currently mounted table has been init()'d. Reset on every mode switch. */
82
+ private tableInited;
83
+ /** The embedded table does not self-load: like every mrd-table it waits for the
84
+ * host to call init() (which emits mrdLoadPage, and — once page 0 lands —
85
+ * mrdLoadAggregations). The section only init()s tables mounted at load time, so
86
+ * when the user switches to list view we init the freshly mounted table here. */
87
+ componentDidRender(): void;
88
+ private setMode;
89
+ private createFolder;
90
+ private renderToolbar;
91
+ private renderTree;
92
+ private renderList;
93
+ render(): any;
94
+ }
@@ -0,0 +1,210 @@
1
+ import { EventEmitter } from '../../stencil-public-runtime';
2
+ import { ClientArchetype, ClientLayoutItem } from '../../types/client-layout';
3
+ /** A distinct value as returned by the /distinct endpoint. */
4
+ export interface DistinctValue {
5
+ /** Relation slot → `{ href, name }`; value slot (folder) → the raw path string. */
6
+ value: {
7
+ href: string;
8
+ name: string;
9
+ } | string | number | null;
10
+ count: number;
11
+ }
12
+ /** A loaded document row (raw data object from the /data endpoint). */
13
+ export type DocRow = Record<string, any>;
14
+ /**
15
+ * Archetype-driven document collection view. Renders documents as a lazy,
16
+ * file-explorer-style folder tree, grouped by the `commons.document` archetype's
17
+ * `container` (dossier, the top folder) and `folder` (a path string like
18
+ * `/draft documents/may 2020`, the sub-path beneath it).
19
+ *
20
+ * Loading is lazy per level, mirroring the /distinct endpoint (FINDING-0106):
21
+ * - on load → `mrdLoadDistinct` for the `container` relation → top folders;
22
+ * - on expanding a container → `mrdLoadDistinct` for the `folder` field, filtered
23
+ * by `{containerField}_href` → all folder path strings for that container
24
+ * (the client splits them on `/` and builds the sub-tree locally);
25
+ * - on expanding a node that holds documents → `mrdLoadPage` (a plain filtered list
26
+ * load, the same one a table page uses), filtered by container + exact folder string.
27
+ *
28
+ * When exactly one container exists (e.g. a dossier detail page) the container
29
+ * level is hidden and its folder tree is shown directly at the root.
30
+ */
31
+ export declare class MrdDocumentList {
32
+ el: HTMLElement;
33
+ /** The VIEW or RELATED_VIEW layout item (dataClass, fromClass, view config). */
34
+ item: ClientLayoutItem | null;
35
+ /** Resolved `commons.document` binding: slot name → concrete field/relation name. */
36
+ archetype: ClientArchetype;
37
+ /** Parent record id — required for RELATED_VIEW path building. */
38
+ parentId: string;
39
+ locale: string;
40
+ /** Request distinct values for a field/relation. Host fetches `{path}?{qs}` and calls `setDistinct(nodeId, values)`. */
41
+ mrdLoadDistinct: EventEmitter<{
42
+ nodeId: string;
43
+ distinct: string;
44
+ path: string;
45
+ qs: string;
46
+ }>;
47
+ /** Request the documents in one folder — the same filtered list load a table does.
48
+ * Host fetches `{path}?{qs}` and calls `setDocuments(nodeId, docs)` (via setViewPage). */
49
+ mrdLoadPage: EventEmitter<{
50
+ nodeId: string;
51
+ page: number;
52
+ sort: string;
53
+ path: string;
54
+ qs: string;
55
+ }>;
56
+ /** A document row was clicked. Host routes to the document object page. */
57
+ mrdNavigate: EventEmitter<{
58
+ href?: string;
59
+ label: string;
60
+ }>;
61
+ /** Emitted whenever the "can create a folder here" state changes, so a host
62
+ * toolbar (mrd-document-container) can enable/disable its New folder button. */
63
+ mrdCanCreate: EventEmitter<boolean>;
64
+ /** Generic "update an existing object" request — fired when a document is
65
+ * dragged into another folder/container. Host PATCHes `href` with `values`
66
+ * (no move/folder knowledge needed). `values` carries the new folder string
67
+ * (or null for the container root) and, on a cross-container move, the new
68
+ * container relation href. */
69
+ mrdUpdateObject: EventEmitter<{
70
+ href: string;
71
+ values: Record<string, unknown>;
72
+ }>;
73
+ /** An external file was dropped onto a folder/container. Same flow as mrd-form:
74
+ * host uploads the file and calls `setFileReference(uri)` with the result. */
75
+ mrdUpload: EventEmitter<{
76
+ file: File;
77
+ }>;
78
+ /** Fired once the dropped file is uploaded — requests creation of a new document.
79
+ * Host POSTs `values` to `path` (on a 400 it can open the create form itself). */
80
+ mrdCreateObject: EventEmitter<{
81
+ path: string;
82
+ values: Record<string, unknown>;
83
+ }>;
84
+ /** Root sentinel id for the container-level distinct request. */
85
+ private static readonly ROOT;
86
+ private containers;
87
+ private rootLoading;
88
+ /** True when the single-container level is collapsed away (dossier context). */
89
+ private singleContainer;
90
+ /** Currently selected node id — the target for "New folder" and (later) drops. */
91
+ private selectedId;
92
+ /** Node id currently highlighted as a drag-drop target (null = none). */
93
+ private dropTargetId;
94
+ /** Node id showing an "uploading…" indicator while a dropped file is processed. */
95
+ private uploadingNodeId;
96
+ private nodeIndex;
97
+ /** The pending node whose inline name input is open (null = not creating). */
98
+ private pendingNode;
99
+ /** The node the pending folder is being created under. */
100
+ private pendingParent;
101
+ /** The container the pending folder belongs to. */
102
+ private pendingContainer;
103
+ /** Current text in the inline name input. */
104
+ private pendingName;
105
+ /** Ref to the inline input, so we can focus it after it mounts. */
106
+ private pendingInputEl;
107
+ /** Set when a fresh input needs focus on the next render. */
108
+ private pendingNeedsFocus;
109
+ /** Monotonic counter for unique temporary pending-node ids. */
110
+ private newFolderSeq;
111
+ /** Last emitted canCreateFolder value, to only emit mrdCanCreate on change. */
112
+ private lastCanCreate;
113
+ /** The document row currently being dragged. */
114
+ private dragDoc;
115
+ /** Id of the node the dragged document currently lives in. */
116
+ private dragFromId;
117
+ /** External file dropped onto a node, awaiting its upload to complete. */
118
+ private pendingUpload;
119
+ /** The optimistic document row awaiting its self href from the create POST. */
120
+ private lastOptimisticDoc;
121
+ componentDidLoad(): void;
122
+ componentDidRender(): void;
123
+ private get containerField();
124
+ private get folderField();
125
+ private get titleField();
126
+ private get fileField();
127
+ private get dateField();
128
+ /** VIEW: `/{dataClass}`; RELATED_VIEW: `/{fromClass}/{parentId}/{dataClass}`. */
129
+ private buildDataPath;
130
+ /** View-level static filters + filterClass, shared by every request. */
131
+ private baseParams;
132
+ private emitContainerDistinct;
133
+ private emitFolderDistinct;
134
+ private emitDocuments;
135
+ /** Inject distinct values for a node. `nodeId` is the sentinel root (containers)
136
+ * or a container node id (folders). */
137
+ setDistinct(nodeId: string, values: DistinctValue[]): Promise<void>;
138
+ /** Inject the documents loaded for one folder node. */
139
+ setDocuments(nodeId: string, docs: DocRow[]): Promise<void>;
140
+ private applyContainers;
141
+ private applyFolders;
142
+ /** Normalise a folder path: null/""/"/" → root ([]); else split on "/" dropping empties. */
143
+ private splitFolder;
144
+ private makeContainerNode;
145
+ private makeFolderNode;
146
+ private computeTotals;
147
+ /** Force a re-render after mutating nodes in place. */
148
+ private bump;
149
+ private toggleContainer;
150
+ private toggleFolder;
151
+ /** Resolve the node a new folder should be created under, and its container.
152
+ * Uses the current selection; falls back to the single container (dossier). */
153
+ private resolveTarget;
154
+ private get canCreateFolder();
155
+ /** Start creating a folder under the current target. Called by the host toolbar
156
+ * (mrd-document-container). No-op when there is no valid target. */
157
+ createFolder(): Promise<void>;
158
+ /** Folder path segments of a node relative to its container (derived from its id). */
159
+ private segmentsOf;
160
+ private startCreateFolder;
161
+ private onPendingInput;
162
+ private onPendingKeyDown;
163
+ private commitFolder;
164
+ private cancelFolder;
165
+ private clearPending;
166
+ private onDocDragStart;
167
+ private onDocDragEnd;
168
+ /** True when the drag carries external files (an OS file drop, not an internal move). */
169
+ private isFileDrag;
170
+ /** A folder/container node (or a document inside it) accepts an internal move
171
+ * or an external file drop. Always claims the event so it never bubbles to the
172
+ * root drop-zone; a different node is highlighted (its own folder = no-op). */
173
+ private onNodeDragOver;
174
+ private onNodeDragLeave;
175
+ private onNodeDrop;
176
+ /** Root-zone drop (dossier context): target the single container's root. */
177
+ private onRootDragOver;
178
+ private onRootDrop;
179
+ /** Begin an upload: emit mrdUpload; the host uploads and calls setFileReference. */
180
+ private startFileUpload;
181
+ /** Strip a single trailing extension for the document title. */
182
+ private stripExtension;
183
+ /** Host callback with the uploaded file reference. Builds the create payload
184
+ * from the archetype slots and requests the new document. */
185
+ setFileReference(uri: string): Promise<void>;
186
+ /** Host callback with the created document's self href, so the optimistic row
187
+ * becomes navigable without waiting for a reload. */
188
+ setCreatedHref(href: string): Promise<void>;
189
+ /** Folder string a node represents: the raw distinct value when it holds
190
+ * documents, else derived from its path segments; null for a container root. */
191
+ private folderStringOf;
192
+ private moveDocument;
193
+ /** Recompute a container's subtree totals from docCounts when its folders are
194
+ * loaded; otherwise just nudge the aggregate badge by the delta. */
195
+ private recomputeContainerTotals;
196
+ private openDoc;
197
+ private renderChevron;
198
+ private renderDossierIcon;
199
+ private renderFolderIcon;
200
+ private renderDocIcon;
201
+ private indent;
202
+ private renderDocRow;
203
+ private renderLoadingRow;
204
+ private renderChildren;
205
+ private renderUploadingRow;
206
+ private renderFolderEditRow;
207
+ private renderFolderNode;
208
+ private renderContainerNode;
209
+ render(): any;
210
+ }
@@ -0,0 +1,36 @@
1
+ import { EventEmitter } from '../../stencil-public-runtime';
2
+ import { ClientArchetype } from '../../types/client-layout';
3
+ /**
4
+ * Archetype-driven single-document view. Given a `commons.document` binding and a
5
+ * data record, renders the document recognisably — title, file preview/download,
6
+ * summary and date — plus a navigation link to the container (the dossier),
7
+ * instead of a generic field form.
8
+ *
9
+ * The component keys on the slot→field map (`archetype.slots`) to locate values:
10
+ * value slots read `data[field]`; the `container` relation slot reads
11
+ * `data._links[field]` (`{ href, name }`). Empty slots are omitted.
12
+ */
13
+ export declare class MrdDocumentView {
14
+ /** Resolved `commons.document` binding: slot name → concrete field/relation name. */
15
+ archetype: ClientArchetype;
16
+ /** The data record from the /data endpoint. Fields keyed by name; relations under `_links`. */
17
+ data: Record<string, unknown>;
18
+ locale: string;
19
+ /** Navigate to the container (dossier). Host resolves the href and routes. */
20
+ mrdNavigate: EventEmitter<{
21
+ href?: string;
22
+ label: string;
23
+ }>;
24
+ /** Download the document file. Host resolves the href to a signed URL. */
25
+ mrdDownload: EventEmitter<{
26
+ href: string;
27
+ fileName: string;
28
+ }>;
29
+ /** Value of a value-slot: reads data[field] via the slot→field map. */
30
+ private slotValue;
31
+ /** Relation link for a relation-slot: reads data._links[field]. */
32
+ private slotLink;
33
+ private renderContainer;
34
+ private renderFile;
35
+ render(): any;
36
+ }
@@ -1,5 +1,6 @@
1
1
  import { EventEmitter } from '../../stencil-public-runtime';
2
- import { ClientLayoutItem, ClientLayoutItemNavigate, ClientViewMetadata, RelationSearchResult } from '../../types/client-layout';
2
+ import { ClientLayoutItem, ClientLayoutItemNavigate, ClientViewMetadata, ClientArchetype, RelationSearchResult } from '../../types/client-layout';
3
+ import { DistinctValue } from '../mrd-document-list/mrd-document-list';
3
4
  export declare class MrdLayoutSection {
4
5
  el: HTMLElement;
5
6
  /** Items from one layout entry in ClientDashboardMetadata.layouts[]. */
@@ -13,6 +14,9 @@ export declare class MrdLayoutSection {
13
14
  href: string;
14
15
  }>;
15
16
  locale: string;
17
+ /** Top-level archetypes on the object dashboard. When it contains commons.document,
18
+ * the record is rendered as a single-document view instead of generic fields. */
19
+ archetypes: ClientArchetype[];
16
20
  private searchQueryMap;
17
21
  private searchResultsMap;
18
22
  private imagePreviewUrl;
@@ -32,13 +36,15 @@ export declare class MrdLayoutSection {
32
36
  href: string;
33
37
  fileName: string;
34
38
  }>;
35
- /** Re-emitted from an embedded mrd-table's mrdLoadPage; host fetches the next page and calls setViewPage(). */
39
+ /** Re-emitted from an embedded mrd-table's or mrd-document-list's mrdLoadPage; host fetches the
40
+ * rows and calls setViewPage(). `nodeId` is present for a document-list folder load. */
36
41
  mrdLoadViewPage: EventEmitter<{
37
42
  name: string;
38
43
  page: number;
39
44
  sort: string;
40
45
  path: string;
41
46
  qs: string;
47
+ nodeId?: string;
42
48
  }>;
43
49
  /** Fired once on load for each IMAGE field that has an href; host resolves the URL and calls setImagePreview(). */
44
50
  mrdLoadImage: EventEmitter<{
@@ -63,6 +69,33 @@ export declare class MrdLayoutSection {
63
69
  qs: string;
64
70
  aggQs: string;
65
71
  }>;
72
+ /** Re-emitted from an embedded mrd-document-list's mrdLoadDistinct; host fetches distinct values and calls setViewDistinct(). */
73
+ mrdLoadViewDistinct: EventEmitter<{
74
+ name: string;
75
+ nodeId: string;
76
+ distinct: string;
77
+ path: string;
78
+ qs: string;
79
+ }>;
80
+ /** Generic "update an existing object" request from an embedded document view
81
+ * (a document dragged into another folder). Host PATCHes `href` with `values`. */
82
+ mrdUpdateObject: EventEmitter<{
83
+ href: string;
84
+ values: Record<string, unknown>;
85
+ }>;
86
+ /** An external file was dropped on a document view; host uploads and calls
87
+ * setViewFileReference(name, uri). */
88
+ mrdViewUpload: EventEmitter<{
89
+ name: string;
90
+ file: File;
91
+ }>;
92
+ /** Create a new document from an uploaded file; host POSTs `values` to `path`,
93
+ * then calls setViewCreatedObject(name, href) with the new object's href. */
94
+ mrdCreateObject: EventEmitter<{
95
+ name: string;
96
+ path: string;
97
+ values: Record<string, unknown>;
98
+ }>;
66
99
  private searchTimers;
67
100
  componentDidLoad(): void;
68
101
  disconnectedCallback(): void;
@@ -74,13 +107,22 @@ export declare class MrdLayoutSection {
74
107
  /** Inject search results. Pass dataClass to target a specific SEARCH item; omit when there is only one. */
75
108
  setSearchResults(results: RelationSearchResult[], dataClass?: string): Promise<void>;
76
109
  /**
77
- * Inject data into an embedded mrd-table for a RELATED_VIEW or VIEW item.
78
- * Pass totalElements to update the pagination total (safe to pass on every page).
79
- * Pass hasNext (from _links.next presence) so the table can decide whether to emit aggregations.
110
+ * Inject rows for a VIEW / RELATED_VIEW item.
111
+ * - Table view: injects the page into the embedded mrd-table (pass totalElements/hasNext).
112
+ * - Document view: pass `nodeId` to route the rows to that folder node in the embedded
113
+ * mrd-document-list. Folder loading is just a filtered list load, so it reuses this method.
80
114
  */
81
- setViewPage(name: string, page: number, rows: any[], totalElements?: number, hasNext?: boolean): Promise<void>;
115
+ setViewPage(name: string, page: number, rows: any[], totalElements?: number, hasNext?: boolean, nodeId?: string): Promise<void>;
82
116
  /** Inject aggregation totals into an embedded mrd-table for a VIEW or RELATED_VIEW item. */
83
117
  setViewAggregations(name: string, data: any): Promise<void>;
118
+ /** Inject distinct values into an embedded mrd-document-list for a document view. */
119
+ setViewDistinct(name: string, nodeId: string, values: DistinctValue[]): Promise<void>;
120
+ /** Inject the uploaded file reference for a dropped file, so the document view
121
+ * can request creation of the new document (see mrdViewUpload). */
122
+ setViewFileReference(name: string, uri: string): Promise<void>;
123
+ /** Inject the created document's href after a file-drop create, so the
124
+ * optimistic row becomes navigable (see mrdCreateObject). */
125
+ setViewCreatedObject(name: string, href: string): Promise<void>;
84
126
  /** Provide a resolved URL for an IMAGE field. Shows as thumbnail; clicking opens the lightbox. */
85
127
  setImagePreview(fieldName: string, url: string): Promise<void>;
86
128
  /** Open the lightbox directly with a URL (e.g. after mrdDownload on a FILE field). */
@@ -95,7 +137,16 @@ export declare class MrdLayoutSection {
95
137
  private renderRelation;
96
138
  private renderSearch;
97
139
  private renderRelatedView;
140
+ /** Document collection view: owns the view-switch + collection actions and
141
+ * swaps between the folder tree and the flat table. Events are re-emitted to
142
+ * the host with the view key, exactly as the raw list/table events were. */
143
+ private renderDocumentContainer;
144
+ private renderTable;
98
145
  private renderItem;
99
146
  private renderImageModal;
147
+ /** Single-document view: the record's own type carries commons.document. Renders
148
+ * a recognisable document instead of generic fields, keeping any related views/
149
+ * searches below it. */
150
+ private renderDocumentObject;
100
151
  render(): any;
101
152
  }