feat: projects
This commit is contained in:
parent
0ee7b771da
commit
20c64664ce
|
@ -14,6 +14,7 @@
|
||||||
"watch": "NODE_PATH=./node_modules webpack --hot --watch --mode development"
|
"watch": "NODE_PATH=./node_modules webpack --hot --watch --mode development"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@avocado/resource": "^2.0.0",
|
||||||
"@latus/core": "^2.0.0",
|
"@latus/core": "^2.0.0",
|
||||||
"@latus/db": "^2.0.0",
|
"@latus/db": "^2.0.0",
|
||||||
"@latus/governor": "^2.0.0",
|
"@latus/governor": "^2.0.0",
|
||||||
|
|
|
@ -1,13 +1,28 @@
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
import {React} from '@latus/react';
|
import {React} from '@latus/react';
|
||||||
|
import {useSelector} from '@latus/redux';
|
||||||
|
import {projectsSelector} from '@persea/core';
|
||||||
|
|
||||||
const Dashboard = () => (
|
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">
|
<div className="dashboard">
|
||||||
<h2 className="dashboard__title">Dashboard</h2>
|
<h2 className="dashboard__title">Dashboard</h2>
|
||||||
<p>Sup ;p</p>
|
{items}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
Dashboard.propTypes = {};
|
Dashboard.propTypes = {};
|
||||||
|
|
||||||
|
|
21
app/src/react/components/dashboard/project-item/index.jsx
Normal file
21
app/src/react/components/dashboard/project-item/index.jsx
Normal 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;
|
|
@ -13,6 +13,7 @@ import {
|
||||||
} from 'react-router-dom';
|
} from 'react-router-dom';
|
||||||
|
|
||||||
import Dashboard from 'components/dashboard';
|
import Dashboard from 'components/dashboard';
|
||||||
|
import ProjectRoute from 'components/project/route';
|
||||||
|
|
||||||
const Persea = ({history}) => {
|
const Persea = ({history}) => {
|
||||||
const isLoggedIn = useSelector(userIdSelector);
|
const isLoggedIn = useSelector(userIdSelector);
|
||||||
|
@ -23,6 +24,7 @@ const Persea = ({history}) => {
|
||||||
{isLoggedIn ? <Redirect to="/" /> : Login}
|
{isLoggedIn ? <Redirect to="/" /> : Login}
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/dashboard" component={Dashboard} />
|
<Route path="/dashboard" component={Dashboard} />
|
||||||
|
<Route path="/project/:uuid" component={ProjectRoute} />
|
||||||
</Switch>
|
</Switch>
|
||||||
<Route exact path="/">
|
<Route exact path="/">
|
||||||
<Redirect to="/dashboard" />
|
<Redirect to="/dashboard" />
|
||||||
|
|
20
app/src/react/components/project/index.jsx
Normal file
20
app/src/react/components/project/index.jsx
Normal 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;
|
0
app/src/react/components/project/index.scss
Normal file
0
app/src/react/components/project/index.scss
Normal file
22
app/src/react/components/project/route/index.jsx
Normal file
22
app/src/react/components/project/route/index.jsx
Normal 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;
|
0
app/src/react/components/project/route/index.scss
Normal file
0
app/src/react/components/project/route/index.scss
Normal file
|
@ -1,6 +1,7 @@
|
||||||
import {projects, user} from './state';
|
import {projects, user} from './state';
|
||||||
|
|
||||||
export * from './state';
|
export * from './state';
|
||||||
|
export * from './tree';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
hooks: {
|
hooks: {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {promisify} from 'util';
|
||||||
|
|
||||||
import {decorateWithLatus, gatherWithLatus} from '@latus/core';
|
import {decorateWithLatus, gatherWithLatus} from '@latus/core';
|
||||||
|
|
||||||
import {treeToPaths} from '../tree';
|
import {treeToPaths, treeToResourcePaths} from '../tree';
|
||||||
|
|
||||||
const readFile = promisify(fs.readFile).bind(fs);
|
const readFile = promisify(fs.readFile).bind(fs);
|
||||||
const stat = promisify(fs.stat).bind(fs);
|
const stat = promisify(fs.stat).bind(fs);
|
||||||
|
@ -49,7 +49,30 @@ export default {
|
||||||
}), {});
|
}), {});
|
||||||
return {
|
return {
|
||||||
projects: {
|
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,
|
resources,
|
||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
import {
|
import {
|
||||||
addPathToTree,
|
addPathToTree,
|
||||||
removePathFromTree,
|
removePathFromTree,
|
||||||
|
treeToResourcePaths,
|
||||||
} from '../tree';
|
} from '../tree';
|
||||||
|
|
||||||
export const projectsSelector = (state) => state.projects;
|
export const projectsSelector = (state) => state.projects;
|
||||||
|
@ -25,8 +26,12 @@ const slice = createSlice({
|
||||||
extraReducers: {
|
extraReducers: {
|
||||||
},
|
},
|
||||||
reducers: {
|
reducers: {
|
||||||
createProject: ({projects}, {payload: {tree, uuid}}) => {
|
createProject: ({projects}, {payload: {label, tree, uuid}}) => {
|
||||||
projects[uuid] = tree;
|
projects[uuid] = {
|
||||||
|
label,
|
||||||
|
tree,
|
||||||
|
resourcePaths: treeToResourcePaths(tree),
|
||||||
|
};
|
||||||
},
|
},
|
||||||
createResource: ({projects, resources}, {payload: {data, project, uri}}) => {
|
createResource: ({projects, resources}, {payload: {data, project, uri}}) => {
|
||||||
projects[project] = addPathToTree(projects[project], uri);
|
projects[project] = addPathToTree(projects[project], uri);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user