feat:日历滑动
This commit is contained in:
parent
c2eb04b4b0
commit
55cfe79dab
|
@ -5,7 +5,7 @@ import {
|
|||
Button,
|
||||
Dialog,
|
||||
TextArea,
|
||||
Space, Tag, Radio
|
||||
Space, Tag, Radio, Checkbox
|
||||
} from 'antd-mobile'
|
||||
import ParentTask from "../ParentTask";
|
||||
import "./index.css"
|
||||
|
@ -13,6 +13,7 @@ import {addTask, getPTask, getTaskById, updateTask} from "../../utils";
|
|||
import {useLocation, useNavigate, useOutletContext, useSearchParams} from "react-router-dom";
|
||||
import dayjs from "dayjs";
|
||||
import DataPickItemPopup from "../DataPickItemPopup";
|
||||
import {getDictionary} from "../../utils/dictUtil";
|
||||
|
||||
const DetailForm = () => {
|
||||
// 进入此页面的操作:添加,修改,详情(按钮为添加任务日志)
|
||||
|
@ -24,6 +25,8 @@ const DetailForm= () => {
|
|||
const [updateFiledDisabled, setUpdateFiledDisabled] = React.useState(true);
|
||||
const [pName, setPName] = React.useState();
|
||||
const [pidArray, setPidArray] = React.useState([]);
|
||||
const [stateList, setStateList] = React.useState([]);
|
||||
const [priorityList, setPriorityList] = React.useState([]);
|
||||
// 路由
|
||||
const navigate = useNavigate();
|
||||
// 获取form引用
|
||||
|
@ -32,6 +35,12 @@ const DetailForm= () => {
|
|||
setPName(name)
|
||||
}
|
||||
useEffect(() => {
|
||||
getDictionary("2").then(stateDictionary => {
|
||||
setStateList(Array.from(stateDictionary.values()));
|
||||
})
|
||||
getDictionary("1").then(priorityDictionary => {
|
||||
setPriorityList(Array.from(priorityDictionary.values()));
|
||||
})
|
||||
window.scrollTo(0, 0);
|
||||
if (location.pathname.endsWith("addTask")) {
|
||||
setTitle("添加任务");
|
||||
|
@ -50,7 +59,8 @@ const DetailForm= () => {
|
|||
initData(params.get('id'));
|
||||
setUpdateFiledDisabled(true);
|
||||
setRightDesc(<div>
|
||||
<Button type="button" color="danger" onClick={() => {Dialog.show({
|
||||
<Button type="button" color="danger" onClick={() => {
|
||||
Dialog.show({
|
||||
content: `进入任务编辑`,
|
||||
closeOnAction: true,
|
||||
actions: [
|
||||
|
@ -68,7 +78,8 @@ const DetailForm= () => {
|
|||
}
|
||||
],
|
||||
],
|
||||
})}}>编辑</Button>
|
||||
})
|
||||
}}>编辑</Button>
|
||||
</div>)
|
||||
} else {
|
||||
// todo 异常处理
|
||||
|
@ -218,23 +229,41 @@ const DetailForm= () => {
|
|||
showCount
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name='state' initialValue='8' label='任务状态' rules={[{required: true, message: '任务状态不能为空'}]} disabled={updateFiledDisabled}>
|
||||
<Form.Item name='state' initialValue='8' label='任务状态'
|
||||
rules={[{required: true, message: '任务状态不能为空'}]} disabled={updateFiledDisabled}>
|
||||
<Radio.Group>
|
||||
<Space direction='vertical'>
|
||||
<Radio value='8'><Tag color='primary'>未开始</Tag></Radio>
|
||||
<Radio value='9'><Tag color='warning'>进行中</Tag></Radio>
|
||||
<Radio value='7'><Tag color='success'>已完成</Tag></Radio>
|
||||
<Radio value='10'><Tag color='danger'>已逾期</Tag></Radio>
|
||||
{/*<Radio value='8'><Tag color='primary'>未开始</Tag></Radio>*/}
|
||||
{/*<Radio value='9'><Tag color='warning'>进行中</Tag></Radio>*/}
|
||||
{/*<Radio value='7'><Tag color='success'>已完成</Tag></Radio>*/}
|
||||
{/*<Radio value='10'><Tag color='danger'>已逾期</Tag></Radio>*/}
|
||||
{
|
||||
stateList.map(stateDict =>
|
||||
<Radio key={stateDict.itemCode} value={stateDict.itemCode}>
|
||||
<Tag key={stateDict.itemCode}
|
||||
color={stateDict.jsonValue?.color}>{stateDict.itemName}</Tag>
|
||||
</Radio>
|
||||
)
|
||||
}
|
||||
</Space>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item name='priority' label='任务优先级' initialValue='2' rules={[{required: true, message: '任务优先级不能为空'}]} disabled={updateFiledDisabled}>
|
||||
<Form.Item name='priority' label='任务优先级' initialValue='2'
|
||||
rules={[{required: true, message: '任务优先级不能为空'}]} disabled={updateFiledDisabled}>
|
||||
<Radio.Group>
|
||||
<Space direction='vertical'>
|
||||
<Radio value='3'><Tag color='danger'>紧急重要</Tag></Radio>
|
||||
<Radio value='2'><Tag color='warning'>不紧急重要</Tag></Radio>
|
||||
<Radio value='1'><Tag>紧急不重要</Tag></Radio>
|
||||
<Radio value='0'><Tag color='success'>不紧急不重要</Tag></Radio>
|
||||
{/*<Radio value='3'><Tag color='danger'>紧急重要</Tag></Radio>*/}
|
||||
{/*<Radio value='2'><Tag color='warning'>不紧急重要</Tag></Radio>*/}
|
||||
{/*<Radio value='1'><Tag>紧急不重要</Tag></Radio>*/}
|
||||
{/*<Radio value='0'><Tag color='success'>不紧急不重要</Tag></Radio>*/}
|
||||
{
|
||||
priorityList.map(stateDict =>
|
||||
<Radio key={stateDict.itemCode} value={stateDict.itemCode}>
|
||||
<Tag key={stateDict.itemCode}
|
||||
color={stateDict.jsonValue?.color}>{stateDict.itemName}</Tag>
|
||||
</Radio>
|
||||
)
|
||||
}
|
||||
</Space>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
|
@ -244,7 +273,8 @@ const DetailForm= () => {
|
|||
labelName={"预计结束时间"}/>
|
||||
<DataPickItemPopup disabled={updateFiledDisabled} fieldName={"actualStartTime"}
|
||||
labelName={"实际开始时间"}/>
|
||||
<DataPickItemPopup disabled={updateFiledDisabled} fieldName={"actualEndTime"} labelName={"实际结束时间"}/>
|
||||
<DataPickItemPopup disabled={updateFiledDisabled} fieldName={"actualEndTime"}
|
||||
labelName={"实际结束时间"}/>
|
||||
</Form>
|
||||
</>
|
||||
)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
.adm-cascader-header-title{
|
||||
flex: 0.5;
|
||||
}
|
|
@ -1,18 +1,27 @@
|
|||
import {Cascader, Input, Toast} from "antd-mobile";
|
||||
import {Cascader, Input, SearchBar, Toast} from "antd-mobile";
|
||||
import React, {useEffect, useMemo, useState} from "react";
|
||||
import {
|
||||
Form,
|
||||
} from 'antd-mobile'
|
||||
import {getTaskByPid} from "../../utils";
|
||||
|
||||
import "./index.css"
|
||||
import {CloseCircleFill} from "antd-mobile-icons";
|
||||
|
||||
const ParentTask = (props) => {
|
||||
const [valueToOptions, setValueToOptions] = useState([])
|
||||
const {form, disabled, pName, pidArray, addEditPName} = props;
|
||||
const [parentValue, setParentValue] = useState(pidArray ?? [])
|
||||
const [visible, setVisible] = useState(false)
|
||||
const [searchValue, setSearchValue] = useState("");
|
||||
const [currentLab, setCurrentLab] = useState(0);
|
||||
const [selectValue, setSelectValue] = useState([]);
|
||||
// 当前标签
|
||||
// let currentLab=0;
|
||||
// let selectValue=[];
|
||||
|
||||
const options = useMemo(() => {
|
||||
console.log("useMemo")
|
||||
|
||||
function generate(v) {
|
||||
const options = valueToOptions[v]
|
||||
if (options === null) {
|
||||
|
@ -21,6 +30,27 @@ const ParentTask = (props) => {
|
|||
if (options === undefined) {
|
||||
return Cascader.optionSkeleton
|
||||
}
|
||||
// 如果有搜索有值,需要过滤,
|
||||
// 根据currentLab查看需要过滤第几层,当前层可能没有值就会停留在上一层
|
||||
if (searchValue && searchValue.length > 0) {
|
||||
if (selectValue.length <= currentLab + 1) {
|
||||
// 可能展示最新的,或没有停留在当前页面,正常是没有选择的时候搜索
|
||||
console.log({searchValue}, {currentLab}, {selectValue})
|
||||
if (currentLab === 0 && v === '0') {
|
||||
return options.filter(option => option.label.includes(searchValue)).map(option => ({
|
||||
...option,
|
||||
children: generate(option.value),
|
||||
}))
|
||||
} else if (v === selectValue[currentLab - 1]) {
|
||||
return options.filter(option => option.label.includes(searchValue)).map(option => ({
|
||||
...option,
|
||||
children: generate(option.value),
|
||||
}))
|
||||
}
|
||||
} else {
|
||||
// 用户切换回之前的标签,暂不处理
|
||||
}
|
||||
}
|
||||
return options.map(option => ({
|
||||
...option,
|
||||
children: generate(option.value),
|
||||
|
@ -28,7 +58,7 @@ const ParentTask = (props) => {
|
|||
}
|
||||
|
||||
return generate('0') ?? []
|
||||
}, [valueToOptions])
|
||||
}, [valueToOptions, searchValue])
|
||||
|
||||
async function fetchOptionsForValue(v, level) {
|
||||
if (v in valueToOptions) return
|
||||
|
@ -72,13 +102,38 @@ const ParentTask = (props) => {
|
|||
return <Form.Item
|
||||
name='pidArray'
|
||||
label='主线任务'
|
||||
value={parentValue}
|
||||
disabled={disabled}
|
||||
arrow={
|
||||
(form.getFieldValue('pidArray') && form.getFieldValue('pidArray').length > 0) ? (
|
||||
<CloseCircleFill
|
||||
style={{
|
||||
color: 'var(--adm-color-light)',
|
||||
fontSize: 14,
|
||||
}}
|
||||
onClick={e => {
|
||||
form.setFieldsValue({pidArray: []})
|
||||
setParentValue([])
|
||||
// 阻止冒泡
|
||||
e.stopPropagation()
|
||||
// 阻止所有后续事件处理程序
|
||||
// e.nativeEvent.stopImmediatePropagation();
|
||||
}}
|
||||
/>) : true
|
||||
|
||||
}
|
||||
onClick={() => {
|
||||
setVisible(true)
|
||||
}}
|
||||
value={parentValue}
|
||||
disabled={disabled}
|
||||
>
|
||||
<Cascader
|
||||
title={<SearchBar placeholder='搜索当前层相关标题' onChange={
|
||||
// 获取当前选卡,过滤当前选项
|
||||
(value) => {
|
||||
console.log("搜索" + value)
|
||||
setSearchValue(value);
|
||||
}
|
||||
}/>}
|
||||
options={options}
|
||||
visible={visible}
|
||||
defaultValue={pidArray}
|
||||
|
@ -91,11 +146,13 @@ const ParentTask = (props) => {
|
|||
setParentValue(val[val.length - 1])
|
||||
form.setFieldValue('pidArray', val)
|
||||
}}
|
||||
// onSelect={(val, extend) => {
|
||||
// console.log('onSelect', val, extend.items)
|
||||
// }}
|
||||
onTabsChange={index => {
|
||||
console.log(index);
|
||||
setCurrentLab(index)
|
||||
}}
|
||||
onSelect={value => {
|
||||
console.log("value", value)
|
||||
console.log("value", value, currentLab)
|
||||
setSelectValue(value)
|
||||
value.forEach((v, index) => {
|
||||
fetchOptionsForValue(v, index + 1)
|
||||
})
|
||||
|
@ -103,10 +160,11 @@ const ParentTask = (props) => {
|
|||
>
|
||||
{items => {
|
||||
if (items.every(item => item === null)) {
|
||||
return pName ? (<span>{pName}</span>) : disabled ?
|
||||
return (pName && form.getFieldValue('pidArray') && form.getFieldValue('pidArray').length > 0) ? (
|
||||
<span>{pName}</span>) : disabled ?
|
||||
(<span>主线任务选填</span>) :
|
||||
(<span style={{color: "#cccccc"}}>主线任务选填</span>)
|
||||
} else {
|
||||
} else if (items) {
|
||||
if (addEditPName) {
|
||||
addEditPName(items[items.length - 1].label)
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ export function DetailLogTask() {
|
|||
const [currentTask, setCurrentTask] = useState({});
|
||||
const [actions,setActions] = useState([
|
||||
{ text: '复制', key: 'copy' },
|
||||
{ text: '有效', key: 'edit' },
|
||||
{ text: '有效', key: 'need' },
|
||||
{ text: '创建任务', key: 'addTask'},
|
||||
{
|
||||
text: '删除',
|
||||
|
@ -48,7 +48,7 @@ export function DetailLogTask() {
|
|||
map.get(dayjs(taskLog.createdDate).format("YYYY-MM-DD"))?.push(taskLog);
|
||||
return map;
|
||||
}, new Map());
|
||||
}, [taskLogList])
|
||||
}, [taskLogList,currentShow])
|
||||
const handleSend = () => {
|
||||
addTaskLog({
|
||||
"description": sendValue,
|
||||
|
@ -110,7 +110,7 @@ export function DetailLogTask() {
|
|||
{taskLogMapMemory.get(key).map(taskLog => {
|
||||
return <div key={taskLog.id} style={{ display: 'flex', width: "80%", padding: "2px 20px"}}>
|
||||
<span className="detail-line" onClick={()=>{
|
||||
actions[1]={ text: '失效', key: 'edit' }
|
||||
actions[1]={ text: '失效', key: 'noneed' }
|
||||
// setActions([...actions])
|
||||
setCurrentTask(taskLog)
|
||||
setActionSheetVisible(true)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Calendar, Cascader, Tag} from "antd-mobile";
|
||||
import {Calendar, Cascader, SwipeAction, Tag} from "antd-mobile";
|
||||
import dayjs from "dayjs";
|
||||
import {TaskCount} from "../TaskCount";
|
||||
import React, {Fragment, useEffect, useLayoutEffect, useMemo, useRef, useState} from "react";
|
||||
|
@ -12,6 +12,7 @@ import './index.css'
|
|||
const ToDoCal = (props) => {
|
||||
const today = new Date()
|
||||
const calRef = useRef(null);
|
||||
const refSwip = useRef(null);
|
||||
const [currentDay, setCurrentDay] = React.useState(new Date())
|
||||
const [currentMonth, setCurrentMonth] = React.useState(dayjs().set("date", 1).format('YYYY-MM-DD'));
|
||||
// Map key为当前月value为当前月的向
|
||||
|
@ -57,6 +58,36 @@ const ToDoCal = (props) => {
|
|||
return (
|
||||
|
||||
<Fragment>
|
||||
<SwipeAction
|
||||
ref={refSwip}
|
||||
rightActions={[
|
||||
{
|
||||
key: 'next',
|
||||
text: '自送进入下一个月',
|
||||
color: 'success',
|
||||
},
|
||||
]}
|
||||
leftActions={[
|
||||
{
|
||||
key: 'last',
|
||||
text: '自送进入上一个月',
|
||||
color: 'success',
|
||||
},
|
||||
]}
|
||||
onActionsReveal={(sideType) => {
|
||||
console.log(sideType,sideType === 'left',sideType === 'right',currentMonth)
|
||||
if (sideType === 'left') {
|
||||
const newMonth = dayjs(currentMonth).subtract(1, 'months')
|
||||
calRef.current.jumpTo({year: newMonth.year(), month: newMonth.month()+1})
|
||||
console.log(newMonth.year(),newMonth.month()+1)
|
||||
} else if (sideType === 'right') {
|
||||
const newMonth = dayjs(currentMonth).add(1, 'months')
|
||||
calRef.current.jumpTo({year: newMonth.year(), month: newMonth.month()+1})
|
||||
console.log(newMonth.year(),newMonth.month()+1)
|
||||
}
|
||||
refSwip.current?.close()
|
||||
}}
|
||||
>
|
||||
<Calendar
|
||||
ref={calRef}
|
||||
selectionMode='single'
|
||||
|
@ -121,6 +152,7 @@ const ToDoCal = (props) => {
|
|||
}}
|
||||
|
||||
/>
|
||||
</SwipeAction>
|
||||
<TaskCount currentDay={currentDay} taskCount={listTaskMap?.get(currentMonth)} today={today}
|
||||
currentMonth={currentMonth}
|
||||
backToToday={backToToday}/>
|
||||
|
|
Loading…
Reference in New Issue