style: allowed models ux
This commit is contained in:
+1
-2
@@ -70,7 +70,6 @@ export default [
|
|||||||
name: 'models',
|
name: 'models',
|
||||||
path: '/models',
|
path: '/models',
|
||||||
key: 'models',
|
key: 'models',
|
||||||
access: 'canSeeAdmin',
|
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/models',
|
path: '/models',
|
||||||
@@ -103,7 +102,7 @@ export default [
|
|||||||
icon: 'icon-models',
|
icon: 'icon-models',
|
||||||
selectedIcon: 'icon-models-filled',
|
selectedIcon: 'icon-models-filled',
|
||||||
defaultIcon: 'icon-models',
|
defaultIcon: 'icon-models',
|
||||||
access: 'canSeeAdmin',
|
access: 'canSeeUser',
|
||||||
component: './llmodels/user-models'
|
component: './llmodels/user-models'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,8 +4,15 @@ export default (initialState: { currentUser?: Global.UserInfo }) => {
|
|||||||
initialState.currentUser &&
|
initialState.currentUser &&
|
||||||
initialState.currentUser.is_admin
|
initialState.currentUser.is_admin
|
||||||
);
|
);
|
||||||
|
const canSeeUser = !!(
|
||||||
|
initialState &&
|
||||||
|
initialState.currentUser &&
|
||||||
|
!initialState.currentUser.is_admin
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
canSeeAdmin,
|
canSeeAdmin,
|
||||||
|
canSeeUser,
|
||||||
canDelete: true,
|
canDelete: true,
|
||||||
canLogin: true
|
canLogin: true
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,5 +11,6 @@ export default {
|
|||||||
'apikeys.form.expiration.7days': '7 days',
|
'apikeys.form.expiration.7days': '7 days',
|
||||||
'apikeys.form.expiration.1month': '1 month',
|
'apikeys.form.expiration.1month': '1 month',
|
||||||
'apikeys.form.expiration.6months': '6 months',
|
'apikeys.form.expiration.6months': '6 months',
|
||||||
'apikeys.form.expiration.never': 'No expiration'
|
'apikeys.form.expiration.never': 'No expiration',
|
||||||
|
'apikeys.table.bindModels': 'Allowed Models'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,5 +11,6 @@ export default {
|
|||||||
'apikeys.form.expiration.7days': '7日間',
|
'apikeys.form.expiration.7days': '7日間',
|
||||||
'apikeys.form.expiration.1month': '1ヶ月',
|
'apikeys.form.expiration.1month': '1ヶ月',
|
||||||
'apikeys.form.expiration.6months': '6ヶ月',
|
'apikeys.form.expiration.6months': '6ヶ月',
|
||||||
'apikeys.form.expiration.never': '無期限'
|
'apikeys.form.expiration.never': '無期限',
|
||||||
|
'apikeys.table.bindModels': '許可されたモデル'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,5 +11,6 @@ export default {
|
|||||||
'apikeys.form.expiration.7days': '7 дней',
|
'apikeys.form.expiration.7days': '7 дней',
|
||||||
'apikeys.form.expiration.1month': '1 месяц',
|
'apikeys.form.expiration.1month': '1 месяц',
|
||||||
'apikeys.form.expiration.6months': '6 месяцев',
|
'apikeys.form.expiration.6months': '6 месяцев',
|
||||||
'apikeys.form.expiration.never': 'Без срока действия'
|
'apikeys.form.expiration.never': 'Без срока действия',
|
||||||
|
'apikeys.table.bindModels': 'Разрешенные модели'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,5 +10,6 @@ export default {
|
|||||||
'apikeys.form.expiration.7days': '7天',
|
'apikeys.form.expiration.7days': '7天',
|
||||||
'apikeys.form.expiration.1month': '1个月',
|
'apikeys.form.expiration.1month': '1个月',
|
||||||
'apikeys.form.expiration.6months': '6个月',
|
'apikeys.form.expiration.6months': '6个月',
|
||||||
'apikeys.form.expiration.never': '永不过期'
|
'apikeys.form.expiration.never': '永不过期',
|
||||||
|
'apikeys.table.bindModels': '绑定模型'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
import { Transfer, TransferProps } from 'antd';
|
import { MoreOutlined } from '@ant-design/icons';
|
||||||
|
import { Pagination, Transfer, TransferProps } from 'antd';
|
||||||
|
import { useState } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
type TransferKey = string | number | bigint;
|
type TransferKey = string | number | bigint;
|
||||||
|
|
||||||
|
const PaginationWrapper = styled.div`
|
||||||
|
padding: 4px 16px;
|
||||||
|
`;
|
||||||
|
|
||||||
const TransferWrap = styled.div`
|
const TransferWrap = styled.div`
|
||||||
.ant-transfer-list {
|
.ant-transfer-list {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 300px;
|
height: 360px;
|
||||||
}
|
}
|
||||||
.ant-transfer-list-content {
|
.ant-transfer-list-content {
|
||||||
.ant-transfer-list-content-item {
|
.ant-transfer-list-content-item {
|
||||||
@@ -27,13 +33,48 @@ const TransferWrap = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
interface TransferInnerProps extends TransferProps {
|
interface TransferInnerProps extends TransferProps {
|
||||||
|
total?: number;
|
||||||
|
perPage?: number;
|
||||||
|
onPageChange?: (page: number, perPage?: number) => void;
|
||||||
dataSource?: Array<{ key: TransferKey; title: string }>;
|
dataSource?: Array<{ key: TransferKey; title: string }>;
|
||||||
targetKeys?: TransferKey[];
|
targetKeys?: TransferKey[];
|
||||||
}
|
}
|
||||||
const TransferInner: React.FC<TransferInnerProps> = (props) => {
|
const TransferInner: React.FC<TransferInnerProps> = (props) => {
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
const { onPageChange, total, perPage = 30 } = props;
|
||||||
|
|
||||||
|
const handleOnPageChange = (page: number, perPage?: number) => {
|
||||||
|
setPage(page);
|
||||||
|
onPageChange?.(page, perPage);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderFooter = (TransferProps: any, { direction }: any) => {
|
||||||
|
if (direction === 'left' && total && total > perPage!) {
|
||||||
|
return (
|
||||||
|
<PaginationWrapper>
|
||||||
|
<Pagination
|
||||||
|
simple={{ readOnly: true }}
|
||||||
|
size="small"
|
||||||
|
total={total}
|
||||||
|
onChange={handleOnPageChange}
|
||||||
|
pageSize={perPage}
|
||||||
|
current={page}
|
||||||
|
showSizeChanger={false}
|
||||||
|
/>
|
||||||
|
</PaginationWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TransferWrap>
|
<TransferWrap>
|
||||||
<Transfer {...props}></Transfer>
|
<Transfer
|
||||||
|
{...props}
|
||||||
|
selectionsIcon={
|
||||||
|
<MoreOutlined style={{ fontSize: 14, marginBottom: 3 }} />
|
||||||
|
}
|
||||||
|
></Transfer>
|
||||||
</TransferWrap>
|
</TransferWrap>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,6 +17,13 @@ export async function createApisKey(params: { data: FormData }) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function updateApisKey(id: number, params: { data: FormData }) {
|
||||||
|
return request<ListItem>(`${APIS_KEYS_API}/${id}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
data: params.data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export async function deleteApisKey(id: number) {
|
export async function deleteApisKey(id: number) {
|
||||||
return request(`${APIS_KEYS_API}/${id}`, {
|
return request(`${APIS_KEYS_API}/${id}`, {
|
||||||
method: 'DELETE'
|
method: 'DELETE'
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ const AllowModelsForm: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
render={(item) => item.title}
|
render={(item) => item.title}
|
||||||
titles={['Available Models', 'Allowed Models']}
|
titles={['Available Models', 'Allowed Models']}
|
||||||
showSearch
|
showSearch={{
|
||||||
|
placeholder: 'Filter by model name'
|
||||||
|
}}
|
||||||
filterOption={(inputValue, item) =>
|
filterOption={(inputValue, item) =>
|
||||||
item.title.toLowerCase().includes(inputValue.toLowerCase())
|
item.title.toLowerCase().includes(inputValue.toLowerCase())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import SealInput from '@/components/seal-form/seal-input';
|
||||||
|
import SealSelect from '@/components/seal-form/seal-select';
|
||||||
|
import { useIntl } from '@umijs/max';
|
||||||
|
import { Form } from 'antd';
|
||||||
|
import React from 'react';
|
||||||
|
import { expirationOptions } from '../../config';
|
||||||
|
import { FormData } from '../../config/types';
|
||||||
|
import AllowModelsForm from './allow-models';
|
||||||
|
|
||||||
|
const APIKeyForm: React.FC = () => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Form.Item<FormData>
|
||||||
|
name="name"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: intl.formatMessage(
|
||||||
|
{ id: 'common.form.rule.input' },
|
||||||
|
{
|
||||||
|
name: intl.formatMessage({ id: 'common.table.name' })
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealInput.Input
|
||||||
|
label={intl.formatMessage({ id: 'common.table.name' })}
|
||||||
|
required
|
||||||
|
></SealInput.Input>
|
||||||
|
</Form.Item>
|
||||||
|
<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
|
||||||
|
options={expirationOptions}
|
||||||
|
label={intl.formatMessage({ id: 'apikeys.form.expiretime' })}
|
||||||
|
required
|
||||||
|
></SealSelect>
|
||||||
|
</Form.Item>
|
||||||
|
<AllowModelsForm></AllowModelsForm>
|
||||||
|
<Form.Item<FormData> name="description" rules={[{ required: false }]}>
|
||||||
|
<SealInput.TextArea
|
||||||
|
scaleSize={true}
|
||||||
|
label={intl.formatMessage({ id: 'common.table.description' })}
|
||||||
|
></SealInput.TextArea>
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default APIKeyForm;
|
||||||
@@ -2,17 +2,17 @@ import CopyButton from '@/components/copy-button';
|
|||||||
import ModalFooter from '@/components/modal-footer';
|
import ModalFooter from '@/components/modal-footer';
|
||||||
import ScrollerModal from '@/components/scroller-modal';
|
import ScrollerModal from '@/components/scroller-modal';
|
||||||
import SealInput from '@/components/seal-form/seal-input';
|
import SealInput from '@/components/seal-form/seal-input';
|
||||||
import SealSelect from '@/components/seal-form/seal-select';
|
|
||||||
import { PageAction } from '@/config';
|
import { PageAction } from '@/config';
|
||||||
import { PageActionType } from '@/config/types';
|
import { PageActionType } from '@/config/types';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Button, Form, Tag } from 'antd';
|
import { Button, Form, Tag } from 'antd';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { createApisKey } from '../../apis';
|
import { createApisKey, updateApisKey } from '../../apis';
|
||||||
import { expirationOptions } from '../../config';
|
import { expirationOptions } from '../../config';
|
||||||
import { FormData, ListItem } from '../../config/types';
|
import { FormData, ListItem } from '../../config/types';
|
||||||
import AllowModelsForm from './allow-models';
|
import AllowModelsForm from './allow-models';
|
||||||
|
import APIKeyForm from './form';
|
||||||
|
|
||||||
type AddModalProps = {
|
type AddModalProps = {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -43,6 +43,13 @@ const AddModal: React.FC<AddModalProps> = ({
|
|||||||
expires_in: 1
|
expires_in: 1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (action === PageAction.EDIT && currentData && open) {
|
||||||
|
form.setFieldsValue({
|
||||||
|
name: currentData.name,
|
||||||
|
description: currentData.description,
|
||||||
|
allowed_model_names: currentData.allowed_model_names || []
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -67,16 +74,29 @@ const AddModal: React.FC<AddModalProps> = ({
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const createAPIKey = async (data: FormData) => {
|
||||||
|
const params = {
|
||||||
|
...data,
|
||||||
|
expires_in: getExpireValue(data.expires_in)
|
||||||
|
};
|
||||||
|
const res = await createApisKey({ data: params });
|
||||||
|
setAPIKeyValue(res.value);
|
||||||
|
setShowKey(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateAPIKey = async (data: FormData) => {
|
||||||
|
await updateApisKey(currentData?.id as number, { data });
|
||||||
|
onOk();
|
||||||
|
};
|
||||||
|
|
||||||
const handleOnOk = async (data: FormData) => {
|
const handleOnOk = async (data: FormData) => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const params = {
|
if (action === PageAction.CREATE) {
|
||||||
...data,
|
await createAPIKey(data);
|
||||||
expires_in: getExpireValue(data.expires_in)
|
} else if (action === PageAction.EDIT && currentData?.id) {
|
||||||
};
|
await updateAPIKey(data);
|
||||||
const res = await createApisKey({ data: params });
|
}
|
||||||
setAPIKeyValue(res.value);
|
|
||||||
setShowKey(true);
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -109,7 +129,7 @@ const AddModal: React.FC<AddModalProps> = ({
|
|||||||
closeIcon={false}
|
closeIcon={false}
|
||||||
maskClosable={false}
|
maskClosable={false}
|
||||||
keyboard={false}
|
keyboard={false}
|
||||||
width={600}
|
width={700}
|
||||||
styles={{}}
|
styles={{}}
|
||||||
footer={
|
footer={
|
||||||
!showKey ? (
|
!showKey ? (
|
||||||
@@ -126,60 +146,9 @@ const AddModal: React.FC<AddModalProps> = ({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Form name="addAPIKey" form={form} onFinish={handleOnOk} preserve={false}>
|
<Form name="addAPIKey" form={form} onFinish={handleOnOk} preserve={false}>
|
||||||
{!showKey ? (
|
{action === PageAction.EDIT && <AllowModelsForm></AllowModelsForm>}
|
||||||
<>
|
{!showKey && action === PageAction.CREATE && <APIKeyForm></APIKeyForm>}
|
||||||
<Form.Item<FormData>
|
{showKey && action === PageAction.CREATE && (
|
||||||
name="name"
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: intl.formatMessage(
|
|
||||||
{ id: 'common.form.rule.input' },
|
|
||||||
{
|
|
||||||
name: intl.formatMessage({ id: 'common.table.name' })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<SealInput.Input
|
|
||||||
label={intl.formatMessage({ id: 'common.table.name' })}
|
|
||||||
required
|
|
||||||
></SealInput.Input>
|
|
||||||
</Form.Item>
|
|
||||||
<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
|
|
||||||
options={expirationOptions}
|
|
||||||
label={intl.formatMessage({ id: 'apikeys.form.expiretime' })}
|
|
||||||
required
|
|
||||||
></SealSelect>
|
|
||||||
</Form.Item>
|
|
||||||
<AllowModelsForm></AllowModelsForm>
|
|
||||||
<Form.Item<FormData>
|
|
||||||
name="description"
|
|
||||||
rules={[{ required: false }]}
|
|
||||||
>
|
|
||||||
<SealInput.TextArea
|
|
||||||
label={intl.formatMessage({ id: 'common.table.description' })}
|
|
||||||
></SealInput.TextArea>
|
|
||||||
</Form.Item>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<div>
|
<div>
|
||||||
<Tag
|
<Tag
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export interface ListItem {
|
|||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
expires_at: string;
|
expires_at: string;
|
||||||
|
allowed_model_names: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormData {
|
export interface FormData {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ interface ColumnsHookProps {
|
|||||||
|
|
||||||
const actionList: Global.ActionItem[] = [
|
const actionList: Global.ActionItem[] = [
|
||||||
{
|
{
|
||||||
label: 'common.button.edit',
|
label: 'Edit Allowed Models',
|
||||||
key: 'edit',
|
key: 'edit',
|
||||||
icon: icons.EditOutlined
|
icon: icons.EditOutlined
|
||||||
},
|
},
|
||||||
@@ -60,6 +60,17 @@ const useModelsColumns = ({
|
|||||||
</AutoTooltip>
|
</AutoTooltip>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: intl.formatMessage({ id: 'apikeys.table.bindModels' }),
|
||||||
|
dataIndex: 'allowed_model_names',
|
||||||
|
key: 'allowed_model_names',
|
||||||
|
ellipsis: {
|
||||||
|
showTitle: false
|
||||||
|
},
|
||||||
|
render: (text: string[], record: ListItem) => (
|
||||||
|
<AutoTooltip ghost>{text?.join(', ')}</AutoTooltip>
|
||||||
|
)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: intl.formatMessage({ id: 'common.table.description' }),
|
title: intl.formatMessage({ id: 'common.table.description' }),
|
||||||
dataIndex: 'description',
|
dataIndex: 'description',
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ const APIKeys: React.FC = () => {
|
|||||||
const handleEditKey = (record: ListItem) => {
|
const handleEditKey = (record: ListItem) => {
|
||||||
setOpenAddModal({
|
setOpenAddModal({
|
||||||
open: true,
|
open: true,
|
||||||
title: 'Edit API Key',
|
title: 'Edit Allowed Models',
|
||||||
action: PageAction.EDIT,
|
action: PageAction.EDIT,
|
||||||
currentData: record
|
currentData: record
|
||||||
});
|
});
|
||||||
@@ -79,7 +79,6 @@ const APIKeys: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleModalCancel = () => {
|
const handleModalCancel = () => {
|
||||||
console.log('handleModalCancel');
|
|
||||||
setOpenAddModal({
|
setOpenAddModal({
|
||||||
open: false,
|
open: false,
|
||||||
title: '',
|
title: '',
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import IconFont from '@/components/icon-font';
|
|
||||||
import CheckboxField from '@/components/seal-form/checkbox-field';
|
import CheckboxField from '@/components/seal-form/checkbox-field';
|
||||||
import TransferInner from '@/pages/_components/transfer';
|
import TransferInner from '@/pages/_components/transfer';
|
||||||
import { queryUsersList } from '@/pages/users/apis';
|
import { queryUsersList } from '@/pages/users/apis';
|
||||||
@@ -33,7 +32,7 @@ const AccessControlForm = forwardRef((props: AccessControlFormProps, ref) => {
|
|||||||
);
|
);
|
||||||
const [queryParams, setQueryParams] = useState<Global.SearchParams>({
|
const [queryParams, setQueryParams] = useState<Global.SearchParams>({
|
||||||
page: 1,
|
page: 1,
|
||||||
perPage: 30
|
perPage: 100
|
||||||
});
|
});
|
||||||
|
|
||||||
const getUserList = async (query: Global.SearchParams) => {
|
const getUserList = async (query: Global.SearchParams) => {
|
||||||
@@ -62,6 +61,10 @@ const AccessControlForm = forwardRef((props: AccessControlFormProps, ref) => {
|
|||||||
form.setFieldsValue({ users });
|
form.setFieldsValue({ users });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onSearch = (dir: 'left' | 'right', value: string) => {
|
||||||
|
console.log('search:', dir, value);
|
||||||
|
};
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
submit: () => {
|
submit: () => {
|
||||||
form.submit();
|
form.submit();
|
||||||
@@ -116,28 +119,34 @@ const AccessControlForm = forwardRef((props: AccessControlFormProps, ref) => {
|
|||||||
></CheckboxField>
|
></CheckboxField>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
{setPublic && (
|
{setPublic && (
|
||||||
<Form.Item<AccessControlFormData>
|
<>
|
||||||
name="users"
|
<Label>User Select</Label>
|
||||||
rules={[
|
<Form.Item<AccessControlFormData>
|
||||||
{
|
name="users"
|
||||||
required: true,
|
rules={[
|
||||||
message: 'Please select at least one user'
|
{
|
||||||
}
|
required: true,
|
||||||
]}
|
message: 'Please select at least one user'
|
||||||
>
|
}
|
||||||
<TransferInner
|
]}
|
||||||
dataSource={userList}
|
>
|
||||||
targetKeys={targetKeys}
|
<TransferInner
|
||||||
showSelectAll
|
total={100}
|
||||||
showSearch
|
dataSource={userList}
|
||||||
pagination={totalPages > 1}
|
targetKeys={targetKeys}
|
||||||
titles={['Available Users', 'Users with Access']}
|
showSelectAll
|
||||||
render={(item) => item.title}
|
pagination={false}
|
||||||
selectAllLabels={[]}
|
titles={['Available Users', 'Users with Access']}
|
||||||
selectionsIcon={<IconFont type="icon-down"></IconFont>}
|
showSearch={{
|
||||||
onChange={handleOnChange}
|
placeholder: 'Filter by username'
|
||||||
/>
|
}}
|
||||||
</Form.Item>
|
render={(item) => item.title}
|
||||||
|
selectAllLabels={[]}
|
||||||
|
onSearch={onSearch}
|
||||||
|
onChange={handleOnChange}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const AccessControlModal: React.FC<
|
|||||||
closeIcon={true}
|
closeIcon={true}
|
||||||
maskClosable={false}
|
maskClosable={false}
|
||||||
keyboard={false}
|
keyboard={false}
|
||||||
width={600}
|
width={700}
|
||||||
footer={
|
footer={
|
||||||
<ModalFooter onOk={handleSumit} onCancel={onCancel}></ModalFooter>
|
<ModalFooter onOk={handleSumit} onCancel={onCancel}></ModalFooter>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user