@cccsaurora/howler-ui 2.19.0-cases.863 → 2.19.0-dev.1023

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 (435) hide show
  1. package/api/action/index.d.ts +5 -4
  2. package/api/action/index.js +8 -8
  3. package/api/analytic/index.d.ts +3 -2
  4. package/api/analytic/index.js +4 -4
  5. package/api/analytic/owner.d.ts +2 -1
  6. package/api/analytic/owner.js +2 -2
  7. package/api/analytic/rules.d.ts +2 -1
  8. package/api/analytic/rules.js +2 -2
  9. package/api/dossier/index.d.ts +4 -3
  10. package/api/dossier/index.js +6 -6
  11. package/api/hit/index.d.ts +3 -2
  12. package/api/hit/index.js +4 -4
  13. package/api/hit/labels.d.ts +3 -2
  14. package/api/hit/labels.js +4 -4
  15. package/api/hit/overwrite.d.ts +2 -1
  16. package/api/hit/overwrite.js +2 -2
  17. package/api/hit/transition.d.ts +2 -1
  18. package/api/hit/transition.js +2 -2
  19. package/api/index.d.ts +5 -8
  20. package/api/index.js +10 -18
  21. package/api/overview/index.d.ts +4 -3
  22. package/api/overview/index.js +6 -6
  23. package/api/search/facet/hit.d.ts +3 -1
  24. package/api/search/facet/index.d.ts +1 -3
  25. package/api/search/index.d.ts +1 -2
  26. package/api/search/index.js +1 -2
  27. package/api/search/overview.d.ts +2 -2
  28. package/api/template/index.d.ts +4 -3
  29. package/api/template/index.js +6 -6
  30. package/api/user/index.d.ts +2 -1
  31. package/api/user/index.js +2 -2
  32. package/api/view/index.d.ts +4 -3
  33. package/api/view/index.js +6 -6
  34. package/commons/components/leftnav/LeftNavDrawer.js +1 -1
  35. package/components/app/App.d.ts +1 -0
  36. package/components/app/App.js +20 -42
  37. package/components/app/hooks/useMatchers.d.ts +1 -1
  38. package/components/app/hooks/useMatchers.js +11 -23
  39. package/components/app/hooks/useMatchers.test.js +22 -22
  40. package/components/app/hooks/useTitle.js +5 -5
  41. package/components/app/providers/FavouritesProvider.js +2 -6
  42. package/components/app/providers/HitProvider.d.ts +22 -0
  43. package/components/app/providers/{RecordProvider.js → HitProvider.js} +42 -42
  44. package/components/app/providers/{RecordSearchProvider.d.ts → HitSearchProvider.d.ts} +6 -6
  45. package/components/app/providers/{RecordSearchProvider.js → HitSearchProvider.js} +17 -12
  46. package/components/app/providers/{RecordSearchProvider.test.js → HitSearchProvider.test.js} +71 -52
  47. package/components/app/providers/ModalProvider.d.ts +1 -1
  48. package/components/app/providers/ModalProvider.js +5 -1
  49. package/components/app/providers/ParameterProvider.d.ts +2 -9
  50. package/components/app/providers/ParameterProvider.js +240 -165
  51. package/components/app/providers/ParameterProvider.test.js +94 -346
  52. package/components/app/providers/SearchResponseProvider.d.ts +21 -0
  53. package/components/app/providers/SearchResponseProvider.js +81 -0
  54. package/components/app/providers/SearchResponseProvider.test.js +406 -0
  55. package/components/app/providers/SocketProvider.d.ts +2 -11
  56. package/components/app/providers/SocketProvider.js +5 -18
  57. package/components/app/providers/UserListProvider.js +8 -28
  58. package/components/app/providers/ViewProvider.test.js +4 -1
  59. package/components/elements/PluginTypography.d.ts +1 -2
  60. package/components/elements/PluginTypography.js +2 -3
  61. package/components/elements/UserList.d.ts +2 -5
  62. package/components/elements/UserList.js +8 -18
  63. package/components/elements/addons/buttons/CustomButton.test.js +106 -0
  64. package/components/elements/addons/layout/FlexOne.test.js +30 -0
  65. package/components/elements/addons/lists/TuiListBase.js +4 -0
  66. package/components/elements/addons/lists/TuiListElement.js +6 -3
  67. package/components/elements/addons/lists/index.d.ts +1 -0
  68. package/components/elements/addons/search/SearchPagination.d.ts +2 -1
  69. package/components/elements/addons/search/SearchPagination.js +4 -4
  70. package/components/elements/addons/search/SearchPagination.test.js +80 -0
  71. package/components/elements/addons/search/SearchTotal.test.js +47 -0
  72. package/components/elements/addons/search/phrase/Phrase.js +1 -1
  73. package/components/elements/display/ChipPopper.d.ts +1 -1
  74. package/components/elements/display/ChipPopper.js +5 -5
  75. package/components/elements/display/DocumentationButton.test.js +84 -0
  76. package/components/elements/display/DynamicTabs.test.js +93 -0
  77. package/components/elements/display/HowlerAvatar.js +2 -1
  78. package/components/elements/display/HowlerCard.js +1 -1
  79. package/components/elements/display/HowlerCard.test.js +55 -0
  80. package/components/elements/display/Image.test.js +79 -0
  81. package/components/elements/display/ItemManager.d.ts +2 -2
  82. package/components/elements/display/ItemManager.js +1 -1
  83. package/components/elements/display/Markdown.js +9 -2
  84. package/components/elements/display/Modal.js +0 -2
  85. package/components/elements/display/QueryResultText.test.js +48 -0
  86. package/components/elements/display/TextDivider.test.js +43 -0
  87. package/components/elements/display/TypingIndicator.test.js +33 -0
  88. package/components/elements/display/icons/BundleButton.d.ts +6 -0
  89. package/components/elements/display/icons/BundleButton.js +32 -0
  90. package/components/elements/display/modals/ConfirmDeleteModal.d.ts +4 -0
  91. package/components/elements/display/modals/ConfirmDeleteModal.js +4 -2
  92. package/components/elements/hit/HitActions.js +4 -4
  93. package/components/elements/hit/HitBanner.d.ts +0 -1
  94. package/components/elements/hit/HitBanner.js +49 -31
  95. package/components/elements/hit/HitCard.d.ts +0 -2
  96. package/components/elements/hit/HitCard.js +7 -7
  97. package/components/elements/{record/RecordComments.d.ts → hit/HitComments.d.ts} +4 -5
  98. package/components/elements/{record/RecordComments.js → hit/HitComments.js} +28 -29
  99. package/components/elements/{ObjectDetails.js → hit/HitDetails.js} +17 -17
  100. package/components/elements/hit/HitLabels.js +2 -2
  101. package/components/elements/hit/HitOutline.d.ts +0 -1
  102. package/components/elements/hit/HitOutline.js +3 -3
  103. package/components/elements/hit/{HitPreview.d.ts → HitQuickSearch.d.ts} +3 -3
  104. package/components/elements/hit/{HitPreview.js → HitQuickSearch.js} +4 -10
  105. package/components/elements/hit/HitRelated.d.ts +6 -0
  106. package/components/elements/hit/HitRelated.js +7 -0
  107. package/components/elements/hit/HitSummary.d.ts +1 -2
  108. package/components/elements/hit/HitSummary.js +8 -8
  109. package/components/elements/{record/RecordWorklog.d.ts → hit/HitWorklog.d.ts} +3 -4
  110. package/components/elements/{record/RecordWorklog.js → hit/HitWorklog.js} +13 -15
  111. package/components/elements/hit/aggregate/HitGraph.js +8 -8
  112. package/components/elements/hit/elements/{Assigned.d.ts → HitUsers.d.ts} +5 -2
  113. package/components/elements/hit/elements/HitUsers.js +33 -0
  114. package/components/elements/hit/outlines/DefaultOutline.js +1 -1
  115. package/components/elements/view/ViewTitle.d.ts +0 -1
  116. package/components/elements/view/ViewTitle.js +2 -9
  117. package/components/hooks/useHitActions.d.ts +1 -1
  118. package/components/hooks/useHitActions.js +4 -4
  119. package/components/hooks/{useRecordSelection.d.ts → useHitSelection.d.ts} +2 -2
  120. package/components/hooks/{useRecordSelection.js → useHitSelection.js} +33 -12
  121. package/components/hooks/useMyApi.d.ts +1 -1
  122. package/components/hooks/useMyPreferences.js +3 -11
  123. package/components/hooks/useMySearch.js +2 -2
  124. package/components/hooks/useMySitemap.js +1 -4
  125. package/components/hooks/useMyTheme.js +2 -9
  126. package/components/routes/403.test.js +27 -0
  127. package/components/routes/404.test.js +26 -0
  128. package/components/routes/ErrorBoundary.test.js +43 -0
  129. package/components/routes/ErrorOccured.test.js +35 -0
  130. package/components/routes/Logout.test.js +59 -0
  131. package/components/routes/action/edit/ActionEditor.js +2 -2
  132. package/components/routes/action/useMyActionFunctions.js +5 -2
  133. package/components/routes/action/view/ActionDetails.js +10 -2
  134. package/components/routes/action/view/ActionSearch.js +30 -19
  135. package/components/routes/advanced/QueryBuilder.js +1 -1
  136. package/components/routes/advanced/QueryEditor.js +3 -3
  137. package/components/routes/advanced/historyCompletionProvider.js +3 -3
  138. package/components/routes/analytics/AnalyticDetails.js +12 -8
  139. package/components/routes/analytics/AnalyticSearch.js +7 -7
  140. package/components/routes/dossiers/DossierEditor.js +2 -2
  141. package/components/routes/dossiers/DossierEditor.test.js +1 -1
  142. package/components/routes/dossiers/Dossiers.js +25 -19
  143. package/components/routes/help/ApiDocumentation.js +1 -1
  144. package/components/routes/help/BundleDocumentation.d.ts +3 -0
  145. package/components/routes/help/BundleDocumentation.js +12 -0
  146. package/components/routes/help/HitBannerDocumentation.js +0 -1
  147. package/components/routes/help/HitDocumentation.js +3 -1
  148. package/components/routes/help/markdown/en/bundles.md.js +1 -0
  149. package/components/routes/help/markdown/en/client.md.js +1 -1
  150. package/components/routes/help/markdown/fr/bundles.md.js +1 -0
  151. package/components/routes/help/markdown/fr/client.md.js +1 -1
  152. package/components/routes/hits/search/BundleParentMenu.d.ts +6 -0
  153. package/components/routes/hits/search/BundleParentMenu.js +32 -0
  154. package/components/routes/hits/search/BundleScroller.d.ts +2 -0
  155. package/components/routes/hits/search/BundleScroller.js +6 -0
  156. package/components/routes/hits/search/{RecordBrowser.js → HitBrowser.js} +9 -9
  157. package/components/{elements/record/RecordContextMenu.d.ts → routes/hits/search/HitContextMenu.d.ts} +3 -3
  158. package/components/routes/hits/search/HitContextMenu.js +239 -0
  159. package/components/{elements/record/RecordContextMenu.test.js → routes/hits/search/HitContextMenu.test.js} +43 -98
  160. package/components/routes/hits/search/{RecordQuery.d.ts → HitQuery.d.ts} +2 -2
  161. package/components/routes/hits/search/{RecordQuery.js → HitQuery.js} +6 -6
  162. package/components/routes/hits/search/InformationPane.d.ts +0 -1
  163. package/components/routes/hits/search/InformationPane.js +63 -50
  164. package/components/routes/hits/search/LayoutSettings.js +3 -3
  165. package/components/routes/hits/search/QuerySettings.js +1 -2
  166. package/components/routes/hits/search/QuerySettings.test.js +9 -14
  167. package/components/routes/hits/search/SearchPane.js +49 -26
  168. package/components/routes/hits/search/ViewLink.js +3 -3
  169. package/components/routes/hits/search/ViewLink.test.js +8 -8
  170. package/components/routes/hits/search/grid/AddColumnModal.js +4 -5
  171. package/components/routes/hits/search/grid/EnhancedCell.d.ts +1 -2
  172. package/components/routes/hits/search/grid/EnhancedCell.js +2 -2
  173. package/components/routes/hits/search/grid/HitGrid.js +18 -20
  174. package/components/routes/hits/search/grid/{RecordRow.d.ts → HitRow.d.ts} +2 -3
  175. package/components/routes/hits/search/grid/{RecordRow.js → HitRow.js} +9 -11
  176. package/components/routes/hits/search/shared/CustomSpan.js +7 -7
  177. package/components/routes/hits/search/shared/CustomSpan.test.js +170 -0
  178. package/components/routes/hits/view/HitViewer.js +13 -12
  179. package/components/routes/home/AddNewCard.test.js +86 -0
  180. package/components/routes/home/ViewCard.js +41 -47
  181. package/components/routes/home/ViewRefresh.test.js +79 -0
  182. package/components/routes/overviews/OverviewCard.test.js +108 -0
  183. package/components/{elements/MarkdownEditor.js → routes/overviews/OverviewEditor.js} +3 -3
  184. package/components/routes/overviews/OverviewViewer.js +18 -10
  185. package/components/routes/overviews/Overviews.js +25 -19
  186. package/components/routes/settings/LocalSection.js +2 -1
  187. package/components/routes/settings/SettingsSection.test.d.ts +1 -0
  188. package/components/routes/settings/SettingsSection.test.js +19 -0
  189. package/components/routes/templates/TemplateCard.d.ts +3 -1
  190. package/components/routes/templates/TemplateCard.js +8 -4
  191. package/components/routes/templates/TemplateCard.test.d.ts +1 -0
  192. package/components/routes/templates/TemplateCard.test.js +115 -0
  193. package/components/routes/templates/TemplateViewer.js +62 -16
  194. package/components/routes/templates/Templates.js +35 -13
  195. package/components/routes/views/ViewComposer.js +19 -46
  196. package/components/routes/views/Views.js +21 -14
  197. package/locales/en/translation.json +21 -118
  198. package/locales/fr/translation.json +23 -120
  199. package/models/WithMetadata.d.ts +1 -2
  200. package/models/entities/generated/{ThreatEnrichment.d.ts → Enrichment.d.ts} +1 -1
  201. package/models/entities/generated/Hit.d.ts +1 -1
  202. package/models/entities/generated/Howler.d.ts +6 -0
  203. package/models/entities/generated/Rule.d.ts +9 -6
  204. package/models/entities/generated/Threat.d.ts +2 -2
  205. package/models/entities/generated/UserUser.d.ts +2 -0
  206. package/models/entities/generated/View.d.ts +0 -1
  207. package/package.json +125 -145
  208. package/plugins/clue/components/ClueTypography.js +2 -2
  209. package/plugins/clue/utils.d.ts +1 -2
  210. package/rest/FetchClient.test.d.ts +1 -0
  211. package/rest/FetchClient.test.js +81 -0
  212. package/setupTests.js +5 -0
  213. package/tests/mocks.d.ts +1 -11
  214. package/tests/mocks.js +7 -12
  215. package/tests/server-handlers.js +1 -6
  216. package/tests/utils.d.ts +0 -4
  217. package/tests/utils.js +0 -20
  218. package/utils/Throttler.test.d.ts +1 -0
  219. package/utils/Throttler.test.js +135 -0
  220. package/utils/actionUtils.test.d.ts +1 -0
  221. package/utils/actionUtils.test.js +140 -0
  222. package/utils/constants.d.ts +4 -4
  223. package/utils/constants.js +1 -6
  224. package/utils/hitFunctions.d.ts +1 -2
  225. package/utils/hitFunctions.js +4 -4
  226. package/utils/hitFunctions.test.d.ts +1 -0
  227. package/utils/hitFunctions.test.js +52 -0
  228. package/utils/localStorage.test.d.ts +1 -0
  229. package/utils/localStorage.test.js +96 -0
  230. package/utils/menuUtils.test.d.ts +1 -0
  231. package/utils/menuUtils.test.js +198 -0
  232. package/utils/sessionStorage.test.d.ts +1 -0
  233. package/utils/sessionStorage.test.js +81 -0
  234. package/utils/socketUtils.d.ts +0 -14
  235. package/utils/socketUtils.js +1 -17
  236. package/utils/socketUtils.test.js +16 -49
  237. package/utils/stringUtils.test.d.ts +1 -0
  238. package/utils/stringUtils.test.js +159 -0
  239. package/utils/utils.test.d.ts +1 -0
  240. package/utils/utils.test.js +292 -0
  241. package/utils/viewUtils.js +0 -3
  242. package/utils/viewUtils.test.d.ts +1 -0
  243. package/utils/viewUtils.test.js +45 -0
  244. package/utils/xsrf.test.d.ts +1 -0
  245. package/utils/xsrf.test.js +41 -0
  246. package/api/search/case.d.ts +0 -4
  247. package/api/search/case.js +0 -8
  248. package/api/socket/index.d.ts +0 -3
  249. package/api/socket/index.js +0 -6
  250. package/api/socket/viewers.d.ts +0 -2
  251. package/api/socket/viewers.js +0 -8
  252. package/api/socket/viewers.test.js +0 -44
  253. package/api/v2/case/index.d.ts +0 -9
  254. package/api/v2/case/index.js +0 -21
  255. package/api/v2/case/items.d.ts +0 -6
  256. package/api/v2/case/items.js +0 -18
  257. package/api/v2/case/rules.d.ts +0 -6
  258. package/api/v2/case/rules.js +0 -18
  259. package/api/v2/index.d.ts +0 -4
  260. package/api/v2/index.js +0 -6
  261. package/api/v2/search/facet.d.ts +0 -3
  262. package/api/v2/search/facet.js +0 -12
  263. package/api/v2/search/index.d.ts +0 -5
  264. package/api/v2/search/index.js +0 -24
  265. package/components/app/providers/RecordProvider.d.ts +0 -23
  266. package/components/elements/ContextMenu.d.ts +0 -56
  267. package/components/elements/ContextMenu.js +0 -109
  268. package/components/elements/ContextMenu.test.js +0 -215
  269. package/components/elements/ObjectDetails.d.ts +0 -6
  270. package/components/elements/case/CaseCard.d.ts +0 -12
  271. package/components/elements/case/CaseCard.js +0 -42
  272. package/components/elements/case/CasePreview.d.ts +0 -6
  273. package/components/elements/case/CasePreview.js +0 -17
  274. package/components/elements/case/StatusIcon.d.ts +0 -5
  275. package/components/elements/case/StatusIcon.js +0 -13
  276. package/components/elements/hit/elements/AnalyticLink.d.ts +0 -9
  277. package/components/elements/hit/elements/AnalyticLink.js +0 -22
  278. package/components/elements/hit/elements/Assigned.js +0 -34
  279. package/components/elements/hit/elements/Assigned.test.js +0 -65
  280. package/components/elements/hit/related/RelatedRecords.js +0 -63
  281. package/components/elements/observable/ObservableCard.d.ts +0 -6
  282. package/components/elements/observable/ObservableCard.js +0 -22
  283. package/components/elements/observable/ObservablePreview.d.ts +0 -6
  284. package/components/elements/observable/ObservablePreview.js +0 -12
  285. package/components/elements/record/RecordContextMenu.js +0 -268
  286. package/components/elements/record/RecordRelated.d.ts +0 -7
  287. package/components/elements/record/RecordRelated.js +0 -34
  288. package/components/hooks/useRelatedRecords.d.ts +0 -13
  289. package/components/hooks/useRelatedRecords.js +0 -32
  290. package/components/routes/cases/CaseViewer.d.ts +0 -2
  291. package/components/routes/cases/CaseViewer.js +0 -44
  292. package/components/routes/cases/CaseViewer.test.js +0 -133
  293. package/components/routes/cases/Cases.d.ts +0 -2
  294. package/components/routes/cases/Cases.js +0 -148
  295. package/components/routes/cases/constants.d.ts +0 -6
  296. package/components/routes/cases/constants.js +0 -6
  297. package/components/routes/cases/detail/AlertPanel.d.ts +0 -6
  298. package/components/routes/cases/detail/AlertPanel.js +0 -33
  299. package/components/routes/cases/detail/CaseAssets.d.ts +0 -11
  300. package/components/routes/cases/detail/CaseAssets.js +0 -104
  301. package/components/routes/cases/detail/CaseAssets.test.js +0 -167
  302. package/components/routes/cases/detail/CaseDashboard.d.ts +0 -7
  303. package/components/routes/cases/detail/CaseDashboard.js +0 -66
  304. package/components/routes/cases/detail/CaseDetails.d.ts +0 -6
  305. package/components/routes/cases/detail/CaseDetails.js +0 -70
  306. package/components/routes/cases/detail/CaseOverview.d.ts +0 -7
  307. package/components/routes/cases/detail/CaseOverview.js +0 -43
  308. package/components/routes/cases/detail/CaseRules.d.ts +0 -7
  309. package/components/routes/cases/detail/CaseRules.js +0 -57
  310. package/components/routes/cases/detail/CaseRules.test.js +0 -221
  311. package/components/routes/cases/detail/CaseSidebar.d.ts +0 -8
  312. package/components/routes/cases/detail/CaseSidebar.js +0 -107
  313. package/components/routes/cases/detail/CaseSidebar.test.js +0 -266
  314. package/components/routes/cases/detail/CaseTask.d.ts +0 -11
  315. package/components/routes/cases/detail/CaseTask.js +0 -66
  316. package/components/routes/cases/detail/CaseTimeline.d.ts +0 -12
  317. package/components/routes/cases/detail/CaseTimeline.js +0 -106
  318. package/components/routes/cases/detail/CaseTimeline.test.js +0 -320
  319. package/components/routes/cases/detail/CreateRuleDialog.d.ts +0 -9
  320. package/components/routes/cases/detail/CreateRuleDialog.js +0 -163
  321. package/components/routes/cases/detail/CreateRuleDialog.test.js +0 -259
  322. package/components/routes/cases/detail/ItemPage.d.ts +0 -6
  323. package/components/routes/cases/detail/ItemPage.js +0 -95
  324. package/components/routes/cases/detail/RelatedCasePanel.d.ts +0 -6
  325. package/components/routes/cases/detail/RelatedCasePanel.js +0 -34
  326. package/components/routes/cases/detail/TaskPanel.d.ts +0 -7
  327. package/components/routes/cases/detail/TaskPanel.js +0 -52
  328. package/components/routes/cases/detail/aggregates/CaseAggregate.d.ts +0 -11
  329. package/components/routes/cases/detail/aggregates/CaseAggregate.js +0 -24
  330. package/components/routes/cases/detail/aggregates/SourceAggregate.d.ts +0 -6
  331. package/components/routes/cases/detail/aggregates/SourceAggregate.js +0 -26
  332. package/components/routes/cases/detail/assets/Asset.d.ts +0 -14
  333. package/components/routes/cases/detail/assets/Asset.js +0 -12
  334. package/components/routes/cases/detail/assets/Asset.test.js +0 -72
  335. package/components/routes/cases/detail/sidebar/CaseFolder.d.ts +0 -20
  336. package/components/routes/cases/detail/sidebar/CaseFolder.js +0 -83
  337. package/components/routes/cases/detail/sidebar/CaseFolder.test.js +0 -295
  338. package/components/routes/cases/detail/sidebar/CaseFolderContextMenu.d.ts +0 -34
  339. package/components/routes/cases/detail/sidebar/CaseFolderContextMenu.js +0 -103
  340. package/components/routes/cases/detail/sidebar/CaseFolderContextMenu.test.js +0 -363
  341. package/components/routes/cases/detail/sidebar/FolderEntry.d.ts +0 -25
  342. package/components/routes/cases/detail/sidebar/FolderEntry.js +0 -88
  343. package/components/routes/cases/detail/sidebar/FolderEntry.test.js +0 -206
  344. package/components/routes/cases/detail/sidebar/RootDropZone.d.ts +0 -5
  345. package/components/routes/cases/detail/sidebar/RootDropZone.js +0 -33
  346. package/components/routes/cases/detail/sidebar/types.d.ts +0 -9
  347. package/components/routes/cases/detail/sidebar/utils.d.ts +0 -3
  348. package/components/routes/cases/detail/sidebar/utils.js +0 -29
  349. package/components/routes/cases/detail/sidebar/utils.test.js +0 -82
  350. package/components/routes/cases/hooks/useCase.d.ts +0 -13
  351. package/components/routes/cases/hooks/useCase.js +0 -69
  352. package/components/routes/cases/hooks/useCase.test.js +0 -141
  353. package/components/routes/cases/modals/AddToCaseModal.d.ts +0 -7
  354. package/components/routes/cases/modals/AddToCaseModal.js +0 -59
  355. package/components/routes/cases/modals/AddToCaseModal.test.js +0 -313
  356. package/components/routes/cases/modals/CaseRecordRow.d.ts +0 -9
  357. package/components/routes/cases/modals/CaseRecordRow.js +0 -15
  358. package/components/routes/cases/modals/CreateCaseModal.d.ts +0 -7
  359. package/components/routes/cases/modals/CreateCaseModal.js +0 -55
  360. package/components/routes/cases/modals/CreateCaseModal.test.js +0 -358
  361. package/components/routes/cases/modals/RenameItemModal.d.ts +0 -9
  362. package/components/routes/cases/modals/RenameItemModal.js +0 -48
  363. package/components/routes/cases/modals/ResolveModal.d.ts +0 -7
  364. package/components/routes/cases/modals/ResolveModal.js +0 -115
  365. package/components/routes/cases/modals/ResolveModal.test.js +0 -394
  366. package/components/routes/cases/modals/hooks.d.ts +0 -7
  367. package/components/routes/cases/modals/hooks.js +0 -44
  368. package/components/routes/cases/modals/types.d.ts +0 -5
  369. package/components/routes/cases/search/CaseAssigneeFilter.d.ts +0 -6
  370. package/components/routes/cases/search/CaseAssigneeFilter.js +0 -33
  371. package/components/routes/cases/search/CaseAssigneeFilter.test.js +0 -127
  372. package/components/routes/cases/search/CaseDateFilter.d.ts +0 -13
  373. package/components/routes/cases/search/CaseDateFilter.js +0 -26
  374. package/components/routes/cases/search/CaseDateFilter.test.js +0 -115
  375. package/components/routes/cases/search/CaseStatusFilter.d.ts +0 -6
  376. package/components/routes/cases/search/CaseStatusFilter.js +0 -13
  377. package/components/routes/cases/search/CaseStatusFilter.test.js +0 -86
  378. package/components/routes/hits/search/shared/IndexPicker.d.ts +0 -2
  379. package/components/routes/hits/search/shared/IndexPicker.js +0 -20
  380. package/components/routes/observables/ObservableViewer.d.ts +0 -7
  381. package/components/routes/observables/ObservableViewer.js +0 -27
  382. package/models/entities/generated/AttachmentsFile.d.ts +0 -12
  383. package/models/entities/generated/Case.d.ts +0 -28
  384. package/models/entities/generated/DestinationOriginal.d.ts +0 -19
  385. package/models/entities/generated/EmailAttachment.d.ts +0 -8
  386. package/models/entities/generated/EmailParent.d.ts +0 -19
  387. package/models/entities/generated/Enrichments.d.ts +0 -7
  388. package/models/entities/generated/EnrichmentsIndicator.d.ts +0 -21
  389. package/models/entities/generated/HttpResponse.d.ts +0 -11
  390. package/models/entities/generated/Item.d.ts +0 -9
  391. package/models/entities/generated/Observable.d.ts +0 -85
  392. package/models/entities/generated/ObservableCloud.d.ts +0 -20
  393. package/models/entities/generated/ObservableDestination.d.ts +0 -23
  394. package/models/entities/generated/ObservableEmail.d.ts +0 -30
  395. package/models/entities/generated/ObservableFile.d.ts +0 -36
  396. package/models/entities/generated/ObservableHowler.d.ts +0 -42
  397. package/models/entities/generated/ObservableHttp.d.ts +0 -11
  398. package/models/entities/generated/ObservableObserver.d.ts +0 -21
  399. package/models/entities/generated/ObservableOrganization.d.ts +0 -7
  400. package/models/entities/generated/ObservableProcess.d.ts +0 -34
  401. package/models/entities/generated/ObservableSource.d.ts +0 -23
  402. package/models/entities/generated/ObservableThreat.d.ts +0 -21
  403. package/models/entities/generated/ObservableTls.d.ts +0 -12
  404. package/models/entities/generated/ObserverIngress.d.ts +0 -9
  405. package/models/entities/generated/Task.d.ts +0 -10
  406. package/models/socket/CaseUpdate.d.ts +0 -5
  407. package/models/socket/ViewersUpdate.d.ts +0 -4
  408. package/utils/typeUtils.d.ts +0 -7
  409. package/utils/typeUtils.js +0 -27
  410. /package/{api/socket/viewers.test.d.ts → components/app/providers/HitSearchProvider.test.d.ts} +0 -0
  411. /package/components/app/providers/{RecordSearchProvider.test.d.ts → SearchResponseProvider.test.d.ts} +0 -0
  412. /package/components/elements/{ContextMenu.test.d.ts → addons/buttons/CustomButton.test.d.ts} +0 -0
  413. /package/components/elements/{hit/elements/Assigned.test.d.ts → addons/layout/FlexOne.test.d.ts} +0 -0
  414. /package/components/elements/{record/RecordContextMenu.test.d.ts → addons/search/SearchPagination.test.d.ts} +0 -0
  415. /package/components/{routes/cases/CaseViewer.test.d.ts → elements/addons/search/SearchTotal.test.d.ts} +0 -0
  416. /package/components/{routes/cases/detail/CaseAssets.test.d.ts → elements/display/DocumentationButton.test.d.ts} +0 -0
  417. /package/components/{routes/cases/detail/CaseRules.test.d.ts → elements/display/DynamicTabs.test.d.ts} +0 -0
  418. /package/components/{routes/cases/detail/CaseSidebar.test.d.ts → elements/display/HowlerCard.test.d.ts} +0 -0
  419. /package/components/{routes/cases/detail/CaseTimeline.test.d.ts → elements/display/Image.test.d.ts} +0 -0
  420. /package/components/{routes/cases/detail/CreateRuleDialog.test.d.ts → elements/display/QueryResultText.test.d.ts} +0 -0
  421. /package/components/{routes/cases/detail/assets/Asset.test.d.ts → elements/display/TextDivider.test.d.ts} +0 -0
  422. /package/components/{routes/cases/detail/sidebar/CaseFolder.test.d.ts → elements/display/TypingIndicator.test.d.ts} +0 -0
  423. /package/components/elements/hit/{related/RelatedRecords.d.ts → HitDetails.d.ts} +0 -0
  424. /package/components/routes/{cases/detail/sidebar/CaseFolderContextMenu.test.d.ts → 403.test.d.ts} +0 -0
  425. /package/components/routes/{cases/detail/sidebar/FolderEntry.test.d.ts → 404.test.d.ts} +0 -0
  426. /package/components/routes/{cases/detail/sidebar/utils.test.d.ts → ErrorBoundary.test.d.ts} +0 -0
  427. /package/components/routes/{cases/hooks/useCase.test.d.ts → ErrorOccured.test.d.ts} +0 -0
  428. /package/components/routes/{cases/modals/AddToCaseModal.test.d.ts → Logout.test.d.ts} +0 -0
  429. /package/components/routes/hits/search/{RecordBrowser.d.ts → HitBrowser.d.ts} +0 -0
  430. /package/components/routes/{cases/modals/CreateCaseModal.test.d.ts → hits/search/HitContextMenu.test.d.ts} +0 -0
  431. /package/components/routes/{cases/modals/ResolveModal.test.d.ts → hits/search/shared/CustomSpan.test.d.ts} +0 -0
  432. /package/components/routes/{cases/search/CaseAssigneeFilter.test.d.ts → home/AddNewCard.test.d.ts} +0 -0
  433. /package/components/routes/{cases/search/CaseDateFilter.test.d.ts → home/ViewRefresh.test.d.ts} +0 -0
  434. /package/components/routes/{cases/search/CaseStatusFilter.test.d.ts → overviews/OverviewCard.test.d.ts} +0 -0
  435. /package/components/{elements/MarkdownEditor.d.ts → routes/overviews/OverviewEditor.d.ts} +0 -0
