@cccsaurora/howler-ui 2.19.0-dev.842 → 2.19.0-dev.897

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 (328) hide show
  1. package/api/index.d.ts +0 -4
  2. package/api/index.js +2 -10
  3. package/api/search/facet/hit.d.ts +3 -1
  4. package/api/search/facet/index.d.ts +1 -3
  5. package/api/search/index.d.ts +1 -2
  6. package/api/search/index.js +1 -2
  7. package/commons/components/leftnav/LeftNavDrawer.js +1 -1
  8. package/components/app/App.js +8 -41
  9. package/components/app/hooks/useMatchers.d.ts +1 -1
  10. package/components/app/hooks/useMatchers.js +11 -23
  11. package/components/app/hooks/useMatchers.test.js +22 -22
  12. package/components/app/hooks/useTitle.js +5 -5
  13. package/components/app/providers/FavouritesProvider.js +2 -2
  14. package/components/app/providers/HitProvider.d.ts +22 -0
  15. package/components/app/providers/{RecordProvider.js → HitProvider.js} +41 -41
  16. package/components/app/providers/{RecordSearchProvider.d.ts → HitSearchProvider.d.ts} +6 -6
  17. package/components/app/providers/{RecordSearchProvider.js → HitSearchProvider.js} +17 -12
  18. package/components/app/providers/{RecordSearchProvider.test.js → HitSearchProvider.test.js} +71 -52
  19. package/components/app/providers/ModalProvider.d.ts +0 -1
  20. package/components/app/providers/ParameterProvider.d.ts +2 -9
  21. package/components/app/providers/ParameterProvider.js +240 -165
  22. package/components/app/providers/ParameterProvider.test.js +94 -346
  23. package/components/app/providers/SocketProvider.d.ts +2 -11
  24. package/components/app/providers/SocketProvider.js +5 -18
  25. package/components/app/providers/UserListProvider.js +8 -28
  26. package/components/elements/PluginTypography.d.ts +1 -2
  27. package/components/elements/PluginTypography.js +2 -3
  28. package/components/elements/UserList.d.ts +2 -5
  29. package/components/elements/UserList.js +8 -18
  30. package/components/elements/addons/search/phrase/Phrase.js +1 -1
  31. package/components/elements/display/ChipPopper.d.ts +1 -1
  32. package/components/elements/display/ChipPopper.js +5 -5
  33. package/components/elements/display/HowlerCard.js +1 -1
  34. package/components/elements/display/Modal.js +0 -2
  35. package/components/elements/display/icons/BundleButton.d.ts +6 -0
  36. package/components/elements/display/icons/BundleButton.js +32 -0
  37. package/components/elements/hit/HitActions.js +4 -4
  38. package/components/elements/hit/HitBanner.d.ts +0 -1
  39. package/components/elements/hit/HitBanner.js +47 -29
  40. package/components/elements/hit/HitCard.d.ts +0 -2
  41. package/components/elements/hit/HitCard.js +7 -7
  42. package/components/elements/{record/RecordComments.d.ts → hit/HitComments.d.ts} +4 -5
  43. package/components/elements/{record/RecordComments.js → hit/HitComments.js} +28 -29
  44. package/components/elements/{ObjectDetails.js → hit/HitDetails.js} +17 -17
  45. package/components/elements/hit/HitLabels.js +2 -2
  46. package/components/elements/hit/HitOutline.d.ts +0 -1
  47. package/components/elements/hit/HitOutline.js +3 -3
  48. package/components/elements/hit/{HitPreview.d.ts → HitQuickSearch.d.ts} +3 -3
  49. package/components/elements/hit/{HitPreview.js → HitQuickSearch.js} +4 -10
  50. package/components/elements/hit/HitRelated.d.ts +6 -0
  51. package/components/elements/hit/HitRelated.js +7 -0
  52. package/components/elements/hit/HitSummary.d.ts +1 -2
  53. package/components/elements/hit/HitSummary.js +5 -6
  54. package/components/elements/{record/RecordWorklog.d.ts → hit/HitWorklog.d.ts} +3 -4
  55. package/components/elements/{record/RecordWorklog.js → hit/HitWorklog.js} +13 -15
  56. package/components/elements/hit/aggregate/HitGraph.js +8 -8
  57. package/components/elements/hit/elements/Assigned.js +3 -6
  58. package/components/elements/hit/outlines/DefaultOutline.js +1 -1
  59. package/components/elements/view/ViewTitle.d.ts +0 -1
  60. package/components/elements/view/ViewTitle.js +2 -9
  61. package/components/hooks/useHitActions.d.ts +1 -1
  62. package/components/hooks/useHitActions.js +4 -4
  63. package/components/hooks/{useRecordSelection.d.ts → useHitSelection.d.ts} +2 -2
  64. package/components/hooks/{useRecordSelection.js → useHitSelection.js} +33 -12
  65. package/components/hooks/useMyPreferences.js +1 -10
  66. package/components/hooks/useMySearch.js +2 -2
  67. package/components/hooks/useMySitemap.js +1 -4
  68. package/components/hooks/useMyTheme.js +2 -9
  69. package/components/routes/action/edit/ActionEditor.js +2 -2
  70. package/components/routes/action/view/ActionSearch.js +1 -1
  71. package/components/routes/advanced/QueryBuilder.js +1 -1
  72. package/components/routes/advanced/QueryEditor.js +3 -3
  73. package/components/routes/advanced/historyCompletionProvider.js +3 -3
  74. package/components/routes/analytics/AnalyticDetails.js +2 -2
  75. package/components/routes/analytics/AnalyticSearch.js +1 -1
  76. package/components/routes/dossiers/DossierEditor.js +2 -2
  77. package/components/routes/dossiers/DossierEditor.test.js +1 -1
  78. package/components/routes/help/ApiDocumentation.js +1 -1
  79. package/components/routes/help/BundleDocumentation.d.ts +3 -0
  80. package/components/routes/help/BundleDocumentation.js +12 -0
  81. package/components/routes/help/HitBannerDocumentation.js +0 -1
  82. package/components/routes/help/HitDocumentation.js +3 -1
  83. package/components/routes/help/markdown/en/bundles.md.js +1 -0
  84. package/components/routes/help/markdown/fr/bundles.md.js +1 -0
  85. package/components/routes/hits/search/BundleParentMenu.d.ts +6 -0
  86. package/components/routes/hits/search/BundleParentMenu.js +32 -0
  87. package/components/routes/hits/search/BundleScroller.d.ts +2 -0
  88. package/components/routes/hits/search/BundleScroller.js +6 -0
  89. package/components/routes/hits/search/{RecordBrowser.js → HitBrowser.js} +9 -9
  90. package/components/{elements/record/RecordContextMenu.d.ts → routes/hits/search/HitContextMenu.d.ts} +3 -3
  91. package/components/routes/hits/search/HitContextMenu.js +239 -0
  92. package/components/{elements/record/RecordContextMenu.test.js → routes/hits/search/HitContextMenu.test.js} +43 -98
  93. package/components/routes/hits/search/{RecordQuery.d.ts → HitQuery.d.ts} +2 -2
  94. package/components/routes/hits/search/{RecordQuery.js → HitQuery.js} +6 -6
  95. package/components/routes/hits/search/InformationPane.d.ts +0 -1
  96. package/components/routes/hits/search/InformationPane.js +63 -50
  97. package/components/routes/hits/search/LayoutSettings.js +3 -3
  98. package/components/routes/hits/search/QuerySettings.js +1 -2
  99. package/components/routes/hits/search/QuerySettings.test.js +9 -14
  100. package/components/routes/hits/search/SearchPane.js +49 -26
  101. package/components/routes/hits/search/ViewLink.js +3 -3
  102. package/components/routes/hits/search/ViewLink.test.js +8 -8
  103. package/components/routes/hits/search/grid/AddColumnModal.js +4 -5
  104. package/components/routes/hits/search/grid/EnhancedCell.d.ts +1 -2
  105. package/components/routes/hits/search/grid/EnhancedCell.js +2 -2
  106. package/components/routes/hits/search/grid/HitGrid.js +18 -20
  107. package/components/routes/hits/search/grid/{RecordRow.d.ts → HitRow.d.ts} +2 -3
  108. package/components/routes/hits/search/grid/{RecordRow.js → HitRow.js} +8 -10
  109. package/components/routes/hits/view/HitViewer.js +13 -12
  110. package/components/routes/home/ViewCard.js +41 -47
  111. package/components/{elements/MarkdownEditor.js → routes/overviews/OverviewEditor.js} +3 -3
  112. package/components/routes/overviews/OverviewViewer.js +2 -2
  113. package/components/routes/views/ViewComposer.js +19 -46
  114. package/locales/en/translation.json +3 -122
  115. package/locales/fr/translation.json +3 -120
  116. package/models/WithMetadata.d.ts +1 -2
  117. package/models/entities/generated/{ThreatEnrichment.d.ts → Enrichment.d.ts} +1 -1
  118. package/models/entities/generated/Hit.d.ts +0 -1
  119. package/models/entities/generated/Howler.d.ts +5 -0
  120. package/models/entities/generated/Rule.d.ts +9 -6
  121. package/models/entities/generated/Threat.d.ts +2 -2
  122. package/models/entities/generated/View.d.ts +0 -1
  123. package/package.json +121 -141
  124. package/plugins/clue/components/ClueTypography.js +2 -2
  125. package/plugins/clue/utils.d.ts +1 -2
  126. package/tests/mocks.d.ts +1 -11
  127. package/tests/mocks.js +7 -12
  128. package/tests/server-handlers.js +1 -6
  129. package/tests/utils.d.ts +0 -4
  130. package/tests/utils.js +0 -20
  131. package/utils/constants.d.ts +3 -4
  132. package/utils/constants.js +0 -6
  133. package/utils/hitFunctions.d.ts +1 -2
  134. package/utils/hitFunctions.js +4 -4
  135. package/utils/socketUtils.d.ts +0 -14
  136. package/utils/socketUtils.js +1 -17
  137. package/utils/viewUtils.js +0 -3
  138. package/api/search/case.d.ts +0 -4
  139. package/api/search/case.js +0 -8
  140. package/api/socket/index.d.ts +0 -3
  141. package/api/socket/index.js +0 -6
  142. package/api/socket/viewers.d.ts +0 -2
  143. package/api/socket/viewers.js +0 -8
  144. package/api/socket/viewers.test.js +0 -44
  145. package/api/v2/case/index.d.ts +0 -9
  146. package/api/v2/case/index.js +0 -21
  147. package/api/v2/case/items.d.ts +0 -6
  148. package/api/v2/case/items.js +0 -18
  149. package/api/v2/case/rules.d.ts +0 -6
  150. package/api/v2/case/rules.js +0 -18
  151. package/api/v2/index.d.ts +0 -4
  152. package/api/v2/index.js +0 -6
  153. package/api/v2/search/facet.d.ts +0 -3
  154. package/api/v2/search/facet.js +0 -12
  155. package/api/v2/search/index.d.ts +0 -5
  156. package/api/v2/search/index.js +0 -24
  157. package/components/app/providers/RecordProvider.d.ts +0 -23
  158. package/components/elements/ContextMenu.d.ts +0 -56
  159. package/components/elements/ContextMenu.js +0 -109
  160. package/components/elements/ContextMenu.test.d.ts +0 -1
  161. package/components/elements/ContextMenu.test.js +0 -215
  162. package/components/elements/ObjectDetails.d.ts +0 -6
  163. package/components/elements/case/CaseCard.d.ts +0 -12
  164. package/components/elements/case/CaseCard.js +0 -42
  165. package/components/elements/case/CasePreview.d.ts +0 -6
  166. package/components/elements/case/CasePreview.js +0 -17
  167. package/components/elements/case/StatusIcon.d.ts +0 -5
  168. package/components/elements/case/StatusIcon.js +0 -13
  169. package/components/elements/hit/elements/AnalyticLink.d.ts +0 -9
  170. package/components/elements/hit/elements/AnalyticLink.js +0 -22
  171. package/components/elements/hit/elements/Assigned.test.d.ts +0 -1
  172. package/components/elements/hit/elements/Assigned.test.js +0 -65
  173. package/components/elements/hit/related/RelatedRecords.js +0 -63
  174. package/components/elements/observable/ObservableCard.d.ts +0 -6
  175. package/components/elements/observable/ObservableCard.js +0 -22
  176. package/components/elements/observable/ObservablePreview.d.ts +0 -6
  177. package/components/elements/observable/ObservablePreview.js +0 -12
  178. package/components/elements/record/RecordContextMenu.js +0 -268
  179. package/components/elements/record/RecordContextMenu.test.d.ts +0 -1
  180. package/components/elements/record/RecordRelated.d.ts +0 -7
  181. package/components/elements/record/RecordRelated.js +0 -34
  182. package/components/hooks/useRelatedRecords.d.ts +0 -13
  183. package/components/hooks/useRelatedRecords.js +0 -32
  184. package/components/routes/cases/CaseViewer.d.ts +0 -2
  185. package/components/routes/cases/CaseViewer.js +0 -44
  186. package/components/routes/cases/CaseViewer.test.d.ts +0 -1
  187. package/components/routes/cases/CaseViewer.test.js +0 -133
  188. package/components/routes/cases/Cases.d.ts +0 -2
  189. package/components/routes/cases/Cases.js +0 -148
  190. package/components/routes/cases/constants.d.ts +0 -6
  191. package/components/routes/cases/constants.js +0 -6
  192. package/components/routes/cases/detail/AlertPanel.d.ts +0 -6
  193. package/components/routes/cases/detail/AlertPanel.js +0 -33
  194. package/components/routes/cases/detail/CaseAssets.d.ts +0 -11
  195. package/components/routes/cases/detail/CaseAssets.js +0 -104
  196. package/components/routes/cases/detail/CaseAssets.test.d.ts +0 -1
  197. package/components/routes/cases/detail/CaseAssets.test.js +0 -167
  198. package/components/routes/cases/detail/CaseDashboard.d.ts +0 -7
  199. package/components/routes/cases/detail/CaseDashboard.js +0 -66
  200. package/components/routes/cases/detail/CaseDetails.d.ts +0 -6
  201. package/components/routes/cases/detail/CaseDetails.js +0 -70
  202. package/components/routes/cases/detail/CaseOverview.d.ts +0 -7
  203. package/components/routes/cases/detail/CaseOverview.js +0 -43
  204. package/components/routes/cases/detail/CaseRules.d.ts +0 -7
  205. package/components/routes/cases/detail/CaseRules.js +0 -57
  206. package/components/routes/cases/detail/CaseRules.test.d.ts +0 -1
  207. package/components/routes/cases/detail/CaseRules.test.js +0 -221
  208. package/components/routes/cases/detail/CaseSidebar.d.ts +0 -8
  209. package/components/routes/cases/detail/CaseSidebar.js +0 -107
  210. package/components/routes/cases/detail/CaseSidebar.test.d.ts +0 -1
  211. package/components/routes/cases/detail/CaseSidebar.test.js +0 -266
  212. package/components/routes/cases/detail/CaseTask.d.ts +0 -11
  213. package/components/routes/cases/detail/CaseTask.js +0 -66
  214. package/components/routes/cases/detail/CaseTimeline.d.ts +0 -12
  215. package/components/routes/cases/detail/CaseTimeline.js +0 -106
  216. package/components/routes/cases/detail/CaseTimeline.test.d.ts +0 -1
  217. package/components/routes/cases/detail/CaseTimeline.test.js +0 -320
  218. package/components/routes/cases/detail/CreateRuleDialog.d.ts +0 -9
  219. package/components/routes/cases/detail/CreateRuleDialog.js +0 -163
  220. package/components/routes/cases/detail/CreateRuleDialog.test.d.ts +0 -1
  221. package/components/routes/cases/detail/CreateRuleDialog.test.js +0 -259
  222. package/components/routes/cases/detail/ItemPage.d.ts +0 -6
  223. package/components/routes/cases/detail/ItemPage.js +0 -95
  224. package/components/routes/cases/detail/RelatedCasePanel.d.ts +0 -6
  225. package/components/routes/cases/detail/RelatedCasePanel.js +0 -34
  226. package/components/routes/cases/detail/TaskPanel.d.ts +0 -7
  227. package/components/routes/cases/detail/TaskPanel.js +0 -52
  228. package/components/routes/cases/detail/aggregates/CaseAggregate.d.ts +0 -11
  229. package/components/routes/cases/detail/aggregates/CaseAggregate.js +0 -24
  230. package/components/routes/cases/detail/aggregates/SourceAggregate.d.ts +0 -6
  231. package/components/routes/cases/detail/aggregates/SourceAggregate.js +0 -26
  232. package/components/routes/cases/detail/assets/Asset.d.ts +0 -14
  233. package/components/routes/cases/detail/assets/Asset.js +0 -12
  234. package/components/routes/cases/detail/assets/Asset.test.d.ts +0 -1
  235. package/components/routes/cases/detail/assets/Asset.test.js +0 -72
  236. package/components/routes/cases/detail/sidebar/CaseFolder.d.ts +0 -20
  237. package/components/routes/cases/detail/sidebar/CaseFolder.js +0 -83
  238. package/components/routes/cases/detail/sidebar/CaseFolder.test.d.ts +0 -1
  239. package/components/routes/cases/detail/sidebar/CaseFolder.test.js +0 -295
  240. package/components/routes/cases/detail/sidebar/CaseFolderContextMenu.d.ts +0 -34
  241. package/components/routes/cases/detail/sidebar/CaseFolderContextMenu.js +0 -103
  242. package/components/routes/cases/detail/sidebar/CaseFolderContextMenu.test.d.ts +0 -1
  243. package/components/routes/cases/detail/sidebar/CaseFolderContextMenu.test.js +0 -363
  244. package/components/routes/cases/detail/sidebar/FolderEntry.d.ts +0 -25
  245. package/components/routes/cases/detail/sidebar/FolderEntry.js +0 -88
  246. package/components/routes/cases/detail/sidebar/FolderEntry.test.d.ts +0 -1
  247. package/components/routes/cases/detail/sidebar/FolderEntry.test.js +0 -206
  248. package/components/routes/cases/detail/sidebar/RootDropZone.d.ts +0 -5
  249. package/components/routes/cases/detail/sidebar/RootDropZone.js +0 -33
  250. package/components/routes/cases/detail/sidebar/types.d.ts +0 -9
  251. package/components/routes/cases/detail/sidebar/utils.d.ts +0 -3
  252. package/components/routes/cases/detail/sidebar/utils.js +0 -29
  253. package/components/routes/cases/detail/sidebar/utils.test.d.ts +0 -1
  254. package/components/routes/cases/detail/sidebar/utils.test.js +0 -82
  255. package/components/routes/cases/hooks/useCase.d.ts +0 -13
  256. package/components/routes/cases/hooks/useCase.js +0 -69
  257. package/components/routes/cases/hooks/useCase.test.d.ts +0 -1
  258. package/components/routes/cases/hooks/useCase.test.js +0 -141
  259. package/components/routes/cases/modals/AddToCaseModal.d.ts +0 -7
  260. package/components/routes/cases/modals/AddToCaseModal.js +0 -59
  261. package/components/routes/cases/modals/AddToCaseModal.test.d.ts +0 -1
  262. package/components/routes/cases/modals/AddToCaseModal.test.js +0 -313
  263. package/components/routes/cases/modals/CaseRecordRow.d.ts +0 -9
  264. package/components/routes/cases/modals/CaseRecordRow.js +0 -15
  265. package/components/routes/cases/modals/CreateCaseModal.d.ts +0 -7
  266. package/components/routes/cases/modals/CreateCaseModal.js +0 -55
  267. package/components/routes/cases/modals/CreateCaseModal.test.d.ts +0 -1
  268. package/components/routes/cases/modals/CreateCaseModal.test.js +0 -358
  269. package/components/routes/cases/modals/RenameItemModal.d.ts +0 -9
  270. package/components/routes/cases/modals/RenameItemModal.js +0 -48
  271. package/components/routes/cases/modals/ResolveModal.d.ts +0 -7
  272. package/components/routes/cases/modals/ResolveModal.js +0 -115
  273. package/components/routes/cases/modals/ResolveModal.test.d.ts +0 -1
  274. package/components/routes/cases/modals/ResolveModal.test.js +0 -394
  275. package/components/routes/cases/modals/hooks.d.ts +0 -7
  276. package/components/routes/cases/modals/hooks.js +0 -44
  277. package/components/routes/cases/modals/types.d.ts +0 -5
  278. package/components/routes/cases/search/CaseAssigneeFilter.d.ts +0 -6
  279. package/components/routes/cases/search/CaseAssigneeFilter.js +0 -33
  280. package/components/routes/cases/search/CaseAssigneeFilter.test.d.ts +0 -1
  281. package/components/routes/cases/search/CaseAssigneeFilter.test.js +0 -127
  282. package/components/routes/cases/search/CaseDateFilter.d.ts +0 -13
  283. package/components/routes/cases/search/CaseDateFilter.js +0 -26
  284. package/components/routes/cases/search/CaseDateFilter.test.d.ts +0 -1
  285. package/components/routes/cases/search/CaseDateFilter.test.js +0 -115
  286. package/components/routes/cases/search/CaseStatusFilter.d.ts +0 -6
  287. package/components/routes/cases/search/CaseStatusFilter.js +0 -13
  288. package/components/routes/cases/search/CaseStatusFilter.test.d.ts +0 -1
  289. package/components/routes/cases/search/CaseStatusFilter.test.js +0 -86
  290. package/components/routes/hits/search/shared/IndexPicker.d.ts +0 -2
  291. package/components/routes/hits/search/shared/IndexPicker.js +0 -20
  292. package/components/routes/observables/ObservableViewer.d.ts +0 -7
  293. package/components/routes/observables/ObservableViewer.js +0 -27
  294. package/models/entities/generated/AttachmentsFile.d.ts +0 -12
  295. package/models/entities/generated/Case.d.ts +0 -28
  296. package/models/entities/generated/DestinationOriginal.d.ts +0 -19
  297. package/models/entities/generated/EmailAttachment.d.ts +0 -8
  298. package/models/entities/generated/EmailParent.d.ts +0 -19
  299. package/models/entities/generated/Enrichments.d.ts +0 -7
  300. package/models/entities/generated/EnrichmentsIndicator.d.ts +0 -21
  301. package/models/entities/generated/HttpResponse.d.ts +0 -11
  302. package/models/entities/generated/Item.d.ts +0 -9
  303. package/models/entities/generated/Observable.d.ts +0 -85
  304. package/models/entities/generated/ObservableCloud.d.ts +0 -20
  305. package/models/entities/generated/ObservableDestination.d.ts +0 -23
  306. package/models/entities/generated/ObservableEmail.d.ts +0 -30
  307. package/models/entities/generated/ObservableFile.d.ts +0 -36
  308. package/models/entities/generated/ObservableHowler.d.ts +0 -42
  309. package/models/entities/generated/ObservableHttp.d.ts +0 -11
  310. package/models/entities/generated/ObservableObserver.d.ts +0 -21
  311. package/models/entities/generated/ObservableOrganization.d.ts +0 -7
  312. package/models/entities/generated/ObservableProcess.d.ts +0 -34
  313. package/models/entities/generated/ObservableSource.d.ts +0 -23
  314. package/models/entities/generated/ObservableThreat.d.ts +0 -21
  315. package/models/entities/generated/ObservableTls.d.ts +0 -12
  316. package/models/entities/generated/ObserverIngress.d.ts +0 -9
  317. package/models/entities/generated/Task.d.ts +0 -10
  318. package/models/socket/CaseUpdate.d.ts +0 -5
  319. package/models/socket/ViewersUpdate.d.ts +0 -4
  320. package/utils/socketUtils.test.d.ts +0 -1
  321. package/utils/socketUtils.test.js +0 -59
  322. package/utils/typeUtils.d.ts +0 -7
  323. package/utils/typeUtils.js +0 -27
  324. /package/{api/socket/viewers.test.d.ts → components/app/providers/HitSearchProvider.test.d.ts} +0 -0
  325. /package/components/elements/hit/{related/RelatedRecords.d.ts → HitDetails.d.ts} +0 -0
  326. /package/components/routes/hits/search/{RecordBrowser.d.ts → HitBrowser.d.ts} +0 -0
  327. /package/components/{app/providers/RecordSearchProvider.test.d.ts → routes/hits/search/HitContextMenu.test.d.ts} +0 -0
  328. /package/components/{elements/MarkdownEditor.d.ts → routes/overviews/OverviewEditor.d.ts} +0 -0
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { ChevronLeft, Close, ManageSearch } from '@mui/icons-material';
3
3
  import { Box, Card, Checkbox, Collapse, Drawer, Fab, IconButton, Stack, Tooltip, Typography, useMediaQuery, useTheme } from '@mui/material';
