openvsx-webui-test 0.19.0-dev.2 → 0.20.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 (350) hide show
  1. package/lib/components/banner.js +1 -2
  2. package/lib/components/banner.js.map +1 -1
  3. package/lib/components/copy-to-clipboard.js +1 -2
  4. package/lib/components/copy-to-clipboard.js.map +1 -1
  5. package/lib/components/delayed-load-indicator.js +2 -4
  6. package/lib/components/delayed-load-indicator.js.map +1 -1
  7. package/lib/components/error-dialog.d.ts.map +1 -1
  8. package/lib/components/error-dialog.js +5 -3
  9. package/lib/components/error-dialog.js.map +1 -1
  10. package/lib/components/rate-limiting/customer/general-details.d.ts +20 -0
  11. package/lib/components/rate-limiting/customer/general-details.d.ts.map +1 -0
  12. package/lib/components/rate-limiting/customer/general-details.js +8 -0
  13. package/lib/components/rate-limiting/customer/general-details.js.map +1 -0
  14. package/lib/components/rate-limiting/customer/index.d.ts +17 -0
  15. package/lib/components/rate-limiting/customer/index.d.ts.map +1 -0
  16. package/lib/components/rate-limiting/customer/index.js +15 -0
  17. package/lib/components/rate-limiting/customer/index.js.map +1 -0
  18. package/lib/components/rate-limiting/customer/usage-stats.d.ts +24 -0
  19. package/lib/components/rate-limiting/customer/usage-stats.d.ts.map +1 -0
  20. package/lib/components/rate-limiting/customer/usage-stats.js +6 -0
  21. package/lib/components/rate-limiting/customer/usage-stats.js.map +1 -0
  22. package/lib/{pages/admin-dashboard → components/rate-limiting}/usage-stats/usage-stats-chart.d.ts +5 -2
  23. package/lib/components/rate-limiting/usage-stats/usage-stats-chart.d.ts.map +1 -0
  24. package/lib/{pages/admin-dashboard → components/rate-limiting}/usage-stats/usage-stats-chart.js +25 -18
  25. package/lib/components/rate-limiting/usage-stats/usage-stats-chart.js.map +1 -0
  26. package/lib/components/rate-limiting/usage-stats/usage-stats-utils.d.ts +15 -0
  27. package/lib/components/rate-limiting/usage-stats/usage-stats-utils.d.ts.map +1 -0
  28. package/{src/pages/admin-dashboard/usage-stats/usage-stats-utils.ts → lib/components/rate-limiting/usage-stats/usage-stats-utils.js} +4 -3
  29. package/lib/components/rate-limiting/usage-stats/usage-stats-utils.js.map +1 -0
  30. package/lib/components/rate-limiting/usage-stats/use-usage-stats.d.ts +22 -0
  31. package/lib/components/rate-limiting/usage-stats/use-usage-stats.d.ts.map +1 -0
  32. package/lib/components/rate-limiting/usage-stats/use-usage-stats.js +58 -0
  33. package/lib/components/rate-limiting/usage-stats/use-usage-stats.js.map +1 -0
  34. package/lib/components/scan-admin/common/conditional-tooltip.js +4 -16
  35. package/lib/components/scan-admin/common/conditional-tooltip.js.map +1 -1
  36. package/lib/components/scan-admin/common/file-table.js +24 -13
  37. package/lib/components/scan-admin/common/file-table.js.map +1 -1
  38. package/lib/components/scan-admin/dialogs/quarantine-dialog.js +4 -8
  39. package/lib/components/scan-admin/dialogs/quarantine-dialog.js.map +1 -1
  40. package/lib/components/scan-admin/scan-card/scan-card-content.js +2 -2
  41. package/lib/components/scan-admin/scan-card/scan-card-content.js.map +1 -1
  42. package/lib/components/scan-admin/scan-card/scan-card-expand-strip-badges.js +21 -16
  43. package/lib/components/scan-admin/scan-card/scan-card-expand-strip-badges.js.map +1 -1
  44. package/lib/components/scan-admin/scan-card/scan-card-expanded-content.js +1 -2
  45. package/lib/components/scan-admin/scan-card/scan-card-expanded-content.js.map +1 -1
  46. package/lib/components/scan-admin/scan-card/scan-card-header.js +10 -5
  47. package/lib/components/scan-admin/scan-card/scan-card-header.js.map +1 -1
  48. package/lib/components/scan-admin/scan-card/utils.js +1 -2
  49. package/lib/components/scan-admin/scan-card/utils.js.map +1 -1
  50. package/lib/components/scan-admin/tab-contents/quarantined-tab-content.js +4 -6
  51. package/lib/components/scan-admin/tab-contents/quarantined-tab-content.js.map +1 -1
  52. package/lib/components/sidepanel/drawer-header.d.ts +14 -0
  53. package/lib/components/sidepanel/drawer-header.d.ts.map +1 -0
  54. package/lib/components/sidepanel/drawer-header.js +22 -0
  55. package/lib/components/sidepanel/drawer-header.js.map +1 -0
  56. package/lib/components/sidepanel/navigation-item.d.ts.map +1 -1
  57. package/lib/components/sidepanel/navigation-item.js +3 -3
  58. package/lib/components/sidepanel/navigation-item.js.map +1 -1
  59. package/lib/components/sidepanel/sidepanel.d.ts +7 -1
  60. package/lib/components/sidepanel/sidepanel.d.ts.map +1 -1
  61. package/lib/components/sidepanel/sidepanel.js +12 -13
  62. package/lib/components/sidepanel/sidepanel.js.map +1 -1
  63. package/lib/components/text-divider.js +1 -2
  64. package/lib/components/text-divider.js.map +1 -1
  65. package/lib/components/timestamp.d.ts +0 -1
  66. package/lib/components/timestamp.d.ts.map +1 -1
  67. package/lib/components/timestamp.js +2 -4
  68. package/lib/components/timestamp.js.map +1 -1
  69. package/lib/context/scan-admin/scan-api-actions.js +7 -16
  70. package/lib/context/scan-admin/scan-api-actions.js.map +1 -1
  71. package/lib/context/scan-admin/scan-api-effects.js +77 -93
  72. package/lib/context/scan-admin/scan-api-effects.js.map +1 -1
  73. package/lib/context/scan-admin/scan-context.d.ts.map +1 -1
  74. package/lib/context/scan-admin/scan-context.js +1 -0
  75. package/lib/context/scan-admin/scan-context.js.map +1 -1
  76. package/lib/context/scan-admin/scan-reducer.js +134 -53
  77. package/lib/context/scan-admin/scan-reducer.js.map +1 -1
  78. package/lib/default/default-app.d.ts +1 -1
  79. package/lib/default/default-app.d.ts.map +1 -1
  80. package/lib/default/default-app.js +11 -22
  81. package/lib/default/default-app.js.map +1 -1
  82. package/lib/default/menu-content.d.ts.map +1 -1
  83. package/lib/default/menu-content.js +7 -3
  84. package/lib/default/menu-content.js.map +1 -1
  85. package/lib/default/page-settings.js +13 -18
  86. package/lib/default/page-settings.js.map +1 -1
  87. package/lib/extension-registry-service.d.ts +11 -1
  88. package/lib/extension-registry-service.d.ts.map +1 -1
  89. package/lib/extension-registry-service.js +618 -629
  90. package/lib/extension-registry-service.js.map +1 -1
  91. package/lib/extension-registry-types.d.ts +7 -0
  92. package/lib/extension-registry-types.d.ts.map +1 -1
  93. package/lib/hooks/scan-admin/use-auto-rejected-tab.js +5 -7
  94. package/lib/hooks/scan-admin/use-auto-rejected-tab.js.map +1 -1
  95. package/lib/hooks/scan-admin/use-quarantined-tab.js +5 -7
  96. package/lib/hooks/scan-admin/use-quarantined-tab.js.map +1 -1
  97. package/lib/main.d.ts.map +1 -1
  98. package/lib/main.js +8 -16
  99. package/lib/main.js.map +1 -1
  100. package/lib/other-pages.d.ts +12 -0
  101. package/lib/other-pages.d.ts.map +1 -1
  102. package/lib/other-pages.js +25 -12
  103. package/lib/other-pages.js.map +1 -1
  104. package/lib/pages/admin-dashboard/admin-dashboard.d.ts +0 -12
  105. package/lib/pages/admin-dashboard/admin-dashboard.d.ts.map +1 -1
  106. package/lib/pages/admin-dashboard/admin-dashboard.js +136 -49
  107. package/lib/pages/admin-dashboard/admin-dashboard.js.map +1 -1
  108. package/lib/pages/admin-dashboard/admin-routes.d.ts +25 -0
  109. package/lib/pages/admin-dashboard/admin-routes.d.ts.map +1 -0
  110. package/lib/pages/admin-dashboard/admin-routes.js +27 -0
  111. package/lib/pages/admin-dashboard/admin-routes.js.map +1 -0
  112. package/lib/pages/admin-dashboard/components/data-grid-filter-operators.d.ts +1 -9
  113. package/lib/pages/admin-dashboard/components/data-grid-filter-operators.d.ts.map +1 -1
  114. package/lib/pages/admin-dashboard/components/data-grid-filter-operators.js +17 -15
  115. package/lib/pages/admin-dashboard/components/data-grid-filter-operators.js.map +1 -1
  116. package/lib/pages/admin-dashboard/components/data-grid-filter.d.ts +22 -0
  117. package/lib/pages/admin-dashboard/components/data-grid-filter.d.ts.map +1 -0
  118. package/lib/pages/admin-dashboard/components/data-grid-filter.js +13 -0
  119. package/lib/pages/admin-dashboard/components/data-grid-filter.js.map +1 -0
  120. package/lib/pages/admin-dashboard/components/index.d.ts +2 -1
  121. package/lib/pages/admin-dashboard/components/index.d.ts.map +1 -1
  122. package/lib/pages/admin-dashboard/components/index.js +2 -1
  123. package/lib/pages/admin-dashboard/components/index.js.map +1 -1
  124. package/lib/pages/admin-dashboard/{usage-stats/usage-stats-utils.d.ts → customers/customer-details.d.ts} +3 -2
  125. package/lib/pages/admin-dashboard/customers/customer-details.d.ts.map +1 -0
  126. package/lib/pages/admin-dashboard/customers/customer-details.js +77 -0
  127. package/lib/pages/admin-dashboard/customers/customer-details.js.map +1 -0
  128. package/lib/pages/admin-dashboard/customers/customer-form-dialog.d.ts +1 -1
  129. package/lib/pages/admin-dashboard/customers/customer-form-dialog.d.ts.map +1 -1
  130. package/lib/pages/admin-dashboard/customers/customer-form-dialog.js +33 -34
  131. package/lib/pages/admin-dashboard/customers/customer-form-dialog.js.map +1 -1
  132. package/lib/pages/admin-dashboard/customers/customer-member-list.d.ts +19 -0
  133. package/lib/pages/admin-dashboard/customers/customer-member-list.d.ts.map +1 -0
  134. package/lib/pages/admin-dashboard/customers/customer-member-list.js +88 -0
  135. package/lib/pages/admin-dashboard/customers/customer-member-list.js.map +1 -0
  136. package/lib/pages/admin-dashboard/customers/customers.d.ts +1 -1
  137. package/lib/pages/admin-dashboard/customers/customers.js +20 -29
  138. package/lib/pages/admin-dashboard/customers/customers.js.map +1 -1
  139. package/lib/pages/admin-dashboard/customers/delete-customer-dialog.js +4 -14
  140. package/lib/pages/admin-dashboard/customers/delete-customer-dialog.js.map +1 -1
  141. package/lib/pages/admin-dashboard/extension-admin.js +7 -16
  142. package/lib/pages/admin-dashboard/extension-admin.js.map +1 -1
  143. package/lib/pages/admin-dashboard/extension-remove-dialog.js +3 -12
  144. package/lib/pages/admin-dashboard/extension-remove-dialog.js.map +1 -1
  145. package/lib/pages/admin-dashboard/extension-version-container.js +3 -5
  146. package/lib/pages/admin-dashboard/extension-version-container.js.map +1 -1
  147. package/lib/pages/admin-dashboard/logs/logs.d.ts.map +1 -1
  148. package/lib/pages/admin-dashboard/logs/logs.js +6 -24
  149. package/lib/pages/admin-dashboard/logs/logs.js.map +1 -1
  150. package/lib/pages/admin-dashboard/namespace-admin.js +7 -16
  151. package/lib/pages/admin-dashboard/namespace-admin.js.map +1 -1
  152. package/lib/pages/admin-dashboard/namespace-change-dialog.js +3 -12
  153. package/lib/pages/admin-dashboard/namespace-change-dialog.js.map +1 -1
  154. package/lib/pages/admin-dashboard/namespace-input.js +1 -1
  155. package/lib/pages/admin-dashboard/namespace-input.js.map +1 -1
  156. package/lib/pages/admin-dashboard/publisher-admin.d.ts.map +1 -1
  157. package/lib/pages/admin-dashboard/publisher-admin.js +28 -22
  158. package/lib/pages/admin-dashboard/publisher-admin.js.map +1 -1
  159. package/lib/pages/admin-dashboard/publisher-revoke-dialog.js +5 -15
  160. package/lib/pages/admin-dashboard/publisher-revoke-dialog.js.map +1 -1
  161. package/lib/pages/admin-dashboard/publisher-revoke-tokens-button.js +3 -12
  162. package/lib/pages/admin-dashboard/publisher-revoke-tokens-button.js.map +1 -1
  163. package/lib/pages/admin-dashboard/tiers/delete-tier-dialog.js +4 -13
  164. package/lib/pages/admin-dashboard/tiers/delete-tier-dialog.js.map +1 -1
  165. package/lib/pages/admin-dashboard/tiers/tier-form-dialog.js +34 -23
  166. package/lib/pages/admin-dashboard/tiers/tier-form-dialog.js.map +1 -1
  167. package/lib/pages/admin-dashboard/tiers/tiers.js +12 -21
  168. package/lib/pages/admin-dashboard/tiers/tiers.js.map +1 -1
  169. package/lib/pages/admin-dashboard/usage-stats/usage-stats-search.js +3 -14
  170. package/lib/pages/admin-dashboard/usage-stats/usage-stats-search.js.map +1 -1
  171. package/lib/pages/admin-dashboard/usage-stats/usage-stats.d.ts.map +1 -1
  172. package/lib/pages/admin-dashboard/usage-stats/usage-stats.js +11 -45
  173. package/lib/pages/admin-dashboard/usage-stats/usage-stats.js.map +1 -1
  174. package/lib/pages/admin-dashboard/usage-stats/use-usage-stats.d.ts +22 -0
  175. package/lib/pages/admin-dashboard/usage-stats/use-usage-stats.d.ts.map +1 -0
  176. package/lib/pages/admin-dashboard/usage-stats/use-usage-stats.js +58 -0
  177. package/lib/pages/admin-dashboard/usage-stats/use-usage-stats.js.map +1 -0
  178. package/lib/pages/admin-dashboard/welcome.js +1 -1
  179. package/lib/pages/admin-dashboard/welcome.js.map +1 -1
  180. package/lib/pages/extension-detail/extension-detail-changes.js +3 -12
  181. package/lib/pages/extension-detail/extension-detail-changes.js.map +1 -1
  182. package/lib/pages/extension-detail/extension-detail-overview.js +6 -16
  183. package/lib/pages/extension-detail/extension-detail-overview.js.map +1 -1
  184. package/lib/pages/extension-detail/extension-detail-reviews.js +12 -24
  185. package/lib/pages/extension-detail/extension-detail-reviews.js.map +1 -1
  186. package/lib/pages/extension-detail/extension-detail-routes.d.ts +32 -0
  187. package/lib/pages/extension-detail/extension-detail-routes.d.ts.map +1 -0
  188. package/lib/pages/extension-detail/extension-detail-routes.js +35 -0
  189. package/lib/pages/extension-detail/extension-detail-routes.js.map +1 -0
  190. package/lib/pages/extension-detail/extension-detail.d.ts +0 -19
  191. package/lib/pages/extension-detail/extension-detail.d.ts.map +1 -1
  192. package/lib/pages/extension-detail/extension-detail.js +28 -50
  193. package/lib/pages/extension-detail/extension-detail.js.map +1 -1
  194. package/lib/pages/extension-detail/extension-rating-stars.js +1 -2
  195. package/lib/pages/extension-detail/extension-rating-stars.js.map +1 -1
  196. package/lib/pages/extension-detail/extension-review-dialog.js +4 -14
  197. package/lib/pages/extension-detail/extension-review-dialog.js.map +1 -1
  198. package/lib/pages/extension-list/extension-list-container.d.ts +0 -3
  199. package/lib/pages/extension-list/extension-list-container.d.ts.map +1 -1
  200. package/lib/pages/extension-list/extension-list-container.js +5 -10
  201. package/lib/pages/extension-list/extension-list-container.js.map +1 -1
  202. package/lib/pages/extension-list/extension-list-header.js +3 -6
  203. package/lib/pages/extension-list/extension-list-header.js.map +1 -1
  204. package/lib/pages/extension-list/extension-list-item.js +7 -17
  205. package/lib/pages/extension-list/extension-list-item.js.map +1 -1
  206. package/lib/pages/extension-list/extension-list-routes.d.ts +16 -0
  207. package/lib/pages/extension-list/extension-list-routes.d.ts.map +1 -0
  208. package/lib/pages/extension-list/extension-list-routes.js +18 -0
  209. package/lib/pages/extension-list/extension-list-routes.js.map +1 -0
  210. package/lib/pages/extension-list/extension-list-searchfield.js +4 -7
  211. package/lib/pages/extension-list/extension-list-searchfield.js.map +1 -1
  212. package/lib/pages/extension-list/extension-list.js +8 -19
  213. package/lib/pages/extension-list/extension-list.js.map +1 -1
  214. package/lib/pages/namespace-detail/namespace-detail-routes.d.ts +20 -0
  215. package/lib/pages/namespace-detail/namespace-detail-routes.d.ts.map +1 -0
  216. package/lib/pages/namespace-detail/namespace-detail-routes.js +23 -0
  217. package/lib/pages/namespace-detail/namespace-detail-routes.js.map +1 -0
  218. package/lib/pages/namespace-detail/namespace-detail.d.ts +0 -7
  219. package/lib/pages/namespace-detail/namespace-detail.d.ts.map +1 -1
  220. package/lib/pages/namespace-detail/namespace-detail.js +4 -24
  221. package/lib/pages/namespace-detail/namespace-detail.js.map +1 -1
  222. package/lib/pages/user/add-namespace-member-dialog.d.ts.map +1 -1
  223. package/lib/pages/user/add-namespace-member-dialog.js +8 -67
  224. package/lib/pages/user/add-namespace-member-dialog.js.map +1 -1
  225. package/lib/pages/user/add-user-dialog.d.ts +25 -0
  226. package/lib/pages/user/add-user-dialog.d.ts.map +1 -0
  227. package/lib/pages/user/add-user-dialog.js +66 -0
  228. package/lib/pages/user/add-user-dialog.js.map +1 -0
  229. package/lib/pages/user/avatar.js +3 -3
  230. package/lib/pages/user/avatar.js.map +1 -1
  231. package/lib/pages/user/create-namespace-dialog.js +3 -12
  232. package/lib/pages/user/create-namespace-dialog.js.map +1 -1
  233. package/lib/pages/user/generate-token-dialog.js +3 -12
  234. package/lib/pages/user/generate-token-dialog.js.map +1 -1
  235. package/lib/pages/user/logout.js +3 -12
  236. package/lib/pages/user/logout.js.map +1 -1
  237. package/lib/pages/user/publish-extension-dialog.js +12 -21
  238. package/lib/pages/user/publish-extension-dialog.js.map +1 -1
  239. package/lib/pages/user/user-namespace-details.js +29 -42
  240. package/lib/pages/user/user-namespace-details.js.map +1 -1
  241. package/lib/pages/user/user-namespace-extension-list-item.js +6 -8
  242. package/lib/pages/user/user-namespace-extension-list-item.js.map +1 -1
  243. package/lib/pages/user/user-namespace-extension-list.js +6 -15
  244. package/lib/pages/user/user-namespace-extension-list.js.map +1 -1
  245. package/lib/pages/user/user-namespace-member-component.js +1 -1
  246. package/lib/pages/user/user-namespace-member-component.js.map +1 -1
  247. package/lib/pages/user/user-namespace-member-list.js +9 -18
  248. package/lib/pages/user/user-namespace-member-list.js.map +1 -1
  249. package/lib/pages/user/user-publisher-agreement.js +8 -18
  250. package/lib/pages/user/user-publisher-agreement.js.map +1 -1
  251. package/lib/pages/user/user-setting-tabs.d.ts.map +1 -1
  252. package/lib/pages/user/user-setting-tabs.js +2 -2
  253. package/lib/pages/user/user-setting-tabs.js.map +1 -1
  254. package/lib/pages/user/user-settings-customer-detail.d.ts +19 -0
  255. package/lib/pages/user/user-settings-customer-detail.d.ts.map +1 -0
  256. package/lib/pages/user/user-settings-customer-detail.js +9 -0
  257. package/lib/pages/user/user-settings-customer-detail.js.map +1 -0
  258. package/lib/pages/user/user-settings-customers.d.ts +15 -0
  259. package/lib/pages/user/user-settings-customers.d.ts.map +1 -0
  260. package/lib/pages/user/user-settings-customers.js +66 -0
  261. package/lib/pages/user/user-settings-customers.js.map +1 -0
  262. package/lib/pages/user/user-settings-delete-extension.js +8 -17
  263. package/lib/pages/user/user-settings-delete-extension.js.map +1 -1
  264. package/lib/pages/user/user-settings-extensions.js +3 -12
  265. package/lib/pages/user/user-settings-extensions.js.map +1 -1
  266. package/lib/pages/user/user-settings-namespace-detail.d.ts.map +1 -1
  267. package/lib/pages/user/user-settings-namespace-detail.js +4 -12
  268. package/lib/pages/user/user-settings-namespace-detail.js.map +1 -1
  269. package/lib/pages/user/user-settings-namespaces.js +6 -15
  270. package/lib/pages/user/user-settings-namespaces.js.map +1 -1
  271. package/lib/pages/user/user-settings-profile.js +1 -2
  272. package/lib/pages/user/user-settings-profile.js.map +1 -1
  273. package/lib/pages/user/user-settings-routes.d.ts +23 -0
  274. package/lib/pages/user/user-settings-routes.d.ts.map +1 -0
  275. package/lib/pages/user/user-settings-routes.js +25 -0
  276. package/lib/pages/user/user-settings-routes.js.map +1 -0
  277. package/lib/pages/user/user-settings-tokens.d.ts +0 -7
  278. package/lib/pages/user/user-settings-tokens.d.ts.map +1 -1
  279. package/lib/pages/user/user-settings-tokens.js +14 -24
  280. package/lib/pages/user/user-settings-tokens.js.map +1 -1
  281. package/lib/pages/user/user-settings.d.ts +0 -9
  282. package/lib/pages/user/user-settings.d.ts.map +1 -1
  283. package/lib/pages/user/user-settings.js +4 -12
  284. package/lib/pages/user/user-settings.js.map +1 -1
  285. package/lib/server-request.js +64 -76
  286. package/lib/server-request.js.map +1 -1
  287. package/lib/utils.d.ts +1 -1
  288. package/lib/utils.d.ts.map +1 -1
  289. package/lib/utils.js +7 -14
  290. package/lib/utils.js.map +1 -1
  291. package/package.json +4 -2
  292. package/src/components/error-dialog.tsx +5 -3
  293. package/src/components/rate-limiting/customer/general-details.tsx +106 -0
  294. package/src/components/rate-limiting/customer/index.ts +18 -0
  295. package/src/components/rate-limiting/customer/usage-stats.tsx +50 -0
  296. package/src/{pages/admin-dashboard → components/rate-limiting}/usage-stats/usage-stats-chart.tsx +46 -26
  297. package/{lib/pages/admin-dashboard/usage-stats/usage-stats-utils.js → src/components/rate-limiting/usage-stats/usage-stats-utils.ts} +4 -2
  298. package/src/components/rate-limiting/usage-stats/use-usage-stats.ts +70 -0
  299. package/src/components/scan-admin/scan-card/scan-card-header.tsx +2 -2
  300. package/src/components/sidepanel/drawer-header.tsx +23 -0
  301. package/src/components/sidepanel/navigation-item.tsx +3 -2
  302. package/src/components/sidepanel/sidepanel.tsx +29 -17
  303. package/src/components/timestamp.tsx +1 -3
  304. package/src/context/scan-admin/scan-context.tsx +1 -0
  305. package/src/default/default-app.tsx +1 -1
  306. package/src/default/menu-content.tsx +6 -2
  307. package/src/default/page-settings.tsx +1 -1
  308. package/src/extension-registry-service.ts +105 -26
  309. package/src/extension-registry-types.ts +9 -0
  310. package/src/main.tsx +2 -1
  311. package/src/other-pages.tsx +21 -4
  312. package/src/pages/admin-dashboard/admin-dashboard.tsx +260 -83
  313. package/src/pages/admin-dashboard/admin-routes.ts +27 -0
  314. package/src/pages/admin-dashboard/components/data-grid-filter-operators.tsx +1 -31
  315. package/src/pages/admin-dashboard/components/data-grid-filter.tsx +45 -0
  316. package/src/pages/admin-dashboard/components/index.ts +1 -1
  317. package/src/pages/admin-dashboard/customers/customer-details.tsx +129 -0
  318. package/src/pages/admin-dashboard/customers/customer-form-dialog.tsx +3 -4
  319. package/src/pages/admin-dashboard/customers/customer-member-list.tsx +174 -0
  320. package/src/pages/admin-dashboard/customers/customers.tsx +8 -8
  321. package/src/pages/admin-dashboard/logs/logs.tsx +1 -10
  322. package/src/pages/admin-dashboard/publisher-admin.tsx +29 -11
  323. package/src/pages/admin-dashboard/usage-stats/usage-stats.tsx +10 -39
  324. package/src/pages/admin-dashboard/usage-stats/use-usage-stats.ts +70 -0
  325. package/src/pages/admin-dashboard/welcome.tsx +1 -1
  326. package/src/pages/extension-detail/extension-detail-overview.tsx +2 -2
  327. package/src/pages/extension-detail/extension-detail-routes.ts +35 -0
  328. package/src/pages/extension-detail/extension-detail.tsx +3 -23
  329. package/src/pages/extension-list/extension-list-container.tsx +1 -5
  330. package/src/pages/extension-list/extension-list-item.tsx +1 -1
  331. package/src/pages/extension-list/extension-list-routes.ts +18 -0
  332. package/src/pages/namespace-detail/namespace-detail-routes.ts +23 -0
  333. package/src/pages/namespace-detail/namespace-detail.tsx +0 -10
  334. package/src/pages/user/add-namespace-member-dialog.tsx +17 -116
  335. package/src/pages/user/add-user-dialog.tsx +141 -0
  336. package/src/pages/user/avatar.tsx +2 -2
  337. package/src/pages/user/user-namespace-extension-list-item.tsx +2 -2
  338. package/src/pages/user/user-setting-tabs.tsx +2 -1
  339. package/src/pages/user/user-settings-customer-detail.tsx +39 -0
  340. package/src/pages/user/user-settings-customers.tsx +120 -0
  341. package/src/pages/user/user-settings-delete-extension.tsx +1 -1
  342. package/src/pages/user/user-settings-namespace-detail.tsx +3 -1
  343. package/src/pages/user/user-settings-routes.ts +25 -0
  344. package/src/pages/user/user-settings-tokens.tsx +2 -9
  345. package/src/pages/user/user-settings.tsx +4 -12
  346. package/src/utils.ts +5 -9
  347. package/lib/pages/admin-dashboard/usage-stats/usage-stats-chart.d.ts.map +0 -1
  348. package/lib/pages/admin-dashboard/usage-stats/usage-stats-chart.js.map +0 -1
  349. package/lib/pages/admin-dashboard/usage-stats/usage-stats-utils.d.ts.map +0 -1
  350. package/lib/pages/admin-dashboard/usage-stats/usage-stats-utils.js.map +0 -1
