openvsx-webui-test 0.17.1 → 0.18.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/lib/components/button-with-progress.d.ts +1 -0
  2. package/lib/components/button-with-progress.d.ts.map +1 -1
  3. package/lib/components/button-with-progress.js +1 -1
  4. package/lib/components/button-with-progress.js.map +1 -1
  5. package/lib/components/sanitized-markdown.d.ts.map +1 -1
  6. package/lib/components/sanitized-markdown.js +79 -1
  7. package/lib/components/sanitized-markdown.js.map +1 -1
  8. package/lib/components/scan-admin/common/auto-refresh.d.ts +21 -0
  9. package/lib/components/scan-admin/common/auto-refresh.d.ts.map +1 -0
  10. package/lib/components/scan-admin/common/auto-refresh.js +45 -0
  11. package/lib/components/scan-admin/common/auto-refresh.js.map +1 -0
  12. package/lib/components/scan-admin/common/conditional-tooltip.d.ts +24 -0
  13. package/lib/components/scan-admin/common/conditional-tooltip.d.ts.map +1 -0
  14. package/lib/components/scan-admin/common/conditional-tooltip.js +63 -0
  15. package/lib/components/scan-admin/common/conditional-tooltip.js.map +1 -0
  16. package/lib/components/scan-admin/common/file-table.d.ts +23 -0
  17. package/lib/components/scan-admin/common/file-table.d.ts.map +1 -0
  18. package/lib/components/scan-admin/common/file-table.js +350 -0
  19. package/lib/components/scan-admin/common/file-table.js.map +1 -0
  20. package/lib/components/scan-admin/common/index.d.ts +18 -0
  21. package/lib/components/scan-admin/common/index.d.ts.map +1 -0
  22. package/lib/components/scan-admin/common/index.js +18 -0
  23. package/lib/components/scan-admin/common/index.js.map +1 -0
  24. package/lib/components/scan-admin/common/tab-panel.d.ts +25 -0
  25. package/lib/components/scan-admin/common/tab-panel.d.ts.map +1 -0
  26. package/lib/components/scan-admin/common/tab-panel.js +22 -0
  27. package/lib/components/scan-admin/common/tab-panel.js.map +1 -0
  28. package/lib/components/scan-admin/common/utils.d.ts +15 -0
  29. package/lib/components/scan-admin/common/utils.d.ts.map +1 -0
  30. package/lib/components/scan-admin/common/utils.js +46 -0
  31. package/lib/components/scan-admin/common/utils.js.map +1 -0
  32. package/lib/components/scan-admin/dialogs/file-dialog.d.ts +19 -0
  33. package/lib/components/scan-admin/dialogs/file-dialog.d.ts.map +1 -0
  34. package/lib/components/scan-admin/dialogs/file-dialog.js +85 -0
  35. package/lib/components/scan-admin/dialogs/file-dialog.js.map +1 -0
  36. package/lib/components/scan-admin/dialogs/index.d.ts +15 -0
  37. package/lib/components/scan-admin/dialogs/index.d.ts.map +1 -0
  38. package/lib/components/scan-admin/dialogs/index.js +15 -0
  39. package/lib/components/scan-admin/dialogs/index.js.map +1 -0
  40. package/lib/components/scan-admin/dialogs/quarantine-dialog.d.ts +23 -0
  41. package/lib/components/scan-admin/dialogs/quarantine-dialog.d.ts.map +1 -0
  42. package/lib/components/scan-admin/dialogs/quarantine-dialog.js +192 -0
  43. package/lib/components/scan-admin/dialogs/quarantine-dialog.js.map +1 -0
  44. package/lib/components/scan-admin/index.d.ts +20 -0
  45. package/lib/components/scan-admin/index.d.ts.map +1 -0
  46. package/lib/components/scan-admin/index.js +25 -0
  47. package/lib/components/scan-admin/index.js.map +1 -0
  48. package/lib/components/scan-admin/scan-card/index.d.ts +20 -0
  49. package/lib/components/scan-admin/scan-card/index.d.ts.map +1 -0
  50. package/lib/components/scan-admin/scan-card/index.js +20 -0
  51. package/lib/components/scan-admin/scan-card/index.js.map +1 -0
  52. package/lib/components/scan-admin/scan-card/scan-card-content.d.ts +30 -0
  53. package/lib/components/scan-admin/scan-card/scan-card-content.d.ts.map +1 -0
  54. package/lib/components/scan-admin/scan-card/scan-card-content.js +232 -0
  55. package/lib/components/scan-admin/scan-card/scan-card-content.js.map +1 -0
  56. package/lib/components/scan-admin/scan-card/scan-card-expand-strip-badges.d.ts +26 -0
  57. package/lib/components/scan-admin/scan-card/scan-card-expand-strip-badges.d.ts.map +1 -0
  58. package/lib/components/scan-admin/scan-card/scan-card-expand-strip-badges.js +121 -0
  59. package/lib/components/scan-admin/scan-card/scan-card-expand-strip-badges.js.map +1 -0
  60. package/lib/components/scan-admin/scan-card/scan-card-expand-strip.d.ts +27 -0
  61. package/lib/components/scan-admin/scan-card/scan-card-expand-strip.d.ts.map +1 -0
  62. package/lib/components/scan-admin/scan-card/scan-card-expand-strip.js +66 -0
  63. package/lib/components/scan-admin/scan-card/scan-card-expand-strip.js.map +1 -0
  64. package/lib/components/scan-admin/scan-card/scan-card-expanded-content.d.ts +26 -0
  65. package/lib/components/scan-admin/scan-card/scan-card-expanded-content.d.ts.map +1 -0
  66. package/lib/components/scan-admin/scan-card/scan-card-expanded-content.js +151 -0
  67. package/lib/components/scan-admin/scan-card/scan-card-expanded-content.js.map +1 -0
  68. package/lib/components/scan-admin/scan-card/scan-card-header.d.ts +26 -0
  69. package/lib/components/scan-admin/scan-card/scan-card-header.d.ts.map +1 -0
  70. package/lib/components/scan-admin/scan-card/scan-card-header.js +101 -0
  71. package/lib/components/scan-admin/scan-card/scan-card-header.js.map +1 -0
  72. package/lib/components/scan-admin/scan-card/scan-card.d.ts +34 -0
  73. package/lib/components/scan-admin/scan-card/scan-card.d.ts.map +1 -0
  74. package/lib/components/scan-admin/scan-card/scan-card.js +90 -0
  75. package/lib/components/scan-admin/scan-card/scan-card.js.map +1 -0
  76. package/lib/components/scan-admin/scan-card/scan-detail-card.d.ts +38 -0
  77. package/lib/components/scan-admin/scan-card/scan-detail-card.d.ts.map +1 -0
  78. package/lib/components/scan-admin/scan-card/scan-detail-card.js +72 -0
  79. package/lib/components/scan-admin/scan-card/scan-detail-card.js.map +1 -0
  80. package/lib/components/scan-admin/scan-card/utils.d.ts +48 -0
  81. package/lib/components/scan-admin/scan-card/utils.d.ts.map +1 -0
  82. package/lib/components/scan-admin/scan-card/utils.js +166 -0
  83. package/lib/components/scan-admin/scan-card/utils.js.map +1 -0
  84. package/lib/components/scan-admin/tab-contents/allow-list-tab-content.d.ts +19 -0
  85. package/lib/components/scan-admin/tab-contents/allow-list-tab-content.d.ts.map +1 -0
  86. package/lib/components/scan-admin/tab-contents/allow-list-tab-content.js +55 -0
  87. package/lib/components/scan-admin/tab-contents/allow-list-tab-content.js.map +1 -0
  88. package/lib/components/scan-admin/tab-contents/auto-rejected-tab-content.d.ts +19 -0
  89. package/lib/components/scan-admin/tab-contents/auto-rejected-tab-content.d.ts.map +1 -0
  90. package/lib/components/scan-admin/tab-contents/auto-rejected-tab-content.js +43 -0
  91. package/lib/components/scan-admin/tab-contents/auto-rejected-tab-content.js.map +1 -0
  92. package/lib/components/scan-admin/tab-contents/block-list-tab-content.d.ts +19 -0
  93. package/lib/components/scan-admin/tab-contents/block-list-tab-content.d.ts.map +1 -0
  94. package/lib/components/scan-admin/tab-contents/block-list-tab-content.js +55 -0
  95. package/lib/components/scan-admin/tab-contents/block-list-tab-content.js.map +1 -0
  96. package/lib/components/scan-admin/tab-contents/index.d.ts +18 -0
  97. package/lib/components/scan-admin/tab-contents/index.d.ts.map +1 -0
  98. package/lib/components/scan-admin/tab-contents/index.js +18 -0
  99. package/lib/components/scan-admin/tab-contents/index.js.map +1 -0
  100. package/lib/components/scan-admin/tab-contents/quarantined-tab-content.d.ts +19 -0
  101. package/lib/components/scan-admin/tab-contents/quarantined-tab-content.d.ts.map +1 -0
  102. package/lib/components/scan-admin/tab-contents/quarantined-tab-content.js +78 -0
  103. package/lib/components/scan-admin/tab-contents/quarantined-tab-content.js.map +1 -0
  104. package/lib/components/scan-admin/tab-contents/scans-tab-content.d.ts +19 -0
  105. package/lib/components/scan-admin/tab-contents/scans-tab-content.d.ts.map +1 -0
  106. package/lib/components/scan-admin/tab-contents/scans-tab-content.js +52 -0
  107. package/lib/components/scan-admin/tab-contents/scans-tab-content.js.map +1 -0
  108. package/lib/components/scan-admin/toolbars/counts-toolbar.d.ts +35 -0
  109. package/lib/components/scan-admin/toolbars/counts-toolbar.d.ts.map +1 -0
  110. package/lib/components/scan-admin/toolbars/counts-toolbar.js +132 -0
  111. package/lib/components/scan-admin/toolbars/counts-toolbar.js.map +1 -0
  112. package/lib/components/scan-admin/toolbars/index.d.ts +16 -0
  113. package/lib/components/scan-admin/toolbars/index.d.ts.map +1 -0
  114. package/lib/components/scan-admin/toolbars/index.js +16 -0
  115. package/lib/components/scan-admin/toolbars/index.js.map +1 -0
  116. package/lib/components/scan-admin/toolbars/search-toolbar.d.ts +43 -0
  117. package/lib/components/scan-admin/toolbars/search-toolbar.d.ts.map +1 -0
  118. package/lib/components/scan-admin/toolbars/search-toolbar.js +106 -0
  119. package/lib/components/scan-admin/toolbars/search-toolbar.js.map +1 -0
  120. package/lib/components/scan-admin/toolbars/tab-toolbar.d.ts +25 -0
  121. package/lib/components/scan-admin/toolbars/tab-toolbar.d.ts.map +1 -0
  122. package/lib/components/scan-admin/toolbars/tab-toolbar.js +33 -0
  123. package/lib/components/scan-admin/toolbars/tab-toolbar.js.map +1 -0
  124. package/lib/context/scan-admin/index.d.ts +21 -0
  125. package/lib/context/scan-admin/index.d.ts.map +1 -0
  126. package/lib/context/scan-admin/index.js +27 -0
  127. package/lib/context/scan-admin/index.js.map +1 -0
  128. package/lib/context/scan-admin/scan-actions.d.ts +19 -0
  129. package/lib/context/scan-admin/scan-actions.d.ts.map +1 -0
  130. package/lib/context/scan-admin/scan-actions.js +64 -0
  131. package/lib/context/scan-admin/scan-actions.js.map +1 -0
  132. package/lib/context/scan-admin/scan-api-actions.d.ts +26 -0
  133. package/lib/context/scan-admin/scan-api-actions.d.ts.map +1 -0
  134. package/lib/context/scan-admin/scan-api-actions.js +118 -0
  135. package/lib/context/scan-admin/scan-api-actions.js.map +1 -0
  136. package/lib/context/scan-admin/scan-api-effects.d.ts +40 -0
  137. package/lib/context/scan-admin/scan-api-effects.d.ts.map +1 -0
  138. package/lib/context/scan-admin/scan-api-effects.js +446 -0
  139. package/lib/context/scan-admin/scan-api-effects.js.map +1 -0
  140. package/lib/context/scan-admin/scan-context-types.d.ts +69 -0
  141. package/lib/context/scan-admin/scan-context-types.d.ts.map +1 -0
  142. package/lib/context/scan-admin/scan-context-types.js +14 -0
  143. package/lib/context/scan-admin/scan-context-types.js.map +1 -0
  144. package/lib/context/scan-admin/scan-context.d.ts +17 -0
  145. package/lib/context/scan-admin/scan-context.d.ts.map +1 -0
  146. package/lib/context/scan-admin/scan-context.js +90 -0
  147. package/lib/context/scan-admin/scan-context.js.map +1 -0
  148. package/lib/context/scan-admin/scan-helpers.d.ts +28 -0
  149. package/lib/context/scan-admin/scan-helpers.d.ts.map +1 -0
  150. package/lib/context/scan-admin/scan-helpers.js +56 -0
  151. package/lib/context/scan-admin/scan-helpers.js.map +1 -0
  152. package/lib/context/scan-admin/scan-reducer.d.ts +18 -0
  153. package/lib/context/scan-admin/scan-reducer.d.ts.map +1 -0
  154. package/lib/context/scan-admin/scan-reducer.js +194 -0
  155. package/lib/context/scan-admin/scan-reducer.js.map +1 -0
  156. package/lib/context/scan-admin/scan-types.d.ts +292 -0
  157. package/lib/context/scan-admin/scan-types.d.ts.map +1 -0
  158. package/lib/context/scan-admin/scan-types.js +67 -0
  159. package/lib/context/scan-admin/scan-types.js.map +1 -0
  160. package/lib/default/page-settings.d.ts.map +1 -1
  161. package/lib/default/page-settings.js +3 -0
  162. package/lib/default/page-settings.js.map +1 -1
  163. package/lib/default/theme.d.ts +50 -12
  164. package/lib/default/theme.d.ts.map +1 -1
  165. package/lib/default/theme.js +42 -0
  166. package/lib/default/theme.js.map +1 -1
  167. package/lib/extension-registry-service.d.ts +85 -1
  168. package/lib/extension-registry-service.d.ts.map +1 -1
  169. package/lib/extension-registry-service.js +197 -0
  170. package/lib/extension-registry-service.js.map +1 -1
  171. package/lib/extension-registry-types.d.ts +140 -0
  172. package/lib/extension-registry-types.d.ts.map +1 -1
  173. package/lib/extension-registry-types.js.map +1 -1
  174. package/lib/hooks/scan-admin/index.d.ts +34 -0
  175. package/lib/hooks/scan-admin/index.d.ts.map +1 -0
  176. package/lib/hooks/scan-admin/index.js +28 -0
  177. package/lib/hooks/scan-admin/index.js.map +1 -0
  178. package/lib/hooks/scan-admin/use-auto-rejected-tab.d.ts +76 -0
  179. package/lib/hooks/scan-admin/use-auto-rejected-tab.d.ts.map +1 -0
  180. package/lib/hooks/scan-admin/use-auto-rejected-tab.js +79 -0
  181. package/lib/hooks/scan-admin/use-auto-rejected-tab.js.map +1 -0
  182. package/lib/hooks/scan-admin/use-dialogs.d.ts +43 -0
  183. package/lib/hooks/scan-admin/use-dialogs.d.ts.map +1 -0
  184. package/lib/hooks/scan-admin/use-dialogs.js +55 -0
  185. package/lib/hooks/scan-admin/use-dialogs.js.map +1 -0
  186. package/lib/hooks/scan-admin/use-file-list-tab.d.ts +208 -0
  187. package/lib/hooks/scan-admin/use-file-list-tab.d.ts.map +1 -0
  188. package/lib/hooks/scan-admin/use-file-list-tab.js +125 -0
  189. package/lib/hooks/scan-admin/use-file-list-tab.js.map +1 -0
  190. package/lib/hooks/scan-admin/use-pagination.d.ts +36 -0
  191. package/lib/hooks/scan-admin/use-pagination.d.ts.map +1 -0
  192. package/lib/hooks/scan-admin/use-pagination.js +79 -0
  193. package/lib/hooks/scan-admin/use-pagination.js.map +1 -0
  194. package/lib/hooks/scan-admin/use-quarantined-tab.d.ts +92 -0
  195. package/lib/hooks/scan-admin/use-quarantined-tab.d.ts.map +1 -0
  196. package/lib/hooks/scan-admin/use-quarantined-tab.js +125 -0
  197. package/lib/hooks/scan-admin/use-quarantined-tab.js.map +1 -0
  198. package/lib/hooks/scan-admin/use-scan-card-state.d.ts +29 -0
  199. package/lib/hooks/scan-admin/use-scan-card-state.d.ts.map +1 -0
  200. package/lib/hooks/scan-admin/use-scan-card-state.js +50 -0
  201. package/lib/hooks/scan-admin/use-scan-card-state.js.map +1 -0
  202. package/lib/hooks/scan-admin/use-scan-filters.d.ts +53 -0
  203. package/lib/hooks/scan-admin/use-scan-filters.d.ts.map +1 -0
  204. package/lib/hooks/scan-admin/use-scan-filters.js +75 -0
  205. package/lib/hooks/scan-admin/use-scan-filters.js.map +1 -0
  206. package/lib/hooks/scan-admin/use-scans-tab.d.ts +85 -0
  207. package/lib/hooks/scan-admin/use-scans-tab.d.ts.map +1 -0
  208. package/lib/hooks/scan-admin/use-scans-tab.js +87 -0
  209. package/lib/hooks/scan-admin/use-scans-tab.js.map +1 -0
  210. package/lib/hooks/scan-admin/use-search.d.ts +32 -0
  211. package/lib/hooks/scan-admin/use-search.d.ts.map +1 -0
  212. package/lib/hooks/scan-admin/use-search.js +48 -0
  213. package/lib/hooks/scan-admin/use-search.js.map +1 -0
  214. package/lib/hooks/scan-admin/use-tab-navigation.d.ts +96 -0
  215. package/lib/hooks/scan-admin/use-tab-navigation.d.ts.map +1 -0
  216. package/lib/hooks/scan-admin/use-tab-navigation.js +70 -0
  217. package/lib/hooks/scan-admin/use-tab-navigation.js.map +1 -0
  218. package/lib/hooks/scan-admin/use-url-sync.d.ts +22 -0
  219. package/lib/hooks/scan-admin/use-url-sync.d.ts.map +1 -0
  220. package/lib/hooks/scan-admin/use-url-sync.js +252 -0
  221. package/lib/hooks/scan-admin/use-url-sync.js.map +1 -0
  222. package/lib/page-settings.d.ts +4 -0
  223. package/lib/page-settings.d.ts.map +1 -1
  224. package/lib/pages/admin-dashboard/admin-dashboard.d.ts +1 -0
  225. package/lib/pages/admin-dashboard/admin-dashboard.d.ts.map +1 -1
  226. package/lib/pages/admin-dashboard/admin-dashboard.js +23 -3
  227. package/lib/pages/admin-dashboard/admin-dashboard.js.map +1 -1
  228. package/lib/pages/admin-dashboard/publisher-admin.js +1 -1
  229. package/lib/pages/admin-dashboard/publisher-admin.js.map +1 -1
  230. package/lib/pages/admin-dashboard/publisher-revoke-dialog.d.ts.map +1 -1
  231. package/lib/pages/admin-dashboard/publisher-revoke-dialog.js +1 -1
  232. package/lib/pages/admin-dashboard/publisher-revoke-dialog.js.map +1 -1
  233. package/lib/pages/admin-dashboard/scan-admin.d.ts +20 -0
  234. package/lib/pages/admin-dashboard/scan-admin.d.ts.map +1 -0
  235. package/lib/pages/admin-dashboard/scan-admin.js +66 -0
  236. package/lib/pages/admin-dashboard/scan-admin.js.map +1 -0
  237. package/lib/pages/admin-dashboard/welcome.d.ts.map +1 -1
  238. package/lib/pages/admin-dashboard/welcome.js +2 -1
  239. package/lib/pages/admin-dashboard/welcome.js.map +1 -1
  240. package/lib/pages/extension-detail/extension-detail-overview.d.ts.map +1 -1
  241. package/lib/pages/extension-detail/extension-detail-overview.js +9 -1
  242. package/lib/pages/extension-detail/extension-detail-overview.js.map +1 -1
  243. package/lib/pages/extension-detail/extension-detail-reviews.d.ts.map +1 -1
  244. package/lib/pages/extension-detail/extension-detail-reviews.js +67 -18
  245. package/lib/pages/extension-detail/extension-detail-reviews.js.map +1 -1
  246. package/lib/pages/extension-detail/extension-detail.js +2 -2
  247. package/lib/pages/extension-detail/extension-detail.js.map +1 -1
  248. package/lib/pages/extension-detail/extension-rating-stars.d.ts +2 -2
  249. package/lib/pages/extension-detail/extension-rating-stars.d.ts.map +1 -1
  250. package/lib/pages/extension-detail/extension-rating-stars.js +1 -1
  251. package/lib/pages/extension-detail/extension-rating-stars.js.map +1 -1
  252. package/lib/pages/extension-list/extension-list-item.js +2 -2
  253. package/lib/pages/extension-list/extension-list-item.js.map +1 -1
  254. package/lib/pages/user/user-namespace-extension-list-item.d.ts.map +1 -1
  255. package/lib/pages/user/user-namespace-extension-list-item.js +23 -9
  256. package/lib/pages/user/user-namespace-extension-list-item.js.map +1 -1
  257. package/lib/pages/user/user-publisher-agreement.d.ts.map +1 -1
  258. package/lib/pages/user/user-publisher-agreement.js +34 -13
  259. package/lib/pages/user/user-publisher-agreement.js.map +1 -1
  260. package/lib/pages/user/user-settings-profile.d.ts.map +1 -1
  261. package/lib/pages/user/user-settings-profile.js +10 -5
  262. package/lib/pages/user/user-settings-profile.js.map +1 -1
  263. package/lib/pages/user/user-settings-tokens.d.ts.map +1 -1
  264. package/lib/pages/user/user-settings-tokens.js +13 -5
  265. package/lib/pages/user/user-settings-tokens.js.map +1 -1
  266. package/package.json +10 -9
  267. package/src/components/button-with-progress.tsx +2 -1
  268. package/src/components/sanitized-markdown.tsx +81 -1
  269. package/src/components/scan-admin/common/auto-refresh.tsx +79 -0
  270. package/src/components/scan-admin/common/conditional-tooltip.tsx +74 -0
  271. package/src/components/scan-admin/common/file-table.tsx +508 -0
  272. package/src/components/scan-admin/common/index.ts +18 -0
  273. package/src/components/scan-admin/common/tab-panel.tsx +42 -0
  274. package/src/components/scan-admin/common/utils.ts +48 -0
  275. package/src/components/scan-admin/dialogs/file-dialog.tsx +137 -0
  276. package/src/components/scan-admin/dialogs/index.ts +15 -0
  277. package/src/components/scan-admin/dialogs/quarantine-dialog.tsx +270 -0
  278. package/src/components/scan-admin/index.ts +52 -0
  279. package/src/components/scan-admin/scan-card/index.ts +20 -0
  280. package/src/components/scan-admin/scan-card/scan-card-content.tsx +457 -0
  281. package/src/components/scan-admin/scan-card/scan-card-expand-strip-badges.tsx +186 -0
  282. package/src/components/scan-admin/scan-card/scan-card-expand-strip.tsx +104 -0
  283. package/src/components/scan-admin/scan-card/scan-card-expanded-content.tsx +262 -0
  284. package/src/components/scan-admin/scan-card/scan-card-header.tsx +176 -0
  285. package/src/components/scan-admin/scan-card/scan-card.tsx +152 -0
  286. package/src/components/scan-admin/scan-card/scan-detail-card.tsx +144 -0
  287. package/src/components/scan-admin/scan-card/utils.ts +199 -0
  288. package/src/components/scan-admin/tab-contents/allow-list-tab-content.tsx +119 -0
  289. package/src/components/scan-admin/tab-contents/auto-rejected-tab-content.tsx +106 -0
  290. package/src/components/scan-admin/tab-contents/block-list-tab-content.tsx +119 -0
  291. package/src/components/scan-admin/tab-contents/index.ts +18 -0
  292. package/src/components/scan-admin/tab-contents/quarantined-tab-content.tsx +158 -0
  293. package/src/components/scan-admin/tab-contents/scans-tab-content.tsx +113 -0
  294. package/src/components/scan-admin/toolbars/counts-toolbar.tsx +262 -0
  295. package/src/components/scan-admin/toolbars/index.ts +16 -0
  296. package/src/components/scan-admin/toolbars/search-toolbar.tsx +255 -0
  297. package/src/components/scan-admin/toolbars/tab-toolbar.tsx +56 -0
  298. package/src/context/scan-admin/index.ts +43 -0
  299. package/src/context/scan-admin/scan-actions.ts +87 -0
  300. package/src/context/scan-admin/scan-api-actions.ts +137 -0
  301. package/src/context/scan-admin/scan-api-effects.ts +491 -0
  302. package/src/context/scan-admin/scan-context-types.ts +102 -0
  303. package/src/context/scan-admin/scan-context.tsx +123 -0
  304. package/src/context/scan-admin/scan-helpers.ts +63 -0
  305. package/src/context/scan-admin/scan-reducer.ts +321 -0
  306. package/src/context/scan-admin/scan-types.ts +337 -0
  307. package/src/default/page-settings.tsx +3 -0
  308. package/src/default/theme.tsx +102 -13
  309. package/src/extension-registry-service.ts +216 -1
  310. package/src/extension-registry-types.ts +157 -0
  311. package/src/hooks/scan-admin/index.ts +48 -0
  312. package/src/hooks/scan-admin/use-auto-rejected-tab.ts +85 -0
  313. package/src/hooks/scan-admin/use-dialogs.ts +83 -0
  314. package/src/hooks/scan-admin/use-file-list-tab.ts +149 -0
  315. package/src/hooks/scan-admin/use-pagination.ts +90 -0
  316. package/src/hooks/scan-admin/use-quarantined-tab.ts +138 -0
  317. package/src/hooks/scan-admin/use-scan-card-state.ts +73 -0
  318. package/src/hooks/scan-admin/use-scan-filters.ts +83 -0
  319. package/src/hooks/scan-admin/use-scans-tab.ts +92 -0
  320. package/src/hooks/scan-admin/use-search.ts +54 -0
  321. package/src/hooks/scan-admin/use-tab-navigation.ts +82 -0
  322. package/src/hooks/scan-admin/use-url-sync.ts +293 -0
  323. package/src/page-settings.ts +4 -0
  324. package/src/pages/admin-dashboard/admin-dashboard.tsx +26 -2
  325. package/src/pages/admin-dashboard/publisher-admin.tsx +1 -1
  326. package/src/pages/admin-dashboard/publisher-revoke-dialog.tsx +2 -1
  327. package/src/pages/admin-dashboard/scan-admin.tsx +109 -0
  328. package/src/pages/admin-dashboard/welcome.tsx +1 -0
  329. package/src/pages/extension-detail/extension-detail-overview.tsx +16 -2
  330. package/src/pages/extension-detail/extension-detail-reviews.tsx +116 -30
  331. package/src/pages/extension-detail/extension-detail.tsx +2 -2
  332. package/src/pages/extension-detail/extension-rating-stars.tsx +2 -2
  333. package/src/pages/extension-list/extension-list-item.tsx +2 -2
  334. package/src/pages/user/user-namespace-extension-list-item.tsx +38 -13
  335. package/src/pages/user/user-publisher-agreement.tsx +30 -11
  336. package/src/pages/user/user-settings-profile.tsx +10 -6
  337. package/src/pages/user/user-settings-tokens.tsx +15 -6
