@ngbplatform/ui 1.3.0

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 (217) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +44 -0
  3. package/package.json +61 -0
  4. package/public/favicon.svg +6 -0
  5. package/public/silent-check-sso.html +8 -0
  6. package/src/assets/ngb_logo.svg +17 -0
  7. package/src/assets/ngb_logo_color.svg +17 -0
  8. package/src/index.ts +1023 -0
  9. package/src/ngb/README.md +27 -0
  10. package/src/ngb/accounting/NgbAccountingPeriodClosingPage.vue +1157 -0
  11. package/src/ngb/accounting/NgbChartOfAccountEditor.vue +590 -0
  12. package/src/ngb/accounting/NgbChartOfAccountsPage.vue +420 -0
  13. package/src/ngb/accounting/NgbGeneralJournalEntryEditPage.vue +796 -0
  14. package/src/ngb/accounting/NgbGeneralJournalEntryLinesEditor.vue +454 -0
  15. package/src/ngb/accounting/NgbGeneralJournalEntryListPage.vue +186 -0
  16. package/src/ngb/accounting/api.ts +79 -0
  17. package/src/ngb/accounting/generalJournalEntry.ts +127 -0
  18. package/src/ngb/accounting/generalJournalEntryApi.ts +112 -0
  19. package/src/ngb/accounting/generalJournalEntryTypes.ts +155 -0
  20. package/src/ngb/accounting/navigation.ts +83 -0
  21. package/src/ngb/accounting/periodClosing.ts +75 -0
  22. package/src/ngb/accounting/periodClosingApi.ts +60 -0
  23. package/src/ngb/accounting/periodClosingTypes.ts +73 -0
  24. package/src/ngb/accounting/types.ts +57 -0
  25. package/src/ngb/api/audit.ts +23 -0
  26. package/src/ngb/api/catalogs.ts +50 -0
  27. package/src/ngb/api/contracts.ts +285 -0
  28. package/src/ngb/api/documents.ts +170 -0
  29. package/src/ngb/api/http.ts +446 -0
  30. package/src/ngb/api/lookups.ts +14 -0
  31. package/src/ngb/api/types.ts +6 -0
  32. package/src/ngb/auth/index.ts +13 -0
  33. package/src/ngb/auth/keycloak.ts +374 -0
  34. package/src/ngb/auth/router.ts +35 -0
  35. package/src/ngb/auth/types.ts +12 -0
  36. package/src/ngb/auth/useAuthStore.ts +209 -0
  37. package/src/ngb/command-palette/NgbCommandPaletteDialog.vue +342 -0
  38. package/src/ngb/command-palette/NgbCommandPaletteEmptyState.vue +55 -0
  39. package/src/ngb/command-palette/NgbCommandPaletteFooterHints.vue +29 -0
  40. package/src/ngb/command-palette/api.ts +10 -0
  41. package/src/ngb/command-palette/config.ts +16 -0
  42. package/src/ngb/command-palette/presentation.ts +85 -0
  43. package/src/ngb/command-palette/search.ts +130 -0
  44. package/src/ngb/command-palette/staticItems.ts +243 -0
  45. package/src/ngb/command-palette/storage.ts +45 -0
  46. package/src/ngb/command-palette/store.ts +716 -0
  47. package/src/ngb/command-palette/types.ts +120 -0
  48. package/src/ngb/command-palette/useCommandPaletteHotkeys.ts +27 -0
  49. package/src/ngb/command-palette/useCommandPalettePageContext.ts +18 -0
  50. package/src/ngb/components/NgbConfirmDialog.vue +63 -0
  51. package/src/ngb/components/NgbDialog.vue +44 -0
  52. package/src/ngb/components/NgbDrawer.vue +156 -0
  53. package/src/ngb/components/NgbHeaderActionCluster.vue +140 -0
  54. package/src/ngb/components/NgbModalShell.vue +99 -0
  55. package/src/ngb/components/NgbToolbar.vue +14 -0
  56. package/src/ngb/components/forms/NgbFormLayout.vue +13 -0
  57. package/src/ngb/components/forms/NgbFormRow.vue +21 -0
  58. package/src/ngb/components/forms/NgbFormSection.vue +16 -0
  59. package/src/ngb/components/forms/NgbValidationSummary.vue +18 -0
  60. package/src/ngb/components/navigation/NgbNavigationTree.vue +68 -0
  61. package/src/ngb/components/navigation/NgbTreeNode.vue +94 -0
  62. package/src/ngb/components/register/NgbColumnChooser.vue +101 -0
  63. package/src/ngb/components/register/NgbRegisterGrid.vue +473 -0
  64. package/src/ngb/components/register/registerTypes.ts +51 -0
  65. package/src/ngb/components/register/useRegisterColumnResize.ts +99 -0
  66. package/src/ngb/components/register/useRegisterColumnState.ts +220 -0
  67. package/src/ngb/components/register/useRegisterRows.ts +209 -0
  68. package/src/ngb/components/register/useRegisterViewport.ts +56 -0
  69. package/src/ngb/editor/NgbDocumentEffectsPage.vue +512 -0
  70. package/src/ngb/editor/NgbDocumentFlowPage.vue +409 -0
  71. package/src/ngb/editor/NgbDocumentPrintPage.vue +712 -0
  72. package/src/ngb/editor/NgbEditorDiscardDialog.vue +40 -0
  73. package/src/ngb/editor/NgbEntityAuditSidebar.vue +288 -0
  74. package/src/ngb/editor/NgbEntityEditor.vue +250 -0
  75. package/src/ngb/editor/NgbEntityEditorDrawerActions.vue +88 -0
  76. package/src/ngb/editor/NgbEntityEditorHeader.vue +114 -0
  77. package/src/ngb/editor/catalogNavigation.ts +13 -0
  78. package/src/ngb/editor/config.ts +252 -0
  79. package/src/ngb/editor/documentCopyDraft.ts +245 -0
  80. package/src/ngb/editor/documentEffects.ts +43 -0
  81. package/src/ngb/editor/documentEffectsDateFormatting.ts +18 -0
  82. package/src/ngb/editor/documentNavigation.ts +115 -0
  83. package/src/ngb/editor/documentStatus.ts +45 -0
  84. package/src/ngb/editor/entityEditorErrors.ts +162 -0
  85. package/src/ngb/editor/entityEditorPersistence.ts +241 -0
  86. package/src/ngb/editor/extensions.ts +40 -0
  87. package/src/ngb/editor/types.ts +295 -0
  88. package/src/ngb/editor/useConfiguredEntityEditorDocumentActions.ts +183 -0
  89. package/src/ngb/editor/useDocumentEditorDrawerState.ts +152 -0
  90. package/src/ngb/editor/useEditorDrawerState.ts +88 -0
  91. package/src/ngb/editor/useEntityEditorBusinessContext.ts +97 -0
  92. package/src/ngb/editor/useEntityEditorCapabilities.ts +190 -0
  93. package/src/ngb/editor/useEntityEditorCommandPalette.ts +154 -0
  94. package/src/ngb/editor/useEntityEditorCommitHandlers.ts +102 -0
  95. package/src/ngb/editor/useEntityEditorHeaderActions.ts +253 -0
  96. package/src/ngb/editor/useEntityEditorLeaveGuard.ts +66 -0
  97. package/src/ngb/editor/useEntityEditorNavigationActions.ts +235 -0
  98. package/src/ngb/editor/useEntityEditorOutputs.ts +59 -0
  99. package/src/ngb/editor/useEntityEditorPageActions.ts +57 -0
  100. package/src/ngb/editor/useRouteQueryEditorDrawer.ts +173 -0
  101. package/src/ngb/env/runtimeConfig.ts +25 -0
  102. package/src/ngb/lookup/config.ts +42 -0
  103. package/src/ngb/lookup/defaultConfig.ts +136 -0
  104. package/src/ngb/lookup/navigation.ts +76 -0
  105. package/src/ngb/lookup/prefetch.ts +40 -0
  106. package/src/ngb/lookup/store.ts +261 -0
  107. package/src/ngb/metadata/NgbDocumentListFiltersDrawer.vue +78 -0
  108. package/src/ngb/metadata/NgbDocumentPeriodFilter.vue +53 -0
  109. package/src/ngb/metadata/NgbEntityForm.vue +84 -0
  110. package/src/ngb/metadata/NgbEntityFormFieldsBlock.vue +110 -0
  111. package/src/ngb/metadata/NgbEntityListPageHeader.vue +80 -0
  112. package/src/ngb/metadata/NgbFilterFieldControl.vue +104 -0
  113. package/src/ngb/metadata/NgbMetadataCatalogEditPage.vue +42 -0
  114. package/src/ngb/metadata/NgbMetadataCatalogListPage.vue +269 -0
  115. package/src/ngb/metadata/NgbMetadataDocumentEditPage.vue +68 -0
  116. package/src/ngb/metadata/NgbMetadataDocumentListPage.vue +353 -0
  117. package/src/ngb/metadata/NgbMetadataFieldRenderer.vue +124 -0
  118. package/src/ngb/metadata/NgbMetadataLookupControl.vue +92 -0
  119. package/src/ngb/metadata/NgbRecycleBinFilter.vue +53 -0
  120. package/src/ngb/metadata/NgbRegisterPageLayout.vue +143 -0
  121. package/src/ngb/metadata/config.ts +28 -0
  122. package/src/ngb/metadata/dataTypes.ts +27 -0
  123. package/src/ngb/metadata/entityForm.ts +114 -0
  124. package/src/ngb/metadata/entityModel.ts +34 -0
  125. package/src/ngb/metadata/entityValueFormatting.ts +83 -0
  126. package/src/ngb/metadata/fieldRendererState.ts +84 -0
  127. package/src/ngb/metadata/filtering.ts +153 -0
  128. package/src/ngb/metadata/lookup.ts +25 -0
  129. package/src/ngb/metadata/monthPagedListQuery.ts +108 -0
  130. package/src/ngb/metadata/normalization.ts +100 -0
  131. package/src/ngb/metadata/referenceHydration.ts +99 -0
  132. package/src/ngb/metadata/register.ts +135 -0
  133. package/src/ngb/metadata/routePages.ts +86 -0
  134. package/src/ngb/metadata/store.ts +35 -0
  135. package/src/ngb/metadata/types.ts +276 -0
  136. package/src/ngb/metadata/useMetadataListFilters.ts +306 -0
  137. package/src/ngb/metadata/useMetadataRegisterPageData.ts +246 -0
  138. package/src/ngb/metadata/useValidationFocus.ts +49 -0
  139. package/src/ngb/primitives/NgbBadge.vue +31 -0
  140. package/src/ngb/primitives/NgbButton.vue +53 -0
  141. package/src/ngb/primitives/NgbCheckbox.vue +33 -0
  142. package/src/ngb/primitives/NgbDatePicker.vue +141 -0
  143. package/src/ngb/primitives/NgbIcon.vue +545 -0
  144. package/src/ngb/primitives/NgbInput.vue +57 -0
  145. package/src/ngb/primitives/NgbLookup.vue +264 -0
  146. package/src/ngb/primitives/NgbMonthPicker.vue +132 -0
  147. package/src/ngb/primitives/NgbMultiSelect.vue +179 -0
  148. package/src/ngb/primitives/NgbPeriodPicker.vue +125 -0
  149. package/src/ngb/primitives/NgbPickerNavButton.vue +31 -0
  150. package/src/ngb/primitives/NgbPickerPopover.vue +79 -0
  151. package/src/ngb/primitives/NgbRadioGroup.vue +53 -0
  152. package/src/ngb/primitives/NgbSelect.vue +108 -0
  153. package/src/ngb/primitives/NgbStatusIcon.vue +63 -0
  154. package/src/ngb/primitives/NgbSwitch.vue +42 -0
  155. package/src/ngb/primitives/NgbTabs.vue +116 -0
  156. package/src/ngb/primitives/NgbToastHost.vue +49 -0
  157. package/src/ngb/primitives/NgbTooltip.vue +27 -0
  158. package/src/ngb/primitives/iconNames.ts +83 -0
  159. package/src/ngb/primitives/toast.ts +66 -0
  160. package/src/ngb/primitives/useAsyncComboboxQuery.ts +85 -0
  161. package/src/ngb/primitives/useFloatingDropdownPosition.ts +129 -0
  162. package/src/ngb/reporting/NgbReportComposerCollectionSection.vue +106 -0
  163. package/src/ngb/reporting/NgbReportComposerPanel.vue +1187 -0
  164. package/src/ngb/reporting/NgbReportDateRangeFilter.vue +54 -0
  165. package/src/ngb/reporting/NgbReportPage.vue +1124 -0
  166. package/src/ngb/reporting/NgbReportSheet.vue +467 -0
  167. package/src/ngb/reporting/api.ts +35 -0
  168. package/src/ngb/reporting/composer.ts +904 -0
  169. package/src/ngb/reporting/config.ts +120 -0
  170. package/src/ngb/reporting/defaultConfig.ts +15 -0
  171. package/src/ngb/reporting/lookupFilters.ts +43 -0
  172. package/src/ngb/reporting/navigation.ts +181 -0
  173. package/src/ngb/reporting/pageHelpers.ts +73 -0
  174. package/src/ngb/reporting/pageSession.ts +92 -0
  175. package/src/ngb/reporting/paging.ts +66 -0
  176. package/src/ngb/reporting/types.ts +333 -0
  177. package/src/ngb/router/backNavigation.ts +122 -0
  178. package/src/ngb/router/queryParams.ts +129 -0
  179. package/src/ngb/router/queryState.ts +121 -0
  180. package/src/ngb/router/routeAliases.ts +66 -0
  181. package/src/ngb/router/routeParams.ts +15 -0
  182. package/src/ngb/router/shareLink.ts +39 -0
  183. package/src/ngb/security/NgbAccessAuditPanel.vue +32 -0
  184. package/src/ngb/security/NgbAccessDeniedState.vue +27 -0
  185. package/src/ngb/security/NgbEffectiveAccessPanel.vue +60 -0
  186. package/src/ngb/security/NgbPermissionMatrix.vue +160 -0
  187. package/src/ngb/security/NgbRoleEditorPage.vue +319 -0
  188. package/src/ngb/security/NgbRolesPage.vue +125 -0
  189. package/src/ngb/security/NgbUserEditorPage.vue +615 -0
  190. package/src/ngb/security/NgbUsersPage.vue +125 -0
  191. package/src/ngb/security/api.ts +91 -0
  192. package/src/ngb/security/audit.ts +21 -0
  193. package/src/ngb/security/permissions.ts +65 -0
  194. package/src/ngb/security/types.ts +157 -0
  195. package/src/ngb/security/useAccessStore.ts +69 -0
  196. package/src/ngb/site/NgbDashboardAsOfToolbar.vue +100 -0
  197. package/src/ngb/site/NgbDashboardStatusBanner.vue +91 -0
  198. package/src/ngb/site/NgbLogo.vue +44 -0
  199. package/src/ngb/site/NgbPageHeader.vue +49 -0
  200. package/src/ngb/site/NgbSiteShell.vue +286 -0
  201. package/src/ngb/site/NgbSiteSidebar.vue +270 -0
  202. package/src/ngb/site/NgbTopBar.vue +425 -0
  203. package/src/ngb/site/NgbTrendChart.vue +224 -0
  204. package/src/ngb/site/dashboardData.ts +324 -0
  205. package/src/ngb/site/mainMenuStore.ts +49 -0
  206. package/src/ngb/site/types.ts +31 -0
  207. package/src/ngb/site/useDashboardPageState.ts +98 -0
  208. package/src/ngb/site/useTheme.ts +95 -0
  209. package/src/ngb/utils/clone.ts +43 -0
  210. package/src/ngb/utils/dateValues.ts +107 -0
  211. package/src/ngb/utils/errorMessage.ts +14 -0
  212. package/src/ngb/utils/guid.ts +21 -0
  213. package/src/ngb/utils/stableValue.ts +21 -0
  214. package/src/ngb/utils/storage.ts +135 -0
  215. package/src/styles/tailwind.css +165 -0
  216. package/src/vite/publicAssets.ts +104 -0
  217. package/vite-public-assets.js +68 -0
