Adds devserver support

* Adds support for webpack devserver
* Enable istanbul on network UI
* Enable capture and replay tests on the network ui
* Normalize mouse wheel events
* Fix missing trailing slash on hosts API
* Add Export YAML button
This commit is contained in:
Ben Thomasson
2017-11-14 13:44:47 -05:00
parent 2713ec2dd5
commit 809eafe9a9
9 changed files with 130 additions and 108 deletions

View File

@@ -23,6 +23,7 @@ from awx.network_ui.utils import transform_dict
import dpath.util import dpath.util
from pprint import pformat from pprint import pformat
import os
import json import json
import time import time
# Connected to websocket.connect # Connected to websocket.connect
@@ -40,7 +41,6 @@ HISTORY_MESSAGE_IGNORE_TYPES = ['DeviceSelected',
SPACING = 200 SPACING = 200
RACK_SPACING = 50 RACK_SPACING = 50
settings.RECORDING = False
logger = logging.getLogger("awx.network_ui.consumers") logger = logging.getLogger("awx.network_ui.consumers")
@@ -430,15 +430,6 @@ class _Persistence(object):
else: else:
logger.warning("Unsupported message %s", message['msg_type']) logger.warning("Unsupported message %s", message['msg_type'])
def onDeploy(self, message_value, topology_id, client_id):
DeviceGroup("workers").send({"text": json.dumps(["Deploy", topology_id, yaml_serialize_topology(topology_id)])})
def onDestroy(self, message_value, topology_id, client_id):
DeviceGroup("workers").send({"text": json.dumps(["Destroy", topology_id])})
def onDiscover(self, message_value, topology_id, client_id):
DeviceGroup("workers").send({"text": json.dumps(["Discover", topology_id, yaml_serialize_topology(topology_id)])})
def onLayout(self, message_value, topology_id, client_id): def onLayout(self, message_value, topology_id, client_id):
# circular_layout(topology_id) # circular_layout(topology_id)
# grid_layout(topology_id) # grid_layout(topology_id)
@@ -448,18 +439,18 @@ class _Persistence(object):
pass pass
def onCoverage(self, coverage, topology_id, client_id): def onCoverage(self, coverage, topology_id, client_id):
with open("coverage/coverage{0}.json".format(int(time.time())), "w") as f: with open(os.path.abspath("coverage/coverage{0}.json".format(int(time.time()))), "w") as f:
f.write(json.dumps(coverage['coverage'])) f.write(json.dumps(coverage['coverage']))
def onStartRecording(self, recording, topology_id, client_id): def onStartRecording(self, recording, topology_id, client_id):
settings.RECORDING = True pass
def onStopRecording(self, recording, topology_id, client_id): def onStopRecording(self, recording, topology_id, client_id):
settings.RECORDING = False pass
def write_event(self, event, topology_id, client_id): def write_event(self, event, topology_id, client_id):
if settings.RECORDING and event.get('save', True): if event.get('save', True):
with open("recording.log", "a") as f: with open(os.path.abspath("recording/recording_{0}.log".format(topology_id)), "a") as f:
f.write(json.dumps(event)) f.write(json.dumps(event))
f.write("\n") f.write("\n")
@@ -896,25 +887,6 @@ def ws_disconnect(message):
def console_printer(message): def console_printer(message):
print message['text'] # pragma: no cover print message['text'] # pragma: no cover
# Worker channel events
@channel_session
def worker_connect(message):
Group("workers").add(message.reply_channel)
@channel_session
def worker_message(message):
# Channel('console_printer').send({"text": message['text']})
pass
@channel_session
def worker_disconnect(message):
pass
# Tester channel events # Tester channel events
@channel_session @channel_session

View File

@@ -16,22 +16,22 @@ class Command(BaseCommand):
parser.add_argument('topology_id', type=int) parser.add_argument('topology_id', type=int)
parser.add_argument('recording') parser.add_argument('recording')
parser.add_argument('--time-scale', dest="time_scale", default=1.0, type=float) parser.add_argument('--time-scale', dest="time_scale", default=1.0, type=float)
parser.add_argument('--delete-topology-at-start', dest="delete_topolgy", action="store_true", default=False) parser.add_argument('--delete-topology-at-start', dest="delete_topology", action="store_true", default=False)
def handle(self, *args, **options): def handle(self, *args, **options):
print options['topology_id'] print options['topology_id']
print options['recording'] print options['recording']
topology_id = options['topology_id'] topology_id = options['topology_id']
if options['delete_topolgy'] is True: if options['delete_topology'] is True:
TopologyHistory.objects.filter(topology_id=topology_id).delete() TopologyHistory.objects.filter(topology_id=topology_id).delete()
Device.objects.filter(topology_id=topology_id).delete() Device.objects.filter(topology_id=topology_id).delete()
time.scale = options.get('time_scale', 1.0) time.scale = options.get('time_scale', 1.0)
ui = MessageHandler(create_connection("ws://localhost:8001/network_ui/topology?topology_id={0}".format(options['topology_id']))) ui = MessageHandler(create_connection("ws://localhost:8013/network_ui/topology?topology_id={0}".format(options['topology_id'])))
ui.recv() ui.recv()
ui.recv() ui.recv()
ui.send('StopRecording') ui.send('StopRecording')
ui.send('StartReplay') ui.send('StartReplay')
if options['delete_topolgy'] is True: if options['delete_topology'] is True:
ui.send_message(['History', []]) ui.send_message(['History', []])
ui.send('Snapshot', sender=ui.client_id, devices=[], links=[]) ui.send('Snapshot', sender=ui.client_id, devices=[], links=[])
messages = [] messages = []

View File

@@ -39,7 +39,7 @@ class Command(BaseCommand):
TestRedoPersistence, TestRedoPersistence,
TestPersistence, TestPersistence,
TestViews, TestViews,
TestWorkerWebSocket, #TestWorkerWebSocket,
TestAnsibleWebSocket, TestAnsibleWebSocket,
TestInvalidValues] TestInvalidValues]
if options.get('suites'): if options.get('suites'):
@@ -49,7 +49,7 @@ class Command(BaseCommand):
verbosity=0 if options.get('quiet') else 2 if options.get('verbose') else 1, verbosity=0 if options.get('quiet') else 2 if options.get('verbose') else 1,
buffer=options.get('buffer')).run(unittest.TestSuite(tests)) buffer=options.get('buffer')).run(unittest.TestSuite(tests))
ui = MessageHandler(create_connection("ws://localhost:8001/network_ui/topology?topology_id=143")) ui = MessageHandler(create_connection("ws://localhost:8013/network_ui/topology?topology_id=143"))
ui.recv() ui.recv()
ui.recv() ui.recv()
ui.send('CoverageRequest') ui.send('CoverageRequest')
@@ -59,7 +59,7 @@ class Command(BaseCommand):
class TestViews(unittest.TestCase): class TestViews(unittest.TestCase):
def test_index(self): def test_index(self):
requests.get("http://localhost:8001/network_ui") requests.get("http://localhost:8013/network_ui")
class MessageHandler(object): class MessageHandler(object):
@@ -104,28 +104,10 @@ class MessageHandler(object):
self.ws.close() self.ws.close()
class TestWorkerWebSocket(unittest.TestCase):
def test(self):
self.worker = MessageHandler(create_connection("ws://localhost:8001/network_ui/worker?topology_id=143"))
self.ui = MessageHandler(create_connection("ws://localhost:8001/network_ui/tester?topology_id=143"))
self.ui.recv()
self.ui.recv()
self.ui.send("Deploy")
self.assertTrue(self.worker.recv())
self.ui.send("Destroy")
self.assertTrue(self.worker.recv())
self.worker.send("Hi")
def tearDown(self):
self.worker.close()
self.ui.close()
class TestAnsibleWebSocket(unittest.TestCase): class TestAnsibleWebSocket(unittest.TestCase):
def test(self): def test(self):
self.ws = MessageHandler(create_connection("ws://localhost:8001/network_ui/ansible?topology_id=143")) self.ws = MessageHandler(create_connection("ws://localhost:8013/network_ui/ansible?topology_id=143"))
self.ws.send('Facts', foo=5) self.ws.send('Facts', foo=5)
def tearDown(self): def tearDown(self):
@@ -135,7 +117,7 @@ class TestAnsibleWebSocket(unittest.TestCase):
class TestPersistence(unittest.TestCase): class TestPersistence(unittest.TestCase):
def setUp(self): def setUp(self):
self.ws = MessageHandler(create_connection("ws://localhost:8001/network_ui/tester?topology_id=143")) self.ws = MessageHandler(create_connection("ws://localhost:8013/network_ui/tester?topology_id=143"))
self.ws.recv() self.ws.recv()
self.ws.recv() self.ws.recv()
@@ -213,7 +195,7 @@ class TestPersistence(unittest.TestCase):
class TestUndoPersistence(unittest.TestCase): class TestUndoPersistence(unittest.TestCase):
def setUp(self): def setUp(self):
self.ws = MessageHandler(create_connection("ws://localhost:8001/network_ui/tester?topology_id=143")) self.ws = MessageHandler(create_connection("ws://localhost:8013/network_ui/tester?topology_id=143"))
self.ws.recv() self.ws.recv()
self.ws.recv() self.ws.recv()
@@ -305,7 +287,7 @@ class TestUndoPersistence(unittest.TestCase):
class TestRedoPersistence(unittest.TestCase): class TestRedoPersistence(unittest.TestCase):
def setUp(self): def setUp(self):
self.ws = MessageHandler(create_connection("ws://localhost:8001/network_ui/tester?topology_id=143")) self.ws = MessageHandler(create_connection("ws://localhost:8013/network_ui/tester?topology_id=143"))
self.ws.recv() self.ws.recv()
self.ws.recv() self.ws.recv()
@@ -332,7 +314,7 @@ class TestRedoPersistence(unittest.TestCase):
class TestUIWebSocket(unittest.TestCase): class TestUIWebSocket(unittest.TestCase):
def test(self): def test(self):
self.ui = MessageHandler(create_connection("ws://localhost:8001/network_ui/topology?topology_id=143")) self.ui = MessageHandler(create_connection("ws://localhost:8013/network_ui/topology?topology_id=143"))
self.ui.recv() self.ui.recv()
self.ui.recv() self.ui.recv()
self.ui.send("Hello") self.ui.send("Hello")
@@ -344,8 +326,8 @@ class TestUIWebSocket(unittest.TestCase):
class TestUI(unittest.TestCase): class TestUI(unittest.TestCase):
def setUp(self): def setUp(self):
self.ws = MessageHandler(create_connection("ws://localhost:8001/network_ui/tester?topology_id=143")) self.ws = MessageHandler(create_connection("ws://localhost:8013/network_ui/tester?topology_id=143"))
self.ui = MessageHandler(create_connection("ws://localhost:8001/network_ui/topology?topology_id=143")) self.ui = MessageHandler(create_connection("ws://localhost:8013/network_ui/topology?topology_id=143"))
self.ws.recv() self.ws.recv()
self.ws.recv() self.ws.recv()
self.ui.recv() self.ui.recv()
@@ -515,22 +497,22 @@ topology_id: 143
class TestInvalidValues(unittest.TestCase): class TestInvalidValues(unittest.TestCase):
def test_bad_topology_id1(self): def test_bad_topology_id1(self):
self.ws = MessageHandler(create_connection("ws://localhost:8001/network_ui/tester?topology_id=0")) self.ws = MessageHandler(create_connection("ws://localhost:8013/network_ui/tester?topology_id=0"))
self.ws.close() self.ws.close()
def test_bad_topology_id2(self): def test_bad_topology_id2(self):
self.ws = MessageHandler(create_connection("ws://localhost:8001/network_ui/tester?topology_id=foo")) self.ws = MessageHandler(create_connection("ws://localhost:8013/network_ui/tester?topology_id=foo"))
self.ws.close() self.ws.close()
def test_bad_sender(self): def test_bad_sender(self):
self.ws = MessageHandler(create_connection("ws://localhost:8001/network_ui/tester?topology_id=143")) self.ws = MessageHandler(create_connection("ws://localhost:8013/network_ui/tester?topology_id=143"))
self.ws.ws.send(json.dumps(['DeviceCreate', dict(sender=-1, name="TestSwitchA", x=100, y=100, type="switch", id=100)])) self.ws.ws.send(json.dumps(['DeviceCreate', dict(sender=-1, name="TestSwitchA", x=100, y=100, type="switch", id=100)]))
self.ws.ws.send(json.dumps(['DeviceDestroy', dict(sender=-1, previous_name="TestSwitchA", self.ws.ws.send(json.dumps(['DeviceDestroy', dict(sender=-1, previous_name="TestSwitchA",
previous_x=100, previous_y=100, previous_type="switch", id=100)])) previous_x=100, previous_y=100, previous_type="switch", id=100)]))
self.ws.close() self.ws.close()
def test_unsupported_command(self): def test_unsupported_command(self):
self.ws = MessageHandler(create_connection("ws://localhost:8001/network_ui/tester?topology_id=143")) self.ws = MessageHandler(create_connection("ws://localhost:8013/network_ui/tester?topology_id=143"))
self.ws.recv() self.ws.recv()
self.ws.recv() self.ws.recv()
self.ws.send("NotSupported") self.ws.send("NotSupported")

