feat: plugin extension slots for access, request interceptors, Users actions, and form fields
Four purely-additive seams that let build-time tooling extend host behaviour without forking files: * `src/access.extensions.ts` — identity `applyAccessExtensions` (mirrors `config/routes.extensions.ts`). `src/access.ts` runs the resolved predicate object through it. Adds two new predicates, `canSeeOrgAdmin` and `canManageCurrentOrg`, alongside the existing `canSeeAdmin`. Resources, Models children, Cluster Management, and Resources/Backends are retagged from `canSeeAdmin` to `canSeeOrgAdmin`. Users and Dashboard stay strict. * `src/request.extensions.ts` — identity-empty `extraRequestInterceptors`. `src/request-config.tsx` spreads it into the existing `requestInterceptors` list so extensions can inject context-aware headers without forking the request config. * Users page action column — renders `getGPUStackPlugin()?.components?.UserRowActions` next to the existing DropdownButtons inside a Space when a plugin component is registered. If absent, the cell renders exactly as before. * `src/components/plugin-extra-fields.tsx` — generic component-slot helper. Renders `pluginManager.components.<name>` if registered, forwarding a `context` payload. Used by create/edit forms to let plugins inject extra `Form.Item` fields. Mounted in the relevant create forms — API Keys, Cloud Credentials, Clusters, Model Routes, Model Providers, and Inference Backends — under the slot name `CreateOrgScopeField`. Resources whose org is implicit from a parent (Models / Workers / Benchmarks / Worker Pools / Model Files inherit from the chosen Cluster) deliberately don't mount the slot.
This commit is contained in:
+19
-20
@@ -104,9 +104,19 @@ const baseRoutes = [
|
||||
icon: 'icon-layers',
|
||||
selectedIcon: 'icon-layers-filled',
|
||||
defaultIcon: 'icon-layers',
|
||||
access: 'canSeeAdmin',
|
||||
access: 'canSeeOrgAdmin',
|
||||
component: './llmodels/catalog'
|
||||
},
|
||||
{
|
||||
name: 'userModels',
|
||||
path: '/models/user-models',
|
||||
key: 'userModels',
|
||||
icon: 'icon-models',
|
||||
selectedIcon: 'icon-models-filled',
|
||||
defaultIcon: 'icon-models',
|
||||
access: 'canSeeUser',
|
||||
component: './llmodels/user-models'
|
||||
},
|
||||
{
|
||||
name: 'deployment',
|
||||
path: '/models/deployments',
|
||||
@@ -114,7 +124,7 @@ const baseRoutes = [
|
||||
icon: 'icon-rocket-launch1',
|
||||
selectedIcon: 'icon-rocket-launch-fill',
|
||||
defaultIcon: 'icon-rocket-launch1',
|
||||
access: 'canSeeAdmin',
|
||||
access: 'canSeeOrgAdmin',
|
||||
component: './llmodels/index'
|
||||
},
|
||||
{
|
||||
@@ -124,7 +134,7 @@ const baseRoutes = [
|
||||
icon: 'icon-captive_portal',
|
||||
selectedIcon: 'icon-captive_portal',
|
||||
defaultIcon: 'icon-captive_portal',
|
||||
access: 'canSeeAdmin',
|
||||
access: 'canSeeOrgAdmin',
|
||||
component: './model-routes/index'
|
||||
},
|
||||
{
|
||||
@@ -143,20 +153,9 @@ const baseRoutes = [
|
||||
icon: 'icon-extension-outline',
|
||||
selectedIcon: 'icon-extension-filled',
|
||||
defaultIcon: 'icon-extension-outline',
|
||||
access: 'canSeeAdmin',
|
||||
access: 'canSeeOrgAdmin',
|
||||
component: './maas-provider/index'
|
||||
},
|
||||
|
||||
{
|
||||
name: 'userModels',
|
||||
path: '/models/user-models',
|
||||
key: 'userModels',
|
||||
icon: 'icon-models',
|
||||
selectedIcon: 'icon-models-filled',
|
||||
defaultIcon: 'icon-models',
|
||||
access: 'canSeeUser',
|
||||
component: './llmodels/user-models'
|
||||
},
|
||||
{
|
||||
name: 'benchmark',
|
||||
path: '/models/benchmark',
|
||||
@@ -164,7 +163,7 @@ const baseRoutes = [
|
||||
icon: 'icon-speed',
|
||||
selectedIcon: 'icon-speed-filled',
|
||||
defaultIcon: 'icon-speed',
|
||||
access: 'canSeeAdmin',
|
||||
access: 'canSeeOrgAdmin',
|
||||
component: './benchmark/index'
|
||||
},
|
||||
{
|
||||
@@ -174,7 +173,7 @@ const baseRoutes = [
|
||||
icon: 'icon-speed',
|
||||
selectedIcon: 'icon-speed-filled',
|
||||
defaultIcon: 'icon-speed',
|
||||
access: 'canSeeAdmin',
|
||||
access: 'canSeeOrgAdmin',
|
||||
hideInMenu: true,
|
||||
component: './benchmark/details'
|
||||
}
|
||||
@@ -184,7 +183,7 @@ const baseRoutes = [
|
||||
name: 'resources',
|
||||
path: '/resources',
|
||||
key: 'resources',
|
||||
access: 'canSeeAdmin',
|
||||
access: 'canSeeOrgAdmin',
|
||||
routes: [
|
||||
{
|
||||
path: '/resources',
|
||||
@@ -215,7 +214,7 @@ const baseRoutes = [
|
||||
icon: 'icon-backend',
|
||||
selectedIcon: 'icon-backend-filled',
|
||||
defaultIcon: 'icon-backend',
|
||||
access: 'canSeeAdmin',
|
||||
access: 'canSeeOrgAdmin',
|
||||
component: './backends/index'
|
||||
},
|
||||
{
|
||||
@@ -233,7 +232,7 @@ const baseRoutes = [
|
||||
name: 'clusterManagement',
|
||||
path: '/cluster-management',
|
||||
key: 'clusterManagement',
|
||||
access: 'canSeeAdmin',
|
||||
access: 'canSeeOrgAdmin',
|
||||
routes: [
|
||||
{
|
||||
path: '/cluster-management',
|
||||
|
||||
Reference in New Issue
Block a user