assistant-todo-mobile/src/components/ParentTask/index.js

202 lines
7.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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) {
return undefined
}
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),
}))
}
return generate('0') ?? []
}, [valueToOptions, searchValue])
async function fetchOptionsForValue(v, level) {
if (v in valueToOptions) return
// if (level >= 3) {
// setValueToOptions(prev => ({
// ...prev,
// [v]: null,
// }))
// return
// }
const data = await getTaskByPid(v)
console.log("await getTaskByPid(v)", data.content)
const options =
data.content.length === 0
? null
: data.content.map(task => ({
value: task.id,
label: task.name,
}))
console.log("await getTaskByPid(v) options", options)
setValueToOptions(prev => ({
...prev,
[v]: options,
}))
}
useEffect(() => {
initDate()
}, [props])
async function initDate() {
await fetchOptionsForValue('0', 0)
if (pidArray && pidArray.length > 0) {
setParentValue(pidArray)
for (const taskId of pidArray) {
await fetchOptionsForValue(taskId, 0)
}
}
}
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)
}}
>
<Cascader
title={<SearchBar placeholder='搜索当前层相关标题' onChange={
// 获取当前选卡,过滤当前选项
(value) => {
console.log("搜索" + value)
setSearchValue(value);
}
}/>}
options={options}
visible={visible}
defaultValue={pidArray}
onClose={() => {
setVisible(false)
}}
value={parentValue}
onConfirm={(val) => {
console.log(val)
setParentValue(val[val.length - 1])
form.setFieldValue('pidArray', val)
}}
onTabsChange={index => {
console.log(index);
setCurrentLab(index)
}}
onSelect={value => {
console.log("value", value, currentLab)
setSelectValue(value)
value.forEach((v, index) => {
fetchOptionsForValue(v, index + 1)
})
}}
>
{items => {
if (items.every(item => item === null)) {
return (pName && form.getFieldValue('pidArray') && form.getFieldValue('pidArray').length > 0) ? (
<span>{pName}</span>) : disabled ?
(<span>主线任务选填</span>) :
(<span style={{color: "#cccccc"}}>主线任务选填</span>)
} else if (items) {
if (addEditPName) {
addEditPName(items[items.length - 1].label)
}
return items[items.length - 1].label
}
}}
</Cascader>
</Form.Item>
// const [parentValue, setParentValue] = useState("")
// return <Form.Item
// name='name'
// label='主线任务'
// onClick={async () => {
// const value = await Cascader.prompt({
// options: options,
// placeholder: '请选择',
// })
// Toast.show(
// value ? `你选择了 ${value.join(' - ')}` : '你没有进行选择'
// )
// if (value){
// setParentValue(value.join(' - '))
// }
// }}
// >
// <Input
// defaultValue={parentValue}
// value={parentValue}
// readOnly={true}
// placeholder='主线任务名称选填'>
// {parentValue}
// </Input>
// </Form.Item>
}
export default ParentTask;