Skip to content

Commit

Permalink
Make it a spa!
Browse files Browse the repository at this point in the history
Lots of stuff going, here are the main features:
- Moved the /run app to index
- Added directory listing functionality
- Implemented React-Router: changing urls no longer cause the entire app
  to refresh

Some of the under-the-hood changes:
- Restructured run app to use redux
- Add font-awesome to app
- Standardized error handler for api
  • Loading branch information
Matt Nibecker committed Feb 2, 2016
1 parent 5dc6d39 commit d10d18e
Show file tree
Hide file tree
Showing 26 changed files with 703 additions and 167 deletions.
5 changes: 3 additions & 2 deletions lib/app-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ module.exports.init = function() {
router.use('/assets', express.static(DIST_DIR));
}

router.get('/run', function(req, res) {
res.sendFile(path.join(__dirname, '../src/apps/run/index.html'));
router.get('/', function(req, res) {
res.sendFile(path.join(__dirname, '../src/apps/assets/index.html'));
});

return router;
};
11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,30 +36,33 @@
"express-ws": "^1.0.0-rc.2",
"extendable-base": "^0.3.1",
"fast-url-parser": "^1.1.3",
"font-awesome": "^4.5.0",
"fs-extra": "^0.26.2",
"history": "^1.13.1",
"history": "^1.17.0",
"immutable": "^3.7.5",
"isomorphic-fetch": "^2.2.0",
"jquery": "^2.1.4",
"juttle": "^0.3.1",
"juttle-client-library": "^0.2.1",
"juttle-client-library": "^0.3.0-rc.1",
"juttle-elastic-adapter": "^0.3.0",
"juttle-gmail-adapter": "^0.4.0",
"juttle-graphite-adapter": "^0.3.0",
"juttle-influx-adapter": "^0.3.0",
"juttle-jsdp": "^0.1.1",
"juttle-mysql-adapter": "^0.2.0",
"juttle-opentsdb-adapter": "^0.1.0",
"juttle-postgres-adapter": "^0.2.0",
"juttle-sqlite-adapter": "^0.2.0",
"juttle-twitter-adapter": "^0.2.1",
"juttle-jsdp": "^0.1.1",
"log4js": "^0.6.28",
"minimist": "^1.2.0",
"moment": "^2.11.1",
"open": "0.0.5",
"react": "^0.14.2",
"react-dom": "^0.14.2",
"react-redux": "^4.0.0",
"react-router": "^2.0.0-rc5",
"react-router-redux": "^2.1.0",
"redux": "^3.0.4",
"redux-logger": "^2.0.4",
"redux-thunk": "^1.0.0",
Expand All @@ -83,6 +86,7 @@
"eslint-plugin-react": "^3.16.1",
"extract-text-webpack-plugin": "^0.9.1",
"find-free-port": "^1.0.2",
"file-loader": "^0.8.5",
"gulp": "^3.9.0",
"gulp-eslint": "^1.1.1",
"gulp-istanbul": "^0.10.3",
Expand All @@ -97,6 +101,7 @@
"sass-loader": "^3.1.1",
"selenium-webdriver": "^2.48.2",
"style-loader": "^0.13.0",
"url-loader": "^0.5.7",
"webpack": "^1.12.6",
"webpack-dev-middleware": "^1.2.0"
},
Expand Down
25 changes: 25 additions & 0 deletions src/apps/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export const NEW_BUNDLE = 'NEW_BUNDLE';
export const NEW_ERROR = 'NEW_ERROR';
export const FETCH_BUNDLE_ERROR = 'FETCH_BUNDLE_ERROR';

export function newBundle(bundle, inputs) {
return {
type: NEW_BUNDLE,
bundle,
inputs
};
}

export function newError(error) {
return {
type: NEW_ERROR,
error
};
}

export function fetchBundleError(error) {
return {
type: FETCH_BUNDLE_ERROR,
error
};
}
27 changes: 27 additions & 0 deletions src/apps/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';

import DirectoryListing from '../client-lib/directory-listing';
import Dropdown from '../client-lib/dropdown';

class App extends React.Component {
handleJuttleSelected = () => {
this.refs.Dropdown.close();
};

render() {
return (
<div className="app-wrapper">
<header>
<div className='header-options'>
<Dropdown ref="Dropdown">
<DirectoryListing onJuttleSelected={this.handleJuttleSelected}/>
</Dropdown>
</div>
</header>
{this.props.children}
</div>
)
}
}

export default App;
13 changes: 13 additions & 0 deletions src/apps/assets/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>

<html>
<head>
<title>Jut Development</title>
<link rel="stylesheet" type="text/css" href="/assets/main.css">
</head>
<body class="app-body">
<div id="app">
</div>
<script src="/assets/app.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ $gray-darker: lighten($gray-base, 13.5%) !default; // #222
$gray-dark: lighten($gray-base, 20%) !default; // #333
$gray: lighten($gray-base, 33.5%) !default; // #555
$gray-light: lighten($gray-base, 46.7%) !default; // #777
$gray-lighter: #B8B8B8;
$gray-lighter: #B8B8B8;
$gray-pale: lighten($gray-base, 90%) !default;
// $gray-lighter: lighten($gray-base, 93.5%) !default; // #eee

