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,104 @@
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, { useRef, useEffect, useState } from 'react';
15
+ import { Box } from '@mui/material';
16
+ import { ExpandMore as ExpandMoreIcon } from '@mui/icons-material';
17
+ import { useTheme } from '@mui/material/styles';
18
+ import { DetailBadge } from './utils';
19
+ import { ScanCardExpandStripBadges } from './scan-card-expand-strip-badges';
20
+
21
+ interface ScanCardExpandStripProps {
22
+ expanded: boolean;
23
+ onExpandClick: () => void;
24
+ badges: DetailBadge[];
25
+ collapseComplete: boolean;
26
+ }
27
+
28
+ /**
29
+ * Expandable strip at the bottom of the card
30
+ * Shows validationFailure/threat badges (click to expand/show detail cards)
31
+ */
32
+ export const ScanCardExpandStrip: React.FC<ScanCardExpandStripProps> = ({
33
+ expanded,
34
+ onExpandClick,
35
+ badges,
36
+ collapseComplete,
37
+ }) => {
38
+ const theme = useTheme();
39
+ const [isHovering, setIsHovering] = useState(false);
40
+ const wrapperRef = useRef<HTMLDivElement>(null);
41
+ const [containerWidth, setContainerWidth] = useState(0);
42
+
43
+ useEffect(() => {
44
+ const updateWidth = () => {
45
+ if (wrapperRef.current) {
46
+ setContainerWidth(wrapperRef.current.offsetWidth);
47
+ }
48
+ };
49
+
50
+ updateWidth();
51
+
52
+ const resizeObserver = new ResizeObserver(() => {
53
+ updateWidth();
54
+ });
55
+
56
+ if (wrapperRef.current) {
57
+ resizeObserver.observe(wrapperRef.current);
58
+ }
59
+
60
+ return () => resizeObserver.disconnect();
61
+ }, []);
62
+
63
+ return (
64
+ <Box
65
+ ref={wrapperRef}
66
+ onClick={onExpandClick}
67
+ onMouseEnter={() => setIsHovering(true)}
68
+ onMouseLeave={() => setIsHovering(false)}
69
+ sx={{
70
+ pb: 0,
71
+ pt: 0.5,
72
+ px: 5,
73
+ display: 'flex',
74
+ alignItems: 'center',
75
+ justifyContent: 'space-between',
76
+ cursor: 'pointer',
77
+ borderBottomRightRadius: expanded ? 0 : 8,
78
+ minHeight: 40,
79
+ backgroundColor: isHovering ? theme.palette.selected.hover : 'transparent',
80
+ transition: 'background-color 0.2s',
81
+ position: 'relative',
82
+ }}
83
+ >
84
+ <Box sx={{ flex: 1 }} />
85
+ <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'absolute', left: '50%', transform: 'translateX(-50%)' }}>
86
+ <ExpandMoreIcon
87
+ sx={{
88
+ fontSize: 36,
89
+ color: 'secondary.main',
90
+ transform: expanded ? 'rotate(180deg)' : 'rotate(0deg)',
91
+ transition: 'transform 0.3s',
92
+ }}
93
+ />
94
+ </Box>
95
+
96
+ {!expanded && collapseComplete && (
97
+ <ScanCardExpandStripBadges
98
+ badges={badges}
99
+ containerWidth={containerWidth}
100
+ />
101
+ )}
102
+ </Box>
103
+ );
104
+ };
@@ -0,0 +1,262 @@
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 from 'react';
15
+ import { Box, Typography, Collapse, Chip } from '@mui/material';
16
+ import { useTheme, Theme } from '@mui/material/styles';
17
+ import { ScanResult, Threat, ValidationFailure, CheckResult } from '../../../context/scan-admin';
18
+ import { ScanDetailCard } from './scan-detail-card';
19
+ import { formatDateTime } from '../common';
20
+
21
+ interface ScanCardExpandedContentProps {
22
+ scan: ScanResult;
23
+ expanded: boolean;
24
+ onCollapseComplete?: () => void;
25
+ }
26
+
27
+ interface ThreatItemProps {
28
+ threat: Threat;
29
+ }
30
+
31
+ interface ValidationFailureItemProps {
32
+ failure: ValidationFailure;
33
+ }
34
+
35
+ interface CheckResultItemProps {
36
+ checkResult: CheckResult;
37
+ }
38
+
39
+ /**
40
+ * A single threat item in the expanded content.
41
+ */
42
+ const ThreatItem: React.FC<ThreatItemProps> = ({ threat }) => {
43
+ const theme = useTheme();
44
+
45
+ return (
46
+ <ScanDetailCard
47
+ accentColor={theme.palette.quarantined.dark as string}
48
+ isUnenforced={!threat.enforcedFlag}
49
+ description={threat.reason}
50
+ descriptionColor='warning.dark'
51
+ details={[
52
+ { label: 'File', value: threat.fileName || '(package-level scan)' },
53
+ { label: 'Hash', value: threat.fileHash || undefined },
54
+ { label: 'Scanner', value: threat.type },
55
+ { label: 'Rule Name', value: threat.ruleName },
56
+ { label: 'Severity', value: threat.severity },
57
+ { label: 'Detected at', value: threat.dateDetected ? formatDateTime(threat.dateDetected) : undefined },
58
+ ]}
59
+ />
60
+ );
61
+ };
62
+
63
+ /**
64
+ * A single validation failure item in the expanded content.
65
+ */
66
+ const ValidationFailureItem: React.FC<ValidationFailureItemProps> = ({ failure }) => {
67
+ const theme = useTheme();
68
+ const isUnenforced = !failure.enforcedFlag;
69
+
70
+ return (
71
+ <ScanDetailCard
72
+ accentColor={theme.palette.rejected.dark as string}
73
+ isUnenforced={isUnenforced}
74
+ chip={{
75
+ label: failure.type,
76
+ color: theme.palette.rejected.dark as string,
77
+ textColor: theme.palette.rejected.light as string,
78
+ }}
79
+ description={failure.reason}
80
+ details={[
81
+ { label: 'Rule Name', value: failure.ruleName },
82
+ { label: 'Detected at', value: failure.dateDetected ? formatDateTime(failure.dateDetected) : undefined },
83
+ ]}
84
+ />
85
+ );
86
+ };
87
+
88
+ /**
89
+ * Get color for check result status.
90
+ */
91
+ const getCheckResultColor = (result: CheckResult['result'], theme: Theme) => {
92
+ switch (result) {
93
+ case 'PASSED':
94
+ return { bg: theme.palette.success.dark, text: theme.palette.success.light };
95
+ case 'QUARANTINE':
96
+ // Orange/amber - scanner found enforced threats, recommends quarantine
97
+ return { bg: theme.palette.quarantined.dark as string, text: theme.palette.quarantined.light as string };
98
+ case 'REJECT':
99
+ // Red - publish check recommends rejection
100
+ return { bg: theme.palette.rejected.dark as string, text: theme.palette.rejected.light as string };
101
+ case 'ERROR':
102
+ return { bg: theme.palette.errorStatus.dark as string, text: theme.palette.errorStatus.light as string };
103
+ default:
104
+ return { bg: theme.palette.grey[500], text: theme.palette.grey[100] };
105
+ }
106
+ };
107
+
108
+ /**
109
+ * Format duration in milliseconds to a readable string.
110
+ */
111
+ const formatDuration = (ms: number | null): string | undefined => {
112
+ if (ms === null) return undefined;
113
+ if (ms === 0) return '<1ms';
114
+ if (ms < 1000) return `${ms}ms`;
115
+ if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
116
+ return `${(ms / 60000).toFixed(1)}m`;
117
+ };
118
+
119
+ /**
120
+ * A single check result item showing what check was run and its outcome.
121
+ */
122
+ const CheckResultItem: React.FC<CheckResultItemProps> = ({ checkResult }) => {
123
+ const theme = useTheme();
124
+ const colors = getCheckResultColor(checkResult.result, theme);
125
+ const isPassed = checkResult.result === 'PASSED';
126
+ const isError = checkResult.result === 'ERROR';
127
+ // Non-required errors get striped styling to indicate they didn't block publishing
128
+ const isOptionalError = isError && checkResult.required === false;
129
+
130
+ return (
131
+ <Box sx={{
132
+ display: 'flex',
133
+ alignItems: 'center',
134
+ justifyContent: 'space-between',
135
+ p: 1.5,
136
+ borderRadius: 1,
137
+ bgcolor: isPassed ? 'action.hover' : 'transparent',
138
+ border: isPassed ? 'none' : `1px solid ${theme.palette.divider}`,
139
+ }}>
140
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>
141
+ <Chip
142
+ label={checkResult.result}
143
+ size='small'
144
+ sx={{
145
+ bgcolor: isOptionalError ? 'transparent' : colors.bg,
146
+ background: isOptionalError
147
+ ? `${theme.palette.unenforced.stripe}, ${colors.bg}`
148
+ : undefined,
149
+ color: colors.text,
150
+ fontWeight: 600,
151
+ fontSize: '0.7rem',
152
+ height: 22,
153
+ }}
154
+ />
155
+ <Typography variant='body2' sx={{ fontWeight: 500 }}>
156
+ {checkResult.checkType}
157
+ </Typography>
158
+ <Chip
159
+ label={checkResult.category === 'PUBLISH_CHECK' ? 'Publish Check' : 'Scanner'}
160
+ size='small'
161
+ variant='outlined'
162
+ sx={{ fontSize: '0.65rem', height: 18 }}
163
+ />
164
+ </Box>
165
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2, color: 'text.secondary' }}>
166
+ {checkResult.summary && (
167
+ <Typography variant='caption'>
168
+ {checkResult.summary}
169
+ </Typography>
170
+ )}
171
+ {checkResult.durationMs !== null && (
172
+ <Typography variant='caption' sx={{ minWidth: 50, textAlign: 'right' }}>
173
+ {formatDuration(checkResult.durationMs)}
174
+ </Typography>
175
+ )}
176
+ </Box>
177
+ </Box>
178
+ );
179
+ };
180
+
181
+ /**
182
+ * The expanded content section showing threats, validation failures, and check results.
183
+ * Each item's enforcedFlag controls its individual striping effect.
184
+ */
185
+ export const ScanCardExpandedContent: React.FC<ScanCardExpandedContentProps> = ({ scan, expanded, onCollapseComplete }) => {
186
+ const theme = useTheme();
187
+ const hasThreats = scan.threats.length > 0;
188
+ const hasValidationFailures = scan.validationFailures.length > 0;
189
+ const hasCheckResults = scan.checkResults && scan.checkResults.length > 0;
190
+ const hasErrorMessage = scan.status === 'ERROR' && scan.errorMessage;
191
+ const hasAnyContent = hasThreats || hasValidationFailures || hasCheckResults || hasErrorMessage;
192
+
193
+ return (
194
+ <Collapse in={expanded} timeout='auto' unmountOnExit onExited={onCollapseComplete}>
195
+ <Box sx={{
196
+ px: 4,
197
+ pb: 3,
198
+ pt: 2,
199
+ borderBottomRightRadius: 8,
200
+ }}>
201
+ {/* Error Message */}
202
+ {hasErrorMessage && (
203
+ <Box sx={{ mb: hasAnyContent ? 2 : 0 }}>
204
+ <ScanDetailCard
205
+ accentColor={theme.palette.errorStatus.dark as string}
206
+ chip={{
207
+ label: 'ERROR',
208
+ color: theme.palette.errorStatus.dark as string,
209
+ textColor: theme.palette.errorStatus.light as string,
210
+ }}
211
+ description={scan.errorMessage ?? undefined}
212
+ descriptionColor='text.secondary'
213
+ details={[]}
214
+ />
215
+ </Box>
216
+ )}
217
+
218
+ {/* Check Results - What scans/checks were run */}
219
+ {hasCheckResults && (
220
+ <Box sx={{ mb: (hasThreats || hasValidationFailures) ? 2 : 0 }}>
221
+ <Typography variant='subtitle2' sx={{ mb: 1.5, color: 'text.secondary' }}>
222
+ Checks Executed
223
+ </Typography>
224
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}>
225
+ {scan.checkResults.map((result, index) => (
226
+ <CheckResultItem key={index} checkResult={result} />
227
+ ))}
228
+ </Box>
229
+ </Box>
230
+ )}
231
+
232
+ {/* Threats */}
233
+ {hasThreats && (
234
+ <Box>
235
+ <Typography variant='subtitle2' sx={{ mb: 1.5, color: 'text.secondary' }}>
236
+ Threats Detected
237
+ </Typography>
238
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>
239
+ {scan.threats.map((threat, index) => (
240
+ <ThreatItem key={index} threat={threat} />
241
+ ))}
242
+ </Box>
243
+ </Box>
244
+ )}
245
+
246
+ {/* Validation Failures */}
247
+ {hasValidationFailures && (
248
+ <Box sx={{ mt: hasThreats ? 2 : 0 }}>
249
+ <Typography variant='subtitle2' sx={{ mb: 1.5, color: 'text.secondary' }}>
250
+ Validation Failures
251
+ </Typography>
252
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>
253
+ {scan.validationFailures.map((failure, index) => (
254
+ <ValidationFailureItem key={index} failure={failure} />
255
+ ))}
256
+ </Box>
257
+ </Box>
258
+ )}
259
+ </Box>
260
+ </Collapse>
261
+ );
262
+ };
@@ -0,0 +1,176 @@
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, { useState } from 'react';
15
+ import { Box, Typography, Chip, CircularProgress } from '@mui/material';
16
+ import {
17
+ CheckCircle as CheckCircleIcon,
18
+ GppMaybe as WarningIcon,
19
+ Block as BlockIcon,
20
+ Cancel as CancelIcon,
21
+ Info as InfoIcon,
22
+ } from '@mui/icons-material';
23
+ import { ScanResult } from '../../../context/scan-admin';
24
+ import { ConditionalTooltip } from '../common';
25
+ import { useTheme } from '@mui/material/styles';
26
+ import {
27
+ ICON_SIZE,
28
+ isRunning,
29
+ shouldShowStriped,
30
+ getHypotheticalStatus,
31
+ getStatusColorSx,
32
+ } from './utils';
33
+
34
+ interface ScanCardHeaderProps {
35
+ scan: ScanResult;
36
+ }
37
+
38
+ const getStatusIcon = (status: ScanResult['status']) => {
39
+ switch (status) {
40
+ case 'PASSED':
41
+ return <CheckCircleIcon fontSize='small' />;
42
+ case 'QUARANTINED':
43
+ return <WarningIcon fontSize='small' />;
44
+ case 'AUTO REJECTED':
45
+ return <BlockIcon fontSize='small' />;
46
+ case 'ERROR':
47
+ return <CancelIcon fontSize='small' />;
48
+ default:
49
+ return null;
50
+ }
51
+ };
52
+
53
+ /**
54
+ * Header section of the ScanCard containing:
55
+ * - Extension icon
56
+ * - Display name and namespace
57
+ * - Status badge
58
+ */
59
+ export const ScanCardHeader: React.FC<ScanCardHeaderProps> = ({ scan }) => {
60
+ const theme = useTheme();
61
+ const [imageError, setImageError] = useState(false);
62
+
63
+ const hasValidIcon = scan.extensionIcon && !imageError;
64
+
65
+ return (
66
+ <>
67
+ {/* Column 1: Icon */}
68
+ <Box
69
+ sx={{
70
+ gridRow: '1',
71
+ gridColumn: '1',
72
+ width: ICON_SIZE,
73
+ height: ICON_SIZE,
74
+ bgcolor: hasValidIcon ? 'transparent' : 'action.hover',
75
+ borderRadius: 1,
76
+ display: 'flex',
77
+ alignItems: 'center',
78
+ justifyContent: 'center',
79
+ overflow: 'hidden',
80
+ }}
81
+ >
82
+ {hasValidIcon ? (
83
+ <img
84
+ src={scan.extensionIcon}
85
+ alt={scan.displayName}
86
+ onError={() => setImageError(true)}
87
+ style={{
88
+ width: '100%',
89
+ height: '100%',
90
+ objectFit: 'contain',
91
+ }}
92
+ />
93
+ ) : (
94
+ <Typography variant='h4' color='text.secondary'>
95
+ {scan.displayName.charAt(0).toUpperCase()}
96
+ </Typography>
97
+ )}
98
+ </Box>
99
+
100
+ {/* Columns 2-4: Display Name and Namespace */}
101
+ <Box sx={{ gridRow: '1', gridColumn: '2 / 5', minWidth: 0 }}>
102
+ <ConditionalTooltip title={scan.displayName} arrow>
103
+ <Typography
104
+ variant='h6'
105
+ sx={{
106
+ fontWeight: 600,
107
+ overflow: 'hidden',
108
+ textOverflow: 'ellipsis',
109
+ whiteSpace: 'nowrap',
110
+ }}
111
+ >
112
+ {scan.displayName}
113
+ </Typography>
114
+ </ConditionalTooltip>
115
+ <ConditionalTooltip title={`${scan.namespace}.${scan.extensionName}`} arrow>
116
+ <Typography
117
+ variant='body2'
118
+ color='text.secondary'
119
+ sx={{
120
+ overflow: 'hidden',
121
+ textOverflow: 'ellipsis',
122
+ whiteSpace: 'nowrap',
123
+ }}
124
+ >
125
+ {scan.namespace}.{scan.extensionName}
126
+ </Typography>
127
+ </ConditionalTooltip>
128
+ </Box>
129
+
130
+ {/* Column 5: Status Badge */}
131
+ <Box sx={{
132
+ gridRow: '1',
133
+ gridColumn: '5',
134
+ display: 'flex',
135
+ flexDirection: 'column',
136
+ alignItems: 'flex-end',
137
+ justifyContent: 'flex-start',
138
+ minWidth: 0,
139
+ gap: 0.5,
140
+ }}>
141
+ {isRunning(scan.status) ? (
142
+ <CircularProgress size={32} color='secondary' />
143
+ ) : (
144
+ <>
145
+ <Chip
146
+ label={scan.status}
147
+ size='medium'
148
+ icon={getStatusIcon(scan.status) || undefined}
149
+ sx={{
150
+ ...getStatusColorSx(scan.status, theme),
151
+ transform: 'scale(1.2)',
152
+ transformOrigin: 'right top',
153
+ ...(shouldShowStriped(scan) && {
154
+ background: `${theme.palette.unenforced.stripe}, ${getStatusColorSx(scan.status, theme).backgroundColor}`,
155
+ }),
156
+ }}
157
+ />
158
+ {shouldShowStriped(scan) && getHypotheticalStatus(scan) && (
159
+ <Box sx={{
160
+ display: 'flex',
161
+ alignItems: 'center',
162
+ gap: 0.5,
163
+ mt: 0.5,
164
+ }}>
165
+ <InfoIcon sx={{ fontSize: 14, color: 'text.secondary' }} />
166
+ <Typography variant='caption' sx={{ color: 'text.secondary', fontSize: '0.7rem' }}>
167
+ Would be {getHypotheticalStatus(scan)}
168
+ </Typography>
169
+ </Box>
170
+ )}
171
+ </>
172
+ )}
173
+ </Box>
174
+ </>
175
+ );
176
+ };
@@ -0,0 +1,152 @@
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 } from 'react';
15
+ import { Card, CardContent, Box } from '@mui/material';
16
+ import { useTheme } from '@mui/material/styles';
17
+ import { ScanResult } from '../../../context/scan-admin';
18
+
19
+ import { ScanCardHeader } from './scan-card-header';
20
+ import { ScanCardContent } from './scan-card-content';
21
+ import { ScanCardExpandStrip } from './scan-card-expand-strip';
22
+ import { ScanCardExpandedContent } from './scan-card-expanded-content';
23
+ import { useScanCardState } from '../../../hooks/scan-admin';
24
+ import {
25
+ ICON_SIZE,
26
+ shouldShowStriped,
27
+ getStatusBarColor,
28
+ } from './utils';
29
+
30
+ interface ScanCardProps {
31
+ scan: ScanResult;
32
+ showCheckbox?: boolean;
33
+ onCheckboxChange?: (id: string, checked: boolean) => void;
34
+ checked?: boolean;
35
+ }
36
+
37
+ /**
38
+ * ScanCard component displays information about an extension scan.
39
+ *
40
+ * Sub-components:
41
+ * - ScanCardHeader: Icon, display name, namespace, status badge
42
+ * - ScanCardContent: Publisher, version, download, scan times, checkbox
43
+ * - ScanCardExpandStrip: Collapsible trigger bar with badges
44
+ * - ScanCardExpandedContent: Threats and validation failures
45
+ *
46
+ * State is managed via the useScanCardState hook.
47
+ */
48
+ export const ScanCard: FunctionComponent<ScanCardProps> = ({
49
+ scan,
50
+ showCheckbox,
51
+ onCheckboxChange,
52
+ checked,
53
+ }) => {
54
+ const theme = useTheme();
55
+ const [collapseComplete, setCollapseComplete] = React.useState(true);
56
+ const {
57
+ expanded,
58
+ handleExpandClick,
59
+ showExpandButton,
60
+ badges,
61
+ liveDuration,
62
+ cardRef,
63
+ } = useScanCardState(scan);
64
+
65
+ // Reset collapseComplete when expanding
66
+ React.useEffect(() => {
67
+ if (expanded) {
68
+ setCollapseComplete(false);
69
+ }
70
+ }, [expanded]);
71
+
72
+ return (
73
+ <Card
74
+ ref={cardRef}
75
+ sx={{
76
+ position: 'relative',
77
+ mb: 1.5,
78
+ borderRadius: 2,
79
+ boxShadow: theme.palette.mode === 'light' ? 4 : 2,
80
+ backgroundColor: 'transparent',
81
+ outline: checked ? '2px solid' : 'none',
82
+ outlineColor: checked ? 'secondary.main' : 'transparent',
83
+ '&:hover': {
84
+ boxShadow: theme.palette.mode === 'light' ? 6 : 4,
85
+ },
86
+ overflow: 'hidden',
87
+ paddingLeft: '16px',
88
+ '&::before': {
89
+ content: '""',
90
+ position: 'absolute',
91
+ left: 0,
92
+ top: 0,
93
+ bottom: 0,
94
+ width: '16px',
95
+ background: shouldShowStriped(scan)
96
+ ? `${theme.palette.unenforced.stripe}, ${getStatusBarColor(scan.status, theme)}`
97
+ : getStatusBarColor(scan.status, theme),
98
+ zIndex: 0,
99
+ },
100
+ }}
101
+ >
102
+ <CardContent
103
+ sx={{
104
+ position: 'relative',
105
+ zIndex: 1,
106
+ pt: 5,
107
+ pr: 5,
108
+ pl: 5,
109
+ pb: showExpandButton ? 0 : 5,
110
+ '&:last-child': { pb: showExpandButton ? 0 : 5 },
111
+ }}
112
+ >
113
+ {/* 3 Row x 5 Column Grid Layout */}
114
+ <Box sx={{
115
+ display: 'grid',
116
+ gridTemplateColumns: `${ICON_SIZE}px 1fr 1fr 1fr 180px`,
117
+ gridTemplateRows: 'auto auto auto',
118
+ gap: 2,
119
+ alignItems: 'start',
120
+ }}>
121
+ <ScanCardHeader scan={scan} />
122
+ <ScanCardContent
123
+ scan={scan}
124
+ showCheckbox={showCheckbox}
125
+ checked={checked}
126
+ onCheckboxChange={onCheckboxChange}
127
+ liveDuration={liveDuration}
128
+ />
129
+ </Box>
130
+ </CardContent>
131
+
132
+ {/* Expandable strip with badges */}
133
+ {showExpandButton && (
134
+ <ScanCardExpandStrip
135
+ expanded={expanded}
136
+ onExpandClick={handleExpandClick}
137
+ badges={badges}
138
+ collapseComplete={collapseComplete}
139
+ />
140
+ )}
141
+
142
+ {/* Expanded content */}
143
+ {showExpandButton && (
144
+ <ScanCardExpandedContent
145
+ scan={scan}
146
+ expanded={expanded}
147
+ onCollapseComplete={() => setCollapseComplete(true)}
148
+ />
149
+ )}
150
+ </Card>
151
+ );
152
+ };