@itwin/reports-config-widget-react 0.0.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.
Files changed (294) hide show
  1. package/.rush/temp/package-deps_rebuild.json +48 -0
  2. package/.rush/temp/shrinkwrap-deps.json +868 -0
  3. package/CHANGELOG.json +17 -0
  4. package/CHANGELOG.md +11 -0
  5. package/LICENSE.md +9 -0
  6. package/README.md +38 -0
  7. package/__mocks__/fileMock.js +5 -0
  8. package/coverage/clover.xml +612 -0
  9. package/coverage/coverage-final.json +19 -0
  10. package/coverage/lcov-report/base.css +224 -0
  11. package/coverage/lcov-report/block-navigation.js +87 -0
  12. package/coverage/lcov-report/favicon.png +0 -0
  13. package/coverage/lcov-report/index.html +191 -0
  14. package/coverage/lcov-report/prettify.css +1 -0
  15. package/coverage/lcov-report/prettify.js +2 -0
  16. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  17. package/coverage/lcov-report/sorter.js +196 -0
  18. package/coverage/lcov-report/src/ReportsConfigWidget.ts.html +193 -0
  19. package/coverage/lcov-report/src/index.html +116 -0
  20. package/coverage/lcov-report/src/test/index.html +116 -0
  21. package/coverage/lcov-report/src/test/test-utils.tsx.html +316 -0
  22. package/coverage/lcov-report/src/widget/ReportsConfigUiProvider.tsx.html +286 -0
  23. package/coverage/lcov-report/src/widget/components/ActionPanel.tsx.html +253 -0
  24. package/coverage/lcov-report/src/widget/components/AddMappingsModal.tsx.html +610 -0
  25. package/coverage/lcov-report/src/widget/components/DeleteModal.tsx.html +385 -0
  26. package/coverage/lcov-report/src/widget/components/Extraction.tsx.html +1030 -0
  27. package/coverage/lcov-report/src/widget/components/HorizontalTile.tsx.html +256 -0
  28. package/coverage/lcov-report/src/widget/components/LocalizedTablePaginator.tsx.html +262 -0
  29. package/coverage/lcov-report/src/widget/components/ReportAction.tsx.html +523 -0
  30. package/coverage/lcov-report/src/widget/components/ReportMappings.tsx.html +1135 -0
  31. package/coverage/lcov-report/src/widget/components/Reports.tsx.html +829 -0
  32. package/coverage/lcov-report/src/widget/components/ReportsContainer.tsx.html +193 -0
  33. package/coverage/lcov-report/src/widget/components/SearchBar.tsx.html +271 -0
  34. package/coverage/lcov-report/src/widget/components/SelectIModel.tsx.html +391 -0
  35. package/coverage/lcov-report/src/widget/components/index.html +296 -0
  36. package/coverage/lcov-report/src/widget/components/utils.tsx.html +562 -0
  37. package/coverage/lcov-report/src/widget/context/ReportsApiConfigContext.tsx.html +166 -0
  38. package/coverage/lcov-report/src/widget/context/index.html +116 -0
  39. package/coverage/lcov-report/src/widget/hooks/index.html +116 -0
  40. package/coverage/lcov-report/src/widget/hooks/useValidator.ts.html +295 -0
  41. package/coverage/lcov-report/src/widget/index.html +116 -0
  42. package/coverage/lcov.info +1260 -0
  43. package/jest.config.js +19 -0
  44. package/lib/cjs/ReportsConfigWidget.d.ts +10 -0
  45. package/lib/cjs/ReportsConfigWidget.d.ts.map +1 -0
  46. package/lib/cjs/ReportsConfigWidget.js +24 -0
  47. package/lib/cjs/ReportsConfigWidget.js.map +1 -0
  48. package/lib/cjs/reports-config-widget-react.d.ts +4 -0
  49. package/lib/cjs/reports-config-widget-react.d.ts.map +1 -0
  50. package/lib/cjs/reports-config-widget-react.js +20 -0
  51. package/lib/cjs/reports-config-widget-react.js.map +1 -0
  52. package/lib/cjs/test/ReportAction.test.d.ts +2 -0
  53. package/lib/cjs/test/ReportAction.test.d.ts.map +1 -0
  54. package/lib/cjs/test/ReportAction.test.js +194 -0
  55. package/lib/cjs/test/ReportAction.test.js.map +1 -0
  56. package/lib/cjs/test/ReportMappings.test.d.ts +2 -0
  57. package/lib/cjs/test/ReportMappings.test.d.ts.map +1 -0
  58. package/lib/cjs/test/ReportMappings.test.js +530 -0
  59. package/lib/cjs/test/ReportMappings.test.js.map +1 -0
  60. package/lib/cjs/test/Reports.test.d.ts +2 -0
  61. package/lib/cjs/test/Reports.test.d.ts.map +1 -0
  62. package/lib/cjs/test/Reports.test.js +232 -0
  63. package/lib/cjs/test/Reports.test.js.map +1 -0
  64. package/lib/cjs/test/WidgetHeader.test.d.ts +2 -0
  65. package/lib/cjs/test/WidgetHeader.test.d.ts.map +1 -0
  66. package/lib/cjs/test/WidgetHeader.test.js +30 -0
  67. package/lib/cjs/test/WidgetHeader.test.js.map +1 -0
  68. package/lib/cjs/test/test-utils.d.ts +69 -0
  69. package/lib/cjs/test/test-utils.d.ts.map +1 -0
  70. package/lib/cjs/test/test-utils.js +77 -0
  71. package/lib/cjs/test/test-utils.js.map +1 -0
  72. package/lib/cjs/tsconfig.tsbuildinfo +1 -0
  73. package/lib/cjs/widget/ReportsConfigUiProvider.d.ts +12 -0
  74. package/lib/cjs/widget/ReportsConfigUiProvider.d.ts.map +1 -0
  75. package/lib/cjs/widget/ReportsConfigUiProvider.js +55 -0
  76. package/lib/cjs/widget/ReportsConfigUiProvider.js.map +1 -0
  77. package/lib/cjs/widget/components/ActionPanel.d.ts +13 -0
  78. package/lib/cjs/widget/components/ActionPanel.d.ts.map +1 -0
  79. package/lib/cjs/widget/components/ActionPanel.js +39 -0
  80. package/lib/cjs/widget/components/ActionPanel.js.map +1 -0
  81. package/lib/cjs/widget/components/ActionPanel.scss +12 -0
  82. package/lib/cjs/widget/components/AddMappingsModal.d.ts +15 -0
  83. package/lib/cjs/widget/components/AddMappingsModal.d.ts.map +1 -0
  84. package/lib/cjs/widget/components/AddMappingsModal.js +118 -0
  85. package/lib/cjs/widget/components/AddMappingsModal.js.map +1 -0
  86. package/lib/cjs/widget/components/AddMappingsModal.scss +18 -0
  87. package/lib/cjs/widget/components/DeleteModal.d.ts +12 -0
  88. package/lib/cjs/widget/components/DeleteModal.d.ts.map +1 -0
  89. package/lib/cjs/widget/components/DeleteModal.js +65 -0
  90. package/lib/cjs/widget/components/DeleteModal.js.map +1 -0
  91. package/lib/cjs/widget/components/DeleteModal.scss +18 -0
  92. package/lib/cjs/widget/components/Extraction.d.ts +28 -0
  93. package/lib/cjs/widget/components/Extraction.d.ts.map +1 -0
  94. package/lib/cjs/widget/components/Extraction.js +193 -0
  95. package/lib/cjs/widget/components/Extraction.js.map +1 -0
  96. package/lib/cjs/widget/components/Extraction.scss +39 -0
  97. package/lib/cjs/widget/components/HorizontalTile.d.ts +13 -0
  98. package/lib/cjs/widget/components/HorizontalTile.d.ts.map +1 -0
  99. package/lib/cjs/widget/components/HorizontalTile.js +18 -0
  100. package/lib/cjs/widget/components/HorizontalTile.js.map +1 -0
  101. package/lib/cjs/widget/components/HorizontalTile.scss +32 -0
  102. package/lib/cjs/widget/components/LocalizedTablePaginator.d.ts +4 -0
  103. package/lib/cjs/widget/components/LocalizedTablePaginator.d.ts.map +1 -0
  104. package/lib/cjs/widget/components/LocalizedTablePaginator.js +41 -0
  105. package/lib/cjs/widget/components/LocalizedTablePaginator.js.map +1 -0
  106. package/lib/cjs/widget/components/ReportAction.d.ts +11 -0
  107. package/lib/cjs/widget/components/ReportAction.d.ts.map +1 -0
  108. package/lib/cjs/widget/components/ReportAction.js +101 -0
  109. package/lib/cjs/widget/components/ReportAction.js.map +1 -0
  110. package/lib/cjs/widget/components/ReportAction.scss +16 -0
  111. package/lib/cjs/widget/components/ReportMappings.d.ts +17 -0
  112. package/lib/cjs/widget/components/ReportMappings.d.ts.map +1 -0
  113. package/lib/cjs/widget/components/ReportMappings.js +174 -0
  114. package/lib/cjs/widget/components/ReportMappings.js.map +1 -0
  115. package/lib/cjs/widget/components/ReportMappings.scss +46 -0
  116. package/lib/cjs/widget/components/Reports.d.ts +7 -0
  117. package/lib/cjs/widget/components/Reports.d.ts.map +1 -0
  118. package/lib/cjs/widget/components/Reports.js +143 -0
  119. package/lib/cjs/widget/components/Reports.js.map +1 -0
  120. package/lib/cjs/widget/components/Reports.scss +36 -0
  121. package/lib/cjs/widget/components/ReportsContainer.d.ts +10 -0
  122. package/lib/cjs/widget/components/ReportsContainer.d.ts.map +1 -0
  123. package/lib/cjs/widget/components/ReportsContainer.js +34 -0
  124. package/lib/cjs/widget/components/ReportsContainer.js.map +1 -0
  125. package/lib/cjs/widget/components/ReportsContainer.scss +15 -0
  126. package/lib/cjs/widget/components/SearchBar.d.ts +10 -0
  127. package/lib/cjs/widget/components/SearchBar.d.ts.map +1 -0
  128. package/lib/cjs/widget/components/SearchBar.js +50 -0
  129. package/lib/cjs/widget/components/SearchBar.js.map +1 -0
  130. package/lib/cjs/widget/components/SearchBar.scss +27 -0
  131. package/lib/cjs/widget/components/SelectIModel.d.ts +9 -0
  132. package/lib/cjs/widget/components/SelectIModel.d.ts.map +1 -0
  133. package/lib/cjs/widget/components/SelectIModel.js +82 -0
  134. package/lib/cjs/widget/components/SelectIModel.js.map +1 -0
  135. package/lib/cjs/widget/components/SelectIModel.scss +15 -0
  136. package/lib/cjs/widget/components/utils.d.ts +23 -0
  137. package/lib/cjs/widget/components/utils.d.ts.map +1 -0
  138. package/lib/cjs/widget/components/utils.js +87 -0
  139. package/lib/cjs/widget/components/utils.js.map +1 -0
  140. package/lib/cjs/widget/components/utils.scss +39 -0
  141. package/lib/cjs/widget/context/ReportsApiConfigContext.d.ts +9 -0
  142. package/lib/cjs/widget/context/ReportsApiConfigContext.d.ts.map +1 -0
  143. package/lib/cjs/widget/context/ReportsApiConfigContext.js +37 -0
  144. package/lib/cjs/widget/context/ReportsApiConfigContext.js.map +1 -0
  145. package/lib/cjs/widget/hooks/useValidator.d.ts +8 -0
  146. package/lib/cjs/widget/hooks/useValidator.d.ts.map +1 -0
  147. package/lib/cjs/widget/hooks/useValidator.js +56 -0
  148. package/lib/cjs/widget/hooks/useValidator.js.map +1 -0
  149. package/lib/esm/ReportsConfigWidget.d.ts +10 -0
  150. package/lib/esm/ReportsConfigWidget.d.ts.map +1 -0
  151. package/lib/esm/ReportsConfigWidget.js +20 -0
  152. package/lib/esm/ReportsConfigWidget.js.map +1 -0
  153. package/lib/esm/reports-config-widget-react.d.ts +4 -0
  154. package/lib/esm/reports-config-widget-react.d.ts.map +1 -0
  155. package/lib/esm/reports-config-widget-react.js +8 -0
  156. package/lib/esm/reports-config-widget-react.js.map +1 -0
  157. package/lib/esm/test/ReportAction.test.d.ts +2 -0
  158. package/lib/esm/test/ReportAction.test.d.ts.map +1 -0
  159. package/lib/esm/test/ReportAction.test.js +170 -0
  160. package/lib/esm/test/ReportAction.test.js.map +1 -0
  161. package/lib/esm/test/ReportMappings.test.d.ts +2 -0
  162. package/lib/esm/test/ReportMappings.test.d.ts.map +1 -0
  163. package/lib/esm/test/ReportMappings.test.js +506 -0
  164. package/lib/esm/test/ReportMappings.test.js.map +1 -0
  165. package/lib/esm/test/Reports.test.d.ts +2 -0
  166. package/lib/esm/test/Reports.test.d.ts.map +1 -0
  167. package/lib/esm/test/Reports.test.js +208 -0
  168. package/lib/esm/test/Reports.test.js.map +1 -0
  169. package/lib/esm/test/WidgetHeader.test.d.ts +2 -0
  170. package/lib/esm/test/WidgetHeader.test.d.ts.map +1 -0
  171. package/lib/esm/test/WidgetHeader.test.js +25 -0
  172. package/lib/esm/test/WidgetHeader.test.js.map +1 -0
  173. package/lib/esm/test/test-utils.d.ts +69 -0
  174. package/lib/esm/test/test-utils.d.ts.map +1 -0
  175. package/lib/esm/test/test-utils.js +48 -0
  176. package/lib/esm/test/test-utils.js.map +1 -0
  177. package/lib/esm/tsconfig.tsbuildinfo +1 -0
  178. package/lib/esm/widget/ReportsConfigUiProvider.d.ts +12 -0
  179. package/lib/esm/widget/ReportsConfigUiProvider.d.ts.map +1 -0
  180. package/lib/esm/widget/ReportsConfigUiProvider.js +29 -0
  181. package/lib/esm/widget/ReportsConfigUiProvider.js.map +1 -0
  182. package/lib/esm/widget/components/ActionPanel.d.ts +13 -0
  183. package/lib/esm/widget/components/ActionPanel.d.ts.map +1 -0
  184. package/lib/esm/widget/components/ActionPanel.js +18 -0
  185. package/lib/esm/widget/components/ActionPanel.js.map +1 -0
  186. package/lib/esm/widget/components/ActionPanel.scss +12 -0
  187. package/lib/esm/widget/components/AddMappingsModal.d.ts +15 -0
  188. package/lib/esm/widget/components/AddMappingsModal.d.ts.map +1 -0
  189. package/lib/esm/widget/components/AddMappingsModal.js +94 -0
  190. package/lib/esm/widget/components/AddMappingsModal.js.map +1 -0
  191. package/lib/esm/widget/components/AddMappingsModal.scss +18 -0
  192. package/lib/esm/widget/components/DeleteModal.d.ts +12 -0
  193. package/lib/esm/widget/components/DeleteModal.d.ts.map +1 -0
  194. package/lib/esm/widget/components/DeleteModal.js +42 -0
  195. package/lib/esm/widget/components/DeleteModal.js.map +1 -0
  196. package/lib/esm/widget/components/DeleteModal.scss +18 -0
  197. package/lib/esm/widget/components/Extraction.d.ts +28 -0
  198. package/lib/esm/widget/components/Extraction.d.ts.map +1 -0
  199. package/lib/esm/widget/components/Extraction.js +169 -0
  200. package/lib/esm/widget/components/Extraction.js.map +1 -0
  201. package/lib/esm/widget/components/Extraction.scss +39 -0
  202. package/lib/esm/widget/components/HorizontalTile.d.ts +13 -0
  203. package/lib/esm/widget/components/HorizontalTile.d.ts.map +1 -0
  204. package/lib/esm/widget/components/HorizontalTile.js +11 -0
  205. package/lib/esm/widget/components/HorizontalTile.js.map +1 -0
  206. package/lib/esm/widget/components/HorizontalTile.scss +32 -0
  207. package/lib/esm/widget/components/LocalizedTablePaginator.d.ts +4 -0
  208. package/lib/esm/widget/components/LocalizedTablePaginator.d.ts.map +1 -0
  209. package/lib/esm/widget/components/LocalizedTablePaginator.js +18 -0
  210. package/lib/esm/widget/components/LocalizedTablePaginator.js.map +1 -0
  211. package/lib/esm/widget/components/ReportAction.d.ts +11 -0
  212. package/lib/esm/widget/components/ReportAction.d.ts.map +1 -0
  213. package/lib/esm/widget/components/ReportAction.js +77 -0
  214. package/lib/esm/widget/components/ReportAction.js.map +1 -0
  215. package/lib/esm/widget/components/ReportAction.scss +16 -0
  216. package/lib/esm/widget/components/ReportMappings.d.ts +17 -0
  217. package/lib/esm/widget/components/ReportMappings.d.ts.map +1 -0
  218. package/lib/esm/widget/components/ReportMappings.js +148 -0
  219. package/lib/esm/widget/components/ReportMappings.js.map +1 -0
  220. package/lib/esm/widget/components/ReportMappings.scss +46 -0
  221. package/lib/esm/widget/components/Reports.d.ts +7 -0
  222. package/lib/esm/widget/components/Reports.d.ts.map +1 -0
  223. package/lib/esm/widget/components/Reports.js +117 -0
  224. package/lib/esm/widget/components/Reports.js.map +1 -0
  225. package/lib/esm/widget/components/Reports.scss +36 -0
  226. package/lib/esm/widget/components/ReportsContainer.d.ts +10 -0
  227. package/lib/esm/widget/components/ReportsContainer.d.ts.map +1 -0
  228. package/lib/esm/widget/components/ReportsContainer.js +13 -0
  229. package/lib/esm/widget/components/ReportsContainer.js.map +1 -0
  230. package/lib/esm/widget/components/ReportsContainer.scss +15 -0
  231. package/lib/esm/widget/components/SearchBar.d.ts +10 -0
  232. package/lib/esm/widget/components/SearchBar.d.ts.map +1 -0
  233. package/lib/esm/widget/components/SearchBar.js +27 -0
  234. package/lib/esm/widget/components/SearchBar.js.map +1 -0
  235. package/lib/esm/widget/components/SearchBar.scss +27 -0
  236. package/lib/esm/widget/components/SelectIModel.d.ts +9 -0
  237. package/lib/esm/widget/components/SelectIModel.d.ts.map +1 -0
  238. package/lib/esm/widget/components/SelectIModel.js +59 -0
  239. package/lib/esm/widget/components/SelectIModel.js.map +1 -0
  240. package/lib/esm/widget/components/SelectIModel.scss +15 -0
  241. package/lib/esm/widget/components/utils.d.ts +23 -0
  242. package/lib/esm/widget/components/utils.d.ts.map +1 -0
  243. package/lib/esm/widget/components/utils.js +73 -0
  244. package/lib/esm/widget/components/utils.js.map +1 -0
  245. package/lib/esm/widget/components/utils.scss +39 -0
  246. package/lib/esm/widget/context/ReportsApiConfigContext.d.ts +9 -0
  247. package/lib/esm/widget/context/ReportsApiConfigContext.d.ts.map +1 -0
  248. package/lib/esm/widget/context/ReportsApiConfigContext.js +14 -0
  249. package/lib/esm/widget/context/ReportsApiConfigContext.js.map +1 -0
  250. package/lib/esm/widget/hooks/useValidator.d.ts +8 -0
  251. package/lib/esm/widget/hooks/useValidator.d.ts.map +1 -0
  252. package/lib/esm/widget/hooks/useValidator.js +50 -0
  253. package/lib/esm/widget/hooks/useValidator.js.map +1 -0
  254. package/lib/public/locales/en/ReportsConfigWidget.json +76 -0
  255. package/package.json +124 -0
  256. package/public/locales/en/ReportsConfigWidget.json +76 -0
  257. package/reports-config-widget-react.build.error.log +10 -0
  258. package/reports-config-widget-react.build.log +45 -0
  259. package/src/ReportsConfigWidget.ts +36 -0
  260. package/src/reports-config-widget-react.ts +7 -0
  261. package/src/test/ReportAction.test.tsx +258 -0
  262. package/src/test/ReportMappings.test.tsx +882 -0
  263. package/src/test/Reports.test.tsx +365 -0
  264. package/src/test/WidgetHeader.test.tsx +29 -0
  265. package/src/test/test-utils.tsx +77 -0
  266. package/src/widget/ReportsConfigUiProvider.tsx +67 -0
  267. package/src/widget/components/ActionPanel.scss +12 -0
  268. package/src/widget/components/ActionPanel.tsx +56 -0
  269. package/src/widget/components/AddMappingsModal.scss +18 -0
  270. package/src/widget/components/AddMappingsModal.tsx +175 -0
  271. package/src/widget/components/DeleteModal.scss +18 -0
  272. package/src/widget/components/DeleteModal.tsx +100 -0
  273. package/src/widget/components/Extraction.scss +39 -0
  274. package/src/widget/components/Extraction.tsx +315 -0
  275. package/src/widget/components/HorizontalTile.scss +32 -0
  276. package/src/widget/components/HorizontalTile.tsx +57 -0
  277. package/src/widget/components/LocalizedTablePaginator.tsx +59 -0
  278. package/src/widget/components/ReportAction.scss +16 -0
  279. package/src/widget/components/ReportAction.tsx +146 -0
  280. package/src/widget/components/ReportMappings.scss +46 -0
  281. package/src/widget/components/ReportMappings.tsx +350 -0
  282. package/src/widget/components/Reports.scss +36 -0
  283. package/src/widget/components/Reports.tsx +248 -0
  284. package/src/widget/components/ReportsContainer.scss +15 -0
  285. package/src/widget/components/ReportsContainer.tsx +36 -0
  286. package/src/widget/components/SearchBar.scss +27 -0
  287. package/src/widget/components/SearchBar.tsx +62 -0
  288. package/src/widget/components/SelectIModel.scss +15 -0
  289. package/src/widget/components/SelectIModel.tsx +102 -0
  290. package/src/widget/components/utils.scss +39 -0
  291. package/src/widget/components/utils.tsx +159 -0
  292. package/src/widget/context/ReportsApiConfigContext.tsx +27 -0
  293. package/src/widget/hooks/useValidator.ts +70 -0
  294. package/tsconfig.json +11 -0
