diff --git a/client/config/design/component_map.js b/client/config/design/component_map.js
new file mode 100644
index 0000000..f599bcd
--- /dev/null
+++ b/client/config/design/component_map.js
@@ -0,0 +1 @@
+export const COMPONENT_MAP = {"about":"dashboard/about/about","energy":"dashboard/energy/energy","energy_graph":"dashboard/energy/graph/graph","energy_table":"dashboard/energy/table/table","house":"dashboard/house/house","layout":"dashboard/layout/layout","power_graph":"dashboard/power/graph/graph","power":"dashboard/power/power","power_table":"dashboard/power/table/table"}
\ No newline at end of file
diff --git a/client/config/design/styles.js b/client/config/design/styles.js
index ad8f27d..544c90f 100644
--- a/client/config/design/styles.js
+++ b/client/config/design/styles.js
@@ -1,16 +1,11 @@
-const STYLE_ROUTES = Object.freeze({
- energy: 'dashboard/energy/energy.scss',
- layout: 'dashboard/layout/layout.scss',
- power: 'dashboard/power/power.scss',
- app: 'dashboard/app.scss'
-});
+import {COMPONENT_MAP} from './component_map';
class Styles {
static sync(){
var all = [],
css = '';
- for (var view in STYLE_ROUTES){
+ for (var view in COMPONENT_MAP){
var done = new Promise((fnResolve, fnReject)=>{
Styles.addCss(view, fnResolve)
}).then((result)=>{
@@ -26,7 +21,7 @@ class Styles {
static addCss(view, fnResolve){
return jQuery.ajax({
- url: STYLE_ROUTES[view]
+ url: COMPONENT_MAP[view] + '.scss'
}).then((scss)=>{
var sass = new Sass();
if (!scss) return fnResolve("");
diff --git a/client/config/design/template_map.js b/client/config/design/template_map.js
new file mode 100644
index 0000000..a99062c
--- /dev/null
+++ b/client/config/design/template_map.js
@@ -0,0 +1 @@
+export const TEMPLATE_MAP = {"about":"dashboard/about/about.rt","energy":"dashboard/energy/energy.rt","energy_graph":"dashboard/energy/graph/graph.rt","energy_table":"dashboard/energy/table/table.rt","house":"dashboard/house/house.rt","layout":"dashboard/layout/layout.rt","power_graph":"dashboard/power/graph/graph.rt","power":"dashboard/power/power.rt","power_table":"dashboard/power/table/table.rt"}
\ No newline at end of file
diff --git a/client/config/design/templates.js b/client/config/design/templates.js
index c798681..7a94949 100644
--- a/client/config/design/templates.js
+++ b/client/config/design/templates.js
@@ -2,14 +2,7 @@ import rt from 'react-templates';
import React from 'react';
import _ from 'lodash';
-import Energy from './../../dashboard/energy/energy';
-import Power from './../../dashboard/power/power';
-
-const TEMPLATE_ROUTES = Object.freeze({
- energy: 'dashboard/energy/energy.rt',
- layout: 'dashboard/layout/layout.rt',
- power: 'dashboard/power/power.rt'
-});
+import {COMPONENT_MAP} from './component_map';
var TEMPLATES = {};
@@ -17,32 +10,32 @@ class Templates {
static sync(){
var all = [];
- for (var view in TEMPLATE_ROUTES){
+ for (var component_name in COMPONENT_MAP){
var done = new Promise((fnResolve, fnReject)=>{
- Templates.evalTemplate(view, fnResolve);
+ Templates.evalTemplate(component_name, fnResolve);
});
all.push(done);
}
return Promise.all(all);
}
- static forComponent(view){
- return TEMPLATES[view];
+ static forComponent(name){
+ return TEMPLATES[name];
}
- static evalTemplate(view, fnResolve){
+ static evalTemplate(component_name, fnResolve){
jQuery.ajax({
- url: TEMPLATE_ROUTES[view]
+ url: COMPONENT_MAP[component_name] + '.rt'
}).done((template)=>{
- var code = rt.convertTemplateToReact(template, {modules: 'none', name: view}),
+ var code = rt.convertTemplateToReact(template, {modules: 'none', name: component_name}),
eval_context = {};
- code = code.replace('var ' + view + ' = ', 'eval_context.' + view + ' = ');
+ code = code.replace('var ' + component_name + ' = ', 'eval_context.' + component_name + ' = ');
new Function('with(this){ ' + code + ' } ').call({
eval_context: eval_context,
'_': _,
'React': React
});
- TEMPLATES[view] = eval_context[view];
+ TEMPLATES[component_name] = eval_context[component_name];
fnResolve();
});
}
diff --git a/client/dashboard/about/about.scss b/client/dashboard/about/about.scss
new file mode 100644
index 0000000..fbbd802
--- /dev/null
+++ b/client/dashboard/about/about.scss
@@ -0,0 +1,3 @@
+#about {
+
+}
diff --git a/client/dashboard/energy/graph/graph.scss b/client/dashboard/energy/graph/graph.scss
new file mode 100644
index 0000000..5d203a6
--- /dev/null
+++ b/client/dashboard/energy/graph/graph.scss
@@ -0,0 +1,3 @@
+#energy_graph {
+
+}
diff --git a/client/dashboard/energy/table/table.rt b/client/dashboard/energy/table/table.rt
index 6b54504..72a6da7 100644
--- a/client/dashboard/energy/table/table.rt
+++ b/client/dashboard/energy/table/table.rt
@@ -1,4 +1,4 @@
-
+
|
diff --git a/client/dashboard/energy/table/table.scss b/client/dashboard/energy/table/table.scss
new file mode 100644
index 0000000..d7bfd55
--- /dev/null
+++ b/client/dashboard/energy/table/table.scss
@@ -0,0 +1,3 @@
+#energy_table {
+
+}
diff --git a/client/dashboard/house/house.scss b/client/dashboard/house/house.scss
new file mode 100644
index 0000000..bf6684c
--- /dev/null
+++ b/client/dashboard/house/house.scss
@@ -0,0 +1 @@
+#house {}
diff --git a/client/dashboard/power/graph/graph.scss b/client/dashboard/power/graph/graph.scss
new file mode 100644
index 0000000..1c41eca
--- /dev/null
+++ b/client/dashboard/power/graph/graph.scss
@@ -0,0 +1,3 @@
+#power_graph {
+
+}
diff --git a/client/dashboard/power/table/table.rt b/client/dashboard/power/table/table.rt
index 86e1f85..0482182 100644
--- a/client/dashboard/power/table/table.rt
+++ b/client/dashboard/power/table/table.rt
@@ -1,4 +1,4 @@
-
+
|
diff --git a/client/dashboard/power/table/table.scss b/client/dashboard/power/table/table.scss
new file mode 100644
index 0000000..f0165f4
--- /dev/null
+++ b/client/dashboard/power/table/table.scss
@@ -0,0 +1,3 @@
+#power_table {
+
+}
diff --git a/gulpfile.babel.js b/gulpfile.babel.js
index 2105d0e..0b1973a 100644
--- a/gulpfile.babel.js
+++ b/gulpfile.babel.js
@@ -3,6 +3,8 @@ import yargs from 'yargs';
import webpack from 'webpack';
import gutil from 'gulp-util';
+import FsHelper from './server/lib/fs_helper';
+import ComponentMapWriter from './server/lib/tasks/component_map_writer';
import DB from './server/config/database';
import {PowerDataSeed, HouseSeed} from './server/lib/tasks/seed_data';
import rtCompile from './server/lib/tasks/react_template_compile';
@@ -41,35 +43,38 @@ gulp.task('build', function(done) {
gulpCopy = require('gulp-copy');
if (yargs.argv.design){
- process.env.NODE_ENV = process.env.NODE_ENV || 'design';
+ process.env.NODE_ENV = 'design';
} else {
- throw new gutil.PluginError("webpack", "Must include '--production' or '--design' option.");
+ throw new gutil.PluginError("webpack", "Must include '--design' option.");
}
- config = require(`${__dirname}/client/config/${process.env.NODE_ENV}/webpack.js`);
- // run webpack
- webpack(config, function(err, stats) {
- if(err) throw new gutil.PluginError("webpack", err);
- gutil.log("[webpack]", stats.toString({
- // output options
- }));
- if (yargs.argv.design){
- gulp.src([
- `client/app.scss`
- ]).pipe(gulpCopy(`client/build/design/dashboard`, {prefix: 1}));
- gulp.src([
- `client/dashboard/layout/layout.rt`,
- `client/dashboard/layout/layout.scss`,
- ]).pipe(gulpCopy(`client/build/design/dashboard/layout`, {prefix: 3}));
- gulp.src([
- `client/dashboard/energy/energy.rt`,
- `client/dashboard/energy/energy.scss`,
- ]).pipe(gulpCopy(`client/build/design/dashboard/energy`, {prefix: 3}));
- gulp.src([
- `client/dashboard/power/power.rt`,
- `client/dashboard/power/power.scss`,
- ]).pipe(gulpCopy(`client/build/design/dashboard/power`, {prefix: 3}));
- }
- done();
- });
+ // write template map.
+ ComponentMapWriter.write(__dirname + '/client/config/design/component_map.js')
+ .then(()=>{
+
+ // build assets/app.js and assets/style.css
+ config = require(`${__dirname}/client/config/${process.env.NODE_ENV}/webpack.js`);
+ webpack(config, function(err, stats) {
+ if(err) throw new gutil.PluginError("webpack", err);
+ gutil.log("[webpack]", stats.toString({}));
+
+ if (yargs.argv.design){
+ // copy all react templates and their styles sheets into build/design/dashboard.
+ gulp.src([
+ `client/app.scss`
+ ]).pipe(gulpCopy(`client/build/design/dashboard`, {prefix: 1}));
+
+ FsHelper.walk('client/dashboard', (err, files)=>{
+ var files_to_copy = files.filter((file)=>{
+ return /\.(rt|scss)$/.test(file)
+ });
+ gulp.src(files_to_copy)
+ .pipe(gulpCopy('client/build/design/dashboard', {prefix: 2}));
+ done()
+ });
+ }
+
+ });
+
+ });
});
diff --git a/server/lib/fs_helper.js b/server/lib/fs_helper.js
new file mode 100644
index 0000000..7068e56
--- /dev/null
+++ b/server/lib/fs_helper.js
@@ -0,0 +1,33 @@
+import fs from 'fs';
+import path from 'path';
+
+class FsHelper {
+
+ // http://stackoverflow.com/questions/5827612/node-js-fs-readdir-recursive-directory-search
+ static walk(dir, done) {
+ var results = [];
+ fs.readdir(dir, function(err, list) {
+ if (err) return done(err);
+ var i = 0;
+ (function next() {
+ var file = list[i++];
+ if (!file) return done(null, results);
+ file = path.resolve(dir, file);
+ fs.stat(file, function(err, stat) {
+ if (stat && stat.isDirectory()) {
+ FsHelper.walk(file, function(err, res) {
+ results = results.concat(res);
+ next();
+ });
+ } else {
+ results.push(file);
+ next();
+ }
+ });
+ })();
+ });
+ }
+
+}
+
+export default FsHelper;
diff --git a/server/lib/tasks/component_map_writer.js b/server/lib/tasks/component_map_writer.js
new file mode 100644
index 0000000..1c4908c
--- /dev/null
+++ b/server/lib/tasks/component_map_writer.js
@@ -0,0 +1,31 @@
+import FsHelper from './../fs_helper';
+import fs from 'fs';
+
+class ComponentMapWriter {
+ static write(path){
+
+ return new Promise((fnResolve, fnReject)=>{
+ var TEMPLATE_ROUTES = {};
+ FsHelper.walk(__dirname + '/../../../client/dashboard', (err, files)=>{
+ files.forEach((file)=>{
+ if (!/\.component\.js$/.test(file)) return true;
+
+ var rel_path = file.match(/dashboard\/.+/)[0].replace('.component.js', ''),
+ parts = file.match(/dashboard\/([^\/]+).*\/([^\/]+)\.component\.js$/),
+ template_name;
+ if (parts[1] === parts[2]) template_name = parts[1];
+ else template_name = parts[1] + '_' + parts[2];
+
+ TEMPLATE_ROUTES[template_name] = rel_path;
+ });
+
+ var content = 'export const COMPONENT_MAP = ' + JSON.stringify(TEMPLATE_ROUTES);
+ fs.writeFile(path, content, function(err) {
+ fnResolve();
+ });
+ });
+ });
+ }
+}
+
+export default ComponentMapWriter;