@@ -12,7 +12,9 @@ import {
12
12
  Extension, UserData, ExtensionCategory, ExtensionReviewList, PersonalAccessToken, SearchResult, NewReview,
13
13
  SuccessResult, ErrorResult, CsrfTokenJson, isError, Namespace, NamespaceDetails, MembershipRole, SortBy,
14
14
  SortOrder, UrlString, NamespaceMembershipList, PublisherInfo, SearchEntry, RegistryVersion,
15
- LoginProviders
15
+ LoginProviders, ScanResultJson, ScanCounts, ScanResultsResponse, ScanFilterOptions,
16
+ FilesResponse, FileDecisionCountsJson, ScanDecisionRequest, ScanDecisionResponse,
17
+ FileDecisionRequest, FileDecisionResponse, FileDecisionDeleteRequest, FileDecisionDeleteResponse
16
18
  } from './extension-registry-types';
17
19
  import { createAbsoluteURL, addQuery } from './utils';
18
20
  import { sendRequest, ErrorResponse } from './server-request';
@@ -209,6 +211,22 @@ export class ExtensionRegistryService {
209
211
  });
210
212
  }
211
213
 
214
+ async deleteUserReview(abortController: AbortController, extension: Extension, user: UserData): Promise<Readonly<SuccessResult | ErrorResult>> {
215
+ const csrfResponse = await this.getCsrfToken(abortController);
216
+ const headers: Record<string, string> = {};
217
+ if (!isError(csrfResponse)) {
218
+ const csrfToken = csrfResponse as CsrfTokenJson;
219
+ headers[csrfToken.header] = csrfToken.value;
220
+ }
221
+ return sendRequest({
222
+ abortController,
223
+ method: 'POST',
224
+ credentials: true,
225
+ endpoint: createAbsoluteURL([this.serverUrl, 'admin', 'extension', extension.namespace, extension.name, 'review', user.provider || 'github', user.loginName, 'delete']),
226
+ headers
227
+ });
228
+ }
229
+
212
230
  getUser(abortController: AbortController): Promise<Readonly<UserData | ErrorResult>> {
213
231
  return sendRequest({
214
232
  abortController,
@@ -470,6 +488,17 @@ export interface AdminService {
470
488
  getPublisherInfo(abortController: AbortController, provider: string, login: string): Promise<Readonly<PublisherInfo>>
471
489
  revokePublisherContributions(abortController: AbortController, provider: string, login: string): Promise<Readonly<SuccessResult | ErrorResult>>
472
490
  revokeAccessTokens(abortController: AbortController, provider: string, login: string): Promise<Readonly<SuccessResult | ErrorResult>>
491
+ getAllScans(abortController: AbortController, params?: { size?: number; offset?: number; status?: string | string[]; publisher?: string; namespace?: string; name?: string; validationType?: string[]; threatScannerName?: string[]; dateStartedFrom?: string; dateStartedTo?: string; enforcement?: 'enforced' | 'notEnforced' | 'all' }): Promise<Readonly<ScanResultsResponse>>
492
+ getScan(abortController: AbortController, scanId: string): Promise<Readonly<ScanResultJson>>
493
+ getScanCounts(abortController: AbortController, params?: { dateStartedFrom?: string; dateStartedTo?: string; enforcement?: 'enforced' | 'notEnforced' | 'all'; threatScannerName?: string[]; validationType?: string[] }): Promise<Readonly<ScanCounts>>
494
+ getScanFilterOptions(abortController: AbortController): Promise<Readonly<ScanFilterOptions>>
495
+ // Files API
496
+ getFiles(abortController: AbortController, params?: { size?: number; offset?: number; decision?: string; publisher?: string; namespace?: string; name?: string; dateDecidedFrom?: string; dateDecidedTo?: string; sortBy?: string; sortOrder?: 'asc' | 'desc' }): Promise<Readonly<FilesResponse>>;
497
+ getFileCounts(abortController: AbortController, params?: { dateDecidedFrom?: string; dateDecidedTo?: string }): Promise<Readonly<FileDecisionCountsJson>>
498
+ // Decision APIs
499
+ makeScanDecision(abortController: AbortController, request: ScanDecisionRequest): Promise<Readonly<ScanDecisionResponse>>
500
+ makeFileDecision(abortController: AbortController, request: FileDecisionRequest): Promise<Readonly<FileDecisionResponse>>
501
+ deleteFileDecisions(abortController: AbortController, request: FileDecisionDeleteRequest): Promise<Readonly<FileDecisionDeleteResponse>>
473
502
  }
474
503
 
475
504
  export interface AdminServiceConstructor {
@@ -593,6 +622,192 @@ export class AdminServiceImpl implements AdminService {
593
622
  headers
594
623
  });
595
624
  }
625
+
626
+ getAllScans(abortController: AbortController, params?: { size?: number; offset?: number; status?: string | string[]; publisher?: string; namespace?: string; name?: string; validationType?: string[]; threatScannerName?: string[]; dateStartedFrom?: string; dateStartedTo?: string; enforcement?: 'enforced' | 'notEnforced' | 'all'; adminDecision?: string[] }): Promise<Readonly<ScanResultsResponse>> {
627
+ const query: { key: string, value: string | number }[] = [];
628
+ if (params) {
629
+ if (params.size !== undefined)
630
+ query.push({ key: 'size', value: params.size });
631
+ if (params.offset !== undefined)
632
+ query.push({ key: 'offset', value: params.offset });
633
+ if (params.status) {
634
+ const statusValue = Array.isArray(params.status) ? params.status.join(',') : params.status;
635
+ query.push({ key: 'status', value: statusValue });
636
+ }
637
+ if (params.publisher)
638
+ query.push({ key: 'publisher', value: params.publisher });
639
+ if (params.namespace)
640
+ query.push({ key: 'namespace', value: params.namespace });
641
+ if (params.name)
642
+ query.push({ key: 'name', value: params.name });
643
+ if (params.validationType && params.validationType.length > 0)
644
+ query.push({ key: 'validationType', value: params.validationType.join(',') });
645
+ if (params.threatScannerName && params.threatScannerName.length > 0)
646
+ query.push({ key: 'threatScannerName', value: params.threatScannerName.join(',') });
647
+ if (params.dateStartedFrom)
648
+ query.push({ key: 'dateStartedFrom', value: params.dateStartedFrom });
649
+ if (params.dateStartedTo)
650
+ query.push({ key: 'dateStartedTo', value: params.dateStartedTo });
651
+ if (params.enforcement)
652
+ query.push({ key: 'enforcement', value: params.enforcement });
653
+ if (params.adminDecision && params.adminDecision.length > 0)
654
+ query.push({ key: 'adminDecision', value: params.adminDecision.join(',') });
655
+ }
656
+ const endpoint = createAbsoluteURL([this.registry.serverUrl, 'admin', 'scans'], query);
657
+ return sendRequest({
658
+ abortController,
659
+ credentials: true,
660
+ endpoint
661
+ });
662
+ }
663
+
664
+ getScan(abortController: AbortController, scanId: string): Promise<Readonly<ScanResultJson>> {
665
+ return sendRequest({
666
+ abortController,
667
+ credentials: true,
668
+ endpoint: createAbsoluteURL([this.registry.serverUrl, 'admin', 'scans', scanId])
669
+ });
670
+ }
671
+
672
+ getScanCounts(abortController: AbortController, params?: { dateStartedFrom?: string; dateStartedTo?: string; enforcement?: 'enforced' | 'notEnforced' | 'all'; threatScannerName?: string[]; validationType?: string[] }): Promise<Readonly<ScanCounts>> {
673
+ const query: { key: string, value: string | number }[] = [];
674
+ if (params) {
675
+ if (params.dateStartedFrom)
676
+ query.push({ key: 'dateStartedFrom', value: params.dateStartedFrom });
677
+ if (params.dateStartedTo)
678
+ query.push({ key: 'dateStartedTo', value: params.dateStartedTo });
679
+ if (params.enforcement)
680
+ query.push({ key: 'enforcement', value: params.enforcement });
681
+ if (params.threatScannerName && params.threatScannerName.length > 0) {
682
+ query.push({ key: 'threatScannerName', value: params.threatScannerName.join(',') });
683
+ }
684
+ if (params.validationType && params.validationType.length > 0) {
685
+ query.push({ key: 'validationType', value: params.validationType.join(',') });
686
+ }
687
+ }
688
+ const endpoint = createAbsoluteURL([this.registry.serverUrl, 'admin', 'scans', 'counts'], query);
689
+ return sendRequest({
690
+ abortController,
691
+ credentials: true,
692
+ endpoint
693
+ });
694
+ }
695
+
696
+ getScanFilterOptions(abortController: AbortController): Promise<Readonly<ScanFilterOptions>> {
697
+ return sendRequest({
698
+ abortController,
699
+ credentials: true,
700
+ endpoint: createAbsoluteURL([this.registry.serverUrl, 'admin', 'scans', 'filterOptions'])
701
+ });
702
+ }
703
+
704
+ getFiles(abortController: AbortController, params?: { size?: number; offset?: number; decision?: string; publisher?: string; namespace?: string; name?: string; dateDecidedFrom?: string; dateDecidedTo?: string; sortBy?: string; sortOrder?: 'asc' | 'desc' }): Promise<Readonly<FilesResponse>> {
705
+ const query: { key: string, value: string | number }[] = [];
706
+ if (params) {
707
+ if (params.size !== undefined)
708
+ query.push({ key: 'size', value: params.size });
709
+ if (params.offset !== undefined)
710
+ query.push({ key: 'offset', value: params.offset });
711
+ if (params.decision)
712
+ query.push({ key: 'decision', value: params.decision });
713
+ if (params.publisher)
714
+ query.push({ key: 'publisher', value: params.publisher });
715
+ if (params.namespace)
716
+ query.push({ key: 'namespace', value: params.namespace });
717
+ if (params.name)
718
+ query.push({ key: 'name', value: params.name });
719
+ if (params.dateDecidedFrom)
720
+ query.push({ key: 'dateDecidedFrom', value: params.dateDecidedFrom });
721
+ if (params.dateDecidedTo)
722
+ query.push({ key: 'dateDecidedTo', value: params.dateDecidedTo });
723
+ if (params.sortBy)
724
+ query.push({ key: 'sortBy', value: params.sortBy });
725
+ if (params.sortOrder)
726
+ query.push({ key: 'sortOrder', value: params.sortOrder });
727
+ }
728
+ const endpoint = createAbsoluteURL([this.registry.serverUrl, 'admin', 'scans', 'files'], query);
729
+ return sendRequest({
730
+ abortController,
731
+ credentials: true,
732
+ endpoint
733
+ });
734
+ }
735
+
736
+ getFileCounts(abortController: AbortController, params?: { dateDecidedFrom?: string; dateDecidedTo?: string }): Promise<Readonly<FileDecisionCountsJson>> {
737
+ const query: { key: string, value: string | number }[] = [];
738
+ if (params) {
739
+ if (params.dateDecidedFrom)
740
+ query.push({ key: 'dateDecidedFrom', value: params.dateDecidedFrom });
741
+ if (params.dateDecidedTo)
742
+ query.push({ key: 'dateDecidedTo', value: params.dateDecidedTo });
743
+ }
744
+ const endpoint = createAbsoluteURL([this.registry.serverUrl, 'admin', 'scans', 'files', 'counts'], query);
745
+ return sendRequest({
746
+ abortController,
747
+ credentials: true,
748
+ endpoint
749
+ });
750
+ }
751
+
752
+ async makeScanDecision(abortController: AbortController, request: ScanDecisionRequest): Promise<Readonly<ScanDecisionResponse>> {
753
+ const csrfResponse = await this.registry.getCsrfToken(abortController);
754
+ const headers: Record<string, string> = {
755
+ 'Content-Type': 'application/json;charset=UTF-8'
756
+ };
757
+ if (!isError(csrfResponse)) {
758
+ const csrfToken = csrfResponse as CsrfTokenJson;
759
+ headers[csrfToken.header] = csrfToken.value;
760
+ }
761
+
762
+ return sendRequest({
763
+ abortController,
764
+ method: 'POST',
765
+ credentials: true,
766
+ endpoint: createAbsoluteURL([this.registry.serverUrl, 'admin', 'scans', 'decisions']),
767
+ headers,
768
+ payload: request
769
+ });
770
+ }
771
+
772
+ async makeFileDecision(abortController: AbortController, request: FileDecisionRequest): Promise<Readonly<FileDecisionResponse>> {
773
+ const csrfResponse = await this.registry.getCsrfToken(abortController);
774
+ const headers: Record<string, string> = {
775
+ 'Content-Type': 'application/json;charset=UTF-8'
776
+ };
777
+ if (!isError(csrfResponse)) {
778
+ const csrfToken = csrfResponse as CsrfTokenJson;
779
+ headers[csrfToken.header] = csrfToken.value;
780
+ }
781
+
782
+ return sendRequest({
783
+ abortController,
784
+ method: 'POST',
785
+ credentials: true,
786
+ endpoint: createAbsoluteURL([this.registry.serverUrl, 'admin', 'scans', 'files', 'decisions']),
787
+ headers,
788
+ payload: request
789
+ });
790
+ }
791
+
792
+ async deleteFileDecisions(abortController: AbortController, request: FileDecisionDeleteRequest): Promise<Readonly<FileDecisionDeleteResponse>> {
793
+ const csrfResponse = await this.registry.getCsrfToken(abortController);
794
+ const headers: Record<string, string> = {
795
+ 'Content-Type': 'application/json;charset=UTF-8'
796
+ };
797
+ if (!isError(csrfResponse)) {
798
+ const csrfToken = csrfResponse as CsrfTokenJson;
799
+ headers[csrfToken.header] = csrfToken.value;
800
+ }
801
+
802
+ return sendRequest({
803
+ abortController,
804
+ method: 'DELETE',
805
+ credentials: true,
806
+ endpoint: createAbsoluteURL([this.registry.serverUrl, 'admin', 'scans', 'files', 'decisions']),
807
+ headers,
808
+ payload: request
809
+ });
810
+ }
596
811
  }
597
812
 
598
813
  export interface ExtensionFilter {
@@ -78,6 +78,8 @@ export interface Extension {
78
78
  // key: version, value: url
79
79
  allVersions: { [version: string]: UrlString };
80
80
  active?: boolean;
81
+ reviewStatus?: 'published' | 'under_review' | 'rejected';
82
+ reviewMessage?: string;
81
83
 
82
84
  averageRating?: number;
83
85
  downloadCount: number;
@@ -258,3 +260,158 @@ export interface LoginProviders {
258
260
  export type MembershipRole = 'contributor' | 'owner';
259
261
  export type SortBy = 'relevance' | 'timestamp' | 'rating' | 'downloadCount';
260
262
  export type SortOrder = 'asc' | 'desc';
263
+
264
+ // Scan and file decision types (used by admin scan UI)
265
+ export interface ScanResultJson {
266
+ id: string;
267
+ namespace: string;
268
+ extensionName: string;
269
+ version: string;
270
+ displayName: string;
271
+ publisher: string;
272
+ extensionIcon?: string;
273
+ downloadUrl?: string;
274
+ publisherUrl?: string;
275
+ status: string;
276
+ dateScanStarted: string;
277
+ dateScanEnded?: string;
278
+ errorMessage?: string;
279
+ dateQuarantined?: string;
280
+ dateRejected?: string;
281
+ threats?: Array<{
282
+ id: string;
283
+ fileName: string;
284
+ fileHash: string;
285
+ type: string;
286
+ severity?: string;
287
+ reason: string;
288
+ fileExtension: string;
289
+ dateDetected: string;
290
+ ruleName: string;
291
+ enforcedFlag?: boolean;
292
+ }>;
293
+ validationFailures?: Array<{
294
+ id: string;
295
+ type: string;
296
+ ruleName: string;
297
+ reason: string;
298
+ dateDetected: string;
299
+ enforcedFlag: boolean;
300
+ }>;
301
+ adminDecision?: {
302
+ decision: string;
303
+ decidedBy: string;
304
+ dateDecided: string;
305
+ };
306
+ }
307
+
308
+ export interface ScanCounts {
309
+ STARTED: number;
310
+ VALIDATING: number;
311
+ SCANNING: number;
312
+ PASSED: number;
313
+ QUARANTINED: number;
314
+ AUTO_REJECTED: number;
315
+ ERROR: number;
316
+ ALLOWED: number;
317
+ BLOCKED: number;
318
+ NEEDS_REVIEW: number;
319
+ }
320
+
321
+ export interface ScanResultsResponse {
322
+ success?: string;
323
+ warning?: string;
324
+ error?: string;
325
+ offset: number;
326
+ totalSize: number;
327
+ scans: ScanResultJson[];
328
+ }
329
+
330
+ export interface ScanFilterOptions {
331
+ validationTypes: string[];
332
+ threatScannerNames: string[];
333
+ }
334
+
335
+ export interface FileDecisionJson {
336
+ id: string;
337
+ fileName: string;
338
+ fileHash: string;
339
+ fileType: string;
340
+ decision: string;
341
+ decidedBy: string;
342
+ dateDecided: string;
343
+ displayName: string;
344
+ namespace: string;
345
+ extensionName: string;
346
+ publisher: string;
347
+ version: string;
348
+ scanId?: string;
349
+ }
350
+
351
+ export interface FilesResponse {
352
+ success?: string;
353
+ warning?: string;
354
+ error?: string;
355
+ offset: number;
356
+ totalSize: number;
357
+ files: FileDecisionJson[];
358
+ }
359
+
360
+ export interface FileDecisionCountsJson {
361
+ allowed: number;
362
+ blocked: number;
363
+ total: number;
364
+ }
365
+
366
+ export interface ScanDecisionRequest {
367
+ scanIds: string[];
368
+ decision: string;
369
+ }
370
+
371
+ export interface ScanDecisionResult {
372
+ scanId: string;
373
+ success: boolean;
374
+ error?: string;
375
+ }
376
+
377
+ export interface ScanDecisionResponse {
378
+ processed: number;
379
+ successful: number;
380
+ failed: number;
381
+ results: ScanDecisionResult[];
382
+ }
383
+
384
+ export interface FileDecisionRequest {
385
+ fileHashes: string[];
386
+ decision: string;
387
+ }
388
+
389
+ export interface FileDecisionResult {
390
+ fileHash: string;
391
+ success: boolean;
392
+ error?: string;
393
+ }
394
+
395
+ export interface FileDecisionResponse {
396
+ processed: number;
397
+ successful: number;
398
+ failed: number;
399
+ results: FileDecisionResult[];
400
+ }
401
+
402
+ export interface FileDecisionDeleteRequest {
403
+ fileIds: string[];
404
+ }
405
+
406
+ export interface FileDecisionDeleteResult {
407
+ fileId: string;
408
+ success: boolean;
409
+ error?: string;
410
+ }
411
+
412
+ export interface FileDecisionDeleteResponse {
413
+ processed: number;
414
+ successful: number;
415
+ failed: number;
416
+ results: FileDecisionDeleteResult[];
417
+ }
@@ -0,0 +1,48 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation
3
+ *
4
+ * See the NOTICE file(s) distributed with this work for additional
5
+ * information regarding copyright ownership.
6
+ *
7
+ * This program and the accompanying materials are made available under the
8
+ * terms of the Eclipse Public License 2.0 which is available at
9
+ * https://www.eclipse.org/legal/epl-2.0
10
+ *
11
+ * SPDX-License-Identifier: EPL-2.0
12
+ ********************************************************************************/
13
+
14
+ // Core hooks
15
+ export { useTabNavigation, TAB_DEFINITIONS } from './use-tab-navigation';
16
+ export type { UseTabNavigationReturn, TabIndex, TabName } from './use-tab-navigation';
17
+
18
+ export { useScanFilters } from './use-scan-filters';
19
+ export type { UseScanFiltersReturn } from './use-scan-filters';
20
+
21
+ export { usePagination } from './use-pagination';
22
+ export type { UsePaginationReturn } from './use-pagination';
23
+
24
+ export { useSearch } from './use-search';
25
+ export type { UseSearchReturn } from './use-search';
26
+
27
+ export { useDialogs } from './use-dialogs';
28
+ export type { UseDialogsReturn } from './use-dialogs';
29
+
30
+ // Tab-specific hooks
31
+ export { useScansTab } from './use-scans-tab';
32
+ export type { UseScansTabReturn } from './use-scans-tab';
33
+
34
+ export { useQuarantinedTab } from './use-quarantined-tab';
35
+ export type { UseQuarantinedTabReturn } from './use-quarantined-tab';
36
+
37
+ export { useAutoRejectedTab } from './use-auto-rejected-tab';
38
+ export type { UseAutoRejectedTabReturn } from './use-auto-rejected-tab';
39
+
40
+ export { useFileListTab, useAllowListTab, useBlockListTab } from './use-file-list-tab';
41
+ export type { UseFileListTabReturn, UseAllowListTabReturn, UseBlockListTabReturn } from './use-file-list-tab';
42
+
43
+ // URL sync hook
44
+ export { useUrlSync } from './use-url-sync';
45
+ export type { UseUrlSyncReturn } from './use-url-sync';
46
+
47
+ // Component-specific hooks
48
+ export { useScanCardState } from './use-scan-card-state';
@@ -0,0 +1,85 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation
3
+ *
4
+ * See the NOTICE file(s) distributed with this work for additional
5
+ * information regarding copyright ownership.
6
+ *
7
+ * This program and the accompanying materials are made available under the
8
+ * terms of the Eclipse Public License 2.0 which is available at
9
+ * https://www.eclipse.org/legal/epl-2.0
10
+ *
11
+ * SPDX-License-Identifier: EPL-2.0
12
+ ********************************************************************************/
13
+
14
+ import { useMemo } from 'react';
15
+ import { useScanContext } from '../../context/scan-admin';
16
+ import { useScanFilters } from './use-scan-filters';
17
+ import { usePagination } from './use-pagination';
18
+ import { useSearch } from './use-search';
19
+
20
+ /**
21
+ * Hook for the Auto Rejected tab (tab index 2).
22
+ * Provides auto-rejected scan data and validation type filtering.
23
+ */
24
+ export const useAutoRejectedTab = () => {
25
+ const { state, actions } = useScanContext();
26
+ const { globalFilters, validationTypeFilters } = useScanFilters();
27
+ const pagination = usePagination();
28
+ const search = useSearch();
29
+
30
+ // Use scans directly from state - backend handles filtering based on tab and enforcement
31
+ const autoRejectedScans = state.scans;
32
+
33
+ // Get validation type breakdown
34
+ const validationTypeBreakdown = useMemo(() => {
35
+ const breakdown: Record<string, number> = {};
36
+ autoRejectedScans.forEach(scan => {
37
+ scan.validationFailures?.forEach(failure => {
38
+ const type = failure.type || 'Unknown';
39
+ breakdown[type] = (breakdown[type] || 0) + 1;
40
+ });
41
+ });
42
+ return breakdown;
43
+ }, [autoRejectedScans]);
44
+
45
+ // Get total count from the counts API (unaffected by search filters)
46
+ const totalCount = (state.scanCounts?.STARTED ?? 0) + (state.scanCounts?.VALIDATING ?? 0) +
47
+ (state.scanCounts?.SCANNING ?? 0) + (state.scanCounts?.PASSED ?? 0) +
48
+ (state.scanCounts?.QUARANTINED ?? 0) + (state.scanCounts?.AUTO_REJECTED ?? 0) +
49
+ (state.scanCounts?.ERROR ?? 0);
50
+
51
+ // Check if there are any validation types available to filter by
52
+ const hasValidationTypes = state.availableValidationTypes.length > 0;
53
+
54
+ return useMemo(() => ({
55
+ tabIndex: 2,
56
+ tabName: 'Auto Rejected',
57
+ scans: autoRejectedScans,
58
+ isLoading: state.isLoadingScans,
59
+ lastRefreshed: state.lastRefreshed,
60
+ autoRefresh: state.autoRefresh,
61
+ onAutoRefreshChange: actions.setAutoRefresh,
62
+ totalCount,
63
+ hasValidationTypes,
64
+ search,
65
+ globalFilters,
66
+ validationTypeFilters,
67
+ pagination,
68
+ validationTypeBreakdown,
69
+ }), [
70
+ autoRejectedScans,
71
+ state.isLoadingScans,
72
+ state.lastRefreshed,
73
+ state.autoRefresh,
74
+ actions.setAutoRefresh,
75
+ totalCount,
76
+ hasValidationTypes,
77
+ search,
78
+ globalFilters,
79
+ validationTypeFilters,
80
+ pagination,
81
+ validationTypeBreakdown,
82
+ ]);
83
+ };
84
+
85
+ export type UseAutoRejectedTabReturn = ReturnType<typeof useAutoRejectedTab>;
@@ -0,0 +1,83 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation
3
+ *
4
+ * See the NOTICE file(s) distributed with this work for additional
5
+ * information regarding copyright ownership.
6
+ *
7
+ * This program and the accompanying materials are made available under the
8
+ * terms of the Eclipse Public License 2.0 which is available at
9
+ * https://www.eclipse.org/legal/epl-2.0
10
+ *
11
+ * SPDX-License-Identifier: EPL-2.0
12
+ ********************************************************************************/
13
+
14
+ import { useMemo } from 'react';
15
+ import { useScanContext } from '../../context/scan-admin';
16
+ import { ConfirmActionType, FileActionType, ScanResult, FileDecision } from '../../context/scan-admin/scan-types';
17
+
18
+ /**
19
+ * Return type for the useDialogs hook
20
+ */
21
+ export interface UseDialogsReturn {
22
+ /** Confirm dialog state and actions (for extension-level allow/block) */
23
+ confirmDialog: {
24
+ isOpen: boolean;
25
+ action: ConfirmActionType;
26
+ selectedExtensions: ScanResult[];
27
+ close: () => void;
28
+ execute: () => void;
29
+ };
30
+ /** File dialog state and actions (for file-level allow/block/delete) */
31
+ fileDialog: {
32
+ isOpen: boolean;
33
+ actionType: FileActionType;
34
+ selectedFiles: FileDecision[];
35
+ close: () => void;
36
+ execute: () => void;
37
+ };
38
+ openAllowDialog: () => void;
39
+ openBlockDialog: () => void;
40
+ openFileDialog: (action: FileActionType) => void;
41
+ }
42
+
43
+ /**
44
+ * Hook for dialog state and actions.
45
+ * Provides a clean interface for dialog components to consume.
46
+ */
47
+ export const useDialogs = (): UseDialogsReturn => {
48
+ const { state, actions, derived } = useScanContext();
49
+
50
+ return useMemo(() => ({
51
+ confirmDialog: {
52
+ isOpen: state.confirmDialogOpen,
53
+ action: state.confirmAction,
54
+ selectedExtensions: derived.selectedExtensions,
55
+ close: actions.closeConfirmDialog,
56
+ execute: actions.executeConfirmAction,
57
+ },
58
+ fileDialog: {
59
+ isOpen: state.fileDialogOpen,
60
+ actionType: state.fileActionType,
61
+ selectedFiles: derived.selectedFiles,
62
+ close: actions.closeFileDialog,
63
+ execute: actions.executeFileAction,
64
+ },
65
+ openAllowDialog: actions.openAllowDialog,
66
+ openBlockDialog: actions.openBlockDialog,
67
+ openFileDialog: actions.openFileDialog,
68
+ }), [
69
+ state.confirmDialogOpen,
70
+ state.confirmAction,
71
+ state.fileDialogOpen,
72
+ state.fileActionType,
73
+ derived.selectedExtensions,
74
+ derived.selectedFiles,
75
+ actions.closeConfirmDialog,
76
+ actions.executeConfirmAction,
77
+ actions.closeFileDialog,
78
+ actions.executeFileAction,
79
+ actions.openAllowDialog,
80
+ actions.openBlockDialog,
81
+ actions.openFileDialog,
82
+ ]);
83
+ };