feat:窗口变动后日志高度自动更新
This commit is contained in:
parent
a2aced4c85
commit
24c01d4dc8
|
@ -1,13 +1,17 @@
|
|||
import React, {useEffect, useRef, useState} from 'react';
|
||||
import {Avatar, Dropdown, Input, List, MenuProps, message} from 'antd';
|
||||
import React, {Fragment, useEffect, useRef, useState} from 'react';
|
||||
import {Dropdown, List, MenuProps, message, Popconfirm} from 'antd';
|
||||
import VirtualList from 'rc-virtual-list';
|
||||
import {Button, Drawer} from 'antd';
|
||||
import {ListDiary, SelectDiary} from "@/components/type/Diary";
|
||||
import TextArea from "antd/es/input/TextArea";
|
||||
import style from "@/components/DiaryOption.module.css"
|
||||
import dayjs from "dayjs";
|
||||
import {addTaskLogAPI} from "@/components/service/Diary";
|
||||
import {addTaskLogAPI, deleteTaskLogByIdAPI, editEnableFlagAPI} from "@/components/service/Diary";
|
||||
import {ListRef} from "rc-virtual-list/lib/List";
|
||||
import {copyToClipboard} from "@/lib/copyToClipboard";
|
||||
import {useWindowSize} from "@/hooks/useWindowSize";
|
||||
import {DetailModelForm} from "@/ui/task/project/DetailModelForm";
|
||||
import {OPERATION_BUTTON_TYPE} from "@/lib/task/project/data";
|
||||
|
||||
const DiaryOption = (props: SelectDiary) => {
|
||||
// 抽屉 start
|
||||
|
@ -19,9 +23,13 @@ const DiaryOption = (props: SelectDiary) => {
|
|||
setOpen(false);
|
||||
};
|
||||
// 抽屉 end
|
||||
const [shouldScroll,setShouldScroll] = React.useState(true);
|
||||
const [shouldScroll, setShouldScroll] = React.useState(true);
|
||||
// 设置高度 start
|
||||
const { height } = useWindowSize();
|
||||
const [containerHeight, setContainerHeight] = useState(400);
|
||||
useEffect(() => {
|
||||
setDiaryList([])
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
// 使用 setTimeout 确保 Drawer 内容已渲染
|
||||
|
@ -47,7 +55,7 @@ const DiaryOption = (props: SelectDiary) => {
|
|||
// observer.observe(contentRef.current);
|
||||
//
|
||||
// return () => observer.disconnect();
|
||||
}, [open]);
|
||||
}, [open,height]);
|
||||
// 设置高度 end
|
||||
|
||||
// 头按钮设置 start
|
||||
|
@ -91,6 +99,9 @@ const DiaryOption = (props: SelectDiary) => {
|
|||
}
|
||||
|
||||
const appendData = (showMessage = true) => {
|
||||
if (!open){
|
||||
return
|
||||
}
|
||||
const fakeDataUrl = process.env.NEXT_PUBLIC_TODO_REQUEST_URL + `/task/message/diary/select`;
|
||||
fetch(fakeDataUrl, {
|
||||
method: 'POST', headers: {
|
||||
|
@ -118,9 +129,7 @@ const DiaryOption = (props: SelectDiary) => {
|
|||
|
||||
useEffect(() => {
|
||||
appendData(false);
|
||||
// 视口高度
|
||||
window.innerHeight
|
||||
}, []);
|
||||
}, [open]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("处理日志集合", diaryList)
|
||||
|
@ -171,13 +180,13 @@ const DiaryOption = (props: SelectDiary) => {
|
|||
|
||||
// 条件滚动
|
||||
useEffect(() => {
|
||||
console.log({shouldScroll},{listRef})
|
||||
console.log({shouldScroll}, {listRef})
|
||||
if (shouldScroll && listRef.current) {
|
||||
listRef.current.scrollTo({
|
||||
top: 99999,
|
||||
});
|
||||
}
|
||||
}, [diaryList, shouldScroll,open]);
|
||||
}, [diaryList, shouldScroll, open]);
|
||||
// 滚动处理 end
|
||||
// 点击操作 start
|
||||
const [clickTaskDiary, setClickTaskDiary] = useState<ListDiary>()
|
||||
|
@ -188,34 +197,103 @@ const DiaryOption = (props: SelectDiary) => {
|
|||
setClickTaskDiary(item)
|
||||
}
|
||||
}
|
||||
const items: MenuProps['items'] = [
|
||||
// 删除操作
|
||||
const [popConfirmOpen, setPopConfirmOpen] = useState(false);
|
||||
const [popConfirmLoading, setPopConfirmLoading] = useState(false);
|
||||
const popConfirmOk = () => {
|
||||
setPopConfirmLoading(true)
|
||||
if (clickTaskDiary){
|
||||
deleteTaskLogByIdAPI(clickTaskDiary.id).then(res=>{
|
||||
if (res.data.status.success){
|
||||
setDiaryList(diaryList.filter(taskLog => taskLog.id != clickTaskDiary.id))
|
||||
message.info("删除成功")
|
||||
setPopConfirmLoading(false)
|
||||
setPopConfirmOpen(false)
|
||||
}else {
|
||||
message.error(res.data.status.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
const handleCancel = () =>{
|
||||
setPopConfirmOpen(false)
|
||||
}
|
||||
|
||||
const editEnableFlag = (enableFlag:string) => {
|
||||
if (clickTaskDiary){
|
||||
editEnableFlagAPI(clickTaskDiary.id,enableFlag).then(res=>{
|
||||
if (res.data.status.success){
|
||||
setDiaryList(diaryList.map(taskLog => {
|
||||
if(taskLog.id == clickTaskDiary.id){
|
||||
taskLog.enableFlag = enableFlag;
|
||||
}
|
||||
return taskLog;
|
||||
}))
|
||||
message.info("设置成功")
|
||||
}else {
|
||||
message.error(res.data.status.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const [addTaskOpen,setAddTaskOpen] = useState(false)
|
||||
|
||||
const commonItems: MenuProps['items'] = [
|
||||
{
|
||||
label: '复制',
|
||||
key: '1',
|
||||
onClick: () => {
|
||||
copyToClipboard(clickTaskDiary!.description)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '失效',
|
||||
key: '2',
|
||||
},
|
||||
{
|
||||
label: '创建计划',
|
||||
key: '3',
|
||||
onClick:()=>{
|
||||
// 打开添加任务窗口
|
||||
setAddTaskOpen(true)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
key: '4',
|
||||
onClick: () => {
|
||||
setPopConfirmOpen(true)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '取消',
|
||||
key: '5',
|
||||
onClick:()=>{
|
||||
setClickTaskDiary(undefined)
|
||||
}
|
||||
},
|
||||
]
|
||||
const items: MenuProps['items'] = [
|
||||
];
|
||||
items.push(...commonItems)
|
||||
items.splice(1,0,{
|
||||
label: '失效',
|
||||
key: '2',
|
||||
onClick:()=>{
|
||||
editEnableFlag("0")
|
||||
},
|
||||
})
|
||||
const itemsEnable: MenuProps['items'] = [
|
||||
];
|
||||
itemsEnable.push(...commonItems)
|
||||
itemsEnable.splice(1,0,{
|
||||
label: '生效',
|
||||
key: '2',
|
||||
onClick:()=>{
|
||||
editEnableFlag("1")
|
||||
},
|
||||
})
|
||||
// 点击操作 end
|
||||
|
||||
return (
|
||||
<>
|
||||
<Fragment>
|
||||
<Button type="primary" onClick={showDrawer}>
|
||||
日志心得
|
||||
</Button>
|
||||
|
@ -309,26 +387,45 @@ const DiaryOption = (props: SelectDiary) => {
|
|||
</div>
|
||||
</div>
|
||||
: <div className={style.logTaskContent} key={item.id}>
|
||||
<Dropdown menu={{items}} trigger={['contextMenu']}>
|
||||
<div
|
||||
className={`${style.detailLine} ${item.id === clickTaskDiary?.id ? style.detailLineClick : ''}`}
|
||||
onClick={() => onClickTAskDiary(item, "L")}
|
||||
onContextMenu={() => onClickTAskDiary(item, "R")}>
|
||||
<text
|
||||
style={{
|
||||
textDecoration: item.enableFlag === '0' && currentIndex === 0 ? 'line-through' : '',
|
||||
whiteSpace: 'pre-line'
|
||||
}}>
|
||||
{item.description}
|
||||
</text>
|
||||
</div>
|
||||
<Dropdown menu={{items: (item.enableFlag == "1" ? items : itemsEnable)}}
|
||||
trigger={['contextMenu']}>
|
||||
<Popconfirm
|
||||
title="警告"
|
||||
description={`确认要删除日志:${item.description.length > 5 ? item.description.substring(0, 5) + '...' : item.description}?`}
|
||||
open={popConfirmOpen&&clickTaskDiary?.id==item.id}
|
||||
onConfirm={popConfirmOk}
|
||||
okButtonProps={{loading: popConfirmLoading}}
|
||||
onCancel={handleCancel}
|
||||
okText="Yes"
|
||||
cancelText="No"
|
||||
>
|
||||
<div
|
||||
className={`${style.detailLine} ${item.id === clickTaskDiary?.id ? style.detailLineClick : ''}`}
|
||||
onClick={() => onClickTAskDiary(item, "L")}
|
||||
onContextMenu={() => onClickTAskDiary(item, "R")}>
|
||||
<text
|
||||
style={{
|
||||
textDecoration: item.enableFlag === '0' && currentIndex === 0 ? 'line-through' : '',
|
||||
whiteSpace: 'pre-line'
|
||||
}}>
|
||||
{item.description}
|
||||
</text>
|
||||
</div>
|
||||
</Popconfirm>
|
||||
</Dropdown>
|
||||
</div>
|
||||
)}
|
||||
</VirtualList>
|
||||
</List>
|
||||
</Drawer>
|
||||
</>
|
||||
{addTaskOpen&&<DetailModelForm pid={props.taskId}
|
||||
operationId={OPERATION_BUTTON_TYPE.ADD_CHILD}
|
||||
description={"新增计划"}
|
||||
open={addTaskOpen}
|
||||
haveButton={false}
|
||||
reloadData={()=>setAddTaskOpen(false)}
|
||||
/>}
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
export default DiaryOption;
|
|
@ -7,3 +7,9 @@ export const addTaskLogAPI= (data:AddDiary):Promise<AxiosResponse<ResponseVO<Lis
|
|||
return httpReq.post(process.env.NEXT_PUBLIC_TODO_REQUEST_URL + "/task/message/diary",
|
||||
data)
|
||||
}
|
||||
export const deleteTaskLogByIdAPI = (id:string) => {
|
||||
return httpReq.delete( process.env.NEXT_PUBLIC_TODO_REQUEST_URL+`/task/message/diary?id=${id}`);
|
||||
}
|
||||
export const editEnableFlagAPI = (id:string,enableFlag:string) => {
|
||||
return httpReq.put( process.env.NEXT_PUBLIC_TODO_REQUEST_URL+`/task/message/diary/enable?id=${id}&enableFlag=${enableFlag}`);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
|
||||
export function useWindowSize() {
|
||||
const [windowSize, setWindowSize] = useState({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
setWindowSize({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
});
|
||||
};
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
}, []);
|
||||
|
||||
return windowSize;
|
||||
}
|
|
@ -2,7 +2,7 @@ import {PlusOutlined, QuestionCircleOutlined} from '@ant-design/icons';
|
|||
import {
|
||||
ModalForm,
|
||||
ProForm,
|
||||
ProFormDateRangePicker, ProFormDateTimeRangePicker,
|
||||
ProFormDateTimeRangePicker,
|
||||
ProFormSelect,
|
||||
ProFormText, ProFormTextArea, ProFormTreeSelect,
|
||||
} from '@ant-design/pro-components';
|
||||
|
@ -29,6 +29,8 @@ export type DetailModelFormProps = {
|
|||
operationId: OPERATION_BUTTON_TYPE,
|
||||
// 标题描述
|
||||
description: string,
|
||||
// 任务内容描述
|
||||
taskContent?:string,
|
||||
// 是否打开界面,用于非按钮操作
|
||||
open: boolean,
|
||||
// 使用按钮操作
|
||||
|
@ -42,12 +44,14 @@ export type PidSelectTree = { label: string; value: string; pid: string; childre
|
|||
|
||||
export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
||||
console.log("DetailModelForm:props:", props)
|
||||
const [closeButton,setCloseButton] =useState(false)
|
||||
const [form] = Form.useForm<DataType>();
|
||||
const [requestTask,setRequestTask]=useState<DataType>()
|
||||
const [editFormDisable, setEditFormDisable] = useState(props.operationId === OPERATION_BUTTON_TYPE.DETAIL)
|
||||
// 团队第一层 pid必须为0
|
||||
const [taskType, setTaskType] = useState('0')
|
||||
useEffect(() => {
|
||||
setCloseButton(false)
|
||||
if (props.itemId != undefined && (
|
||||
props.operationId === OPERATION_BUTTON_TYPE.DETAIL || props.operationId === OPERATION_BUTTON_TYPE.UPDATE)) {
|
||||
getTask(props.itemId).then(task => {
|
||||
|
@ -100,7 +104,7 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
return (
|
||||
<ModalForm<DataType>
|
||||
title={props.description}
|
||||
open={props.open && !props.haveButton}
|
||||
open={props.open && !props.haveButton&&!closeButton}
|
||||
trigger={props.haveButton ?
|
||||
<Button type="primary">
|
||||
<PlusOutlined/>
|
||||
|
@ -109,6 +113,12 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
}
|
||||
form={form}
|
||||
autoFocusFirstInput
|
||||
onOpenChange={(state)=>{
|
||||
console.log("state",{state})
|
||||
if(!state) {
|
||||
setCloseButton(state)
|
||||
}
|
||||
}}
|
||||
modalProps={{
|
||||
destroyOnClose: true,
|
||||
onCancel: () => {
|
||||
|
@ -118,7 +128,8 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
}}
|
||||
submitter={props.itemId !== undefined && props.itemId !== '-1' ? {
|
||||
render: (prop, defaultDoms) => {
|
||||
return [
|
||||
prop.resetButtonProps
|
||||
let result = [
|
||||
editFormDisable ? <Button
|
||||
key="edit"
|
||||
onClick={() => {
|
||||
|
@ -154,8 +165,16 @@ export const DetailModelForm: React.FC<DetailModelFormProps> = (props) => {
|
|||
</Popconfirm> : undefined
|
||||
,
|
||||
requestTask&&requestTask.id?<DiaryOption taskId={requestTask.id} taskName={requestTask.name}/>:undefined,
|
||||
...defaultDoms
|
||||
];
|
||||
]
|
||||
// 非新增或者编辑状态不展示
|
||||
if (!editFormDisable) {
|
||||
result.push(...defaultDoms)
|
||||
}else {
|
||||
result.push(<Button type="primary" onClick={()=>setCloseButton(true)}>
|
||||
关闭
|
||||
</Button>)
|
||||
}
|
||||
return result;
|
||||
},
|
||||
} : undefined}
|
||||
onFinish={async (values) => {
|
||||
|
|
Loading…
Reference in New Issue