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 @@ + + + + + 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 @@ + + + + + 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 @@ + + + + + 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',