@@ -16,19 +16,9 @@ import TwitterIcon from '@mui/icons-material/Twitter';
16
16
  import { useParams } from 'react-router-dom';
17
17
  import { ExtensionListItem } from '../extension-list/extension-list-item';
18
18
  import { MainContext } from '../../context';
19
- import { createRoute } from '../../utils';
20
19
  import { DelayedLoadIndicator } from '../../components/delayed-load-indicator';
21
20
  import { NamespaceDetails, isError, UrlString } from '../../extension-registry-types';
22
21
 
23
- export namespace NamespaceDetailRoutes {
24
- export namespace Parameters {
25
- export const NAME = ':name';
26
- }
27
-
28
- export const ROOT = 'namespace';
29
- export const MAIN = createRoute([ROOT, Parameters.NAME]);
30
- }
31
-
32
22
  export const NamespaceDetail: FunctionComponent = () => {
33
23
  const [loading, setLoading] = useState(true);
34
24
  const [truncateReadMore, setTruncateReadMore] = useState(true);
@@ -8,15 +8,12 @@
8
8
  * SPDX-License-Identifier: EPL-2.0
9
9
  ********************************************************************************/
10
10
 
11
- import { ChangeEvent, FunctionComponent, KeyboardEvent, useState, useContext, useEffect, useRef } from 'react';
11
+ import { FunctionComponent, useContext, useRef } from 'react';
12
12
  import { UserData } from '../..';
13
- import {
14
- Dialog, DialogTitle, DialogContent, DialogContentText, TextField, DialogActions, Button, Popper, Fade, Paper,
15
- Box, Avatar
16
- } from '@mui/material';
17
13
  import { Namespace, NamespaceMembership, isError } from '../../extension-registry-types';
18
14
  import { NamespaceDetailConfigContext } from './user-settings-namespace-detail';
19
15
  import { MainContext } from '../../context';
16
+ import { AddUserDialog } from './add-user-dialog';
20
17
 
21
18
  export interface AddMemberDialogProps {
22
19
  open: boolean;
@@ -28,29 +25,17 @@ export interface AddMemberDialogProps {
28
25
  }
29
26
 
30
27
  export const AddMemberDialog: FunctionComponent<AddMemberDialogProps> = props => {
31
- const { open } = props;
32
28
  const config = useContext(NamespaceDetailConfigContext);
33
29
  const { service, handleError } = useContext(MainContext);
34
- const [foundUsers, setFoundUsers] = useState<UserData[]>([]);
35
- const [showUserPopper, setShowUserPopper] = useState(false);
36
- const [popperTarget, setPopperTarget] = useState<HTMLInputElement | undefined>(undefined);
37
30
  const abortController = useRef<AbortController>(new AbortController());
38
- useEffect(() => {
39
- return () => {
40
- abortController.current.abort();
41
- };
42
- }, []);
43
31
 
44
- const addUser = async (user: UserData) => {
32
+ const existingUsers = props.members.map(m => m.user);
33
+
34
+ const handleAddUser = async (user: UserData) => {
45
35
  try {
46
36
  if (!props.namespace) {
47
37
  return;
48
38
  }
49
- if (props.members.find(m => m.user.loginName === user.loginName && m.user.provider === user.provider)) {
50
- setShowUserPopper(false);
51
- handleError({ message: `User ${user.loginName} is already a member of ${props.namespace.name}.` });
52
- return;
53
- }
54
39
  props.setLoadingState(true);
55
40
  const endpoint = props.namespace.roleUrl;
56
41
  const result = await service.setNamespaceMember(abortController.current, endpoint, user, config.defaultMemberRole ?? 'contributor');
@@ -58,106 +43,22 @@ export const AddMemberDialog: FunctionComponent<AddMemberDialogProps> = props =>
58
43
  throw result;
59
44
  }
60
45
  props.setLoadingState(false);
61
- onClose();
46
+ props.onClose();
62
47
  } catch (err) {
63
- setShowUserPopper(false);
64
48
  props.setLoadingState(false);
65
49
  handleError(err);
66
50
  }
67
51
  };
68
52
 
69
- const onClose = () => {
70
- setShowUserPopper(false);
71
- props.onClose();
72
- };
73
-
74
- const handleUserSearch = async (e: ChangeEvent<HTMLInputElement>) => {
75
- const popperTarget = e.currentTarget;
76
- setPopperTarget(popperTarget);
77
- const val = popperTarget.value;
78
- let showUserPopper = false;
79
- let foundUsers: UserData[] = [];
80
- if (val) {
81
- const users = await service.getUserByName(abortController.current, val);
82
- if (users) {
83
- showUserPopper = true;
84
- foundUsers = users;
85
- }
86
- }
87
- setShowUserPopper(showUserPopper);
88
- setFoundUsers(foundUsers);
89
- };
90
-
91
- return <>
92
- <Dialog onClose={onClose} open={open} aria-labelledby='form-dialog-title'>
93
- <DialogTitle id='form-dialog-title'>Add User to Namespace</DialogTitle>
94
- <DialogContent>
95
- <DialogContentText>
96
- Enter the Login Name of the User you want to add.
97
- </DialogContentText>
98
- <TextField
99
- autoFocus
100
- margin='dense'
101
- id='name'
102
- autoComplete='off'
103
- label='Open VSX User'
104
- fullWidth
105
- onChange={handleUserSearch}
106
- onKeyDown={(e: KeyboardEvent) => {
107
- if (e.key === "Enter" && foundUsers.length === 1) {
108
- e.preventDefault();
109
- addUser(foundUsers[0]);
110
- }
111
- }}
112
- />
113
- </DialogContent>
114
- <DialogActions>
115
- <Button onClick={onClose} color='secondary'>
116
- Cancel
117
- </Button>
118
- </DialogActions>
119
- </Dialog>
120
- <Popper
121
- sx={{ zIndex: 'tooltip' }}
122
- open={showUserPopper}
123
- anchorEl={popperTarget}
124
- placement='bottom'
125
- transition>
126
- {({ TransitionProps }) => (
127
- <Fade {...TransitionProps} timeout={350}>
128
- <Paper sx={{ display: 'flex', flexDirection: 'column', width: 350 }}>
129
- {
130
- foundUsers.filter(props.filterUsers).map(foundUser => {
131
- return <Box
132
- onClick={() => addUser(foundUser)}
133
- key={'found' + foundUser.loginName}
134
- sx={{
135
- display: 'flex',
136
- height: 60,
137
- alignItems: 'center',
138
- '&:hover': {
139
- cursor: 'pointer',
140
- bgcolor: 'action.hover'
141
- }
142
- }}
143
- >
144
- <Box flex='1' marginLeft='10px'>
145
- <Box fontWeight='bold'>
146
- {foundUser.loginName}
147
- </Box>
148
- <Box fontSize='0.75rem'>
149
- {foundUser.fullName}
150
- </Box>
151
- </Box>
152
- <Box flex='1'>
153
- <Avatar variant='rounded' src={foundUser.avatarUrl} />
154
- </Box>
155
- </Box>;
156
- })
157
- }
158
- </Paper>
159
- </Fade>
160
- )}
161
- </Popper>
162
- </>;
53
+ return (
54
+ <AddUserDialog
55
+ open={props.open}
56
+ title='Add Member'
57
+ description='Enter the Login Name of the User you want to add.'
58
+ existingUsers={existingUsers}
59
+ filterUsers={props.filterUsers}
60
+ onClose={props.onClose}
61
+ onAddUser={handleAddUser}
62
+ />
63
+ );
163
64
  };
@@ -0,0 +1,141 @@
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 { FC, useState, useContext, useEffect, useRef } from 'react';
15
+ import {
16
+ Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Button,
17
+ TextField, Autocomplete, Box, Avatar
18
+ } from '@mui/material';
19
+ import type { UserData } from '../../extension-registry-types';
20
+ import { MainContext } from '../../context';
21
+
22
+ export interface AddUserDialogProps {
23
+ open: boolean;
24
+ title: string;
25
+ description: string;
26
+ existingUsers: UserData[];
27
+ onClose: () => void;
28
+ onAddUser: (user: UserData) => void;
29
+ filterUsers?: (user: UserData) => boolean;
30
+ }
31
+
32
+ export const AddUserDialog: FC<AddUserDialogProps> = ({
33
+ open,
34
+ title,
35
+ description,
36
+ existingUsers,
37
+ onClose,
38
+ onAddUser,
39
+ filterUsers: externalFilter
40
+ }) => {
41
+ const { service, handleError } = useContext(MainContext);
42
+ const [options, setOptions] = useState<UserData[]>([]);
43
+ const [loading, setLoading] = useState(false);
44
+ const abortController = useRef<AbortController>(new AbortController());
45
+ const debounceTimeout = useRef<ReturnType<typeof setTimeout>>();
46
+
47
+ useEffect(() => {
48
+ return () => {
49
+ abortController.current.abort();
50
+ clearTimeout(debounceTimeout.current);
51
+ };
52
+ }, []);
53
+
54
+ const isUserExcluded = (user: UserData) =>
55
+ existingUsers.some(u => u.loginName === user.loginName && u.provider === user.provider)
56
+ || (externalFilter && !externalFilter(user));
57
+
58
+ const handleInputChange = (_: unknown, value: string) => {
59
+ clearTimeout(debounceTimeout.current);
60
+ if (!value) {
61
+ setOptions([]);
62
+ setLoading(false);
63
+ return;
64
+ }
65
+ setLoading(true);
66
+ debounceTimeout.current = setTimeout(async () => {
67
+ const users = await service.getUserByName(abortController.current, value);
68
+ if (users) {
69
+ setOptions(users);
70
+ }
71
+ setLoading(false);
72
+ }, 300);
73
+ };
74
+
75
+ const handleSelect = (_: unknown, user: UserData | null) => {
76
+ if (!user) return;
77
+ if (isUserExcluded(user)) {
78
+ handleError({ message: `User ${user.loginName} is already added.` });
79
+ return;
80
+ }
81
+ onAddUser(user);
82
+ onClose();
83
+ };
84
+
85
+ const handleClose = () => {
86
+ setOptions([]);
87
+ onClose();
88
+ };
89
+
90
+ return (
91
+ <Dialog onClose={handleClose} open={open} maxWidth='sm' fullWidth>
92
+ <DialogTitle>{title}</DialogTitle>
93
+ <DialogContent>
94
+ <DialogContentText>{description}</DialogContentText>
95
+ <Autocomplete<UserData>
96
+ options={options}
97
+ loading={loading}
98
+ filterOptions={(opts) => opts.filter(u => !isUserExcluded(u))}
99
+ getOptionLabel={(option) => option.loginName}
100
+ isOptionEqualToValue={(option, value) =>
101
+ option.loginName === value.loginName && option.provider === value.provider
102
+ }
103
+ onInputChange={handleInputChange}
104
+ onChange={handleSelect}
105
+ renderOption={(props, user) => (
106
+ <Box
107
+ component='li'
108
+ {...props}
109
+ key={user.loginName + user.provider}
110
+ sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}
111
+ >
112
+ <Avatar
113
+ variant='rounded'
114
+ src={user.avatarUrl}
115
+ sx={{ width: 36, height: 36 }}
116
+ />
117
+ <Box>
118
+ <Box fontWeight='bold'>{user.loginName}</Box>
119
+ <Box fontSize='0.75rem' color='text.secondary'>{user.fullName}</Box>
120
+ </Box>
121
+ </Box>
122
+ )}
123
+ renderInput={(params) => (
124
+ <TextField
125
+ {...params}
126
+ autoFocus
127
+ margin='dense'
128
+ label='Search User'
129
+ fullWidth
130
+ />
131
+ )}
132
+ />
133
+ </DialogContent>
134
+ <DialogActions>
135
+ <Button onClick={handleClose} color='secondary'>
136
+ Cancel
137
+ </Button>
138
+ </DialogActions>
139
+ </Dialog>
140
+ );
141
+ };
@@ -11,8 +11,8 @@
11
11
  import { FunctionComponent, useContext, useRef, useState } from 'react';
12
12
  import { Avatar, Menu, Typography, MenuItem, Link, Divider, IconButton } from '@mui/material';
13
13
  import { Link as RouteLink } from 'react-router-dom';
14
- import { UserSettingsRoutes } from './user-settings';
15
- import { AdminDashboardRoutes } from '../admin-dashboard/admin-dashboard';
14
+ import { UserSettingsRoutes } from './user-settings-routes';
15
+ import { AdminDashboardRoutes } from '../admin-dashboard/admin-routes';
16
16
  import { MainContext } from '../../context';
17
17
  import { LogoutForm } from './logout';
18
18
 
@@ -16,9 +16,9 @@ import { Link as RouteLink, useNavigate } from 'react-router-dom';
16
16
  import { MainContext } from '../../context';
17
17
  import { createRoute } from '../../utils';
18
18
  import { Timestamp } from '../../components/timestamp';
19
- import { ExtensionDetailRoutes } from '../extension-detail/extension-detail';
19
+ import { ExtensionDetailRoutes } from '../extension-detail/extension-detail-routes';
20
20
  import DeleteIcon from '@mui/icons-material/Delete';
21
- import { UserSettingsRoutes } from './user-settings';
21
+ import { UserSettingsRoutes } from './user-settings-routes';
22
22
 
23
23
  const getOpacity = (extension: Extension) => {
24
24
  if (extension.deprecated) {
@@ -12,7 +12,7 @@ import { ChangeEvent, ReactElement } from 'react';
12
12
  import { Tabs, Tab, useTheme, useMediaQuery } from '@mui/material';
13
13
  import { useNavigate, useParams } from 'react-router-dom';
14
14
  import { createRoute } from '../../utils';
15
- import { UserSettingsRoutes } from './user-settings';
15
+ import { UserSettingsRoutes } from './user-settings-routes';
16
16
 
17
17
  export const UserSettingTabs = (): ReactElement => {
18
18
 
@@ -42,6 +42,7 @@ export const UserSettingTabs = (): ReactElement => {
42
42
  <Tab value='tokens' label='Access Tokens' />
43
43
  <Tab value='namespaces' label='Namespaces' />
44
44
  <Tab value='extensions' label='Extensions' />
45
+ <Tab value='customers' label='Rate Limiting' />
45
46
  </Tabs>
46
47
  );
47
48
  };
@@ -0,0 +1,39 @@
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 { FC } from 'react';
15
+ import { Box, Typography } from '@mui/material';
16
+ import type { Customer } from '../../extension-registry-types';
17
+ import { useUsageStats } from '../../components/rate-limiting/usage-stats/use-usage-stats';
18
+ import { UsageStats } from '../../components/rate-limiting/customer';
19
+
20
+ export interface UserSettingsCustomerDetailProps {
21
+ customer: Customer;
22
+ }
23
+
24
+ export const UserSettingsCustomerDetail: FC<UserSettingsCustomerDetailProps> = ({ customer }) => {
25
+ const { usageStats, startDate, setStartDate } = useUsageStats(customer.name);
26
+
27
+ return (
28
+ <Box sx={{ flex: 5, pl: { xs: 0, lg: 2 } }}>
29
+ <Typography variant='h4' sx={{ mb: 2 }}>{customer.name}</Typography>
30
+ <UsageStats
31
+ usageStats={usageStats}
32
+ customer={customer}
33
+ startDate={startDate}
34
+ onStartDateChange={setStartDate}
35
+ compact
36
+ />
37
+ </Box>
38
+ );
39
+ };
@@ -0,0 +1,120 @@
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 { FunctionComponent, ReactNode, useContext, useEffect, useState, useRef } from 'react';
15
+ import { Box, Typography, Tabs, Tab, useTheme, useMediaQuery } from '@mui/material';
16
+ import { Customer } from '../../extension-registry-types';
17
+ import { DelayedLoadIndicator } from '../../components/delayed-load-indicator';
18
+ import { MainContext } from '../../context';
19
+ import { UserSettingsCustomerDetail } from './user-settings-customer-detail';
20
+
21
+ interface CustomerTabsProps {
22
+ chosenCustomer: Customer;
23
+ onChange: (value: Customer) => void;
24
+ customers: Customer[];
25
+ }
26
+
27
+ const CustomersTabs = (props: CustomerTabsProps) => {
28
+ const theme = useTheme();
29
+ const isATablet = useMediaQuery(theme.breakpoints.down('md'));
30
+ return (
31
+ <Tabs
32
+ orientation={isATablet ? 'horizontal' : 'vertical'}
33
+ value={props.chosenCustomer}
34
+ onChange={(event, value) => props.onChange(value)}
35
+ variant={isATablet ? 'scrollable' : 'standard'}
36
+ scrollButtons={isATablet ? 'auto' : false}
37
+ indicatorColor='secondary'
38
+ sx={{ width: { xs: '80%', sm: '80%', md: '80%', lg: '160px', xl: '160px' } }}
39
+ >
40
+ {props.customers.map(customer => (
41
+ <Tab
42
+ sx={{
43
+ root: { minHeight: '24px' },
44
+ wrapper: { textTransform: 'none' }
45
+ }}
46
+ key={'cust-' + customer.name}
47
+ value={customer}
48
+ label={customer.name}
49
+ />
50
+ ))}
51
+ </Tabs>
52
+ );
53
+ };
54
+
55
+ export const UserSettingsCustomers: FunctionComponent = () => {
56
+ const [loading, setLoading] = useState(true);
57
+ const [customers, setCustomers] = useState<Customer[]>([]);
58
+ const [chosenCustomer, setChosenCustomer] = useState<Customer>();
59
+ const { service, handleError } = useContext(MainContext);
60
+ const abortController = useRef<AbortController>(new AbortController());
61
+
62
+ useEffect(() => {
63
+ loadCustomers();
64
+ return () => {
65
+ abortController.current.abort();
66
+ };
67
+ }, []);
68
+
69
+ const loadCustomers = async (): Promise<void> => {
70
+ try {
71
+ const data = await service.getCustomers(abortController.current);
72
+ const chosen = data.length ? data[0] : undefined;
73
+ setCustomers(data);
74
+ setChosenCustomer(chosen);
75
+ setLoading(false);
76
+ } catch (err) {
77
+ handleError(err);
78
+ setLoading(false);
79
+ }
80
+ };
81
+
82
+ let customerContainer: ReactNode = null;
83
+ if (customers.length > 0 && chosenCustomer) {
84
+ customerContainer = (
85
+ <Box
86
+ sx={{
87
+ display: 'flex',
88
+ width: '100%',
89
+ flexDirection: { xs: 'column', sm: 'column', md: 'column', lg: 'row', xl: 'row' },
90
+ alignItems: { xs: 'center', sm: 'center', md: 'center', lg: 'normal', xl: 'normal' }
91
+ }}
92
+ >
93
+ <CustomersTabs
94
+ chosenCustomer={chosenCustomer}
95
+ customers={customers}
96
+ onChange={setChosenCustomer}
97
+ />
98
+ <UserSettingsCustomerDetail customer={chosenCustomer} />
99
+ </Box>
100
+ );
101
+ } else if (!loading) {
102
+ customerContainer = (
103
+ <Typography variant='body1'>
104
+ You are not a member of any rate limiting customer group.
105
+ </Typography>
106
+ );
107
+ }
108
+
109
+ return (
110
+ <>
111
+ <Box>
112
+ <Typography variant='h5' gutterBottom>Rate Limiting</Typography>
113
+ </Box>
114
+ <Box mt={2}>
115
+ <DelayedLoadIndicator loading={loading} />
116
+ {customerContainer}
117
+ </Box>
118
+ </>
119
+ );
120
+ };
@@ -15,7 +15,7 @@ import { isError, Extension, TargetPlatformVersion } from '../../extension-regis
15
15
  import { DelayedLoadIndicator } from '../../components/delayed-load-indicator';
16
16
  import { ExtensionVersionContainer } from '../admin-dashboard/extension-version-container';
17
17
  import { useNavigate } from 'react-router';
18
- import { UserSettingsRoutes } from './user-settings';
18
+ import { UserSettingsRoutes } from './user-settings-routes';
19
19
 
20
20
  export const UserSettingsDeleteExtension: FunctionComponent<UserSettingsDeleteExtensionProps> = props => {
21
21
  const navigate = useNavigate();
@@ -14,7 +14,7 @@ import { Box, Button, Link, Paper, Grid, Typography } from '@mui/material';
14
14
  import { styled, Theme } from '@mui/material/styles';
15
15
  import WarningIcon from '@mui/icons-material/Warning';
16
16
  import { UserNamespaceExtensionListContainer } from './user-namespace-extension-list';
17
- import { AdminDashboardRoutes } from '../admin-dashboard/admin-dashboard';
17
+ import { AdminDashboardRoutes } from '../admin-dashboard/admin-routes';
18
18
  import { Namespace, UserData } from '../../extension-registry-types';
19
19
  import { NamespaceChangeDialog } from '../admin-dashboard/namespace-change-dialog';
20
20
  import { UserNamespaceMemberList } from './user-namespace-member-list';
@@ -23,6 +23,8 @@ import { UserNamespaceDetails } from './user-namespace-details';
23
23
  export interface NamespaceDetailConfig {
24
24
  defaultMemberRole?: 'contributor' | 'owner';
25
25
  }
26
+
27
+ // eslint-disable-next-line react-refresh/only-export-components
26
28
  export const NamespaceDetailConfigContext = createContext<NamespaceDetailConfig>({});
27
29
 
28
30
  const NamespaceDetailContainer = styled(Grid)(({ theme }: { theme: Theme }) => ({
@@ -0,0 +1,25 @@
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 { createRoute } from '../../utils';
15
+
16
+ export namespace UserSettingsRoutes {
17
+ export const ROOT = createRoute(['user-settings']);
18
+ export const MAIN = createRoute([ROOT, ':tab']);
19
+ export const PROFILE = createRoute([ROOT, 'profile']);
20
+ export const TOKENS = createRoute([ROOT, 'tokens']);
21
+ export const NAMESPACES = createRoute([ROOT, 'namespaces']);
22
+ export const EXTENSIONS = createRoute([ROOT, 'extensions']);
23
+ export const DELETE_EXTENSION = createRoute([ROOT, 'extensions', ':namespace', ':extension', 'delete']);
24
+ export const CUSTOMERS = createRoute([ROOT, 'customers']);
25
+ }
@@ -16,7 +16,7 @@ import { Timestamp } from '../../components/timestamp';
16
16
  import { PersonalAccessToken } from '../../extension-registry-types';
17
17
  import { MainContext } from '../../context';
18
18
  import { GenerateTokenDialog } from './generate-token-dialog';
19
- import { UserSettingsRoutes } from './user-settings';
19
+ import { UserSettingsRoutes } from './user-settings-routes';
20
20
  import styled from '@mui/material/styles/styled';
21
21
 
22
22
  const link = ({ theme }: { theme: Theme }) => ({
@@ -105,7 +105,7 @@ export const UserSettingsTokens: FunctionComponent = () => {
105
105
  <Box alignItems='center' overflow='auto'>
106
106
  <Typography sx={{ fontWeight: 'bold', overflow: 'hidden', textOverflow: 'ellipsis' }}>{token.description}</Typography>
107
107
  <Typography variant='body2'>Created: <Timestamp value={token.createdTimestamp}/></Typography>
108
- <Typography variant='body2'>Expires: {token.expiresTimestamp ? <Timestamp value={token.expiresTimestamp} isFutureTime={true} /> : 'never'}</Typography>
108
+ <Typography variant='body2'>Expires: {token.expiresTimestamp ? <Timestamp value={token.expiresTimestamp}/> : 'never'}</Typography>
109
109
  <Typography variant='body2'>Accessed: {token.accessedTimestamp ? <Timestamp value={token.accessedTimestamp}/> : 'never'}</Typography>
110
110
  </Box>
111
111
  <Box display='flex' alignItems='center'>
@@ -216,10 +216,3 @@ export const UserSettingsTokens: FunctionComponent = () => {
216
216
  </Dialog>
217
217
  </>;
218
218
  };
219
-
220
- export namespace UserSettingsTokens {
221
- export interface State {
222
- tokens: PersonalAccessToken[];
223
- loading: boolean;
224
- }
225
- }
@@ -12,28 +12,18 @@ import { FunctionComponent, ReactNode, useContext } from 'react';
12
12
  import { Helmet } from 'react-helmet-async';
13
13
  import { Grid, Container, Box, Typography, Link } from '@mui/material';
14
14
  import { useParams } from 'react-router-dom';
15
- import { createRoute } from '../../utils';
16
15
  import { DelayedLoadIndicator } from '../../components/delayed-load-indicator';
17
16
  import { UserSettingTabs } from './user-setting-tabs';
18
17
  import { UserSettingsTokens } from './user-settings-tokens';
19
18
  import { UserSettingsProfile } from './user-settings-profile';
20
19
  import { UserSettingsNamespaces } from './user-settings-namespaces';
21
20
  import { UserSettingsExtensions } from './user-settings-extensions';
21
+ import { UserSettingsCustomers } from './user-settings-customers';
22
22
  import { MainContext } from '../../context';
23
23
  import { UserData } from '../../extension-registry-types';
24
24
  import { LoginComponent } from '../../default/login';
25
25
  import { UserSettingsDeleteExtension } from './user-settings-delete-extension';
26
26
 
27
- export namespace UserSettingsRoutes {
28
- export const ROOT = createRoute(['user-settings']);
29
- export const MAIN = createRoute([ROOT, ':tab']);
30
- export const PROFILE = createRoute([ROOT, 'profile']);
31
- export const TOKENS = createRoute([ROOT, 'tokens']);
32
- export const NAMESPACES = createRoute([ROOT, 'namespaces']);
33
- export const EXTENSIONS = createRoute([ROOT, 'extensions']);
34
- export const DELETE_EXTENSION = createRoute([ROOT, 'extensions', ':namespace', ':extension', 'delete']);
35
- }
36
-
37
27
  export const UserSettings: FunctionComponent<UserSettingsProps> = props => {
38
28
 
39
29
  const { pageSettings, user, loginProviders } = useContext(MainContext);
@@ -53,6 +43,8 @@ export const UserSettings: FunctionComponent<UserSettingsProps> = props => {
53
43
  return <UserSettingsNamespaces />;
54
44
  case 'extensions':
55
45
  return <UserSettingsExtensions />;
46
+ case 'customers':
47
+ return <UserSettingsCustomers />;
56
48
  default:
57
49
  return null;
58
50
  }
@@ -79,7 +71,7 @@ return (<Link color='secondary' href={href} onClick={onClick}>log in</Link>);
79
71
  </Container> : null;
80
72
  }
81
73
 
82
- return <Container>
74
+ return <Container maxWidth={'xl'}>
83
75
  <Box mt={6}>
84
76
  <Grid container sx={{ flexDirection: { xs: 'column', sm: 'column', md: 'column', lg: 'row', xl: 'row' } }}>
85
77
  <Grid item sx={{ mb: { xs: '3rem', sm: '3rem', md: '3rem', lg: '3rem', xl: 0 } }}>