@@ -26,13 +26,6 @@ import UserSearchProvider from '@cccsaurora/howler-ui/components/routes/admin/us
26
26
  import QueryBuilder from '@cccsaurora/howler-ui/components/routes/advanced/QueryBuilder';
27
27
  import AnalyticDetails from '@cccsaurora/howler-ui/components/routes/analytics/AnalyticDetails';
28
28
  import AnalyticSearch from '@cccsaurora/howler-ui/components/routes/analytics/AnalyticSearch';
29
- import CaseViewer from '@cccsaurora/howler-ui/components/routes/cases/CaseViewer';
30
- import Cases from '@cccsaurora/howler-ui/components/routes/cases/Cases';
31
- import CaseAssets from '@cccsaurora/howler-ui/components/routes/cases/detail/CaseAssets';
32
- import CaseDashboard from '@cccsaurora/howler-ui/components/routes/cases/detail/CaseDashboard';
33
- import CaseRules from '@cccsaurora/howler-ui/components/routes/cases/detail/CaseRules';
34
- import CaseTimeline from '@cccsaurora/howler-ui/components/routes/cases/detail/CaseTimeline';
35
- import ItemPage from '@cccsaurora/howler-ui/components/routes/cases/detail/ItemPage';
36
29
  import DossierEditor from '@cccsaurora/howler-ui/components/routes/dossiers/DossierEditor';
