chore: tidy
This commit is contained in:
parent
dd36832bcc
commit
ec4e72c54a
|
@ -7,8 +7,8 @@ import {projectsSelector} from '@persea/core';
|
|||
import ProjectItem from './project-item';
|
||||
|
||||
const Dashboard = React.memo(() => {
|
||||
const {projects} = useSelector(projectsSelector);
|
||||
const items = Object.entries(projects)
|
||||
const {structure} = useSelector(projectsSelector);
|
||||
const items = Object.entries(structure)
|
||||
.map(([uuid, project]) => (
|
||||
<ProjectItem
|
||||
key={uuid}
|
||||
|
|
|
@ -44,7 +44,7 @@ const treeFromResourcePaths = (label, uuid, resourcePaths) => {
|
|||
return tree;
|
||||
};
|
||||
|
||||
const Project = ({project: {label, resourcePaths}, uuid}) => (
|
||||
const Project = ({structure: {label, resourcePaths}, uuid}) => (
|
||||
<div className="project">
|
||||
<ProjectContext.Provider value={uuid}>
|
||||
<div className="sidebar">
|
||||
|
@ -69,7 +69,7 @@ export const propTypes = PropTypes.shape({
|
|||
});
|
||||
|
||||
Project.propTypes = {
|
||||
project: propTypes.isRequired,
|
||||
structure: propTypes.isRequired,
|
||||
uuid: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
|
|
|
@ -5,14 +5,14 @@ import {join} from 'path';
|
|||
import {Resource} from '@avocado/resource';
|
||||
import {PropTypes, React} from '@latus/react';
|
||||
import {useSelector} from '@latus/redux';
|
||||
import {projectsSelector} from '@persea/core';
|
||||
import {structureSelector} from '@persea/core';
|
||||
|
||||
import Project from '../index';
|
||||
|
||||
const ProjectRoute = ({match: {params: {uuid}}}) => {
|
||||
const {projects} = useSelector(projectsSelector);
|
||||
const structure = useSelector((state) => structureSelector(state, uuid));
|
||||
Resource.root = join('/projects', uuid);
|
||||
return <Project uuid={uuid} project={projects[uuid]} />;
|
||||
return <Project uuid={uuid} structure={structure} />;
|
||||
};
|
||||
|
||||
ProjectRoute.propTypes = {
|
||||
|
|
|
@ -6,13 +6,13 @@ import {
|
|||
useLatus,
|
||||
} from '@latus/react';
|
||||
import {useSelector} from '@latus/redux';
|
||||
import {projectsSelector, UriContext} from '@persea/core';
|
||||
import {resourceSelector, UriContext} from '@persea/core';
|
||||
|
||||
const Resource = ({uri, uuid}) => {
|
||||
const latus = useLatus();
|
||||
const {resources} = useSelector(projectsSelector);
|
||||
const resource = useSelector((state) => resourceSelector(state, `${uuid}${uri}`));
|
||||
const Component = latus.get('%resource-renderers')(uri);
|
||||
const buffer = Buffer.from(resources[`${uuid}${uri}`], 'base64');
|
||||
const buffer = Buffer.from(resource, 'base64');
|
||||
return (
|
||||
<div className="resource">
|
||||
<UriContext.Provider value={uri}>
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
import fs from 'fs';
|
||||
import {join} from 'path';
|
||||
import {promisify} from 'util';
|
||||
|
||||
import {decorateWithLatus, gatherWithLatus} from '@latus/core';
|
||||
import express from 'express';
|
||||
|
||||
const readFile = promisify(fs.readFile).bind(fs);
|
||||
const stat = promisify(fs.stat).bind(fs);
|
||||
import projectsState from './state/projects';
|
||||
|
||||
const resources = express.static(join(process.cwd(), 'projects'));
|
||||
|
||||
|
@ -28,69 +25,17 @@ export default {
|
|||
}
|
||||
next();
|
||||
},
|
||||
'@latus/redux/defaultState': async (req) => {
|
||||
const projectsResourcePaths = req
|
||||
? await req.user.projectsResourcePaths()
|
||||
: {};
|
||||
const resources = await Object.entries(projectsResourcePaths)
|
||||
.reduce(async (r, [uuid, resourcePaths]) => ({
|
||||
...(await r),
|
||||
...(
|
||||
await (await Promise.all(resourcePaths
|
||||
.map(async ([, path]) => {
|
||||
try {
|
||||
return [
|
||||
(await stat(join(process.cwd(), 'projects', uuid, path))).isFile(),
|
||||
path,
|
||||
];
|
||||
}
|
||||
catch (error) {
|
||||
return [false];
|
||||
}
|
||||
})))
|
||||
.filter(([stat]) => stat)
|
||||
.map(([, path]) => path)
|
||||
.reduce(async (r, path) => ({
|
||||
...(await r),
|
||||
[join(uuid, path)]: (
|
||||
await readFile(join(process.cwd(), 'projects', uuid, path))
|
||||
).toString('base64'),
|
||||
}), {})
|
||||
),
|
||||
}), {});
|
||||
return {
|
||||
projects: {
|
||||
projects: Object.fromEntries(
|
||||
await Promise.all(
|
||||
Object.entries(projectsResourcePaths)
|
||||
.map(async ([uuid, resourcePaths]) => {
|
||||
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,
|
||||
resourcePaths,
|
||||
},
|
||||
];
|
||||
}),
|
||||
),
|
||||
),
|
||||
resources,
|
||||
},
|
||||
user: {
|
||||
id: req
|
||||
? req.user.id
|
||||
: 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
'@latus/redux/defaultState': async (req) => ({
|
||||
projects: await projectsState(
|
||||
req
|
||||
? await req.user.projectsResourcePaths()
|
||||
: {},
|
||||
),
|
||||
user: {
|
||||
id: req
|
||||
? req.user.id
|
||||
: 0,
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
|
72
packages/core/src/server/state/projects.js
Normal file
72
packages/core/src/server/state/projects.js
Normal file
|
@ -0,0 +1,72 @@
|
|||
import fs from 'fs';
|
||||
import {join} from 'path';
|
||||
import {promisify} from 'util';
|
||||
|
||||
const readFile = promisify(fs.readFile).bind(fs);
|
||||
const stat = promisify(fs.stat).bind(fs);
|
||||
|
||||
const projectResources = async (uuid, resourcePaths) => {
|
||||
const statPaths = await Promise.all(
|
||||
resourcePaths
|
||||
.map(async ([, path]) => {
|
||||
try {
|
||||
return [
|
||||
(await stat(join(process.cwd(), 'projects', uuid, path))).isFile(),
|
||||
path,
|
||||
];
|
||||
}
|
||||
catch (error) {
|
||||
return [false];
|
||||
}
|
||||
}),
|
||||
);
|
||||
const filePaths = statPaths
|
||||
.filter(([stat]) => stat)
|
||||
.map(([, path]) => path);
|
||||
return filePaths
|
||||
.reduce(async (r, path) => ({
|
||||
...(await r),
|
||||
[join(uuid, path)]: (
|
||||
await readFile(join(process.cwd(), 'projects', uuid, path))
|
||||
).toString('base64'),
|
||||
}), {});
|
||||
};
|
||||
|
||||
const projectsResources = (projectsResourcePaths) => (
|
||||
Object.entries(projectsResourcePaths)
|
||||
.reduce(async (r, [uuid, resourcePaths]) => ({
|
||||
...(await r),
|
||||
...(await projectResources(uuid, resourcePaths)),
|
||||
}), {})
|
||||
);
|
||||
|
||||
const projectsStructure = async (projectsResourcePaths) => (
|
||||
Object.fromEntries(
|
||||
await Promise.all(
|
||||
Object.entries(projectsResourcePaths)
|
||||
.map(async ([uuid, resourcePaths]) => {
|
||||
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,
|
||||
resourcePaths,
|
||||
},
|
||||
];
|
||||
}),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
export default async (projectsResourcePaths) => ({
|
||||
structure: await projectsStructure(projectsResourcePaths),
|
||||
resources: await projectsResources(projectsResourcePaths),
|
||||
});
|
|
@ -5,15 +5,20 @@ import {
|
|||
|
||||
export const projectsSelector = (state) => state.projects;
|
||||
|
||||
export const projectSelector = createSelector(
|
||||
export const resourceSelector = createSelector(
|
||||
[projectsSelector, (_, path) => path],
|
||||
({resources}, path) => path && resources[path],
|
||||
);
|
||||
|
||||
export const structureSelector = createSelector(
|
||||
[projectsSelector, (_, uuid) => uuid],
|
||||
(projects, uuid) => uuid && projects[uuid],
|
||||
({structure}, uuid) => uuid && structure[uuid],
|
||||
);
|
||||
|
||||
const slice = createSlice({
|
||||
name: 'persea/projects',
|
||||
initialState: {
|
||||
projects: {},
|
||||
structure: {},
|
||||
resources: {},
|
||||
},
|
||||
/* eslint-disable no-param-reassign */
|
||||
|
|
|
@ -1,28 +1,12 @@
|
|||
import {JSONB} from '@avocado/resource';
|
||||
import {createNextState} from '@latus/redux';
|
||||
import {applyPatch} from 'fast-json-patch';
|
||||
|
||||
import JsonResourceComponent from './json';
|
||||
import {patchJsonResource} from './state';
|
||||
import reducer from './state/reducer';
|
||||
|
||||
export {default as useJsonPatcher} from './hooks/use-json-patcher';
|
||||
export * from './state';
|
||||
|
||||
export default {
|
||||
hooks: {
|
||||
'@latus/redux/reducers': () => (state, {payload, type}) => {
|
||||
if (type !== patchJsonResource.toString()) {
|
||||
return state;
|
||||
}
|
||||
const {patch, project, uri} = payload;
|
||||
return createNextState(state, (draft) => {
|
||||
const buffer = Buffer.from(draft.projects.resources[`${project}${uri}`], 'base64');
|
||||
const json = JSONB.parse(buffer);
|
||||
applyPatch(json, patch);
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
draft.projects.resources[`${project}${uri}`] = JSONB.bufferify(json).toString('base64');
|
||||
});
|
||||
},
|
||||
'@latus/redux/reducers': () => reducer,
|
||||
'@persea/core/resource-renderers': () => [
|
||||
JsonResourceComponent,
|
||||
],
|
||||
|
|
19
packages/json/src/state/reducer.js
Normal file
19
packages/json/src/state/reducer.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import {JSONB} from '@avocado/resource';
|
||||
import {createNextState} from '@latus/redux';
|
||||
import {applyPatch} from 'fast-json-patch';
|
||||
|
||||
import {patchJsonResource} from './json';
|
||||
|
||||
export default (state, {payload, type}) => {
|
||||
if (type !== patchJsonResource.toString()) {
|
||||
return state;
|
||||
}
|
||||
const {patch, project, uri} = payload;
|
||||
return createNextState(state, (draft) => {
|
||||
const buffer = Buffer.from(draft.projects.resources[`${project}${uri}`], 'base64');
|
||||
const json = JSONB.parse(buffer);
|
||||
applyPatch(json, patch);
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
draft.projects.resources[`${project}${uri}`] = JSONB.bufferify(json).toString('base64');
|
||||
});
|
||||
};
|
Loading…
Reference in New Issue
Block a user