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:
@@ -1,4 +1,5 @@
|
||||
// columns.ts
|
||||
import PluginExtraFields from '@/components/plugin-extra-fields';
|
||||
import { tableSorter } from '@/config/settings';
|
||||
import {
|
||||
AutoTooltip,
|
||||
@@ -8,7 +9,7 @@ import {
|
||||
} from '@gpustack/core-ui';
|
||||
import { useIntl, useModel } from '@umijs/max';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { Tag } from 'antd';
|
||||
import { Space, Tag } from 'antd';
|
||||
import { ColumnsType } from 'antd/lib/table';
|
||||
import dayjs from 'dayjs';
|
||||
import { useMemo } from 'react';
|
||||
@@ -197,10 +198,19 @@ const useUsersColumns = ({
|
||||
dataIndex: 'operation',
|
||||
span: 3,
|
||||
render: (text, record) => (
|
||||
<DropdownButtons
|
||||
items={setActions(record)}
|
||||
onSelect={(val) => handleSelect(val, record)}
|
||||
/>
|
||||
// Plugin slot for per-row user actions. If no plugin is
|
||||
// registered, `PluginExtraFields` renders nothing and the
|
||||
// cell looks exactly as before.
|
||||
<Space size={4}>
|
||||
<DropdownButtons
|
||||
items={setActions(record)}
|
||||
onSelect={(val) => handleSelect(val, record)}
|
||||
/>
|
||||
<PluginExtraFields
|
||||
name="UserRowActions"
|
||||
context={{ user: record }}
|
||||
/>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user