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 { 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'; type TransferKey = string | number | bigint; const Label = styled.div` font-weight: 500; margin-block: 8px 12px; font-size: 14px; color: var(--ant-color-text-tertiary); `; interface AccessControlFormProps { currentData?: ListItem | null; onFinish: (values: AccessControlFormData) => void; } const AccessControlForm = forwardRef((props: AccessControlFormProps, ref) => { const { currentData, onFinish } = props; const intl = useIntl(); const [form] = Form.useForm(); const accessPolicy = Form.useWatch('access_policy', form); const [targetKeys, setTargetKeys] = useState([]); const [totalPages, setTotalPages] = useState(0); const [userList, setUserList] = useState< { title: string; key: number; is_admin: boolean; is_active: boolean }[] >([]); const [open, setOpen] = useState(false); const [filterInUsers, setFilterInUsers] = useState>(new Set()); const [queryParams, setQueryParams] = useState({ 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 as boolean, is_active: item.is_active as boolean })); setTotalPages(res.pagination.totalPage); setUserList(options); return options; } catch (error) { setUserList([]); return []; } }; const handleOnChange = ( nextTargetKeys: TransferKey[], direction: string, removeKeys: TransferKey[] ) => { setTargetKeys(nextTargetKeys); const users = nextTargetKeys.map((key) => ({ id: key })); form.setFieldsValue({ users }); }; const onSearch = (dir: 'left' | 'right', value: string) => { 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); } }; useImperativeHandle(ref, () => ({ submit: () => { form.submit(); }, setFieldsValue: (values: Partial) => { form.setFieldsValue(values); }, getFieldsValue: () => { return form.getFieldsValue(); }, resetFields: () => { form.resetFields(); } })); useEffect(() => { const init = async () => { const allusers = await getUserList(queryParams); const userMap = new Map(allusers.map((u) => [u.key, u])); if (currentData?.id) { queryModelAccessUserList(currentData.id).then((res) => { const keys = res.items.map((item) => item.id); setTargetKeys(keys); let hasAdmin = false; let hasInactive = false; for (const key of keys) { const user = userMap.get(key); if (!user) continue; if (user.is_admin) hasAdmin = true; if (!user.is_active) hasInactive = true; if (hasAdmin && hasInactive) break; } const filterSet = new Set(); if (hasAdmin) filterSet.add('admin'); if (hasInactive) filterSet.add('inactive'); setFilterInUsers(filterSet); form.setFieldsValue({ access_policy: currentData.access_policy, users: res.items.map((item) => ({ id: item.id })) }); }); } else { setTargetKeys([]); form.setFieldsValue({ users: [] }); } }; init(); }, [currentData?.id]); const renderFilterDropdown = () => { return ( handleCheck(e, 'admin')} > {intl.formatMessage({ id: 'models.table.admin' })} ), key: '0' }, { label: ( handleCheck(e, 'inactive')} > {intl.formatMessage({ id: 'users.status.deactivate' })} ), key: '1' } ] }} > {intl.formatMessage({ id: 'models.accessControlModal.includeusers' })} ); }; return (
name="access_policy" noStyle> {accessPolicy === 'public' && (
)} {accessPolicy === 'allowed_users' && ( <> name="users"> , ] }} showSearch={{ placeholder: intl.formatMessage({ id: 'common.filter.name' }) }} filterOption={(inputValue, item) => item.title.toLowerCase().includes(inputValue.toLowerCase()) } render={(item) => ( {item.title} {!item.is_active ? `[${intl.formatMessage({ id: 'users.status.inactive' })}]` : item.is_admin ? `[${intl.formatMessage({ id: 'models.table.admin' })}]` : ''} )} onSearch={onSearch} onChange={handleOnChange} /> )} ); }); export default AccessControlForm;