From ab2a0d8ae249e4600d8e3a8ed8fc98c8005293d3 Mon Sep 17 00:00:00 2001 From: maggieyyy <61950669+maggieyyy@users.noreply.github.com> Date: Tue, 29 Oct 2024 11:58:09 +0800 Subject: [PATCH] fix: Modify member transfer --- .../components/aoplatform/MemberTransfer.tsx | 214 ++++++------------ frontend/packages/core/src/App.css | 5 + .../src/pages/member/MemberDropdownModal.tsx | 1 - .../core/src/pages/team/TeamConfig.tsx | 7 +- .../core/src/pages/team/TeamInsideMember.tsx | 13 +- 5 files changed, 89 insertions(+), 151 deletions(-) diff --git a/frontend/packages/common/src/components/aoplatform/MemberTransfer.tsx b/frontend/packages/common/src/components/aoplatform/MemberTransfer.tsx index 90c2e424..4945379c 100644 --- a/frontend/packages/common/src/components/aoplatform/MemberTransfer.tsx +++ b/frontend/packages/common/src/components/aoplatform/MemberTransfer.tsx @@ -1,27 +1,24 @@ -import { GetProp, TransferProps, TreeDataNode, theme, Transfer, Tree, Spin } from "antd"; -import { DataNode, TreeProps } from "antd/es/tree"; +import { TransferProps, TreeDataNode, Tree, Spin, Input } from "antd"; +import { DataNode } from "antd/es/tree"; import { Ref, forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react"; -import { ApartmentOutlined, LoadingOutlined, UserOutlined } from "@ant-design/icons"; -import { cloneDeep, debounce } from "lodash-es"; +import { LoadingOutlined } from "@ant-design/icons"; import { ColumnsType } from "antd/es/table"; import { $t } from "@common/locales"; import { useGlobalContext } from "@common/contexts/GlobalStateContext"; - -type TransferItem = GetProp[number]; +import Search from "antd/es/input/Search"; export type TransferTableProps = { request?:(k?:string)=>Promise<{data:T[],success:boolean}> columns: ColumnsType primaryKey:string - onSelect:(selectedData:T[])=>void + onSelect:(selectedData:string[])=>void tableType?:'member'|'api' disabledData:string[] searchPlaceholder?:string } export type TransferTableHandle = { - selectedData: () => T[]; selectedRowKeys: () => React.Key[]; } @@ -31,10 +28,6 @@ interface TreeTransferProps { onChange: TransferProps['onChange']; } -// Customize Table Transfer -const isChecked = (selectedKeys: React.Key[], eventKey: React.Key) => - selectedKeys.includes(eventKey); - const generateTree = ( treeNodes: TreeDataNode[] = [], checkedKeys: TreeTransferProps['targetKeys'] = [], @@ -73,167 +66,102 @@ const generateTree = ( ) }; -const TransferTree = (props)=>{ - const { direction, token, tableHeight, dataSource, targetKeys, onItemSelect, onItemSelectAll,checkedKey,selectedKeys, filteredItems ,disabledData} = props; - const [expandedKeys, setExpandedKeys] = useState([]); - - const getExpandedKeys = (newData:TreeDataNode[], expandedSet:Set = new Set())=>{ - newData.forEach((item)=>{ - if(item.children && item.children.length > 0){ - expandedSet.add(item.key) - getExpandedKeys(item.children,expandedSet) - } - }) - return expandedSet - } - - const treeData:TreeDataNode[] = useMemo(()=>{ - const filteredSet = filteredItems && filteredItems.length > 0 ? new Set(filteredItems.map((x)=>x.id)) : new Set() - const res = dataSource && dataSource.length > 0 ? generateTree(dataSource, targetKeys,direction === 'right',disabledData,filteredSet) : [] - setExpandedKeys(Array.from(getExpandedKeys(res))) - return res - },[ - dataSource, targetKeys,direction ,disabledData,filteredItems - ]) - - const onExpand: TreeProps['onExpand'] = (expandedKeysValue) => { - setExpandedKeys(expandedKeysValue as string[]); - }; - - return ( - -
- { return (props.type === 'member' ? : )} } - treeData={treeData} - onCheck={(_checkedKeys, e:{checked: boolean, checkedNodes, node, event, halfCheckedKeys}) => { - if(e.checked){ - onItemSelectAll( _checkedKeys, e.checked); - }else{ - const checkedKeyArrFromTree = e.checkedNodes.map(node => node.key) - onItemSelectAll((checkedKey as string[]).filter(key => checkedKeyArrFromTree.indexOf(key) === -1),e.checked) - } - }} - onSelect={(_, { node: { key } }) => { - onItemSelect(key as string, !isChecked(checkedKey, key)); - }} - /> -
- ) -} - const MemberTransfer= forwardRef, TransferTableProps<{[k:string]:unknown}>>( (props: TransferTableProps, ref:Ref>) => { const {request,columns,primaryKey,onSelect,tableType,disabledData = [],searchPlaceholder} = props - const [tableHeight, setTableHeight] = useState(window.innerHeight * 80 / 100 - 64 - 72 - 56 - 16 -3); const [targetKeys, setTargetKeys] = useState([]); const [dataSource, setDataSource] = useState([]) const parentRef = useRef(null); const [loading, setLoading] = useState(false) const {state} = useGlobalContext() - + const [expandedKeys, setExpandedKeys] = useState([]); + const [searchWord, setSearchWord] = useState('') useEffect(()=>{ setTargetKeys(disabledData) },[disabledData]) useImperativeHandle(ref, () =>({ - selectedData: () => dataSource, selectedRowKeys: () => targetKeys,})) - const onChange: TreeTransferProps['onChange'] = (keys) => { - onSelect?.(new Set(keys)) - setTargetKeys(Array.from(new Set(keys))); - }; + const translatedDataSource = useMemo(()=>{ + + const loop = (data: DataNode[]): DataNode[] => + data?.map((item) => { + const strTitle:string = item.name === '所有成员' ? $t(item.name) as string : item.name as string; + const index = strTitle.indexOf(searchWord); + const beforeStr = strTitle.substring(0, index); + const afterStr = strTitle.slice(index + searchWord.length); + const title = + index > -1 ? ( + + {beforeStr} + {searchWord} + {afterStr} + + ) : ( + {strTitle} + ) + if (item.children) { + return { + ...item, + title, + disableCheckbox:disabledData.indexOf(item.key as string) !== -1, + children: loop(item.children as T[]) }; + } - const { token } = theme.useToken(); - - const transferDataSource: TransferItem[] = useMemo(()=>{ - function flatten(list: TreeDataNode[] = [], res:TransferItem[]) { - list.forEach((item) => { - res.push({...item, title:item.title === '所有成员' ? $t((item as unknown as {title:string}).title):item.title }as TransferItem); - flatten(item.children,res); - }); - } - const res:TransferItem[] =[] - flatten(dataSource,res); - return res - },[ - dataSource, state.language - ]) - - - const translatedDataSource = useMemo(()=>dataSource.map((item)=>({ - ...item, - name:item.name === '所有成员' ? $t((item as unknown as {name:string}).name):item.name, - })),[dataSource, state.language]) - - - - let memo: Record = {}; - - const handlerFilterOption = (inputValue: string, item: any, parentResult: boolean = false, childrenSet: Set = new Set()): boolean => { - const cacheKey = `${inputValue}_${item.key}`; - if (memo[cacheKey]) { - return memo[cacheKey]; - } - - childrenSet.add(item.key); - let result = item.title.includes(inputValue) || parentResult - if (item.children) { - for (const child of item.children) { - if (handlerFilterOption(inputValue, child, result,childrenSet)) { - result = true; - } - } - } - - if (result) { - memo[cacheKey] = result; - childrenSet.forEach((key) => { - memo[`${inputValue}_${key}`] = result; + return { + ...item, + title, + isLeaf:true, + disableCheckbox:disabledData.indexOf(item.key as string) !== -1 + }; }); - } - return result; - }; + console.log(searchWord, dataSource) + return loop(dataSource); + },[dataSource, state.language, searchWord]) + + const getInitExpandKeys = (data:T[], expandKeys:string[] = [])=>{ + data.forEach((item)=>{ + if(item.children?.length){ + expandKeys.push(item.key as string) + getInitExpandKeys(item.children,expandKeys) + } + }) + return expandKeys + } const getDataSource = ()=>{ setLoading(true) request && request().then((res)=>{ const {data,success} = res setDataSource(success? data : []) + setExpandedKeys(getInitExpandKeys(success? data:[])) }).finally(()=>{setLoading(false)}) -} + } -useEffect(() => { - getDataSource() - const handleResize = () => { - setTableHeight(window.innerHeight * 80 / 100 - 64 - 72 - 56 - 16 -3) - }; - const debouncedHandleResize = debounce(handleResize, 200); - - // 监听窗口大小变化 - window.addEventListener('resize', debouncedHandleResize); - handleResize(); - return () => { - window.removeEventListener('resize', debouncedHandleResize); - }; -}, []); + useEffect(() => { + getDataSource() + }, []); return (
} spinning={loading} className=''> - setSearchWord(e.target.value)} value={searchWord} /> + {setTargetKeys(e); + onSelect(((e as string[])?.filter(x=>disabledData.indexOf(x as string) === -1))||[])}} + onExpand={setExpandedKeys} + treeData={translatedDataSource} + blockNode + /> + + {/* { memo = {}; @@ -266,7 +194,7 @@ useEffect(() => { ); } }} - + */}
); diff --git a/frontend/packages/core/src/App.css b/frontend/packages/core/src/App.css index d50fdc28..9afb2c31 100644 --- a/frontend/packages/core/src/App.css +++ b/frontend/packages/core/src/App.css @@ -290,3 +290,8 @@ a{ transition: background-color 0s 600000s, color 0s 600000s !important; } } + + .ant-select-selection-overflow-item:first-child { + max-width: calc(100% - 60px); + margin-right: 4px; + } \ No newline at end of file diff --git a/frontend/packages/core/src/pages/member/MemberDropdownModal.tsx b/frontend/packages/core/src/pages/member/MemberDropdownModal.tsx index d0c1a6f4..5d4cbe52 100644 --- a/frontend/packages/core/src/pages/member/MemberDropdownModal.tsx +++ b/frontend/packages/core/src/pages/member/MemberDropdownModal.tsx @@ -117,7 +117,6 @@ export const MemberDropdownModal = forwardRef
((props,ref) => { const [managerOption, setManagerOption] = useState([]) const { setBreadcrumb} = useBreadcrumb() const { setTeamInfo } =useTeamContext() - const {checkPermission,accessInit} = useGlobalContext() + const {checkPermission,accessInit,state} = useGlobalContext() const pageType= useMemo(()=>{ if(!accessInit) return 'myteam' return checkPermission('system.workspace.team.view_all') ? 'manage' : 'myteam' @@ -128,7 +128,10 @@ const TeamConfig= forwardRef((props,ref) => { getTeamInfo(); } else { setOnEdit(false); - form.setFieldsValue({id:uuidv4()}); // 清空 initialValues + form.setFieldsValue( + {id:uuidv4(), + master:state?.userData?.uid + }); // 清空 initialValues } return (form.setFieldsValue({})) }, [teamId]); diff --git a/frontend/packages/core/src/pages/team/TeamInsideMember.tsx b/frontend/packages/core/src/pages/team/TeamInsideMember.tsx index 0c61cc18..81836fb1 100644 --- a/frontend/packages/core/src/pages/team/TeamInsideMember.tsx +++ b/frontend/packages/core/src/pages/team/TeamInsideMember.tsx @@ -273,7 +273,6 @@ const TeamInsideMember:FC = ()=>{ },[ state.language,roleList]) useEffect(() => { - getRoleList() setBreadcrumb([ {title:{$t('团队')}}, {title:$t('成员')} @@ -281,6 +280,11 @@ const TeamInsideMember:FC = ()=>{ manualReloadTable() }, [teamId]); + + useEffect(()=>{ + getRoleList() + },[state.language]) + const treeDisabledData = useMemo(()=>{ return [...allMemberIds,...allMemberSelectedDepartIds]},[allMemberIds,allMemberSelectedDepartIds]) return ( @@ -303,7 +307,7 @@ const TeamInsideMember:FC = ()=>{ title={$t("添加成员")} open={modalVisible} destroyOnClose={true} - width={900} + width={600} onCancel={() => cleanModalData()} maskClosable={false} footer={[ @@ -327,10 +331,9 @@ const TeamInsideMember:FC = ()=>{ disabledData={treeDisabledData} request={()=>getDepartmentMemberList()} onSelect={(selectedData: Set) => { - const memberKeyFromModal = Array.from(selectedData)?.filter(x => allMemberIds.indexOf(x) === -1 &&selectableMemberIds.has(x)) || []; - setAddMemberBtnDisabled((memberKeyFromModal.length === 0)); + setAddMemberBtnDisabled((selectedData.length === 0)); }} - searchPlaceholder={$t("搜索用户名、邮箱")} + searchPlaceholder={$t("搜索用户名")} />