37
30
  import Dossiers from '@cccsaurora/howler-ui/components/routes/dossiers/Dossiers';
38
31
  import ActionDocumentation from '@cccsaurora/howler-ui/components/routes/help/ActionDocumentation';
@@ -47,7 +40,7 @@ import RetentionDocumentation from '@cccsaurora/howler-ui/components/routes/help
47
40
  import SearchDocumentation from '@cccsaurora/howler-ui/components/routes/help/SearchDocumentation';
48
41
  import TemplateDocumentation from '@cccsaurora/howler-ui/components/routes/help/TemplateDocumentation';
49
42
  import ViewDocumentation from '@cccsaurora/howler-ui/components/routes/help/ViewDocumentation';
50
- import RecordBrowser from '@cccsaurora/howler-ui/components/routes/hits/search/RecordBrowser';
43
+ import HitBrowser from '@cccsaurora/howler-ui/components/routes/hits/search/HitBrowser';
51
44
  import HitViewer from '@cccsaurora/howler-ui/components/routes/hits/view/HitViewer';
52
45
  import Home from '@cccsaurora/howler-ui/components/routes/home';
53
46
  import OverviewViewer from '@cccsaurora/howler-ui/components/routes/overviews/OverviewViewer';
@@ -58,14 +51,16 @@ import Templates from '@cccsaurora/howler-ui/components/routes/templates/Templat
58
51
  import ViewComposer from '@cccsaurora/howler-ui/components/routes/views/ViewComposer';
