fix: access control, voices options

This commit is contained in:
jialin
2025-11-11 15:47:32 +08:00
parent ee5c30934b
commit 84187eedc4
19 changed files with 196 additions and 59 deletions
@@ -1,9 +1,16 @@
import AlertBlockInfo from '@/components/alert-info/block';
import TransferInner from '@/pages/_components/transfer';
import { queryUsersList } from '@/pages/users/apis';
import { DownOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Empty, Form, Radio } from 'antd';
import { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
import { Checkbox, Dropdown, DropdownProps, Empty, Form, Radio } from 'antd';
import {
forwardRef,
useEffect,
useImperativeHandle,
useMemo,
useState
} from 'react';
import styled from 'styled-components';
import { queryModelAccessUserList } from '../../apis';
import { AccessControlFormData, ListItem } from '../../config/types';
@@ -29,20 +36,42 @@ const AccessControlForm = forwardRef((props: AccessControlFormProps, ref) => {
const accessPolicy = Form.useWatch('access_policy', form);
const [targetKeys, setTargetKeys] = useState<TransferKey[]>([]);
const [totalPages, setTotalPages] = useState(0);
const [userList, setUserList] = useState<{ title: string; key: number }[]>(
[]
);
const [userList, setUserList] = useState<
{ title: string; key: number; is_admin: boolean; is_active: boolean }[]
>([]);
const [open, setOpen] = useState(false);
const [filterInUsers, setFilterInUsers] = useState<Set<string>>(new Set());
const [queryParams, setQueryParams] = useState<Global.SearchParams>({
page: -1
});
const dataList = useMemo(() => {
if (filterInUsers.size === 0) {
return userList.filter((user) => {
return !user.is_admin && user.is_active;
});
}
return userList.filter((user) => {
const isAdmin = user.is_admin;
const isActive = user.is_active;
if (!filterInUsers.has('admin') && isAdmin) {
return false;
}
if (!filterInUsers.has('inactive') && !isActive) {
return false;
}
return true;
});
}, [userList, filterInUsers]);
const getUserList = async (query: Global.SearchParams) => {
try {
const res = await queryUsersList(query);
const options = res.items.map((item) => ({
title: item.username,
key: item.id,
is_admin: item.is_admin
is_admin: item.is_admin as boolean,
is_active: item.is_active as boolean
}));
setTotalPages(res.pagination.totalPage);
setUserList(options);
@@ -65,6 +94,30 @@ const AccessControlForm = forwardRef((props: AccessControlFormProps, ref) => {
console.log('search:', dir, value);
};
const handleCheck = (e: any, type: string) => {
const newSet = new Set(filterInUsers);
if (e.target.checked) {
newSet.add(type);
} else {
newSet.delete(type);
}
setFilterInUsers(newSet);
};
const handleOpenChange: DropdownProps['onOpenChange'] = (nextOpen, info) => {
if (info.source === 'trigger' || nextOpen) {
setOpen(nextOpen);
}
};
const handleFilterChange = (e: any) => {
if (e.target.checked) {
setFilterInUsers(new Set(['admin', 'inactive']));
} else {
setFilterInUsers(new Set());
}
};
useImperativeHandle(ref, () => ({
submit: () => {
form.submit();
@@ -97,6 +150,51 @@ const AccessControlForm = forwardRef((props: AccessControlFormProps, ref) => {
getUserList(queryParams);
}, [currentData?.id]);
const renderFilterDropdown = () => {
return (
<Dropdown
open={open}
onOpenChange={handleOpenChange}
key="filter-dropdown"
menu={{
items: [
{
label: (
<Checkbox
checked={filterInUsers.has('admin')}
onChange={(e: any) => handleCheck(e, 'admin')}
>
{intl.formatMessage({ id: 'models.table.admin' })}
</Checkbox>
),
key: '0'
},
{
label: (
<Checkbox
checked={filterInUsers.has('inactive')}
onChange={(e: any) => handleCheck(e, 'inactive')}
>
{intl.formatMessage({ id: 'users.status.deactivate' })}
</Checkbox>
),
key: '1'
}
]
}}
>
<span>
<span className="m-r-8" style={{ cursor: 'default' }}>
{intl.formatMessage({
id: 'models.accessControlModal.includeusers'
})}
</span>
<DownOutlined />
</span>
</Dropdown>
);
};
return (
<Form
form={form}
@@ -149,11 +247,11 @@ const AccessControlForm = forwardRef((props: AccessControlFormProps, ref) => {
</Label>
<Form.Item<AccessControlFormData> name="users">
<TransferInner
dataSource={userList}
dataSource={dataList}
targetKeys={targetKeys}
pagination={false}
titles={[
intl.formatMessage({ id: 'models.table.users.all' }),
renderFilterDropdown(),
intl.formatMessage({
id: 'models.table.users.selected'
})
@@ -188,9 +286,11 @@ const AccessControlForm = forwardRef((props: AccessControlFormProps, ref) => {
<span className="flex-center gap-4">
<span>{item.title}</span>
<span className="text-tertiary">
{item.is_admin
? `[${intl.formatMessage({ id: 'models.table.admin' })}]`
: ''}
{!item.is_active
? `[${intl.formatMessage({ id: 'users.status.inactive' })}]`
: item.is_admin
? `[${intl.formatMessage({ id: 'models.table.admin' })}]`
: ''}
</span>
</span>
)}
@@ -9,7 +9,7 @@ import AccessControlForm from './form';
const AccessControlModal: React.FC<
Global.ScrollerModalProps<ListItem, AccessControlFormData>
> = ({ open, title, currentData, action, onOk, onCancel }) => {
> = ({ open, title, currentData, action, onCancel }) => {
const intl = useIntl();
const form = useRef<any>(null);
+12 -3
View File
@@ -1,4 +1,4 @@
import { modelsExpandKeysAtom } from '@/atoms/models';
import { modelsExpandKeysAtom, modelsSessionAtom } from '@/atoms/models';
import DeleteModal from '@/components/delete-modal';
import DropDownActions from '@/components/drop-down-actions';
import DropdownButtons from '@/components/drop-down-buttons';
@@ -137,6 +137,7 @@ const Models: React.FC<ModelsProps> = ({
isGGUF: false
});
const [expandAtom, setExpandAtom] = useAtom(modelsExpandKeysAtom);
const [modelsSession, setModelsSession] = useAtom(modelsSessionAtom);
const intl = useIntl();
const navigate = useNavigate();
const rowSelection = useTableRowSelection();
@@ -591,7 +592,16 @@ const Models: React.FC<ModelsProps> = ({
});
};
const handleSubmitAccessControl = (data: any) => {};
useEffect(() => {
if (modelsSession.source && loadend) {
handleClickDropdown({
key: modelsSession.source
});
}
return () => {
setModelsSession({});
};
}, [loadend]);
return (
<>
@@ -774,7 +784,6 @@ const Models: React.FC<ModelsProps> = ({
></APIAccessInfoModal>
<AccessControlModal
onCancel={handleCancelAccessControl}
onOk={handleSubmitAccessControl}
title={openAccessControlModal.title}
open={openAccessControlModal.open}
currentData={openAccessControlModal.currentData}