@@ -0,0 +1,365 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import React from "react";
6
+ import "@testing-library/jest-dom";
7
+ import {
8
+ render,
9
+ screen,
10
+ TestUtils,
11
+ waitForElementToBeRemoved,
12
+ within,
13
+ } from "../test/test-utils";
14
+ import { Reports } from "../widget/components/Reports";
15
+ import type {
16
+ IModelConnection,
17
+ SelectionSet,
18
+ SelectionSetEvent,
19
+ } from "@itwin/core-frontend";
20
+ import { NoRenderApp } from "@itwin/core-frontend";
21
+ import { ReportsConfigWidget } from "../ReportsConfigWidget";
22
+ import { rest } from "msw";
23
+ import { setupServer } from "msw/node";
24
+ import * as moq from "typemoq";
25
+ import type {
26
+ SelectionManager,
27
+ SelectionScopesManager,
28
+ } from "@itwin/presentation-frontend";
29
+ import {
30
+ Presentation,
31
+ SelectionChangeEvent,
32
+ } from "@itwin/presentation-frontend";
33
+ import faker from "@faker-js/faker";
34
+ import type { ReportCollection } from "@itwin/insights-client";
35
+ import userEvent from "@testing-library/user-event";
36
+ import { REPORTS_CONFIG_BASE_URL } from "../widget/ReportsConfigUiProvider";
37
+ import type { BeEvent } from "@itwin/core-bentley";
38
+
39
+ const mockITwinId = faker.datatype.uuid();
40
+ const mockIModelId = faker.datatype.uuid();
41
+
42
+ const reportsFactory = (): ReportCollection => ({
43
+ reports: Array.from(
44
+ { length: faker.datatype.number({ min: 3, max: 5 }) },
45
+ () => ({
46
+ id: `${faker.datatype.uuid()}`,
47
+ displayName: faker.random.alpha(10),
48
+ description: faker.random.words(10),
49
+ })
50
+ ),
51
+ _links: {
52
+ next: undefined,
53
+ self: {
54
+ href: "",
55
+ },
56
+ },
57
+ });
58
+
59
+ const connectionMock = moq.Mock.ofType<IModelConnection>();
60
+ const selectionManagerMock = moq.Mock.ofType<SelectionManager>();
61
+ const selectionScopesManagerMock = moq.Mock.ofType<SelectionScopesManager>();
62
+
63
+ jest.mock("@itwin/appui-react", () => ({
64
+ ...jest.requireActual("@itwin/appui-react"),
65
+ useActiveIModelConnection: () => connectionMock.object,
66
+ }));
67
+
68
+ jest.mock("../widget/components/ReportMappings", () => ({
69
+ ReportMappings: () => "MockReportMappings",
70
+ }));
71
+
72
+ const server = setupServer();
73
+
74
+ beforeAll(async () => {
75
+ // This is required by the i18n module within iTwin.js
76
+ (global as any).XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; // eslint-disable-line @typescript-eslint/no-var-requires
77
+
78
+ await NoRenderApp.startup();
79
+ await Presentation.initialize();
80
+ const selectionSet = moq.Mock.ofType<SelectionSet>();
81
+ const onChanged = moq.Mock.ofType<BeEvent<(ev: SelectionSetEvent) => void>>();
82
+ selectionSet.setup((x) => x.elements).returns(() => new Set([]));
83
+ selectionSet.setup((x) => x.onChanged).returns(() => onChanged.object);
84
+ connectionMock
85
+ .setup((x) => x.selectionSet)
86
+ .returns(() => selectionSet.object);
87
+ connectionMock.setup((x) => x.iModelId).returns(() => mockIModelId);
88
+ connectionMock.setup((x) => x.iTwinId).returns(() => mockITwinId);
89
+
90
+ selectionManagerMock
91
+ .setup((x) => x.selectionChange)
92
+ .returns(() => new SelectionChangeEvent());
93
+
94
+ selectionScopesManagerMock
95
+ .setup(async (x) => x.getSelectionScopes(connectionMock.object))
96
+ .returns(async () => []);
97
+ selectionManagerMock
98
+ .setup((x) => x.scopes)
99
+ .returns(() => selectionScopesManagerMock.object);
100
+
101
+ Presentation.setSelectionManager(selectionManagerMock.object);
102
+ await TestUtils.initializeUiFramework(connectionMock.object);
103
+ await ReportsConfigWidget.initialize();
104
+ server.listen();
105
+ });
106
+
107
+ afterAll(() => {
108
+ TestUtils.terminateUiFramework();
109
+ server.close();
110
+ });
111
+
112
+ afterEach(() => server.resetHandlers());
113
+
114
+ describe("Reports View", () => {
115
+ it("call to action button should be clickable with no reports", async () => {
116
+ server.use(
117
+ rest.get(
118
+ `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports`,
119
+ async (_req, res, ctx) => {
120
+ return res(
121
+ ctx.delay(500),
122
+ ctx.status(200),
123
+ ctx.json({ reports: [] })
124
+ );
125
+ }
126
+ )
127
+ );
128
+
129
+ const { user } = render(<Reports />);
130
+
131
+ await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
132
+ const ctaButton = screen.getByRole("button", {
133
+ name: /createonereportcta/i,
134
+ });
135
+ await user.click(ctaButton);
136
+ expect(screen.getByText(/addreport/i)).toBeInTheDocument();
137
+ });
138
+
139
+ it("be able to add new report", async () => {
140
+ server.use(
141
+ rest.get(
142
+ `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports`,
143
+ async (_req, res, ctx) => {
144
+ return res(
145
+ ctx.delay(500),
146
+ ctx.status(200),
147
+ ctx.json({ reports: [] })
148
+ );
149
+ }
150
+ )
151
+ );
152
+
153
+ const { user } = render(<Reports />);
154
+
155
+ await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
156
+ const newButton = screen.getByRole("button", {
157
+ name: /new/i,
158
+ });
159
+ await user.click(newButton);
160
+ expect(screen.getByText(/addreport/i)).toBeInTheDocument();
161
+ });
162
+
163
+ it("list all reports", async () => {
164
+ const mockedReports: ReportCollection = reportsFactory();
165
+ server.use(
166
+ rest.get(
167
+ `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports`,
168
+ async (_req, res, ctx) => {
169
+ return res(ctx.delay(500), ctx.status(200), ctx.json(mockedReports));
170
+ }
171
+ )
172
+ );
173
+
174
+ render(<Reports />);
175
+
176
+ await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
177
+ const horizontalTiles = screen.getAllByTestId("horizontal-tile");
178
+ // TODO check for all descriptions and names and imodels
179
+ expect(horizontalTiles).toHaveLength(mockedReports?.reports!.length);
180
+
181
+ for (const [index, horizontalTile] of horizontalTiles.entries()) {
182
+ const reportMappingTile = within(horizontalTile);
183
+ expect(
184
+ reportMappingTile.getByText(
185
+ mockedReports?.reports![index].displayName ?? ""
186
+ )
187
+ ).toBeInTheDocument();
188
+ expect(
189
+ reportMappingTile.getByTitle(
190
+ mockedReports?.reports![index].description ?? ""
191
+ )
192
+ ).toBeInTheDocument();
193
+ }
194
+ });
195
+
196
+ it("able to modify a report", async () => {
197
+ const mockedReports: ReportCollection = reportsFactory();
198
+ server.use(
199
+ rest.get(
200
+ `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports`,
201
+ async (_req, res, ctx) => {
202
+ return res(ctx.delay(500), ctx.status(200), ctx.json(mockedReports));
203
+ }
204
+ )
205
+ );
206
+
207
+ const { user } = render(<Reports />);
208
+
209
+ await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
210
+
211
+ const firstMenuDropdown = within(
212
+ screen.getAllByTestId(/tile-action-button/i)[0]
213
+ ).getByRole("button");
214
+ await user.click(firstMenuDropdown);
215
+ const modifyButton = screen.getByRole("menuitem", { name: /modify/i });
216
+ await user.click(modifyButton);
217
+
218
+ expect(screen.getByText(/modifyreport/i)).toBeInTheDocument();
219
+ });
220
+
221
+ it("remove a report", async () => {
222
+ const mockedReports: ReportCollection = reportsFactory();
223
+ const mockedReportsOriginalLength = mockedReports.reports!.length;
224
+ server.use(
225
+ rest.get(
226
+ `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports`,
227
+ async (_req, res, ctx) => {
228
+ return res(ctx.delay(200), ctx.status(200), ctx.json(mockedReports));
229
+ }
230
+ ),
231
+ rest.delete(
232
+ `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports/${
233
+ mockedReports.reports![0].id
234
+ }`,
235
+ async (_req, res, ctx) => {
236
+ mockedReports.reports = mockedReports.reports!.filter(
237
+ (report) => report.id !== mockedReports.reports![0].id
238
+ );
239
+ return res(ctx.delay(100), ctx.status(204));
240
+ }
241
+ )
242
+ );
243
+
244
+ const { user } = render(<Reports />);
245
+
246
+ await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
247
+
248
+ const firstMenuDropdown = within(
249
+ screen.getAllByTestId(/tile-action-button/i)[0]
250
+ ).getByRole("button");
251
+ await user.click(firstMenuDropdown);
252
+ const removeButton = screen.getByRole("menuitem", { name: /remove/i });
253
+ await user.click(removeButton);
254
+ // Delete modal dialog should appear
255
+ expect(screen.getByRole("dialog")).toBeInTheDocument();
256
+
257
+ const deleteButton = screen.getByRole("button", {
258
+ name: /delete/i,
259
+ });
260
+
261
+ await user.click(deleteButton);
262
+
263
+ await waitForElementToBeRemoved(() =>
264
+ screen.getByTestId(/rcw-loading-delete/i)
265
+ );
266
+ await waitForElementToBeRemoved(() => screen.getByRole("dialog"));
267
+
268
+ // Should be one less report
269
+ expect(screen.getAllByTestId("horizontal-tile")).toHaveLength(
270
+ mockedReportsOriginalLength - 1
271
+ );
272
+ });
273
+
274
+ it("search for a report", async () => {
275
+ const mockedReports: ReportCollection = reportsFactory();
276
+ server.use(
277
+ rest.get(
278
+ `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports`,
279
+ async (_req, res, ctx) => {
280
+ return res(ctx.delay(200), ctx.status(200), ctx.json(mockedReports));
281
+ }
282
+ )
283
+ );
284
+
285
+ const { user } = render(<Reports />);
286
+
287
+ await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
288
+
289
+ const searchButton = within(screen.getByTestId(/search-bar/i)).getByRole(
290
+ "button"
291
+ );
292
+ await user.click(searchButton);
293
+ const searchInput = screen.getByRole("textbox", {
294
+ name: /search\-textbox/i,
295
+ });
296
+
297
+ // Be an exact match on display name.
298
+ await userEvent.type(
299
+ searchInput,
300
+ mockedReports.reports![0].displayName ?? ""
301
+ );
302
+ expect(screen.getAllByTestId("horizontal-tile")).toHaveLength(1);
303
+ expect(
304
+ screen.getByText(mockedReports.reports![0].displayName ?? "")
305
+ ).toBeInTheDocument();
306
+
307
+ // Be an exact match on description.
308
+ await userEvent.clear(searchInput);
309
+ await userEvent.type(
310
+ searchInput,
311
+ mockedReports.reports![0].description ?? ""
312
+ );
313
+ expect(screen.getAllByTestId("horizontal-tile")).toHaveLength(1);
314
+ expect(
315
+ screen.getByText(mockedReports.reports![0].displayName ?? "")
316
+ ).toBeInTheDocument();
317
+ });
318
+
319
+ it("modify a report", async () => {
320
+ const mockedReports: ReportCollection = reportsFactory();
321
+ server.use(
322
+ rest.get(
323
+ `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports`,
324
+ async (_req, res, ctx) => {
325
+ return res(ctx.delay(200), ctx.status(200), ctx.json(mockedReports));
326
+ }
327
+ )
328
+ );
329
+
330
+ const { user } = render(<Reports />);
331
+
332
+ await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
333
+
334
+ const firstMenuDropdown = within(
335
+ screen.getAllByTestId(/tile-action-button/i)[0]
336
+ ).getByRole("button");
337
+ await user.click(firstMenuDropdown);
338
+ const modifyButton = screen.getByRole("menuitem", { name: /modify/i });
339
+ await user.click(modifyButton);
340
+ // Modify report should appear
341
+ expect(screen.getByText(/modifyreport/i)).toBeInTheDocument();
342
+ });
343
+
344
+ it("click a report", async () => {
345
+ const mockedReports: ReportCollection = reportsFactory();
346
+ server.use(
347
+ rest.get(
348
+ `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports`,
349
+ async (_req, res, ctx) => {
350
+ return res(ctx.delay(200), ctx.status(200), ctx.json(mockedReports));
351
+ }
352
+ )
353
+ );
354
+
355
+ const { user } = render(<Reports />);
356
+
357
+ await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
358
+
359
+ const reportName = screen.getByText(
360
+ mockedReports.reports![0].displayName ?? ""
361
+ );
362
+ await user.click(reportName);
363
+ expect(screen.getByText(/MockReportMappings/i)).toBeInTheDocument();
364
+ });
365
+ });
@@ -0,0 +1,29 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import React from "react";
6
+ import "@testing-library/jest-dom";
7
+ import { render, screen } from "../test/test-utils";
8
+ import { WidgetHeader } from "../widget/components/utils";
9
+ import { faker } from "@faker-js/faker";
10
+
11
+ describe("Widget Header Component", () => {
12
+ it("title renders", async () => {
13
+ const fakeTitle = faker.word.interjection();
14
+ render(<WidgetHeader title={fakeTitle} />);
15
+
16
+ const title = screen.getByText(fakeTitle);
17
+
18
+ expect(title).toHaveTextContent(fakeTitle);
19
+ });
20
+
21
+ it("header allows return callback", async () => {
22
+ const mockReturnFn = jest.fn();
23
+ const { user } = render(<WidgetHeader title="" returnFn={mockReturnFn} />);
24
+
25
+ const returnBtn = screen.getByRole("button");
26
+ await user.click(returnBtn);
27
+ expect(mockReturnFn).toHaveBeenCalledTimes(1);
28
+ });
29
+ });
@@ -0,0 +1,77 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import * as React from "react";
6
+ import { render as rtlRender } from "@testing-library/react";
7
+ import { ReportsApiConfigContext } from "../widget/context/ReportsApiConfigContext";
8
+ import type { Store } from "redux";
9
+ import { combineReducers, createStore } from "redux";
10
+ import {
11
+ FrameworkReducer,
12
+ SyncUiEventDispatcher,
13
+ UiFramework,
14
+ } from "@itwin/appui-react";
15
+ import type { IModelConnection } from "@itwin/core-frontend";
16
+ import { ReportsConfigWidget } from "../ReportsConfigWidget";
17
+ import userEvent from "@testing-library/user-event";
18
+ import { REPORTS_CONFIG_BASE_URL } from "../widget/ReportsConfigUiProvider";
19
+
20
+ export const mockAccessToken = async () => "Bearer eyJhbGci";
21
+
22
+ interface WrapperProps {
23
+ children?: React.ReactNode;
24
+ }
25
+
26
+ function render(ui: React.ReactElement, { ...options } = {}) {
27
+ const Wrapper = ({ children }: WrapperProps) => (
28
+ <ReportsApiConfigContext.Provider
29
+ value={{
30
+ getAccessToken: mockAccessToken,
31
+ baseUrl: REPORTS_CONFIG_BASE_URL,
32
+ }}
33
+ >
34
+ {children}
35
+ </ReportsApiConfigContext.Provider>
36
+ );
37
+
38
+ return {
39
+ user: userEvent.setup(),
40
+ ...rtlRender(ui, { wrapper: Wrapper, ...options }),
41
+ };
42
+ }
43
+
44
+ export * from "@testing-library/react";
45
+ // override React Testing Library's render with our own
46
+ export { render };
47
+
48
+ export class TestUtils {
49
+ public static createAppStore(): Store {
50
+ const rootReducer = combineReducers({
51
+ frameworkState: FrameworkReducer,
52
+ });
53
+
54
+ return createStore(
55
+ rootReducer,
56
+ (window as any).__REDUX_DEVTOOLS_EXTENSION__ &&
57
+ (window as any).__REDUX_DEVTOOLS_EXTENSION__()
58
+ );
59
+ }
60
+
61
+ public static async initializeUiFramework(_?: IModelConnection) {
62
+ const store = this.createAppStore();
63
+
64
+ await UiFramework.initialize(store);
65
+
66
+ // Set the iModelConnection in the Redux store
67
+ // Can not get it to function as intended. Store does not update with the iModel connection
68
+ // if (imodel)
69
+ // UiFramework.setIModelConnection(imodel);
70
+
71
+ SyncUiEventDispatcher.setTimeoutPeriod(0); // disables non-immediate event processing.
72
+ }
73
+
74
+ public static terminateUiFramework() {
75
+ ReportsConfigWidget.terminate();
76
+ }
77
+ }
@@ -0,0 +1,67 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import type {
6
+ AbstractWidgetProps,
7
+ UiItemsProvider,
8
+ } from "@itwin/appui-abstract";
9
+ import {
10
+ StagePanelLocation,
11
+ StagePanelSection,
12
+ StageUsage,
13
+ } from "@itwin/appui-abstract";
14
+ import type { AccessToken } from "@itwin/core-bentley";
15
+
16
+ import * as React from "react";
17
+ import { ReportsConfigWidget } from "../ReportsConfigWidget";
18
+ import ReportsContainer from "./components/ReportsContainer";
19
+
20
+ export const REPORTS_CONFIG_BASE_URL = "https://api.bentley.com";
21
+
22
+ export class ReportsConfigProvider implements UiItemsProvider {
23
+ public readonly id = "ReportsConfigProvider";
24
+ private readonly _getAccessToken?: () => Promise<AccessToken>;
25
+ private readonly _baseUrl: string;
26
+
27
+ constructor(
28
+ getAccessToken?: () => Promise<AccessToken>,
29
+ baseUrl: string = REPORTS_CONFIG_BASE_URL
30
+ ) {
31
+ this._getAccessToken = getAccessToken;
32
+ this._baseUrl = baseUrl;
33
+ }
34
+
35
+ public provideWidgets(
36
+ _stageId: string,
37
+ stageUsage: string,
38
+ location: StagePanelLocation,
39
+ section?: StagePanelSection
40
+ ): ReadonlyArray<AbstractWidgetProps> {
41
+ const widgets: AbstractWidgetProps[] = [];
42
+ if (
43
+ location === StagePanelLocation.Left &&
44
+ section === StagePanelSection.Start &&
45
+ stageUsage === StageUsage.General
46
+ ) {
47
+ const ReportsWidget: AbstractWidgetProps = {
48
+ id: "reports-config-widget",
49
+ label: ReportsConfigWidget.localization.getLocalizedString(
50
+ "ReportsConfigWidget:ReportsConfig"
51
+ ),
52
+ getWidgetContent: () => {
53
+ return (
54
+ <ReportsContainer
55
+ getAccessToken={this._getAccessToken}
56
+ baseUrl={this._baseUrl}
57
+ />
58
+ );
59
+ },
60
+ };
61
+
62
+ widgets.push(ReportsWidget);
63
+ }
64
+
65
+ return widgets;
66
+ }
67
+ }
@@ -0,0 +1,12 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ @import "~@itwin/itwinui-css/scss/variables";
6
+
7
+ .rcw-action-panel {
8
+ display: flex;
9
+ justify-content: right;
10
+ padding: $iui-baseline * 2 $iui-m $iui-baseline;
11
+ gap: $iui-s;
12
+ }
@@ -0,0 +1,56 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { Button } from "@itwin/itwinui-react";
6
+ import * as React from "react";
7
+ import { ReportsConfigWidget } from "../../ReportsConfigWidget";
8
+ import "./ActionPanel.scss";
9
+ import { LoadingSpinner } from "./utils";
10
+
11
+ export interface ActionPanelProps {
12
+ actionLabel: string;
13
+ onAction: () => Promise<void>;
14
+ onCancel: () => void;
15
+ isCancelDisabled?: boolean;
16
+ isSavingDisabled?: boolean;
17
+ isLoading?: boolean;
18
+ }
19
+
20
+ const ActionPanel = ({
21
+ actionLabel,
22
+ onAction,
23
+ onCancel,
24
+ isCancelDisabled = false,
25
+ isSavingDisabled = false,
26
+ isLoading = false,
27
+ }: ActionPanelProps): JSX.Element => {
28
+ return (
29
+ <div id="action">
30
+ <div className="rcw-action-panel">
31
+ {isLoading && <LoadingSpinner />}
32
+ <Button
33
+ disabled={isSavingDisabled || isLoading}
34
+ styleType="high-visibility"
35
+ id="save-app"
36
+ onClick={onAction}
37
+ >
38
+ {actionLabel}
39
+ </Button>
40
+ <Button
41
+ styleType="default"
42
+ type="button"
43
+ id="cancel"
44
+ onClick={onCancel}
45
+ disabled={isCancelDisabled || isLoading}
46
+ >
47
+ {ReportsConfigWidget.localization.getLocalizedString(
48
+ "ReportsConfigWidget:Cancel"
49
+ )}
50
+ </Button>
51
+ </div>
52
+ </div>
53
+ );
54
+ };
55
+
56
+ export default ActionPanel;
@@ -0,0 +1,18 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ @import "~@itwin/itwinui-css/scss/variables";
6
+
7
+ .add-mappings-container {
8
+ display: flex;
9
+ flex-direction: column;
10
+ gap: $iui-baseline;
11
+ width: 45vw;
12
+ min-width: 100%;
13
+ overflow: auto;
14
+ .add-mappings-table {
15
+ flex-grow: 1;
16
+ overflow: auto;
17
+ }
18
+ }