Changes to the app

This commit is contained in:
Andrew Revinsky (DART)
2016-08-26 14:13:50 +03:00
parent ef444bde9b
commit 1e7234166a
9 changed files with 324 additions and 90 deletions

View File

@@ -0,0 +1,11 @@
/**
* Created by andrew on 8/18/16.
*/
export const useJSON = () => {};
export const clean = () => {};
export const useJQuery = () => {};
export const extractBundle = () => {};
export const extractLESS = () => {};
export const purifyCSS = () => {};
export const setupLess = () => {};
export const devServer = () => {};

View File

@@ -23,6 +23,7 @@
"babel-preset-stage-0": "6.1.2",
"babel-register": "6.1.4",
"babel-runtime": "^6.0.14",
"copy-webpack-plugin": "^3.0.1",
"css-loader": "^0.14.4",
"del": "^1.2.0",
"extract-text-webpack-plugin": "^0.8.1",
@@ -35,6 +36,7 @@
"gulp-load-plugins": "^0.10.0",
"gulp-size": "^1.2.1",
"gulp-util": "^3.0.5",
"html-webpack-plugin": "^2.22.0",
"json-loader": "^0.5.4",
"less": "^2.5.3",
"less-loader": "^2.2.0",
@@ -45,7 +47,9 @@
"style-loader": "^0.12.3",
"url-loader": "^0.5.6",
"webpack": "^1.9.10",
"webpack-dev-server": "^1.9.0"
"webpack-dev-server": "^1.9.0",
"webpack-merge": "^0.14.1",
"webpack-validator": "^2.2.7"
},
"dependencies": {
"classnames": "^2.2.3",

View File

@@ -1,81 +1,81 @@
import defineActionTypes from '../utils/defineActionTypes'
import { TODO_DEFINE, defineActionType } from '../utils/defineActionTypes'
export default defineActionTypes({
export default defineActionType({
/*
* View model
*/
AUTH: `
CONFIGURE_START
CONFIGURE_COMPLETE
CONFIGURE_ERROR
AUTHENTICATE_START
AUTHENTICATE_COMPLETE
AUTHENTICATE_ERROR
SIGN_IN_START
SIGN_IN_COMPLETE
SIGN_IN_ERROR
SIGN_IN_FORM_UPDATE
SIGN_UP_START
SIGN_UP_COMPLETE
SIGN_UP_ERROR
SIGN_UP_FORM_UPDATE
SIGN_OUT_START
SIGN_OUT_COMPLETE
`,
AUTH: {
CONFIGURE_START: TODO_DEFINE,
CONFIGURE_COMPLETE: TODO_DEFINE,
CONFIGURE_ERROR: TODO_DEFINE,
AUTHENTICATE_START: TODO_DEFINE,
AUTHENTICATE_COMPLETE: TODO_DEFINE,
AUTHENTICATE_ERROR: TODO_DEFINE,
SIGN_IN_START: TODO_DEFINE,
SIGN_IN_COMPLETE: TODO_DEFINE,
SIGN_IN_ERROR: TODO_DEFINE,
SIGN_IN_FORM_UPDATE: TODO_DEFINE,
SIGN_UP_START: TODO_DEFINE,
SIGN_UP_COMPLETE: TODO_DEFINE,
SIGN_UP_ERROR: TODO_DEFINE,
SIGN_UP_FORM_UPDATE: TODO_DEFINE,
SIGN_OUT_START: TODO_DEFINE,
SIGN_OUT_COMPLETE: TODO_DEFINE
},
ENTITIES: `
REQUESTED
RECEIVED
RECEIVED_LIST
`,
ENTITIES: {
REQUESTED: TODO_DEFINE,
RECEIVED: TODO_DEFINE,
RECEIVED_LIST: TODO_DEFINE
},
ACCOUNTS: `
LIST_START
LIST_COMPLETE
LIST_ERROR
LIST_REF_START
LIST_REF_COMPLETE
LIST_REF_ERROR
CREATE_START
CREATE_COMPLETE
CREATE_ERROR
CREATE_FORM_UPDATE
EDIT_START
EDIT_COMPLETE
EDIT_ERROR
EDIT_FORM_UPDATE
CREATE_REF_START
CREATE_REF_COMPLETE
CREATE_REF_ERROR
CREATE_REF_FORM_UPDATE
CREATE_REF_OWNER_LOOKUP_START
CREATE_REF_OWNER_LOOKUP_COMPLETE
CREATE_REF_ACCOUNT_LOOKUP_START
CREATE_REF_ACCOUNT_LOOKUP_COMPLETE
`,
ACCOUNTS: {
LIST_START: TODO_DEFINE,
LIST_COMPLETE: TODO_DEFINE,
LIST_ERROR: TODO_DEFINE,
LIST_REF_START: TODO_DEFINE,
LIST_REF_COMPLETE: TODO_DEFINE,
LIST_REF_ERROR: TODO_DEFINE,
CREATE_START: TODO_DEFINE,
CREATE_COMPLETE: TODO_DEFINE,
CREATE_ERROR: TODO_DEFINE,
CREATE_FORM_UPDATE: TODO_DEFINE,
EDIT_START: TODO_DEFINE,
EDIT_COMPLETE: TODO_DEFINE,
EDIT_ERROR: TODO_DEFINE,
EDIT_FORM_UPDATE: TODO_DEFINE,
CREATE_REF_START: TODO_DEFINE,
CREATE_REF_COMPLETE: TODO_DEFINE,
CREATE_REF_ERROR: TODO_DEFINE,
CREATE_REF_FORM_UPDATE: TODO_DEFINE,
CREATE_REF_OWNER_LOOKUP_START: TODO_DEFINE,
CREATE_REF_OWNER_LOOKUP_COMPLETE: TODO_DEFINE,
CREATE_REF_ACCOUNT_LOOKUP_START: TODO_DEFINE,
CREATE_REF_ACCOUNT_LOOKUP_COMPLETE: TODO_DEFINE
},
ACCOUNT: `
SINGLE_START
SINGLE_COMPLETE
SINGLE_ERROR
DELETE_START
DELETE_COMPLETE
DELETE_ERROR
`,
ACCOUNT: {
SINGLE_START: TODO_DEFINE,
SINGLE_COMPLETE: TODO_DEFINE,
SINGLE_ERROR: TODO_DEFINE,
DELETE_START: TODO_DEFINE,
DELETE_COMPLETE: TODO_DEFINE,
DELETE_ERROR: TODO_DEFINE
},
TRANSFERS: `
MAKE_START
MAKE_COMPLETE
MAKE_ERROR
MAKE_FORM_UPDATE
LIST_START
LIST_COMPLETE
LIST_ERROR
`,
TRANSFERS: {
MAKE_START: TODO_DEFINE,
MAKE_COMPLETE: TODO_DEFINE,
MAKE_ERROR: TODO_DEFINE,
MAKE_FORM_UPDATE: TODO_DEFINE,
LIST_START: TODO_DEFINE,
LIST_COMPLETE: TODO_DEFINE,
LIST_ERROR: TODO_DEFINE
},
ERROR: `
START
STOP
`
ERROR: {
START:TODO_DEFINE,
STOP:TODO_DEFINE
}
})

View File

@@ -5,7 +5,8 @@ import { batchedSubscribe } from 'redux-batched-subscribe'
import * as navigation from './actions/navigation'
import actors from './actors'
import rootReducer from './reducers'
import rootReducer from './reducers';
import { blocked } from './utils/blockedExecution';
// Add middleware to allow our action creators to return functions and arrays
@@ -25,18 +26,11 @@ const store = createStoreWithBatching(rootReducer)
// Handle changes to our store with a list of actor functions, but ensure
// that the actor sequence cannot be started by a dispatch from an actor
let acting = false
store.subscribe(function() {
if (!acting) {
acting = true
for (let actor of actors) {
actor(store.getState(), store.dispatch)
}
acting = false
store.subscribe(blocked(() => {
for (let actor of actors) {
actor(store.getState(), store.dispatch)
}
})
}));
// Dispatch navigation events when the URL's hash changes, and when the
// application loads

View File

@@ -0,0 +1,17 @@
/**
* Created by andrew on 8/17/16.
*/
export const blocked = (fn) => {
let isBlocked = false;
return (...args) => {
if (isBlocked) {
return;
}
//noinspection JSUnusedAssignment
isBlocked = true;
const result = fn(...args);
isBlocked = false;
return result;
};
};

View File

@@ -3,6 +3,8 @@
*/
import * as C from "./constants";
import root from './root';
import fetch from "./fetch";
import parseEndpointConfig from "./parseEndpointConfig";
@@ -20,9 +22,6 @@ import {
destroySession
} from "./sessionStorage";
// can't use "window" with node app
var root = Function("return this")() || (42, eval)("this");
const defaultSettings = {
//proxyIf: function() { return false; },
//proxyUrl: "/proxy",

View File

@@ -1,4 +1,4 @@
export default function compose(...funcs) {
const innerFunc = funcs.pop()
const innerFunc = funcs.pop();
return (...args) => funcs.reduceRight((composed, f) => f(composed), innerFunc(...args))
}

View File

@@ -1,5 +1,46 @@
import invariant from 'invariant'
export const TODO_DEFINE = Symbol('Define property');
export const defineActionType = (obj) => {
const result = Object.entries(obj).reduce((memo, [namespace, value]) => {
let types = [];
const namespaceTypes = {};
if (typeof value == 'string') {
types = value.trim().split(/\s+/);
} else {
types = Object.entries(value)
.filter(([key, needDefinition]) => needDefinition === TODO_DEFINE)
.map(([key]) => key);
}
invariant(
/^[A-Z][A-Z0-9_]*$/.test(namespace),
"Namespace names must start with a capital letter, and be composed entirely of capital letters, numbers, and the underscore character."
);
invariant(
(new Set(types)).size == types.length,
"There must be no repeated action types passed to defineActionTypes"
);
types.forEach(t => {
invariant(
/^[A-Z][A-Z0-9_]*$/.test(t),
"Types must start with a capital letter, and be composed entirely of capital letters, numbers, and the underscore character."
);
namespaceTypes[t] = `@@app/${namespace}/${t}`;
});
memo[namespace] = namespaceTypes;
return memo;
}, {});
return result;
};
export default function defineActionTypes(obj) {
const result = {}

View File

@@ -1,6 +1,174 @@
import path from "path";
import webpack from "webpack";
import ExtractTextPlugin from "extract-text-webpack-plugin";
'use strict';
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const merge = require('webpack-merge');
const validate = require('webpack-validator');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const pkg = require('./package.json');
const parts = require('./config/webpackConfigParts');
const ENTRIES = Object.keys(pkg.dependencies);
const CSS_ENTIRES = ['bootstrap-horizon'];
const JS_ENTRIES = ENTRIES.filter(p => CSS_ENTIRES.indexOf(p) < 0);
const PATHS = {
app: path.join(__dirname, 'src'),
appEntry: path.join(__dirname, 'src', 'index.js'),
style: [
path.join(__dirname, 'node_modules', 'bootstrap-horizon'),
path.join(__dirname, 'node_modules', 'rc-slider/assets'),
path.join(__dirname, 'src', 'style.css')
],
styleLess: [
path.join(__dirname, 'node_modules', 'bootstrap-horizon'),
path.join(__dirname, 'node_modules/rc-slider/assets/index.css'),
path.join(__dirname, 'src', 'style.less')
],
build: path.join(__dirname, 'build')
};
const common = {
entry: {
app: PATHS.appEntry,
// ,
style: PATHS.styleLess
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'react-hot!babel'
}]
},
resolve: {
extensions: ['', '.js', '.jsx'],
alias: {
'bootstrap': path.join(__dirname, 'node_modules/bootstrap/dist/js/bootstrap.js')
}
},
node: {
net: 'empty',
tls: 'empty',
dns: 'empty'
},
output: {
path: PATHS.build,
publicPath: '/',
filename: '[name].js',
// Modify the name of the generated sourcemap file.
// You can use [file], [id], and [hash] replacements here.
// The default option is enough for most use cases.
sourceMapFilename: '[file].map', // Default
// This is the sourcemap filename template. It's default format
// depends on the devtool option used. You don't need to modify this
// often.
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]?[loaders]'
},
plugins: [
new CopyWebpackPlugin([
{ from: 'public/**', to: PATHS.build, flatten: true }
], {
ignore: [
'*.ejs'
]
}),
new HtmlWebpackPlugin({
// Required
inject: false,
template: './public/index.ejs',
//template: 'node_modules/html-webpack-template/index.ejs',
// Optional
title: 'ES IOT Lighting',
description: 'ES IOT Lighting App',
appMountId: 'root',
// baseHref: 'http://example.com/awesome',
// devServer: 3001,
googleAnalytics: {
trackingId: 'UA-XXXX-XX',
pageViewOnLoad: true
},
mobile: true
// window: {
// env: {
// apiHost: 'http://myapi.com/api/v1'
// }
// }
})
]
};
console.log('process.env.npm_lifecycle_event', process.env.npm_lifecycle_event);
const config = (() => {
switch(process.env.npm_lifecycle_event) {
case 'build':
case 'watch':
return merge(
common,
{
devtool: 'source-map',
output: {
path: PATHS.build,
filename: '[name].[chunkhash].js',
// This is used for require.ensure. The setup
// will work without but this is useful to set.
chunkFilename: '[chunkhash].js'
}
},
parts.clean(path.join(PATHS.build, '*')),
// parts.setupCSS(PATHS.style),
parts.useJSON(),
parts.useJQuery(),
parts.extractBundle({
name: 'vendor',
entries: JS_ENTRIES
}),
// parts.minify(),
// parts.extractCSS(PATHS.style),
parts.extractLESS(PATHS.styleLess),
parts.purifyCSS([PATHS.app])
);
default:
return merge(
common,
{
devtool: 'eval-source-map'
},
parts.useJSON(),
parts.useJQuery(),
parts.extractBundle({
name: 'vendor',
entries: JS_ENTRIES
}),
// parts.setupCSS(PATHS.style),
parts.setupLess(PATHS.styleLess),
parts.devServer({
// Customize host/port here if needed
host: process.env.HOST,
port: process.env.PORT
})
);
}
})();
// module.exports = validate(config);
//import ExtractTextPlugin from "extract-text-webpack-plugin";
export default (DEBUG, PATH, PORT=3000) => ({