feat: projects

This commit is contained in:
cha0s 2021-01-23 18:16:43 -06:00
parent 0ee7b771da
commit 20c64664ce
12 changed files with 120 additions and 10 deletions

View File

@ -14,6 +14,7 @@
"watch": "NODE_PATH=./node_modules webpack --hot --watch --mode development"
},
"dependencies": {
"@avocado/resource": "^2.0.0",
"@latus/core": "^2.0.0",
"@latus/db": "^2.0.0",
"@latus/governor": "^2.0.0",

View File

@ -1,13 +1,28 @@
import './index.scss';
import {React} from '@latus/react';
import {useSelector} from '@latus/redux';
import {projectsSelector} from '@persea/core';
const Dashboard = () => (
<div className="dashboard">
<h2 className="dashboard__title">Dashboard</h2>
<p>Sup ;p</p>
</div>
);
import ProjectItem from './project-item';
const Dashboard = () => {
const {projects} = useSelector(projectsSelector);
const items = Object.entries(projects)
.map(([uuid, project]) => (
<ProjectItem
key={uuid}
project={project}
uuid={uuid}
/>
));
return (
<div className="dashboard">
<h2 className="dashboard__title">Dashboard</h2>
{items}
</div>
);
};
Dashboard.propTypes = {};

View File

@ -0,0 +1,21 @@
import './index.scss';
import {Link} from 'react-router-dom';
import {PropTypes, React} from '@latus/react';
import {propTypes as projectPropTypes} from 'components/project';
const ProjectItem = ({project: {label, resourcePaths}, uuid}) => (
<Link className="project-item" to={`/project/${uuid}`}>
<h2 className="project-item__title">{label}</h2>
<div className="project-item__uuid">{uuid}</div>
<div className="project-item__resourceCount">{resourcePaths.length}</div>
</Link>
);
ProjectItem.propTypes = {
project: projectPropTypes.isRequired,
uuid: PropTypes.string.isRequired,
};
export default ProjectItem;

View File

@ -13,6 +13,7 @@ import {
} from 'react-router-dom';
import Dashboard from 'components/dashboard';
import ProjectRoute from 'components/project/route';
const Persea = ({history}) => {
const isLoggedIn = useSelector(userIdSelector);
@ -23,6 +24,7 @@ const Persea = ({history}) => {
{isLoggedIn ? <Redirect to="/" /> : Login}
</Route>
<Route path="/dashboard" component={Dashboard} />
<Route path="/project/:uuid" component={ProjectRoute} />
</Switch>
<Route exact path="/">
<Redirect to="/dashboard" />

View File

@ -0,0 +1,20 @@
import './index.scss';
import {PropTypes, React} from '@latus/react';
const Project = ({project: {label}}) => (
<div className="project">
<h2 className="project__title">{label}</h2>
</div>
);
export const propTypes = PropTypes.shape({
label: PropTypes.string.isRequired,
resourcePaths: PropTypes.arrayOf(PropTypes.string).isRequired,
});
Project.propTypes = {
project: propTypes.isRequired,
};
export default Project;

View File

@ -0,0 +1,22 @@
import './index.scss';
import {PropTypes, React} from '@latus/react';
import {useSelector} from '@latus/redux';
import {projectsSelector} from '@persea/core';
import Project from '../index';
const ProjectRoute = ({match: {params: {uuid}}}) => {
const {projects} = useSelector(projectsSelector);
return <Project uuid={uuid} project={projects[uuid]} />;
};
ProjectRoute.propTypes = {
match: PropTypes.shape({
params: PropTypes.shape({
uuid: PropTypes.string,
}),
}).isRequired,
};
export default ProjectRoute;

View File

@ -1,6 +1,7 @@
import {projects, user} from './state';
export * from './state';
export * from './tree';
export default {
hooks: {

View File

@ -4,7 +4,7 @@ import {promisify} from 'util';
import {decorateWithLatus, gatherWithLatus} from '@latus/core';
import {treeToPaths} from '../tree';
import {treeToPaths, treeToResourcePaths} from '../tree';
const readFile = promisify(fs.readFile).bind(fs);
const stat = promisify(fs.stat).bind(fs);
@ -49,7 +49,30 @@ export default {
}), {});
return {
projects: {
projects,
projects: Object.fromEntries(
await Promise.all(
Object.entries(projects)
.map(async ([uuid, tree]) => {
let label;
try {
const buffer = await readFile(join(process.cwd(), 'projects', `${uuid}.json`));
const config = JSON.parse(buffer.toString());
label = config.name;
}
catch (error) {
label = uuid;
}
return [
uuid,
{
label,
tree,
resourcePaths: treeToResourcePaths(tree),
},
];
}),
),
),
resources,
},
user: {

View File

@ -6,6 +6,7 @@ import {
import {
addPathToTree,
removePathFromTree,
treeToResourcePaths,
} from '../tree';
export const projectsSelector = (state) => state.projects;
@ -25,8 +26,12 @@ const slice = createSlice({
extraReducers: {
},
reducers: {
createProject: ({projects}, {payload: {tree, uuid}}) => {
projects[uuid] = tree;
createProject: ({projects}, {payload: {label, tree, uuid}}) => {
projects[uuid] = {
label,
tree,
resourcePaths: treeToResourcePaths(tree),
};
},
createResource: ({projects, resources}, {payload: {data, project, uri}}) => {
projects[project] = addPathToTree(projects[project], uri);