59
52
  import Views from '@cccsaurora/howler-ui/components/routes/views/Views';
60
53
  import dayjs from 'dayjs';
54
+ import 'dayjs/locale/fr-ca';
61
55
  import duration from 'dayjs/plugin/duration';
62
56
  import localizedFormat from 'dayjs/plugin/localizedFormat';
57
+ import minMax from 'dayjs/plugin/minMax';
63
58
  import relativeTime from 'dayjs/plugin/relativeTime';
64
59
  import utc from 'dayjs/plugin/utc';
65
60
  import i18n from '@cccsaurora/howler-ui/i18n';
66
61
  import * as monaco from 'monaco-editor';
67
62
  import howlerPluginStore from '@cccsaurora/howler-ui/plugins/store';
68
- import { useContext, useEffect, useMemo } from 'react';
63
+ import { useCallback, useContext, useEffect, useMemo } from 'react';
69
64
  import { I18nextProvider } from 'react-i18next';
70
65
  import { PluginProvider, usePluginStore } from 'react-pluggable';
71
66
  import { createBrowserRouter, Outlet, RouterProvider, useLocation, useNavigate } from 'react-router-dom';
@@ -79,11 +74,11 @@ import AvatarProvider from './providers/AvatarProvider';
79
74
  import CustomPluginProvider from './providers/CustomPluginProvider';
