openvsx-webui-test 0.19.0-dev.1 → 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.
- package/lib/components/banner.js +1 -2
- package/lib/components/banner.js.map +1 -1
- package/lib/components/copy-to-clipboard.js +1 -2
- package/lib/components/copy-to-clipboard.js.map +1 -1
- package/lib/components/delayed-load-indicator.js +2 -4
- package/lib/components/delayed-load-indicator.js.map +1 -1
- package/lib/components/rate-limiting/customer/general-details.d.ts +20 -0
- package/lib/components/rate-limiting/customer/general-details.d.ts.map +1 -0
- package/lib/components/rate-limiting/customer/general-details.js +8 -0
- package/lib/components/rate-limiting/customer/general-details.js.map +1 -0
- package/lib/components/rate-limiting/customer/index.d.ts +17 -0
- package/lib/components/rate-limiting/customer/index.d.ts.map +1 -0
- package/lib/components/rate-limiting/customer/index.js +15 -0
- package/lib/components/rate-limiting/customer/index.js.map +1 -0
- package/lib/components/rate-limiting/customer/usage-stats.d.ts +24 -0
- package/lib/components/rate-limiting/customer/usage-stats.d.ts.map +1 -0
- package/lib/components/rate-limiting/customer/usage-stats.js +6 -0
- package/lib/components/rate-limiting/customer/usage-stats.js.map +1 -0
- package/lib/{pages/admin-dashboard → components/rate-limiting}/usage-stats/usage-stats-chart.d.ts +5 -2
- package/lib/components/rate-limiting/usage-stats/usage-stats-chart.d.ts.map +1 -0
- package/lib/{pages/admin-dashboard → components/rate-limiting}/usage-stats/usage-stats-chart.js +25 -18
- package/lib/components/rate-limiting/usage-stats/usage-stats-chart.js.map +1 -0
- package/lib/components/rate-limiting/usage-stats/usage-stats-utils.d.ts +15 -0
- package/lib/components/rate-limiting/usage-stats/usage-stats-utils.d.ts.map +1 -0
- package/{src/pages/admin-dashboard/usage-stats/usage-stats-utils.ts → lib/components/rate-limiting/usage-stats/usage-stats-utils.js} +4 -3
- package/lib/components/rate-limiting/usage-stats/usage-stats-utils.js.map +1 -0
- package/lib/components/rate-limiting/usage-stats/use-usage-stats.d.ts +22 -0
- package/lib/components/rate-limiting/usage-stats/use-usage-stats.d.ts.map +1 -0
- package/lib/components/rate-limiting/usage-stats/use-usage-stats.js +58 -0
- package/lib/components/rate-limiting/usage-stats/use-usage-stats.js.map +1 -0
- package/lib/components/scan-admin/common/conditional-tooltip.js +4 -16
- package/lib/components/scan-admin/common/conditional-tooltip.js.map +1 -1
- package/lib/components/scan-admin/common/file-table.js +24 -13
- package/lib/components/scan-admin/common/file-table.js.map +1 -1
- package/lib/components/scan-admin/dialogs/quarantine-dialog.js +4 -8
- package/lib/components/scan-admin/dialogs/quarantine-dialog.js.map +1 -1
- package/lib/components/scan-admin/scan-card/scan-card-content.js +2 -2
- package/lib/components/scan-admin/scan-card/scan-card-content.js.map +1 -1
- package/lib/components/scan-admin/scan-card/scan-card-expand-strip-badges.js +21 -16
- package/lib/components/scan-admin/scan-card/scan-card-expand-strip-badges.js.map +1 -1
- package/lib/components/scan-admin/scan-card/scan-card-expanded-content.js +1 -2
- package/lib/components/scan-admin/scan-card/scan-card-expanded-content.js.map +1 -1
- package/lib/components/scan-admin/scan-card/scan-card-header.js +10 -5
- package/lib/components/scan-admin/scan-card/scan-card-header.js.map +1 -1
- package/lib/components/scan-admin/scan-card/utils.js +1 -2
- package/lib/components/scan-admin/scan-card/utils.js.map +1 -1
- package/lib/components/scan-admin/tab-contents/quarantined-tab-content.js +4 -6
- package/lib/components/scan-admin/tab-contents/quarantined-tab-content.js.map +1 -1
- package/lib/components/sidepanel/drawer-header.d.ts +14 -0
- package/lib/components/sidepanel/drawer-header.d.ts.map +1 -0
- package/lib/components/sidepanel/drawer-header.js +22 -0
- package/lib/components/sidepanel/drawer-header.js.map +1 -0
- package/lib/components/sidepanel/navigation-item.d.ts.map +1 -1
- package/lib/components/sidepanel/navigation-item.js +3 -3
- package/lib/components/sidepanel/navigation-item.js.map +1 -1
- package/lib/components/sidepanel/sidepanel.d.ts +7 -1
- package/lib/components/sidepanel/sidepanel.d.ts.map +1 -1
- package/lib/components/sidepanel/sidepanel.js +12 -13
- package/lib/components/sidepanel/sidepanel.js.map +1 -1
- package/lib/components/text-divider.js +1 -2
- package/lib/components/text-divider.js.map +1 -1
- package/lib/components/timestamp.js +1 -2
- package/lib/components/timestamp.js.map +1 -1
- package/lib/context/scan-admin/scan-api-actions.js +7 -16
- package/lib/context/scan-admin/scan-api-actions.js.map +1 -1
- package/lib/context/scan-admin/scan-api-effects.js +77 -93
- package/lib/context/scan-admin/scan-api-effects.js.map +1 -1
- package/lib/context/scan-admin/scan-context.d.ts.map +1 -1
- package/lib/context/scan-admin/scan-context.js +1 -0
- package/lib/context/scan-admin/scan-context.js.map +1 -1
- package/lib/context/scan-admin/scan-reducer.js +134 -53
- package/lib/context/scan-admin/scan-reducer.js.map +1 -1
- package/lib/default/default-app.d.ts +1 -1
- package/lib/default/default-app.d.ts.map +1 -1
- package/lib/default/default-app.js +11 -22
- package/lib/default/default-app.js.map +1 -1
- package/lib/default/menu-content.d.ts.map +1 -1
- package/lib/default/menu-content.js +7 -3
- package/lib/default/menu-content.js.map +1 -1
- package/lib/default/page-settings.js +13 -18
- package/lib/default/page-settings.js.map +1 -1
- package/lib/extension-registry-service.d.ts +11 -1
- package/lib/extension-registry-service.d.ts.map +1 -1
- package/lib/extension-registry-service.js +618 -629
- package/lib/extension-registry-service.js.map +1 -1
- package/lib/extension-registry-types.d.ts +7 -0
- package/lib/extension-registry-types.d.ts.map +1 -1
- package/lib/hooks/scan-admin/use-auto-rejected-tab.js +5 -7
- package/lib/hooks/scan-admin/use-auto-rejected-tab.js.map +1 -1
- package/lib/hooks/scan-admin/use-quarantined-tab.js +5 -7
- package/lib/hooks/scan-admin/use-quarantined-tab.js.map +1 -1
- package/lib/main.d.ts.map +1 -1
- package/lib/main.js +8 -16
- package/lib/main.js.map +1 -1
- package/lib/other-pages.d.ts +12 -0
- package/lib/other-pages.d.ts.map +1 -1
- package/lib/other-pages.js +25 -12
- package/lib/other-pages.js.map +1 -1
- package/lib/pages/admin-dashboard/admin-dashboard.d.ts +0 -12
- package/lib/pages/admin-dashboard/admin-dashboard.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/admin-dashboard.js +136 -49
- package/lib/pages/admin-dashboard/admin-dashboard.js.map +1 -1
- package/lib/pages/admin-dashboard/admin-routes.d.ts +25 -0
- package/lib/pages/admin-dashboard/admin-routes.d.ts.map +1 -0
- package/lib/pages/admin-dashboard/admin-routes.js +27 -0
- package/lib/pages/admin-dashboard/admin-routes.js.map +1 -0
- package/lib/pages/admin-dashboard/components/data-grid-filter-operators.d.ts +1 -9
- package/lib/pages/admin-dashboard/components/data-grid-filter-operators.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/components/data-grid-filter-operators.js +17 -15
- package/lib/pages/admin-dashboard/components/data-grid-filter-operators.js.map +1 -1
- package/lib/pages/admin-dashboard/components/data-grid-filter.d.ts +22 -0
- package/lib/pages/admin-dashboard/components/data-grid-filter.d.ts.map +1 -0
- package/lib/pages/admin-dashboard/components/data-grid-filter.js +13 -0
- package/lib/pages/admin-dashboard/components/data-grid-filter.js.map +1 -0
- package/lib/pages/admin-dashboard/components/index.d.ts +2 -1
- package/lib/pages/admin-dashboard/components/index.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/components/index.js +2 -1
- package/lib/pages/admin-dashboard/components/index.js.map +1 -1
- package/lib/pages/admin-dashboard/{usage-stats/usage-stats-utils.d.ts → customers/customer-details.d.ts} +3 -2
- package/lib/pages/admin-dashboard/customers/customer-details.d.ts.map +1 -0
- package/lib/pages/admin-dashboard/customers/customer-details.js +77 -0
- package/lib/pages/admin-dashboard/customers/customer-details.js.map +1 -0
- package/lib/pages/admin-dashboard/customers/customer-form-dialog.d.ts +1 -1
- package/lib/pages/admin-dashboard/customers/customer-form-dialog.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/customers/customer-form-dialog.js +33 -34
- package/lib/pages/admin-dashboard/customers/customer-form-dialog.js.map +1 -1
- package/lib/pages/admin-dashboard/customers/customer-member-list.d.ts +19 -0
- package/lib/pages/admin-dashboard/customers/customer-member-list.d.ts.map +1 -0
- package/lib/pages/admin-dashboard/customers/customer-member-list.js +88 -0
- package/lib/pages/admin-dashboard/customers/customer-member-list.js.map +1 -0
- package/lib/pages/admin-dashboard/customers/customers.d.ts +1 -1
- package/lib/pages/admin-dashboard/customers/customers.js +20 -29
- package/lib/pages/admin-dashboard/customers/customers.js.map +1 -1
- package/lib/pages/admin-dashboard/customers/delete-customer-dialog.js +4 -14
- package/lib/pages/admin-dashboard/customers/delete-customer-dialog.js.map +1 -1
- package/lib/pages/admin-dashboard/extension-admin.js +7 -16
- package/lib/pages/admin-dashboard/extension-admin.js.map +1 -1
- package/lib/pages/admin-dashboard/extension-remove-dialog.js +3 -12
- package/lib/pages/admin-dashboard/extension-remove-dialog.js.map +1 -1
- package/lib/pages/admin-dashboard/extension-version-container.js +3 -5
- package/lib/pages/admin-dashboard/extension-version-container.js.map +1 -1
- package/lib/pages/admin-dashboard/logs/logs.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/logs/logs.js +6 -24
- package/lib/pages/admin-dashboard/logs/logs.js.map +1 -1
- package/lib/pages/admin-dashboard/namespace-admin.js +7 -16
- package/lib/pages/admin-dashboard/namespace-admin.js.map +1 -1
- package/lib/pages/admin-dashboard/namespace-change-dialog.js +3 -12
- package/lib/pages/admin-dashboard/namespace-change-dialog.js.map +1 -1
- package/lib/pages/admin-dashboard/namespace-input.js +1 -1
- package/lib/pages/admin-dashboard/namespace-input.js.map +1 -1
- package/lib/pages/admin-dashboard/publisher-admin.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/publisher-admin.js +28 -22
- package/lib/pages/admin-dashboard/publisher-admin.js.map +1 -1
- package/lib/pages/admin-dashboard/publisher-revoke-dialog.js +5 -15
- package/lib/pages/admin-dashboard/publisher-revoke-dialog.js.map +1 -1
- package/lib/pages/admin-dashboard/publisher-revoke-tokens-button.js +3 -12
- package/lib/pages/admin-dashboard/publisher-revoke-tokens-button.js.map +1 -1
- package/lib/pages/admin-dashboard/tiers/delete-tier-dialog.js +4 -13
- package/lib/pages/admin-dashboard/tiers/delete-tier-dialog.js.map +1 -1
- package/lib/pages/admin-dashboard/tiers/tier-form-dialog.js +34 -23
- package/lib/pages/admin-dashboard/tiers/tier-form-dialog.js.map +1 -1
- package/lib/pages/admin-dashboard/tiers/tiers.js +12 -21
- package/lib/pages/admin-dashboard/tiers/tiers.js.map +1 -1
- package/lib/pages/admin-dashboard/usage-stats/usage-stats-search.js +3 -14
- package/lib/pages/admin-dashboard/usage-stats/usage-stats-search.js.map +1 -1
- package/lib/pages/admin-dashboard/usage-stats/usage-stats.d.ts.map +1 -1
- package/lib/pages/admin-dashboard/usage-stats/usage-stats.js +11 -45
- package/lib/pages/admin-dashboard/usage-stats/usage-stats.js.map +1 -1
- package/lib/pages/admin-dashboard/usage-stats/use-usage-stats.d.ts +22 -0
- package/lib/pages/admin-dashboard/usage-stats/use-usage-stats.d.ts.map +1 -0
- package/lib/pages/admin-dashboard/usage-stats/use-usage-stats.js +58 -0
- package/lib/pages/admin-dashboard/usage-stats/use-usage-stats.js.map +1 -0
- package/lib/pages/admin-dashboard/welcome.js +1 -1
- package/lib/pages/admin-dashboard/welcome.js.map +1 -1
- package/lib/pages/extension-detail/extension-detail-changes.js +3 -12
- package/lib/pages/extension-detail/extension-detail-changes.js.map +1 -1
- package/lib/pages/extension-detail/extension-detail-overview.js +7 -17
- package/lib/pages/extension-detail/extension-detail-overview.js.map +1 -1
- package/lib/pages/extension-detail/extension-detail-reviews.js +12 -24
- package/lib/pages/extension-detail/extension-detail-reviews.js.map +1 -1
- package/lib/pages/extension-detail/extension-detail-routes.d.ts +32 -0
- package/lib/pages/extension-detail/extension-detail-routes.d.ts.map +1 -0
- package/lib/pages/extension-detail/extension-detail-routes.js +35 -0
- package/lib/pages/extension-detail/extension-detail-routes.js.map +1 -0
- package/lib/pages/extension-detail/extension-detail.d.ts +0 -19
- package/lib/pages/extension-detail/extension-detail.d.ts.map +1 -1
- package/lib/pages/extension-detail/extension-detail.js +28 -50
- package/lib/pages/extension-detail/extension-detail.js.map +1 -1
- package/lib/pages/extension-detail/extension-rating-stars.js +1 -2
- package/lib/pages/extension-detail/extension-rating-stars.js.map +1 -1
- package/lib/pages/extension-detail/extension-review-dialog.d.ts.map +1 -1
- package/lib/pages/extension-detail/extension-review-dialog.js +6 -25
- package/lib/pages/extension-detail/extension-review-dialog.js.map +1 -1
- package/lib/pages/extension-list/extension-list-container.d.ts +0 -3
- package/lib/pages/extension-list/extension-list-container.d.ts.map +1 -1
- package/lib/pages/extension-list/extension-list-container.js +5 -10
- package/lib/pages/extension-list/extension-list-container.js.map +1 -1
- package/lib/pages/extension-list/extension-list-header.js +3 -6
- package/lib/pages/extension-list/extension-list-header.js.map +1 -1
- package/lib/pages/extension-list/extension-list-item.js +7 -17
- package/lib/pages/extension-list/extension-list-item.js.map +1 -1
- package/lib/pages/extension-list/extension-list-routes.d.ts +16 -0
- package/lib/pages/extension-list/extension-list-routes.d.ts.map +1 -0
- package/lib/pages/extension-list/extension-list-routes.js +18 -0
- package/lib/pages/extension-list/extension-list-routes.js.map +1 -0
- package/lib/pages/extension-list/extension-list-searchfield.js +4 -7
- package/lib/pages/extension-list/extension-list-searchfield.js.map +1 -1
- package/lib/pages/extension-list/extension-list.js +8 -19
- package/lib/pages/extension-list/extension-list.js.map +1 -1
- package/lib/pages/namespace-detail/namespace-detail-routes.d.ts +20 -0
- package/lib/pages/namespace-detail/namespace-detail-routes.d.ts.map +1 -0
- package/lib/pages/namespace-detail/namespace-detail-routes.js +23 -0
- package/lib/pages/namespace-detail/namespace-detail-routes.js.map +1 -0
- package/lib/pages/namespace-detail/namespace-detail.d.ts +0 -7
- package/lib/pages/namespace-detail/namespace-detail.d.ts.map +1 -1
- package/lib/pages/namespace-detail/namespace-detail.js +4 -24
- package/lib/pages/namespace-detail/namespace-detail.js.map +1 -1
- package/lib/pages/user/add-namespace-member-dialog.d.ts.map +1 -1
- package/lib/pages/user/add-namespace-member-dialog.js +8 -67
- package/lib/pages/user/add-namespace-member-dialog.js.map +1 -1
- package/lib/pages/user/add-user-dialog.d.ts +25 -0
- package/lib/pages/user/add-user-dialog.d.ts.map +1 -0
- package/lib/pages/user/add-user-dialog.js +66 -0
- package/lib/pages/user/add-user-dialog.js.map +1 -0
- package/lib/pages/user/avatar.js +3 -3
- package/lib/pages/user/avatar.js.map +1 -1
- package/lib/pages/user/create-namespace-dialog.js +3 -12
- package/lib/pages/user/create-namespace-dialog.js.map +1 -1
- package/lib/pages/user/generate-token-dialog.js +3 -12
- package/lib/pages/user/generate-token-dialog.js.map +1 -1
- package/lib/pages/user/logout.js +3 -12
- package/lib/pages/user/logout.js.map +1 -1
- package/lib/pages/user/publish-extension-dialog.js +12 -21
- package/lib/pages/user/publish-extension-dialog.js.map +1 -1
- package/lib/pages/user/user-namespace-details.js +29 -42
- package/lib/pages/user/user-namespace-details.js.map +1 -1
- package/lib/pages/user/user-namespace-extension-list-item.js +6 -8
- package/lib/pages/user/user-namespace-extension-list-item.js.map +1 -1
- package/lib/pages/user/user-namespace-extension-list.js +6 -15
- package/lib/pages/user/user-namespace-extension-list.js.map +1 -1
- package/lib/pages/user/user-namespace-member-component.js +1 -1
- package/lib/pages/user/user-namespace-member-component.js.map +1 -1
- package/lib/pages/user/user-namespace-member-list.js +9 -18
- package/lib/pages/user/user-namespace-member-list.js.map +1 -1
- package/lib/pages/user/user-publisher-agreement.js +8 -18
- package/lib/pages/user/user-publisher-agreement.js.map +1 -1
- package/lib/pages/user/user-setting-tabs.d.ts.map +1 -1
- package/lib/pages/user/user-setting-tabs.js +2 -2
- package/lib/pages/user/user-setting-tabs.js.map +1 -1
- package/lib/pages/user/user-settings-customer-detail.d.ts +19 -0
- package/lib/pages/user/user-settings-customer-detail.d.ts.map +1 -0
- package/lib/pages/user/user-settings-customer-detail.js +9 -0
- package/lib/pages/user/user-settings-customer-detail.js.map +1 -0
- package/lib/pages/user/user-settings-customers.d.ts +15 -0
- package/lib/pages/user/user-settings-customers.d.ts.map +1 -0
- package/lib/pages/user/user-settings-customers.js +66 -0
- package/lib/pages/user/user-settings-customers.js.map +1 -0
- package/lib/pages/user/user-settings-delete-extension.js +8 -17
- package/lib/pages/user/user-settings-delete-extension.js.map +1 -1
- package/lib/pages/user/user-settings-extensions.js +3 -12
- package/lib/pages/user/user-settings-extensions.js.map +1 -1
- package/lib/pages/user/user-settings-namespace-detail.d.ts.map +1 -1
- package/lib/pages/user/user-settings-namespace-detail.js +4 -12
- package/lib/pages/user/user-settings-namespace-detail.js.map +1 -1
- package/lib/pages/user/user-settings-namespaces.js +6 -15
- package/lib/pages/user/user-settings-namespaces.js.map +1 -1
- package/lib/pages/user/user-settings-profile.js +1 -2
- package/lib/pages/user/user-settings-profile.js.map +1 -1
- package/lib/pages/user/user-settings-routes.d.ts +23 -0
- package/lib/pages/user/user-settings-routes.d.ts.map +1 -0
- package/lib/pages/user/user-settings-routes.js +25 -0
- package/lib/pages/user/user-settings-routes.js.map +1 -0
- package/lib/pages/user/user-settings-tokens.d.ts +0 -7
- package/lib/pages/user/user-settings-tokens.d.ts.map +1 -1
- package/lib/pages/user/user-settings-tokens.js +13 -23
- package/lib/pages/user/user-settings-tokens.js.map +1 -1
- package/lib/pages/user/user-settings.d.ts +0 -9
- package/lib/pages/user/user-settings.d.ts.map +1 -1
- package/lib/pages/user/user-settings.js +4 -12
- package/lib/pages/user/user-settings.js.map +1 -1
- package/lib/server-request.js +64 -76
- package/lib/server-request.js.map +1 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +3 -4
- package/lib/utils.js.map +1 -1
- package/package.json +4 -2
- package/src/components/rate-limiting/customer/general-details.tsx +106 -0
- package/src/components/rate-limiting/customer/index.ts +18 -0
- package/src/components/rate-limiting/customer/usage-stats.tsx +50 -0
- package/src/{pages/admin-dashboard → components/rate-limiting}/usage-stats/usage-stats-chart.tsx +46 -26
- package/{lib/pages/admin-dashboard/usage-stats/usage-stats-utils.js → src/components/rate-limiting/usage-stats/usage-stats-utils.ts} +4 -2
- package/src/components/rate-limiting/usage-stats/use-usage-stats.ts +70 -0
- package/src/components/scan-admin/scan-card/scan-card-header.tsx +2 -2
- package/src/components/sidepanel/drawer-header.tsx +23 -0
- package/src/components/sidepanel/navigation-item.tsx +3 -2
- package/src/components/sidepanel/sidepanel.tsx +29 -17
- package/src/context/scan-admin/scan-context.tsx +1 -0
- package/src/default/default-app.tsx +1 -1
- package/src/default/menu-content.tsx +6 -2
- package/src/default/page-settings.tsx +1 -1
- package/src/extension-registry-service.ts +105 -26
- package/src/extension-registry-types.ts +9 -0
- package/src/main.tsx +2 -1
- package/src/other-pages.tsx +21 -4
- package/src/pages/admin-dashboard/admin-dashboard.tsx +260 -83
- package/src/pages/admin-dashboard/admin-routes.ts +27 -0
- package/src/pages/admin-dashboard/components/data-grid-filter-operators.tsx +1 -31
- package/src/pages/admin-dashboard/components/data-grid-filter.tsx +45 -0
- package/src/pages/admin-dashboard/components/index.ts +1 -1
- package/src/pages/admin-dashboard/customers/customer-details.tsx +129 -0
- package/src/pages/admin-dashboard/customers/customer-form-dialog.tsx +3 -4
- package/src/pages/admin-dashboard/customers/customer-member-list.tsx +174 -0
- package/src/pages/admin-dashboard/customers/customers.tsx +8 -8
- package/src/pages/admin-dashboard/logs/logs.tsx +1 -10
- package/src/pages/admin-dashboard/publisher-admin.tsx +29 -11
- package/src/pages/admin-dashboard/usage-stats/usage-stats.tsx +10 -39
- package/src/pages/admin-dashboard/usage-stats/use-usage-stats.ts +70 -0
- package/src/pages/admin-dashboard/welcome.tsx +1 -1
- package/src/pages/extension-detail/extension-detail-overview.tsx +3 -3
- package/src/pages/extension-detail/extension-detail-routes.ts +35 -0
- package/src/pages/extension-detail/extension-detail.tsx +3 -23
- package/src/pages/extension-detail/extension-review-dialog.tsx +2 -12
- package/src/pages/extension-list/extension-list-container.tsx +1 -5
- package/src/pages/extension-list/extension-list-item.tsx +1 -1
- package/src/pages/extension-list/extension-list-routes.ts +18 -0
- package/src/pages/namespace-detail/namespace-detail-routes.ts +23 -0
- package/src/pages/namespace-detail/namespace-detail.tsx +0 -10
- package/src/pages/user/add-namespace-member-dialog.tsx +17 -116
- package/src/pages/user/add-user-dialog.tsx +141 -0
- package/src/pages/user/avatar.tsx +2 -2
- package/src/pages/user/user-namespace-extension-list-item.tsx +2 -2
- package/src/pages/user/user-setting-tabs.tsx +2 -1
- package/src/pages/user/user-settings-customer-detail.tsx +39 -0
- package/src/pages/user/user-settings-customers.tsx +120 -0
- package/src/pages/user/user-settings-delete-extension.tsx +1 -1
- package/src/pages/user/user-settings-namespace-detail.tsx +3 -1
- package/src/pages/user/user-settings-routes.ts +25 -0
- package/src/pages/user/user-settings-tokens.tsx +1 -8
- package/src/pages/user/user-settings.tsx +4 -12
- package/src/utils.ts +2 -1
- package/lib/pages/admin-dashboard/usage-stats/usage-stats-chart.d.ts.map +0 -1
- package/lib/pages/admin-dashboard/usage-stats/usage-stats-chart.js.map +0 -1
- package/lib/pages/admin-dashboard/usage-stats/usage-stats-utils.d.ts.map +0 -1
- package/lib/pages/admin-dashboard/usage-stats/usage-stats-utils.js.map +0 -1
|
@@ -9,45 +9,48 @@
|
|
|
9
9
|
********************************************************************************/
|
|
10
10
|
|
|
11
11
|
import { FunctionComponent, ReactNode, useContext, useState } from 'react';
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
import {
|
|
13
|
+
Box,
|
|
14
|
+
Container,
|
|
15
|
+
CssBaseline,
|
|
16
|
+
Typography,
|
|
17
|
+
IconButton,
|
|
18
|
+
Breadcrumbs,
|
|
19
|
+
LinkProps,
|
|
20
|
+
Link,
|
|
21
|
+
Toolbar
|
|
22
|
+
} from '@mui/material';
|
|
23
|
+
import MuiAppBar, { AppBarProps as MuiAppBarProps } from '@mui/material/AppBar';
|
|
24
|
+
import { styled } from "@mui/material/styles";
|
|
25
|
+
import { Link as RouterLink, Route, Routes, useNavigate, useLocation } from 'react-router-dom';
|
|
26
|
+
import AccountBoxIcon from '@mui/icons-material/AccountBox';
|
|
16
27
|
import AssignmentIndIcon from '@mui/icons-material/AssignmentInd';
|
|
28
|
+
import BarChartIcon from '@mui/icons-material/BarChart';
|
|
17
29
|
import ExtensionSharpIcon from '@mui/icons-material/ExtensionSharp';
|
|
18
|
-
import { Route, Routes, useNavigate, useLocation } from 'react-router-dom';
|
|
19
|
-
import { NamespaceAdmin } from './namespace-admin';
|
|
20
|
-
import { ExtensionAdmin } from './extension-admin';
|
|
21
|
-
import { MainContext } from '../../context';
|
|
22
30
|
import HighlightOffIcon from '@mui/icons-material/HighlightOff';
|
|
23
|
-
import
|
|
24
|
-
import
|
|
25
|
-
import PersonIcon from '@mui/icons-material/Person';
|
|
31
|
+
import HistoryIcon from '@mui/icons-material/History';
|
|
32
|
+
import MenuIcon from '@mui/icons-material/Menu';
|
|
26
33
|
import PeopleIcon from '@mui/icons-material/People';
|
|
27
|
-
import
|
|
34
|
+
import PersonIcon from '@mui/icons-material/Person';
|
|
28
35
|
import SecurityIcon from '@mui/icons-material/Security';
|
|
36
|
+
import SpeedIcon from '@mui/icons-material/Speed';
|
|
29
37
|
import StarIcon from '@mui/icons-material/Star';
|
|
30
|
-
import
|
|
31
|
-
import HistoryIcon from '@mui/icons-material/History';
|
|
32
|
-
import { Tiers } from './tiers/tiers';
|
|
38
|
+
import { CustomerDetails } from './customers/customer-details';
|
|
33
39
|
import { Customers } from './customers/customers';
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
40
|
+
import { DrawerHeader } from '../../components/sidepanel/drawer-header';
|
|
41
|
+
import { Sidepanel } from "../../components/sidepanel/sidepanel";
|
|
42
|
+
import { ExtensionAdmin } from './extension-admin';
|
|
36
43
|
import { LoginComponent } from "../../default/login";
|
|
37
|
-
import
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
export const CUSTOMERS = createRoute([ROOT, 'customers']);
|
|
48
|
-
export const USAGE_STATS = createRoute([ROOT, 'usage']);
|
|
49
|
-
export const LOGS = createRoute([ROOT, 'logs']);
|
|
50
|
-
}
|
|
44
|
+
import { Logs } from './logs/logs';
|
|
45
|
+
import { MainContext } from '../../context';
|
|
46
|
+
import { NamespaceAdmin } from './namespace-admin';
|
|
47
|
+
import { NavigationItem } from '../../components/sidepanel/navigation-item';
|
|
48
|
+
import { PublisherAdmin } from './publisher-admin';
|
|
49
|
+
import { ScanAdmin } from './scan-admin';
|
|
50
|
+
import { Tiers } from './tiers/tiers';
|
|
51
|
+
import { UsageStatsView } from './usage-stats/usage-stats';
|
|
52
|
+
import { Welcome } from './welcome';
|
|
53
|
+
import { AdminDashboardRoutes } from "./admin-routes";
|
|
51
54
|
|
|
52
55
|
const Message: FunctionComponent<{message: string}> = ({ message }) => {
|
|
53
56
|
return (<Box sx={{
|
|
@@ -60,68 +63,242 @@ const Message: FunctionComponent<{message: string}> = ({ message }) => {
|
|
|
60
63
|
</Box>);
|
|
61
64
|
};
|
|
62
65
|
|
|
66
|
+
interface RouteEntry {
|
|
67
|
+
path: string;
|
|
68
|
+
name: string;
|
|
69
|
+
icon: ReactNode;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
interface NavGroup {
|
|
73
|
+
name: string;
|
|
74
|
+
icon: ReactNode;
|
|
75
|
+
children: RouteEntry[];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
type NavEntry = RouteEntry | NavGroup;
|
|
79
|
+
|
|
80
|
+
const isNavGroup = (entry: NavEntry): entry is NavGroup => 'children' in entry;
|
|
81
|
+
|
|
82
|
+
const navConfig: NavEntry[] = [
|
|
83
|
+
{ path: AdminDashboardRoutes.NAMESPACE_ADMIN, name: 'Namespaces', icon: <AssignmentIndIcon /> },
|
|
84
|
+
{ path: AdminDashboardRoutes.EXTENSION_ADMIN, name: 'Extensions', icon: <ExtensionSharpIcon /> },
|
|
85
|
+
{ path: AdminDashboardRoutes.PUBLISHER_ADMIN, name: 'Publisher', icon: <PersonIcon /> },
|
|
86
|
+
{ path: AdminDashboardRoutes.SCANS_ADMIN, name: 'Scans', icon: <SecurityIcon /> },
|
|
87
|
+
{
|
|
88
|
+
name: 'Rate Limiting',
|
|
89
|
+
icon: <SpeedIcon />,
|
|
90
|
+
children: [
|
|
91
|
+
{ path: AdminDashboardRoutes.TIERS, name: 'Tiers', icon: <StarIcon /> },
|
|
92
|
+
{ path: AdminDashboardRoutes.CUSTOMERS, name: 'Customers', icon: <PeopleIcon /> },
|
|
93
|
+
{ path: AdminDashboardRoutes.USAGE_STATS, name: 'Usage Stats', icon: <BarChartIcon /> },
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
{ path: AdminDashboardRoutes.LOGS, name: 'Logs', icon: <HistoryIcon /> },
|
|
97
|
+
];
|
|
98
|
+
|
|
99
|
+
// Flat name lookup for breadcrumbs
|
|
100
|
+
const routeNames: { [key: string]: string } = {
|
|
101
|
+
[AdminDashboardRoutes.MAIN]: 'Admin Dashboard',
|
|
102
|
+
...navConfig.reduce<{ [key: string]: string }>((acc, entry) => {
|
|
103
|
+
if (isNavGroup(entry)) {
|
|
104
|
+
entry.children.forEach(child => {
|
|
105
|
+
acc[child.path] = child.name;
|
|
106
|
+
});
|
|
107
|
+
} else {
|
|
108
|
+
acc[entry.path] = entry.name;
|
|
109
|
+
}
|
|
110
|
+
return acc;
|
|
111
|
+
}, {}),
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const drawerWidth = 240;
|
|
115
|
+
|
|
116
|
+
interface AppBarProps extends MuiAppBarProps {
|
|
117
|
+
open?: boolean;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const AppBar = styled(MuiAppBar, {
|
|
121
|
+
shouldForwardProp: (prop) => prop !== 'open',
|
|
122
|
+
})<AppBarProps>(({ theme }) => ({
|
|
123
|
+
transition: theme.transitions.create(['margin', 'width'], {
|
|
124
|
+
easing: theme.transitions.easing.sharp,
|
|
125
|
+
duration: theme.transitions.duration.leavingScreen,
|
|
126
|
+
}),
|
|
127
|
+
variants: [
|
|
128
|
+
{
|
|
129
|
+
props: ({ open }) => open,
|
|
130
|
+
style: {
|
|
131
|
+
width: `calc(100% - ${drawerWidth}px)`,
|
|
132
|
+
marginLeft: `${drawerWidth}px`,
|
|
133
|
+
transition: theme.transitions.create(['margin', 'width'], {
|
|
134
|
+
easing: theme.transitions.easing.easeOut,
|
|
135
|
+
duration: theme.transitions.duration.enteringScreen,
|
|
136
|
+
}),
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
}));
|
|
141
|
+
|
|
142
|
+
interface LinkRouterProps extends LinkProps {
|
|
143
|
+
to: string;
|
|
144
|
+
replace?: boolean;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const LinkRouter = (props: LinkRouterProps) => (
|
|
148
|
+
<Link {...props} component={RouterLink as any} />
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
const BreadcrumbsComponent = () => {
|
|
152
|
+
const { pathname } = useLocation();
|
|
153
|
+
|
|
154
|
+
const pathnames = pathname.split("/").filter((segment) => segment);
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<Breadcrumbs aria-label='breadcrumb' sx={{ pt: 2, pb: 2, px: 4 }} >
|
|
158
|
+
<LinkRouter underline='hover' color='inherit' to='/'>
|
|
159
|
+
Home
|
|
160
|
+
</LinkRouter>
|
|
161
|
+
{pathnames.map((value, index) => {
|
|
162
|
+
const last = index === pathnames.length - 1;
|
|
163
|
+
const to = `/${pathnames.slice(0, index + 1).join("/")}`;
|
|
164
|
+
|
|
165
|
+
return last ? (
|
|
166
|
+
<Typography color='text.primary' key={to}>
|
|
167
|
+
{routeNames[to] ?? value}
|
|
168
|
+
</Typography>
|
|
169
|
+
) : (
|
|
170
|
+
<LinkRouter underline='hover' color='inherit' to={to} key={to}>
|
|
171
|
+
{routeNames[to]}
|
|
172
|
+
</LinkRouter>
|
|
173
|
+
);
|
|
174
|
+
})}
|
|
175
|
+
</Breadcrumbs>
|
|
176
|
+
);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const Main = styled('main', { shouldForwardProp: (prop) => prop !== 'open' })<{
|
|
180
|
+
open?: boolean;
|
|
181
|
+
}>(({ theme }) => ({
|
|
182
|
+
flexGrow: 1,
|
|
183
|
+
padding: theme.spacing(3),
|
|
184
|
+
transition: theme.transitions.create('margin', {
|
|
185
|
+
easing: theme.transitions.easing.sharp,
|
|
186
|
+
duration: theme.transitions.duration.leavingScreen,
|
|
187
|
+
}),
|
|
188
|
+
marginLeft: `-${drawerWidth}px`,
|
|
189
|
+
variants: [
|
|
190
|
+
{
|
|
191
|
+
props: ({ open }) => open,
|
|
192
|
+
style: {
|
|
193
|
+
transition: theme.transitions.create('margin', {
|
|
194
|
+
easing: theme.transitions.easing.easeOut,
|
|
195
|
+
duration: theme.transitions.duration.enteringScreen,
|
|
196
|
+
}),
|
|
197
|
+
marginLeft: 0,
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
}));
|
|
202
|
+
|
|
63
203
|
export const AdminDashboard: FunctionComponent<AdminDashboardProps> = props => {
|
|
64
204
|
const { user, loginProviders } = useContext(MainContext);
|
|
205
|
+
const [drawerOpen, setDrawerOpen] = useState(true);
|
|
65
206
|
|
|
66
207
|
const navigate = useNavigate();
|
|
67
208
|
const toMainPage = () => navigate('/');
|
|
68
209
|
|
|
69
210
|
const [currentPage, setCurrentPage] = useState<string | undefined>(useLocation().pathname);
|
|
70
|
-
const handleOpenRoute = (route: string) =>
|
|
211
|
+
const handleOpenRoute = (route: string) => {
|
|
212
|
+
setCurrentPage(route);
|
|
213
|
+
};
|
|
71
214
|
|
|
72
215
|
let content: ReactNode = null;
|
|
73
216
|
if (user?.role === 'admin') {
|
|
74
|
-
content =
|
|
75
|
-
<
|
|
76
|
-
<
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
217
|
+
content =
|
|
218
|
+
<Box sx={{ display: 'flex', width: '100%' }}>
|
|
219
|
+
<CssBaseline />
|
|
220
|
+
<AppBar position='fixed' open={drawerOpen} color='default' enableColorOnDark elevation={0}>
|
|
221
|
+
<Toolbar>
|
|
222
|
+
<IconButton
|
|
223
|
+
aria-label='open drawer'
|
|
224
|
+
onClick={() => setDrawerOpen(true)}
|
|
225
|
+
edge='start'
|
|
226
|
+
sx={[{ mr: 2 }, drawerOpen && { display: 'none' }]}
|
|
227
|
+
>
|
|
228
|
+
<MenuIcon />
|
|
229
|
+
</IconButton>
|
|
230
|
+
<Box sx={{ display: 'flex', justifyContent: 'space-between', width: '100%' }}>
|
|
231
|
+
<BreadcrumbsComponent />
|
|
232
|
+
<IconButton onClick={toMainPage} sx={{ mt: 1, mr: 1 }}>
|
|
233
|
+
<HighlightOffIcon/>
|
|
234
|
+
</IconButton>
|
|
235
|
+
</Box>
|
|
236
|
+
</Toolbar>
|
|
237
|
+
</AppBar>
|
|
238
|
+
<Sidepanel width={drawerWidth} open={drawerOpen} handleDrawerClose={() => setDrawerOpen(false)} >
|
|
239
|
+
{navConfig.map((entry) => {
|
|
240
|
+
if (isNavGroup(entry)) {
|
|
241
|
+
return (
|
|
242
|
+
<NavigationItem
|
|
243
|
+
key={entry.name}
|
|
244
|
+
label={entry.name}
|
|
245
|
+
icon={entry.icon}
|
|
246
|
+
>
|
|
247
|
+
{entry.children.map((child) => (
|
|
248
|
+
<NavigationItem key={child.path} onOpenRoute={handleOpenRoute} active={currentPage?.startsWith(child.path)}
|
|
249
|
+
label={child.name} icon={child.icon} route={child.path}/>
|
|
250
|
+
))}
|
|
251
|
+
</NavigationItem>
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
return (
|
|
255
|
+
<NavigationItem key={entry.path} onOpenRoute={handleOpenRoute} active={currentPage?.startsWith(entry.path)}
|
|
256
|
+
label={entry.name} icon={entry.icon} route={entry.path}/>
|
|
257
|
+
);
|
|
258
|
+
})}
|
|
259
|
+
</Sidepanel>
|
|
260
|
+
<Main open={drawerOpen} >
|
|
261
|
+
<DrawerHeader />
|
|
262
|
+
<Box
|
|
263
|
+
overflow='auto'
|
|
264
|
+
flex={1}
|
|
265
|
+
sx={{
|
|
266
|
+
overflowY: 'scroll',
|
|
267
|
+
'&::-webkit-scrollbar': {
|
|
268
|
+
width: '12px',
|
|
269
|
+
},
|
|
270
|
+
'&::-webkit-scrollbar-track': {
|
|
271
|
+
backgroundColor: 'rgba(0, 0, 0, 0.2)',
|
|
272
|
+
},
|
|
273
|
+
'&::-webkit-scrollbar-thumb': {
|
|
274
|
+
backgroundColor: 'rgba(255, 255, 255, 0.2)',
|
|
275
|
+
borderRadius: '6px',
|
|
276
|
+
'&:hover': {
|
|
277
|
+
backgroundColor: 'rgba(255, 255, 255, 0.3)',
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
}}
|
|
281
|
+
>
|
|
282
|
+
<Container sx={{ pt: 2, pb: 4, px: 3 }} maxWidth='xl'>
|
|
283
|
+
<Routes>
|
|
284
|
+
<Route path='/namespaces' element={<NamespaceAdmin/>} />
|
|
285
|
+
<Route path='/extensions' element={<ExtensionAdmin/>} />
|
|
286
|
+
<Route path='/extensions/:namespace/:extension' element={<ExtensionAdmin/>} />
|
|
287
|
+
<Route path='/publisher' element={<PublisherAdmin/>} />
|
|
288
|
+
<Route path='/publisher/:publisher' element={<PublisherAdmin/>} />
|
|
289
|
+
<Route path='/scans' element={<ScanAdmin/>} />
|
|
290
|
+
<Route path='/tiers' element={<Tiers/>} />
|
|
291
|
+
<Route path='/customers' element={<Customers/>} />
|
|
292
|
+
<Route path='/customers/:customer' element={<CustomerDetails/>} />
|
|
293
|
+
<Route path='/usage' element={<UsageStatsView/>} />
|
|
294
|
+
<Route path='/usage/:customer' element={<UsageStatsView/>} />
|
|
295
|
+
<Route path='/logs' element={<Logs/>} />
|
|
296
|
+
<Route path='*' element={<Welcome/>} />
|
|
297
|
+
</Routes>
|
|
298
|
+
</Container>
|
|
299
|
+
</Box>
|
|
300
|
+
</Main>
|
|
301
|
+
</Box>;
|
|
125
302
|
} else if (user) {
|
|
126
303
|
content = <Message message='You are not authorized as administrator.'/>;
|
|
127
304
|
} else if (!props.userLoading && loginProviders) {
|
|
@@ -0,0 +1,27 @@
|
|
|
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 AdminDashboardRoutes {
|
|
17
|
+
export const ROOT = 'admin-dashboard';
|
|
18
|
+
export const MAIN = createRoute([ROOT]);
|
|
19
|
+
export const NAMESPACE_ADMIN = createRoute([ROOT, 'namespaces']);
|
|
20
|
+
export const EXTENSION_ADMIN = createRoute([ROOT, 'extensions']);
|
|
21
|
+
export const PUBLISHER_ADMIN = createRoute([ROOT, 'publisher']);
|
|
22
|
+
export const SCANS_ADMIN = createRoute([ROOT, 'scans']);
|
|
23
|
+
export const TIERS = createRoute([ROOT, 'tiers']);
|
|
24
|
+
export const CUSTOMERS = createRoute([ROOT, 'customers']);
|
|
25
|
+
export const USAGE_STATS = createRoute([ROOT, 'usage']);
|
|
26
|
+
export const LOGS = createRoute([ROOT, 'logs']);
|
|
27
|
+
}
|
|
@@ -11,39 +11,9 @@
|
|
|
11
11
|
* SPDX-License-Identifier: EPL-2.0
|
|
12
12
|
*****************************************************************************/
|
|
13
13
|
|
|
14
|
-
import
|
|
15
|
-
import { FC } from 'react';
|
|
16
|
-
import { Autocomplete, TextField } from '@mui/material';
|
|
14
|
+
import { MultiSelectFilterInput } from "./data-grid-filter";
|
|
17
15
|
import { GridFilterOperator, GridFilterInputValueProps } from '@mui/x-data-grid';
|
|
18
16
|
|
|
19
|
-
/**
|
|
20
|
-
* Custom multi-select filter input component for DataGrid columns.
|
|
21
|
-
* Renders an Autocomplete with multiple selection support.
|
|
22
|
-
*/
|
|
23
|
-
export const MultiSelectFilterInput: FC<GridFilterInputValueProps & { options: string[] }> = ({
|
|
24
|
-
item,
|
|
25
|
-
applyValue,
|
|
26
|
-
options
|
|
27
|
-
}) => {
|
|
28
|
-
const handleChange = (_event: SyntheticEvent, newValue: string[]) => {
|
|
29
|
-
applyValue({ ...item, value: newValue });
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<Autocomplete
|
|
34
|
-
multiple
|
|
35
|
-
size='small'
|
|
36
|
-
options={options}
|
|
37
|
-
value={(item.value as string[]) || []}
|
|
38
|
-
onChange={handleChange}
|
|
39
|
-
renderInput={(params) => (
|
|
40
|
-
<TextField {...params} variant='standard' placeholder='Filter...' />
|
|
41
|
-
)}
|
|
42
|
-
sx={{ minWidth: 150, mt: 'auto' }}
|
|
43
|
-
/>
|
|
44
|
-
);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
17
|
/**
|
|
48
18
|
* Creates filter operators for single-value columns with multi-select capability.
|
|
49
19
|
* Includes "is any of" and "is none of" operators.
|
|
@@ -0,0 +1,45 @@
|
|
|
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 type { SyntheticEvent } from "react";
|
|
15
|
+
import { FC } from 'react';
|
|
16
|
+
import { Autocomplete, TextField } from '@mui/material';
|
|
17
|
+
import { GridFilterInputValueProps } from '@mui/x-data-grid';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Custom multi-select filter input component for DataGrid columns.
|
|
21
|
+
* Renders an Autocomplete with multiple selection support.
|
|
22
|
+
*/
|
|
23
|
+
export const MultiSelectFilterInput: FC<GridFilterInputValueProps & { options: string[] }> = ({
|
|
24
|
+
item,
|
|
25
|
+
applyValue,
|
|
26
|
+
options
|
|
27
|
+
}) => {
|
|
28
|
+
const handleChange = (_event: SyntheticEvent, newValue: string[]) => {
|
|
29
|
+
applyValue({ ...item, value: newValue });
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<Autocomplete
|
|
34
|
+
multiple
|
|
35
|
+
size='small'
|
|
36
|
+
options={options}
|
|
37
|
+
value={(item.value as string[]) || []}
|
|
38
|
+
onChange={handleChange}
|
|
39
|
+
renderInput={(params) => (
|
|
40
|
+
<TextField {...params} variant='standard' placeholder='Filter...' />
|
|
41
|
+
)}
|
|
42
|
+
sx={{ minWidth: 150, mt: 'auto' }}
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
* SPDX-License-Identifier: EPL-2.0
|
|
12
12
|
*****************************************************************************/
|
|
13
13
|
|
|
14
|
+
export { MultiSelectFilterInput } from './data-grid-filter';
|
|
14
15
|
export {
|
|
15
|
-
MultiSelectFilterInput,
|
|
16
16
|
createMultiSelectFilterOperators,
|
|
17
17
|
createArrayContainsFilterOperators
|
|
18
18
|
} from './data-grid-filter-operators';
|
|
@@ -0,0 +1,129 @@
|
|
|
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, useContext, useState, useEffect, useRef, useCallback } from "react";
|
|
15
|
+
import {
|
|
16
|
+
Box,
|
|
17
|
+
Typography,
|
|
18
|
+
Button,
|
|
19
|
+
Alert,
|
|
20
|
+
LinearProgress
|
|
21
|
+
} from "@mui/material";
|
|
22
|
+
import EditIcon from '@mui/icons-material/Edit';
|
|
23
|
+
import { useParams } from 'react-router-dom';
|
|
24
|
+
import { MainContext } from '../../../context';
|
|
25
|
+
import type { Customer } from '../../../extension-registry-types';
|
|
26
|
+
import { handleError } from '../../../utils';
|
|
27
|
+
import { useAdminUsageStats } from '../usage-stats/use-usage-stats';
|
|
28
|
+
import { GeneralDetails, UsageStats } from '../../../components/rate-limiting/customer';
|
|
29
|
+
import { CustomerFormDialog } from './customer-form-dialog';
|
|
30
|
+
import { CustomerMemberList } from './customer-member-list';
|
|
31
|
+
|
|
32
|
+
const CustomerDetailsLoading: FC = () => (
|
|
33
|
+
<Box sx={{ p: 3 }}>
|
|
34
|
+
<LinearProgress color='secondary' sx={{ width: "100%" }} />
|
|
35
|
+
</Box>
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const CustomerDetailsError: FC<{ message: string }> = ({ message }) => (
|
|
39
|
+
<Box sx={{ p: 3 }}>
|
|
40
|
+
<Alert severity='error'>{message}</Alert>
|
|
41
|
+
</Box>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
export const CustomerDetails: FC = () => {
|
|
45
|
+
const { customer: customerName } = useParams<{ customer: string }>();
|
|
46
|
+
const abortController = useRef(new AbortController());
|
|
47
|
+
const { service } = useContext(MainContext);
|
|
48
|
+
|
|
49
|
+
const [customer, setCustomer] = useState<Customer | null>(null);
|
|
50
|
+
const [loading, setLoading] = useState(true);
|
|
51
|
+
const [error, setError] = useState<string | null>(null);
|
|
52
|
+
const [formDialogOpen, setFormDialogOpen] = useState(false);
|
|
53
|
+
|
|
54
|
+
const { usageStats, error: statsError, startDate, setStartDate } = useAdminUsageStats(customerName);
|
|
55
|
+
|
|
56
|
+
const loadCustomer = useCallback(async () => {
|
|
57
|
+
if (!customerName) return;
|
|
58
|
+
try {
|
|
59
|
+
setLoading(true);
|
|
60
|
+
setError(null);
|
|
61
|
+
const data = await service.admin.getCustomer(abortController.current, customerName);
|
|
62
|
+
setCustomer(data);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
if ((err as { status?: number })?.status === 404) {
|
|
65
|
+
setError(`Customer "${customerName}" not found.`);
|
|
66
|
+
} else {
|
|
67
|
+
setError(handleError(err as Error));
|
|
68
|
+
}
|
|
69
|
+
} finally {
|
|
70
|
+
setLoading(false);
|
|
71
|
+
}
|
|
72
|
+
}, [service, customerName]);
|
|
73
|
+
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
loadCustomer();
|
|
76
|
+
return () => abortController.current.abort();
|
|
77
|
+
}, [loadCustomer]);
|
|
78
|
+
|
|
79
|
+
const handleFormSubmit = async (updatedCustomer: Customer) => {
|
|
80
|
+
if (customer) {
|
|
81
|
+
await service.admin.updateCustomer(abortController.current, customer.name, updatedCustomer);
|
|
82
|
+
await loadCustomer();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
if (loading) {
|
|
87
|
+
return <CustomerDetailsLoading />;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (error || statsError) {
|
|
91
|
+
return <CustomerDetailsError message={error ?? statsError ?? ''} />;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (!customer) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<>
|
|
100
|
+
<Box sx={{ p: 2 }}>
|
|
101
|
+
<Box sx={{ display: 'flex', alignItems: 'center', mb: 3 }}>
|
|
102
|
+
<Typography variant='h4' component='h1'>
|
|
103
|
+
{customer.name}
|
|
104
|
+
</Typography>
|
|
105
|
+
</Box>
|
|
106
|
+
|
|
107
|
+
<GeneralDetails
|
|
108
|
+
customer={customer}
|
|
109
|
+
headerAction={
|
|
110
|
+
<Button size='small' startIcon={<EditIcon />} onClick={() => setFormDialogOpen(true)}>
|
|
111
|
+
Edit
|
|
112
|
+
</Button>
|
|
113
|
+
}
|
|
114
|
+
/>
|
|
115
|
+
<CustomerMemberList
|
|
116
|
+
customer={customer}
|
|
117
|
+
/>
|
|
118
|
+
<UsageStats usageStats={usageStats} customer={customer} startDate={startDate} onStartDateChange={setStartDate} />
|
|
119
|
+
</Box>
|
|
120
|
+
|
|
121
|
+
<CustomerFormDialog
|
|
122
|
+
open={formDialogOpen}
|
|
123
|
+
customer={customer}
|
|
124
|
+
onClose={() => setFormDialogOpen(false)}
|
|
125
|
+
onSubmit={handleFormSubmit}
|
|
126
|
+
/>
|
|
127
|
+
</>
|
|
128
|
+
);
|
|
129
|
+
};
|
|
@@ -31,9 +31,9 @@ import {
|
|
|
31
31
|
styled
|
|
32
32
|
} from '@mui/material';
|
|
33
33
|
import type { SelectChangeEvent } from '@mui/material';
|
|
34
|
-
import { type Customer, EnforcementState, type Tier } from
|
|
35
|
-
import { MainContext } from
|
|
36
|
-
import { handleError } from
|
|
34
|
+
import { type Customer, EnforcementState, type Tier } from '../../../extension-registry-types';
|
|
35
|
+
import { MainContext } from '../../../context';
|
|
36
|
+
import { handleError } from '../../../utils';
|
|
37
37
|
|
|
38
38
|
interface CustomerFormDialogProps {
|
|
39
39
|
open: boolean;
|
|
@@ -42,7 +42,6 @@ interface CustomerFormDialogProps {
|
|
|
42
42
|
onSubmit: (formData: Customer) => Promise<void>;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
|
|
46
45
|
const Code = styled('code')(({ theme }) => ({
|
|
47
46
|
fontFamily: 'source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace',
|
|
48
47
|
backgroundColor: theme.palette.action.hover, // Subtle gray background
|