refactor: tree
This commit is contained in:
parent
2771776d32
commit
64488e5d46
|
@ -9,6 +9,7 @@
|
|||
'@avocado/math/persea': {}
|
||||
'@avocado/persea': {}
|
||||
'@avocado/physics': {}
|
||||
'@avocado/react': {}
|
||||
'@avocado/resource': {
|
||||
'persea.controllers': [
|
||||
'@avocado/graphics/persea',
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
"react-hex-editor": "^0.3.0",
|
||||
"react-hot-loader": "^4.13.0",
|
||||
"react-modal": "^3.12.1",
|
||||
"react-resize-panel": "^0.3.5",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-ui-tree": "^4.0.0"
|
||||
},
|
||||
|
|
|
@ -1,56 +1,24 @@
|
|||
import './index.scss';
|
||||
|
||||
import {join} from 'path';
|
||||
|
||||
import {PropTypes, React} from '@latus/react';
|
||||
import {Link, Route} from 'react-router-dom';
|
||||
import Tree from 'react-ui-tree';
|
||||
import ResizePanel from 'react-resize-panel';
|
||||
import {Route} from 'react-router-dom';
|
||||
|
||||
import {ProjectContext} from '@avocado/persea';
|
||||
|
||||
import ResourceRoute from '../resource/route';
|
||||
|
||||
const renderNode = ({isFile, label, path}) => (
|
||||
isFile
|
||||
? <Link to={path}>{label}</Link>
|
||||
: <span>{label}</span>
|
||||
);
|
||||
|
||||
const treeFromResourcePath = (tree, uuid, [isFile, resourcePath]) => {
|
||||
const parts = resourcePath.split('/');
|
||||
parts.shift();
|
||||
let walk = tree;
|
||||
parts.forEach((part) => {
|
||||
let index = walk.children.findIndex(({label}) => label === part);
|
||||
if (-1 === index) {
|
||||
index = walk.children.length;
|
||||
walk.children.push({
|
||||
children: [],
|
||||
isFile,
|
||||
label: part,
|
||||
path: join('/project', uuid, resourcePath),
|
||||
});
|
||||
}
|
||||
walk = walk.children[index];
|
||||
});
|
||||
};
|
||||
|
||||
const treeFromResourcePaths = (label, uuid, resourcePaths) => {
|
||||
const tree = {label, children: []};
|
||||
resourcePaths
|
||||
.forEach((resourcePath) => treeFromResourcePath(tree, uuid, resourcePath));
|
||||
return tree;
|
||||
};
|
||||
import Sidebar from './sidebar';
|
||||
|
||||
const Project = ({structure: {label, resourcePaths}, uuid}) => (
|
||||
<div className="project">
|
||||
<ProjectContext.Provider value={uuid}>
|
||||
<div className="sidebar">
|
||||
<Tree
|
||||
paddingLeft={20}
|
||||
tree={treeFromResourcePaths(label, uuid, resourcePaths)}
|
||||
renderNode={renderNode}
|
||||
<ResizePanel direction="e">
|
||||
<Sidebar
|
||||
label={label}
|
||||
uuid={uuid}
|
||||
resourcePaths={resourcePaths}
|
||||
/>
|
||||
</div>
|
||||
</ResizePanel>
|
||||
<div className="resource-container">
|
||||
<Route path="/project/:uuid:uri(/*)" component={ResourceRoute} />
|
||||
</div>
|
||||
|
|
|
@ -1,38 +1,9 @@
|
|||
$sidebar-basis: 10rem;
|
||||
|
||||
.project {
|
||||
display: flex;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
.sidebar {
|
||||
height: 100%;
|
||||
min-width: 25rem;
|
||||
overflow: auto;
|
||||
padding: 1em;
|
||||
}
|
||||
.m-tree {
|
||||
user-select: none;
|
||||
> .m-node {
|
||||
> .children {
|
||||
margin-left: -20px;
|
||||
}
|
||||
> .inner {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.m-node {
|
||||
font-family: monospace;
|
||||
.inner {
|
||||
padding: 0.25em;
|
||||
}
|
||||
.caret-right::before {
|
||||
content: "\25B8";
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
.caret-down::before {
|
||||
content: "\25BE";
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
}
|
||||
.resource-container {
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
flex-grow: 1;
|
||||
|
@ -40,3 +11,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
[class*="ResizePanel-module_ResizeHandleHorizontal"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[class*="ResizePanel-module_ResizeContent"] {
|
||||
min-width: $sidebar-basis;
|
||||
}
|
||||
|
|
63
packages/core/src/components/project/sidebar/index.jsx
Normal file
63
packages/core/src/components/project/sidebar/index.jsx
Normal file
|
@ -0,0 +1,63 @@
|
|||
import './index.scss';
|
||||
|
||||
import {join} from 'path';
|
||||
|
||||
import {Tree} from '@avocado/react';
|
||||
import {PropTypes, React} from '@latus/react';
|
||||
import {useHistory} from 'react-router-dom';
|
||||
|
||||
const treeFromResourcePath = (tree, uuid, [isFile, resourcePath]) => {
|
||||
const parts = resourcePath.split('/');
|
||||
parts.shift();
|
||||
let walk = tree;
|
||||
parts.forEach((part) => {
|
||||
let index = walk.nodes.findIndex(({label}) => label === part);
|
||||
if (-1 === index) {
|
||||
index = walk.nodes.length;
|
||||
walk.nodes.push({
|
||||
...(isFile ? {} : {nodes: []}),
|
||||
label: part,
|
||||
value: join(uuid, resourcePath),
|
||||
});
|
||||
}
|
||||
walk = walk.nodes[index];
|
||||
});
|
||||
};
|
||||
|
||||
const nodesFromResourcePaths = (label, uuid, resourcePaths) => {
|
||||
const tree = {label, nodes: []};
|
||||
resourcePaths
|
||||
.forEach((resourcePath) => treeFromResourcePath(tree, uuid, resourcePath));
|
||||
return tree.nodes;
|
||||
};
|
||||
|
||||
const Sidebar = ({label, resourcePaths, uuid}) => {
|
||||
const history = useHistory();
|
||||
return (
|
||||
<div className="sidebar">
|
||||
<Tree
|
||||
activate={(item, nodes) => {
|
||||
if (!nodes) {
|
||||
history.push(join('/project', item));
|
||||
}
|
||||
}}
|
||||
label={label}
|
||||
nodes={nodesFromResourcePaths(label, uuid, resourcePaths)}
|
||||
value={uuid}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Sidebar.defaultProps = {};
|
||||
|
||||
Sidebar.propTypes = {
|
||||
label: PropTypes.string.isRequired,
|
||||
// eslint-disable-next-line react/no-unused-prop-types
|
||||
resourcePaths: PropTypes.arrayOf(PropTypes.any).isRequired,
|
||||
uuid: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
Sidebar.displayName = 'Sidebar';
|
||||
|
||||
export default Sidebar;
|
9
packages/core/src/components/project/sidebar/index.scss
Normal file
9
packages/core/src/components/project/sidebar/index.scss
Normal file
|
@ -0,0 +1,9 @@
|
|||
$sidebar-basis: 10rem;
|
||||
|
||||
.sidebar {
|
||||
height: 100%;
|
||||
min-width: $sidebar-basis;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
}
|
|
@ -2566,6 +2566,11 @@ caseless@~0.12.0:
|
|||
resolved "http://npm.cha0sdev/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||
|
||||
cash-dom@^4.1.5:
|
||||
version "4.1.5"
|
||||
resolved "http://npm.cha0sdev/cash-dom/-/cash-dom-4.1.5.tgz#0ef0cf205bc7603aa4e2dfada5808442a7a0e6ca"
|
||||
integrity sha512-E6MO0A6ms5iZPtexznQXWRkFEvqdPqCmdx/SiJr2PnhOQNhZNfALkLG5t83Hk3J5JELzED7PJuzhMoS2tT64XA==
|
||||
|
||||
chai@4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "http://npm.cha0sdev/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5"
|
||||
|
@ -7050,7 +7055,7 @@ promise-inflight@^1.0.1:
|
|||
resolved "http://npm.cha0sdev/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
|
||||
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
|
||||
|
||||
prop-types@^15.5.10, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
version "15.7.2"
|
||||
resolved "http://npm.cha0sdev/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
|
@ -7300,6 +7305,14 @@ react-dom@^17.0.1:
|
|||
object-assign "^4.1.1"
|
||||
scheduler "^0.20.2"
|
||||
|
||||
react-draggable@^4.0.3:
|
||||
version "4.4.3"
|
||||
resolved "http://npm.cha0sdev/react-draggable/-/react-draggable-4.4.3.tgz#0727f2cae5813e36b0e4962bf11b2f9ef2b406f3"
|
||||
integrity sha512-jV4TE59MBuWm7gb6Ns3Q1mxX8Azffb7oTtDtBgFkxRvhDp38YAARmRplrj0+XGkhOJB5XziArX+4HUUABtyZ0w==
|
||||
dependencies:
|
||||
classnames "^2.2.5"
|
||||
prop-types "^15.6.0"
|
||||
|
||||
react-hex-editor@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "http://npm.cha0sdev/react-hex-editor/-/react-hex-editor-0.3.0.tgz#4133715faa9eb46ea3f373ec0c81a2e379fe6575"
|
||||
|
@ -7356,6 +7369,16 @@ react-redux@^7.2.2:
|
|||
prop-types "^15.7.2"
|
||||
react-is "^16.13.1"
|
||||
|
||||
react-resize-panel@^0.3.5:
|
||||
version "0.3.5"
|
||||
resolved "http://npm.cha0sdev/react-resize-panel/-/react-resize-panel-0.3.5.tgz#43aa3450bf5b5a2566b40c4201445ced96c2a905"
|
||||
integrity sha512-iyHOFTrSt+WV4Ilzi81x6KH3FU7VsGP736rmxepwGrgAEATmCvXzZdluTm3NpsptP7aC3hLODmXwnxusyA393A==
|
||||
dependencies:
|
||||
cash-dom "^4.1.5"
|
||||
classnames "^2.2.6"
|
||||
lodash.debounce "^4.0.8"
|
||||
react-draggable "^4.0.3"
|
||||
|
||||
react-router-dom@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "http://npm.cha0sdev/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662"
|
||||
|
|
Loading…
Reference in New Issue
Block a user