80
75
  import FavouriteProvider from './providers/FavouritesProvider';
81
76
  import FieldProvider from './providers/FieldProvider';
77
+ import HitProvider from './providers/HitProvider';
82
78
  import LocalStorageProvider from './providers/LocalStorageProvider';
83
79
  import ModalProvider from './providers/ModalProvider';
84
80
  import OverviewProvider from './providers/OverviewProvider';
85
81
  import ParameterProvider from './providers/ParameterProvider';
86
- import RecordProvider from './providers/RecordProvider';
87
82
  import SocketProvider from './providers/SocketProvider';
88
83
  import UserListProvider from './providers/UserListProvider';
89
84
  import ViewProvider from './providers/ViewProvider';
@@ -91,6 +86,8 @@ dayjs.extend(utc);
91
86
  dayjs.extend(duration);
92
87
  dayjs.extend(relativeTime);
93
88
  dayjs.extend(localizedFormat);
89
+ dayjs.extend(minMax);
90
+ dayjs.locale(i18n.language === 'en' ? 'en' : 'fr-ca');
94
91
  loader.config({ monaco });
95
92
  const RoleRoute = ({ roles }) => {
96
93
  const appUser = useAppUser();
@@ -112,6 +109,13 @@ const MyApp = () => {
112
109
  const { setItems } = useAppSwitcher();
113
110
  const { get, set, remove } = useMyLocalStorage();
114
111
  const pluginStore = usePluginStore();
112
+ const onLanguageChange = useCallback((language) => dayjs.locale(language === 'en' ? 'en' : 'fr-ca'), []);
113
+ useEffect(() => {
114
+ i18n.on('languageChanged', onLanguageChange);
115
+ return () => {
116
+ i18n.off('languageChanged', onLanguageChange);
117
+ };
118
+ }, [onLanguageChange]);
115
119
  // Simulate app loading time...
116
120
  // e.g. fetching initial app data, etc.
117
121
  useEffect(() => {
@@ -156,7 +160,7 @@ const MyAppProvider = ({ children }) => {
156
160
  const mySitemap = useMySitemap();
157
161
  const myUser = useMyUser();
158
162
  const mySearch = useMySearch();
159
- return (_jsx(ErrorBoundary, { children: _jsx(AppProvider, { preferences: myPreferences, theme: myTheme, sitemap: mySitemap, user: myUser, search: mySearch, children: _jsx(CustomPluginProvider, { children: _jsx(ErrorBoundary, { children: _jsx(ErrorBoundary, { children: _jsx(ViewProvider, { children: _jsx(AvatarProvider, { children: _jsx(ModalProvider, { children: _jsx(FieldProvider, { children: _jsx(LocalStorageProvider, { children: _jsx(SocketProvider, { children: _jsx(RecordProvider, { children: _jsx(OverviewProvider, { children: _jsx(AnalyticProvider, { children: _jsx(FavouriteProvider, { children: _jsx(UserListProvider, { children: children }) }) }) }) }) }) }) }) }) }) }) }) }) }) }) }));
163
+ return (_jsx(ErrorBoundary, { children: _jsx(AppProvider, { preferences: myPreferences, theme: myTheme, sitemap: mySitemap, user: myUser, search: mySearch, children: _jsx(CustomPluginProvider, { children: _jsx(ErrorBoundary, { children: _jsx(ErrorBoundary, { children: _jsx(ViewProvider, { children: _jsx(AvatarProvider, { children: _jsx(ModalProvider, { children: _jsx(FieldProvider, { children: _jsx(LocalStorageProvider, { children: _jsx(SocketProvider, { children: _jsx(HitProvider, { children: _jsx(OverviewProvider, { children: _jsx(AnalyticProvider, { children: _jsx(FavouriteProvider, { children: _jsx(UserListProvider, { children: children }) }) }) }) }) }) }) }) }) }) }) }) }) }) }) }));
160
164
  };
161
165
  const AppProviderWrapper = () => {
162
166
  return (_jsx(I18nextProvider, { i18n: i18n, defaultNS: "translation", children: _jsx(ApiConfigProvider, { children: _jsx(PluginProvider, { pluginStore: howlerPluginStore.pluginStore, children: _jsx(AppBarProvider, { children: _jsxs(MyAppProvider, { children: [_jsx(MyApp, {}), _jsx(Modal, {})] }) }) }) }) }));
@@ -180,45 +184,19 @@ const createRouter = () => createBrowserRouter([
180
184
  },
181
185
  {
182
186
  path: 'hits',
183
- element: _jsx(RecordBrowser, {})
187
+ element: _jsx(HitBrowser, {})
184
188
  },
185
189
  {
186
190
  path: 'search',
187
- element: _jsx(RecordBrowser, {})
191
+ element: _jsx(HitBrowser, {})
188
192
  },
189
193
  {
190
194
  path: 'hits/:id',
191
195
  element: _jsx(HitViewer, {})
192
196
  },
193
197
  {
194
- path: 'cases',
195
- element: _jsx(Cases, {})
196
- },
197
- {
198
- path: 'cases/:id',
199
- element: _jsx(ParameterProvider, { children: _jsx(CaseViewer, {}) }),
200
- children: [
201
- {
202
- index: true,
203
- element: _jsx(CaseDashboard, {})
204
- },
205
- {
206
- path: 'assets',
207
- element: _jsx(CaseAssets, {})
208
- },
209
- {
210
- path: 'timeline',
211
- element: _jsx(CaseTimeline, {})
212
- },
213
- {
214
- path: 'rules',
215
- element: _jsx(CaseRules, {})
216
- },
217
- {
218
- path: '*',
219
- element: _jsx(ItemPage, {})
220
- }
221
- ]
198
+ path: 'bundles/:id',
199
+ element: _jsx(HitBrowser, {})
222
200
  },
223
201
  {
224
202
  path: 'templates',
@@ -258,7 +236,7 @@ const createRouter = () => createBrowserRouter([
258
236
  },
259
237
  {
260
238
  path: 'views/:id',
261
- element: _jsx(RecordBrowser, {})
239
+ element: _jsx(HitBrowser, {})
262
240
  },
263
241
  {
264
242
  path: 'views/:id/edit',
@@ -1,6 +1,6 @@
1
1
  import type { Hit } from '@cccsaurora/howler-ui/models/entities/generated/Hit';
2
2
  import type { WithMetadata } from '@cccsaurora/howler-ui/models/WithMetadata';
3
- declare const useMatchers: (lazy?: boolean) => {
3
+ declare const useMatchers: () => {
4
4
  getMatchingDossiers: (hit: WithMetadata<Hit>) => Promise<import("../../../models/entities/generated/Dossier").Dossier[]>;
5
5
  getMatchingOverview: (hit: WithMetadata<Hit>) => Promise<import("../../../models/entities/generated/Overview").Overview>;
6
6
  getMatchingTemplate: (hit: WithMetadata<Hit>) => Promise<import("../../../models/entities/generated/Template").Template>;
@@ -2,9 +2,9 @@
2
2
  import { has } from 'lodash-es';
3
3
  import { useCallback } from 'react';
4
4
  import { useContextSelector } from 'use-context-selector';
5
- import { RecordContext } from '../providers/RecordProvider';
6
- const useMatchers = (lazy = false) => {
7
- const getRecord = useContextSelector(RecordContext, ctx => ctx.getRecord);
5
+ import { HitContext } from '../providers/HitProvider';
6
+ const useMatchers = () => {
7
+ const getHit = useContextSelector(HitContext, ctx => ctx.getHit);
8
8
  const getMatchingTemplate = useCallback(async (hit) => {
9
9
  if (!hit) {
10
10
  return null;
@@ -12,18 +12,15 @@ const useMatchers = (lazy = false) => {
12
12
  if (has(hit, '__template')) {
13
13
  return hit.__template;
14
14
  }
15
- if (lazy) {
16
- return null;
17
- }
18
15
  // This is a fallback in case metadata is not included. In most cases templates are shown, the template metadata
19
16
  // should also exist
20
17
  try {
21
- return (await getRecord(hit.howler.id, true)).__template;
18
+ return (await getHit(hit.howler.id, true)).__template;
22
19
  }
23
20
  catch (e) {
24
21
  return null;
25
22
  }
26
- }, [getRecord, lazy]);
23
+ }, [getHit]);
27
24
  const getMatchingOverview = useCallback(async (hit) => {
28
25
  if (!hit) {
29
26
  return null;
@@ -31,18 +28,15 @@ const useMatchers = (lazy = false) => {
31
28
  if (has(hit, '__overview')) {
32
29
  return hit.__overview;
33
30
  }
34
- if (lazy) {
35
- return null;
36
- }
37
31
  // This is a fallback in case metadata is not included. In most cases templates are shown, the template metadata
38
32
  // should also exist
39
33
  try {
40
- return (await getRecord(hit.howler.id, true)).__overview;
34
+ return (await getHit(hit.howler.id, true)).__overview;
41
35
  }
42
36
  catch (e) {
43
37
  return null;
44
38
  }
45
- }, [getRecord, lazy]);
39
+ }, [getHit]);
46
40
  const getMatchingDossiers = useCallback(async (hit) => {
47
41
  if (!hit) {
48
42
  return null;
@@ -50,18 +44,15 @@ const useMatchers = (lazy = false) => {
50
44
  if (has(hit, '__dossiers')) {
51
45
  return hit.__dossiers;
52
46
  }
53
- if (lazy) {
54
- return null;
55
- }
56
47
  // This is a fallback in case metadata is not included. In most cases templates are shown, the template metadata
57
48
  // should also exist
58
49
  try {
59
- return (await getRecord(hit.howler.id, true)).__dossiers ?? [];
50
+ return (await getHit(hit.howler.id, true)).__dossiers ?? [];
60
51
  }
61
52
  catch (e) {
62
53
  return [];
63
54
  }
64
- }, [getRecord, lazy]);
55
+ }, [getHit]);
65
56
  const getMatchingAnalytic = useCallback(async (hit) => {
66
57
  if (!hit) {
67
58
  return null;
@@ -69,17 +60,14 @@ const useMatchers = (lazy = false) => {
69
60
  if (has(hit, '__analytic')) {
70
61
  return hit.__analytic;
71
62
  }
72
- if (lazy) {
73
- return null;
74
- }
75
63
  // This is a fallback in case metadata is not included.
76
64
  try {
77
- return (await getRecord(hit.howler.id, true)).__analytic;
65
+ return (await getHit(hit.howler.id, true)).__analytic;
78
66
  }
79
67
  catch (e) {
80
68
  return null;
81
69
  }
82
- }, [getRecord, lazy]);
70
+ }, [getHit]);
83
71
  return {
84
72
  getMatchingDossiers,
85
73
  getMatchingOverview,
@@ -1,7 +1,7 @@
1
1
  import { renderHook } from '@testing-library/react';
2
2
  import { useContextSelector } from 'use-context-selector';
3
3
  import { beforeEach, describe, expect, it, vi } from 'vitest';
4
- import { RecordContext } from '../providers/RecordProvider';
4
+ import { HitContext } from '../providers/HitProvider';
5
5
  import useMatchers from './useMatchers';
6
6
  // Mock the useContextSelector hook
7
7
  vi.mock('use-context-selector', () => ({
@@ -40,14 +40,14 @@ const mockHitWithMetadata = {
40
40
  __overview: mockOverview,
41
41
  __dossiers: mockDossiers
42
42
  };
43
- const mockGetRecord = vi.fn();
43
+ const mockGetHit = vi.fn();
44
44
  describe('useMatchers', () => {
45
45
  beforeEach(() => {
46
46
  vi.clearAllMocks();
47
47
  // Mock useContextSelector to return our mock getHit function
48
48
  useContextSelector.mockImplementation((context, selector) => {
49
- if (context === RecordContext) {
50
- return selector({ getRecord: mockGetRecord });
49
+ if (context === HitContext) {
50
+ return selector({ getHit: mockGetHit });
51
51
  }
52
52
  return null;
53
53
  });
@@ -69,25 +69,25 @@ describe('useMatchers', () => {
69
69
  const { result } = renderHook(() => useMatchers());
70
70
  const template = await result.current.getMatchingTemplate(mockHitWithMetadata);
71
71
  expect(template).toBe(mockTemplate);
72
- expect(mockGetRecord).not.toHaveBeenCalled();
72
+ expect(mockGetHit).not.toHaveBeenCalled();
73
73
  });
74
74
  it('should fetch hit with metadata when template is not present', async () => {
75
75
  const { has } = await import('lodash-es');
76
76
  has.mockReturnValue(false);
77
77
  const hitWithFetchedMetadata = { ...mockHit, __template: mockTemplate };
78
- mockGetRecord.mockResolvedValue(hitWithFetchedMetadata);
78
+ mockGetHit.mockResolvedValue(hitWithFetchedMetadata);
79
79
  const { result } = renderHook(() => useMatchers());
80
80
  const template = await result.current.getMatchingTemplate(mockHit);
81
81
  expect(template).toBe(mockTemplate);
82
- expect(mockGetRecord).toHaveBeenCalledWith('test-hit-id', true);
82
+ expect(mockGetHit).toHaveBeenCalledWith('test-hit-id', true);
83
83
  });
84
84
  it('should handle getHit rejection gracefully', async () => {
85
85
  const { has } = await import('lodash-es');
86
86
  has.mockReturnValue(false);
87
- mockGetRecord.mockRejectedValue(new Error('Failed to fetch hit'));
87
+ mockGetHit.mockRejectedValue(new Error('Failed to fetch hit'));
88
88
  const { result } = renderHook(() => useMatchers());
89
89
  await expect(result.current.getMatchingTemplate(mockHit)).resolves.toBeNull();
90
- expect(mockGetRecord).toHaveBeenCalledWith('test-hit-id', true);
90
+ expect(mockGetHit).toHaveBeenCalledWith('test-hit-id', true);
91
91
  });
92
92
  });
93
93
  describe('getMatchingOverview', () => {
@@ -107,25 +107,25 @@ describe('useMatchers', () => {
107
107
  const { result } = renderHook(() => useMatchers());
108
108
  const overview = await result.current.getMatchingOverview(mockHitWithMetadata);
109
109
  expect(overview).toBe(mockOverview);
110
- expect(mockGetRecord).not.toHaveBeenCalled();
110
+ expect(mockGetHit).not.toHaveBeenCalled();
111
111
  });
112
112
  it('should fetch hit with metadata when overview is not present', async () => {
113
113
  const { has } = await import('lodash-es');
114
114
  has.mockReturnValue(false);
115
115
  const hitWithFetchedMetadata = { ...mockHit, __overview: mockOverview };
116
- mockGetRecord.mockResolvedValue(hitWithFetchedMetadata);
116
+ mockGetHit.mockResolvedValue(hitWithFetchedMetadata);
117
117
  const { result } = renderHook(() => useMatchers());
118
118
  const overview = await result.current.getMatchingOverview(mockHit);
119
119
  expect(overview).toBe(mockOverview);
120
- expect(mockGetRecord).toHaveBeenCalledWith('test-hit-id', true);
120
+ expect(mockGetHit).toHaveBeenCalledWith('test-hit-id', true);
121
121
  });
122
122
  it('should handle getHit rejection gracefully', async () => {
123
123
  const { has } = await import('lodash-es');
124
124
  has.mockReturnValue(false);
125
- mockGetRecord.mockRejectedValue(new Error('Failed to fetch hit'));
125
+ mockGetHit.mockRejectedValue(new Error('Failed to fetch hit'));
126
126
  const { result } = renderHook(() => useMatchers());
127
127
  await expect(result.current.getMatchingOverview(mockHit)).resolves.toBeNull();
128
- expect(mockGetRecord).toHaveBeenCalledWith('test-hit-id', true);
128
+ expect(mockGetHit).toHaveBeenCalledWith('test-hit-id', true);
129
129
  });
130
130
  });
131
131
  describe('getMatchingDossiers', () => {
@@ -145,25 +145,25 @@ describe('useMatchers', () => {
145
145
  const { result } = renderHook(() => useMatchers());
146
146
  const dossiers = await result.current.getMatchingDossiers(mockHitWithMetadata);
147
147
  expect(dossiers).toBe(mockDossiers);
148
- expect(mockGetRecord).not.toHaveBeenCalled();
148
+ expect(mockGetHit).not.toHaveBeenCalled();
149
149
  });
150
150
  it('should fetch hit with metadata when dossiers are not present', async () => {
151
151
  const { has } = await import('lodash-es');
152
152
  has.mockReturnValue(false);
153
153
  const hitWithFetchedMetadata = { ...mockHit, __dossiers: mockDossiers };
154
- mockGetRecord.mockResolvedValue(hitWithFetchedMetadata);
154
+ mockGetHit.mockResolvedValue(hitWithFetchedMetadata);
155
155
  const { result } = renderHook(() => useMatchers());
156
156
  const dossiers = await result.current.getMatchingDossiers(mockHit);
157
157
  expect(dossiers).toBe(mockDossiers);
158
- expect(mockGetRecord).toHaveBeenCalledWith('test-hit-id', true);
158
+ expect(mockGetHit).toHaveBeenCalledWith('test-hit-id', true);
159
159
  });
160
160
  it('should handle getHit rejection gracefully', async () => {
161
161
  const { has } = await import('lodash-es');
162
162
  has.mockReturnValue(false);
163
- mockGetRecord.mockRejectedValue(new Error('Failed to fetch hit'));
163
+ mockGetHit.mockRejectedValue(new Error('Failed to fetch hit'));
164
164
  const { result } = renderHook(() => useMatchers());
165
165
  await expect(result.current.getMatchingDossiers(mockHit)).resolves.toEqual([]);
166
- expect(mockGetRecord).toHaveBeenCalledWith('test-hit-id', true);
166
+ expect(mockGetHit).toHaveBeenCalledWith('test-hit-id', true);
167
167
  });
168
168
  });
169
169
  describe('integration tests', () => {
@@ -177,7 +177,7 @@ describe('useMatchers', () => {
177
177
  ...mockHit,
178
178
  __template: mockTemplate
179
179
  };
180
- mockGetRecord.mockResolvedValue({
180
+ mockGetHit.mockResolvedValue({
181
181
  ...mockHit,
182
182
  __overview: mockOverview,
183
183
  __dossiers: mockDossiers
@@ -200,7 +200,7 @@ describe('useMatchers', () => {
200
200
  it('should handle empty or undefined metadata gracefully', async () => {
201
201
  const { has } = await import('lodash-es');
202
202
  has.mockReturnValue(false);
203
- mockGetRecord.mockResolvedValue({
203
+ mockGetHit.mockResolvedValue({
204
204
  ...mockHit,
205
205
  __template: undefined,
206
206
  __overview: null,
@@ -213,7 +213,7 @@ describe('useMatchers', () => {
213
213
  expect(template).toBeUndefined();
214
214
  expect(overview).toBeNull();
215
215
  expect(dossiers).toEqual([]);
216
- expect(mockGetRecord).toHaveBeenCalledTimes(3);
216
+ expect(mockGetHit).toHaveBeenCalledTimes(3);
217
217
  });
218
218
  it('should maintain referential equality of returned functions', () => {
219
219
  const { result, rerender } = renderHook(() => useMatchers());
@@ -5,23 +5,23 @@ import { useTranslation } from 'react-i18next';
5
5
  import { useLocation, useParams, useSearchParams } from 'react-router-dom';
6
6
  import { useContextSelector } from 'use-context-selector';
7
7
  import { AnalyticContext } from '../providers/AnalyticProvider';
8
- import { RecordContext } from '../providers/RecordProvider';
8
+ import { HitContext } from '../providers/HitProvider';
9
9
  const useTitle = () => {
10
10
  const { t } = useTranslation();
11
11
  const location = useLocation();
12
12
  const params = useParams();
13
13
  const searchParams = useSearchParams()[0];
14
14
  const sitemap = useMySitemap();
15
- const { getAnalyticFromId } = useContext(AnalyticContext) ?? {};
16
- const hits = useContextSelector(RecordContext, ctx => ctx.records);
17
- const getHit = useContextSelector(RecordContext, ctx => ctx.getRecord);
15
+ const { getAnalyticFromId } = useContext(AnalyticContext);
16
+ const hits = useContextSelector(HitContext, ctx => ctx.hits);
17
+ const getHit = useContextSelector(HitContext, ctx => ctx.getHit);
18
18
  const setTitle = useCallback((title) => {
19
19
  document.querySelector('title').innerHTML = title;
20
20
  }, []);
21
21
  const runChecks = useCallback(async () => {
22
22
  const searchType = location.pathname.replace(/^\/(\w+)(\/.+)?$/, '$1').replace(/s$/, '');
23
23
  if (searchType === 'analytic') {
24
- if (params.id && getAnalyticFromId) {
24
+ if (params.id) {
25
25
  const analytic = await getAnalyticFromId(params.id);
26
26
  if (analytic) {
27
27
  setTitle(`${t('route.analytics.view')} - ${analytic.name}`);
@@ -26,10 +26,6 @@ const FavouriteProvider = ({ children }) => {
26
26
  if (favourites.length < 1) {
27
27
  return null;
28
28
  }
29
- // The favourite list is fully represented, skip
30
- if (favourites.length === viewElement?.element?.items?.length) {
31
- return viewElement;
32
- }
33
29
  const savedViews = await fetchViews(favourites);
34
30
  const items = sortBy(savedViews, 'title')
35
31
  .filter(view => !!view)
@@ -120,11 +116,11 @@ const FavouriteProvider = ({ children }) => {
120
116
  (async () => {
121
117
  const analyticElement = processAnalyticElement();
122
118
  if (analyticElement) {
123
- newElements.splice(2, 0, analyticElement);
119
+ newElements.splice(1, 0, analyticElement);
124
120
  }
125
121
  const viewElement = await processViewElement();
126
122
  if (viewElement) {
127
- newElements.splice(2, 0, viewElement);
123
+ newElements.splice(1, 0, viewElement);
128
124
  }
129
125
  leftNav.setElements(newElements);
130
126
  })();
@@ -0,0 +1,22 @@
1
+ import type { Hit } from '@cccsaurora/howler-ui/models/entities/generated/Hit';
2
+ import type { WithMetadata } from '@cccsaurora/howler-ui/models/WithMetadata';
3
+ import type { FC, PropsWithChildren } from 'react';
4
+ export interface HitContextType {
5
+ hits: {
6
+ [index: string]: Hit;
7
+ };
8
+ selectedHits: Hit[];
9
+ addHitToSelection: (id: string) => void;
10
+ removeHitFromSelection: (id: string) => void;
11
+ clearSelectedHits: (except?: string) => void;
12
+ loadHits: (hits: Hit[]) => void;
13
+ updateHit: (newHit: Hit) => void;
14
+ getHit: (id: string, force?: boolean) => Promise<WithMetadata<Hit>>;
15
+ }
16
+ export declare const HitContext: import("use-context-selector").Context<HitContextType>;
17
+ /**
18
+ * Central repository for storing individual hit data across the application. Allows efficient retrieval of hits across componenents.
19
+ */
20
+ declare const HitProvider: FC<PropsWithChildren>;
21
+ export declare const useHitContextSelector: <Selected>(selector: (value: HitContextType) => Selected) => Selected;
22
+ export default HitProvider;
@@ -5,25 +5,25 @@ import { uniq } from 'lodash-es';
5
5
  import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
6
6
  import { createContext, useContextSelector } from 'use-context-selector';
7
7
  import { SocketContext } from './SocketProvider';
8
- export const RecordContext = createContext(null);
8
+ export const HitContext = createContext(null);
9
9
  /**
10
10
  * Central repository for storing individual hit data across the application. Allows efficient retrieval of hits across componenents.
11
11
  */
12
- const RecordProvider = ({ children }) => {
12
+ const HitProvider = ({ children }) => {
13
13
  const { dispatchApi } = useMyApi();
14
14
  const { addListener, removeListener } = useContext(SocketContext);
15
15
  /**
16
16
  * The most immediate of two levels of caching, this ref stores the raw promises for each hit.
17
17
  * Rapidly updates, good for uses in-context where parallel updates my be occurring, i.e.
18
- * when two cards request the same hit that's missing from the store. Used in getRecord for this reason.
18
+ * when two cards request the same hit that's missing from the store. Used in getHit for this reason.
19
19
  */
20
- const recordRequests = useRef({});
20
+ const hitRequests = useRef({});
21
21
  /**
22
22
  * The "Authoritative" store of hits. Changes here will trigger rerenders, and essentially
23
23
  * caches the result of the above promises. Slower to update, so used outside of the hitcontext
24
24
  * where parallel requests aren't an issue.
25
25
  */
26
- const [records, setRecords] = useState({});
26
+ const [hits, setHits] = useState({});
27
27
  const [selectedHitIds, setSelectedHitIds] = useState([]);
28
28
  // The central location where we propagate any changes from hits made via websockets into the repository. We just save every update,
29
29
  // instead of caching it across many components inconsistently as before.
@@ -31,8 +31,8 @@ const RecordProvider = ({ children }) => {
31
31
  if (data.hit) {
32
32
  // eslint-disable-next-line no-console
33
33
  console.debug('Received websocket update for hit', data.hit.howler.id);
34
- recordRequests.current[data.hit.howler.id] = Promise.resolve(data.hit);
35
- setRecords(_hits => ({
34
+ hitRequests.current[data.hit.howler.id] = Promise.resolve(data.hit);
35
+ setHits(_hits => ({
36
36
  ..._hits,
37
37
  [data.hit.howler.id]: {
38
38
  ..._hits[data.hit.howler.id],
@@ -46,68 +46,68 @@ const RecordProvider = ({ children }) => {
46
46
  return () => removeListener('hits');
47
47
  }, [addListener, handler, removeListener]);
48
48
  /**
49
- * A method to retrieve a record from the context. It first checks the hit state,
49
+ * A method to retrieve a hit from the context. It first checks the hit state,
50
50
  * then checks for ongoing requests, then finally executes a new request if necessary.
51
51
  */
52
- const getRecord = useCallback(async (id, force = false) => {
53
- if (!recordRequests.current[id] || force) {
54
- recordRequests.current[id] = dispatchApi(api.hit.get(id, ['template', 'dossiers', 'analytic', 'overview']));
55
- const newRecord = await recordRequests.current[id];
56
- setRecords(_records => ({ ..._records, [id]: newRecord }));
52
+ const getHit = useCallback(async (id, force = false) => {
53
+ if (!hitRequests.current[id] || force) {
54
+ hitRequests.current[id] = dispatchApi(api.hit.get(id, ['template', 'dossiers', 'analytic', 'overview']));
55
+ const newHit = await hitRequests.current[id];
56
+ setHits(_hits => ({ ..._hits, [id]: newHit }));
57
57
  }
58
- return recordRequests.current[id];
58
+ return hitRequests.current[id];
59
59
  }, [dispatchApi]);
60
60
  /**
61
61
  * Update a hit in the context locally
62
62
  */
63
- const updateRecord = useCallback((newHit) => {
64
- recordRequests.current[newHit.howler.id] = Promise.resolve(newHit);
65
- setRecords(_hits => ({ ..._hits, [newHit.howler.id]: newHit }));
63
+ const updateHit = useCallback((newHit) => {
64
+ hitRequests.current[newHit.howler.id] = Promise.resolve(newHit);
65
+ setHits(_hits => ({ ..._hits, [newHit.howler.id]: newHit }));
66
66
  }, []);
67
67
  /**
68
68
  * Add a large number of hits to the cache. Used for results of searches.
69
69
  */
70
- const loadRecords = useCallback((newHits) => {
70
+ const loadHits = useCallback((newHits) => {
71
71
  const mappedHits = newHits.map(hit => [hit.howler.id, hit]);
72
72
  mappedHits.forEach(([id, hit]) => {
73
- recordRequests.current[id] = Promise.resolve(hit);
73
+ hitRequests.current[id] = Promise.resolve(hit);
74
74
  });
75
- setRecords(_hits => ({ ..._hits, ...Object.fromEntries(mappedHits) }));
75
+ setHits(_hits => ({ ..._hits, ...Object.fromEntries(mappedHits) }));
76
76
  }, []);
77
- const addRecordToSelection = useCallback((id) => {
77
+ const addHitToSelection = useCallback((id) => {
78
78
  setSelectedHitIds(_selected => uniq([..._selected, id]));
79
79
  }, []);
80
- const removeRecordFromSelection = useCallback((id) => {
80
+ const removeHitFromSelection = useCallback((id) => {
81
81
  setSelectedHitIds(_selected => _selected.filter(_id => _id !== id));
82
82
  }, []);
83
- const clearSelectedRecords = useCallback((except) => {
83
+ const clearSelectedHits = useCallback((except) => {
84
84
  setSelectedHitIds(!!except ? [except] : []);
85
85
  }, []);
86
- const selectedRecords = useMemo(() => selectedHitIds.map(id => records[id]).filter(hit => !!hit), [records, selectedHitIds]);
86
+ const selectedHits = useMemo(() => selectedHitIds.map(id => hits[id]).filter(hit => !!hit), [hits, selectedHitIds]);
87
87
  useEffect(() => {
88
88
  selectedHitIds.forEach(id => {
89
- if (!recordRequests.current[id]) {
90
- getRecord(id);
89
+ if (!hitRequests.current[id]) {
90
+ getHit(id);
91
91
  }
92
92
  });
93
- }, [getRecord, selectedHitIds]);
93
+ }, [getHit, selectedHitIds]);
94
94
  useEffect(() => {
95
- Object.entries(records).forEach(([id, hit]) => {
96
- recordRequests.current[id] = Promise.resolve(hit);
95
+ Object.entries(hits).forEach(([id, hit]) => {
96
+ hitRequests.current[id] = Promise.resolve(hit);
97
97
  });
98
- }, [records]);
99
- return (_jsx(RecordContext.Provider, { value: {
100
- records,
101
- getRecord,
102
- updateRecord,
103
- selectedRecords,
104
- addRecordToSelection,
105
- removeRecordFromSelection,
106
- clearSelectedRecords,
107
- loadRecords
98
+ }, [hits]);
99
+ return (_jsx(HitContext.Provider, { value: {
100
+ hits,
101
+ getHit,
102
+ updateHit,
103
+ selectedHits,
104
+ addHitToSelection,
105
+ removeHitFromSelection,
106
+ clearSelectedHits,
107
+ loadHits
108
108
  }, children: children }));
109
109
  };
110
- export const useRecordContextSelector = (selector) => {
111
- return useContextSelector(RecordContext, selector);
110
+ export const useHitContextSelector = (selector) => {
111
+ return useContextSelector(HitContext, selector);
112
112
  };
113
- export default RecordProvider;
113
+ export default HitProvider;
@@ -1,17 +1,17 @@
1
1
  import type { HowlerSearchResponse } from '@cccsaurora/howler-ui/api/search';
2
2
  import { useMyLocalStorageItem } from '@cccsaurora/howler-ui/components/hooks/useMyLocalStorage';
3
3
  import type { Hit } from '@cccsaurora/howler-ui/models/entities/generated/Hit';
4
- import type { Observable } from '@cccsaurora/howler-ui/models/entities/generated/Observable';
5
4
  import type { WithMetadata } from '@cccsaurora/howler-ui/models/WithMetadata';
6
5
  import { type Dispatch, type FC, type PropsWithChildren, type SetStateAction } from 'react';
7
6
  export interface QueryEntry {
8
7
  [query: string]: string;
9
8
  }
10
- export interface RecordSearchContextType {
9
+ export interface HitSearchContextType {
11
10
  displayType: 'list' | 'grid';
12
11
  searching: boolean;
13
12
  error: string | null;
14
- response: HowlerSearchResponse<WithMetadata<Hit | Observable>> | null;
13
+ response: HowlerSearchResponse<WithMetadata<Hit>> | null;
14
+ bundleId: string | null;
15
15
  fzfSearch: boolean;
16
16
  setDisplayType: (type: 'list' | 'grid') => void;
17
17
  setFzfSearch: Dispatch<SetStateAction<boolean>>;
@@ -20,6 +20,6 @@ export interface RecordSearchContextType {
20
20
  queryHistory: QueryEntry;
21
21
  setQueryHistory: ReturnType<typeof useMyLocalStorageItem>[1];
22
22
  }
23
- export declare const RecordSearchContext: import("use-context-selector").Context<RecordSearchContextType>;
24
- declare const RecordSearchProvider: FC<PropsWithChildren>;
25
- export default RecordSearchProvider;
23
+ export declare const HitSearchContext: import("use-context-selector").Context<HitSearchContextType>;
24
+ declare const HitSearchProvider: FC<PropsWithChildren>;
25
+ export default HitSearchProvider;