4
+ import { HitContext } from '@cccsaurora/howler-ui/components/app/providers/HitProvider';
5
+ import HitSearchProvider, { HitSearchContext } from '@cccsaurora/howler-ui/components/app/providers/HitSearchProvider';
4
6
  import ParameterProvider, { ParameterContext } from '@cccsaurora/howler-ui/components/app/providers/ParameterProvider';
5
- import { RecordContext } from '@cccsaurora/howler-ui/components/app/providers/RecordProvider';
6
- import RecordSearchProvider, { RecordSearchContext } from '@cccsaurora/howler-ui/components/app/providers/RecordSearchProvider';
7
7
  import { ViewContext } from '@cccsaurora/howler-ui/components/app/providers/ViewProvider';
8
8
  import FlexOne from '@cccsaurora/howler-ui/components/elements/addons/layout/FlexOne';
9
9
  import FlexPort from '@cccsaurora/howler-ui/components/elements/addons/layout/FlexPort';
@@ -32,14 +32,14 @@ const HitBrowser = () => {
32
32
  const setQuery = useContextSelector(ParameterContext, ctx => ctx.setQuery);
33
33
  const setOffset = useContextSelector(ParameterContext, ctx => ctx.setOffset);
34
34
  const selectedViews = useContextSelector(ParameterContext, ctx => ctx.views);
35
- const selectedHits = useContextSelector(RecordContext, ctx => ctx.selectedRecords);
36
- const addHitToSelection = useContextSelector(RecordContext, ctx => ctx.addRecordToSelection);
37
- const removeHitFromSelection = useContextSelector(RecordContext, ctx => ctx.removeRecordFromSelection);
38
- const clearSelectedHits = useContextSelector(RecordContext, ctx => ctx.clearSelectedRecords);
35
+ const selectedHits = useContextSelector(HitContext, ctx => ctx.selectedHits);
36
+ const addHitToSelection = useContextSelector(HitContext, ctx => ctx.addHitToSelection);
37
+ const removeHitFromSelection = useContextSelector(HitContext, ctx => ctx.removeHitFromSelection);
38
+ const clearSelectedHits = useContextSelector(HitContext, ctx => ctx.clearSelectedHits);
39
39
  const searchPaneWidth = useMyLocalStorageItem(StorageKey.SEARCH_PANE_WIDTH, null)[0];
40
40
  const forceDrawer = useMyLocalStorageItem(StorageKey.FORCE_DRAWER, false)[0];
41
- const displayType = useContextSelector(RecordSearchContext, ctx => ctx.displayType);
42
- const response = useContextSelector(RecordSearchContext, ctx => ctx.response);
41
+ const displayType = useContextSelector(HitSearchContext, ctx => ctx.displayType);
42
+ const response = useContextSelector(HitSearchContext, ctx => ctx.response);
43
43
  const location = useLocation();
44
44
  const routeParams = useParams();
45
45
  const [show, setShow] = useState(!!selected);
@@ -128,6 +128,6 @@ const HitBrowser = () => {
128
128
  }, children: _jsx(ChevronLeft, { sx: { transition: 'rotate 250ms', rotate: show ? '180deg' : '0deg' } }) }))] }));