View File

@@ -2,7 +2,6 @@
from channels.routing import route from channels.routing import route
from awx.network_ui.consumers import ws_connect, ws_message, ws_disconnect, console_printer, persistence, discovery from awx.network_ui.consumers import ws_connect, ws_message, ws_disconnect, console_printer, persistence, discovery
from awx.network_ui.consumers import ansible_connect, ansible_message, ansible_disconnect from awx.network_ui.consumers import ansible_connect, ansible_message, ansible_disconnect
from awx.network_ui.consumers import worker_connect, worker_message, worker_disconnect
from awx.network_ui.consumers import tester_connect, tester_message, tester_disconnect from awx.network_ui.consumers import tester_connect, tester_message, tester_disconnect
from awx.network_ui.consumers import tables_connect, tables_message, tables_disconnect from awx.network_ui.consumers import tables_connect, tables_message, tables_disconnect
@@ -13,9 +12,6 @@ channel_routing = [
route("websocket.connect", ansible_connect, path=r"^/network_ui/ansible"), route("websocket.connect", ansible_connect, path=r"^/network_ui/ansible"),
route("websocket.receive", ansible_message, path=r"^/network_ui/ansible"), route("websocket.receive", ansible_message, path=r"^/network_ui/ansible"),
route("websocket.disconnect", ansible_disconnect, path=r"^/network_ui/ansible"), route("websocket.disconnect", ansible_disconnect, path=r"^/network_ui/ansible"),
route("websocket.connect", worker_connect, path=r"^/network_ui/worker"),
route("websocket.receive", worker_message, path=r"^/network_ui/worker"),
route("websocket.disconnect", worker_disconnect, path=r"^/network_ui/worker"),
route("websocket.connect", tester_connect, path=r"^/network_ui/tester"), route("websocket.connect", tester_connect, path=r"^/network_ui/tester"),
route("websocket.receive", tester_message, path=r"^/network_ui/tester"), route("websocket.receive", tester_message, path=r"^/network_ui/tester"),
route("websocket.disconnect", tester_disconnect, path=r"^/network_ui/tester"), route("websocket.disconnect", tester_disconnect, path=r"^/network_ui/tester"),

View File

@@ -20,11 +20,11 @@ lint:
lessc: lessc:
lessc src/style.less css/style.css lessc src/style.less css/style.css
istanbul: istanbul: main
istanbul instrument --output src-instrumented src istanbul instrument --output src-instrumented src
webpack src-instrumented/main.js js/bundle-instrumented.js webpack --config webpack-instrumented.config.js
cp index.html index-instrumented.html cp index.html index-instrumented.html
sed -i "s/bundle.js/bundle-instrumented.js/g" index-instrumented.html sed -i "s/\/bundle.js/\/bundle-instrumented.js/g" index-instrumented.html
cp vendor/*.js js/ cp vendor/*.js js/
@@ -35,6 +35,8 @@ simple-server: lint main lessc
deploy: main deploy: main
rsync -av src/ ../../../../awx/ui/client/src/network_ui/ rsync -av src/ ../../../../awx/ui/client/src/network_ui/
deploy-instrumented: istanbul
rsync -av src-instrumented/ ../../../../awx/ui/client/src/network_ui/
extract: extract:
mkdir -p extracted mkdir -p extracted

View File

@@ -22,7 +22,8 @@
"reconnectingwebsocket": "^1.0.0", "reconnectingwebsocket": "^1.0.0",
"require": "", "require": "",
"webpack": "", "webpack": "",
"titlecase": "" "titlecase": "",
"lodash": ""
}, },
"devDependencies": { "devDependencies": {
"eslint": "^3.17.1", "eslint": "^3.17.1",

View File

@@ -1,4 +1,5 @@
/* Copyright (c) 2017 Red Hat, Inc. */ /* Copyright (c) 2017 Red Hat, Inc. */
var _ = require('lodash');
var angular = require('angular'); var angular = require('angular');
var fsm = require('./fsm.js'); var fsm = require('./fsm.js');
var null_fsm = require('./null.fsm.js'); var null_fsm = require('./null.fsm.js');
@@ -21,21 +22,23 @@ var messages = require('./messages.js');
var svg_crowbar = require('./svg-crowbar.js'); var svg_crowbar = require('./svg-crowbar.js');
var ReconnectingWebSocket = require('reconnectingwebsocket'); var ReconnectingWebSocket = require('reconnectingwebsocket');
var NetworkUIController = function($scope, $document, $location, $window, $http) { var NetworkUIController = function($scope, $document, $location, $window, $http, $q) {
window.scope = $scope; window.scope = $scope;
var i = 0; var i = 0;
$scope.http = $http;
$scope.api_token = ''; $scope.api_token = '';
$scope.disconnected = true; $scope.disconnected = false;
$scope.topology_id = $location.search().topology_id || 0; $scope.topology_id = $location.search().topology_id || 0;
// Create a web socket to connect to the backend server // Create a web socket to connect to the backend server
// //
$scope.inventory_id = $location.search().inventory_id || 0; $scope.inventory_id = $location.search().inventory_id || 1;
if (!$scope.disconnected) { if (!$scope.disconnected) {
$scope.control_socket = new ReconnectingWebSocket("ws://" + window.location.host + "/network_ui/topology?topology_id=" + $scope.topology_id, $scope.control_socket = new ReconnectingWebSocket("wss://" + window.location.host + "/network_ui/topology?topology_id=" + $scope.topology_id,
null, null,
{debug: false, reconnectInterval: 300}); {debug: false, reconnectInterval: 300});
} else { } else {
@@ -43,6 +46,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http)
on_message: util.noop on_message: util.noop
}; };
} }
$scope.my_location = $location.protocol() + "://" + $location.host() + ':' + $location.port();
$scope.history = []; $scope.history = [];
$scope.client_id = 0; $scope.client_id = 0;
$scope.onMouseDownResult = ""; $scope.onMouseDownResult = "";
@@ -143,23 +147,39 @@ var NetworkUIController = function($scope, $document, $location, $window, $http)
//Inventory Toolbox Setup //Inventory Toolbox Setup
$scope.inventory_toolbox = new models.ToolBox(0, 'Inventory', 'device', 10, 200, 150, $scope.graph.height - 200 - 100); $scope.inventory_toolbox = new models.ToolBox(0, 'Inventory', 'device', 10, 200, 150, $scope.graph.height - 200 - 100);
if (!$scope.disconnected) { if (!$scope.disconnected) {
console.log($location.protocol() + "://" + $location.host() + ':' + $location.port());
console.log($scope.my_location);
function add_host (host) {
console.log(host);
var device = new models.Device(0, host.data.name, 0, 0, host.data.type);
device.icon = true;
$scope.inventory_toolbox.items.push(device);
}
$http.get('/api/v2/inventories/' + $scope.inventory_id + '/hosts/?format=json') $http.get('/api/v2/inventories/' + $scope.inventory_id + '/hosts/?format=json')
.then(function(response) { .then(function(inventory) {
console.log(response); console.log(inventory);
console.log(inventory.headers());
var host = null; var host = null;
var i = 0; var i = 0;
function add_host (response) { var httpGets = [];
console.log(response); for (i=0; i < inventory.data.results.length;i++) {
var device = new models.Device(0, response.data.name, 0, 0, response.data.type); host = inventory.data.results[i];
device.icon = true; console.log($location.protocol() + "://" + $location.host() + ':' + $location.port());
$scope.inventory_toolbox.items.push(device); console.log($scope.my_location);
} httpGets.push($http.get('/api/v2/hosts/'+ host.id + '/variable_data/?format=json'));
for (i=0; i<response.data.results.length;i++) {
host = response.data.results[i];
$http.get('/api/v2/hosts/'+ host.id + '/variable_data?format=json')
.then(add_host);
} }
return httpGets;
})
.then(function(httpGets) {
console.log(httpGets);
$q.all(httpGets).then(function (results) {
var i = 0;
for (i=0; i < results.length; i++) {
add_host(results[i]);
}
console.log(['done', x]);
});
}); });
} }
$scope.inventory_toolbox.spacing = 150; $scope.inventory_toolbox.spacing = 150;
@@ -352,8 +372,24 @@ var NetworkUIController = function($scope, $document, $location, $window, $http)
// Event Handlers // Event Handlers
$scope.normalize_mouse_event = function ($event) { $scope.normalize_mouse_event = function ($event) {
$event.x = $event.pageX; if ($event.pageX !== undefined) {
$event.y = $event.pageY; $event.x = $event.pageX;
}
if ($event.pageY !== undefined) {
$event.y = $event.pageY;
}
if ($event.originalEvent !== undefined) {
var originalEvent = $event.originalEvent;
if (originalEvent.wheelDelta !== undefined) {
$event.delta = $event.originalEvent.wheelDelta;
}
if (originalEvent.wheelDeltaX !== undefined) {
$event.deltaX = $event.originalEvent.wheelDeltaX;
}
if (originalEvent.wheelDeltaY !== undefined) {
$event.deltaY = $event.originalEvent.wheelDeltaY;
}
}
}; };
$scope.onMouseDown = function ($event) { $scope.onMouseDown = function ($event) {
@@ -418,9 +454,10 @@ var NetworkUIController = function($scope, $document, $location, $window, $http)
$scope.onMouseEnter = $scope.onMouseOver; $scope.onMouseEnter = $scope.onMouseOver;
$scope.onMouseWheel = function ($event) { $scope.onMouseWheel = function ($event) {
var delta = $event.originalEvent.wheelDelta; $scope.normalize_mouse_event($event);
var deltaX = $event.originalEvent.wheelDeltaX; var delta = $event.delta;
var deltaY = $event.originalEvent.wheelDeltaY; var deltaX = $event.deltaX;
var deltaY = $event.deltaY;
console.log([$event, delta, deltaX, deltaY]); console.log([$event, delta, deltaX, deltaY]);
if ($scope.recording) { if ($scope.recording) {
$scope.send_control_message(new messages.MouseWheelEvent($scope.client_id, delta, deltaX, deltaY, $event.type, $event.originalEvent.metaKey)); $scope.send_control_message(new messages.MouseWheelEvent($scope.client_id, delta, deltaX, deltaY, $event.type, $event.originalEvent.metaKey));
@@ -609,20 +646,24 @@ var NetworkUIController = function($scope, $document, $location, $window, $http)
$scope.group_controller.changeState(group.Ready); $scope.group_controller.changeState(group.Ready);
}; };
$scope.onExportYamlButton = function (button) {
console.log(button);
$window.open('/network_ui/topology.yaml?topology_id=' + $scope.topology_id , '_blank');
};
// Buttons // Buttons
$scope.buttons = [ $scope.buttons = [
new models.Button("DEPLOY", 10, 10, 70, 30, $scope.onDeployButton), new models.Button("DEPLOY", 10, 48, 70, 30, $scope.onDeployButton),
new models.Button("DESTROY", 90, 10, 80, 30, $scope.onDestroyButton), new models.Button("DESTROY", 90, 48, 80, 30, $scope.onDestroyButton),
new models.Button("RECORD", 180, 10, 80, 30, $scope.onRecordButton), new models.Button("RECORD", 180, 48, 80, 30, $scope.onRecordButton),
new models.Button("EXPORT", 270, 10, 70, 30, $scope.onExportButton), new models.Button("EXPORT", 270, 48, 70, 30, $scope.onExportButton),
new models.Button("DISCOVER", 350, 10, 80, 30, $scope.onDiscoverButton), new models.Button("DISCOVER", 350, 48, 80, 30, $scope.onDiscoverButton),
new models.Button("LAYOUT", 440, 10, 70, 30, $scope.onLayoutButton), new models.Button("LAYOUT", 440, 48, 70, 30, $scope.onLayoutButton),
new models.Button("CONFIGURE", 520, 10, 90, 30, $scope.onConfigureButton) new models.Button("CONFIGURE", 520, 48, 90, 30, $scope.onConfigureButton),
new models.Button("EXPORT YAML", 620, 48, 120, 30, $scope.onExportYamlButton),
]; ];
$scope.buttons = [];
var LAYERS_X = 160; var LAYERS_X = 160;
$scope.layers = [ $scope.layers = [
@@ -644,6 +685,8 @@ var NetworkUIController = function($scope, $document, $location, $window, $http)
true) true)
]; ];
$scope.layers = [];
$scope.all_buttons = []; $scope.all_buttons = [];
$scope.all_buttons.extend($scope.buttons); $scope.all_buttons.extend($scope.buttons);
$scope.all_buttons.extend($scope.layers); $scope.all_buttons.extend($scope.layers);

View File

@@ -0,0 +1,20 @@
var webpack = require('webpack');
module.exports = {
entry: {
app: "./src-instrumented/main.js",
vendor: ["angular",
"angular-ui-router",
"hamsterjs",
"angular-mousewheel",
"reconnectingwebsocket",
"angular-xeditable"]
},
output: {
path: __dirname + "/js",
filename: "bundle-instrumented.js",
},
plugins: [
new webpack.ProvidePlugin({Hamster: 'hamsterjs'}),
new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: 'vendor.bundle.js' })
]
};

View File

@@ -51,6 +51,7 @@ const watch = {
stats: 'minimal', stats: 'minimal',
publicPath: '/static/', publicPath: '/static/',
host: '127.0.0.1', host: '127.0.0.1',
https: true,
port: 3000, port: 3000,
https: true, https: true,
proxy: { proxy: {
@@ -64,6 +65,11 @@ const watch = {
target: TARGET, target: TARGET,
secure: false, secure: false,
ws: true ws: true
},
'/network_ui': {
target: TARGET,
secure: false,
ws: true
} }
} }
} }