diff --git a/app.js b/app.js
index 5fcbe8958c..bf8e65c0c2 100644
--- a/app.js
+++ b/app.js
@@ -42,15 +42,30 @@ app.use('/proxyUrl', function proxyRequest(req, res, next) {
const webpack = require('webpack');
const webpackConfig = require('./webpack.config.js');
+webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
+webpackConfig.plugins.push(function() { this.plugin('watch-run', function(watching, callback) { console.log('Begin compile at ' + new Date()); callback(); }) });
+
+webpackConfig.entry.openmct = [
+ 'webpack-hot-middleware/client',
+ webpackConfig.entry.openmct
+];
+
const compiler = webpack(webpackConfig);
-const webpackDevRoute = require('webpack-dev-middleware')(
- compiler, {
+
+app.use(require('webpack-dev-middleware')(
+ compiler,
+ {
publicPath: '/dist',
logLevel: 'warn'
}
-);
+));
-app.use(webpackDevRoute);
+app.use(require('webpack-hot-middleware')(
+ compiler,
+ {
+
+ }
+));
// Expose index.html for development users.
app.get('/', function (req, res) {
diff --git a/index.html b/index.html
index 5281757d0d..ff3a38cfe3 100644
--- a/index.html
+++ b/index.html
@@ -34,9 +34,6 @@
-
diff --git a/src/ui/components/controls/pane.vue b/src/ui/components/controls/pane.vue
new file mode 100644
index 0000000000..9e4c8578c1
--- /dev/null
+++ b/src/ui/components/controls/pane.vue
@@ -0,0 +1,418 @@
+
+
+
+
+
+
+
diff --git a/src/ui/components/controls/search.vue b/src/ui/components/controls/search.vue
new file mode 100644
index 0000000000..8b81a51ba8
--- /dev/null
+++ b/src/ui/components/controls/search.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
diff --git a/src/ui/components/controls/splitter.vue b/src/ui/components/controls/splitter.vue
new file mode 100644
index 0000000000..eb15975c2a
--- /dev/null
+++ b/src/ui/components/controls/splitter.vue
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/ui/components/controls/viewControl.vue b/src/ui/components/controls/viewControl.vue
new file mode 100644
index 0000000000..d3c024eeb2
--- /dev/null
+++ b/src/ui/components/controls/viewControl.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
diff --git a/src/ui/components/layout/Layout.vue b/src/ui/components/layout/Layout.vue
new file mode 100644
index 0000000000..dbec15225b
--- /dev/null
+++ b/src/ui/components/layout/Layout.vue
@@ -0,0 +1,172 @@
+
+
+
+ [ Create Button ]
+ [ App Logo ]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ui/components/layout/MCTSearch.vue b/src/ui/components/layout/MCTSearch.vue
new file mode 100644
index 0000000000..0f3de1f25e
--- /dev/null
+++ b/src/ui/components/layout/MCTSearch.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/ui/components/layout/MctInspector.vue b/src/ui/components/layout/MctInspector.vue
new file mode 100644
index 0000000000..d032e16663
--- /dev/null
+++ b/src/ui/components/layout/MctInspector.vue
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+ c-inspector__elements 1
+
+
+
+
+
+
+
diff --git a/src/ui/components/layout/MctMain.vue b/src/ui/components/layout/MctMain.vue
new file mode 100644
index 0000000000..a67c8ee208
--- /dev/null
+++ b/src/ui/components/layout/MctMain.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/ui/components/layout/MctStatus.vue b/src/ui/components/layout/MctStatus.vue
new file mode 100644
index 0000000000..8158e85551
--- /dev/null
+++ b/src/ui/components/layout/MctStatus.vue
@@ -0,0 +1,14 @@
+
+
+ [ Status ]
+
+
+
+
+
+
diff --git a/src/ui/components/layout/mct-tree.vue b/src/ui/components/layout/mct-tree.vue
new file mode 100644
index 0000000000..d55c322ba3
--- /dev/null
+++ b/src/ui/components/layout/mct-tree.vue
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
diff --git a/src/ui/components/layout/tree-item.vue b/src/ui/components/layout/tree-item.vue
new file mode 100644
index 0000000000..f4cddaaba9
--- /dev/null
+++ b/src/ui/components/layout/tree-item.vue
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
diff --git a/src/ui/InspectorViewRegistry.js b/src/ui/registries/InspectorViewRegistry.js
similarity index 100%
rename from src/ui/InspectorViewRegistry.js
rename to src/ui/registries/InspectorViewRegistry.js
diff --git a/src/ui/ToolbarRegistry.js b/src/ui/registries/ToolbarRegistry.js
similarity index 100%
rename from src/ui/ToolbarRegistry.js
rename to src/ui/registries/ToolbarRegistry.js
diff --git a/src/ui/ViewRegistry.js b/src/ui/registries/ViewRegistry.js
similarity index 100%
rename from src/ui/ViewRegistry.js
rename to src/ui/registries/ViewRegistry.js
diff --git a/src/ui/router/ApplicationRouter.js b/src/ui/router/ApplicationRouter.js
new file mode 100644
index 0000000000..ec935feb16
--- /dev/null
+++ b/src/ui/router/ApplicationRouter.js
@@ -0,0 +1,172 @@
+/**
+
+Application router -- must
+
+*/
+
+const LocationBar = require('location-bar');
+const EventEmitter = require('EventEmitter');
+
+function paramsToObject(searchParams) {
+ let params = {};
+ for ([key, value] of searchParams.entries()) {
+ if (params[key]) {
+ if (!Array.isArray(params[key])) {
+ params[key] = [params[key]];
+ }
+ params[key].push(value);
+ } else {
+ params[key] = value;
+ }
+ }
+ return params;
+}
+
+class ApplicationRouter extends EventEmitter {
+ /**
+ * events
+ * change:params -> notify listeners w/ new, old, and changed.
+ * change:path -> notify listeners w/ new, old paths.
+ *
+ * methods:
+ * update(path, params) -> updates path and params at the same time. Only
+ * updates specified params, other params are not modified.
+ * updateParams(newParams) -> update only specified params, leaving rest
+ * intact. Does not modify path.
+ * updatePath(path);
+
+ * route(path, handler);
+ * start(); Start routing.
+ */
+ constructor() {
+ super()
+ this.routes = [];
+ this.started = false;
+ }
+
+ /**
+ * start application routing, should be done after handlers are registered.
+ */
+ start() {
+ if (this.started) {
+ throw new Error('Router already started!');
+ }
+ this.started = true;
+ let locationBar = new LocationBar();
+ locationBar.onChange(p => this.handleLocationChange(p));
+ locationBar.start({
+ root: location.pathname
+ });
+ }
+
+ handleLocationChange(pathString) {
+ let url = new URL(
+ pathString,
+ `${location.protocol}//${location.host}${location.pathname}`
+ )
+
+ let oldLocation = this.currentLocation;
+
+ let newLocation = {
+ url: url,
+ path: url.pathname,
+ queryString: url.search.replace(/^\?/, ''),
+ params: paramsToObject(url.searchParams)
+ };
+
+ this.currentLocation = newLocation;
+
+ if (!oldLocation) {
+ this.doPathChange(newLocation.path, null, newLocation);
+ this.doParamsChange(newLocation.params, {}, newLocation);
+ return;
+ }
+
+ if (oldLocation.path !== newLocation.path) {
+ this.doPathChange(
+ newLocation.path,
+ oldLocation.path,
+ this
+ );
+ }
+ if (!_.isEqual(oldLocation.params, newLocation.params)) {
+ this.doParamsChange(
+ newLocation.params,
+ oldLocation.params,
+ newLocation
+ );
+ }
+ }
+
+ doPathChange(newPath, oldPath, newLocation) {
+ let route = this.routes.filter(r => r.matcher.test(newPath))[0];
+ if (route) {
+ route.callback(newPath, route.matcher.exec(newPath));
+ }
+ this.emit('change:path', newPath, oldPath);
+ }
+
+ doParamsChange(newParams, oldParams, newLocation) {
+ let changedParams = {};
+ for (let [key, value] of Object.entries(newParams)) {
+ if (value !== oldParams[key]) {
+ changedParams[key] = value;
+ }
+ }
+ for (let [key, value] of Object.entries(oldParams)) {
+ if (!newParams.hasOwnProperty(key)) {
+ changedParams[key] = undefined;
+ }
+ }
+ this.emit('change:params', newParams, oldParams, changedParams);
+ }
+
+ /**
+ * Update route params. Takes an object of updates. New parameters
+ */
+ updateParams(updateParams) {
+ let searchParams = this.currentLocation.url.searchParams;
+ for (let [key, value] of Object.entries(updateParams)) {
+ if (typeof value === 'undefined') {
+ searchParams.delete(key);
+ } else {
+ searchParams.set(key, value);
+ }
+ }
+ this.setQueryString(searchParams.toString());
+ }
+
+ getParams() {
+ return this.currentLocation.params;
+ }
+
+ update(path, params) {
+ let searchParams = this.currentLocation.url.searchParams;
+ for (let [key, value] of Object.entries(params)) {
+ if (typeof value === 'undefined') {
+ searchParams.delete(key);
+ } else {
+ searchParams.set(key, value);
+ }
+ }
+ this.set(path, searchParams.toString());
+ }
+
+ set(path, queryString) {
+ location.hash = `${path}?${queryString}`;
+ }
+
+ setQueryString(queryString) {
+ this.set(this.currentLocation.path, queryString);
+ }
+
+ setPath(path) {
+ this.set(path, this.currentLocation.queryString);
+ }
+
+ route(matcher, callback) {
+ this.routes.push({matcher, callback});
+ }
+}
+
+module.exports = ApplicationRouter;
diff --git a/webpack.config.js b/webpack.config.js
index f7efd75355..e89b5fb3bc 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -28,7 +28,8 @@ const webpackConfig = {
"espresso": path.join(__dirname, "src/styles/theme-espresso.scss"),
"snow": path.join(__dirname, "src/styles/theme-snow.scss"),
"vue": path.join(__dirname, "node_modules/vue/dist/vue.min.js"),
- "d3-scale": path.join(__dirname, "node_modules/d3-scale/build/d3-scale.min.js")
+ "d3-scale": path.join(__dirname, "node_modules/d3-scale/build/d3-scale.min.js"),
+ "styles": path.join(__dirname, "src/styles-new")
}
},
devtool: devMode ? 'eval-source-map' : 'source-map',