@@ -0,0 +1,333 @@
1
+ import type { LookupItem, LookupSource } from '../metadata/types'
2
+
3
+ export enum ReportAggregationKind {
4
+ Sum = 1,
5
+ Min = 2,
6
+ Max = 3,
7
+ Average = 4,
8
+ Count = 5,
9
+ CountDistinct = 6,
10
+ First = 7,
11
+ Last = 8,
12
+ }
13
+
14
+ export enum ReportExecutionMode {
15
+ Canonical = 1,
16
+ Composable = 2,
17
+ }
18
+
19
+ export enum ReportFieldKind {
20
+ Attribute = 1,
21
+ Dimension = 2,
22
+ Time = 3,
23
+ Detail = 4,
24
+ System = 5,
25
+ }
26
+
27
+ export enum ReportTimeGrain {
28
+ Day = 1,
29
+ Week = 2,
30
+ Month = 3,
31
+ Quarter = 4,
32
+ Year = 5,
33
+ }
34
+
35
+ export enum ReportSortDirection {
36
+ Asc = 1,
37
+ Desc = 2,
38
+ }
39
+
40
+ export enum ReportRowKind {
41
+ Header = 1,
42
+ Group = 2,
43
+ Detail = 3,
44
+ Subtotal = 4,
45
+ Total = 5,
46
+ }
47
+
48
+ export type ReportCapabilitiesDto = {
49
+ allowsFilters?: boolean
50
+ allowsRowGroups?: boolean
51
+ allowsColumnGroups?: boolean
52
+ allowsMeasures?: boolean
53
+ allowsDetailFields?: boolean
54
+ allowsSorting?: boolean
55
+ allowsShowDetails?: boolean
56
+ allowsSubtotals?: boolean
57
+ allowsSeparateRowSubtotals?: boolean
58
+ allowsGrandTotals?: boolean
59
+ allowsVariants?: boolean
60
+ allowsXlsxExport?: boolean
61
+ maxRowGroupDepth?: number | null
62
+ maxColumnGroupDepth?: number | null
63
+ maxVisibleColumns?: number | null
64
+ maxVisibleRows?: number | null
65
+ maxRenderedCells?: number | null
66
+ }
67
+
68
+ export type ReportPresentationDto = {
69
+ initialPageSize?: number | null
70
+ rowNoun?: string | null
71
+ emptyStateMessage?: string | null
72
+ }
73
+
74
+ export type ReportFieldDto = {
75
+ code: string
76
+ label: string
77
+ dataType: string
78
+ kind: ReportFieldKind
79
+ isFilterable?: boolean
80
+ isGroupable?: boolean
81
+ isSortable?: boolean
82
+ isSelectable?: boolean
83
+ supportsIncludeDescendants?: boolean
84
+ defaultIncludeDescendants?: boolean
85
+ supportedTimeGrains?: ReportTimeGrain[] | null
86
+ lookup?: LookupSource | null
87
+ description?: string | null
88
+ format?: string | null
89
+ }
90
+
91
+ export type ReportMeasureDto = {
92
+ code: string
93
+ label: string
94
+ dataType: string
95
+ supportedAggregations?: ReportAggregationKind[] | null
96
+ format?: string | null
97
+ description?: string | null
98
+ }
99
+
100
+ export type ReportDatasetDto = {
101
+ datasetCode: string
102
+ fields?: ReportFieldDto[] | null
103
+ measures?: ReportMeasureDto[] | null
104
+ }
105
+
106
+ export type ReportParameterMetadataDto = {
107
+ code: string
108
+ dataType: string
109
+ isRequired: boolean
110
+ description?: string | null
111
+ defaultValue?: string | null
112
+ label?: string | null
113
+ }
114
+
115
+ export type ReportFilterOptionDto = {
116
+ value: string
117
+ label: string
118
+ }
119
+
120
+ export type ReportFilterFieldDto = {
121
+ fieldCode: string
122
+ label: string
123
+ dataType: string
124
+ isRequired?: boolean
125
+ isMulti?: boolean
126
+ supportsIncludeDescendants?: boolean
127
+ defaultIncludeDescendants?: boolean
128
+ lookup?: LookupSource | null
129
+ options?: ReportFilterOptionDto[] | null
130
+ description?: string | null
131
+ }
132
+
133
+ export type ReportGroupingDto = {
134
+ fieldCode: string
135
+ timeGrain?: ReportTimeGrain | null
136
+ includeDetails?: boolean
137
+ includeEmpty?: boolean
138
+ includeDescendants?: boolean
139
+ labelOverride?: string | null
140
+ groupKey?: string | null
141
+ }
142
+
143
+ export type ReportMeasureSelectionDto = {
144
+ measureCode: string
145
+ aggregation?: ReportAggregationKind
146
+ labelOverride?: string | null
147
+ formatOverride?: string | null
148
+ }
149
+
150
+ export type ReportSortDto = {
151
+ fieldCode: string
152
+ direction?: ReportSortDirection
153
+ timeGrain?: ReportTimeGrain | null
154
+ appliesToColumnAxis?: boolean
155
+ groupKey?: string | null
156
+ }
157
+
158
+ export type ReportLayoutDto = {
159
+ rowGroups?: ReportGroupingDto[] | null
160
+ columnGroups?: ReportGroupingDto[] | null
161
+ measures?: ReportMeasureSelectionDto[] | null
162
+ detailFields?: string[] | null
163
+ sorts?: ReportSortDto[] | null
164
+ showDetails?: boolean
165
+ showSubtotals?: boolean
166
+ showSubtotalsOnSeparateRows?: boolean
167
+ showGrandTotals?: boolean
168
+ }
169
+
170
+ export type ReportDefinitionDto = {
171
+ reportCode: string
172
+ name: string
173
+ group?: string | null
174
+ description?: string | null
175
+ mode?: ReportExecutionMode
176
+ dataset?: ReportDatasetDto | null
177
+ capabilities?: ReportCapabilitiesDto | null
178
+ defaultLayout?: ReportLayoutDto | null
179
+ parameters?: ReportParameterMetadataDto[] | null
180
+ filters?: ReportFilterFieldDto[] | null
181
+ presentation?: ReportPresentationDto | null
182
+ }
183
+
184
+ export type ReportFilterValueDto = {
185
+ value: unknown
186
+ includeDescendants?: boolean
187
+ }
188
+
189
+ export type ReportExportRequestDto = {
190
+ layout?: ReportLayoutDto | null
191
+ filters?: Record<string, ReportFilterValueDto> | null
192
+ parameters?: Record<string, string> | null
193
+ variantCode?: string | null
194
+ }
195
+
196
+ export type ReportExecutionRequestDto = {
197
+ layout?: ReportLayoutDto | null
198
+ filters?: Record<string, ReportFilterValueDto> | null
199
+ parameters?: Record<string, string> | null
200
+ variantCode?: string | null
201
+ offset?: number
202
+ limit?: number
203
+ cursor?: string | null
204
+ }
205
+
206
+ export type ReportCellReportTargetDto = {
207
+ reportCode: string
208
+ parameters?: Record<string, string> | null
209
+ filters?: Record<string, ReportFilterValueDto> | null
210
+ }
211
+
212
+ export type ReportCellActionDto = {
213
+ kind: string
214
+ documentType?: string | null
215
+ documentId?: string | null
216
+ accountId?: string | null
217
+ catalogType?: string | null
218
+ catalogId?: string | null
219
+ report?: ReportCellReportTargetDto | null
220
+ }
221
+
222
+ export type ReportCellDto = {
223
+ value?: unknown
224
+ display?: string | null
225
+ valueType?: string | null
226
+ colSpan?: number
227
+ rowSpan?: number
228
+ styleKey?: string | null
229
+ semanticRole?: string | null
230
+ action?: ReportCellActionDto | null
231
+ }
232
+
233
+ export type ReportSheetColumnDto = {
234
+ code: string
235
+ title: string
236
+ dataType: string
237
+ width?: number
238
+ isFrozen?: boolean
239
+ semanticRole?: string | null
240
+ }
241
+
242
+ export type ReportSheetRowDto = {
243
+ rowKind: ReportRowKind
244
+ cells: ReportCellDto[]
245
+ outlineLevel?: number
246
+ isExpanded?: boolean
247
+ groupKey?: string | null
248
+ semanticRole?: string | null
249
+ }
250
+
251
+ export type ReportSheetMetaDto = {
252
+ title?: string | null
253
+ subtitle?: string | null
254
+ isPivot?: boolean
255
+ hasRowOutline?: boolean
256
+ hasColumnGroups?: boolean
257
+ diagnostics?: Record<string, string> | null
258
+ }
259
+
260
+ export type ReportSheetDto = {
261
+ columns: ReportSheetColumnDto[]
262
+ rows: ReportSheetRowDto[]
263
+ meta?: ReportSheetMetaDto | null
264
+ headerRows?: ReportSheetRowDto[] | null
265
+ }
266
+
267
+ export type ReportExecutionResponseDto = {
268
+ sheet: ReportSheetDto
269
+ offset: number
270
+ limit: number
271
+ total?: number | null
272
+ hasMore: boolean
273
+ nextCursor?: string | null
274
+ diagnostics?: Record<string, string> | null
275
+ }
276
+
277
+ export type ReportVariantDto = {
278
+ variantCode: string
279
+ reportCode: string
280
+ name: string
281
+ layout?: ReportLayoutDto | null
282
+ filters?: Record<string, ReportFilterValueDto> | null
283
+ parameters?: Record<string, string> | null
284
+ isDefault?: boolean
285
+ isShared?: boolean
286
+ }
287
+
288
+ export type ReportComposerLookupItem = LookupItem
289
+
290
+ export type ReportComposerFilterState = {
291
+ raw: string
292
+ items: ReportComposerLookupItem[]
293
+ includeDescendants: boolean
294
+ }
295
+
296
+ export type ReportComposerGroupingState = {
297
+ groupKey?: string | null
298
+ fieldCode: string
299
+ timeGrain: ReportTimeGrain | null
300
+ }
301
+
302
+ export type ReportComposerMeasureState = {
303
+ measureCode: string
304
+ aggregation: ReportAggregationKind | null
305
+ labelOverride: string | null
306
+ }
307
+
308
+ export type ReportComposerSortState = {
309
+ fieldCode: string
310
+ groupKey?: string | null
311
+ appliesToColumnAxis?: boolean
312
+ direction: ReportSortDirection
313
+ timeGrain: ReportTimeGrain | null
314
+ }
315
+
316
+ export type ReportComposerDraft = {
317
+ parameters: Record<string, string>
318
+ filters: Record<string, ReportComposerFilterState>
319
+ rowGroups: ReportComposerGroupingState[]
320
+ columnGroups: ReportComposerGroupingState[]
321
+ measures: ReportComposerMeasureState[]
322
+ detailFields: string[]
323
+ sorts: ReportComposerSortState[]
324
+ showDetails: boolean
325
+ showSubtotals: boolean
326
+ showSubtotalsOnSeparateRows: boolean
327
+ showGrandTotals: boolean
328
+ }
329
+
330
+ export type ReportOptionItem<T extends string | number = string | number> = {
331
+ value: T
332
+ label: string
333
+ }
@@ -0,0 +1,122 @@
1
+ import type { RouteLocationNormalizedLoaded, Router } from 'vue-router';
2
+
3
+ function normalizeQueryValue(value: unknown): string | null {
4
+ if (Array.isArray(value)) return normalizeQueryValue(value[0] ?? null);
5
+ const raw = String(value ?? '').trim();
6
+ return raw.length > 0 ? raw : null;
7
+ }
8
+
9
+ function encodeBase64Url(value: string): string {
10
+ const bytes = new TextEncoder().encode(value);
11
+ let binary = '';
12
+ bytes.forEach((byte) => {
13
+ binary += String.fromCharCode(byte);
14
+ });
15
+ return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '');
16
+ }
17
+
18
+ function decodeBase64Url(value: string): string | null {
19
+ try {
20
+ const padded = value.replace(/-/g, '+').replace(/_/g, '/') + '==='.slice((value.length + 3) % 4);
21
+ const binary = atob(padded);
22
+ const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
23
+ return new TextDecoder().decode(bytes);
24
+ } catch {
25
+ return null;
26
+ }
27
+ }
28
+
29
+ export function encodeBackTarget(target: string | null | undefined): string | null {
30
+ const normalized = String(target ?? '').trim();
31
+ if (!normalized) return null;
32
+ return encodeBase64Url(normalized);
33
+ }
34
+
35
+ export function decodeBackTarget(value: unknown): string | null {
36
+ const normalized = normalizeQueryValue(value);
37
+ if (!normalized) return null;
38
+ return decodeBase64Url(normalized);
39
+ }
40
+
41
+ function parseRouteTarget(target: string | null | undefined): URL | null {
42
+ const normalized = String(target ?? '').trim();
43
+ if (!normalized) return null;
44
+
45
+ try {
46
+ // Provide a synthetic absolute base only so the URL constructor can parse app-relative routes
47
+ // like "/documents/...". This value is never used for network requests and should not represent
48
+ // a real environment or host.
49
+ return new URL(normalized, 'http://ngb.local');
50
+ } catch {
51
+ return null;
52
+ }
53
+ }
54
+
55
+ export function resolveBackTargetFromPath(target: string | null | undefined): string | null {
56
+ const parsed = parseRouteTarget(target);
57
+ if (!parsed) return null;
58
+ return decodeBackTarget(parsed.searchParams.get('back'));
59
+ }
60
+
61
+ export function routeTargetMatches(
62
+ candidate: string | null | undefined,
63
+ expected: string | null | undefined,
64
+ ): boolean {
65
+ const parsedCandidate = parseRouteTarget(candidate);
66
+ const parsedExpected = parseRouteTarget(expected);
67
+ if (!parsedCandidate || !parsedExpected) return false;
68
+ if (parsedCandidate.pathname !== parsedExpected.pathname) return false;
69
+
70
+ for (const [key, value] of parsedExpected.searchParams.entries()) {
71
+ if (parsedCandidate.searchParams.get(key) !== value) return false;
72
+ }
73
+
74
+ return true;
75
+ }
76
+
77
+ export function buildPathWithQuery(path: string, patch: Record<string, string | null | undefined>): string {
78
+ const [pathname, rawQuery = ''] = path.split('?', 2);
79
+ const query = new URLSearchParams(rawQuery);
80
+
81
+ Object.entries(patch).forEach(([key, value]) => {
82
+ const normalized = String(value ?? '').trim();
83
+ if (normalized.length === 0) query.delete(key);
84
+ else query.set(key, normalized);
85
+ });
86
+
87
+ const suffix = query.toString();
88
+ return suffix ? `${pathname}?${suffix}` : pathname;
89
+ }
90
+
91
+ export function withBackTarget(path: string, backTarget: string | null | undefined): string {
92
+ const encoded = encodeBackTarget(backTarget);
93
+ return buildPathWithQuery(path, { back: encoded });
94
+ }
95
+
96
+ export function currentRouteBackTarget(route: Pick<RouteLocationNormalizedLoaded, 'fullPath'>): string {
97
+ return String(route.fullPath ?? '').trim() || '/';
98
+ }
99
+
100
+ export function resolveBackTarget(route: Pick<RouteLocationNormalizedLoaded, 'query'>): string | null {
101
+ return decodeBackTarget(route.query?.back);
102
+ }
103
+
104
+ export async function navigateBack(
105
+ router: Router,
106
+ route: Pick<RouteLocationNormalizedLoaded, 'query'>,
107
+ fallback?: string | null,
108
+ ): Promise<void> {
109
+ const explicit = resolveBackTarget(route);
110
+ if (explicit) {
111
+ await router.replace(explicit);
112
+ return;
113
+ }
114
+
115
+ const normalizedFallback = String(fallback ?? '').trim();
116
+ if (normalizedFallback.length > 0 && typeof window !== 'undefined' && window.history.length <= 1) {
117
+ await router.replace(normalizedFallback);
118
+ return;
119
+ }
120
+
121
+ router.back();
122
+ }
@@ -0,0 +1,129 @@
1
+ import {
2
+ type LocationQueryRaw,
3
+ type RouteLocationNormalizedLoaded,
4
+ type Router,
5
+ } from 'vue-router'
6
+ import {
7
+ normalizeDateOnlyValue as normalizeSharedDateOnlyValue,
8
+ normalizeMonthValue as normalizeSharedMonthValue,
9
+ } from '../utils/dateValues'
10
+
11
+ export type QueryTrashMode = 'active' | 'deleted' | 'all'
12
+ export type QueryPatch = Record<string, unknown>
13
+ export type QueryNavigationMode = 'push' | 'replace'
14
+
15
+ export function normalizeTrashMode(value: unknown): QueryTrashMode {
16
+ const normalized = String(value ?? '').toLowerCase()
17
+ if (normalized === 'deleted') return 'deleted'
18
+ if (normalized === 'all') return 'all'
19
+ return 'active'
20
+ }
21
+
22
+ export function normalizeMonthValue(value: unknown): string {
23
+ return normalizeSharedMonthValue(value) ?? ''
24
+ }
25
+
26
+ export function normalizeMonthQueryValue(value: unknown): string | null {
27
+ const normalized = normalizeMonthValue(value)
28
+ return normalized || null
29
+ }
30
+
31
+ export function normalizeDateOnlyQueryValue(value: unknown): string | null {
32
+ const normalized = normalizeSingleQueryValue(value)
33
+ return normalizeSharedDateOnlyValue(normalized)
34
+ }
35
+
36
+ export function normalizeYearQueryValue(value: unknown): number | null {
37
+ const normalized = normalizeSingleQueryValue(value)
38
+ const parsed = Number.parseInt(normalized, 10)
39
+ return Number.isInteger(parsed) && parsed >= 1900 && parsed <= 9999 ? parsed : null
40
+ }
41
+
42
+ export function normalizeSingleQueryValue(value: unknown): string {
43
+ if (Array.isArray(value)) return String(value[0] ?? '').trim()
44
+ return String(value ?? '').trim()
45
+ }
46
+
47
+ export function firstQueryValue(value: unknown): string | null {
48
+ const normalized = normalizeSingleQueryValue(value)
49
+ return normalized.length > 0 ? normalized : null
50
+ }
51
+
52
+ export function normalizeBooleanQueryFlag(value: unknown): boolean {
53
+ const normalized = normalizeSingleQueryValue(value).toLowerCase()
54
+ return normalized === '1' || normalized === 'true' || normalized === 'yes'
55
+ }
56
+
57
+ export function normalizeAllowedQueryValue<TValue extends string>(
58
+ value: unknown,
59
+ allowedValues: readonly TValue[],
60
+ ): TValue | null {
61
+ const normalized = normalizeSingleQueryValue(value)
62
+ if (!normalized) return null
63
+
64
+ const allowed = new Set<string>(allowedValues)
65
+ return allowed.has(normalized) ? normalized as TValue : null
66
+ }
67
+
68
+ export function cleanQueryObject<T extends Record<string, unknown>>(query: T): T {
69
+ const next = { ...query }
70
+ for (const key of Object.keys(next)) {
71
+ if (next[key] == null || next[key] === '') delete next[key]
72
+ }
73
+ return next
74
+ }
75
+
76
+ export function mergeCleanQuery<TBase extends Record<string, unknown>, TPatch extends Record<string, unknown>>(
77
+ base: TBase,
78
+ patch: TPatch,
79
+ ): TBase & TPatch {
80
+ return cleanQueryObject({ ...base, ...patch })
81
+ }
82
+
83
+ export function navigateCleanRouteQuery(
84
+ route: RouteLocationNormalizedLoaded,
85
+ router: Router,
86
+ patch: QueryPatch,
87
+ mode: QueryNavigationMode = 'replace',
88
+ ) {
89
+ return setCleanRouteQuery(route, router, { ...route.query, ...patch }, mode)
90
+ }
91
+
92
+ export function setCleanRouteQuery(
93
+ route: RouteLocationNormalizedLoaded,
94
+ router: Router,
95
+ query: Record<string, unknown>,
96
+ mode: QueryNavigationMode = 'replace',
97
+ ) {
98
+ const nextQuery = cleanQueryObject({ ...query }) as LocationQueryRaw
99
+ return mode === 'push'
100
+ ? router.push({ path: route.path, query: nextQuery })
101
+ : router.replace({ path: route.path, query: nextQuery })
102
+ }
103
+
104
+ export function replaceCleanRouteQuery(
105
+ route: RouteLocationNormalizedLoaded,
106
+ router: Router,
107
+ patch: QueryPatch,
108
+ ) {
109
+ return navigateCleanRouteQuery(route, router, patch, 'replace')
110
+ }
111
+
112
+ export function pushCleanRouteQuery(
113
+ route: RouteLocationNormalizedLoaded,
114
+ router: Router,
115
+ patch: QueryPatch,
116
+ ) {
117
+ return navigateCleanRouteQuery(route, router, patch, 'push')
118
+ }
119
+
120
+ export function omitRouteQueryKeys(
121
+ route: RouteLocationNormalizedLoaded,
122
+ router: Router,
123
+ keys: readonly string[],
124
+ mode: QueryNavigationMode = 'replace',
125
+ ) {
126
+ const next = { ...route.query } as QueryPatch
127
+ for (const key of keys) delete next[key]
128
+ return setCleanRouteQuery(route, router, next, mode)
129
+ }
@@ -0,0 +1,121 @@
1
+ import { computed, ref, watch, type WatchSource } from 'vue'
2
+ import type { RouteLocationNormalizedLoaded, RouteLocationRaw, Router } from 'vue-router'
3
+
4
+ import type { UiLookupItem } from '../lookup/store'
5
+ import { isNonEmptyGuid } from '../utils/guid'
6
+ import {
7
+ firstQueryValue,
8
+ normalizeAllowedQueryValue,
9
+ normalizeBooleanQueryFlag,
10
+ replaceCleanRouteQuery,
11
+ type QueryPatch,
12
+ } from './queryParams'
13
+
14
+ export type UseRouteQueryMigrationArgs<TValues extends readonly unknown[]> = {
15
+ route: RouteLocationNormalizedLoaded
16
+ router: Router
17
+ sources: WatchSource<TValues>
18
+ migrate: (values: TValues) => QueryPatch | null
19
+ }
20
+
21
+ export function useRouteQueryMigration<TValues extends readonly unknown[]>(
22
+ args: UseRouteQueryMigrationArgs<TValues>,
23
+ ) {
24
+ watch(
25
+ args.sources,
26
+ (values) => {
27
+ const patch = args.migrate(values)
28
+ if (!patch) return
29
+ void replaceCleanRouteQuery(args.route, args.router, patch)
30
+ },
31
+ { immediate: true },
32
+ )
33
+ }
34
+
35
+ export function useGuidQueryParam(
36
+ route: RouteLocationNormalizedLoaded,
37
+ key: string,
38
+ ) {
39
+ return computed(() => {
40
+ const value = firstQueryValue(route.query[key])
41
+ return isNonEmptyGuid(value) ? value : null
42
+ })
43
+ }
44
+
45
+ export function useBooleanQueryFlag(
46
+ route: RouteLocationNormalizedLoaded,
47
+ key: string,
48
+ ) {
49
+ return computed(() => normalizeBooleanQueryFlag(route.query[key]))
50
+ }
51
+
52
+ export function useAllowedQueryValue<TValue extends string>(
53
+ route: RouteLocationNormalizedLoaded,
54
+ key: string,
55
+ allowedValues: readonly TValue[],
56
+ ) {
57
+ return computed<TValue | null>(() => normalizeAllowedQueryValue(route.query[key], allowedValues))
58
+ }
59
+
60
+ export type UseRouteLookupSelectionArgs<TItem extends UiLookupItem = UiLookupItem> = {
61
+ route: RouteLocationNormalizedLoaded
62
+ router: Router
63
+ queryKey: string
64
+ lookupById: (id: string) => Promise<string | null | undefined>
65
+ search: (query: string) => Promise<TItem[]>
66
+ openTarget: (value: TItem | null) => Promise<RouteLocationRaw | null>
67
+ }
68
+
69
+ export function useRouteLookupSelection<TItem extends UiLookupItem = UiLookupItem>(
70
+ args: UseRouteLookupSelectionArgs<TItem>,
71
+ ) {
72
+ const selected = ref<TItem | null>(null)
73
+ const items = ref<TItem[]>([])
74
+ const routeId = useGuidQueryParam(args.route, args.queryKey)
75
+
76
+ async function hydrateSelected(): Promise<void> {
77
+ const id = routeId.value
78
+ if (!id) {
79
+ selected.value = null
80
+ return
81
+ }
82
+
83
+ try {
84
+ const label = await args.lookupById(id)
85
+ selected.value = { id, label: label ?? id } as TItem
86
+ } catch {
87
+ selected.value = { id, label: id } as TItem
88
+ }
89
+ }
90
+
91
+ async function onQuery(queryText: string): Promise<void> {
92
+ const query = queryText.trim()
93
+ if (!query) {
94
+ items.value = []
95
+ return
96
+ }
97
+
98
+ items.value = await args.search(query)
99
+ }
100
+
101
+ function onSelect(value: TItem | null): void {
102
+ selected.value = value
103
+ void replaceCleanRouteQuery(args.route, args.router, { [args.queryKey]: value?.id ?? null })
104
+ }
105
+
106
+ async function openSelected(): Promise<void> {
107
+ const target = await args.openTarget(selected.value)
108
+ if (!target) return
109
+ await args.router.push(target)
110
+ }
111
+
112
+ return {
113
+ selected,
114
+ items,
115
+ routeId,
116
+ hydrateSelected,
117
+ onQuery,
118
+ onSelect,
119
+ openSelected,
120
+ }
121
+ }