$brand-primary: darken(#428bca, 6.5%) !default; // #337ab7
Expand Down Expand Up @@ -150,9 +151,9 @@ $table-border-color: #ddd !default;

$btn-font-weight: normal !default;

$btn-default-color: #333 !default;
$btn-default-bg: #fff !default;
$btn-default-border: #ccc !default;
$btn-default-color: $gray-light !default;
$btn-default-bg: $gray-darker !default;
$btn-default-border: $gray-light !default;

$btn-primary-color: #fff !default;
$btn-primary-bg: $brand-primary !default;
Expand Down
48 changes: 48 additions & 0 deletions src/apps/assets/sass/_bootstrap.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/variables";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/mixins";

// Reset and dependencies
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/normalize";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/print";

// Core CSS
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/scaffolding";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/type";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/code";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/grid";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/tables";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/forms";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/buttons";

// Components
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/component-animations";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/dropdowns";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/button-groups";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/input-groups";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/navs";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/navbar";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/breadcrumbs";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/pagination";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/pager";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/labels";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/badges";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/jumbotron";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/thumbnails";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/alerts";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/progress-bars";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/media";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/list-group";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/panels";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/responsive-embed";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/wells";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/close";

// Components w/ JavaScript
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/modals";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/tooltip";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/popovers";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/carousel";

// Utility classes
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/utilities";
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/responsive-utilities";
15 changes: 15 additions & 0 deletions src/apps/assets/sass/_directory-listing.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.dir-list {
.dir-list-item {
display: block;
padding: 10px 15px;
}

.dir-list-item.path {
border-bottom: 1px solid $gray-pale;
}

.dir-entry:hover {
text-decoration: none;
background-color: $gray-pale;
}
}
File renamed without changes.
40 changes: 31 additions & 9 deletions src/apps/sass/main.scss → src/apps/assets/sass/main.scss
Original file line number Diff line number Diff line change
@@ -1,35 +1,48 @@
//@import "../../../node_modules/font-awesome/scss/font-awesome";
@import "./bootstrap-variables";
@import "./bootstrap";
@import "./flexbox";
@import "./juttle-client-library-overrides";
@import "directory-listing";

html, body {
html, body, #app {
height: 100%;
}

#app {
min-height: 100%;
display: flex;
}

span.logo {
font-size: 28px;
font-weight: bolder;
font-family: Rockwell Extra Bold;
vertical-align: middle;

}

.outrigger {
header {
border-bottom: 1px solid $gray-dark;
height: 60px;
padding: 0 15px;
@include flexbox;
.header-options {
@include flexbox;
@include align-items(center);
}
}

.app-wrapper {
height: 100%;
width: 100%;
}

.app-main {
min-height: 100%;
width: 100%;
@include flexbox;
}


.main-view {
@include flex-grow(1);
overflow: hidden;
margin: 10px;
margin: 15px;
}

.right-rail {
Expand All @@ -53,3 +66,12 @@ span.logo {
margin-top: 10px;
margin-bottom: 10px;
}

.dropdown-menu {
max-height: 50vh;
overflow-y: auto;
}

#directory-listing.dropdown-menu {
width: 300px;
}
34 changes: 34 additions & 0 deletions src/apps/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import { syncHistory } from 'react-router-redux';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';

import reducers from './reducers';
import { bundleMiddleware } from './middleware';

import App from './app';
import Run from './run';


// import sass
import 'juttle-client-library/dist/juttle-client-library.css';
import 'font-awesome/css/font-awesome.css';
import './assets/sass/main.scss';

// setup redux
const reduxRouterMiddeware = syncHistory(browserHistory);
const createStoreWithMiddleware = applyMiddleware(reduxRouterMiddeware, bundleMiddleware)(createStore);
const store = createStoreWithMiddleware(reducers);

// setup main app
ReactDOM.render((
<Provider store={store}>
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute component={Run} />
</Route>
</Router>
</Provider>
), document.getElementById('app'));
54 changes: 54 additions & 0 deletions src/apps/middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { UPDATE_LOCATION } from 'react-router-redux';

import { newBundle, fetchBundleError } from './actions';
import * as api from '../client-lib/api';
import RendezvousSocket from '../client-lib/rendezvous-socket';

// this should come from a config options, do this for now
let outriggerHost = window.location.host;

export const bundleMiddleware = store => {
let rendezvous;

function bundleReceived(bundle) {
api.describe(bundle)
.then(inputs => {
store.dispatch(newBundle(bundle, inputs));
})
}

function runModeChanged(runMode) {
if (runMode.path) {
api.getBundle(runMode.path)
.then(res => { bundleReceived(res.bundle) })
.catch(err => { store.dispatch(fetchBundleError(err)) })
} else if (runMode.rendezvous) {
if (rendezvous) {
rendezvous.close();
}

rendezvous = new RendezvousSocket(`ws://${outriggerHost}/rendezvous/${runMode.rendezvous}`);
rendezvous.on('message', msg => bundleReceived(msg.bundle));
}
}

runModeChanged(store.getState().runMode);

return next => action => {
// only update if prevRunMode is different from newRunMode
if (action.type !== UPDATE_LOCATION) {
return next(action);
}

let prevRunMode = store.getState().runMode;
let result = next(action);
let newRunMode = store.getState().runMode;
if (newRunMode.path !== prevRunMode.path
|| newRunMode.rendezvous !== prevRunMode.rendezvous) {

runModeChanged(newRunMode);
}

return result;
}
}
Loading

0 comments on commit d10d18e

Please sign in to comment.