129
129
  };
130
130
  const HitBrowserProvider = () => {
131
- return (_jsx(ParameterProvider, { children: _jsx(RecordSearchProvider, { children: _jsx(HitBrowser, {}) }) }));
131
+ return (_jsx(ParameterProvider, { children: _jsx(HitSearchProvider, { children: _jsx(HitBrowser, {}) }) }));
132
132
  };
133
133
  export default HitBrowserProvider;
@@ -3,7 +3,7 @@ import React from 'react';
3
3
  /**
4
4
  * Props for the HitContextMenu component
5
5
  */
6
- interface RecordContextMenuProps {
6
+ interface HitContextMenuProps {
7
7
  /**
8
8
  * Function to extract the hit ID from a mouse event
9
9
  */
@@ -18,5 +18,5 @@ interface RecordContextMenuProps {
18
18
  * Provides quick access to common hit actions including assessment, voting,
19
19
  * transitions, and exclusion filters based on template fields.
20
20
  */
21
- declare const RecordContextMenu: FC<PropsWithChildren<RecordContextMenuProps>>;
22
- export default RecordContextMenu;
21
+ declare const HitContextMenu: FC<PropsWithChildren<HitContextMenuProps>>;
22
+ export default HitContextMenu;
@@ -0,0 +1,239 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { AddCircleOutline, Assignment, Edit, HowToVote, KeyboardArrowRight, OpenInNew, QueryStats, RemoveCircleOutline, SettingsSuggest, Terminal } from '@mui/icons-material';
3
+ import { Box, Divider, Fade, ListItemIcon, ListItemText, Menu, MenuItem, MenuList, Paper } from '@mui/material';
4
+ import api from '@cccsaurora/howler-ui/api';
5
+ import { useAppUser } from '@cccsaurora/howler-ui/commons/components/app/hooks';
6
+ import useMatchers from '@cccsaurora/howler-ui/components/app/hooks/useMatchers';
7
+ import { ApiConfigContext } from '@cccsaurora/howler-ui/components/app/providers/ApiConfigProvider';
8
+ import { HitContext } from '@cccsaurora/howler-ui/components/app/providers/HitProvider';
9
+ import { ParameterContext } from '@cccsaurora/howler-ui/components/app/providers/ParameterProvider';
10
+ import { TOP_ROW, VOTE_OPTIONS } from '@cccsaurora/howler-ui/components/elements/hit/actions/SharedComponents';
11
+ import useHitActions from '@cccsaurora/howler-ui/components/hooks/useHitActions';
12
+ import useMyApi from '@cccsaurora/howler-ui/components/hooks/useMyApi';
13
+ import useMyActionFunctions from '@cccsaurora/howler-ui/components/routes/action/useMyActionFunctions';
14
+ import { capitalize, get, groupBy, isEmpty, toString } from 'lodash-es';
15
+ import howlerPluginStore from '@cccsaurora/howler-ui/plugins/store';
16
+ import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
17
+ import { useTranslation } from 'react-i18next';
18
+ import { usePluginStore } from 'react-pluggable';
19
+ import { Link } from 'react-router-dom';
20
+ import { useContextSelector } from 'use-context-selector';
21
+ import { DEFAULT_QUERY } from '@cccsaurora/howler-ui/utils/constants';
22
+ import { sanitizeLuceneQuery } from '@cccsaurora/howler-ui/utils/stringUtils';
23
+ /**
24
+ * Order in which action types should be displayed in the context menu
25
+ */
26
+ const ORDER = ['assessment', 'vote', 'action'];
27
+ /**
28
+ * The margin at the bottom of the screen by which the context menu should be inverted.
29
+ * That is, if right clicking within this many pixels of the bottom, render the context menu to the top right
30
+ * of the pointer instead of the bottom right.
31
+ */
32
+ const CONTEXTMENU_MARGIN = 350;
33
+ /**
34
+ * Icon mapping for different action types
35
+ */
36
+ const ICON_MAP = {
37
+ assessment: _jsx(Assignment, {}),
38
+ vote: _jsx(HowToVote, {}),
39
+ action: _jsx(Edit, {})
40
+ };
41
+ /**
42
+ * Context menu component for hit operations.
43
+ * Provides quick access to common hit actions including assessment, voting,
44
+ * transitions, and exclusion filters based on template fields.
45
+ */
46
+ const HitContextMenu = ({ children, getSelectedId, Component = Box }) => {
47
+ const { t } = useTranslation();
48
+ const { dispatchApi } = useMyApi();
49
+ const { executeAction } = useMyActionFunctions();
50
+ const appUser = useAppUser();
51
+ const { config } = useContext(ApiConfigContext);
52
+ const pluginStore = usePluginStore();
53
+ const { getMatchingAnalytic, getMatchingTemplate } = useMatchers();
54
+ const query = useContextSelector(ParameterContext, ctx => ctx?.query);
55
+ const setQuery = useContextSelector(ParameterContext, ctx => ctx?.setQuery);
56
+ const [id, setId] = useState(null);
57
+ const hit = useContextSelector(HitContext, ctx => ctx.hits[id]);
58
+ const selectedHits = useContextSelector(HitContext, ctx => ctx.selectedHits);
59
+ const [analytic, setAnalytic] = useState(null);
60
+ const [template, setTemplate] = useState(null);
61
+ const [anchorEl, setAnchorEl] = useState();
62
+ const [transformProps, setTransformProps] = useState({});
63
+ const [actions, setActions] = useState([]);
64
+ const [show, setShow] = useState({});
65
+ const hits = useMemo(() => (selectedHits.some(_hit => _hit.howler.id === hit?.howler.id) ? selectedHits : [hit]), [hit, selectedHits]);
66
+ const { availableTransitions, canVote, canAssess, assess, vote } = useHitActions(hits);
67
+ /**
68
+ * Checks if the current user has permission to run actions.
69
+ * Users must have one of the automation or actionrunner roles, or be an admin.
70
+ */
71
+ const canRunActions = useCallback(() => {
72
+ const roles = ['admin', 'automation_advanced', 'automation_basic', 'actionrunner_advanced', 'actionrunner_basic'];
73
+ return roles.some((role) => appUser.user?.roles?.includes(role));
74
+ }, [appUser.user?.roles]);
75
+ /**
76
+ * Handles right-click context menu events.
77
+ * Opens the context menu at the click location and loads available actions.
78
+ */
79
+ const onContextMenu = useCallback(async (event) => {
80
+ if (anchorEl) {
81
+ event.preventDefault();
82
+ setAnchorEl(null);
83
+ return;
84
+ }
85
+ event.preventDefault();
86
+ const _id = getSelectedId(event);
87
+ setId(_id);
88
+ if (window.innerHeight - event.clientY < 300) {
89
+ setTransformProps({
90
+ position: 'fixed',
91
+ bottom: `${window.innerHeight - event.clientY}px !important`,
92
+ top: 'unset !important',
93
+ left: `${event.clientX}px !important`
94
+ });
95
+ }
96
+ else {
97
+ setTransformProps({
98
+ position: 'fixed',
99
+ top: `${event.clientY}px !important`,
100
+ left: `${event.clientX}px !important`
101
+ });
102
+ }
103
+ setAnchorEl(event.target);
104
+ // TODO: Bumping the number of rows is a temporary fix - we'll need to improve this.
105
+ const _actions = (await dispatchApi(api.search.action.post({ query: 'action_id:*', rows: 100, sort: 'name asc' }), {
106
+ throwError: false
107
+ }))?.items;
108
+ if (_actions) {
109
+ setActions(_actions);
110
+ }
111
+ }, [anchorEl, dispatchApi, getSelectedId]);
112
+ const rowStatus = useMemo(() => ({
113
+ assessment: canAssess,
114
+ vote: canVote
115
+ }), [canAssess, canVote]);
116
+ const pluginActions = howlerPluginStore.plugins.flatMap(plugin => pluginStore.executeFunction(`${plugin}.actions`, hits));
117
+ /**
118
+ * Generates grouped action entries for the context menu.
119
+ * Combines transitions, plugin actions, votes, and assessments based on permissions.
120
+ */
121
+ const entries = useMemo(() => {
122
+ let _actions = [...availableTransitions, ...pluginActions];
123
+ if (canVote) {
124
+ _actions = [
125
+ ..._actions,
126
+ ...VOTE_OPTIONS.map(option => ({ ...option, actionFunction: () => vote(option.name.toLowerCase()) }))
127
+ ];
128
+ }
129
+ if (config.lookups?.['howler.assessment'] && canAssess) {
130
+ _actions = [
131
+ ..._actions,
132
+ ...config.lookups['howler.assessment']
133
+ .filter(_assessment => analytic?.triage_settings?.valid_assessments
134
+ ? analytic.triage_settings?.valid_assessments.includes(_assessment)
135
+ : true)
136
+ .sort((a, b) => +TOP_ROW.includes(b) - +TOP_ROW.includes(a))
137
+ .map(assessment => ({
138
+ type: 'assessment',
139
+ name: assessment,
140
+ actionFunction: async () => {
141
+ await assess(assessment, analytic?.triage_settings?.skip_rationale);
142
+ }
143
+ }))
144
+ ];
145
+ }
146
+ return Object.entries(groupBy(_actions, 'type')).sort(([a], [b]) => ORDER.indexOf(a) - ORDER.indexOf(b));
147
+ }, [analytic, assess, availableTransitions, canAssess, canVote, config.lookups, vote, pluginActions]);
148
+ /**
149
+ * Calculates appropriate styles for submenu positioning.
150
+ * Adjusts position based on available screen space to prevent overflow.
151
+ */
152
+ const calculateSubMenuStyles = useCallback((parent) => {
153
+ const baseStyles = { position: 'absolute', maxHeight: '300px', overflow: 'auto' };
154
+ const defaultStyles = { ...baseStyles, top: 0, left: '100%' };
155
+ if (!parent) {
156
+ return defaultStyles;
157
+ }
158
+ const parentBounds = parent.getBoundingClientRect();
159
+ if (window.innerHeight - parentBounds.y < CONTEXTMENU_MARGIN) {
160
+ return { ...baseStyles, bottom: 0, left: '100%' };
161
+ }
162
+ return defaultStyles;
163
+ }, []);
164
+ // Load analytic and template data when a hit is selected
165
+ useEffect(() => {
166
+ if (!hit?.howler.analytic) {
167
+ return;
168
+ }
169
+ getMatchingAnalytic(hit).then(setAnalytic);
170
+ getMatchingTemplate(hit).then(setTemplate);
171
+ // eslint-disable-next-line react-hooks/exhaustive-deps
172
+ }, [hit]);
173
+ // Reset menu state when context menu is closed
174
+ useEffect(() => {
175
+ if (!anchorEl) {
176
+ setShow({});
177
+ setAnalytic(null);
178
+ }
179
+ }, [anchorEl]);
180
+ return (_jsxs(Component, { id: "contextMenu", onContextMenu: onContextMenu, children: [children, _jsxs(Menu, { id: "hit-menu", open: !!anchorEl, anchorEl: anchorEl, onClose: () => setAnchorEl(null), slotProps: {
181
+ paper: {
182
+ sx: {
183
+ ...transformProps,
184
+ overflow: 'visible !important'
185
+ }
186
+ }
187
+ }, MenuListProps: { dense: true, sx: { minWidth: '250px' } }, anchorOrigin: { vertical: 'top', horizontal: 'left' }, onClick: () => setAnchorEl(null), children: [_jsxs(MenuItem, { component: Link, to: `/hits/${hit?.howler.id}`, disabled: !hit, children: [_jsx(ListItemIcon, { children: _jsx(OpenInNew, {}) }), _jsx(ListItemText, { children: t('hit.panel.open') })] }), _jsxs(MenuItem, { component: Link, to: `/analytics/${analytic?.analytic_id}`, disabled: !analytic, children: [_jsx(ListItemIcon, { children: _jsx(QueryStats, {}) }), _jsx(ListItemText, { children: t('hit.panel.analytic.open') })] }), _jsx(Divider, {}), entries.map(([type, items]) => (_jsxs(MenuItem, { id: `${type}-menu-item`, sx: { position: 'relative' }, onMouseEnter: ev => setShow(_show => ({ ..._show, [type]: ev.target })), onMouseLeave: () => setShow(_show => ({ ..._show, [type]: null })), disabled: rowStatus[type] === false, children: [_jsx(ListItemIcon, { children: ICON_MAP[type] ?? _jsx(Terminal, {}) }), _jsx(ListItemText, { sx: { flex: 1 }, children: t(`hit.details.actions.${type}`) }), rowStatus[type] !== false && (_jsx(KeyboardArrowRight, { fontSize: "small", sx: { color: 'text.secondary', mr: -1 } })), _jsx(Fade, { in: !!show[type], unmountOnExit: true, children: _jsx(Paper, { id: `${type}-submenu`, sx: calculateSubMenuStyles(show[type]), elevation: 8, children: _jsx(MenuList, { sx: { p: 0, borderTopLeftRadius: 0 }, dense: true, role: "group", children: items.map(a => (_jsx(MenuItem, { value: a.name, onClick: a.actionFunction, children: a.i18nKey ? t(a.i18nKey) : capitalize(a.name) }, a.name))) }) }) })] }, type))), _jsxs(MenuItem, { id: "actions-menu-item", sx: { position: 'relative' }, onMouseEnter: ev => setShow(_show => ({ ..._show, actions: ev.target })), onMouseLeave: () => setShow(_show => ({ ..._show, actions: null })), disabled: actions.length < 1 || !canRunActions(), children: [_jsx(ListItemIcon, { children: _jsx(SettingsSuggest, {}) }), _jsx(ListItemText, { sx: { flex: 1 }, children: t('route.actions.change') }), actions.length > 0 && _jsx(KeyboardArrowRight, { fontSize: "small", sx: { color: 'text.secondary', mr: -1 } }), _jsx(Fade, { in: !!show.actions, unmountOnExit: true, children: _jsx(Paper, { id: "actions-submenu", sx: calculateSubMenuStyles(show.actions), elevation: 8, children: _jsx(MenuList, { sx: { p: 0 }, dense: true, role: "group", children: actions.map(action => (_jsx(MenuItem, { onClick: () => executeAction(action.action_id, `howler.id:${hit?.howler.id}`), children: _jsx(ListItemText, { children: action.name }) }, action.action_id))) }) }) })] }), !isEmpty(template?.keys ?? []) && setQuery && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsxs(MenuItem, { id: "excludes-menu-item", sx: { position: 'relative' }, onMouseEnter: ev => setShow(_show => ({ ..._show, excludes: ev.target })), onMouseLeave: () => setShow(_show => ({ ..._show, excludes: null })), children: [_jsx(ListItemIcon, { children: _jsx(RemoveCircleOutline, {}) }), _jsx(ListItemText, { sx: { flex: 1 }, children: t('hit.panel.exclude') }), _jsx(KeyboardArrowRight, { fontSize: "small", sx: { color: 'text.secondary', mr: -1 } }), _jsx(Fade, { in: !!show.excludes, unmountOnExit: true, children: _jsx(Paper, { id: "excludes-submenu", sx: calculateSubMenuStyles(show.excludes), elevation: 8, children: _jsx(MenuList, { sx: { p: 0 }, dense: true, role: "group", children: template?.keys.map(key => {
188
+ // Build exclusion query based on current query and field value
189
+ let newQuery = '';
190
+ if (query !== DEFAULT_QUERY) {
191
+ newQuery = `(${query}) AND `;
192
+ }
193
+ const value = get(hit, key);
194
+ if (!value) {
195
+ return null;
196
+ }
197
+ else if (Array.isArray(value)) {
198
+ // Handle array values by excluding all items
199
+ const sanitizedValues = value
200
+ .map(toString)
201
+ .filter(val => !!val)
202
+ .map(val => `"${sanitizeLuceneQuery(val)}"`);
203
+ if (sanitizedValues.length < 1) {
204
+ return null;
205
+ }
206
+ newQuery += `-${key}:(${sanitizedValues.join(' OR ')})`;
207
+ }
208
+ else {
209
+ // Handle single value
210
+ newQuery += `-${key}:"${sanitizeLuceneQuery(value.toString())}"`;
211
+ }
212
+ return (_jsx(MenuItem, { onClick: () => setQuery(newQuery), children: _jsx(ListItemText, { children: key }) }, key));
213
+ }) }) }) })] }), _jsxs(MenuItem, { id: "includes-menu-item", sx: { position: 'relative' }, onMouseEnter: ev => setShow(_show => ({ ..._show, includes: ev.target })), onMouseLeave: () => setShow(_show => ({ ..._show, includes: null })), children: [_jsx(ListItemIcon, { children: _jsx(AddCircleOutline, {}) }), _jsx(ListItemText, { sx: { flex: 1 }, children: t('hit.panel.include') }), _jsx(KeyboardArrowRight, { fontSize: "small", sx: { color: 'text.secondary', mr: -1 } }), _jsx(Fade, { in: !!show.includes, unmountOnExit: true, children: _jsx(Paper, { id: "includes-submenu", sx: calculateSubMenuStyles(show.includes), elevation: 8, children: _jsx(MenuList, { sx: { p: 0 }, dense: true, role: "group", children: template?.keys.map(key => {
214
+ // Build inclusion query based on current query and field
215
+ // If default, we include default query
216
+ let newQuery = `(${query}) AND `;
217
+ const value = get(hit, key);
218
+ if (!value) {
219
+ return null;
220
+ }
221
+ else if (Array.isArray(value)) {
222
+ // Handle array values by including all items
223
+ const sanitizedValues = value
224
+ .map(toString)
225
+ .filter(val => !!val)
226
+ .map(val => `"${sanitizeLuceneQuery(val)}"`);
227
+ if (sanitizedValues.length < 1) {
228
+ return null;
229
+ }
230
+ newQuery += `${key}:(${sanitizedValues.join(' OR ')})`;
231
+ }
232
+ else {
233
+ // Handle single value
234
+ newQuery += `${key}:"${sanitizeLuceneQuery(value.toString())}"`;
235
+ }
236
+ return (_jsx(MenuItem, { onClick: () => setQuery(newQuery), children: _jsx(ListItemText, { children: key }) }, key));
237
+ }) }) }) })] })] }))] })] }));
238
+ };
239
+ export default HitContextMenu;