mirror of
https://github.com/whyour/qinglong.git
synced 2026-07-17 17:54:32 +08:00
修复脚本和日志搜索逻辑
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
export default (
|
||||
treeData: any[],
|
||||
searchValue: string,
|
||||
{
|
||||
treeNodeFilterProp,
|
||||
}: {
|
||||
treeNodeFilterProp: string;
|
||||
},
|
||||
) => {
|
||||
return useMemo(() => {
|
||||
const keys: string[] = [];
|
||||
|
||||
if (!searchValue) {
|
||||
return { treeData, keys };
|
||||
}
|
||||
|
||||
const upperStr = searchValue.toUpperCase();
|
||||
function filterOptionFunc(_: string, dataNode: any[]) {
|
||||
const value = dataNode[treeNodeFilterProp as any];
|
||||
|
||||
return String(value).toUpperCase().includes(upperStr);
|
||||
}
|
||||
|
||||
function dig(list: any[], keepAll: boolean = false): any[] {
|
||||
return list
|
||||
.map((dataNode) => {
|
||||
const children = dataNode.children;
|
||||
|
||||
const match = keepAll || filterOptionFunc!(searchValue, dataNode);
|
||||
const childList = dig(children || [], match);
|
||||
|
||||
if (match || childList.length) {
|
||||
childList.length && keys.push(dataNode.key);
|
||||
return {
|
||||
...dataNode,
|
||||
children: childList,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter((node) => node);
|
||||
}
|
||||
|
||||
return { treeData: dig(treeData), keys };
|
||||
}, [treeData, searchValue, treeNodeFilterProp]);
|
||||
};
|
||||
+22
-45
@@ -21,44 +21,16 @@ import { useOutletContext } from '@umijs/max';
|
||||
import { SharedContext } from '@/layouts';
|
||||
import { DeleteOutlined } from '@ant-design/icons';
|
||||
import { depthFirstSearch } from '@/utils';
|
||||
import { debounce } from 'lodash';
|
||||
import { debounce, uniq } from 'lodash';
|
||||
import useFilterTreeData from '@/hooks/useFilterTreeData';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
function getFilterData(keyword: string, data: any) {
|
||||
const expandedKeys: string[] = [];
|
||||
if (keyword) {
|
||||
const tree: any = [];
|
||||
data.forEach((item: any) => {
|
||||
if (item.title.toLocaleLowerCase().includes(keyword)) {
|
||||
tree.push(item);
|
||||
} else {
|
||||
const children: any[] = [];
|
||||
(item.children || []).forEach((subItem: any) => {
|
||||
if (subItem.title.toLocaleLowerCase().includes(keyword)) {
|
||||
children.push(subItem);
|
||||
}
|
||||
});
|
||||
if (children.length > 0) {
|
||||
tree.push({
|
||||
...item,
|
||||
children,
|
||||
});
|
||||
expandedKeys.push(item.key);
|
||||
}
|
||||
}
|
||||
});
|
||||
return { tree, expandedKeys };
|
||||
}
|
||||
return { tree: data, expandedKeys };
|
||||
}
|
||||
|
||||
const Log = () => {
|
||||
const { headerStyle, isPhone, theme } = useOutletContext<SharedContext>();
|
||||
const [value, setValue] = useState('请选择日志文件');
|
||||
const [select, setSelect] = useState<string>('');
|
||||
const [data, setData] = useState<any[]>([]);
|
||||
const [filterData, setFilterData] = useState<any[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [height, setHeight] = useState<number>();
|
||||
const treeDom = useRef<any>();
|
||||
@@ -73,7 +45,6 @@ const Log = () => {
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
setData(data);
|
||||
setFilterData(data);
|
||||
}
|
||||
})
|
||||
.finally(() => setLoading(false));
|
||||
@@ -115,22 +86,26 @@ const Log = () => {
|
||||
const keyword = e.target.value;
|
||||
debounceSearch(keyword);
|
||||
},
|
||||
[data, setFilterData],
|
||||
[data],
|
||||
);
|
||||
|
||||
const debounceSearch = useCallback(
|
||||
debounce((keyword) => {
|
||||
setSearchValue(keyword);
|
||||
const { tree, expandedKeys } = getFilterData(
|
||||
keyword.toLocaleLowerCase(),
|
||||
data,
|
||||
);
|
||||
setFilterData(tree);
|
||||
setExpandedKeys(expandedKeys);
|
||||
}, 300),
|
||||
[data, setFilterData],
|
||||
[data],
|
||||
);
|
||||
|
||||
const { treeData: filterData, keys: searchExpandedKeys } = useFilterTreeData(
|
||||
data,
|
||||
searchValue,
|
||||
{ treeNodeFilterProp: 'title' },
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setExpandedKeys(uniq([...expandedKeys, ...searchExpandedKeys]));
|
||||
}, [searchExpandedKeys]);
|
||||
|
||||
const deleteFile = () => {
|
||||
Modal.confirm({
|
||||
title: `确认删除`,
|
||||
@@ -187,11 +162,9 @@ const Log = () => {
|
||||
setValue('请选择脚本文件');
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const word = searchValue || '';
|
||||
const { tree } = getFilterData(word.toLocaleLowerCase(), data);
|
||||
setFilterData(tree);
|
||||
}, [data]);
|
||||
const onExpand = (expKeys: any) => {
|
||||
setExpandedKeys(expKeys);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getLogs();
|
||||
@@ -217,8 +190,10 @@ const Log = () => {
|
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
treeData={data}
|
||||
placeholder="请选择日志"
|
||||
fieldNames={{ value: 'key', label: 'title' }}
|
||||
fieldNames={{ value: 'key' }}
|
||||
treeNodeFilterProp="title"
|
||||
showSearch
|
||||
allowClear
|
||||
onSelect={onSelect}
|
||||
/>,
|
||||
]
|
||||
@@ -260,6 +235,8 @@ const Log = () => {
|
||||
selectedKeys={[select]}
|
||||
showLine={{ showLeafIcon: true }}
|
||||
onSelect={onTreeSelect}
|
||||
expandedKeys={expandedKeys}
|
||||
onExpand={onExpand}
|
||||
></Tree>
|
||||
</div>
|
||||
</>
|
||||
|
||||
+21
-49
@@ -37,37 +37,11 @@ import { history, useOutletContext, useLocation } from '@umijs/max';
|
||||
import { parse } from 'query-string';
|
||||
import { depthFirstSearch } from '@/utils';
|
||||
import { SharedContext } from '@/layouts';
|
||||
import useFilterTreeData from '@/hooks/useFilterTreeData';
|
||||
import { uniq } from 'lodash';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
function getFilterData(keyword: string, data: any) {
|
||||
const expandedKeys: string[] = [];
|
||||
if (keyword) {
|
||||
const tree: any = [];
|
||||
data.forEach((item: any) => {
|
||||
if (item.title.toLocaleLowerCase().includes(keyword)) {
|
||||
tree.push(item);
|
||||
} else {
|
||||
const children: any[] = [];
|
||||
(item.children || []).forEach((subItem: any) => {
|
||||
if (subItem.title.toLocaleLowerCase().includes(keyword)) {
|
||||
children.push(subItem);
|
||||
}
|
||||
});
|
||||
if (children.length > 0) {
|
||||
tree.push({
|
||||
...item,
|
||||
children,
|
||||
});
|
||||
expandedKeys.push(item.key);
|
||||
}
|
||||
}
|
||||
});
|
||||
return { tree, expandedKeys };
|
||||
}
|
||||
return { tree: data, expandedKeys };
|
||||
}
|
||||
|
||||
const LangMap: any = {
|
||||
'.py': 'python',
|
||||
'.js': 'javascript',
|
||||
@@ -81,7 +55,6 @@ const Script = () => {
|
||||
const [value, setValue] = useState('请选择脚本文件');
|
||||
const [select, setSelect] = useState<string>('');
|
||||
const [data, setData] = useState<any[]>([]);
|
||||
const [filterData, setFilterData] = useState<any[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [mode, setMode] = useState('');
|
||||
const [height, setHeight] = useState<number>();
|
||||
@@ -101,7 +74,6 @@ const Script = () => {
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
setData(data);
|
||||
setFilterData(data);
|
||||
initGetScript();
|
||||
}
|
||||
})
|
||||
@@ -153,10 +125,6 @@ const Script = () => {
|
||||
getDetail(node);
|
||||
};
|
||||
|
||||
const onExpand = (expKeys: any) => {
|
||||
setExpandedKeys(expKeys);
|
||||
};
|
||||
|
||||
const onTreeSelect = useCallback(
|
||||
(keys: Key[], e: any) => {
|
||||
const content = editorRef.current
|
||||
@@ -187,22 +155,30 @@ const Script = () => {
|
||||
const keyword = e.target.value;
|
||||
debounceSearch(keyword);
|
||||
},
|
||||
[data, setFilterData],
|
||||
[data],
|
||||
);
|
||||
|
||||
const debounceSearch = useCallback(
|
||||
debounce((keyword) => {
|
||||
setSearchValue(keyword);
|
||||
const { tree, expandedKeys } = getFilterData(
|
||||
keyword.toLocaleLowerCase(),
|
||||
data,
|
||||
);
|
||||
setExpandedKeys(expandedKeys);
|
||||
setFilterData(tree);
|
||||
}, 300),
|
||||
[data, setFilterData],
|
||||
[data],
|
||||
);
|
||||
|
||||
const { treeData: filterData, keys: searchExpandedKeys } = useFilterTreeData(
|
||||
data,
|
||||
searchValue,
|
||||
{ treeNodeFilterProp: 'title' },
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setExpandedKeys(uniq([...expandedKeys, ...searchExpandedKeys]));
|
||||
}, [searchExpandedKeys]);
|
||||
|
||||
const onExpand = (expKeys: any) => {
|
||||
setExpandedKeys(expKeys);
|
||||
};
|
||||
|
||||
const editFile = () => {
|
||||
setTimeout(() => {
|
||||
setIsEditing(true);
|
||||
@@ -367,12 +343,6 @@ const Script = () => {
|
||||
setValue('请选择脚本文件');
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const word = searchValue || '';
|
||||
const { tree } = getFilterData(word.toLocaleLowerCase(), data);
|
||||
setFilterData(tree);
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
getScripts();
|
||||
}, []);
|
||||
@@ -462,8 +432,10 @@ const Script = () => {
|
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
treeData={data}
|
||||
placeholder="请选择脚本"
|
||||
fieldNames={{ value: 'key', label: 'title' }}
|
||||
fieldNames={{ value: 'key' }}
|
||||
treeNodeFilterProp="title"
|
||||
showSearch
|
||||
allowClear
|
||||
onSelect={onSelect}
|
||||
/>,
|
||||
<Dropdown overlay={menu} trigger={['click']}>
|
||||
|
||||
Reference in New Issue
Block a user