feat:团队列表
This commit is contained in:
parent
cf68c5e915
commit
55ffba0953
|
@ -29,6 +29,7 @@ export default function Layout({children}: { children: React.ReactNode }) {
|
|||
},
|
||||
},
|
||||
token: {
|
||||
controlItemBgHover:"#4096ff",
|
||||
controlItemBgActiveHover:"#4096ff",
|
||||
controlItemBgActive:"#4096ff"
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
updateStepItemIndexAPI
|
||||
} from "@/components/service/StepSort";
|
||||
import {QuestionCircleOutlined} from "@ant-design/icons";
|
||||
import {copyToClipboard} from "@/lib/copyToClipboard";
|
||||
|
||||
const reorder = (list: TaskStepSortVO[], startIndex: number, endIndex: number) => {
|
||||
const result = Array.from(list);
|
||||
|
@ -42,7 +43,12 @@ const StepSort = (props: { taskId: string, stepList: TaskStepSortVO[] }) => {
|
|||
const [modalText, setModalText] = useState<TaskStepSortOperateVO>(initModalText);
|
||||
const items: MenuProps['items'] = [
|
||||
{
|
||||
key: "0", label: "上方插入", onClick: () => {
|
||||
key: "0", label: "复制", onClick: () => {
|
||||
copyToClipboard(clickTaskSortItem?.stepDesc || "")
|
||||
// copyToClipboard(clickTaskSortItem?.stepDesc ?? "")
|
||||
}
|
||||
},{
|
||||
key: "1", label: "上方插入", onClick: () => {
|
||||
setDialogueOpen(true)
|
||||
setModalText({
|
||||
id: "",
|
||||
|
@ -56,7 +62,7 @@ const StepSort = (props: { taskId: string, stepList: TaskStepSortVO[] }) => {
|
|||
}
|
||||
},
|
||||
{
|
||||
key: "1", label: "下方插入", onClick: () => {
|
||||
key: "2", label: "下方插入", onClick: () => {
|
||||
setDialogueOpen(true)
|
||||
setModalText({
|
||||
id: "",
|
||||
|
@ -70,13 +76,13 @@ const StepSort = (props: { taskId: string, stepList: TaskStepSortVO[] }) => {
|
|||
}
|
||||
},
|
||||
{
|
||||
key: "2", label: "修改步骤", onClick: () => {
|
||||
key: "3", label: "修改步骤", onClick: () => {
|
||||
setDialogueOpen(true)
|
||||
setModalText(clickTaskSortItem!)
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "3", label:
|
||||
key: "4", label:
|
||||
<Popconfirm
|
||||
title="删除步骤"
|
||||
description="确认要删除步骤?"
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
import React, {Fragment, useEffect, useRef, useState} from "react";
|
||||
import {Button, Modal, TablePaginationConfig} from "antd";
|
||||
import {ActionType, ProColumns, ProTable} from "@ant-design/pro-components";
|
||||
|
||||
import {Params} from "next/dist/shared/lib/router/utils/route-matcher";
|
||||
import {TeamMemberVO} from "@/components/type/Share.d";
|
||||
import type {FilterValue, SorterResult, TableCurrentDataSource} from "antd/es/table/interface";
|
||||
import {listTeamMemberAPI} from "@/components/service/Share";
|
||||
|
||||
const TeamMember = (props: { taskId: string }) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const onClose = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
const ref = useRef<ActionType>();
|
||||
|
||||
const [userList, setUserList] = React.useState<TeamMemberVO[]>([]);
|
||||
const [totalUserList, setTotalUserList] = React.useState<TeamMemberVO[]>([]);
|
||||
const [totalElement, setTotalElement] = React.useState(0);
|
||||
const [loading, setLoading] = React.useState(false);
|
||||
useEffect(() => {
|
||||
if (open){
|
||||
setLoading(true);
|
||||
listTeamMemberAPI(props.taskId).then((res)=>{
|
||||
if (res.data.status.success){
|
||||
setUserList(res.data.data.splice(0,10))
|
||||
setTotalUserList(res.data.data)
|
||||
setTotalElement(res.data.data.length)
|
||||
setTimeout(()=>{ref.current?.reload()},100)
|
||||
}
|
||||
setLoading(false)
|
||||
})
|
||||
}
|
||||
},[open])
|
||||
const columns: ProColumns<TeamMemberVO>[] = [
|
||||
{
|
||||
title: 'ID',
|
||||
key: 'username',
|
||||
dataIndex: 'username',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '昵称',
|
||||
key: 'nickname',
|
||||
dataIndex: 'nickname',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'operate',
|
||||
width: 120,
|
||||
valueType: 'option',
|
||||
render: () => [<Button key="1">操作</Button>],
|
||||
},
|
||||
];
|
||||
return (
|
||||
<Fragment>
|
||||
<Button type="primary" onClick={() => setOpen(!open)}>
|
||||
查看团队
|
||||
</Button>
|
||||
<Modal
|
||||
title="团队成员"
|
||||
closable={{'aria-label': 'Custom Close Button'}}
|
||||
open={open}
|
||||
destroyOnClose={true}
|
||||
footer={null}
|
||||
onCancel={onClose}
|
||||
>
|
||||
<ProTable<TeamMemberVO, Params>
|
||||
actionRef={ref}
|
||||
search={false}
|
||||
toolBarRender={false}
|
||||
loading={loading}
|
||||
columns={columns}
|
||||
dataSource={userList}
|
||||
// request={(params, sorter, filter) => {
|
||||
// // 表单搜索项会从 params 传入,传递给后端接口。
|
||||
// console.log(params, sorter, filter);
|
||||
// return Promise.resolve({
|
||||
// data: userList,
|
||||
// success: true,
|
||||
// });
|
||||
// }}
|
||||
/* Pagination */
|
||||
pagination={{
|
||||
defaultPageSize:10,
|
||||
defaultCurrent:1,
|
||||
total: totalElement,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
showTotal: (total) => `总共 ${total} 条`
|
||||
}}
|
||||
onChange={(pagination: TablePaginationConfig, filters: Record<string, FilterValue | null>,
|
||||
sorter: SorterResult<TeamMemberVO> | SorterResult<TeamMemberVO>[], extra:
|
||||
TableCurrentDataSource<TeamMemberVO>) => {
|
||||
setUserList(totalUserList.splice((pagination.current??1-1)*(pagination.pageSize??10),pagination.pageSize))
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
</Fragment>)
|
||||
}
|
||||
export default TeamMember;
|
|
@ -1,9 +1,12 @@
|
|||
import {AxiosResponse} from "axios";
|
||||
import {ResponseVO} from "@/lib/definitions";
|
||||
import {httpReq} from "@/utils/axiosReq";
|
||||
import {ShareVO} from "@/components/type/Share.d";
|
||||
import {ShareVO, TeamMemberVO} from "@/components/type/Share.d";
|
||||
|
||||
export const addTaskPassAPI= (data:ShareVO):Promise<AxiosResponse<ResponseVO<ShareVO>>> =>{
|
||||
return httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + "/task/pass",
|
||||
data)
|
||||
}
|
||||
export const listTeamMemberAPI = (taskId:string):Promise<AxiosResponse<ResponseVO<TeamMemberVO[]>>> =>{
|
||||
return httpReq.get(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + `/task/team/member/list?taskId=${taskId}`)
|
||||
}
|
|
@ -1 +1,12 @@
|
|||
export interface ShareVO { taskId: string, pass: string, joinCheck: string ,id?:string}
|
||||
export interface ShareVO { taskId: string, pass: string, joinCheck: string ,id?:string}
|
||||
|
||||
export interface TeamMemberVO {
|
||||
id:string,
|
||||
userId:string,
|
||||
username:string,
|
||||
nickname:string,
|
||||
userState:string,
|
||||
userRole:string,
|
||||
taskId:string,
|
||||
fId:string,
|
||||
}
|
|
@ -47,9 +47,10 @@ class OperationButton extends React.Component<OperationButtonProps, OperationMod
|
|||
render() {
|
||||
const handleCancel = () => {
|
||||
this.setState({...this.state, openModal: false})
|
||||
if (this.state.operationId !== OPERATION_BUTTON_TYPE.DETAIL) {
|
||||
this.props.refreshDate?.()
|
||||
}
|
||||
}
|
||||
const closeAndReloadData = () => {
|
||||
this.setState({...this.state, openModal: false})
|
||||
this.props.refreshDate?.()
|
||||
}
|
||||
const onClick: MenuProps['onClick'] = ({key}) => {
|
||||
console.log(key)
|
||||
|
@ -156,6 +157,7 @@ class OperationButton extends React.Component<OperationButtonProps, OperationMod
|
|||
key: OPERATION_BUTTON_TYPE.UPDATE_PRIORITY,
|
||||
label: <a onClick={(e) => {
|
||||
this.setState({updatePriority: true})
|
||||
console.log("修改优先级",this.state.priority)
|
||||
}}>修改优先级</a>,
|
||||
},
|
||||
{
|
||||
|
@ -213,7 +215,8 @@ class OperationButton extends React.Component<OperationButtonProps, OperationMod
|
|||
this.state.operationId === OPERATION_BUTTON_TYPE.ADD_CHILD ? '添加支线任务' :
|
||||
this.state.operationId === OPERATION_BUTTON_TYPE.UPDATE ? '修改任务' : '未知操作'}
|
||||
open={this.state.openModal}
|
||||
reloadData={handleCancel}/>}
|
||||
closeOpen={handleCancel}
|
||||
reloadData={closeAndReloadData}/>}
|
||||
</Fragment>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import ClickRecord from "@/components/ClickRecord";
|
|||
import onceConsumeList from "@/components/constant/onceConsumeList.json"
|
||||
import {onceConsumerRead} from "@/utils/codeToReadName";
|
||||
import style from "@/ui/task/project/DetailModelForm.module.css"
|
||||
import TeamMember from "@/components/TeamMember";
|
||||
export type DetailModelFormProps = {
|
||||
// 当前内容id
|
||||
itemId?: string,
|
||||
|
@ -51,9 +52,10 @@ export type DetailModelFormProps = {
|
|||
export type PidSelectTree = { label: string; value: string; pid: string; children?: PidSelectTree[] }
|
||||
|
||||
export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||
console.log("DetailModelForm:props:", props)
|
||||
|
||||
const [form] = Form.useForm<DataType>();
|
||||
const [requestTask, setRequestTask] = useState<DataType>()
|
||||
console.log("DetailModelForm:props:", props,requestTask)
|
||||
const [editFormDisable, setEditFormDisable] = useState(props.operationId === OPERATION_BUTTON_TYPE.DETAIL)
|
||||
// 团队第一层 pid必须为0
|
||||
const [taskType, setTaskType] = useState('0')
|
||||
|
@ -87,6 +89,8 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
console.log("form.setFieldsValue(task.data)" + JSON.stringify(task.data))
|
||||
} else {
|
||||
message.error(task.status.message);
|
||||
setRequestTask(undefined)
|
||||
form.resetFields()
|
||||
props.reloadData?.()
|
||||
}
|
||||
}).finally(() => {
|
||||
|
@ -141,6 +145,8 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
destroyOnClose: true,
|
||||
maskClosable: false,
|
||||
onCancel: () => {
|
||||
setRequestTask(undefined)
|
||||
form.resetFields()
|
||||
props.reloadData?.();
|
||||
},
|
||||
}}
|
||||
|
@ -170,6 +176,8 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
console.log('response', response)
|
||||
if (response.status.success) {
|
||||
message.success("删除任务成功:" + response.data)
|
||||
setRequestTask(undefined)
|
||||
form.resetFields()
|
||||
props.reloadData?.()
|
||||
}
|
||||
}));
|
||||
|
@ -191,6 +199,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
} else {
|
||||
if (editFormDisable && taskType == '1') {
|
||||
result.push(<ShareOption taskId={props.itemId!}/>)
|
||||
result.push(<TeamMember taskId={props.itemId!}/> )
|
||||
}
|
||||
result.push(<Button type="primary" key="close"
|
||||
onClick={() => props.closeOpen?.()}>关闭</Button>)
|
||||
|
@ -269,6 +278,8 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
// 树任务重新刷新
|
||||
// 四象限任务重新刷新
|
||||
// 如果可以直接更新列表而不请求。。。。。。
|
||||
setRequestTask(undefined)
|
||||
form.resetFields()
|
||||
props.reloadData?.()
|
||||
result = true
|
||||
} else {
|
||||
|
@ -289,6 +300,8 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
// 如果可以直接更新列表而不请求。。。。。。
|
||||
console.log('props.reloadData?.()', props.reloadData)
|
||||
result = (taskType != '1')
|
||||
setRequestTask(undefined)
|
||||
form.resetFields()
|
||||
props.reloadData?.()
|
||||
} else {
|
||||
message.error(response.data.status.message)
|
||||
|
|
|
@ -11,4 +11,24 @@
|
|||
}
|
||||
.ant-form-item .ant-form-item-label{
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.text-ellipsis {
|
||||
/* 单行省略 */
|
||||
/*width: 100%;*/
|
||||
/*box-sizing: border-box;*/
|
||||
/*white-space: nowrap;*/
|
||||
/*overflow: hidden;*/
|
||||
/*text-overflow: ellipsis;*/
|
||||
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
line-height: 1.5em; /* 根据实际字体大小调整 */
|
||||
max-height: 3em; /* 2行 x 1.5em */
|
||||
word-break: break-word; /* 允许长单词换行 */
|
||||
}
|
|
@ -5,11 +5,11 @@ import {
|
|||
} from '@ant-design/icons';
|
||||
import type {ActionType, FormInstance, ProColumns, ProFormInstance} from '@ant-design/pro-components';
|
||||
import {ProTable, TableDropdown} from '@ant-design/pro-components';
|
||||
import {Button, DatePicker, Dropdown, Space, Switch, Tag, Tooltip} from 'antd';
|
||||
import { DatePicker, Dropdown, Space, Switch, Tag, Tooltip} from 'antd';
|
||||
import React, {Fragment, useContext, useEffect, useRef} from 'react';
|
||||
import {DataType} from "@/lib/definitions";
|
||||
import {
|
||||
getTaskTreeResult, getTaskTreeResultAPI,
|
||||
getTaskTreeResultAPI,
|
||||
OPERATION_BUTTON_TYPE,
|
||||
taskPriorityList,
|
||||
taskStateList,
|
||||
|
@ -63,6 +63,11 @@ const TreeTablePro: React.FC = (props:{joinId?:string}) => {
|
|||
key: 'description',
|
||||
title: '任务描述',
|
||||
dataIndex: 'description',
|
||||
render: (_, record) => {
|
||||
return <Tooltip placement="topLeft" title={record.description}>
|
||||
<div className='text-ellipsis'>{record.description}</div>
|
||||
</Tooltip>
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'priority',
|
||||
|
@ -152,6 +157,7 @@ const TreeTablePro: React.FC = (props:{joinId?:string}) => {
|
|||
title: '操作',
|
||||
valueType: 'option',
|
||||
render: (_, record) => <OperationButton itemId={record.id} itemName={record.name} pid={record.pid} pPid={record.pPid}
|
||||
priority={record.priority}
|
||||
refreshDate={() => {
|
||||
actionRef.current?.reload(false);
|
||||
}}/>,
|
||||
|
|
Loading…
Reference in New Issue