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
@@ -0,0 +1,82 @@
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, useCallback } from 'react';
15
+ import { useScanContext } from '../../context/scan-admin';
16
+
17
+ /**
18
+ * Tab definitions for the Scans Admin page.
19
+ */
20
+ export const TAB_DEFINITIONS = [
21
+ { index: 0, name: 'Scans', path: 'scans' },
22
+ { index: 1, name: 'Quarantined', path: 'quarantined' },
23
+ { index: 2, name: 'Auto Rejected', path: 'auto-rejected' },
24
+ { index: 3, name: 'Allowed Files', path: 'allowed-files' },
25
+ { index: 4, name: 'Blocked Files', path: 'blocked-files' },
26
+ ] as const;
27
+
28
+ export type TabIndex = 0 | 1 | 2 | 3 | 4;
29
+ export type TabName = typeof TAB_DEFINITIONS[number]['name'];
30
+
31
+ /**
32
+ * Hook for managing tab navigation state and actions.
33
+ */
34
+ export const useTabNavigation = () => {
35
+ const { state, actions } = useScanContext();
36
+
37
+ const setTab = useCallback((tab: number) => {
38
+ if (tab >= 0 && tab <= 4) {
39
+ actions.setTab(tab);
40
+ }
41
+ }, [actions]);
42
+
43
+ const currentTab = useMemo(() => {
44
+ return TAB_DEFINITIONS[state.selectedTab] || TAB_DEFINITIONS[0];
45
+ }, [state.selectedTab]);
46
+
47
+ const isScansTab = state.selectedTab === 0;
48
+ const isQuarantinedTab = state.selectedTab === 1;
49
+ const isAutoRejectedTab = state.selectedTab === 2;
50
+ const isAllowListTab = state.selectedTab === 3;
51
+ const isBlockListTab = state.selectedTab === 4;
52
+
53
+ const isScanDataTab = state.selectedTab <= 2;
54
+ const isFileDataTab = state.selectedTab >= 3;
55
+
56
+ return useMemo(() => ({
57
+ selectedTab: state.selectedTab,
58
+ currentTab,
59
+ tabs: TAB_DEFINITIONS,
60
+ setTab,
61
+ isScansTab,
62
+ isQuarantinedTab,
63
+ isAutoRejectedTab,
64
+ isAllowListTab,
65
+ isBlockListTab,
66
+ isScanDataTab,
67
+ isFileDataTab,
68
+ }), [
69
+ state.selectedTab,
70
+ currentTab,
71
+ setTab,
72
+ isScansTab,
73
+ isQuarantinedTab,
74
+ isAutoRejectedTab,
75
+ isAllowListTab,
76
+ isBlockListTab,
77
+ isScanDataTab,
78
+ isFileDataTab,
79
+ ]);
80
+ };
81
+
82
+ export type UseTabNavigationReturn = ReturnType<typeof useTabNavigation>;
@@ -0,0 +1,293 @@
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 { useEffect, useRef, useCallback } from 'react';
15
+ import { useScanContext } from '../../context/scan-admin';
16
+ import { DateRangeType, EnforcementType } from '../../context/scan-admin/scan-types';
17
+
18
+ /**
19
+ * URL parameter keys
20
+ */
21
+ const URL_PARAMS = {
22
+ TAB: 'tab',
23
+ PAGE: 'page',
24
+ PUBLISHER: 'publisher',
25
+ NAMESPACE: 'namespace',
26
+ NAME: 'name',
27
+ DATE_RANGE: 'dateRange',
28
+ FILE_DATE_RANGE: 'fileDateRange',
29
+ ENFORCEMENT: 'enforcement',
30
+ // Checkbox filters
31
+ STATUS_FILTERS: 'status',
32
+ QUARANTINE_FILTERS: 'quarantine',
33
+ THREAT_SCANNER_FILTERS: 'threatScanner',
34
+ VALIDATION_TYPE_FILTERS: 'validationType',
35
+ } as const;
36
+
37
+ /**
38
+ * Tab name to index mapping
39
+ */
40
+ const TAB_NAME_TO_INDEX: Record<string, number> = {
41
+ 'scans': 0,
42
+ 'quarantined': 1,
43
+ 'auto-rejected': 2,
44
+ 'allowed-files': 3,
45
+ 'blocked-files': 4,
46
+ };
47
+
48
+ const TAB_INDEX_TO_NAME: Record<number, string> = {
49
+ 0: 'scans',
50
+ 1: 'quarantined',
51
+ 2: 'auto-rejected',
52
+ 3: 'allowed-files',
53
+ 4: 'blocked-files',
54
+ };
55
+
56
+ /**
57
+ * Valid date range values
58
+ */
59
+ const VALID_DATE_RANGES: DateRangeType[] = ['today', 'last7days', 'last30days', 'last90days', 'all'];
60
+
61
+ /**
62
+ * Valid enforcement values
63
+ */
64
+ const VALID_ENFORCEMENTS: EnforcementType[] = ['enforced', 'notEnforced', 'all'];
65
+
66
+ /**
67
+ * Hook to sync scan admin state with URL parameters.
68
+ * This enables bookmarkable URLs and browser back/forward navigation.
69
+ */
70
+ export const useUrlSync = () => {
71
+ const { state, dispatch } = useScanContext();
72
+ const isInitialized = useRef(false);
73
+ const isUpdatingFromUrl = useRef(false);
74
+
75
+ /**
76
+ * Parse URL parameters and apply to state on initial load
77
+ */
78
+ const initializeFromUrl = useCallback(() => {
79
+ const params = new URLSearchParams(window.location.search);
80
+
81
+ // Tab
82
+ const tabParam = params.get(URL_PARAMS.TAB);
83
+ if (tabParam && TAB_NAME_TO_INDEX[tabParam] !== undefined) {
84
+ dispatch({ type: 'SET_TAB', payload: TAB_NAME_TO_INDEX[tabParam] });
85
+ }
86
+
87
+ // Page (URL is 1-indexed, state is 0-indexed)
88
+ const pageParam = params.get(URL_PARAMS.PAGE);
89
+ if (pageParam) {
90
+ const page = parseInt(pageParam, 10);
91
+ if (!isNaN(page) && page >= 1) {
92
+ dispatch({ type: 'SET_PAGE', payload: page - 1 });
93
+ }
94
+ }
95
+
96
+ // Search queries
97
+ const publisherParam = params.get(URL_PARAMS.PUBLISHER);
98
+ if (publisherParam) {
99
+ dispatch({ type: 'SET_PUBLISHER_QUERY', payload: publisherParam });
100
+ }
101
+
102
+ const namespaceParam = params.get(URL_PARAMS.NAMESPACE);
103
+ if (namespaceParam) {
104
+ dispatch({ type: 'SET_NAMESPACE_QUERY', payload: namespaceParam });
105
+ }
106
+
107
+ const nameParam = params.get(URL_PARAMS.NAME);
108
+ if (nameParam) {
109
+ dispatch({ type: 'SET_NAME_QUERY', payload: nameParam });
110
+ }
111
+
112
+ // Date range
113
+ const dateRangeParam = params.get(URL_PARAMS.DATE_RANGE);
114
+ if (dateRangeParam && VALID_DATE_RANGES.indexOf(dateRangeParam as DateRangeType) !== -1) {
115
+ dispatch({ type: 'SET_DATE_RANGE', payload: dateRangeParam as DateRangeType });
116
+ }
117
+
118
+ // File date range
119
+ const fileDateRangeParam = params.get(URL_PARAMS.FILE_DATE_RANGE);
120
+ if (fileDateRangeParam && VALID_DATE_RANGES.indexOf(fileDateRangeParam as DateRangeType) !== -1) {
121
+ dispatch({ type: 'SET_FILE_DATE_RANGE', payload: fileDateRangeParam as DateRangeType });
122
+ }
123
+
124
+ // Enforcement
125
+ const enforcementParam = params.get(URL_PARAMS.ENFORCEMENT);
126
+ if (enforcementParam && VALID_ENFORCEMENTS.indexOf(enforcementParam as EnforcementType) !== -1) {
127
+ dispatch({ type: 'SET_ENFORCEMENT', payload: enforcementParam as EnforcementType });
128
+ }
129
+
130
+ // Status filters (comma-separated)
131
+ const statusFiltersParam = params.get(URL_PARAMS.STATUS_FILTERS);
132
+ if (statusFiltersParam) {
133
+ const filters = new Set(statusFiltersParam.split(',').filter(Boolean));
134
+ if (filters.size > 0) {
135
+ dispatch({ type: 'SET_STATUS_FILTERS', payload: filters });
136
+ }
137
+ }
138
+
139
+ // Quarantine filters (comma-separated)
140
+ const quarantineFiltersParam = params.get(URL_PARAMS.QUARANTINE_FILTERS);
141
+ if (quarantineFiltersParam) {
142
+ const filters = new Set(quarantineFiltersParam.split(',').filter(Boolean));
143
+ if (filters.size > 0) {
144
+ dispatch({ type: 'SET_QUARANTINE_FILTERS', payload: filters });
145
+ }
146
+ }
147
+
148
+ // Threat scanner filters (comma-separated)
149
+ const threatScannerFiltersParam = params.get(URL_PARAMS.THREAT_SCANNER_FILTERS);
150
+ if (threatScannerFiltersParam) {
151
+ const filters = new Set(threatScannerFiltersParam.split(',').filter(Boolean));
152
+ if (filters.size > 0) {
153
+ dispatch({ type: 'SET_THREAT_SCANNER_FILTERS', payload: filters });
154
+ }
155
+ }
156
+
157
+ // Validation type filters (comma-separated)
158
+ const validationTypeFiltersParam = params.get(URL_PARAMS.VALIDATION_TYPE_FILTERS);
159
+ if (validationTypeFiltersParam) {
160
+ const filters = new Set(validationTypeFiltersParam.split(',').filter(Boolean));
161
+ if (filters.size > 0) {
162
+ dispatch({ type: 'SET_VALIDATION_TYPE_FILTERS', payload: filters });
163
+ }
164
+ }
165
+ }, [dispatch]);
166
+
167
+ /**
168
+ * Update URL parameters from state
169
+ */
170
+ const updateUrlFromState = useCallback(() => {
171
+ if (isUpdatingFromUrl.current) {
172
+ return;
173
+ }
174
+
175
+ const params = new URLSearchParams();
176
+
177
+ // Tab (only add if not default)
178
+ if (state.selectedTab !== 0) {
179
+ params.set(URL_PARAMS.TAB, TAB_INDEX_TO_NAME[state.selectedTab] || 'scans');
180
+ }
181
+
182
+ // Page (only add if not first page, URL is 1-indexed)
183
+ if (state.currentPage > 0) {
184
+ params.set(URL_PARAMS.PAGE, String(state.currentPage + 1));
185
+ }
186
+
187
+ // Search queries (only add if not empty)
188
+ if (state.publisherQuery) {
189
+ params.set(URL_PARAMS.PUBLISHER, state.publisherQuery);
190
+ }
191
+ if (state.namespaceQuery) {
192
+ params.set(URL_PARAMS.NAMESPACE, state.namespaceQuery);
193
+ }
194
+ if (state.nameQuery) {
195
+ params.set(URL_PARAMS.NAME, state.nameQuery);
196
+ }
197
+
198
+ // Date range (only add if not default)
199
+ if (state.dateRange !== 'all') {
200
+ params.set(URL_PARAMS.DATE_RANGE, state.dateRange);
201
+ }
202
+
203
+ // File date range (only add if not default)
204
+ if (state.fileDateRange !== 'all') {
205
+ params.set(URL_PARAMS.FILE_DATE_RANGE, state.fileDateRange);
206
+ }
207
+
208
+ // Enforcement (only add if not tab-specific default)
209
+ // Tabs 1 (Quarantined) and 2 (Auto Rejected) default to 'enforced', others default to 'all'
210
+ const defaultEnforcement = (state.selectedTab === 1 || state.selectedTab === 2) ? 'enforced' : 'all';
211
+ if (state.enforcement !== defaultEnforcement) {
212
+ params.set(URL_PARAMS.ENFORCEMENT, state.enforcement);
213
+ }
214
+
215
+ // Status filters (only add if any are selected)
216
+ if (state.statusFilters.size > 0) {
217
+ params.set(URL_PARAMS.STATUS_FILTERS, Array.from(state.statusFilters).join(','));
218
+ }
219
+
220
+ // Quarantine filters (only add if any are selected - default is empty)
221
+ if (state.quarantineFilters.size > 0) {
222
+ params.set(URL_PARAMS.QUARANTINE_FILTERS, Array.from(state.quarantineFilters).join(','));
223
+ }
224
+
225
+ // Threat scanner filters (only add if any are selected)
226
+ if (state.threatScannerFilters.size > 0) {
227
+ params.set(URL_PARAMS.THREAT_SCANNER_FILTERS, Array.from(state.threatScannerFilters).join(','));
228
+ }
229
+
230
+ // Validation type filters (only add if any are selected)
231
+ if (state.validationTypeFilters.size > 0) {
232
+ params.set(URL_PARAMS.VALIDATION_TYPE_FILTERS, Array.from(state.validationTypeFilters).join(','));
233
+ }
234
+
235
+ // Build new URL
236
+ const newSearch = params.toString();
237
+ const newUrl = newSearch
238
+ ? `${window.location.pathname}?${newSearch}`
239
+ : window.location.pathname;
240
+
241
+ // Update URL without triggering a page reload
242
+ if (window.location.search !== (newSearch ? `?${newSearch}` : '')) {
243
+ window.history.replaceState(null, '', newUrl);
244
+ }
245
+ }, [state.selectedTab, state.currentPage, state.publisherQuery, state.namespaceQuery, state.nameQuery, state.dateRange, state.fileDateRange, state.enforcement, state.statusFilters, state.quarantineFilters, state.threatScannerFilters, state.validationTypeFilters]);
246
+
247
+ /**
248
+ * Handle browser back/forward navigation
249
+ */
250
+ const handlePopState = useCallback(() => {
251
+ isUpdatingFromUrl.current = true;
252
+ initializeFromUrl();
253
+ // Reset the flag after a short delay to allow state to settle
254
+ setTimeout(() => {
255
+ isUpdatingFromUrl.current = false;
256
+ }, 100);
257
+ }, [initializeFromUrl]);
258
+
259
+ // Initialize from URL on mount
260
+ useEffect(() => {
261
+ if (!isInitialized.current) {
262
+ isInitialized.current = true;
263
+ isUpdatingFromUrl.current = true;
264
+ initializeFromUrl();
265
+ // Reset the flag after initialization
266
+ setTimeout(() => {
267
+ isUpdatingFromUrl.current = false;
268
+ }, 100);
269
+ }
270
+ }, [initializeFromUrl]);
271
+
272
+ // Update URL when state changes
273
+ useEffect(() => {
274
+ if (isInitialized.current) {
275
+ updateUrlFromState();
276
+ }
277
+ }, [updateUrlFromState]);
278
+
279
+ // Listen for browser back/forward
280
+ useEffect(() => {
281
+ window.addEventListener('popstate', handlePopState);
282
+ return () => {
283
+ window.removeEventListener('popstate', handlePopState);
284
+ };
285
+ }, [handlePopState]);
286
+
287
+ return {
288
+ initializeFromUrl,
289
+ updateUrlFromState,
290
+ };
291
+ };
292
+
293
+ export type UseUrlSyncReturn = ReturnType<typeof useUrlSync>;
@@ -16,6 +16,10 @@ import { Cookie } from './utils';
16
16
  export interface PageSettings {
17
17
  pageTitle: string;
18
18
  themeType?: 'light' | 'dark';
19
+ publisherAgreement?: {
20
+ name?: string;
21
+ email?: string;
22
+ };
19
23
  elements: {
20
24
  toolbarContent?: ComponentType;
21
25
  defaultMenuContent?: ComponentType;
@@ -23,6 +23,8 @@ import HighlightOffIcon from '@mui/icons-material/HighlightOff';
23
23
  import { Welcome } from './welcome';
24
24
  import { PublisherAdmin } from './publisher-admin';
25
25
  import PersonIcon from '@mui/icons-material/Person';
26
+ import { ScanAdmin } from './scan-admin';
27
+ import SecurityIcon from '@mui/icons-material/Security';
26
28
 
27
29
  export namespace AdminDashboardRoutes {
28
30
  export const ROOT = 'admin-dashboard';
@@ -30,6 +32,7 @@ export namespace AdminDashboardRoutes {
30
32
  export const NAMESPACE_ADMIN = createRoute([ROOT, 'namespaces']);
31
33
  export const EXTENSION_ADMIN = createRoute([ROOT, 'extensions']);
32
34
  export const PUBLISHER_ADMIN = createRoute([ROOT, 'publisher']);
35
+ export const SCANS_ADMIN = createRoute([ROOT, 'scans']);
33
36
  }
34
37
 
35
38
  const Message: FunctionComponent<{message: string}> = ({ message }) => {
@@ -59,16 +62,37 @@ export const AdminDashboard: FunctionComponent<AdminDashboardProps> = props => {
59
62
  <NavigationItem onOpenRoute={handleOpenRoute} active={currentPage === AdminDashboardRoutes.NAMESPACE_ADMIN} label='Namespaces' icon={<AssignmentIndIcon />} route={AdminDashboardRoutes.NAMESPACE_ADMIN} />
60
63
  <NavigationItem onOpenRoute={handleOpenRoute} active={currentPage === AdminDashboardRoutes.EXTENSION_ADMIN} label='Extensions' icon={<ExtensionSharpIcon />} route={AdminDashboardRoutes.EXTENSION_ADMIN} />
61
64
  <NavigationItem onOpenRoute={handleOpenRoute} active={currentPage === AdminDashboardRoutes.PUBLISHER_ADMIN} label='Publishers' icon={<PersonIcon />} route={AdminDashboardRoutes.PUBLISHER_ADMIN} />
65
+ <NavigationItem onOpenRoute={handleOpenRoute} active={currentPage === AdminDashboardRoutes.SCANS_ADMIN} label='Scans' icon={<SecurityIcon />} route={AdminDashboardRoutes.SCANS_ADMIN} />
62
66
  </Sidepanel>
63
- <Box overflow='auto' flex={1}>
67
+ <Box
68
+ overflow='auto'
69
+ flex={1}
70
+ sx={{
71
+ overflowY: 'scroll',
72
+ '&::-webkit-scrollbar': {
73
+ width: '12px',
74
+ },
75
+ '&::-webkit-scrollbar-track': {
76
+ backgroundColor: 'rgba(0, 0, 0, 0.2)',
77
+ },
78
+ '&::-webkit-scrollbar-thumb': {
79
+ backgroundColor: 'rgba(255, 255, 255, 0.2)',
80
+ borderRadius: '6px',
81
+ '&:hover': {
82
+ backgroundColor: 'rgba(255, 255, 255, 0.3)',
83
+ },
84
+ },
85
+ }}
86
+ >
64
87
  <IconButton onClick={toMainPage} sx={{ float: 'right', mt: 1, mr: 1 }}>
65
88
  <HighlightOffIcon/>
66
89
  </IconButton>
67
- <Container sx={{ pt: 8, height: '100%' }} maxWidth='lg'>
90
+ <Container sx={{ pt: 4, pb: 4, px: 3, height: '100%' }} maxWidth='xl'>
68
91
  <Routes>
69
92
  <Route path='/namespaces' element={<NamespaceAdmin/>} />
70
93
  <Route path='/extensions' element={<ExtensionAdmin/>} />
71
94
  <Route path='/publisher' element={<PublisherAdmin/>} />
95
+ <Route path='/scans' element={<ScanAdmin/>} />
72
96
  <Route path='*' element={<Welcome/>} />
73
97
  </Routes>
74
98
  </Container>
@@ -17,7 +17,7 @@ import { SearchListContainer } from './search-list-container';
17
17
  import { PublisherDetails } from './publisher-details';
18
18
 
19
19
  export const UpdateContext = createContext({ handleUpdate: () => { } });
20
- export const PublisherAdmin: FunctionComponent = props => {
20
+ export const PublisherAdmin: FunctionComponent = () => {
21
21
  const { pageSettings, service, user, handleError } = useContext(MainContext);
22
22
 
23
23
  const abortController = useRef<AbortController>(new AbortController());
@@ -61,6 +61,7 @@ export const PublisherRevokeDialog: FunctionComponent<PublisherRevokeDialogProps
61
61
  const tokenCount = props.publisherInfo.activeAccessTokenNum;
62
62
  const extensionCount = props.publisherInfo.extensions.filter(e => e.active).length;
63
63
  const hasAgreement = props.publisherInfo.user.publisherAgreement?.status !== 'none';
64
+
64
65
  return <>
65
66
  <Button
66
67
  variant='contained'
@@ -74,7 +75,7 @@ export const PublisherRevokeDialog: FunctionComponent<PublisherRevokeDialogProps
74
75
  <DialogTitle >Revoke Publisher Contributions</DialogTitle>
75
76
  <DialogContent>
76
77
  <DialogContentText component='div'>
77
- <Typography>
78
+ <Typography component='div'>
78
79
  {
79
80
  !tokenCount && !extensionCount && !hasAgreement ?
80
81
  <>
@@ -0,0 +1,109 @@
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 React, { FunctionComponent, useContext } from 'react';
15
+ import { Box, Typography } from '@mui/material';
16
+ import { ScanProvider } from '../../context/scan-admin';
17
+ import { useTabNavigation, useUrlSync } from '../../hooks/scan-admin';
18
+ import {
19
+ TabToolbar,
20
+ TabPanel,
21
+ ScansTabContent,
22
+ QuarantinedTabContent,
23
+ AutoRejectedTabContent,
24
+ AllowListTabContent,
25
+ BlockListTabContent,
26
+ QuarantineDialog,
27
+ FileDialog,
28
+ } from '../../components/scan-admin';
29
+ import { MainContext } from '../../context';
30
+
31
+ /**
32
+ * Inner component that consumes the ScanContext.
33
+ * Uses lean tab components that consume context via hooks.
34
+ */
35
+ const ScanAdminContent: FunctionComponent = () => {
36
+ const { selectedTab, setTab } = useTabNavigation();
37
+
38
+ // Sync state with URL parameters for bookmarkable URLs and browser navigation
39
+ useUrlSync();
40
+
41
+ const handleTabChange = (_event: React.SyntheticEvent, newValue: number) => {
42
+ setTab(newValue);
43
+ };
44
+
45
+ return (
46
+ <Box sx={{
47
+ width: 'min(1500px, 100vw - 280px)',
48
+ maxWidth: 'none',
49
+ mx: 'auto',
50
+ px: 2,
51
+ pb: 3,
52
+ position: 'relative',
53
+ left: '50%',
54
+ transform: 'translateX(-50%)',
55
+ }}>
56
+ <Typography variant='h5' gutterBottom sx={{ mb: 2 }}>
57
+ Extension Scans
58
+ </Typography>
59
+ <Box sx={{ width: '100%' }}>
60
+ <TabToolbar
61
+ selectedTab={selectedTab}
62
+ onTabChange={handleTabChange}
63
+ tabs={['Scans', 'Quarantined', 'Auto Rejected', 'Allowed Files', 'Blocked Files']}
64
+ />
65
+
66
+ {/* Tab panels - each tab content component consumes context via hooks */}
67
+ <TabPanel value={selectedTab} index={0}>
68
+ <ScansTabContent />
69
+ </TabPanel>
70
+
71
+ <TabPanel value={selectedTab} index={1}>
72
+ <QuarantinedTabContent />
73
+ </TabPanel>
74
+
75
+ <TabPanel value={selectedTab} index={2}>
76
+ <AutoRejectedTabContent />
77
+ </TabPanel>
78
+
79
+ <TabPanel value={selectedTab} index={3}>
80
+ <AllowListTabContent />
81
+ </TabPanel>
82
+
83
+ <TabPanel value={selectedTab} index={4}>
84
+ <BlockListTabContent />
85
+ </TabPanel>
86
+ </Box>
87
+
88
+ {/* Dialogs - consume context via hooks */}
89
+ <QuarantineDialog />
90
+ <FileDialog />
91
+ </Box>
92
+ );
93
+ };
94
+
95
+ /**
96
+ * Main ScanAdmin component that provides the context.
97
+ * This is the entry point for the scan administration feature.
98
+ */
99
+ export const ScanAdmin: FunctionComponent = () => {
100
+ const { service, handleError } = useContext(MainContext);
101
+
102
+ return (
103
+ <ScanProvider service={service} handleError={handleError}>
104
+ <ScanAdminContent />
105
+ </ScanProvider>
106
+ );
107
+ };
108
+
109
+ export default ScanAdmin;
@@ -27,6 +27,7 @@ export const Welcome: FunctionComponent = props => {
27
27
  <WelcomeLinkItem route={AdminDashboardRoutes.NAMESPACE_ADMIN} label='Namespaces' description='Manage user roles, create new namespaces' />
28
28
  <WelcomeLinkItem route={AdminDashboardRoutes.EXTENSION_ADMIN} label='Extensions' description='Search for extensions and remove certain versions' />
29
29
  <WelcomeLinkItem route={AdminDashboardRoutes.PUBLISHER_ADMIN} label='Publishers' description='Search for publishers and revoke their contributions' />
30
+ <WelcomeLinkItem route={AdminDashboardRoutes.SCANS_ADMIN} label='Scans' description='View security scan results and manage quarantined extensions' />
30
31
  </Grid>
31
32
  </Paper>
32
33
  </Grid>
@@ -141,6 +141,13 @@ export const ExtensionDetailOverview: FunctionComponent<ExtensionDetailOverviewP
141
141
  </>;
142
142
  };
143
143
 
144
+ const renderIdentifierSection = (): ReactNode => {
145
+ return <>
146
+ <Typography variant='h6'>Unique Identifier</Typography>
147
+ <Typography variant='body2'><code>{`${extension.namespace}.${extension.name}`}</code></Typography>
148
+ </>;
149
+ };
150
+
144
151
  const renderAliasesSection = (otherAliases: string[], sx: SxProps<Theme>): ReactNode => {
145
152
  const { extension } = props;
146
153
  const aliasButtons = otherAliases.length ?
@@ -321,6 +328,13 @@ export const ExtensionDetailOverview: FunctionComponent<ExtensionDetailOverviewP
321
328
  (otherAliases.length || extension.versionAlias.length) ? <Box>{renderAliasesSection(otherAliases, tagButton)}</Box> : ''
322
329
  }
323
330
  </Box>
331
+
332
+ <Box sx={resourcesGroup}>
333
+ <Box>
334
+ {renderIdentifierSection()}
335
+ </Box>
336
+ </Box>
337
+
324
338
  <Box sx={resourcesGroup}>
325
339
  {
326
340
  extension.categories && extension.categories.length > 0 ?
@@ -331,7 +345,7 @@ export const ExtensionDetailOverview: FunctionComponent<ExtensionDetailOverviewP
331
345
  }
332
346
  {
333
347
  tags && tags.length > 0 ?
334
- <Box mt={2}>
348
+ <Box mt={extension.categories && extension.categories.length > 0 ? 2 : 0}>
335
349
  {renderButtonList('search', 'Tags', tags, tagButton)}
336
350
  </Box>
337
351
  : null
@@ -392,4 +406,4 @@ export const ExtensionDetailOverview: FunctionComponent<ExtensionDetailOverviewP
392
406
  export interface ExtensionDetailOverviewProps {
393
407
  extension: Extension;
394
408
  selectVersion: (version: string) => void;
395
- }
409
+ }