diff --git a/app/frontend.js b/app/frontend.js
index 47cf49814b5cfa2c75283087c5a3c8cae3eb3321..24eb72c44cb315f83a883ff59c0a359d65a77d85 100644
--- a/app/frontend.js
+++ b/app/frontend.js
@@ -21,8 +21,6 @@ if (__DEV__) {
const compiler = webpack(webpackConfig);
const app = express();
- app.use(apiEndpoint + '/algorithm', express.static(algorithmApiSrcPath));
- app.use(apiEndpoint + '/wiki', express.static(wikiApiSrcPath));
app.use(express.static(path.resolve(frontendSrcPath, 'static')));
app.use(webpackDev(compiler, {
stats: {
diff --git a/app/index.js b/app/index.js
index 322286f487649b0514348e8e1efe8dd8a0a9fe1a..ce2b1c3fc252fbd934f31a10335f7950ebc6bf38 100644
--- a/app/index.js
+++ b/app/index.js
@@ -8,8 +8,8 @@ const {
} = require('../environment');
const frontend = require('./frontend');
-//const backend = require('./backend');
-//app.use(apiEndpoint, backend);
+const backend = require('./backend');
+app.use(apiEndpoint, backend);
app.use(history());
app.use(compression());
app.use(frontend);
diff --git a/bin/temporary_action.js b/bin/temporary_action.js
new file mode 100644
index 0000000000000000000000000000000000000000..1494087563fa4290a6981f0fa44060ed883b7610
--- /dev/null
+++ b/bin/temporary_action.js
@@ -0,0 +1,57 @@
+const path = require('path');
+const fs = require('fs');
+
+const getPath = (...args) => path.resolve(__dirname, '..', 'algorithm', ...args);
+
+const readCategories = () => {
+ const createKey = name => name.toLowerCase().replace(/ /g, '-');
+ const subdirectories = dirPath => fs.readdirSync(dirPath).filter(subdir => !subdir.startsWith('.'));
+ const getCategory = categoryName => {
+ const categoryPath = getPath(categoryName);
+ const categoryKey = createKey(categoryName);
+ const algorithms = subdirectories(categoryPath).map(algorithmName => getAlgorithm(categoryName, algorithmName));
+ return {
+ key: categoryKey,
+ name: categoryName,
+ algorithms,
+ };
+ };
+ const getAlgorithm = (categoryName, algorithmName) => {
+ const algorithmPath = getPath(categoryName, algorithmName);
+ const algorithmKey = createKey(algorithmName);
+ const files = subdirectories(algorithmPath).filter(fileName => fileName !== 'desc.json');
+ return {
+ key: algorithmKey,
+ name: algorithmName,
+ files,
+ }
+ };
+ return subdirectories(getPath()).map(getCategory);
+};
+
+const categories = readCategories();
+
+categories.forEach(category => {
+ category.algorithms.forEach(algorithm => {
+ algorithm.files.forEach(fileKey => {
+ const fileName = ['basic', 'normal'].includes(fileKey) ? algorithm.name : fileKey.split('_').map(s => s.charAt(0).toUpperCase() + s.slice(1)).join(' ');
+ const oldPath = getPath(category.name, algorithm.name, fileKey);
+ const newPath = getPath(category.name, algorithm.name, fileName);
+ //fs.renameSync(oldPath, newPath);
+ console.log(oldPath + '->', newPath);
+ })
+ })
+});
+
+/*Object.values(hierarchy).forEach(({ name: categoryName, list }) => {
+ Object.values(list).forEach(algorithmName => {
+ const desc = require(path.resolve(algorithmPath, categoryName, algorithmName, 'desc.json'));
+ Object.keys(desc.files).forEach(fileKey => {
+ const fileName = fileKey.split('_').map(s => s.charAt(0).toUpperCase() + s.slice(1)).join(' ');
+ const oldPath = path.resolve(algorithmPath, categoryName, algorithmName, fileKey);
+ const newPath = path.resolve(algorithmPath, categoryName, algorithmName, fileName);
+ //fs.renameSync(newPath, oldPath);
+ console.log(oldPath, newPath);
+ });
+ });
+});*/
\ No newline at end of file
diff --git a/environment.js b/environment.js
index fd674cc9e82b8372786b067d7f99dd3a6cb0a522..d1d2e6521472c8ab282bd5afd2ba0d264e797de9 100644
--- a/environment.js
+++ b/environment.js
@@ -16,16 +16,10 @@ const proxyPort = parseInt(PROXY_PORT);
const builtPath = path.resolve(__dirname, 'built');
const frontendBuiltPath = path.resolve(builtPath, 'frontend');
const backendBuiltPath = path.resolve(builtPath, 'backend');
-const apiBuiltPath = path.resolve(frontendBuiltPath, 'api');
-const algorithmApiBuiltPath = path.resolve(apiBuiltPath, 'algorithm');
-const wikiApiBuiltPath = path.resolve(apiBuiltPath, 'wiki');
const srcPath = path.resolve(__dirname, 'src');
const frontendSrcPath = path.resolve(srcPath, 'frontend');
const backendSrcPath = path.resolve(srcPath, 'backend');
-const apiSrcPath = path.resolve(__dirname);
-const algorithmApiSrcPath = path.resolve(apiSrcPath, 'algorithm');
-const wikiApiSrcPath = path.resolve(apiSrcPath, 'wiki');
const apiEndpoint = '/api';
@@ -36,13 +30,7 @@ module.exports = {
proxyPort,
frontendBuiltPath,
backendBuiltPath,
- apiBuiltPath,
- algorithmApiBuiltPath,
- wikiApiBuiltPath,
frontendSrcPath,
backendSrcPath,
- apiSrcPath,
- algorithmApiSrcPath,
- wikiApiSrcPath,
apiEndpoint,
};
\ No newline at end of file
diff --git a/src/backend/controllers/auth.js b/src/backend/controllers/auth.js
deleted file mode 100644
index d4cd7a85bef8500478a795479b48f507a1b2ebd5..0000000000000000000000000000000000000000
--- a/src/backend/controllers/auth.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import express from 'express';
-
-const router = express.Router();
-
-const createAuth = (req, res, next) => {
- res.json({});
-};
-
-const destroyAuth = (req, res, next) => {
- res.json({});
-};
-
-router.route('/')
- .post(createAuth)
- .delete(destroyAuth);
-
-export default router;
\ No newline at end of file
diff --git a/src/backend/controllers/directory.js b/src/backend/controllers/directory.js
new file mode 100644
index 0000000000000000000000000000000000000000..09f45ea0c22b5c20d6cb726fbf0ffc8031dc0f91
--- /dev/null
+++ b/src/backend/controllers/directory.js
@@ -0,0 +1,95 @@
+import express from 'express';
+import fs from 'fs';
+import path from 'path';
+import { NotFoundError } from '/common/error';
+
+const router = express.Router();
+
+const getPath = (...args) => path.resolve(__dirname, '..', '..', '..', 'algorithm', ...args);
+
+const readCategories = () => {
+ const createKey = name => name.toLowerCase().replace(/ /g, '-');
+ const list = dirPath => fs.readdirSync(dirPath).filter(filename => !/\./.test(filename)); // visible directories only
+ const getCategory = categoryName => {
+ const categoryKey = createKey(categoryName);
+ const categoryPath = getPath(categoryName);
+ const algorithms = list(categoryPath).map(algorithmName => getAlgorithm(categoryName, algorithmName));
+ return {
+ key: categoryKey,
+ name: categoryName,
+ algorithms,
+ };
+ };
+ const getAlgorithm = (categoryName, algorithmName) => {
+ const algorithmKey = createKey(algorithmName);
+ const algorithmPath = getPath(categoryName, algorithmName);
+ const files = list(algorithmPath).map(fileName => getFile(categoryName, algorithmName, fileName));
+ return {
+ key: algorithmKey,
+ name: algorithmName,
+ files,
+ }
+ };
+ const getFile = (categoryName, algorithmName, fileName) => {
+ const fileKey = createKey(fileName);
+ return {
+ key: fileKey,
+ name: fileName,
+ };
+ };
+ return list(getPath()).map(getCategory);
+};
+
+const categories = readCategories();
+
+const getCategories = (req, res, next) => {
+ res.json({ categories });
+};
+
+const getFile = (req, res, next) => {
+ const { categoryKey, algorithmKey, fileKey } = req.params;
+
+ const category = categories.find(category => category.key === categoryKey);
+ if (!category) return next(new NotFoundError());
+ const algorithm = category.algorithms.find(algorithm => algorithm.key === algorithmKey);
+ if (!algorithm) return next(new NotFoundError());
+ const file = algorithm.files.find(file => file.key === fileKey);
+ if (!file) return next(new NotFoundError());
+
+ const dataPath = getPath(category.name, algorithm.name, file.name, 'data.js');
+ const codePath = getPath(category.name, algorithm.name, file.name, 'code.js');
+ fs.readFile(dataPath, 'utf8', (err, data) => {
+ if (err) return next(err);
+ fs.readFile(codePath, 'utf8', (err, code) => {
+ if (err) return next(err);
+ res.json({ data, code });
+ });
+ });
+};
+
+const getDescription = (req, res, next) => {
+ const { categoryKey, algorithmKey } = req.params;
+
+ const category = categories.find(category => category.key === categoryKey);
+ if (!category) return next(new NotFoundError());
+ const algorithm = category.algorithms.find(algorithm => algorithm.key === algorithmKey);
+ if (!algorithm) return next(new NotFoundError());
+
+ const descriptionPath = getPath(category.name, algorithm.name, 'desc.json');
+ fs.readFile(descriptionPath, 'utf8', (err, raw) => {
+ if (err) return next(err);
+ const description = JSON.parse(raw);
+ res.json({ description });
+ });
+};
+
+router.route('/')
+ .get(getCategories);
+
+router.route('/description/:categoryKey/:algorithmKey')
+ .get(getDescription);
+
+router.route('/:categoryKey/:algorithmKey/:fileKey')
+ .get(getFile);
+
+export default router;
\ No newline at end of file
diff --git a/src/backend/controllers/index.js b/src/backend/controllers/index.js
index ba02bbcfa7a7986f78dcac26eebbc09a3f7e76fe..9ea5fd545d93a49ef099f58ab62248480487549d 100644
--- a/src/backend/controllers/index.js
+++ b/src/backend/controllers/index.js
@@ -1,10 +1,12 @@
import express from 'express';
import { AuthorizationError, NotFoundError, PermissionError } from '/common/error';
-import auth from './auth';
+import directory from './directory';
+import wiki from './wiki';
const router = new express.Router();
-router.use('/auth', auth);
+router.use('/directory', directory);
+router.use('/wiki', wiki);
router.use((req, res, next) => next(new NotFoundError()));
router.use((err, req, res, next) => {
const statusMap = [
diff --git a/src/backend/controllers/wiki.js b/src/backend/controllers/wiki.js
new file mode 100644
index 0000000000000000000000000000000000000000..3b9174289e1db74185d5eab470cda477581f2ea1
--- /dev/null
+++ b/src/backend/controllers/wiki.js
@@ -0,0 +1,44 @@
+import express from 'express';
+import fs from 'fs';
+import path from 'path';
+import { NotFoundError } from '/common/error';
+
+const router = express.Router();
+
+const getPath = (...args) => path.resolve(__dirname, '..', '..', '..', 'wiki', ...args);
+
+const readWikis = () => {
+ const createKey = name => name.slice(0, -3);
+ const list = dirPath => fs.readdirSync(dirPath).filter(filename => /(\.md)$/.test(filename));
+ return list(getPath()).map(wikiName => ({
+ key: createKey(wikiName),
+ name: wikiName,
+ }));
+};
+
+const wikis = readWikis();
+
+const getWikis = (req, res, next) => {
+ res.json({ wikis });
+};
+
+const getWiki = (req, res, next) => {
+ const { wikiKey } = req.params;
+
+ const wiki = wikis.find(wiki => wiki.key === wikiKey);
+ if (!wiki) return next(new NotFoundError());
+
+ const wikiPath = getPath(wiki.name);
+ fs.readFile(wikiPath, 'utf8', (err, wiki) => {
+ if (err) return next(err);
+ res.json({ wiki });
+ });
+};
+
+router.route('/')
+ .get(getWikis);
+
+router.route('/:wikiKey')
+ .get(getWiki);
+
+export default router;
\ No newline at end of file
diff --git a/src/frontend/apis/index.js b/src/frontend/apis/index.js
index a684a0007c68607e09878ebc1da9c1edd8c51895..b9d55653d9d48e2a0f0036f90f1dd29496b25fa2 100644
--- a/src/frontend/apis/index.js
+++ b/src/frontend/apis/index.js
@@ -46,23 +46,23 @@ const PUT = URL => {
});
};
-const AlgorithmApi = {
- getCategories: GET('/algorithm/category.json'),
- getAlgorithm: GET('/algorithm/:category/:algorithm/desc.json'),
- getDataFile: GET('/algorithm/:category/:algorithm/:file/data.js'),
- getCodeFile: GET('/algorithm/:category/:algorithm/:file/code.js'),
-};
-
-const ScratchApi = {
- getScratch: GET('https://api.github.com/gists/:gist_id'),
+const DirectoryApi = {
+ getCategories: GET('/directory'),
+ getDescription: GET('/directory/description/:categoryKey/:algorithmKey'),
+ getFile: GET('/directory/:categoryKey/:algorithmKey/:fileKey'),
};
const WikiApi = {
+ getWikis: GET('/wiki'),
getWiki: GET('/wiki/:wiki'),
};
+const ScratchApi = {
+ getScratch: GET('https://api.github.com/gists/:gist_id'),
+};
+
export {
- AlgorithmApi,
- ScratchApi,
+ DirectoryApi,
WikiApi,
+ ScratchApi,
};
\ No newline at end of file
diff --git a/src/frontend/components/App/index.jsx b/src/frontend/components/App/index.jsx
index 7f58b7589ad5c28cf531ef95c454640a444e0902..b5fa1ec4acb556f2e767a425997fb0a4d9463496 100644
--- a/src/frontend/components/App/index.jsx
+++ b/src/frontend/components/App/index.jsx
@@ -5,7 +5,7 @@ import { Divider, EditorSection, Header, Navigator, ToastContainer, ViewerSectio
import { actions as toastActions } from '/reducers/toast';
import { actions as envActions } from '/reducers/env';
import { calculatePercentageWidth } from '/common/util';
-import { AlgorithmApi } from '/apis';
+import { DirectoryApi } from '/apis';
import { tracerManager } from '/core';
import styles from './stylesheet.scss';
import 'axios-progress-bar/dist/nprogress.css'
@@ -33,12 +33,13 @@ class App extends React.Component {
}
componentDidMount() {
- AlgorithmApi.getCategories()
- .then(categories => {
+ DirectoryApi.getCategories()
+ .then(({ categories }) => {
this.props.setCategories(categories);
- const categoryKey = Object.keys(categories)[0];
- const algorithmKey = Object.keys(categories[categoryKey].list)[0];
- this.props.selectAlgorithm(categoryKey, algorithmKey);
+ const [category] = categories;
+ const [algorithm] = category.algorithms;
+ const [file] = algorithm.files;
+ this.props.selectFile(category.key, algorithm.key, file.key);
});
tracerManager.setOnError(error => this.props.showErrorToast(error.message));
}
@@ -47,18 +48,6 @@ class App extends React.Component {
tracerManager.setOnError(null);
}
- componentWillReceiveProps(nextProp) {
- const { categoryKey, algorithmKey } = nextProp.env;
- if (categoryKey !== this.props.env.categoryKey || algorithmKey !== this.props.env.algorithmKey) {
- AlgorithmApi.getAlgorithm(categoryKey, algorithmKey)
- .then(algorithm => {
- this.props.setAlgorithm(algorithm);
- const fileKey = Object.keys(algorithm.files)[0];
- this.props.selectFile(categoryKey, algorithmKey, fileKey);
- });
- }
- }
-
toggleNavigator(navigatorOpened = !this.state.navigatorOpened) {
this.setState({ navigatorOpened });
}
@@ -75,15 +64,9 @@ class App extends React.Component {
render() {
const { navigatorOpened, navigatorWidth, viewerSectionWidth } = this.state;
- const { categories, algorithm } = this.props.env;
-
- if (!categories || !algorithm) {
- return (
-
- );
- }
+ const { categories, categoryKey, algorithmKey, fileKey } = this.props.env;
- return (
+ return categories && categoryKey && algorithmKey && fileKey && (
this.toggleNavigator()} navigatorOpened={navigatorOpened} />
this.elMain = ref}>
diff --git a/src/frontend/components/App/stylesheet.scss b/src/frontend/components/App/stylesheet.scss
index d46f94dab86c1a8df75350950a166bf2b3060d28..86f6b735997926c5aff49d2eab79ccb13a142795 100644
--- a/src/frontend/components/App/stylesheet.scss
+++ b/src/frontend/components/App/stylesheet.scss
@@ -12,8 +12,10 @@ body {
body {
font-family: 'Roboto', sans-serif;
-webkit-font-smoothing: subpixel-antialiased;
- color: $color-font;
user-select: none;
+ background-color: $theme-normal;
+ color: $color-font;
+ font-size: $font-size-normal;
}
a {
@@ -34,8 +36,6 @@ input {
flex-direction: column;
align-items: stretch;
height: 100%;
- background-color: $theme-normal;
- font-size: $font-size-normal;
.loading_slider {
position: absolute;
diff --git a/src/frontend/components/DescriptionViewer/index.jsx b/src/frontend/components/DescriptionViewer/index.jsx
index 6914cdc59f30262d2bcb874622fc7f1dc654f811..81dce629080677eac8bd9e7076ee70f7305efc55 100644
--- a/src/frontend/components/DescriptionViewer/index.jsx
+++ b/src/frontend/components/DescriptionViewer/index.jsx
@@ -3,6 +3,7 @@ import { connect } from 'react-redux';
import { classes } from '/common/util';
import { actions as envActions } from '/reducers/env';
import styles from './stylesheet.scss';
+import { DirectoryApi } from '/apis/index';
@connect(
({ env }) => ({
@@ -12,6 +13,32 @@ import styles from './stylesheet.scss';
}
)
class DescriptionViewer extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ description: null,
+ };
+ }
+
+ componentDidMount() {
+ const { categoryKey, algorithmKey } = this.props.env;
+ this.loadDescription(categoryKey, algorithmKey);
+ }
+
+ componentWillReceiveProps(nextProps) {
+ const { categoryKey, algorithmKey } = nextProps.env;
+ if (categoryKey !== this.props.env.categoryKey ||
+ algorithmKey !== this.props.env.algorithmKey) {
+ this.loadDescription(categoryKey, algorithmKey);
+ }
+ }
+
+ loadDescription(categoryKey, algorithmKey) {
+ DirectoryApi.getDescription(categoryKey, algorithmKey)
+ .then(({ description }) => this.setState({ description }));
+ }
+
getChild(value) {
if (typeof value === 'string') {
return (
@@ -44,15 +71,15 @@ class DescriptionViewer extends React.Component {
}
render() {
+ const { description } = this.state;
const { className } = this.props;
- const { algorithm } = this.props.env;
- return (
+ return description && (
{
- Object.keys(algorithm).map((key, i) => {
+ Object.keys(description).map((key, i) => {
if (key === 'files') return null;
- const value = algorithm[key];
+ const value = description[key];
return (
{key}
diff --git a/src/frontend/components/EditorSection/index.jsx b/src/frontend/components/EditorSection/index.jsx
index 69448c480d4f3b2b414b02d568dac59e1ff1fe20..0172f90b26808619744ba7cef612884c8932554b 100644
--- a/src/frontend/components/EditorSection/index.jsx
+++ b/src/frontend/components/EditorSection/index.jsx
@@ -8,18 +8,15 @@ import faInfoCircle from '@fortawesome/fontawesome-free-solid/faInfoCircle';
import { calculatePercentageHeight, classes } from '/common/util';
import { Divider, Ellipsis, TabBar } from '/components';
import { actions as envActions } from '/reducers/env';
-import { actions as tracerActions } from '/reducers/tracer';
import { tracerManager } from '/core';
-import { AlgorithmApi } from '/apis';
+import { DirectoryApi } from '/apis';
import styles from './stylesheet.scss';
@connect(
- ({ env, tracer }) => ({
+ ({ env }) => ({
env,
- tracer,
}), {
...envActions,
- ...tracerActions,
}
)
class EditorSection extends React.Component {
@@ -30,16 +27,22 @@ class EditorSection extends React.Component {
this.state = {
dataContainerHeight: '30%',
lineMarker: this.createLineMarker(lineIndicator),
+ data: '',
+ code: '',
};
}
componentDidMount() {
const { categoryKey, algorithmKey, fileKey } = this.props.env;
this.loadCodeAndData(categoryKey, algorithmKey, fileKey);
+ tracerManager.setDataGetter(() => this.state.data);
+ tracerManager.setCodeGetter(() => this.state.code);
tracerManager.setOnUpdateLineIndicator(lineIndicator => this.setState({ lineMarker: this.createLineMarker(lineIndicator) }));
}
componentWillUnmount() {
+ tracerManager.setDataGetter(null);
+ tracerManager.setCodeGetter(null);
tracerManager.setOnUpdateLineIndicator(null);
}
@@ -68,11 +71,11 @@ class EditorSection extends React.Component {
}
loadCodeAndData(categoryKey, algorithmKey, fileKey) {
- if (!fileKey) return;
- AlgorithmApi.getDataFile(categoryKey, algorithmKey, fileKey)
- .then(data => this.handleChangeData(data))
- .then(() => AlgorithmApi.getCodeFile(categoryKey, algorithmKey, fileKey))
- .then(code => this.handleChangeCode(code));
+ DirectoryApi.getFile(categoryKey, algorithmKey, fileKey)
+ .then(({ data, code }) => {
+ this.handleChangeData(data);
+ this.handleChangeCode(code);
+ });
}
handleResizeDataContainer(x, y) {
@@ -81,29 +84,23 @@ class EditorSection extends React.Component {
}
handleChangeData(data) {
- this.props.setData(data);
- this.executeData(data);
+ this.setState({ data }, () => tracerManager.runData());
}
handleChangeCode(code) {
- this.props.setCode(code);
- const { data } = this.props.tracer;
- this.executeData(data);
- }
-
- executeData(data) {
- tracerManager.runData(data);
+ this.setState({ code }, () => tracerManager.runData());
}
render() {
- const { dataContainerHeight, lineMarker } = this.state;
+ const { dataContainerHeight, lineMarker, data, code } = this.state;
const { className } = this.props;
- const { categoryKey, algorithmKey, fileKey, algorithm } = this.props.env;
- const { data, code } = this.props.tracer;
+ const { categories, categoryKey, algorithmKey, fileKey } = this.props.env;
- const fileKeys = Object.keys(algorithm.files);
+ const category = categories.find(category => category.key === categoryKey);
+ const algorithm = category.algorithms.find(algorithm => algorithm.key === algorithmKey);
+ const fileKeys = algorithm.files.map(file => file.key);
const tabIndex = fileKeys.findIndex(v => v === fileKey);
- const fileInfo = algorithm.files[fileKey];
+ const fileInfo = ''; // TODO
return (
diff --git a/src/frontend/components/Header/index.jsx b/src/frontend/components/Header/index.jsx
index 9abb39bc1ad7813da788688583af866ff99283e3..905a5d64707cbb0d8fff10015eff3ca8e2d1eefd 100644
--- a/src/frontend/components/Header/index.jsx
+++ b/src/frontend/components/Header/index.jsx
@@ -13,19 +13,16 @@ import faChevronLeft from '@fortawesome/fontawesome-free-solid/faChevronLeft';
import faPause from '@fortawesome/fontawesome-free-solid/faPause';
import faExpandArrowsAlt from '@fortawesome/fontawesome-free-solid/faExpandArrowsAlt';
import { actions as envActions } from '/reducers/env';
-import { actions as tracerActions } from '/reducers/tracer';
import { classes } from '/common/util';
import { Button, Ellipsis } from '/components';
import { tracerManager } from '/core';
import styles from './stylesheet.scss';
@connect(
- ({ env, tracer }) => ({
+ ({ env }) => ({
env,
- tracer,
}), {
...envActions,
- ...tracerActions,
}
)
class Header extends React.Component {
@@ -58,17 +55,16 @@ class Header extends React.Component {
const { interval, paused, started } = this.state;
const { className, onClickTitleBar, navigatorOpened } = this.props;
const { categories, categoryKey, algorithmKey } = this.props.env;
- const { data, code } = this.props.tracer;
- const { name: categoryName, list: algorithmList } = categories[categoryKey];
- const algorithmName = algorithmList[algorithmKey];
+ const category = categories.find(category => category.key === categoryKey);
+ const algorithm = category.algorithms.find(algorithm => algorithm.key === algorithmKey);
return (
@@ -80,9 +76,9 @@ class Header extends React.Component {
{
started ? (
-
+
) : (
-
+
)
}
{
- Object.keys(categories).map(categoryKey => {
- const { name, list } = categories[categoryKey];
- const categoryOpened = categoriesOpened[categoryKey];
- let algorithmKeys = Object.keys(list);
- if (!this.testQuery(name)) {
- algorithmKeys = algorithmKeys.filter(algorithmKey => this.testQuery(list[algorithmKey]));
- if (!algorithmKeys.length) return null;
+ categories.map(category => {
+ const categoryOpened = categoriesOpened[category.key];
+ let algorithms = category.algorithms;
+ if (!this.testQuery(category.name)) {
+ algorithms = algorithms.filter(algorithm => this.testQuery(algorithm.name));
+ if (!algorithms.length) return null;
}
return (
-
this.toggleCategory(categoryKey)} label={name}
+ this.toggleCategory(category.key)}
+ label={category.name}
opened={categoryOpened}>
{
- algorithmKeys.map(algorithmKey => {
- const name = list[algorithmKey];
- const selected = categoryKey === selectedCategoryKey && algorithmKey === selectedAlgorithmKey;
+ algorithms.map(algorithm => {
+ const selected = category.key === selectedCategoryKey && algorithm.key === selectedAlgorithmKey;
+ const [file] = algorithm.files;
return (
- this.props.selectAlgorithm(categoryKey, algorithmKey)}>
- {name}
+ this.props.selectFile(category.key, algorithm.key, file.key)}>
+ {algorithm.name}
)
})
diff --git a/src/frontend/components/ViewerSection/index.jsx b/src/frontend/components/ViewerSection/index.jsx
index 123214fb58104fef72571178c076c2a34d840332..e60a39cae4b79a281fdcaa3d5d345ee19704df76 100644
--- a/src/frontend/components/ViewerSection/index.jsx
+++ b/src/frontend/components/ViewerSection/index.jsx
@@ -1,17 +1,8 @@
import React from 'react';
-import { connect } from 'react-redux';
import { classes } from '/common/util';
import { DescriptionViewer, RendererContainer, TabBar, WikiViewer } from '/components';
-import { actions as envActions } from '/reducers/env';
import styles from './stylesheet.scss';
-@connect(
- ({ env }) => ({
- env
- }), {
- ...envActions
- }
-)
class ViewerSection extends React.Component {
constructor(props) {
super(props);
@@ -21,13 +12,6 @@ class ViewerSection extends React.Component {
};
}
- componentWillReceiveProps(nextProp) {
- const { algorithm } = nextProp.env;
- if (algorithm !== this.props.env.algorithm) {
- this.setTabIndex(0);
- }
- }
-
setTabIndex(tabIndex) {
this.setState({ tabIndex });
}
diff --git a/src/frontend/components/WikiViewer/index.jsx b/src/frontend/components/WikiViewer/index.jsx
index f93fee207f6abc6d904346dabf7724534668a727..25827c1a94955b81523e74eeb06037854f083b23 100644
--- a/src/frontend/components/WikiViewer/index.jsx
+++ b/src/frontend/components/WikiViewer/index.jsx
@@ -14,12 +14,12 @@ class WikiViewer extends React.Component {
}
componentDidMount() {
- this.load('Tracer');
+ this.loadWiki('Tracer');
}
- load(wikiKey) {
- WikiApi.getWiki(wikiKey + '.md')
- .then(wiki => this.setState({ wiki: `# ${wikiKey}\n${wiki}` }));
+ loadWiki(wikiKey) {
+ WikiApi.getWiki(wikiKey)
+ .then(({ wiki }) => this.setState({ wiki: `# ${wikiKey}\n${wiki}` }));
}
render() {
@@ -28,7 +28,7 @@ class WikiViewer extends React.Component {
const InnerLink = ({ href, ...rest }) => {
return /^\w+$/.test(href) ? (
- this.load(href)} />
+ this.loadWiki(href)} />
) : (
);
diff --git a/src/frontend/core/tracerManager.jsx b/src/frontend/core/tracerManager.jsx
index 787a5f62ce09e0e7ba9a5ddb12643ff964b610e1..86c6de7c7bbfbf13bb7b1f640ee91371977f3e26 100644
--- a/src/frontend/core/tracerManager.jsx
+++ b/src/frontend/core/tracerManager.jsx
@@ -1,10 +1,10 @@
import React from 'react';
import { Seed } from '/core';
import * as Tracers from '/core/tracers';
-import * as Datas from '/core/datas';
import { Tracer } from '/core/tracers';
-import { Array1DRenderer, Array2DRenderer, ChartRenderer, GraphRenderer, LogRenderer, Renderer } from '/core/renderers';
+import * as Datas from '/core/datas';
import { Array1DData, Array2DData, ChartData, Data, GraphData, LogData } from '/core/datas';
+import { Array1DRenderer, Array2DRenderer, ChartRenderer, GraphRenderer, LogRenderer, Renderer } from '/core/renderers';
Object.assign(window, Tracers);
Object.assign(window, Datas);
@@ -34,6 +34,14 @@ class TracerManager {
this.onError = onError;
}
+ setDataGetter(dataGetter) {
+ this.dataGetter = dataGetter;
+ }
+
+ setCodeGetter(codeGetter) {
+ this.codeGetter = codeGetter;
+ }
+
render() {
if (this.onRender) this.onRender(this.renderers);
}
@@ -58,6 +66,16 @@ class TracerManager {
if (this.onUpdateLineIndicator) this.onUpdateLineIndicator(lineIndicator);
}
+ getData(){
+ if(this.dataGetter) return this.dataGetter();
+ return null;
+ }
+
+ getCode(){
+ if(this.codeGetter) return this.codeGetter();
+ return null;
+ }
+
reset(seed) {
this.traces = seed.traces;
this.resetCursor();
@@ -156,11 +174,14 @@ class TracerManager {
}
}
- runData(data) {
+ runData() {
+ const data = this.getData();
this.execute(data, '', () => this.applyTraceChunk());
}
- run(data, code) {
+ run() {
+ const data = this.getData();
+ const code = this.getCode();
const error = this.execute(data, code, () => this.resume());
if (error) {
this.handleError(error);
diff --git a/src/frontend/reducers/env.js b/src/frontend/reducers/env.js
index 60912d496cff0e90e22493b19d96dc70cd6fc85b..e59d4382428bd8c115de4efe5451a3b6026f4e31 100644
--- a/src/frontend/reducers/env.js
+++ b/src/frontend/reducers/env.js
@@ -3,12 +3,6 @@ import { combineActions, createAction, handleActions } from 'redux-actions';
const prefix = 'ENV';
const setCategories = createAction(`${prefix}/SET_CATEGORIES`, categories => ({ categories }));
-const selectAlgorithm = createAction(`${prefix}/SELECT_ALGORITHM`, (categoryKey, algorithmKey) => ({
- categoryKey,
- algorithmKey,
- fileKey: null,
-}));
-const setAlgorithm = createAction(`${prefix}/SET_ALGORITHM`, algorithm => ({ algorithm }));
const selectFile = createAction(`${prefix}/SELECT_FILE`, (categoryKey, algorithmKey, fileKey) => ({
categoryKey,
algorithmKey,
@@ -17,8 +11,6 @@ const selectFile = createAction(`${prefix}/SELECT_FILE`, (categoryKey, algorithm
export const actions = {
setCategories,
- selectAlgorithm,
- setAlgorithm,
selectFile,
};
@@ -29,14 +21,11 @@ const mutables = {
categoryKey: null,
algorithmKey: null,
fileKey: null,
- algorithm: null,
};
export default handleActions({
[combineActions(
setCategories,
- selectAlgorithm,
- setAlgorithm,
selectFile,
)]: (state, { payload }) => ({
...state,
diff --git a/src/frontend/reducers/index.js b/src/frontend/reducers/index.js
index af4efde1617611e80da2991c76af4885b7bd4785..b3eb7c62073b75eb52fc85391a2dc6850373445a 100644
--- a/src/frontend/reducers/index.js
+++ b/src/frontend/reducers/index.js
@@ -1,3 +1,2 @@
export { default as env } from './env';
-export { default as toast } from './toast';
-export { default as tracer } from './tracer';
\ No newline at end of file
+export { default as toast } from './toast';
\ No newline at end of file
diff --git a/src/frontend/reducers/tracer.js b/src/frontend/reducers/tracer.js
deleted file mode 100644
index 2d827274ce8e32ba18e298502b22c9ec4a75b016..0000000000000000000000000000000000000000
--- a/src/frontend/reducers/tracer.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import { combineActions, createAction, handleActions } from 'redux-actions';
-
-const prefix = 'TRACER';
-
-const setData = createAction(`${prefix}/SET_DATA`, data => ({ data }));
-const setCode = createAction(`${prefix}/SET_CODE`, code => ({ code }));
-
-export const actions = {
- setData,
- setCode,
-};
-
-const immutables = {};
-
-const mutables = {
- data: '',
- code: '',
-};
-
-export default handleActions({
- [combineActions(
- setData,
- setCode,
- )]: (state, { payload }) => ({
- ...state,
- ...payload,
- }),
-}, {
- ...immutables,
- ...mutables,
-});
diff --git a/webpack.backend.config.js b/webpack.backend.config.js
index ec3af9c0c950a78525fa8f6a5263d8f4423bf789..be0f76a8e9c3bfea78e8ac5f26ce813e797e4b65 100644
--- a/webpack.backend.config.js
+++ b/webpack.backend.config.js
@@ -18,6 +18,9 @@ fs.readdirSync(srcPath).forEach(name => {
module.exports = {
target: 'node',
+ node: {
+ __dirname: true,
+ },
entry: srcPath,
externals: [nodeExternals()],
resolve: {
diff --git a/webpack.frontend.config.js b/webpack.frontend.config.js
index 83ef3dece1bbfaef8e2373ecacbf096636cd59ab..a1c0946572d24e0efcd87a3d14c9d32998c95add 100644
--- a/webpack.frontend.config.js
+++ b/webpack.frontend.config.js
@@ -13,11 +13,7 @@ const {
__PROD__,
__DEV__,
frontendBuiltPath: builtPath,
- algorithmApiBuiltPath,
- wikiApiBuiltPath,
frontendSrcPath: srcPath,
- algorithmApiSrcPath,
- wikiApiSrcPath,
} = require('./environment');
const filter = arr => arr.filter(v => v);
@@ -102,11 +98,7 @@ module.exports = {
},
plugins: filter([
new CleanWebpackPlugin([builtPath]),
- new CopyWebpackPlugin([
- { from: path.resolve(srcPath, 'static'), to: builtPath },
- { from: algorithmApiSrcPath, to: algorithmApiBuiltPath },
- { from: wikiApiSrcPath, to: wikiApiBuiltPath },
- ]),
+ new CopyWebpackPlugin([{ from: path.resolve(srcPath, 'static'), to: builtPath }]),
new HtmlWebpackPlugin({
template: path.resolve(srcPath, 'template.html'),
hash: false,