The CreateOrgScopeField slot only renders a "Global" choice when the host form passes ``allowGlobal: true``. Without it, an admin in the "All Orgs" view sees only Personal + every org in the dropdown — and the form's submit injects an ``X-Organization-Id`` header for every choice, pinning the new key to a tenant. The matching backend change (api_keys.owner_principal_id nullable) only kicks in when no header is sent. Pass ``allowGlobal: true`` (default-selects Global for admin) plus ``globalLabelId: 'scope.global'`` so the dropdown option reads as plain "Global" — matching the existing tag / column labels for the same concept elsewhere in the UI, instead of the longer inference-backend "shared with all organizations" copy. Relax the ListItem type so ``owner_principal_id`` may be ``null`` — the OrganizationCell / OwnerScopeTag renderers already render the "Global" placeholder for null/undefined; the type was the only thing still claiming the column was always present.
142 lines
3.9 KiB
TypeScript
142 lines
3.9 KiB
TypeScript
import PluginExtraFields from '@/components/plugin-extra-fields';
|
|
import { PageAction } from '@/config';
|
|
import { PageActionType } from '@/config/types';
|
|
import {
|
|
Input as CInput,
|
|
Password,
|
|
Select as SealSelect
|
|
} from '@gpustack/core-ui';
|
|
import { useIntl } from '@umijs/max';
|
|
import { Form } from 'antd';
|
|
import React from 'react';
|
|
import { expirationOptions } from '../../config';
|
|
import { FormData, ListItem } from '../../config/types';
|
|
import AllowModelsForm from './allow-models';
|
|
|
|
const APIKeyForm: React.FC<{
|
|
action: PageActionType;
|
|
currentData?: Partial<ListItem> | null;
|
|
onValuesChange?: (changedValues: any, allValues: any) => void;
|
|
}> = ({ action, currentData, onValuesChange }) => {
|
|
const intl = useIntl();
|
|
const keyType = Form.useWatch('key_type') as FormData['key_type'];
|
|
|
|
return (
|
|
<>
|
|
<Form.Item<FormData>
|
|
name="name"
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: intl.formatMessage(
|
|
{ id: 'common.form.rule.input' },
|
|
{
|
|
name: intl.formatMessage({ id: 'common.table.name' })
|
|
}
|
|
)
|
|
}
|
|
]}
|
|
>
|
|
<CInput.Input
|
|
trim
|
|
disabled={action === PageAction.EDIT}
|
|
label={intl.formatMessage({ id: 'common.table.name' })}
|
|
required
|
|
></CInput.Input>
|
|
</Form.Item>
|
|
|
|
<PluginExtraFields
|
|
name="CreateOrgScopeField"
|
|
context={{
|
|
action,
|
|
allowPersonal: true,
|
|
allowGlobal: true,
|
|
globalLabelId: 'scope.global'
|
|
}}
|
|
/>
|
|
|
|
<Form.Item<FormData>
|
|
name="expires_in"
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: intl.formatMessage(
|
|
{ id: 'common.form.rule.select' },
|
|
{
|
|
name: intl.formatMessage({
|
|
id: 'apikeys.form.expiretime'
|
|
})
|
|
}
|
|
)
|
|
}
|
|
]}
|
|
>
|
|
<SealSelect
|
|
disabled={action === PageAction.EDIT}
|
|
options={expirationOptions}
|
|
label={intl.formatMessage({ id: 'apikeys.form.expiretime' })}
|
|
required
|
|
></SealSelect>
|
|
</Form.Item>
|
|
<Form.Item<FormData> name="description" rules={[{ required: false }]}>
|
|
<CInput.TextArea
|
|
scaleSize={true}
|
|
label={intl.formatMessage({ id: 'common.table.description' })}
|
|
></CInput.TextArea>
|
|
</Form.Item>
|
|
{action === PageAction.CREATE && (
|
|
<>
|
|
<Form.Item<FormData> name="key_type" initialValue="auto">
|
|
<SealSelect
|
|
options={[
|
|
{
|
|
label: intl.formatMessage({ id: 'apikeys.type.auto' }),
|
|
value: 'auto'
|
|
},
|
|
{
|
|
label: intl.formatMessage({ id: 'apikeys.type.custom' }),
|
|
value: 'custom'
|
|
}
|
|
]}
|
|
label={intl.formatMessage({ id: 'common.table.type' })}
|
|
></SealSelect>
|
|
</Form.Item>
|
|
{keyType === 'custom' && (
|
|
<Form.Item<FormData>
|
|
name="custom"
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: intl.formatMessage(
|
|
{ id: 'common.form.rule.input' },
|
|
{
|
|
name: intl.formatMessage({
|
|
id: 'apikeys.table.key'
|
|
})
|
|
}
|
|
)
|
|
}
|
|
]}
|
|
>
|
|
<Password
|
|
trim
|
|
required
|
|
autoComplete="new-password"
|
|
label={intl.formatMessage({ id: 'apikeys.table.key' })}
|
|
></Password>
|
|
</Form.Item>
|
|
)}
|
|
</>
|
|
)}
|
|
|
|
<AllowModelsForm
|
|
currentData={currentData}
|
|
action={action}
|
|
onValuesChange={onValuesChange}
|
|
></AllowModelsForm>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default APIKeyForm;
|