feat:去除四象限滚动条
This commit is contained in:
parent
47aeb7c228
commit
135bf4ff41
|
@ -12,7 +12,7 @@
|
|||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
/docker/out/
|
||||
# production
|
||||
/build
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
"react-big-calendar": "^1.12.2",
|
||||
"react-device-detect": "^2.2.3",
|
||||
"react-dom": "^18",
|
||||
"react-virtualized": "^9.22.6",
|
||||
"sass": "^1.77.3",
|
||||
"tailwindcss": "3.3.3"
|
||||
},
|
||||
|
@ -31,6 +32,7 @@
|
|||
"@types/react": "^18",
|
||||
"@types/react-big-calendar": "^1.8.9",
|
||||
"@types/react-dom": "^18",
|
||||
"@types/react-virtualized": "^9.22.2",
|
||||
"@vercel/style-guide": "^5.0.1",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.2.29",
|
||||
|
@ -1647,6 +1649,16 @@
|
|||
"redux": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-virtualized": {
|
||||
"version": "9.22.2",
|
||||
"resolved": "https://registry.npmmirror.com/@types/react-virtualized/-/react-virtualized-9.22.2.tgz",
|
||||
"integrity": "sha512-0Eg/ME3OHYWGxs+/n4VelfYrhXssireZaa1Uqj5SEkTpSaBu5ctFGOCVxcOqpGXRiEdrk/7uho9tlZaryCIjHA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/scheduler": {
|
||||
"version": "0.16.8",
|
||||
"resolved": "https://registry.npmmirror.com/@types/scheduler/-/scheduler-0.16.8.tgz",
|
||||
|
@ -6318,6 +6330,23 @@
|
|||
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/react-virtualized": {
|
||||
"version": "9.22.6",
|
||||
"resolved": "https://registry.npmmirror.com/react-virtualized/-/react-virtualized-9.22.6.tgz",
|
||||
"integrity": "sha512-U5j7KuUQt3AaMatlMJ0UJddqSiX+Km0YJxSqbAzIiGw5EmNz0khMyqP2hzgu4+QUtm+QPIrxzUX4raJxmVJnHg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.7.2",
|
||||
"clsx": "^1.0.4",
|
||||
"dom-helpers": "^5.1.3",
|
||||
"loose-envify": "^1.4.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-lifecycles-compat": "^3.0.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/reactcss": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/reactcss/-/reactcss-1.2.3.tgz",
|
||||
|
@ -8919,6 +8948,16 @@
|
|||
"redux": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@types/react-virtualized": {
|
||||
"version": "9.22.2",
|
||||
"resolved": "https://registry.npmmirror.com/@types/react-virtualized/-/react-virtualized-9.22.2.tgz",
|
||||
"integrity": "sha512-0Eg/ME3OHYWGxs+/n4VelfYrhXssireZaa1Uqj5SEkTpSaBu5ctFGOCVxcOqpGXRiEdrk/7uho9tlZaryCIjHA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/scheduler": {
|
||||
"version": "0.16.8",
|
||||
"resolved": "https://registry.npmmirror.com/@types/scheduler/-/scheduler-0.16.8.tgz",
|
||||
|
@ -12437,6 +12476,19 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"react-virtualized": {
|
||||
"version": "9.22.6",
|
||||
"resolved": "https://registry.npmmirror.com/react-virtualized/-/react-virtualized-9.22.6.tgz",
|
||||
"integrity": "sha512-U5j7KuUQt3AaMatlMJ0UJddqSiX+Km0YJxSqbAzIiGw5EmNz0khMyqP2hzgu4+QUtm+QPIrxzUX4raJxmVJnHg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.7.2",
|
||||
"clsx": "^1.0.4",
|
||||
"dom-helpers": "^5.1.3",
|
||||
"loose-envify": "^1.4.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-lifecycles-compat": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"reactcss": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/reactcss/-/reactcss-1.2.3.tgz",
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"react-big-calendar": "^1.12.2",
|
||||
"react-device-detect": "^2.2.3",
|
||||
"react-dom": "^18",
|
||||
"react-virtualized": "^9.22.6",
|
||||
"sass": "^1.77.3",
|
||||
"tailwindcss": "3.3.3"
|
||||
},
|
||||
|
@ -32,6 +33,7 @@
|
|||
"@types/react": "^18",
|
||||
"@types/react-big-calendar": "^1.8.9",
|
||||
"@types/react-dom": "^18",
|
||||
"@types/react-virtualized": "^9.22.2",
|
||||
"@vercel/style-guide": "^5.0.1",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.2.29",
|
||||
|
|
|
@ -21,8 +21,11 @@ export default function RootLayout({
|
|||
<title>任务管理</title>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<script src="/static/iconfont.js"></script>
|
||||
{/*FOUC,Flash of Unstyled Content*/}
|
||||
{/*<link rel="preload" href="https://cdn.jsdelivr.net/npm/antd/dist/antd.min.css" as="style"/>*/}
|
||||
{/*<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/antd/dist/antd.min.css"/>*/}
|
||||
</head>
|
||||
<body style={{margin: 0,padding:0,maxHeight:"100vh",overflow:"hidden"}}>{children}</body>
|
||||
<body style={{margin: 0, padding: 0, maxHeight: "100vh", overflow: "hidden"}}>{children}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
* A layout is UI that is shared between multiple routes. On navigation, layouts preserve state, remain interactive, and do not re-render.
|
||||
*/
|
||||
'use client'
|
||||
import React, { useState} from 'react';
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {DragDropContext, DropResult} from 'react-beautiful-dnd';
|
||||
import {DroppableTable} from "@/ui/task/drag/DroppableTable";
|
||||
import {DataType, Request} from "@/lib/definitions";
|
||||
import {useEffect} from "react";
|
||||
import {TaskSelectVO} from "@/lib/task/drag/data";
|
||||
import {selectTaskAPI} from "@/lib/task/drag/service";
|
||||
|
||||
|
@ -14,13 +13,13 @@ export default function Layout({children}: { children: React.ReactNode }) {
|
|||
const [allTaskList, setAllTaskList] = useState<DataType[]>([]);
|
||||
useEffect(() => {
|
||||
addData()
|
||||
},[])
|
||||
}, [])
|
||||
|
||||
async function addData() {
|
||||
const requestParam: Request<TaskSelectVO> = {
|
||||
pageSize: 1000,
|
||||
pageNumber: 1,
|
||||
data: {state:'9'}
|
||||
data: {state: '9'}
|
||||
}
|
||||
const res = await selectTaskAPI(requestParam)
|
||||
setAllTaskList(res.data.content)
|
||||
|
@ -41,9 +40,8 @@ export default function Layout({children}: { children: React.ReactNode }) {
|
|||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
<div style={{display: 'flex',flexWrap: 'wrap',boxSizing: 'border-box',width:'100vw'}}>
|
||||
return (<div style={{display: 'flex', flexWrap: 'wrap', boxSizing: 'border-box', width: '100vw'}}>
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
{/* 紧急重要 */}
|
||||
<DroppableTable tableCode='3' taskList={allTaskList.filter(task => task.priority == '3')}/>
|
||||
{/* 不紧急重要 */}
|
||||
|
@ -52,7 +50,7 @@ export default function Layout({children}: { children: React.ReactNode }) {
|
|||
<DroppableTable tableCode="1" taskList={allTaskList.filter(task => task.priority == '1')}/>
|
||||
{/* 不紧急不重要 */}
|
||||
<DroppableTable tableCode='0' taskList={allTaskList.filter(task => task.priority == '0')}/>
|
||||
</div>
|
||||
</DragDropContext>
|
||||
);
|
||||
</DragDropContext></div>
|
||||
)
|
||||
;
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
export default function Page() {
|
||||
return <p>Dashboard test</p>;
|
||||
}
|
|
@ -88,6 +88,15 @@ export async function deleteTaskAPI(id: string): Promise<ResponseVO<string>> {
|
|||
return response.data;
|
||||
}
|
||||
|
||||
export function getTaskState(code:string){
|
||||
return taskStateList.filter(taskState => code==taskState.code)[0];
|
||||
}
|
||||
export const TASK_TYPE:{label:string,value:string}[]=[
|
||||
{label:"常规",value:"0"},
|
||||
{label:"团队",value:"1"},
|
||||
{label:"顺序",value:"2"},
|
||||
{label:"周期",value:"3"}
|
||||
]
|
||||
//0,重要紧急红色,1,重要不紧急黄色,2,不重要紧急灰色,3不重要,不紧急绿色
|
||||
export const taskPriorityList: DictType[] = [
|
||||
{
|
||||
|
|
|
@ -31,3 +31,23 @@ html {
|
|||
overflow: hidden;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
.displayFlexRow{
|
||||
display: flex;
|
||||
justify-content: flex-start; /* 水平居中 */
|
||||
align-items: center; /* 垂直居中 */
|
||||
}
|
||||
|
||||
.displayFlexColumn{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start; /* 水平居中 */
|
||||
align-items: center; /* 垂直居中 */
|
||||
}
|
||||
.scrollHidden{
|
||||
overflow: auto;
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* IE和Edge */
|
||||
}
|
||||
.scrollHidden::-webkit-scrollbar {
|
||||
display: none; /* Chrome, Safari, Opera */
|
||||
}
|
|
@ -163,7 +163,7 @@ class OperationButton extends React.Component<OperationButtonProps, OperationMod
|
|||
},
|
||||
{
|
||||
key: OPERATION_BUTTON_TYPE.SHOW_FOUR,
|
||||
label: <Link href={"/task/four?pid=" + this.props.itemId}>四象限显示子任务</Link>,
|
||||
label: <Link href={"/task/drag?pid=" + this.props.itemId}>四象限显示子任务</Link>,
|
||||
},
|
||||
{
|
||||
key: OPERATION_BUTTON_TYPE.SHOW_CALENDAR,
|
||||
|
|
|
@ -43,9 +43,9 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
|
|||
}}>任务树</Button>
|
||||
}
|
||||
{
|
||||
!usePathname().startsWith("/task/four") &&
|
||||
!usePathname().startsWith("/task/drag") &&
|
||||
<Button type="primary" onClick={() => {
|
||||
replace("/task/four");
|
||||
replace("/task/drag");
|
||||
// setCurrentPath("/task/four");
|
||||
}}>四象限显示</Button>
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
|
|||
}
|
||||
{
|
||||
/*四相线需要状态时间*/
|
||||
usePathname().startsWith("/task/four") && <Fragment>
|
||||
usePathname().startsWith("/task/drag") && <Fragment>
|
||||
<span style={{whiteSpace: 'nowrap'}}>期望开始时间范围:</span>
|
||||
<RangePicker
|
||||
placeholder={['开始时间', '结束时间']}
|
||||
|
@ -114,6 +114,12 @@ export const TitleOperation: React.FC<TitleOperationProps> = ({
|
|||
/>
|
||||
</Fragment>
|
||||
}
|
||||
{
|
||||
/*日历需要状态*/
|
||||
!usePathname().startsWith("/task/project") && <Fragment>
|
||||
<Button>搜索</Button>
|
||||
</Fragment>
|
||||
}
|
||||
</Space>
|
||||
<svg style={{height: "32px", width: "32px", alignItems: "center"}} className="icon" aria-hidden="true">
|
||||
<use xlinkHref="#icon-user__easyico"></use>
|
||||
|
|
|
@ -1,176 +1,145 @@
|
|||
'use client'
|
||||
|
||||
import React, {CSSProperties, useEffect} from "react";
|
||||
import React, {CSSProperties} from "react";
|
||||
import {Draggable, Droppable} from "react-beautiful-dnd";
|
||||
import {ConfigProvider, Table, TableProps, Tooltip} from "antd";
|
||||
import {ConfigProvider, Tooltip} from "antd";
|
||||
import {DataType} from "@/lib/definitions";
|
||||
import './index.modules.css'
|
||||
import dayjs, {Dayjs} from "dayjs";
|
||||
import {taskPriorityList} from "@/lib/task/project/data";
|
||||
import dayjs from "dayjs";
|
||||
import {getTaskState, taskPriorityList} from "@/lib/task/project/data";
|
||||
import {List as VirtualizedList, AutoSizer} from "react-virtualized";
|
||||
import 'react-virtualized/styles.css';
|
||||
import OperationButton from "@/ui/task/OperationButton";
|
||||
|
||||
interface DroppableTableProps // extends DragDropContextProps
|
||||
{
|
||||
tableCode:string,
|
||||
taskList:DataType[]
|
||||
interface DroppableTableProps {
|
||||
tableCode: string,
|
||||
taskList: DataType[]
|
||||
}
|
||||
|
||||
export const DroppableTable: React.FC<DroppableTableProps> = (props) => {
|
||||
|
||||
const [stateName, setStateName] = React.useState("");
|
||||
useEffect(() => {
|
||||
if(props.tableCode=='0'){
|
||||
setStateName('不紧急不重要');
|
||||
}else if (props.tableCode=='1'){
|
||||
setStateName('紧急不重要');
|
||||
}else if (props.tableCode=='2'){
|
||||
setStateName('不紧急重要');
|
||||
}else if (props.tableCode=='3'){
|
||||
setStateName('紧急重要');
|
||||
export const DroppableTable = React.memo((props: DroppableTableProps) => {
|
||||
const stateName = React.useMemo(() => {
|
||||
switch (props.tableCode) {
|
||||
case '0':
|
||||
return '不紧急不重要';
|
||||
case '1':
|
||||
return '紧急不重要';
|
||||
case '2':
|
||||
return '不紧急重要';
|
||||
case '3':
|
||||
return '紧急重要';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}, [props]);
|
||||
const getItemStyle = (isDragging:any, draggableStyle:any):CSSProperties => {
|
||||
console.log({draggableStyle})
|
||||
return {
|
||||
// some basic styles to make the items look a bit nicer
|
||||
}, [props.tableCode]);
|
||||
|
||||
const getItemStyle = React.useCallback((isDragging: boolean, draggableStyle: any): CSSProperties => ({
|
||||
userSelect: "none",
|
||||
// change background colour if dragging
|
||||
background: isDragging ? "lightgreen" : "grey",
|
||||
// styles we need to apply on draggables
|
||||
background: isDragging ? "lightgreen" : "white",
|
||||
position: 'relative', // 确保 zIndex 生效
|
||||
zIndex: isDragging ? 2147483647 : 'auto', // 使用 'auto' 代替 0 可能更好
|
||||
...draggableStyle,
|
||||
height:80
|
||||
}};
|
||||
borderBottom: '1px solid #f0f0f0',
|
||||
boxSizing: 'border-box',
|
||||
// verticalAlign: 'middle',
|
||||
// textAlign: 'center',
|
||||
}), []);
|
||||
|
||||
const getListStyle = (isDraggingOver:boolean) => ({
|
||||
background: isDraggingOver ? "lightblue" : "lightgrey",
|
||||
overflow:'hidden'
|
||||
});
|
||||
const getListStyle = React.useCallback((isDraggingOver: boolean) => ({
|
||||
background: isDraggingOver ? "lightblue" : "white",
|
||||
height: 'calc((100vh - 42px)/2)',
|
||||
width: '50vw'
|
||||
}), []);
|
||||
|
||||
function isDayjs(obj: unknown): obj is Dayjs {
|
||||
return obj != null && typeof (obj as Dayjs).format === 'function';
|
||||
}
|
||||
const rowRenderer = React.useCallback(({index, key, style}: {
|
||||
index: number;
|
||||
key: string;
|
||||
style: React.CSSProperties
|
||||
}) => {
|
||||
const record = props.taskList[index];
|
||||
if (!record) return null;
|
||||
|
||||
// 渲染表格行
|
||||
// @ts-ignore
|
||||
const renderTableRow = (data: DataType[], droppableId: string): TableProps<Item>['components']['body']['row'] =>
|
||||
(props:any) => {
|
||||
// console.log({props, droppableId});
|
||||
const { children, ...restProps } = props;
|
||||
const record = data.find((item) => item.id === restProps['data-row-key']);
|
||||
const index = data.findIndex((item) => item.id === restProps['data-row-key']);
|
||||
if (!record) {
|
||||
// console.error('Invalid record at index:', index);
|
||||
return null; // 或者返回一个占位符
|
||||
}
|
||||
return (
|
||||
<Draggable key={record.id} draggableId={record.id} index={index}>
|
||||
{(provided,snapshot) => (
|
||||
<tr
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
style={getItemStyle(
|
||||
snapshot.isDragging,
|
||||
provided.draggableProps.style
|
||||
)}
|
||||
>
|
||||
{/*<td>{record.code}</td>*/}
|
||||
<td>{record.name}</td>
|
||||
<td>{record?.description}</td>
|
||||
<td>{record.state}</td>
|
||||
<td>起:{record.expectedStartTime? dayjs(record.expectedStartTime).format("YYYY-MM-DD HH:mm") :""}<br/>
|
||||
止:{record.expectedStartTime? dayjs(record.expectedStartTime).format("YYYY-MM-DD HH:mm") : ""}</td>
|
||||
</tr>
|
||||
)}
|
||||
</Draggable>
|
||||
);
|
||||
};
|
||||
const calculateScrollHeight = () => {
|
||||
// 计算50%视窗高度减去21px
|
||||
const height = `calc(50vh - 80px)`;
|
||||
return { y: height };
|
||||
};
|
||||
return (
|
||||
<Draggable key={record.id} draggableId={record.id} index={index}>
|
||||
{(provided, snapshot) => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
style={getItemStyle(snapshot.isDragging, {...provided.draggableProps.style, ...style})}
|
||||
className="virtualized-row displayFlexRow"
|
||||
>
|
||||
<div style={{width: '15%'}} className='displayFlexRow'>
|
||||
<Tooltip placement="topLeft" title={record.name} className='displayFlexRow'>
|
||||
<div className='displayFlexRow'>{record.name}</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div style={{width: '40%' , boxSizing: 'border-box', minWidth: 0}} className='displayFlexRow'>
|
||||
<Tooltip placement="topLeft" title={record.description}>
|
||||
<div className='displayFlexRow'>{record.description}</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div style={{
|
||||
width: '10%',
|
||||
}} className='displayFlexRow'>{getTaskState(record.state) ? getTaskState(record.state).name : ""}</div>
|
||||
<div style={{width: '25%'}} className='displayFlexColumn'>
|
||||
<div>起: {record.expectedStartTime ? dayjs(record.expectedStartTime).format("YYYY-MM-DD HH:mm") : ""}</div>
|
||||
<div>止: {record.expectedStartTime ? dayjs(record.expectedStartTime).format("YYYY-MM-DD HH:mm") : ""}</div>
|
||||
</div>
|
||||
<div style={{width: '10%'}} className='displayFlexRow'>
|
||||
<OperationButton itemId={record.id} priority={record.priority} pid={record.pid}
|
||||
pPid={record.pPid}/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
);
|
||||
}, [props.taskList, getItemStyle]);
|
||||
|
||||
const headerStyle = React.useMemo(() => ({
|
||||
backgroundColor: taskPriorityList.find((item) => item.code === props.tableCode)?.color,
|
||||
height: '55px',
|
||||
borderBottom: '1px solid #f0f0f0',
|
||||
fontWeight: 'bold'
|
||||
}), [props.tableCode]);
|
||||
|
||||
return (
|
||||
<Droppable droppableId={props.tableCode} key={props.tableCode} >
|
||||
{(provided,snapshot) => (
|
||||
<div ref={provided.innerRef}
|
||||
{...provided.droppableProps}
|
||||
style={getListStyle(snapshot.isDraggingOver)}
|
||||
className="droppable-table"
|
||||
<Droppable droppableId={props.tableCode} key={props.tableCode}>
|
||||
{(provided, snapshot) => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
{...provided.droppableProps}
|
||||
style={getListStyle(snapshot.isDraggingOver)}
|
||||
className="droppable-table"
|
||||
>
|
||||
<ConfigProvider
|
||||
theme={{
|
||||
components: {
|
||||
Table: {
|
||||
headerBg: taskPriorityList.find((item) => item.code === props.tableCode)?.color
|
||||
/* 这里是你的组件 token */
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Table<DataType>
|
||||
dataSource={props.taskList}
|
||||
scroll={calculateScrollHeight()}
|
||||
columns={[
|
||||
// {
|
||||
// title: '任务编码',
|
||||
// dataIndex: 'code',
|
||||
// key: 'code',
|
||||
// width: '10%',
|
||||
// },
|
||||
{
|
||||
title: stateName,
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
width: '10%',
|
||||
ellipsis: {
|
||||
showTitle: false,
|
||||
},
|
||||
render: (address) => (
|
||||
<Tooltip placement="topLeft" title={address}>
|
||||
{address}
|
||||
</Tooltip>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '任务描述',
|
||||
dataIndex: 'description',
|
||||
key: 'description',
|
||||
width: '20%',
|
||||
ellipsis: {
|
||||
showTitle: false,
|
||||
},
|
||||
render: (description) => (
|
||||
<Tooltip placement="topLeft" title={description}>
|
||||
{description}
|
||||
</Tooltip>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '任务状态',
|
||||
dataIndex: 'state',
|
||||
width: '5%',
|
||||
key: 'state',
|
||||
},
|
||||
{
|
||||
title: '期望时间',
|
||||
dataIndex: 'expectedStartTime',
|
||||
width: '10%',
|
||||
key: 'expectedStartTime',
|
||||
},
|
||||
]}
|
||||
rowKey="id"
|
||||
components={{
|
||||
body: {
|
||||
row: renderTableRow(props.taskList, props.tableCode),
|
||||
},
|
||||
}}
|
||||
pagination={false}
|
||||
/>
|
||||
<ConfigProvider>
|
||||
{/* 表头 */}
|
||||
<div style={headerStyle} className='displayFlexRow'>
|
||||
<div style={{width: '15%'}} className='displayFlexRow'>{stateName}</div>
|
||||
<div style={{width: '40%'}} className='displayFlexRow'>任务描述</div>
|
||||
<div style={{width: '15%'}} className='displayFlexRow'>任务状态</div>
|
||||
<div style={{width: '20%'}} className='displayFlexRow'>期望时间</div>
|
||||
<div style={{width: '10%'}} className='displayFlexRow'>操作</div>
|
||||
</div>
|
||||
{/* 虚拟列表主体 */}
|
||||
<div style={{height: 'calc(50vh - 76px)'}}>
|
||||
<AutoSizer>
|
||||
{({height, width}) => (
|
||||
<VirtualizedList
|
||||
className={"scrollHidden"}
|
||||
height={height}
|
||||
width={width}
|
||||
rowCount={props.taskList.length}
|
||||
rowHeight={80} // 与你的行高匹配
|
||||
rowRenderer={rowRenderer}
|
||||
overscanRowCount={8} // 预渲染的行数
|
||||
/>
|
||||
)}
|
||||
</AutoSizer>
|
||||
</div>
|
||||
</ConfigProvider>
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
)
|
||||
}
|
||||
});
|
|
@ -1,5 +1,36 @@
|
|||
.droppable-table{
|
||||
width: 50vw;
|
||||
height: calc(50vh - 21px);
|
||||
overflow-y: auto;
|
||||
.droppable-table {
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #f0f0f0;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.virtualized-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.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; /* 允许长单词换行 */
|
||||
}
|
||||
|
||||
/* 拖拽时的样式增强 */
|
||||
.ReactVirtualized__List {
|
||||
outline: none;
|
||||
}
|
|
@ -11,7 +11,7 @@ import React, {useEffect, useState} from "react";
|
|||
import {
|
||||
addTask, deleteTask, getTask,
|
||||
getTaskTreeResult,
|
||||
OPERATION_BUTTON_TYPE,
|
||||
OPERATION_BUTTON_TYPE, TASK_TYPE,
|
||||
taskPriorityList,
|
||||
taskStateList, updateTask
|
||||
} from "@/lib/task/project/data";
|
||||
|
@ -44,6 +44,8 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
const [form] = Form.useForm<DataType>();
|
||||
const [pid, setPid] = useState<string>(props.pid?props.pid:'0');
|
||||
const [editFormDisable, setEditFormDisable] = useState(props.operationId === OPERATION_BUTTON_TYPE.DETAIL)
|
||||
// 团队第一层 pid必须为0
|
||||
const [taskType, setTaskType] = useState('0')
|
||||
useEffect(() => {
|
||||
if (props.itemId!=undefined&&(
|
||||
props.operationId === OPERATION_BUTTON_TYPE.DETAIL || props.operationId === OPERATION_BUTTON_TYPE.UPDATE)) {
|
||||
|
@ -209,8 +211,31 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
<ProFormText width="sm" name="code" initialValue={props.itemId} hidden={true} label="任务编码" />
|
||||
<ProFormText width="sm" name="pPid" initialValue={props.pPid} hidden={true} label="祖宗id" />
|
||||
<ProForm.Group>
|
||||
<ProFormSelect
|
||||
required={true}
|
||||
options={TASK_TYPE}
|
||||
width="sm"
|
||||
name="taskType"
|
||||
label="任务类型"
|
||||
initialValue='0'
|
||||
disabled ={editFormDisable}
|
||||
onChange={(value:string, option)=>{
|
||||
setTaskType(value)
|
||||
}}
|
||||
/>
|
||||
<ProFormText
|
||||
required={true}
|
||||
hidden={taskType!='1'}
|
||||
width="sm"
|
||||
name="fName"
|
||||
label="团队名称"
|
||||
tooltip="最长为 10 位"
|
||||
placeholder="请输入团队名称"
|
||||
disabled ={editFormDisable}
|
||||
/>
|
||||
<ProFormTreeSelect
|
||||
width="md"
|
||||
hidden={taskType=='1'}
|
||||
width="sm"
|
||||
request={() =>{
|
||||
return getTaskTreeResult(JSON.stringify(
|
||||
{pageSize:1000,pageNumber:1,data:[{code:'pid',value:'0',operateType:'='},{code:'state',value:'8,9',operateType:'IN'},{code:'',value:true,operateType: "TREE"}]}
|
||||
|
@ -222,10 +247,11 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
disabled ={editFormDisable}
|
||||
/>
|
||||
<ProFormText
|
||||
width="md"
|
||||
required={true}
|
||||
width="sm"
|
||||
name="name"
|
||||
label="任务名称"
|
||||
tooltip="最长为 24 位"
|
||||
tooltip="最长为 10 位"
|
||||
placeholder="请输入任务名称"
|
||||
disabled ={editFormDisable}
|
||||
/>
|
||||
|
|
Loading…
Reference in New Issue