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,