Newer
Older
import { FolderOutlined, ReloadOutlined } from "@ant-design/icons";
import { Button, Col, Divider, Layout, Row, Typography } from "antd";
import { Content } from "antd/lib/layout/layout";
import { FunctionComponent, useEffect, useState } from "react";
import { apiGetLibrary, apiMoveItem } from "../../common/APIUtils";
import { Item, ItemType } from "../../common/Common";
import ItemInfo, { getIconForItemType } from "./items/ItemInfo";
const { Title } = Typography;
interface LibraryProps {
}
const Library: FunctionComponent<LibraryProps> = () => {
const auth = useAuth();
const [isLibraryLoading, setIsLibraryLoading] = useState(false);
const [expandedKeys, setExpandedKeys] = useState<Array<string>>([]);
const [selectedItem, setSelectedItem] = useState<any | null>(null);
// fetch library on load
useEffect(() => {
fetchLibrary();
}, [auth.user.token]); // [] execute on user token value change, could be replaced with just [] which is basicly onLoad ..
const compare = (a: Item, b: Item) => {
let aIndex = Object.keys(ItemType).indexOf(a.type);
let bIndex = Object.keys(ItemType).indexOf(b.type);
if (aIndex < bIndex) {
return -1;
}
if (aIndex > bIndex) {
return 1;
}
return 0;
}
const fetchLibrary = () => {
setIsLibraryLoading(true);
setTimeout(
() => {
apiGetLibrary(auth.user.token)
.then(response => {
console.log("fetched library: ", response);
setIconsAndSortRecursive(data[0]);
selectedItem ? setSelectedItem(findItemByIdIter(selectedItem?.id, data[0])) : setSelectedItem(null);
}).catch(error => {
console.error("error fetching library: ", error);
}).finally(() => setIsLibraryLoading(false))
},
500
);
}
const setIconsAndSortRecursive = (item: any) => {
item.icon = getIconForItemType(item?.type as ItemType);
// item.children?.sort(compare);
setIconsAndSortRecursive(element);
const findItemByIdIter = (id: string, root: any) => {
var stack = [], item, ii;
stack.push(root);
while (stack.length > 0) {
item = stack.pop();
if (item.id === id) {
return item;
} else if (item.children && item.children.length) {
for (ii = 0; ii < item.children.length; ii += 1) {
stack.push(item.children[ii]);
}
}
}
// Didn't find it. Return null.
return null;
}
console.log("onSelect: ", keys, info);
const onDrop = (info: any) => {
// TODO: clean this up a bit
// console.log("item dropped: ", info);
const dropKey = info.node.key;
const dragKey = info.dragNode.key;
const dropPos = dropKey.split('-');
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
var actualPosition = dropPosition;
console.log(`dropkey: ${dropKey}, dragKey: ${dragKey}, dropPos: ${dropPos}, dropPosition: ${dropPosition}`);
const loop = (data: any, key: any, callback: any) => {
for (let i = 0; i < data.length; i++) {
if (data[i].key === key) {
return callback(data[i], i, data);
}
if (data[i].children) {
loop(data[i].children, key, callback);
}
}
};
const data = [...treeData];
// Find dragObject
let draggedItem: any;
loop(data, dragKey, (item: any, index: any, arr: any) => {
arr.splice(index, 1);
draggedItem = item;
});
let newParentId: any;
console.log("item dropped onto another item, move to first position");
// item dropped onto another item
loop(data, dropKey, (newParent: any) => {
newParentId = newParent.id;
newParent.children = newParent.children || [];
// insert at the beginning of that element's children
newParent.children.unshift(draggedItem);
});
} else if (
(info.node.props.children || []).length > 0 && // Has children
info.node.props.expanded && // Is expanded
dropPosition === 1 // On the bottom gap
) {
console.log("item dropped into gap, different parent");
loop(data, dropKey, (newParent: any) => {
newParentId = newParent.id;
newParent.children = newParent.children || [];
// where to insert 示例添加到头部,可以是随意位置
newParent.children.unshift(draggedItem);
// in previous version, we use item.children.push(dragObj) to insert the
// item to the tail of the children
});
} else {
console.log("item dropped into gap, same parent");
let ar: any;
let i: any;
loop(data, dropKey, (item: any, index: any, arr: any) => {
newParentId = item.parentId;
ar = arr;
i = index;
});
if (dropPosition === -1) {
actualPosition = i;
ar.splice(i, 0, draggedItem);
} else {
actualPosition = i + 1;
ar.splice(i + 1, 0, draggedItem);
}
}
console.log(`move item ${draggedItem.title} to position ${actualPosition} under new parent ${newParentId}`);
apiMoveItem(draggedItem, newParentId, actualPosition, auth.user?.token)
.then(() => {
console.log("ITEM MOVED");
}).catch(error => {
console.error(error);
}).finally(() => fetchLibrary());
// setTreeData(data);
};
const onExpand = (expandedKeys: Array<any>, info: any) => {
console.log("expanded key:", info);
setExpandedKeys(expandedKeys);
}
const library = [
{
title: 'Root Category',
key: '0-0',
icon: <FolderOutlined />,
children: [
{
title: 'Subcategory',
key: '0-0-0',
icon: <FolderOutlined />,
children: [],
}
]
}
]
<Layout className="site-layout-background">
<Content className="site-layout-background"
style={{
padding: 24,
margin: 0,
minHeight: "90vh",
}}>
<Title level={3} style={{ paddingLeft: "25px", paddingBottom: "15px" }}>Library</Title>
<Divider orientation="left" orientationMargin="25px">
Browser
<Button loading={isLibraryLoading} onClick={fetchLibrary} style={{ margin: "0 15px" }} icon={<ReloadOutlined />}>
<Col flex="600px">
<Tree
defaultExpandAll
showIcon={true}
selectedKeys={[selectedItem?.key]}
defaultExpandedKeys={expandedKeys}
onExpand={onExpand}
onDrop={onDrop}
style={{ padding: "15px" }}
{
selectedItem !== null ?
<div style={{ padding: "15px" }}>
<ItemInfo selectedItem={selectedItem} selectedItemParent={findItemByIdIter(selectedItem.parentId, treeData[0])} onContentUpdate={fetchLibrary} />
</div> :
<></>
}
</Col>
</Row>
</Content>
</Layout>