refactor: tree
This commit is contained in:
parent
2771776d32
commit
64488e5d46
|
@ -9,6 +9,7 @@
|
||||||
'@avocado/math/persea': {}
|
'@avocado/math/persea': {}
|
||||||
'@avocado/persea': {}
|
'@avocado/persea': {}
|
||||||
'@avocado/physics': {}
|
'@avocado/physics': {}
|
||||||
|
'@avocado/react': {}
|
||||||
'@avocado/resource': {
|
'@avocado/resource': {
|
||||||
'persea.controllers': [
|
'persea.controllers': [
|
||||||
'@avocado/graphics/persea',
|
'@avocado/graphics/persea',
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
"react-hex-editor": "^0.3.0",
|
"react-hex-editor": "^0.3.0",
|
||||||
"react-hot-loader": "^4.13.0",
|
"react-hot-loader": "^4.13.0",
|
||||||
"react-modal": "^3.12.1",
|
"react-modal": "^3.12.1",
|
||||||
|
"react-resize-panel": "^0.3.5",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-ui-tree": "^4.0.0"
|
"react-ui-tree": "^4.0.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,56 +1,24 @@
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
import {join} from 'path';
|
|
||||||
|
|
||||||
import {PropTypes, React} from '@latus/react';
|
import {PropTypes, React} from '@latus/react';
|
||||||
import {Link, Route} from 'react-router-dom';
|
import ResizePanel from 'react-resize-panel';
|
||||||
import Tree from 'react-ui-tree';
|
import {Route} from 'react-router-dom';
|
||||||
|
|
||||||
import {ProjectContext} from '@avocado/persea';
|
import {ProjectContext} from '@avocado/persea';
|
||||||
|
|
||||||
import ResourceRoute from '../resource/route';
|
import ResourceRoute from '../resource/route';
|
||||||
|
import Sidebar from './sidebar';
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Project = ({structure: {label, resourcePaths}, uuid}) => (
|
const Project = ({structure: {label, resourcePaths}, uuid}) => (
|
||||||
<div className="project">
|
<div className="project">
|
||||||
<ProjectContext.Provider value={uuid}>
|
<ProjectContext.Provider value={uuid}>
|
||||||
<div className="sidebar">
|
<ResizePanel direction="e">
|
||||||
<Tree
|
<Sidebar
|
||||||
paddingLeft={20}
|
label={label}
|
||||||
tree={treeFromResourcePaths(label, uuid, resourcePaths)}
|
uuid={uuid}
|
||||||
renderNode={renderNode}
|
resourcePaths={resourcePaths}
|
||||||
/>
|
/>
|
||||||
</div>
|
</ResizePanel>
|
||||||
<div className="resource-container">
|
<div className="resource-container">
|
||||||
<Route path="/project/:uuid:uri(/*)" component={ResourceRoute} />
|
<Route path="/project/:uuid:uri(/*)" component={ResourceRoute} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,38 +1,9 @@
|
||||||
|
$sidebar-basis: 10rem;
|
||||||
|
|
||||||
.project {
|
.project {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
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 {
|
.resource-container {
|
||||||
background-color: rgba(0, 0, 0, 0.2);
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
flex-grow: 1;
|
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"
|
resolved "http://npm.cha0sdev/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
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:
|
chai@4.2.0:
|
||||||
version "4.2.0"
|
version "4.2.0"
|
||||||
resolved "http://npm.cha0sdev/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5"
|
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"
|
resolved "http://npm.cha0sdev/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
|
||||||
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
|
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"
|
version "15.7.2"
|
||||||
resolved "http://npm.cha0sdev/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
resolved "http://npm.cha0sdev/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||||
|
@ -7300,6 +7305,14 @@ react-dom@^17.0.1:
|
||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
scheduler "^0.20.2"
|
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:
|
react-hex-editor@^0.3.0:
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
resolved "http://npm.cha0sdev/react-hex-editor/-/react-hex-editor-0.3.0.tgz#4133715faa9eb46ea3f373ec0c81a2e379fe6575"
|
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"
|
prop-types "^15.7.2"
|
||||||
react-is "^16.13.1"
|
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:
|
react-router-dom@^5.2.0:
|
||||||
version "5.2.0"
|
version "5.2.0"
|
||||||
resolved "http://npm.cha0sdev/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662"
|
resolved "http://npm.cha0sdev/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user